Quellcode durchsuchen

Merge branch 'dev_1.3.0' of http://git.qmth.com.cn/union-question/union-question-web into dev_1.3.0

刘洋 vor 1 Jahr
Ursprung
Commit
23b738ee15

+ 539 - 147
src/modules/card/assets/styles/card-preview.scss

@@ -23,6 +23,8 @@
     }
   }
   .elem-fill-question .option-item,
+  .elem-fill-number .fill-number-option,
+  .card-head-body .head-stdno .stdno-fill-option,
   .page-number-rect-list li,
   .card-head .head-dynamic-rect {
     border-width: 0.5pt;
@@ -635,28 +637,51 @@
 }
 // card-head
 .card-head {
-  &-title {
+  &-top {
     text-align: center;
     color: #000;
+  }
+  &-title {
     font-size: 24px;
     font-weight: bold;
     overflow: hidden;
 
     > h1 {
-      line-height: 40px;
+      line-height: 33px;
       white-space: nowrap;
       letter-spacing: -1px;
     }
   }
-  &-info {
-    padding-bottom: 30px;
-    .info-item {
+  &-subtitle {
+    height: 44px;
+    font-size: 14px;
+    overflow: hidden;
+    white-space: normal;
+    margin-bottom: 10px;
+
+    p {
+      padding: 0 10px;
+      line-height: 22px;
+      height: 22px;
+      white-space: pre;
+    }
+  }
+  &-body {
+    font-weight: normal;
+    .el-col {
+      padding-top: 5px;
+      padding-bottom: 5px;
+    }
+    &-spin {
+      padding: 5px 12px;
+      white-space: normal;
+      word-break: break-all;
+    }
+    .stdinfo-item {
       height: 30px;
       line-height: 30px;
       position: relative;
       overflow: hidden;
-      width: 80%;
-      margin: 0 auto;
 
       &::after {
         content: "";
@@ -679,6 +704,18 @@
           float: left;
           background-color: #fff;
           text-align: justify;
+          font-size: 0px;
+          & > i {
+            font-size: 14px;
+          }
+
+          &::after {
+            content: "";
+            display: inline-block;
+            width: 100%;
+            height: 0;
+            line-height: 0;
+          }
         }
         &:nth-of-type(2) {
           float: left;
@@ -686,206 +723,561 @@
           background-color: #fff;
         }
         &:last-child {
+          margin-left: 80px;
           height: 100%;
         }
       }
     }
-  }
+    .head-stdno {
+      height: 100%;
+      padding: 0;
+      .stdno-empty {
+        min-height: 130px;
+        font-weight: bold;
+        letter-spacing: 3px;
+        text-align: center;
+        position: relative;
+        > p {
+          position: absolute;
+          left: 0;
+          width: 100%;
+          top: 50%;
+          transform: translateY(-50%);
+          -webkit-transform: translateY(-50%);
+        }
+      }
+      .stdno-fill {
+        min-height: 240px;
+        height: 100%;
+        position: relative;
 
-  &-notice {
-    border: 1px solid #000;
-    padding: 6px 8px;
-    > h4 {
-      font-weight: normal;
-      margin-bottom: 8px;
-    }
-    &-cont {
-      line-height: 1.5;
-      font-size: 12px;
-      margin-bottom: 5px;
+        &-rect {
+          font-size: 0;
+          height: 27px;
+          border-bottom: 1px solid #000;
+        }
+        &-number {
+          display: inline-block;
+          vertical-align: top;
+          width: 7.692%;
+          height: 100%;
+          &:not(:last-child) {
+            border-right: 1px solid #000;
+          }
+        }
 
-      > span {
-        display: block;
+        &-head {
+          position: absolute;
+          width: 100%;
+          height: 51px;
+          top: 0;
+          left: 0;
+          z-index: 9;
+
+          > h5 {
+            border-bottom: 1px solid #000;
+            line-height: 24px;
+            font-size: 14px;
+            font-weight: bold;
+            text-align: center;
+          }
+        }
 
-        &:first-child {
-          width: 20px;
-          white-space: nowrap;
-          float: left;
+        &-body {
+          position: absolute;
+          top: 0;
+          bottom: 0;
+          padding-top: 51px;
+          display: table;
+          width: 100%;
         }
-        &:last-child {
-          margin-left: 20px;
-          white-space: normal;
+        &-list {
+          display: table-cell;
+          width: 7.692%;
+          padding: 1px 0;
+        }
+        &-option {
+          margin: 8px auto;
+          width: 18px;
+          height: 10px;
+          font-size: 12px;
+          line-height: 8px;
+          text-align: center;
+          color: #000;
+          // border-rect
+          border: 1px solid #000;
+          font-family: "Times New Roman", Arial, sans-serif;
+          > i {
+            display: inline-block;
+            transform: scale(0.67, 0.67);
+            -webkit-transform: scale(0.67, 0.67);
+          }
+        }
+      }
+      .stdno-auto {
+        &-barcode {
+          height: 70px;
+          text-align: center;
+
+          > img {
+            display: block;
+            height: 50px;
+            width: 300px;
+            margin: 0 auto;
+          }
+          > p {
+            line-height: 20px;
+          }
         }
       }
     }
-  }
 
-  &-dynamic {
-    padding: 6px 8px;
-    border: 1px solid #000;
-    border-top: none;
+    .head-notice {
+      > h4 {
+        font-weight: normal;
+        margin-bottom: 8px;
+        line-height: 20px;
+      }
+      &-cont {
+        line-height: 1.5;
+        font-size: 12px;
+        margin-bottom: 5px;
 
-    p {
-      display: inline-block;
-      vertical-align: middle;
-      line-height: 18px;
-      word-wrap: normal;
+        > span {
+          display: block;
 
-      &:first-child {
-        margin-right: 100px;
+          &:first-child {
+            width: 20px;
+            white-space: nowrap;
+            float: left;
+          }
+          &:last-child {
+            margin-left: 20px;
+          }
+        }
       }
 
-      > span,
-      > i {
-        display: inline-block;
-        vertical-align: middle;
-        box-sizing: border-box;
+      &-exam-number-fill {
+        span {
+          display: inline;
+
+          &:first-child {
+            float: none;
+          }
+          &:last-child {
+            margin: 0;
+          }
+        }
       }
-      &:first-child {
-        i {
-          width: 28px;
-          height: 14px;
-          background-color: #000;
+    }
+
+    .head-dynamic {
+      padding: 0;
+      font-size: 12px;
+      border-spacing: 0;
+      border-collapse: collapse;
+
+      &-part:not(:last-child) {
+        border-bottom: 1px solid #000;
+      }
+      &-write {
+        padding: 5px 12px;
+        .stdinfo-item {
+          margin-bottom: 0;
+        }
+        > p {
+          line-height: 18px;
         }
       }
-      &:last-child {
-        > i {
-          width: 28px;
+      &-missfill {
+        display: table;
+        width: 100%;
+      }
+      &-miss {
+        padding: 10px;
+        display: table-cell;
+        vertical-align: middle;
+
+        &:nth-of-type(2) {
+          border-left: 1px solid #000;
+        }
+        span {
+          display: block;
+        }
+        .head-dynamic-content {
+          height: 14px;
+          line-height: 14px;
+        }
+        .dynamic-miss-title {
+          width: 54px;
+          float: left;
+        }
+        .dynamic-miss-body {
+          margin-left: 54px;
           height: 14px;
-          border: 1px solid #000;
-          font-size: 14px;
-          font-weight: bold;
-          margin-right: 6px;
-          line-height: 12px;
           text-align: center;
+          font-size: 0;
+        }
+      }
+      &-fill {
+        padding: 10px;
 
-          &:last-child {
-            margin-right: 0;
+        p {
+          display: inline-block;
+          vertical-align: middle;
+          line-height: 18px;
+          word-wrap: normal;
+
+          &:first-child {
+            margin-right: 20px;
+          }
+
+          > span,
+          > i {
+            display: inline-block;
+            vertical-align: middle;
+            box-sizing: border-box;
           }
-          &:nth-of-type(3) {
-            &::before {
-              content: "";
-              display: inline-block;
-              vertical-align: top;
-              margin-left: -5px;
-              height: 100%;
-              width: 5px;
+          &:first-child {
+            i {
+              width: 28px;
+              height: 14px;
               background-color: #000;
             }
           }
-          &:nth-of-type(4) {
-            &::before {
-              content: "";
-              display: inline-block;
-              margin-top: 1px;
-              width: 10px;
-              height: 10px;
-              border-radius: 50%;
-              background-color: #000;
+          &:last-child {
+            > i {
+              width: 28px;
+              height: 14px;
+              border: 1px solid #000;
+              font-size: 14px;
+              font-weight: bold;
+              margin-right: 6px;
+              line-height: 12px;
+              text-align: center;
+
+              &:last-child {
+                margin-right: 0;
+              }
+              &:nth-of-type(3) {
+                &::before {
+                  content: "";
+                  display: inline-block;
+                  vertical-align: top;
+                  margin-left: -5px;
+                  height: 100%;
+                  width: 5px;
+                  background-color: #000;
+                }
+              }
+              &:nth-of-type(4) {
+                &::before {
+                  content: "";
+                  display: inline-block;
+                  margin-top: 1px;
+                  width: 10px;
+                  height: 10px;
+                  border-radius: 50%;
+                  background-color: #000;
+                }
+              }
             }
           }
         }
       }
+      &-rect {
+        display: inline-block;
+        vertical-align: middle;
+        width: 24px;
+        height: 12px;
+        // border-rect
+        border: 1px solid #000;
+        font-size: 12px;
+        text-align: center;
+        line-height: 10px;
+        color: #000;
+        margin: 0 5px;
+        font-family: "Times New Roman", Arial, sans-serif;
+
+        > i {
+          display: inline-block;
+          transform: scale(0.67, 0.67);
+          -webkit-transform: scale(0.67, 0.67);
+        }
+      }
+      &-aorb {
+        display: table;
+        width: 100%;
+        .dynamic-aorb-item {
+          display: table-cell;
+          vertical-align: middle;
+          text-align: center;
+          &:not(:last-child) {
+            border-right: 1px solid #000;
+          }
+        }
+        &-fill {
+          .dynamic-aorb-item:first-child {
+            border: none;
+          }
+        }
+
+        .dynamic-aorb-title {
+          width: 83px;
+        }
+        .dynamic-aorb-info {
+          width: 50px;
+          font-size: 16px;
+          position: relative;
+          overflow: hidden;
+          .dynamic-aorb-content {
+            position: absolute;
+            top: 50%;
+            left: 0;
+            width: 100%;
+            transform: translateY(-50%);
+            -webkit-transform: translateY(-50%);
+            z-index: auto;
+          }
+        }
+        .dynamic-aorb-barcode {
+          img {
+            display: block;
+            position: relative;
+            margin: 0 auto;
+            width: 200px;
+            height: 26px;
+            padding: 7px 0;
+          }
+        }
+        .dynamic-aorb-rects {
+          padding: 16px 10px;
+        }
+      }
+    }
+  }
+  &-part {
+    border: 1px solid #000;
+    &:not(:last-child) {
+      margin-bottom: 10px;
+    }
+  }
+  &-normal {
+    .head-dynamic {
+      &-1 {
+        .head-dynamic-part {
+          height: 100%;
+        }
+      }
+    }
+  }
+  &-narrow {
+    .head-stdno {
+      height: 138px;
+      .stdno-auto {
+        position: relative;
+        top: 50%;
+        margin-top: -40px;
+      }
+    }
+  }
+
+  &-handle {
+    &.card-head-narrow {
+      .head-stdno {
+        height: 242px;
+      }
     }
   }
 }
-.card-head-model-two {
+// card-head
+.card-head-model-one {
   .card-head {
     &-info {
-      padding-bottom: 15px;
-      text-align: center;
+      padding-bottom: 30px;
       .info-item {
         height: 30px;
         line-height: 30px;
         position: relative;
         overflow: hidden;
-        width: 26%;
-        display: inline-block;
-        vertical-align: text-bottom;
-        margin: 0 10px;
+        width: 80%;
+        margin: 0 auto;
+
+        &::after {
+          content: "";
+          display: block;
+          position: absolute;
+          width: 100%;
+          border-bottom: 1px solid #000;
+          bottom: 6px;
+          left: 0;
+          z-index: 1;
+        }
+
+        > span {
+          z-index: 2;
+          display: block;
+          position: relative;
+          font-size: 14px;
+
+          &:first-child {
+            float: left;
+            background-color: #fff;
+            text-align: justify;
+          }
+          &:nth-of-type(2) {
+            float: left;
+            width: 20px;
+            background-color: #fff;
+          }
+          &:last-child {
+            height: 100%;
+          }
+        }
       }
     }
-    &-body {
-      border: 1px solid #000;
-      position: relative;
-    }
-    &-notice {
-      position: relative;
-      min-height: 200px;
-      width: 50%;
-      left: 50%;
-      border: none;
-      border-left: 1px solid #000;
-    }
-    &-stdno {
-      position: absolute;
-      left: 0;
-      top: 0;
-      width: 50%;
-      height: 75%;
-      z-index: 2;
-      border-bottom: 1px solid #000;
 
-      &:last-child {
-        border-bottom: none;
-        height: 100%;
+    &-notice {
+      border: 1px solid #000;
+      padding: 6px 8px;
+      > h4 {
+        font-weight: normal;
+        margin-bottom: 8px;
       }
+      &-cont {
+        line-height: 1.5;
+        font-size: 12px;
+        margin-bottom: 5px;
 
-      .stdno-empty {
-        position: absolute;
-        width: 100%;
-        top: 50%;
-        height: 30px;
-        line-height: 30px;
-        text-align: center;
-        font-size: 26px;
-        margin-top: -15px;
-        left: 0;
+        > span {
+          display: block;
+
+          &:first-child {
+            width: 20px;
+            white-space: nowrap;
+            float: left;
+          }
+          &:last-child {
+            margin-left: 20px;
+            white-space: normal;
+          }
+        }
       }
     }
+
     &-dynamic {
-      position: absolute;
-      left: 0;
-      bottom: 0;
-      width: 50%;
-      height: 25%;
-      z-index: 2;
-      border: none;
-      padding: 0;
-      .head-dynamic-content {
-        height: 100%;
-        display: inline-table;
-        width: 50%;
-        text-align: center;
+      padding: 6px 8px;
+      border: 1px solid #000;
+      border-top: none;
 
-        &:not(:first-child) {
-          border-left: 1px solid #000;
+      p {
+        display: inline-block;
+        vertical-align: middle;
+        line-height: 18px;
+        word-wrap: normal;
+
+        &:first-child {
+          margin-right: 100px;
         }
 
-        > * {
-          display: table-cell;
+        > span,
+        > i {
+          display: inline-block;
           vertical-align: middle;
+          box-sizing: border-box;
         }
-      }
-      .dynamic-miss {
-        &-title {
-          width: 50%;
-          & > h5 {
-            font-size: 16px;
-            font-weight: 600;
+        &:first-child {
+          i {
+            width: 28px;
+            height: 14px;
+            background-color: #000;
+          }
+        }
+        &:last-child {
+          > i {
+            width: 28px;
+            height: 14px;
+            border: 1px solid #000;
+            font-size: 14px;
+            font-weight: bold;
+            margin-right: 6px;
+            line-height: 12px;
+            text-align: center;
+
+            &:last-child {
+              margin-right: 0;
+            }
+            &:nth-of-type(3) {
+              &::before {
+                content: "";
+                display: inline-block;
+                vertical-align: top;
+                margin-left: -5px;
+                height: 100%;
+                width: 5px;
+                background-color: #000;
+              }
+            }
+            &:nth-of-type(4) {
+              &::before {
+                content: "";
+                display: inline-block;
+                margin-top: 1px;
+                width: 10px;
+                height: 10px;
+                border-radius: 50%;
+                background-color: #000;
+              }
+            }
           }
         }
       }
-      .head-dynamic-rect {
-        display: inline-block;
-        vertical-align: middle;
-        width: 24px;
-        height: 12px;
-        border: 1px solid #000;
+    }
+  }
+}
+
+// card-head-body-auto-resize
+.card-head-body-auto-resize {
+  margin-left: -5px;
+  margin-right: -5px;
+  overflow: hidden;
+
+  &.col-item-auto-height {
+    .card-head-body-spin {
+      height: auto;
+    }
+  }
+
+  .head-dynamic-2 {
+    .head-dynamic-part {
+      height: auto;
+    }
+  }
+
+  .rect-col {
+    padding: 5px;
+    &:first-child {
+      float: left;
+      width: 50%;
+    }
+    &:last-child {
+      float: right;
+      width: 50%;
+    }
+
+    &-item {
+      border: 1px solid #000;
+      &:nth-of-type(2) {
+        margin-top: 10px;
+      }
+      &-none {
+        border: none;
+        margin: 0 !important;
       }
     }
   }
 }
+
 // elem-topic-head
 .elem-topic-head {
   text-align: center;

+ 462 - 92
src/modules/card/assets/styles/card-temp.css

@@ -8,6 +8,7 @@
   -webkit-box-shadow: 0 0 4px #ddd;
   box-shadow: 0 0 4px #ddd;
 }
+
 .card-print {
   padding: 0;
 }
@@ -21,10 +22,13 @@
   display: none;
 }
 .card-print .elem-fill-question .option-item,
+.card-print .elem-fill-number .fill-number-option,
+.card-print .card-head-body .head-stdno .stdno-fill-option,
 .card-print .page-number-rect-list li,
 .card-print .card-head .head-dynamic-rect {
   border-width: 0.5pt;
 }
+
 .page-box {
   position: relative;
   background: #fff;
@@ -236,6 +240,7 @@
   height: 14px;
   line-height: 14px;
 }
+
 .page-main-side {
   position: absolute;
   top: 60px;
@@ -256,6 +261,7 @@
   -webkit-transform-origin: 0 0;
   transform-origin: 0 0;
 }
+
 .page-main-inner {
   position: absolute;
   width: 100%;
@@ -266,6 +272,7 @@
   z-index: 9;
   font-size: 0;
 }
+
 .page-main-outer {
   position: absolute;
   top: 0;
@@ -276,6 +283,7 @@
   background-color: transparent;
   overflow: hidden;
 }
+
 .page-column {
   display: inline-block;
   vertical-align: middle;
@@ -405,6 +413,7 @@
   text-align: center;
   bottom: -26px;
 }
+
 .page-locator {
   position: absolute;
   left: 80px;
@@ -430,6 +439,7 @@
 .page-locator-item:nth-of-type(2) {
   right: 96px;
 }
+
 .page-box-1 .page-locator-bottom .page-locator-item:nth-of-type(1) {
   right: 0;
   left: auto;
@@ -440,6 +450,7 @@
 .page-box-1 .page-locator-item:nth-of-type(2) {
   right: 0;
 }
+
 .page-number-rect {
   position: absolute;
   bottom: 30px;
@@ -469,6 +480,7 @@
   height: 16px;
   line-height: 16px;
 }
+
 .elem-title {
   padding: 10px;
   font-size: 14px;
@@ -479,10 +491,12 @@
 .elem-body {
   padding: 10px;
 }
+
 .grid-container {
   margin-left: -10px;
   margin-right: -10px;
 }
+
 .grid-row {
   display: table;
   width: 100%;
@@ -502,30 +516,53 @@
   border-style: dashed;
   vertical-align: middle;
 }
-.card-head-title {
+
+.card-head-top {
   text-align: center;
   color: #000;
+}
+.card-head-title {
   font-size: 24px;
   font-weight: bold;
   overflow: hidden;
 }
 .card-head-title > h1 {
-  line-height: 40px;
+  line-height: 33px;
   white-space: nowrap;
   letter-spacing: -1px;
 }
-.card-head-info {
-  padding-bottom: 30px;
+.card-head-subtitle {
+  height: 44px;
+  font-size: 14px;
+  overflow: hidden;
+  white-space: normal;
+  margin-bottom: 10px;
+}
+.card-head-subtitle p {
+  padding: 0 10px;
+  line-height: 22px;
+  height: 22px;
+  white-space: pre;
+}
+.card-head-body {
+  font-weight: normal;
+}
+.card-head-body .el-col {
+  padding-top: 5px;
+  padding-bottom: 5px;
 }
-.card-head-info .info-item {
+.card-head-body-spin {
+  padding: 5px 12px;
+  white-space: normal;
+  word-break: break-all;
+}
+.card-head-body .stdinfo-item {
   height: 30px;
   line-height: 30px;
   position: relative;
   overflow: hidden;
-  width: 80%;
-  margin: 0 auto;
 }
-.card-head-info .info-item::after {
+.card-head-body .stdinfo-item::after {
   content: "";
   display: block;
   position: absolute;
@@ -535,77 +572,234 @@
   left: 0;
   z-index: 1;
 }
-.card-head-info .info-item > span {
+.card-head-body .stdinfo-item > span {
   z-index: 2;
   display: block;
   position: relative;
   font-size: 14px;
 }
-.card-head-info .info-item > span:first-child {
+.card-head-body .stdinfo-item > span:first-child {
   float: left;
   background-color: #fff;
   text-align: justify;
+  font-size: 0px;
 }
-.card-head-info .info-item > span:nth-of-type(2) {
+.card-head-body .stdinfo-item > span:first-child > i {
+  font-size: 14px;
+}
+.card-head-body .stdinfo-item > span:first-child::after {
+  content: "";
+  display: inline-block;
+  width: 100%;
+  height: 0;
+  line-height: 0;
+}
+.card-head-body .stdinfo-item > span:nth-of-type(2) {
   float: left;
   width: 20px;
   background-color: #fff;
 }
-.card-head-info .info-item > span:last-child {
+.card-head-body .stdinfo-item > span:last-child {
+  margin-left: 80px;
+  height: 100%;
+}
+.card-head-body .head-stdno {
+  height: 100%;
+  padding: 0;
+}
+.card-head-body .head-stdno .stdno-empty {
+  min-height: 130px;
+  font-weight: bold;
+  letter-spacing: 3px;
+  text-align: center;
+  position: relative;
+}
+.card-head-body .head-stdno .stdno-empty > p {
+  position: absolute;
+  left: 0;
+  width: 100%;
+  top: 50%;
+  transform: translateY(-50%);
+  -webkit-transform: translateY(-50%);
+}
+.card-head-body .head-stdno .stdno-fill {
+  min-height: 240px;
+  height: 100%;
+  position: relative;
+}
+.card-head-body .head-stdno .stdno-fill-rect {
+  font-size: 0;
+  height: 27px;
+  border-bottom: 1px solid #000;
+}
+.card-head-body .head-stdno .stdno-fill-number {
+  display: inline-block;
+  vertical-align: top;
+  width: 7.692%;
   height: 100%;
 }
-.card-head-notice {
+.card-head-body .head-stdno .stdno-fill-number:not(:last-child) {
+  border-right: 1px solid #000;
+}
+.card-head-body .head-stdno .stdno-fill-head {
+  position: absolute;
+  width: 100%;
+  height: 51px;
+  top: 0;
+  left: 0;
+  z-index: 9;
+}
+.card-head-body .head-stdno .stdno-fill-head > h5 {
+  border-bottom: 1px solid #000;
+  line-height: 24px;
+  font-size: 14px;
+  font-weight: bold;
+  text-align: center;
+}
+.card-head-body .head-stdno .stdno-fill-body {
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  padding-top: 51px;
+  display: table;
+  width: 100%;
+}
+.card-head-body .head-stdno .stdno-fill-list {
+  display: table-cell;
+  width: 7.692%;
+  padding: 1px 0;
+}
+.card-head-body .head-stdno .stdno-fill-option {
+  margin: 8px auto;
+  width: 18px;
+  height: 10px;
+  font-size: 12px;
+  line-height: 8px;
+  text-align: center;
+  color: #000;
   border: 1px solid #000;
-  padding: 6px 8px;
+  font-family: "Times New Roman", Arial, sans-serif;
+}
+.card-head-body .head-stdno .stdno-fill-option > i {
+  display: inline-block;
+  transform: scale(0.67, 0.67);
+  -webkit-transform: scale(0.67, 0.67);
+}
+.card-head-body .head-stdno .stdno-auto-barcode {
+  height: 70px;
+  text-align: center;
+}
+.card-head-body .head-stdno .stdno-auto-barcode > img {
+  display: block;
+  height: 50px;
+  width: 300px;
+  margin: 0 auto;
+}
+.card-head-body .head-stdno .stdno-auto-barcode > p {
+  line-height: 20px;
 }
-.card-head-notice > h4 {
+.card-head-body .head-notice > h4 {
   font-weight: normal;
   margin-bottom: 8px;
+  line-height: 20px;
 }
-.card-head-notice-cont {
+.card-head-body .head-notice-cont {
   line-height: 1.5;
   font-size: 12px;
   margin-bottom: 5px;
 }
-.card-head-notice-cont > span {
+.card-head-body .head-notice-cont > span {
   display: block;
 }
-.card-head-notice-cont > span:first-child {
+.card-head-body .head-notice-cont > span:first-child {
   width: 20px;
   white-space: nowrap;
   float: left;
 }
-.card-head-notice-cont > span:last-child {
+.card-head-body .head-notice-cont > span:last-child {
   margin-left: 20px;
-  white-space: normal;
 }
-.card-head-dynamic {
-  padding: 6px 8px;
-  border: 1px solid #000;
-  border-top: none;
+.card-head-body .head-notice-exam-number-fill span {
+  display: inline;
+}
+.card-head-body .head-notice-exam-number-fill span:first-child {
+  float: none;
+}
+.card-head-body .head-notice-exam-number-fill span:last-child {
+  margin: 0;
+}
+.card-head-body .head-dynamic {
+  padding: 0;
+  font-size: 12px;
+  border-spacing: 0;
+  border-collapse: collapse;
+}
+.card-head-body .head-dynamic-part:not(:last-child) {
+  border-bottom: 1px solid #000;
+}
+.card-head-body .head-dynamic-write {
+  padding: 5px 12px;
+}
+.card-head-body .head-dynamic-write .stdinfo-item {
+  margin-bottom: 0;
+}
+.card-head-body .head-dynamic-write > p {
+  line-height: 18px;
+}
+.card-head-body .head-dynamic-missfill {
+  display: table;
+  width: 100%;
+}
+.card-head-body .head-dynamic-miss {
+  padding: 10px;
+  display: table-cell;
+  vertical-align: middle;
+}
+.card-head-body .head-dynamic-miss:nth-of-type(2) {
+  border-left: 1px solid #000;
+}
+.card-head-body .head-dynamic-miss span {
+  display: block;
 }
-.card-head-dynamic p {
+.card-head-body .head-dynamic-miss .head-dynamic-content {
+  height: 14px;
+  line-height: 14px;
+}
+.card-head-body .head-dynamic-miss .dynamic-miss-title {
+  width: 54px;
+  float: left;
+}
+.card-head-body .head-dynamic-miss .dynamic-miss-body {
+  margin-left: 54px;
+  height: 14px;
+  text-align: center;
+  font-size: 0;
+}
+.card-head-body .head-dynamic-fill {
+  padding: 10px;
+}
+.card-head-body .head-dynamic-fill p {
   display: inline-block;
   vertical-align: middle;
   line-height: 18px;
   word-wrap: normal;
 }
-.card-head-dynamic p:first-child {
-  margin-right: 100px;
+.card-head-body .head-dynamic-fill p:first-child {
+  margin-right: 20px;
 }
-.card-head-dynamic p > span,
-.card-head-dynamic p > i {
+.card-head-body .head-dynamic-fill p > span,
+.card-head-body .head-dynamic-fill p > i {
   display: inline-block;
   vertical-align: middle;
   -webkit-box-sizing: border-box;
   box-sizing: border-box;
 }
-.card-head-dynamic p:first-child i {
+.card-head-body .head-dynamic-fill p:first-child i {
   width: 28px;
   height: 14px;
   background-color: #000;
 }
-.card-head-dynamic p:last-child > i {
+.card-head-body .head-dynamic-fill p:last-child > i {
   width: 28px;
   height: 14px;
   border: 1px solid #000;
@@ -615,10 +809,10 @@
   line-height: 12px;
   text-align: center;
 }
-.card-head-dynamic p:last-child > i:last-child {
+.card-head-body .head-dynamic-fill p:last-child > i:last-child {
   margin-right: 0;
 }
-.card-head-dynamic p:last-child > i:nth-of-type(3)::before {
+.card-head-body .head-dynamic-fill p:last-child > i:nth-of-type(3)::before {
   content: "";
   display: inline-block;
   vertical-align: top;
@@ -627,7 +821,7 @@
   width: 5px;
   background-color: #000;
 }
-.card-head-dynamic p:last-child > i:nth-of-type(4)::before {
+.card-head-body .head-dynamic-fill p:last-child > i:nth-of-type(4)::before {
   content: "";
   display: inline-block;
   margin-top: 1px;
@@ -636,95 +830,251 @@
   border-radius: 50%;
   background-color: #000;
 }
-.card-head-model-two .card-head-info {
-  padding-bottom: 15px;
+.card-head-body .head-dynamic-rect {
+  display: inline-block;
+  vertical-align: middle;
+  width: 24px;
+  height: 12px;
+  border: 1px solid #000;
+  font-size: 12px;
   text-align: center;
+  line-height: 10px;
+  color: #000;
+  margin: 0 5px;
+  font-family: "Times New Roman", Arial, sans-serif;
 }
-.card-head-model-two .card-head-info .info-item {
-  height: 30px;
-  line-height: 30px;
-  position: relative;
-  overflow: hidden;
-  width: 26%;
+.card-head-body .head-dynamic-rect > i {
   display: inline-block;
-  vertical-align: text-bottom;
-  margin: 0 10px;
+  transform: scale(0.67, 0.67);
+  -webkit-transform: scale(0.67, 0.67);
 }
-.card-head-model-two .card-head-body {
-  border: 1px solid #000;
-  position: relative;
+.card-head-body .head-dynamic-aorb {
+  display: table;
+  width: 100%;
 }
-.card-head-model-two .card-head-notice {
-  position: relative;
-  min-height: 200px;
-  width: 50%;
-  left: 50%;
+.card-head-body .head-dynamic-aorb .dynamic-aorb-item {
+  display: table-cell;
+  vertical-align: middle;
+  text-align: center;
+}
+.card-head-body .head-dynamic-aorb .dynamic-aorb-item:not(:last-child) {
+  border-right: 1px solid #000;
+}
+.card-head-body .head-dynamic-aorb-fill .dynamic-aorb-item:first-child {
   border: none;
-  border-left: 1px solid #000;
 }
-.card-head-model-two .card-head-stdno {
+.card-head-body .head-dynamic-aorb .dynamic-aorb-title {
+  width: 83px;
+}
+.card-head-body .head-dynamic-aorb .dynamic-aorb-info {
+  width: 50px;
+  font-size: 16px;
+  position: relative;
+  overflow: hidden;
+}
+.card-head-body .head-dynamic-aorb .dynamic-aorb-info .dynamic-aorb-content {
   position: absolute;
+  top: 50%;
   left: 0;
-  top: 0;
-  width: 50%;
-  height: 75%;
-  z-index: 2;
-  border-bottom: 1px solid #000;
+  width: 100%;
+  transform: translateY(-50%);
+  -webkit-transform: translateY(-50%);
+  z-index: auto;
 }
-.card-head-model-two .card-head-stdno:last-child {
-  border-bottom: none;
+.card-head-body .head-dynamic-aorb .dynamic-aorb-barcode img {
+  display: block;
+  position: relative;
+  margin: 0 auto;
+  width: 200px;
+  height: 26px;
+  padding: 7px 0;
+}
+.card-head-body .head-dynamic-aorb .dynamic-aorb-rects {
+  padding: 16px 10px;
+}
+.card-head-part {
+  border: 1px solid #000;
+}
+.card-head-part:not(:last-child) {
+  margin-bottom: 10px;
+}
+.card-head-normal .head-dynamic-1 .head-dynamic-part {
   height: 100%;
 }
-.card-head-model-two .card-head-stdno .stdno-empty {
-  position: absolute;
-  width: 100%;
+.card-head-narrow .head-stdno {
+  height: 138px;
+}
+.card-head-narrow .head-stdno .stdno-auto {
+  position: relative;
   top: 50%;
+  margin-top: -40px;
+}
+.card-head-handle.card-head-narrow .head-stdno {
+  height: 242px;
+}
+
+.card-head-model-one .card-head-info {
+  padding-bottom: 30px;
+}
+.card-head-model-one .card-head-info .info-item {
   height: 30px;
   line-height: 30px;
-  text-align: center;
-  font-size: 26px;
-  margin-top: -15px;
-  left: 0;
+  position: relative;
+  overflow: hidden;
+  width: 80%;
+  margin: 0 auto;
 }
-.card-head-model-two .card-head-dynamic {
+.card-head-model-one .card-head-info .info-item::after {
+  content: "";
+  display: block;
   position: absolute;
+  width: 100%;
+  border-bottom: 1px solid #000;
+  bottom: 6px;
   left: 0;
-  bottom: 0;
-  width: 50%;
-  height: 25%;
+  z-index: 1;
+}
+.card-head-model-one .card-head-info .info-item > span {
   z-index: 2;
-  border: none;
-  padding: 0;
+  display: block;
+  position: relative;
+  font-size: 14px;
+}
+.card-head-model-one .card-head-info .info-item > span:first-child {
+  float: left;
+  background-color: #fff;
+  text-align: justify;
+}
+.card-head-model-one .card-head-info .info-item > span:nth-of-type(2) {
+  float: left;
+  width: 20px;
+  background-color: #fff;
 }
-.card-head-model-two .card-head-dynamic .head-dynamic-content {
+.card-head-model-one .card-head-info .info-item > span:last-child {
   height: 100%;
-  display: inline-table;
-  width: 50%;
+}
+.card-head-model-one .card-head-notice {
+  border: 1px solid #000;
+  padding: 6px 8px;
+}
+.card-head-model-one .card-head-notice > h4 {
+  font-weight: normal;
+  margin-bottom: 8px;
+}
+.card-head-model-one .card-head-notice-cont {
+  line-height: 1.5;
+  font-size: 12px;
+  margin-bottom: 5px;
+}
+.card-head-model-one .card-head-notice-cont > span {
+  display: block;
+}
+.card-head-model-one .card-head-notice-cont > span:first-child {
+  width: 20px;
+  white-space: nowrap;
+  float: left;
+}
+.card-head-model-one .card-head-notice-cont > span:last-child {
+  margin-left: 20px;
+  white-space: normal;
+}
+.card-head-model-one .card-head-dynamic {
+  padding: 6px 8px;
+  border: 1px solid #000;
+  border-top: none;
+}
+.card-head-model-one .card-head-dynamic p {
+  display: inline-block;
+  vertical-align: middle;
+  line-height: 18px;
+  word-wrap: normal;
+}
+.card-head-model-one .card-head-dynamic p:first-child {
+  margin-right: 100px;
+}
+.card-head-model-one .card-head-dynamic p > span,
+.card-head-model-one .card-head-dynamic p > i {
+  display: inline-block;
+  vertical-align: middle;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.card-head-model-one .card-head-dynamic p:first-child i {
+  width: 28px;
+  height: 14px;
+  background-color: #000;
+}
+.card-head-model-one .card-head-dynamic p:last-child > i {
+  width: 28px;
+  height: 14px;
+  border: 1px solid #000;
+  font-size: 14px;
+  font-weight: bold;
+  margin-right: 6px;
+  line-height: 12px;
   text-align: center;
 }
-.card-head-model-two
+.card-head-model-one .card-head-dynamic p:last-child > i:last-child {
+  margin-right: 0;
+}
+.card-head-model-one
   .card-head-dynamic
-  .head-dynamic-content:not(:first-child) {
-  border-left: 1px solid #000;
+  p:last-child
+  > i:nth-of-type(3)::before {
+  content: "";
+  display: inline-block;
+  vertical-align: top;
+  margin-left: -5px;
+  height: 100%;
+  width: 5px;
+  background-color: #000;
 }
-.card-head-model-two .card-head-dynamic .head-dynamic-content > * {
-  display: table-cell;
-  vertical-align: middle;
+.card-head-model-one
+  .card-head-dynamic
+  p:last-child
+  > i:nth-of-type(4)::before {
+  content: "";
+  display: inline-block;
+  margin-top: 1px;
+  width: 10px;
+  height: 10px;
+  border-radius: 50%;
+  background-color: #000;
+}
+
+.card-head-body-auto-resize {
+  margin-left: -5px;
+  margin-right: -5px;
+  overflow: hidden;
+}
+.card-head-body-auto-resize.col-item-auto-height .card-head-body-spin {
+  height: auto;
 }
-.card-head-model-two .card-head-dynamic .dynamic-miss-title {
+.card-head-body-auto-resize .head-dynamic-2 .head-dynamic-part {
+  height: auto;
+}
+.card-head-body-auto-resize .rect-col {
+  padding: 5px;
+}
+.card-head-body-auto-resize .rect-col:first-child {
+  float: left;
   width: 50%;
 }
-.card-head-model-two .card-head-dynamic .dynamic-miss-title > h5 {
-  font-size: 16px;
-  font-weight: 600;
+.card-head-body-auto-resize .rect-col:last-child {
+  float: right;
+  width: 50%;
 }
-.card-head-model-two .card-head-dynamic .head-dynamic-rect {
-  display: inline-block;
-  vertical-align: middle;
-  width: 24px;
-  height: 12px;
+.card-head-body-auto-resize .rect-col-item {
   border: 1px solid #000;
 }
+.card-head-body-auto-resize .rect-col-item:nth-of-type(2) {
+  margin-top: 10px;
+}
+.card-head-body-auto-resize .rect-col-item-none {
+  border: none;
+  margin: 0 !important;
+}
+
 .elem-topic-head {
   text-align: center;
 }
@@ -752,6 +1102,7 @@
   white-space: nowrap;
   overflow: hidden;
 }
+
 .elem-line-horizontal {
   height: 100%;
   line-height: 30px;
@@ -762,6 +1113,7 @@
   width: 100%;
   border-bottom: 1px solid #000;
 }
+
 .elem-line-vertical {
   height: 100%;
   text-align: center;
@@ -772,10 +1124,12 @@
   height: 100%;
   border-left: 1px solid #000;
 }
+
 .elem-lines .line-item {
   display: inline-block;
   vertical-align: top;
 }
+
 .elem-rect .rect-body {
   position: absolute;
   width: 100%;
@@ -783,6 +1137,7 @@
   top: 0;
   left: 0;
 }
+
 .elem-text .text-body {
   padding: 5px;
   line-height: 1.4;
@@ -802,6 +1157,7 @@
   -webkit-transform-origin: 0 100%;
   transform-origin: 0 100%;
 }
+
 .elem-barcode {
   height: 100%;
   border-color: transparent;
@@ -818,6 +1174,7 @@
   right: 0;
   margin: auto;
 }
+
 .elem-image {
   height: 100%;
   border-color: transparent;
@@ -849,6 +1206,7 @@
   right: 0;
   margin: auto;
 }
+
 .elem-grids > table {
   table-layout: fixed;
   border-spacing: 0;
@@ -861,6 +1219,7 @@
   table-layout: auto;
   width: 100%;
 }
+
 .elem-fill-question {
   white-space: normal;
   line-height: 1;
@@ -967,6 +1326,7 @@
 .elem-fill-question-vertical .option-item:last-child {
   margin-bottom: 0 !important;
 }
+
 .elem-fill-area .option-item {
   display: inline-block;
   vertical-align: middle;
@@ -983,6 +1343,7 @@
 .elem-fill-area-vertical .option-item:last-child {
   margin-bottom: 0 !important;
 }
+
 .elem-fill-line {
   white-space: normal;
 }
@@ -1043,6 +1404,7 @@
   text-align: center;
   border: none;
 }
+
 .elem-explain .elem-title {
   padding-bottom: 0;
 }
@@ -1068,6 +1430,7 @@
 .elem-explain .elem-explain-element .explain-element-body {
   position: absolute;
 }
+
 .elem-composition .elem-title {
   padding-bottom: 0;
 }
@@ -1087,6 +1450,7 @@
   position: absolute;
   overflow: hidden;
 }
+
 .elem-fill-number {
   border: 1px solid #000;
 }
@@ -1139,6 +1503,7 @@
   transform: scale(0.67, 0.67);
   -webkit-transform: scale(0.67, 0.67);
 }
+
 .elem-fill-field {
   white-space: normal;
   overflow: hidden;
@@ -1150,6 +1515,7 @@
   -webkit-transform-origin: 0 100%;
   transform-origin: 0 100%;
 }
+
 .fill-field-item {
   display: inline-block;
   padding: 0 10px;
@@ -1187,6 +1553,7 @@
   width: 10px;
   background-color: #fff;
 }
+
 .elem-fill-pane {
   font-size: 0;
   white-space: normal;
@@ -1200,6 +1567,7 @@
 .elem-fill-pane .fill-pane-cont {
   border: 1px solid #000;
 }
+
 .elem-gutter {
   position: relative;
   width: 30px;
@@ -1226,9 +1594,11 @@
   transform: rotate(-90deg);
   -webkit-transform: rotate(-90deg);
 }
+
 .elem-pane {
   height: 100%;
 }
+
 .card-free-preview:not(.card-print) {
   padding: 10px 0;
   background-color: #f0f0f0;

+ 345 - 0
src/modules/card/components/ModifyCardRule.vue

@@ -0,0 +1,345 @@
+<template>
+  <div>
+    <el-dialog
+      class="modify-card-rule"
+      :visible.sync="modalIsShow"
+      :title="title"
+      top="10px"
+      width="900px"
+      :close-on-click-modal="false"
+      :close-on-press-escape="false"
+      append-to-body
+      @open="visibleChange"
+    >
+      <el-form
+        ref="modalFormComp"
+        label-width="130px"
+        :rules="rules"
+        :model="modalForm"
+        :key="modalForm.id"
+      >
+        <el-form-item prop="name" label="题卡规则名称:">
+          <el-input
+            v-model.trim="modalForm.name"
+            placeholder="建议不超过30个字,规则名称不允许重复"
+            style="width: 100%"
+            clearable
+          ></el-input>
+        </el-form-item>
+        <el-form-item prop="modeType" label="模板选择:">
+          <el-radio-group
+            v-model="modalForm.modeType"
+            :disabled="isEdit"
+            @change="modeTypeChange"
+          >
+            <el-radio label="POSTGRADUATE">研究生题卡模板</el-radio>
+            <el-radio label="EDUCATIONAL">教务处题卡模板A3</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <template v-if="IS_EDUCATIONAL_MODE">
+          <el-form-item
+            prop="examNumberStyle"
+            label="学号版式:"
+            class="inline-block"
+          >
+            <el-select
+              v-model="modalForm.examNumberStyle"
+              placeholder="请选择"
+              @change="numStyleChange"
+            >
+              <el-option
+                v-for="(val, key) in EXAM_NUMBER_STYLE"
+                :key="key"
+                :value="key"
+                :label="val"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item
+            v-if="modalForm.examNumberStyle === 'FILL'"
+            prop="examNumberDigit"
+            label="学号位数:"
+            class="inline-block"
+          >
+            <el-input-number
+              v-model="modalForm.examNumberDigit"
+              :min="5"
+              :max="15"
+              :step="1"
+              step-strictly
+              :controls="false"
+            ></el-input-number>
+          </el-form-item>
+          <el-form-item>
+            <el-checkbox v-model="modalForm.examAbsent"
+              >启用“缺考填涂”</el-checkbox
+            >
+            <el-checkbox v-model="modalForm.discipline"
+              >启用“违纪填涂”</el-checkbox
+            >
+          </el-form-item>
+          <el-form-item prop="studentFields" label="考生信息设置:">
+            <el-input
+              v-model.trim="modalForm.studentFields"
+              clearable
+            ></el-input>
+            <p class="tips-info">
+              提示:填写字段名,字段间用","隔开,例如:姓名,学号,班级。
+            </p>
+          </el-form-item>
+        </template>
+        <el-form-item prop="title" label="题卡正标题:">
+          <el-input v-model.trim="modalForm.title" clearable></el-input>
+        </el-form-item>
+        <el-form-item prop="subTitle" label="题卡副标题:">
+          <el-input v-model.trim="modalForm.subTitle" clearable></el-input>
+        </el-form-item>
+        <el-form-item prop="attention" label="注意事项:">
+          <el-input
+            type="textarea"
+            :rows="4"
+            v-model="modalForm.attention"
+          ></el-input>
+          <p class="tips-info">
+            提示:换行之后,题卡注意事项会展示为多条内容,内容序号会被自动添加。
+          </p>
+        </el-form-item>
+        <el-form-item prop="objectiveAttention" label="客观题注意事项:">
+          <el-input v-model.trim="modalForm.objectiveAttention"></el-input>
+        </el-form-item>
+        <el-form-item prop="subjectiveAttention" label="主观题注意事项:">
+          <el-input v-model.trim="modalForm.subjectiveAttention"></el-input>
+        </el-form-item>
+      </el-form>
+
+      <div slot="footer">
+        <el-button type="primary" :disabled="isSubmit" @click="submit"
+          >确认</el-button
+        >
+        <el-button @click="cancel">取消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { EXAM_NUMBER_STYLE } from "../enumerate";
+import { cardHeadDetailApi, cardHeadUpdateApi } from "../api";
+
+const initModalForm = {
+  id: null,
+  name: "",
+  modeType: "EDUCATIONAL",
+  pageSize: "A3",
+  examNumberStyle: "",
+  examNumberDigit: 10,
+  examAbsent: true,
+  discipline: true,
+  studentFields: "",
+  title: "",
+  subTitle: "",
+  attention: "",
+  objectiveAttention: "",
+  subjectiveAttention: "",
+};
+
+export default {
+  name: "modify-card-rule",
+  props: {
+    instance: {
+      type: Object,
+      default() {
+        return {};
+      },
+    },
+  },
+  computed: {
+    isEdit() {
+      return !!this.instance.id;
+    },
+    title() {
+      return (this.isEdit ? "编辑" : "新增") + "题卡规则";
+    },
+    IS_EDUCATIONAL_MODE() {
+      return this.modalForm.modeType === "EDUCATIONAL";
+    },
+  },
+  data() {
+    return {
+      modalIsShow: false,
+      isSubmit: false,
+      modalForm: { ...initModalForm },
+      EXAM_NUMBER_STYLE,
+      rules: {
+        name: [
+          {
+            required: true,
+            message: "题卡规则名称不能超过30个字",
+            max: 30,
+            trigger: "change",
+          },
+        ],
+        modeType: [
+          {
+            required: true,
+            message: "请选择模板",
+            trigger: "change",
+          },
+        ],
+        examNumberStyle: [
+          {
+            required: true,
+            message: "请选择学号版式",
+            trigger: "change",
+          },
+        ],
+        examNumberDigit: [
+          {
+            required: true,
+            message: "请输入学号位数",
+            trigger: "change",
+          },
+        ],
+        studentFields: [
+          {
+            required: true,
+            message: "请输入考生信息设置",
+            trigger: "change",
+          },
+          {
+            validator: (rule, value, callback) => {
+              const vals = value.split(/,|,/);
+              if (vals.length > 10) {
+                return callback(new Error("最多只能输入10个字段名"));
+              }
+              if (vals.some((val) => val.length > 8)) {
+                return callback(new Error("每个字段名最多只能输入8字符"));
+              }
+              return callback();
+            },
+            trigger: "change",
+          },
+        ],
+        title: [
+          {
+            required: true,
+            message: "请输入题卡正标题",
+            trigger: "change",
+          },
+          {
+            message: "题卡正标题不能超过26个字",
+            max: 26,
+            trigger: "change",
+          },
+        ],
+        subTitle: [
+          {
+            required: false,
+            message: "题卡副标题不能超过40个字",
+            max: 40,
+            trigger: "change",
+          },
+        ],
+        attention: [
+          {
+            required: true,
+            message: "请输入注意事项",
+            trigger: "change",
+          },
+          {
+            validator: (rule, value, callback) => {
+              const val = value.replace(/\n/g, "");
+              if (val.length > 200) {
+                callback(new Error("注意事项最多只能输入200个字符"));
+              } else {
+                callback();
+              }
+            },
+            trigger: "change",
+          },
+        ],
+        objectiveAttention: [
+          {
+            required: false,
+            message: "请输入客观题注意事项",
+            trigger: "change",
+          },
+          {
+            max: 40,
+            message: "客观题注意事项最多只能输入40个汉字",
+            trigger: "change",
+          },
+        ],
+        subjectiveAttention: [
+          {
+            required: false,
+            message: "请输入主观题注意事项",
+            trigger: "change",
+          },
+          {
+            max: 40,
+            message: "主观题注意事项最多只能输入40个汉字",
+            trigger: "change",
+          },
+        ],
+      },
+    };
+  },
+  methods: {
+    async initData(val) {
+      if (val.id) {
+        const res = await cardHeadDetailApi(val.id);
+        this.modalForm = this.$objAssign(initModalForm, res.data);
+      } else {
+        this.modalForm = this.$objAssign(initModalForm, val);
+      }
+      this.modalForm.examNumberDigit =
+        this.modalForm.examNumberDigit || initModalForm.examNumberDigit;
+    },
+    visibleChange() {
+      this.initData(this.instance);
+
+      this.$nextTick(() => {
+        this.$refs.modalFormComp.clearValidate();
+      });
+    },
+    cancel() {
+      this.modalIsShow = false;
+    },
+    open() {
+      this.modalIsShow = true;
+    },
+    modeTypeChange(val) {
+      if (val === "POSTGRADUATE") {
+        this.modalForm.pageSize = "8K";
+        this.modalForm.examAbsent = false;
+        this.modalForm.discipline = false;
+        this.modalForm.studentFields = "";
+      } else {
+        this.modalForm.pageSize = "A3";
+        this.modalForm.examAbsent = true;
+        this.modalForm.discipline = true;
+      }
+    },
+    numStyleChange() {
+      if (this.modalForm.examNumberStyle !== "FILL") {
+        this.modalForm.examNumberDigit = 10;
+      }
+    },
+    async submit() {
+      const valid = await this.$refs.modalFormComp.validate().catch(() => {});
+      if (!valid) return;
+
+      if (this.isSubmit) return;
+      this.isSubmit = true;
+      const data = await cardHeadUpdateApi(this.modalForm).catch(() => {});
+      this.isSubmit = false;
+      if (!data) return;
+
+      this.$message.success("保存成功!");
+      this.$emit("modified");
+      this.cancel();
+    },
+  },
+};
+</script>

+ 5 - 1
src/modules/card/elements/card-head/CardHead.vue

@@ -1,6 +1,6 @@
 <template>
   <div :class="classes">
-    <component :is="compName" :data="data"></component>
+    <component :is="compName" :data="data" preview></component>
   </div>
 </template>
 
@@ -18,6 +18,10 @@ export default {
         return {};
       },
     },
+    preview: {
+      type: Boolean,
+      default: false,
+    },
   },
   data() {
     return {};

+ 124 - 0
src/modules/card/elements/card-head/CardHeadBodyAutoResize.vue

@@ -0,0 +1,124 @@
+<template>
+  <div :class="classes">
+    <div class="rect-col" :style="{ width: rightColWidth + '%' }">
+      <div
+        class="rect-col-item"
+        ref="stdnoContainer"
+        :style="{ height: heights.stdno + 'px' }"
+      >
+        <slot name="stdno"></slot>
+      </div>
+      <div
+        :class="['rect-col-item', { 'rect-col-item-none': !$slots.dynamic }]"
+        ref="dynamicContainer"
+        :style="{ height: heights.dynamic + 'px' }"
+      >
+        <slot name="dynamic"></slot>
+      </div>
+    </div>
+    <div class="rect-col" :style="{ width: leftColWidth + '%' }">
+      <div
+        class="rect-col-item"
+        ref="stdinfoContainer"
+        :style="{ height: heights.stdinfo + 'px' }"
+      >
+        <slot name="stdinfo"></slot>
+      </div>
+      <div
+        class="rect-col-item"
+        ref="noticeContainer"
+        :style="{ height: heights.notice + 'px' }"
+      >
+        <slot name="notice"></slot>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "card-head-body-auto-resize",
+  props: {
+    data: {
+      type: Object,
+    },
+  },
+  data() {
+    return {
+      orgHeights: {
+        stdinfo: 40,
+        notice: 40,
+        stdno: 40,
+        dynamic: 40,
+      },
+      heights: {
+        stdinfo: 40,
+        notice: 40,
+        stdno: 40,
+        dynamic: 40,
+      },
+      leftColWidth: 50,
+      rightColWidth: 50,
+      maxRigthColWidth: 60,
+    };
+  },
+  computed: {
+    classes() {
+      return ["card-head-body-auto-resize", "col-item-auto-height"];
+    },
+  },
+  mounted() {
+    this.initStyles();
+  },
+  methods: {
+    initStyles() {
+      const containers = ["stdinfo", "notice", "stdno", "dynamic"];
+      containers.forEach((container) => {
+        const dom =
+          this.$refs[`${container}Container`] &&
+          this.$refs[`${container}Container`].firstChild;
+        this.orgHeights[container] = dom ? dom.offsetHeight : 0;
+      });
+      Object.keys(this.orgHeights).map((key) => {
+        this.heights[key] = this.orgHeights[key] + 2;
+      });
+      this.resizeRect();
+    },
+    resizeRect() {
+      // width size
+      const examNumberDigit = this.data.examNumberDigit || 13;
+      if (examNumberDigit <= 10) {
+        this.rightColWidth = 50;
+      } else {
+        let rightColWidth = 50 + 4 * (examNumberDigit - 10);
+        this.rightColWidth = Math.min(this.maxRigthColWidth, rightColWidth);
+      }
+      this.leftColWidth = 100 - this.rightColWidth;
+
+      // height size
+      let col1 = this.orgHeights.stdinfo + this.orgHeights.notice;
+      let col2 = this.orgHeights.stdno + this.orgHeights.dynamic;
+      if (this.$slots.dynamic) {
+        if (col1 > col2) {
+          this.heights.stdno = col1 - col2 + this.orgHeights.stdno + 2;
+          this.heights.dynamic = this.orgHeights.dynamic + 2;
+        } else {
+          const splitHeight = (col2 - col1) / 2;
+          this.heights.stdinfo = splitHeight + this.orgHeights.stdinfo + 2;
+          this.heights.notice = splitHeight + this.orgHeights.notice + 2;
+        }
+      } else {
+        col1 += 14;
+        col2 -= 2;
+        if (col1 > col2) {
+          this.heights.stdno = col1;
+        } else {
+          const splitHeight = (col2 - col1) / 2;
+          this.heights.stdinfo = splitHeight + this.orgHeights.stdinfo + 2;
+          this.heights.notice = splitHeight + this.orgHeights.notice + 2;
+        }
+      }
+    },
+  },
+};
+</script>

+ 9 - 8
src/modules/card/elements/card-head/CardHeadModelOne.vue

@@ -1,10 +1,14 @@
 <template>
   <div class="card-head">
-    <div class="card-head-title">
-      <h1 v-for="(t, tindex) in titles" :key="tindex">
-        {{ t }}
-      </h1>
+    <div class="card-head-top">
+      <div class="card-head-title">
+        <h1>{{ data.title }}</h1>
+      </div>
+      <div v-if="data.subTitle" class="card-head-subtitle">
+        <p>{{ data.subTitle }}</p>
+      </div>
     </div>
+
     <div class="card-head-info">
       <div v-for="(info, index) in fields" :key="index" class="info-item">
         <span>{{ info }}</span>
@@ -55,10 +59,7 @@ export default {
   },
   computed: {
     notices() {
-      return this.data.attention.split("\n") || [];
-    },
-    titles() {
-      return this.data.title.split("\n") || [];
+      return this.data.attention ? this.data.attention.split("\n") : [];
     },
   },
   methods: {},

+ 95 - 46
src/modules/card/elements/card-head/CardHeadModelTwo.vue

@@ -1,58 +1,83 @@
 <template>
-  <div class="card-head">
-    <div class="card-head-title">
-      <h1 v-for="(t, tindex) in titles" :key="tindex">
-        {{ t }}
-      </h1>
-    </div>
-    <div class="card-head-info">
-      <div v-for="(info, index) in fields" :key="index" class="info-item">
-        <span>{{ info }}</span>
-        <span>:</span>
-        <span></span>
+  <div :class="classes">
+    <div class="card-head-top">
+      <!-- 高度变化之后会影响内容排版,先固定高度 -->
+      <div class="card-head-title">
+        <el-input
+          v-if="!preview && !data.isSimple"
+          v-model="cardTitle"
+          size="small"
+          placeholder="请输入题卡标题"
+          @blur="nameChange"
+        >
+        </el-input>
+        <h1 v-else>{{ data.title }}</h1>
       </div>
-    </div>
-    <div class="card-head-body">
-      <div class="card-head-notice">
-        <h4>注意事项:</h4>
-        <div
-          v-for="(cont, index) in notices"
-          :key="index"
-          class="card-head-notice-cont"
+      <div class="card-head-subtitle">
+        <el-input
+          v-if="!preview && !data.isSimple"
+          v-model="cardSubTitle"
+          size="small"
+          placeholder="请输入题卡副标题"
+          @blur="nameChange"
         >
-          <span>{{ index + 1 }}、</span>
-          <span>{{ cont }}</span>
-        </div>
+        </el-input>
+        <p v-else>{{ data.subTitle }}</p>
       </div>
+    </div>
 
-      <div class="card-head-stdno">
-        <div class="stdno-empty">条码粘贴区</div>
-      </div>
-      <div v-if="!data.isSimple" class="card-head-dynamic">
-        <div class="head-dynamic-content">
-          <span class="dynamic-miss-title">
-            <h5>缺考标记</h5>
-          </span>
-          <span class="dynamic-miss-body"
-            ><i class="head-dynamic-rect" id="dynamic-miss-area"></i
-          ></span>
+    <div class="card-head-body" v-if="data.examNumberStyle !== 'FILL'">
+      <div class="grid-container">
+        <div class="grid-row">
+          <div class="grid-col grid-col-dash">
+            <head-stdno :data="data"></head-stdno>
+          </div>
+          <div class="grid-col">
+            <head-stdinfo :data="data"></head-stdinfo>
+          </div>
         </div>
-        <div class="head-dynamic-content">
-          <span class="dynamic-miss-title">
-            <h5>违纪标记</h5>
-          </span>
-          <span class="dynamic-miss-body"
-            ><i class="head-dynamic-rect" id="dynamic-miss-area"></i
-          ></span>
+        <div class="grid-row" v-if="!data.isSimple">
+          <div class="grid-col">
+            <head-notice :data="data"></head-notice>
+          </div>
+          <div class="grid-col">
+            <head-dynamic :data="data"></head-dynamic>
+          </div>
         </div>
       </div>
     </div>
+    <div class="card-head-body" v-else>
+      <card-head-body-auto-resize :data="data">
+        <head-stdinfo :data="data" slot="stdinfo"></head-stdinfo>
+        <head-notice :data="data" slot="notice"></head-notice>
+        <head-stdno :data="data" slot="stdno"></head-stdno>
+        <head-dynamic
+          :data="data"
+          slot="dynamic"
+          v-if="!data.isSimple && hasDynamicArea"
+        ></head-dynamic>
+      </card-head-body-auto-resize>
+    </div>
   </div>
 </template>
 
 <script>
+import HeadDynamic from "./cardHeadSpin/HeadDynamic";
+import HeadNotice from "./cardHeadSpin/HeadNotice";
+import HeadStdinfo from "./cardHeadSpin/HeadStdinfo";
+import HeadStdno from "./cardHeadSpin/HeadStdno";
+import CardHeadBodyAutoResize from "./CardHeadBodyAutoResize";
+import { mapMutations } from "vuex";
+
 export default {
   name: "CardHeadModelTwo",
+  components: {
+    HeadStdno,
+    HeadStdinfo,
+    HeadNotice,
+    HeadDynamic,
+    CardHeadBodyAutoResize,
+  },
   props: {
     data: {
       type: Object,
@@ -60,20 +85,44 @@ export default {
         return {};
       },
     },
+    preview: {
+      type: Boolean,
+      default: false,
+    },
   },
   data() {
     return {
-      fields: ["学号", "姓名", "学院"],
+      cardTitle: "",
+      cardSubTitle: "",
     };
   },
   computed: {
-    notices() {
-      return this.data.attention.split("\n") || [];
+    classes() {
+      return [
+        "page-element",
+        "card-head",
+        {
+          "card-head-handle": this.data.examNumberStyle === "FILL",
+          "card-head-normal": this.data.examNumberStyle !== "FILL",
+        },
+      ];
     },
-    titles() {
-      return this.data.title.split("\n") || [];
+    hasDynamicArea() {
+      return this.data.examAbsent || this.data.discipline;
+    },
+  },
+  created() {
+    this.cardTitle = this.data.title;
+    this.cardSubTitle = this.data.subTitle;
+  },
+  methods: {
+    ...mapMutations("card", ["setCardConfig"]),
+    nameChange() {
+      this.setCardConfig({
+        title: this.cardTitle,
+        subTitle: this.cardSubTitle,
+      });
     },
   },
-  methods: {},
 };
 </script>

+ 107 - 0
src/modules/card/elements/card-head/cardHeadSpin/HeadDynamic.vue

@@ -0,0 +1,107 @@
+<template>
+  <div :class="classes">
+    <!-- write -->
+    <div
+      class="head-dynamic-part head-dynamic-write"
+      v-if="data.examNumberStyle !== 'FILL'"
+    >
+      <div class="stdinfo-item">
+        <span><i>手写签名</i></span>
+        <span>:</span>
+        <span></span>
+      </div>
+      <p>
+        注意:签名则表示您认可答题卡提供的信息与您本人信息相符;如签名与信息不符或者未签名,试卷作废。
+      </p>
+    </div>
+    <!-- file -->
+    <div class="head-dynamic-part head-dynamic-fill">
+      <div class="head-dynamic-content">
+        <p><span>正确填涂:</span><i></i></p>
+        <p>
+          <span>错误填涂:</span>
+          <i>√</i>
+          <i>×</i>
+          <i></i>
+          <i></i>
+        </p>
+      </div>
+    </div>
+    <!-- miss discipline -->
+    <div
+      v-if="data.examAbsent || data.discipline"
+      class="head-dynamic-part head-dynamic-missfill"
+    >
+      <div class="head-dynamic-miss" v-if="data.examAbsent">
+        <div class="head-dynamic-content">
+          <span class="dynamic-miss-title">缺考标记</span>
+          <span class="dynamic-miss-body"
+            ><i
+              class="head-dynamic-rect dynamic-miss-area"
+              id="dynamic-miss-area"
+            ></i
+          ></span>
+        </div>
+      </div>
+      <div class="head-dynamic-miss" v-if="data.discipline">
+        <div class="head-dynamic-content">
+          <span class="dynamic-miss-title">违纪标记</span>
+          <span class="dynamic-miss-body"
+            ><i
+              class="head-dynamic-rect dynamic-breach-area"
+              id="dynamic-breach-area"
+            ></i
+          ></span>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { calcSum } from "../../../plugins/utils";
+
+export default {
+  name: "head-dynamic",
+  props: {
+    data: {
+      type: Object,
+    },
+  },
+  data() {
+    return {};
+  },
+  computed: {
+    classes() {
+      let partNum = 1;
+      if (this.data.examNumberStyle !== "FILL" && this.data.writeSign)
+        partNum++;
+      if (this.data.examAbsent || this.data.discipline) partNum++;
+
+      return ["head-dynamic", "card-head-body-spin", `head-dynamic-${partNum}`];
+    },
+  },
+  mounted() {
+    this.initStyles();
+  },
+  methods: {
+    initStyles() {
+      const { examNumberStyle } = this.data;
+      if (examNumberStyle === "FILL") return;
+
+      const parentHeight = this.$el.parentNode.offsetHeight;
+      this.$el.style.height = parentHeight + "px";
+      const childrenCount = this.$el.children.length;
+      if (childrenCount > 1) {
+        let heights = [];
+        for (let i = 0; i < childrenCount; i++) {
+          heights[i] = this.$el.children[i].offsetHeight;
+        }
+        const lastChildHeight = parentHeight - calcSum(heights.slice(0, -1));
+        this.$el.children[childrenCount - 1].style.height =
+          lastChildHeight + "px";
+      }
+    },
+  },
+};
+</script>

+ 39 - 0
src/modules/card/elements/card-head/cardHeadSpin/HeadNotice.vue

@@ -0,0 +1,39 @@
+<template>
+  <div :class="classes">
+    <h4>注意事项:</h4>
+    <div class="head-notice-cont" v-for="(cont, index) in notices" :key="index">
+      <span>{{ index + 1 }}、</span>
+      <span>{{ cont }}</span>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "head-notice",
+  props: {
+    data: {
+      type: Object,
+    },
+  },
+  data() {
+    return {};
+  },
+  computed: {
+    classes() {
+      return [
+        "head-notice",
+        "card-head-body-spin",
+        {
+          "head-notice-exam-number-fill": this.data.examNumberStyle === "fill",
+        },
+      ];
+    },
+    notices() {
+      const conts = this.data.attention.split("\n") || [];
+      return conts.map((item) => item.trim()).filter((item) => !!item);
+    },
+  },
+  methods: {},
+};
+</script>

+ 63 - 0
src/modules/card/elements/card-head/cardHeadSpin/HeadStdinfo.vue

@@ -0,0 +1,63 @@
+<template>
+  <div class="head-stdinfo card-head-body-spin">
+    <div class="stdinfo-item" v-for="(info, index) in fields" :key="index">
+      <span :style="paramStyle" v-html="info.htmlCont"></span>
+      <span>:</span>
+      <span :style="contStyle"></span>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "head-stdinfo",
+  props: {
+    data: {
+      type: Object,
+    },
+  },
+  data() {
+    return {
+      fields: [],
+      paramStyle: {},
+      contStyle: {},
+      lenWidths: {
+        3: 45,
+        4: 62,
+        5: 75,
+        6: 90,
+        7: 105,
+        8: 120,
+      },
+    };
+  },
+  created() {
+    this.init();
+  },
+  methods: {
+    init() {
+      this.fields = (this.data.studentFields || "")
+        .split(/,|,/)
+        .map((item) => {
+          // 兼容wkhtmltopdf 汉字两端对齐的问题
+          return {
+            name: item,
+            htmlCont: item
+              .split("")
+              .map((str) => `<i>${str}</i>`)
+              .join(" "),
+          };
+        });
+      const nameNums = this.fields.map((item) => item.name.length);
+      const maxNameLen = Math.max.apply(null, nameNums);
+      const num = maxNameLen < 3 ? 3 : maxNameLen > 8 ? 8 : maxNameLen;
+      this.paramStyle = {
+        width: this.lenWidths[num] + "px",
+      };
+      this.contStyle = {
+        marginLeft: this.lenWidths[num] + 20 + "px",
+      };
+    },
+  },
+};
+</script>

+ 59 - 0
src/modules/card/elements/card-head/cardHeadSpin/HeadStdno.vue

@@ -0,0 +1,59 @@
+<template>
+  <div :class="classes">
+    <div class="stdno-empty" v-if="data.examNumberStyle === 'PASTE'">
+      <p class="">粘贴条形码区</p>
+    </div>
+    <div class="stdno-fill" v-if="data.examNumberStyle === 'FILL'">
+      <div class="stdno-fill-head">
+        <h5>学号</h5>
+        <div class="stdno-fill-rect">
+          <div
+            class="stdno-fill-number"
+            v-for="n in examNumberDigit"
+            :key="n"
+            :style="columnStyles"
+          ></div>
+        </div>
+      </div>
+      <div class="stdno-fill-body">
+        <div
+          class="stdno-fill-list"
+          v-for="n in examNumberDigit"
+          :key="n"
+          :style="columnStyles"
+        >
+          <div class="stdno-fill-option" v-for="m in 10" :key="m">
+            <i>{{ m - 1 }}</i>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "head-stdno",
+  props: {
+    data: {
+      type: Object,
+    },
+  },
+  data() {
+    return {
+      examNumberDigit: this.data.examNumberDigit || 13,
+    };
+  },
+  computed: {
+    classes() {
+      return ["head-stdno", "card-head-body-spin"];
+    },
+    columnStyles() {
+      return {
+        width: (100 / this.examNumberDigit).toFixed(2) + "%",
+      };
+    },
+  },
+  methods: {},
+};
+</script>

+ 6 - 0
src/modules/card/elements/card-head/model.js

@@ -6,7 +6,13 @@ const MODEL = {
   y: 0,
   w: 0,
   h: 0,
+  examNumberStyle: "",
+  examNumberDigit: 10,
+  examAbsent: true,
+  discipline: true,
+  studentFields: "",
   title: "测试题卡规则1-题卡标题",
+  subTitle: "测试题卡规则1-题卡副标题",
   attention: "测试题卡规则1-注意事项",
   objectiveAttention: "测试题卡规则1-客观题-注意事项",
   subjectiveAttention: "测试题卡规则1-主观题-注意事项",

+ 1 - 1
src/modules/card/elements/explain/model.js

@@ -18,7 +18,7 @@ const MODEL = {
   x: 0,
   y: 0,
   w: 0,
-  h: 458,
+  h: 476,
   minHeight: 60,
   sign: "subjective",
   topicName: "",

+ 5 - 1
src/modules/card/enumerate.js

@@ -1,10 +1,14 @@
 export const CARD_VERSION = "1.0.0";
 
 export const EXAM_NUMBER_STYLE = {
-  PRINT: "印刷条码",
+  // PRINT: "印刷条码",
   PASTE: "粘贴条码",
   FILL: "考号填涂",
 };
+export const CARD_MODE_TYPE = {
+  POSTGRADUATE: "研究生",
+  EDUCATIONAL: "教务处",
+};
 
 export const PAPER_TYPE = {
   PRINT: "印刷",

+ 135 - 0
src/modules/card/modelData.js

@@ -0,0 +1,135 @@
+const markModeA3 = {
+  elements: [
+    {
+      type: "CARD_HEAD",
+      modelType: "MODEL_ONE",
+    },
+  ],
+  sideLeft: [
+    {
+      type: "GUTTER",
+      direction: "left",
+      x: 60,
+      w: 30,
+    },
+    {
+      type: "FILL_FIELD",
+      fieldCountPerLine: 2,
+      w: 440,
+      h: 40,
+      y: 980,
+      x: 26,
+      fields: [
+        {
+          name: "考生编号",
+          code: "",
+        },
+        {
+          name: "姓名",
+          code: "",
+        },
+      ],
+    },
+    {
+      type: "FILL_FIELD",
+      w: 220,
+      h: 40,
+      y: 510,
+      x: 26,
+      fields: [
+        {
+          name: "考生确认签名",
+          code: "",
+        },
+      ],
+    },
+  ],
+  sideRight: [
+    {
+      type: "GUTTER",
+      direction: "right",
+      x: 0,
+      w: 30,
+    },
+  ],
+};
+
+const markMode8K = {
+  elements: [
+    {
+      type: "CARD_HEAD",
+      modelType: "MODEL_ONE",
+    },
+  ],
+  sideLeft: [
+    {
+      type: "GUTTER",
+      direction: "left",
+      x: 60,
+      w: 30,
+    },
+    {
+      type: "FILL_FIELD",
+      fieldCountPerLine: 2,
+      w: 400,
+      h: 30,
+      y: 870,
+      x: 26,
+      fields: [
+        {
+          name: "考生编号",
+          code: "",
+        },
+        {
+          name: "姓名",
+          code: "",
+        },
+      ],
+    },
+    {
+      type: "FILL_FIELD",
+      w: 220,
+      h: 30,
+      y: 470,
+      x: 26,
+      fields: [
+        {
+          name: "考生确认签名",
+          code: "",
+        },
+      ],
+    },
+  ],
+  sideRight: [
+    {
+      type: "GUTTER",
+      direction: "right",
+      x: 0,
+      w: 30,
+    },
+  ],
+};
+
+const teachMode = {
+  elements: [
+    {
+      type: "CARD_HEAD",
+      modelType: "MODEL_TWO",
+    },
+  ],
+};
+
+export const cardModels = {
+  POSTGRADUATE: {
+    A3: markModeA3,
+    "8K": markMode8K,
+  },
+  EDUCATIONAL: {
+    A3: teachMode,
+    "8K": teachMode,
+  },
+};
+
+export const getCardModels = (modeType, pageSize = "A3") => {
+  return cardModels[modeType][pageSize];
+};

Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
src/modules/card/previewTemp.js


+ 6 - 5
src/modules/card/views/CardEdit.vue

@@ -24,11 +24,11 @@ import {
   saveCard,
   paperDetailApi,
   cardDetailByPaperId,
-  cardTemplateDetail,
   saveCardByPaper,
 } from "../api";
 import CardDesign from "../components/CardDesign";
 import { getPaperJsonSimpleStructInfo } from "../autoBuild/paperStruct";
+import { getCardModels } from "../modelData";
 
 export default {
   name: "CardEdit",
@@ -144,8 +144,9 @@ export default {
         this.$message.error("找不到题卡版头!");
         return;
       }
-      const tempRes = await cardTemplateDetail(res.data.cardTemplateId);
-      if (!tempRes.data) {
+
+      const templateInfo = getCardModels(res.data.modeType, res.data.pageSize);
+      if (!templateInfo) {
         this.$message.error("找不到题卡模板!");
         return;
       }
@@ -157,10 +158,10 @@ export default {
           columnGap: 20,
           showForbidArea: false,
           showScorePan: false,
-          templateInfo: JSON.parse(tempRes.data.content),
+          templateInfo,
         },
       };
-      config.pageSize = config.pageSize || "A3";
+
       return config;
     },
     // 操作

+ 15 - 33
src/modules/card/views/CardHeadManage.vue

@@ -6,7 +6,7 @@
   >
     <div class="part-box">
       <div class="part-box-header">
-        <h2 class="part-box-title">题卡版头管理</h2>
+        <h2 class="part-box-title">题卡规则管理</h2>
         <el-button type="danger" plain icon="icon icon-back" @click="goBack"
           >返回</el-button
         >
@@ -129,14 +129,22 @@
         />
       </div>
     </div>
+    <!-- ModifyCardRule -->
+    <modify-card-rule
+      ref="ModifyCardRule"
+      :instance="curRow"
+      @modified="search"
+    ></modify-card-rule>
   </div>
 </template>
 
 <script>
 import { cardHeadListApi, cardHeadDeleteApi, cardHeadEnableApi } from "../api";
+import ModifyCardRule from "../components/ModifyCardRule.vue";
 
 export default {
   name: "CardHeadManage",
+  components: { ModifyCardRule },
   data() {
     return {
       loading: false,
@@ -145,23 +153,14 @@ export default {
       },
       selectedIds: [],
       tableData: [],
+      curRow: {},
       currentPage: 1,
       pageSize: 10,
       total: 10,
     };
   },
   mounted() {
-    const cacheInfo = window.sessionStorage.getItem("card-head-manage");
-    if (cacheInfo) {
-      const { currentPage, pageSize, searchForm } = JSON.parse(cacheInfo);
-      this.searchForm = { ...searchForm };
-      this.currentPage = currentPage;
-      this.pageSize = pageSize;
-      this.handleCurrentChange(this.currentPage);
-      window.sessionStorage.removeItem("card-head-manage");
-    } else {
-      this.handleCurrentChange(1);
-    }
+    this.handleCurrentChange(1);
   },
   methods: {
     async search() {
@@ -214,10 +213,8 @@ export default {
       this.deletePageLastItem(this.selectedIds.length);
     },
     toAdd() {
-      this.cacheSearchInfo();
-      this.$router.push({
-        name: "CardHeadEdit",
-      });
+      this.curRow = {};
+      this.$refs.ModifyCardRule.open();
     },
     async toEnable(row) {
       const action = row.enable ? "禁用" : "启用";
@@ -239,13 +236,8 @@ export default {
       this.search();
     },
     toEdit(row) {
-      this.cacheSearchInfo();
-      this.$router.push({
-        name: "CardHeadEdit",
-        params: {
-          cardHeadId: row.id,
-        },
-      });
+      this.curRow = row;
+      this.$refs.ModifyCardRule.open();
     },
     async toDelete(row) {
       const confirm = await this.$confirm(
@@ -264,16 +256,6 @@ export default {
     goBack() {
       window.history.go(-1);
     },
-    cacheSearchInfo() {
-      window.sessionStorage.setItem(
-        "card-head-mamange",
-        JSON.stringify({
-          searchForm: this.searchForm,
-          currentPage: this.currentPage,
-          pageSize: this.pageSize,
-        })
-      );
-    },
   },
 };
 </script>

+ 8 - 8
src/modules/card/views/CardManage.vue

@@ -47,8 +47,8 @@
             type="primary"
             plain
             icon="icon icon-edit"
-            @click="toCardHead"
-            >题卡版头管理
+            @click="toCardRule"
+            >题卡规则管理
           </el-button>
           <el-button
             type="primary"
@@ -244,7 +244,6 @@ import {
   cardDeleteApi,
   cardEnableApi,
   cardConfigInfos,
-  cardTemplateDetail,
   cardDownloadApi,
   cardPackageDownloadApi,
 } from "../api";
@@ -256,6 +255,7 @@ import { QUESTION_API } from "@/constants/constants.js";
 import { mapState } from "vuex";
 import { getPaperStructSimpleStructInfo } from "../autoBuild/paperStruct";
 import { downloadByApi } from "@/plugins/download";
+import { getCardModels } from "../modelData";
 
 export default {
   name: "CardManage",
@@ -350,7 +350,7 @@ export default {
     selectChange(selections) {
       this.selectedIds = selections.map((item) => item.id);
     },
-    toCardHead() {
+    toCardRule() {
       this.cacheSearchInfo();
       this.$router.push({ name: "CardHeadManage" });
     },
@@ -399,8 +399,9 @@ export default {
         this.$message.error("找不到题卡版头!");
         return;
       }
-      const tempRes = await cardTemplateDetail(res.data.cardTemplateId);
-      if (!tempRes.data) {
+
+      const templateInfo = getCardModels(res.data.modeType, res.data.pageSize);
+      if (!templateInfo) {
         this.$message.error("找不到题卡模板!");
         return;
       }
@@ -412,10 +413,9 @@ export default {
           columnGap: 20,
           showForbidArea: false,
           showScorePan: false,
-          templateInfo: JSON.parse(tempRes.data.content),
+          templateInfo,
         },
       };
-      config.pageSize = config.pageSize || "A3";
 
       return config;
     },

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.