zhangjie 5 anni fa
parent
commit
0fb7f21ee8

+ 1558 - 0
public/pag.html

@@ -0,0 +1,1558 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta name="viewport" content="width=device-width,initial-scale=1.0,
+    maximum-scale=1.0,minimum-scale=1.0, user-scalable=no" "="">
+    <meta name=" renderer" content="webkit|ie-comp|ie-stand" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
+    <title>教务处平台题卡</title>
+  </head>
+  <style>
+    body,
+    div,
+    ul,
+    ol,
+    li,
+    h1,
+    h2,
+    h3,
+    h4,
+    h5,
+    h6,
+    input,
+    p,
+    tr,
+    th,
+    td,
+    span,
+    a,
+    header,
+    footer,
+    i {
+      margin: 0;
+      padding: 0;
+      -webkit-box-sizing: border-box;
+      box-sizing: border-box;
+      -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+    }
+    li {
+      list-style: none;
+    }
+    em,
+    i,
+    u {
+      font-style: normal;
+    }
+    button {
+      font-family: "Helvetica Neue", Helvetica, "PingFang SC",
+        "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;
+    }
+    h1,
+    h2,
+    h3,
+    h4,
+    h5,
+    h6 {
+      font-size: 100%;
+    }
+    fieldset,
+    img {
+      border: 0;
+    }
+    abbr {
+      border: 0;
+      font-variant: normal;
+    }
+    a {
+      text-decoration: none;
+      color: inherit;
+      *color: #bbbbbb;
+    }
+    img {
+      vertical-align: middle;
+    }
+    body {
+      font-family: "Helvetica Neue", Helvetica, "PingFang SC",
+        "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;
+      -webkit-font-smoothing: antialiased;
+      -moz-osx-font-smoothing: grayscale;
+      font-size: 14px;
+      color: #545454;
+      font-weight: bold;
+    }
+    .color-primary {
+      color: #23c4b9 !important;
+    }
+    .color-success {
+      color: #1cd0a1;
+    }
+    .color-warning {
+      color: #ff9f45;
+    }
+    .color-danger {
+      color: #fe6c69;
+    }
+    .color-info {
+      color: #909399;
+    }
+    .btn--danger.el-button--text {
+      color: #fe6c69 !important;
+    }
+    .btn-white {
+      background-color: #fff !important;
+      color: #999 !important;
+    }
+    .font-bold {
+      font-weight: bold;
+    }
+    .table-head-bg th {
+      background-color: #f6f6f6;
+      color: #545454;
+    }
+    .btn-act {
+      background: #1cd0a1 !important;
+      -webkit-box-shadow: 5px 5px 4px 0px rgba(28, 208, 161, 0.3);
+      box-shadow: 5px 5px 4px 0px rgba(28, 208, 161, 0.3);
+      border-radius: 10px;
+    }
+    .card-preview {
+      padding-top: 70px;
+      background-color: #f0f0f0;
+    }
+    .card-preview .page-box {
+      margin: 10px auto;
+      -webkit-box-shadow: 0 0 4px #ddd;
+      box-shadow: 0 0 4px #ddd;
+    }
+    .card-preview .element-item {
+      width: 100% !important;
+    }
+    .card-print {
+      padding: 0;
+    }
+    .card-print .page-box {
+      margin: 0 auto;
+      -webkit-box-shadow: none;
+      box-shadow: none;
+      page-break-after: always;
+    }
+    .page-box {
+      position: relative;
+      width: 1587px;
+      height: 1122px;
+      background: #fff;
+      margin: 0 auto;
+      font-weight: normal;
+    }
+    .page-box .page-main {
+      height: 100%;
+      position: relative;
+      white-space: nowrap;
+      margin: 0 -10px;
+    }
+    .page-box .page-main-3 .page-column:first-child {
+      width: 430px;
+    }
+    .page-box .page-main-3 .page-column:not(:first-child) {
+      width: 508.5px;
+    }
+    .page-box .page-main-4 .page-column:first-child {
+      width: 430px;
+    }
+    .page-box .page-main-4 .page-column:not(:first-child) {
+      width: 335.5px;
+    }
+    .page-box-1 .page-main-3 .page-column {
+      width: 33.33% !important;
+    }
+    .page-box-1 .page-main-4 .page-column {
+      width: 25% !important;
+    }
+    .page-main-inner {
+      position: absolute;
+      width: 100%;
+      height: 100%;
+      top: 0;
+      left: 0;
+      padding: 106px 80px;
+      z-index: 9;
+      font-size: 0;
+    }
+    .page-main-outer {
+      position: absolute;
+      top: 0;
+      left: 0;
+      right: 0;
+      bottom: 0;
+      z-index: 8;
+      background-color: transparent;
+      overflow: hidden;
+    }
+    .page-column {
+      display: inline-block;
+      vertical-align: middle;
+      position: relative;
+      height: 100%;
+      width: 50%;
+      font-size: 14px;
+      padding: 0 10px;
+    }
+    .page-column-forbid-area {
+      position: absolute;
+      top: 0;
+      left: 0;
+      bottom: 0;
+      right: 0;
+      z-index: 1;
+      border: 1px solid #333;
+      overflow: hidden;
+      background: linear-gradient(
+          to top right,
+          rgba(172, 172, 172, 0) 0%,
+          rgba(172, 172, 172, 0) calc(50% - 1px),
+          #acacac 50%,
+          rgba(172, 172, 172, 0) calc(50% + 1px),
+          rgba(172, 172, 172, 0) 100%
+        ),
+        linear-gradient(
+          to bottom right,
+          rgba(172, 172, 172, 0) 0%,
+          rgba(172, 172, 172, 0) calc(50% - 1px),
+          #acacac 50%,
+          rgba(172, 172, 172, 0) calc(50% + 1px),
+          rgba(172, 172, 172, 0) 100%
+        );
+    }
+    .page-column-forbid-area > p {
+      color: #333;
+      padding: 20px;
+      position: absolute;
+      top: 50%;
+      left: 50%;
+      -webkit-transform: translate(-50%, -50%);
+      transform: translate(-50%, -50%);
+      font-weight: bold;
+      font-size: 30px;
+      color: #999;
+      background-color: #fff;
+    }
+    .page-column-main {
+      position: relative;
+      height: 100%;
+      overflow: hidden;
+    }
+    .page-column-main
+      .page-column-element:nth-of-type(1)
+      .element-item-topic-head {
+      margin-top: 0;
+    }
+    .page-column-body {
+      position: absolute;
+      top: 0;
+      bottom: 0;
+      left: 0;
+      right: 0;
+      z-index: 9;
+    }
+    .page-column-element .element-item {
+      position: relative;
+      border: 1px solid #333;
+      border-top: 0;
+    }
+    .page-column-element .element-item-card-head {
+      border: 0;
+    }
+    .page-column-element .element-item-topic-head {
+      margin-top: 10px;
+      border-top: 1px solid #333;
+    }
+    .page-locators {
+      position: absolute;
+      top: 106px;
+      left: 80px;
+      right: 80px;
+      bottom: 106px;
+      z-index: 8;
+    }
+    .page-locators-4 .page-locator-group:nth-of-type(2) {
+      left: 33.3%;
+      margin-left: -4.5mm;
+    }
+    .page-locators-4 .page-locator-group:nth-of-type(3) {
+      left: 66.6%;
+      margin-left: -2.3mm;
+    }
+    .page-locators-5 .page-locator-group:nth-of-type(2) {
+      left: 25%;
+      margin-left: -5.1mm;
+    }
+    .page-locators-5 .page-locator-group:nth-of-type(3) {
+      left: 50%;
+      margin-left: -3.4mm;
+    }
+    .page-locators-5 .page-locator-group:nth-of-type(4) {
+      left: 75%;
+      margin-left: -1.8mm;
+    }
+    .page-locator-group {
+      position: absolute;
+      top: 0;
+      bottom: 0;
+      width: 24px;
+    }
+    .page-locator-group:first-child {
+      left: 0;
+    }
+    .page-locator-group:nth-of-type(2) {
+      left: 50%;
+      margin-left: -12px;
+    }
+    .page-locator-group:last-child {
+      right: 0;
+    }
+    .page-locator-group li {
+      position: absolute;
+      width: 24px;
+      border-bottom: 16px solid #000;
+      z-index: 99;
+    }
+    .page-locator-group li:first-child {
+      top: -46px;
+    }
+    .page-locator-group li:last-child {
+      bottom: -46px;
+    }
+    .elem-title {
+      padding: 10px 13px 20px;
+      font-size: 14px;
+      font-weight: bold;
+      color: black;
+      line-height: 1;
+    }
+    .elem-body {
+      padding: 10px;
+    }
+    .grid-container {
+      margin-left: -10px;
+      margin-right: -10px;
+    }
+    .grid-row {
+      display: table;
+      width: 100%;
+      border-spacing: 10px 5px;
+      border-collapse: separate;
+    }
+    .grid-row .grid-col {
+      display: table-cell;
+      width: 50%;
+      vertical-align: top;
+      border: 1px solid #333;
+    }
+    .grid-row .grid-col-dash {
+      border-style: dashed;
+      vertical-align: middle;
+    }
+    .card-head-top {
+      text-align: center;
+    }
+    .card-head-title {
+      font-size: 36px;
+      font-family: "宋体";
+      font-weight: bold;
+      line-height: 48px;
+    }
+    .card-head-subtitle textarea,
+    .card-head-subtitle > p {
+      height: 55px;
+      padding: 0 10px;
+      font-size: 14px;
+      font-family: "Helvetica Neue", Helvetica, "PingFang SC",
+        "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;
+      font-weight: bold;
+      line-height: 20px;
+      text-align: center;
+      border-color: transparent;
+      background-color: transparent;
+      color: #000;
+      overflow: hidden;
+    }
+    .card-head-body {
+      font-weight: normal;
+    }
+    .card-head-body .el-col {
+      padding-top: 5px;
+      padding-bottom: 5px;
+    }
+    .card-head-body-spin {
+      padding: 5px 12px;
+      white-space: normal;
+      word-break: break-all;
+    }
+    .card-head-body .stdinfo-item {
+      height: 34px;
+      line-height: 34px;
+      position: relative;
+      overflow: hidden;
+    }
+    .card-head-body .stdinfo-item::after {
+      content: "";
+      display: block;
+      position: absolute;
+      width: 100%;
+      border-bottom: 1px solid #333;
+      bottom: 6px;
+      left: 0;
+      z-index: 1;
+    }
+    .card-head-body .stdinfo-item > span {
+      z-index: 2;
+      display: block;
+      position: relative;
+      font-weight: bold;
+      font-size: 14px;
+    }
+    .card-head-body .stdinfo-item > span:first-child {
+      float: left;
+      background-color: #fff;
+      width: 60px;
+      text-align: justify;
+    }
+    .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-body .stdinfo-item > span:last-child {
+      margin-left: 80px;
+      height: 100%;
+      overflow: hidden;
+    }
+    .card-head-body .head-stdno {
+      height: 100%;
+      padding: 0;
+    }
+    .card-head-body .head-stdno .stdno-empty {
+      font-weight: bold;
+      letter-spacing: 3px;
+    }
+    .card-head-body .head-stdno .stdno-fill {
+      min-height: 286px;
+      height: 100%;
+      position: relative;
+    }
+    .card-head-body .head-stdno .stdno-fill-rect {
+      font-size: 0;
+      height: 27px;
+      border-bottom: 1px solid #333;
+    }
+    .card-head-body .head-stdno .stdno-fill-number {
+      display: inline-block;
+      vertical-align: top;
+      width: 7.692%;
+      height: 100%;
+    }
+    .card-head-body .head-stdno .stdno-fill-number:not(:last-child) {
+      border-right: 1px solid #333;
+    }
+    .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 #333;
+      line-height: 24px;
+      font-size: 16px;
+      font-weight: bold;
+      text-align: center;
+    }
+    .card-head-body .head-stdno .stdno-fill-body {
+      position: absolute;
+      top: 0;
+      bottom: 0;
+      padding-top: 51px;
+      overflow: hidden;
+      display: table;
+      width: 100%;
+    }
+    .card-head-body .head-stdno .stdno-fill-list {
+      display: table-cell;
+      width: 7.692%;
+      padding: 3px 0;
+    }
+    .card-head-body .head-stdno .stdno-fill-option {
+      margin: 8px auto;
+      width: 20px;
+      height: 14px;
+      font-size: 12px;
+      line-height: 1;
+      text-align: center;
+      color: #666;
+      border: 1px solid #333;
+    }
+    .card-head-body .head-stdno .stdno-auto-barcode {
+      height: 80px;
+      padding: 10px 0;
+      text-align: center;
+    }
+    .card-head-body .head-stdno .stdno-auto-barcode > img {
+      height: 100%;
+      width: auto;
+      display: inline-block;
+      vertical-align: top;
+    }
+    .card-head-body .head-notice > h4 {
+      font-weight: bold;
+      margin-bottom: 8px;
+    }
+    .card-head-body .head-notice-cont {
+      line-height: 1.5;
+      font-size: 12px;
+      margin-bottom: 5px;
+    }
+    .card-head-body .head-notice-cont > span {
+      display: block;
+    }
+    .card-head-body .head-notice-cont > span:first-child {
+      width: 20px;
+      float: left;
+    }
+    .card-head-body .head-notice-cont > span:last-child {
+      margin-left: 20px;
+    }
+    .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;
+      width: 133px;
+      border-right: 1px solid #000;
+    }
+    .card-head-body .head-dynamic-miss .head-dynamic-content {
+      height: 32px;
+    }
+    .card-head-body .head-dynamic-miss span {
+      display: block;
+    }
+    .card-head-body .head-dynamic-miss .dynamic-miss-title {
+      width: 32px;
+      float: left;
+    }
+    .card-head-body .head-dynamic-miss .dynamic-miss-body {
+      margin-left: 32px;
+      padding-top: 8px;
+      text-align: center;
+    }
+    .card-head-body .head-dynamic-fill {
+      display: table-cell;
+      vertical-align: middle;
+      padding: 10px;
+    }
+    .card-head-body .head-dynamic-fill p {
+      line-height: 18px;
+      word-wrap: normal;
+    }
+    .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-body .head-dynamic-fill p:first-child i {
+      width: 24px;
+      height: 14px;
+      background-color: #000;
+    }
+    .card-head-body .head-dynamic-fill 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-body .head-dynamic-fill p:last-child > i:last-child {
+      margin-right: 0;
+    }
+    .card-head-body .head-dynamic-fill 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-body .head-dynamic-fill 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 .head-dynamic-rect {
+      display: inline-block;
+      width: 30px;
+      height: 14px;
+      border: 1px solid #000;
+      font-size: 12px;
+      text-align: center;
+      line-height: 1;
+      color: #666;
+      margin: 0 5px;
+    }
+    .card-head-body .head-dynamic-aorb {
+      display: table;
+      width: 100%;
+    }
+    .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 #333;
+    }
+    .card-head-body .head-dynamic-aorb-fill .dynamic-aorb-item:first-child {
+      border: none;
+    }
+    .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;
+    }
+    .card-head-body .head-dynamic-aorb .dynamic-aorb-barcode img {
+      display: block;
+      padding: 10px 0;
+      position: relative;
+      margin: 0 auto;
+      height: 32px;
+    }
+    .card-head-body .head-dynamic-aorb .dynamic-aorb-rects {
+      padding: 10px;
+    }
+    .card-head-part {
+      border: 1px solid #333;
+    }
+    .card-head-part:not(:last-child) {
+      margin-bottom: 10px;
+    }
+    .card-head-normal .head-dynamic-1 .head-dynamic-part {
+      height: 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: 286px;
+    }
+    .card-head-body-auto-resize {
+      margin-left: -5px;
+      margin-right: -5px;
+      display: -webkit-box;
+      display: -ms-flexbox;
+      display: flex;
+    }
+    .card-head-body-auto-resize.col-item-auto-height .card-head-body-spin {
+      height: auto;
+    }
+    .card-head-body-auto-resize .head-dynamic-2 .head-dynamic-part {
+      height: auto;
+    }
+    .card-head-body-auto-resize::before {
+      display: table;
+      content: "";
+    }
+    .card-head-body-auto-resize .rect-col {
+      float: left;
+      height: 100%;
+      padding: 5px;
+    }
+    .card-head-body-auto-resize .rect-col:first-child {
+      width: 324px;
+    }
+    .card-head-body-auto-resize .rect-col:last-child {
+      width: 440px;
+    }
+    .card-head-body-auto-resize .rect-col-item {
+      border: 1px solid #333;
+    }
+    .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;
+    }
+    .elem-topic-head > h3 {
+      font-size: 16px;
+      line-height: 28px;
+      border-bottom: 1px dotted #333;
+    }
+    .elem-topic-head > p {
+      font-size: 12px;
+      line-height: 29px;
+      white-space: nowrap;
+      overflow: hidden;
+      text-overflow: ellipsis;
+    }
+    .elem-line-horizontal {
+      height: 100%;
+      line-height: 10px;
+    }
+    .elem-line-horizontal .line-body {
+      display: inline-block;
+      vertical-align: middle;
+      width: 100%;
+      border-bottom: 1px solid #000;
+    }
+    .elem-line-vertical {
+      height: 100%;
+      text-align: center;
+    }
+    .elem-line-vertical .line-body {
+      display: inline-block;
+      vertical-align: top;
+      height: 100%;
+      border-left: 1px solid #000;
+    }
+    .elem-rect .rect-body {
+      position: absolute;
+      width: 100%;
+      height: 100%;
+      top: 0;
+      left: 0;
+    }
+    .elem-text .text-body {
+      padding: 5px;
+      line-height: 1.4;
+    }
+    .elem-text .text-body span {
+      white-space: pre-wrap;
+      word-wrap: normal;
+      word-break: break-all;
+    }
+    .elem-text .text-body span.cont-variate {
+      color: #a0a0a0;
+      margin: 0 2px;
+    }
+    .elem-barcode {
+      height: 100%;
+      border-color: transparent;
+      border-width: 1pt;
+      position: relative;
+    }
+    .elem-barcode > img {
+      max-height: 100%;
+      max-width: 100%;
+      position: absolute;
+      top: 0;
+      bottom: 0;
+      left: 0;
+      right: 0;
+      margin: auto;
+    }
+    .elem-image {
+      height: 100%;
+      border-color: transparent;
+      border-width: 1pt;
+      position: relative;
+    }
+    .elem-image > p {
+      position: absolute;
+      color: #b0b0b0;
+      font-size: 30pt;
+      text-align: center;
+      left: 0;
+      width: 100%;
+      top: 50%;
+      -webkit-transform: translateY(-50%);
+      transform: translateY(-50%);
+    }
+    .elem-image > img {
+      max-height: 100%;
+      max-width: 100%;
+      position: absolute;
+      top: 0;
+      bottom: 0;
+      left: 0;
+      right: 0;
+      margin: auto;
+    }
+    .elem-fill-question {
+      white-space: normal;
+    }
+    .elem-fill-question .elem-body {
+      padding: 10px 20px;
+    }
+    .elem-fill-question .group-item {
+      display: inline-block;
+      vertical-align: top;
+      font-size: 0;
+      margin-bottom: 30px;
+    }
+    .elem-fill-question .question-item {
+      font-size: 0;
+    }
+    .elem-fill-question .question-item:last-child {
+      margin-bottom: 0 !important;
+    }
+    .elem-fill-question .option-item {
+      display: inline-block;
+      vertical-align: middle;
+      padding: 0;
+      width: 24px;
+      height: 14px;
+      text-align: center;
+      font-size: 12px;
+      line-height: 1;
+      border: 1px solid #000;
+      color: #666;
+      -webkit-box-sizing: border-box;
+      box-sizing: border-box;
+    }
+    .elem-fill-question .option-item:first-child {
+      text-align: right;
+      border-color: transparent;
+      font-size: 12px;
+      margin-right: 20px !important;
+      color: #000;
+    }
+    .elem-fill-question .option-item:last-child {
+      margin-right: 0 !important;
+    }
+    .elem-fill-question-vertical .question-item {
+      display: inline-block;
+      vertical-align: top;
+    }
+    .elem-fill-question-vertical .question-item:last-child {
+      margin-right: 0 !important;
+    }
+    .elem-fill-question-vertical .option-item {
+      display: block;
+    }
+    .elem-fill-question-vertical .option-item:first-child {
+      padding: 0;
+      text-align: center;
+    }
+    .elem-fill-question-vertical .option-item:last-child {
+      margin-bottom: 0 !important;
+    }
+    .elem-fill-area .option-item {
+      display: inline-block;
+      vertical-align: middle;
+      width: 30px;
+      height: 16px;
+      border: 1px solid #000;
+    }
+    .elem-fill-area .option-item:last-child {
+      margin-right: 0 !important;
+    }
+    .elem-fill-area-vertical .option-item {
+      display: block;
+    }
+    .elem-fill-area-vertical .option-item:last-child {
+      margin-bottom: 0 !important;
+    }
+    .elem-fill-line {
+      white-space: normal;
+    }
+    .elem-fill-line .elem-title {
+      padding-bottom: 0;
+    }
+    .elem-fill-line .elem-body {
+      padding-bottom: 30px;
+      font-size: 0;
+    }
+    .elem-fill-line .elem-fill-quesiton {
+      display: inline-block;
+      vertical-align: top;
+      position: relative;
+      padding: 0 5px;
+      font-size: 12px;
+    }
+    .elem-fill-line .elem-fill-quesiton li {
+      height: 50px;
+      border-bottom: 1px solid #000;
+      position: relative;
+      z-index: 8;
+    }
+    .elem-fill-line .elem-fill-quesiton > li:first-child {
+      position: absolute;
+      height: 100%;
+      background-color: #fff;
+      top: 0;
+      left: 5px;
+      z-index: 9;
+      padding-top: 30px;
+      border: none;
+    }
+    .elem-explain-children .elem-title {
+      padding-bottom: 0;
+    }
+    .elem-explain-children .elem-body {
+      min-height: 60px;
+      position: relative;
+    }
+    .elem-explain-children .elem-explain-no {
+      position: absolute;
+      left: 20px;
+      top: 10px;
+      font-size: 12px;
+      z-index: 9;
+    }
+    .elem-explain-children .elem-explain-elements {
+      position: absolute;
+      width: 100%;
+      height: 100%;
+      top: 0;
+      left: 0;
+      z-index: 8;
+    }
+    .elem-explain-children .explain-children-element .explain-element {
+      position: absolute;
+    }
+    .elem-composition .elem-body {
+      padding: 0;
+    }
+    .elem-composition-lines {
+      padding: 10px;
+    }
+    .elem-composition-lines li {
+      height: 50px;
+      border-bottom: 1px solid #000;
+    }
+    .elem-composition-elements {
+      padding: 5px 0;
+    }
+    .elem-composition .composition-element-item {
+      position: relative;
+    }
+  </style>
+  <body>
+    <div class="card-preview card-print">
+      <div class="preview-body">
+        <div class="page-box page-box-0">
+          <div class="page-locators page-locators-3">
+            <ul class="page-locator-group">
+              <li id="locator-0-00"></li>
+              <li id="locator-0-01"></li>
+            </ul>
+            <ul class="page-locator-group">
+              <li id="locator-0-10"></li>
+              <li id="locator-0-11"></li>
+            </ul>
+            <ul class="page-locator-group">
+              <li id="locator-0-20"></li>
+              <li id="locator-0-21"></li>
+            </ul>
+          </div>
+          <div class="page-main-inner">
+            <div class="page-main page-main-2" style="margin: 0px -10px;">
+              <div class="page-column" style="padding: 0px 10px;">
+                <div id="column-0-0" class="page-column-main">
+                  <div class="page-column-body">
+                    <div class="topic-element page-column-element">
+                      <div
+                        id="element-elm1ogleju81fgio"
+                        data-type="CARD_HEAD"
+                        class="topic-preview element-item element-item-card-head"
+                        style="left: 0px; top: 0px; width: 704px; height: 393px;"
+                      >
+                        <div class="page-element card-head card-head-normal">
+                          <div class="card-head-top">
+                            <h1 class="card-head-title">华中师范大学</h1>
+                            <div class="card-head-subtitle"><p>dgsdfg</p></div>
+                          </div>
+                          <div class="card-head-body">
+                            <div class="grid-container">
+                              <div class="grid-row">
+                                <div class="grid-col grid-col-dash">
+                                  <div class="head-stdno card-head-body-spin">
+                                    <!---->
+                                    <div class="stdno-auto">
+                                      <div class="stdno-auto-barcode">
+                                        <img src="${examNumber}" />
+                                      </div>
+                                    </div>
+                                    <!---->
+                                  </div>
+                                </div>
+                                <div class="grid-col">
+                                  <div class="head-stdinfo card-head-body-spin">
+                                    <div class="stdinfo-item">
+                                      <span>学号</span><span>:</span
+                                      ><span>${studentCode}</span>
+                                    </div>
+                                    <div class="stdinfo-item">
+                                      <span>姓名</span><span>:</span
+                                      ><span>${name}</span>
+                                    </div>
+                                    <div class="stdinfo-item">
+                                      <span>科目名称</span><span>:</span
+                                      ><span>${courseName}</span>
+                                    </div>
+                                    <div class="stdinfo-item">
+                                      <span>教学班级</span><span>:</span
+                                      ><span>${classNo}</span>
+                                    </div>
+                                    <div class="stdinfo-item">
+                                      <span>考场</span><span>:</span
+                                      ><span>${examRoom}</span>
+                                    </div>
+                                  </div>
+                                </div>
+                              </div>
+                              <div class="grid-row">
+                                <div class="grid-col">
+                                  <div class="head-notice card-head-body-spin">
+                                    <h4>注意事项:</h4>
+                                    <div class="head-notice-cont">
+                                      <span>1、</span><span>123</span>
+                                    </div>
+                                    <div class="head-notice-cont">
+                                      <span>2、</span><span>dfgsd</span>
+                                    </div>
+                                  </div>
+                                </div>
+                                <div class="grid-col">
+                                  <div
+                                    class="head-dynamic card-head-body-spin head-dynamic-1"
+                                    style="height: 86px;"
+                                  >
+                                    <div
+                                      class="head-dynamic-part head-dynamic-write"
+                                    >
+                                      <div class="stdinfo-item">
+                                        <span>手写签名</span><span>:</span
+                                        ><span></span>
+                                      </div>
+                                      <p>
+                                        注意:签名则表示您认可答题卡提供的信息与您本人信息相符;如签名与信息不符或者未签名,试卷作废。
+                                      </p>
+                                    </div>
+                                    <!----><!---->
+                                  </div>
+                                </div>
+                              </div>
+                            </div>
+                          </div>
+                          <!---->
+                        </div>
+                      </div>
+                    </div>
+                    <div class="topic-element page-column-element">
+                      <div
+                        id="element-bl4v53r82iff6l1e"
+                        data-type="TOPIC_HEAD"
+                        class="topic-preview element-item element-item-topic-head"
+                        style="left: 0px; top: 0px; width: 0px; height: 60px;"
+                      >
+                        <div class="page-element elem-topic-head" preview="">
+                          <h3>客观题答题区</h3>
+                          <p>无2342</p>
+                        </div>
+                      </div>
+                    </div>
+                    <div class="topic-element page-column-element">
+                      <div
+                        id="element-kka5pun859s17gug"
+                        data-type="FILL_QUESTION"
+                        class="topic-preview element-item element-item-fill-question"
+                        style="left: 0px; top: 0px; width: 704px; height: 230px;"
+                      >
+                        <div
+                          class="elem-fill-question elem-fill-question-horizontal"
+                          preview=""
+                        >
+                          <div class="elem-title">123</div>
+                          <div class="elem-body">
+                            <ul class="group-item" style="margin-right: 80px;">
+                              <li
+                                class="question-item"
+                                style="margin-bottom: 10px;"
+                              >
+                                <i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >1</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >A</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >B</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >C</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >D</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >E</i
+                                >
+                              </li>
+                              <li
+                                class="question-item"
+                                style="margin-bottom: 10px;"
+                              >
+                                <i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >2</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >A</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >B</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >C</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >D</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >E</i
+                                >
+                              </li>
+                              <li
+                                class="question-item"
+                                style="margin-bottom: 10px;"
+                              >
+                                <i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >3</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >A</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >B</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >C</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >D</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >E</i
+                                >
+                              </li>
+                              <li
+                                class="question-item"
+                                style="margin-bottom: 10px;"
+                              >
+                                <i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >4</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >A</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >B</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >C</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >D</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >E</i
+                                >
+                              </li>
+                              <li
+                                class="question-item"
+                                style="margin-bottom: 10px;"
+                              >
+                                <i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >5</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >A</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >B</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >C</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >D</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >E</i
+                                >
+                              </li>
+                            </ul>
+                            <ul class="group-item" style="margin-right: 80px;">
+                              <li
+                                class="question-item"
+                                style="margin-bottom: 10px;"
+                              >
+                                <i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >6</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >A</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >B</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >C</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >D</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >E</i
+                                >
+                              </li>
+                              <li
+                                class="question-item"
+                                style="margin-bottom: 10px;"
+                              >
+                                <i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >7</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >A</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >B</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >C</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >D</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >E</i
+                                >
+                              </li>
+                              <li
+                                class="question-item"
+                                style="margin-bottom: 10px;"
+                              >
+                                <i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >8</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >A</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >B</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >C</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >D</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >E</i
+                                >
+                              </li>
+                              <li
+                                class="question-item"
+                                style="margin-bottom: 10px;"
+                              >
+                                <i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >9</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >A</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >B</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >C</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >D</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >E</i
+                                >
+                              </li>
+                              <li
+                                class="question-item"
+                                style="margin-bottom: 10px;"
+                              >
+                                <i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >10</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >A</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >B</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >C</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >D</i
+                                ><i
+                                  class="option-item"
+                                  style="margin-right: 10px;"
+                                  >E</i
+                                >
+                              </li>
+                            </ul>
+                          </div>
+                        </div>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+              <div class="page-column" style="padding: 0px 10px;">
+                <div id="column-0-1" class="page-column-main">
+                  <div class="page-column-body">
+                    <div class="topic-element page-column-element">
+                      <div
+                        id="element-40dd5f08vncf4t7o"
+                        data-type="TOPIC_HEAD"
+                        class="topic-preview element-item element-item-topic-head"
+                        style="left: 0px; top: 0px; width: 0px; height: 60px;"
+                      >
+                        <div class="page-element elem-topic-head" preview="">
+                          <h3>主观题答题区</h3>
+                          <p>无</p>
+                        </div>
+                      </div>
+                    </div>
+                    <div class="topic-element page-column-element">
+                      <div
+                        id="element-gogev9v803shjg7o"
+                        data-type="FILL_LINE"
+                        class="topic-preview element-item element-item-fill-line"
+                        style="left: 0px; top: 0px; width: 704px; height: 180px;"
+                      >
+                        <div class="elem-fill-line" preview="">
+                          <div class="elem-title">123</div>
+                          <div class="elem-body">
+                            <ul class="elem-fill-quesiton" style="width: 50%;">
+                              <li class="elem-fill-no">
+                                1、
+                              </li>
+                              <li></li>
+                            </ul>
+                            <ul class="elem-fill-quesiton" style="width: 50%;">
+                              <li class="elem-fill-no">
+                                2、
+                              </li>
+                              <li></li>
+                            </ul>
+                            <ul class="elem-fill-quesiton" style="width: 50%;">
+                              <li class="elem-fill-no">
+                                3、
+                              </li>
+                              <li></li>
+                            </ul>
+                            <ul class="elem-fill-quesiton" style="width: 50%;">
+                              <li class="elem-fill-no">
+                                4、
+                              </li>
+                              <li></li>
+                            </ul>
+                          </div>
+                        </div>
+                      </div>
+                    </div>
+                    <div class="topic-element page-column-element">
+                      <div
+                        id="element-p1uu2hsmetdaf2r8"
+                        data-type="EXPLAIN_CHILDREN"
+                        class="topic-preview element-item element-item-explain-children"
+                        style="left: 0px; top: 0px; width: 704px; height: 425px;"
+                      >
+                        <div class="elem-explain-children" preview="">
+                          <div class="elem-title">
+                            12321312
+                          </div>
+                          <div class="elem-body" style="height: 395px;">
+                            <div class="elem-explain-no">1、</div>
+                            <div class="elem-explain-elements"></div>
+                          </div>
+                        </div>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+          <div class="page-main-outer"></div>
+        </div>
+        <div class="page-box page-box-1">
+          <div class="page-locators page-locators-3">
+            <ul class="page-locator-group">
+              <li id="locator-1-00"></li>
+              <li id="locator-1-01"></li>
+            </ul>
+            <ul class="page-locator-group">
+              <li id="locator-1-10"></li>
+              <li id="locator-1-11"></li>
+            </ul>
+            <ul class="page-locator-group">
+              <li id="locator-1-20"></li>
+              <li id="locator-1-21"></li>
+            </ul>
+          </div>
+          <div class="page-main-inner">
+            <div class="page-main page-main-2" style="margin: 0px -10px;">
+              <div class="page-column" style="padding: 0px 10px;">
+                <div id="column-1-0" class="page-column-main">
+                  <div class="page-column-body">
+                    <div class="page-column-forbid-area">
+                      <p>该区域严禁作答</p>
+                    </div>
+                  </div>
+                </div>
+              </div>
+              <div class="page-column" style="padding: 0px 10px;">
+                <div id="column-1-1" class="page-column-main">
+                  <div class="page-column-body">
+                    <div class="page-column-forbid-area">
+                      <p>该区域严禁作答</p>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+          <div class="page-main-outer"></div>
+        </div>
+      </div>
+    </div>
+  </body>
+</html>

+ 13 - 2
src/assets/styles/card-design.scss

@@ -176,7 +176,7 @@
 
   .control-right {
     float: right;
-    width: 300px;
+    width: 400px;
     line-height: 40px;
     text-align: right;
 
@@ -186,7 +186,7 @@
     }
   }
   .control-left {
-    margin-right: 310px;
+    margin-right: 410px;
     white-space: nowrap;
     overflow-y: hidden;
     overflow-x: auto;
@@ -429,3 +429,14 @@
   padding: 0;
   min-width: 0;
 }
+
+// design-preview-frame
+.design-preview-frame {
+  position: absolute;
+  width: 1000px;
+  height: 600px;
+  left: -9999px;
+  top: 0;
+  z-index: 1001;
+  visibility: hidden;
+}

+ 1 - 0
src/assets/styles/card-preview.scss

@@ -933,6 +933,7 @@
   }
   .elem-body {
     padding-bottom: 30px;
+    font-size: 0;
   }
   .elem-fill-quesiton {
     display: inline-block;

+ 2 - 2
src/assets/styles/element-ui-costom.scss

@@ -124,12 +124,12 @@
   }
 }
 .el-button--default {
-  color: $--color-text-secondary;
+  color: $--color-text-regular;
   background: $--color-background;
   border: 1px solid $--color-border;
   &:hover,
   &:focus {
-    color: $--color-text-secondary;
+    color: $--color-text-regular;
     background: $--color-white;
     border: 1px solid $--color-border;
   }

+ 19 - 13
src/components/UploadButton.vue

@@ -4,15 +4,15 @@
     :headers="headers"
     :max-size="maxSize"
     :format="format"
-    :data="uploadData"
+    :data="uploadDataDict"
     :before-upload="handleBeforeUpload"
     :on-error="handleError"
     :on-success="handleSuccess"
+    :http-request="upload"
     :show-file-list="false"
     style="display:inline-block;margin: 0 18px;"
     ref="UploadComp"
   >
-    <!-- <slot></slot> -->
     <el-button :type="btnType" :icon="btnIcon" :loading="loading">{{
       btnContent
     }}</el-button>
@@ -21,6 +21,7 @@
 
 <script>
 import { fileMD5 } from "../plugins/md5";
+import ajax from "@/plugins/ajax";
 
 export default {
   name: "import-file",
@@ -62,15 +63,13 @@ export default {
   },
   data() {
     return {
-      headers: {},
+      headers: {
+        token: this.$ls.get("token"),
+        md5: ""
+      },
       res: {},
-      loading: false
-    };
-  },
-  created() {
-    this.headers = {
-      token: this.$ls.get("token"),
-      md5: ""
+      loading: false,
+      uploadDataDict: {}
     };
   },
   methods: {
@@ -84,8 +83,12 @@ export default {
       );
     },
     async handleBeforeUpload(file) {
-      if (this.addFilenameParam)
-        this.uploadData[this.addFilenameParam] = file.name;
+      this.uploadDataDict = {
+        ...this.uploadData,
+        schoolId: this.$ls.get("schoolId"),
+        userId: this.$ls.get("user", { id: "" }).id
+      };
+      this.uploadDataDict[this.addFilenameParam] = file.name;
 
       if (file.size > this.maxSize) {
         this.handleExceededSize();
@@ -103,6 +106,9 @@ export default {
 
       return true;
     },
+    upload(options) {
+      return ajax(options);
+    },
     handleError(error) {
       this.loading = false;
       this.res = {
@@ -133,7 +139,7 @@ export default {
     },
     handleExceededSize() {
       const content =
-        "文件大小不能超过" + Math.floor(this.maxSize / 1024) + "M";
+        "文件大小不能超过" + Math.floor(this.maxSize / (1024 * 1024)) + "M";
       this.res = {
         success: false,
         msg: content

+ 12 - 22
src/constants/enumerate.js

@@ -25,27 +25,6 @@ export const AUDITING_STATUS = {
   1: "已审核"
 };
 
-export const EXAM_NUMBER_STYLE = {
-  0: "印刷条码",
-  1: "粘贴条码",
-  2: "卡号填涂"
-};
-export const EXAM_NUMBER_STYLE_MAP = {
-  0: "auto",
-  1: "empty",
-  2: "fill"
-};
-
-export const PAPER_TYPE = {
-  0: "印刷",
-  1: "填涂"
-};
-
-export const PAPER_TYPE_MAP = {
-  0: "auto",
-  1: "fill"
-};
-
 export const CARD_BUSINESS_FIELDS = {
   must: [
     {
@@ -80,6 +59,17 @@ export const RESERVE_TYPE = {
 
 export const CARD_SOURCE_TYPE = {
   0: "选择已有答题卡",
-  1: "自创建",
+  1: "自创建",
   2: "申请客服制卡"
 };
+
+export const EXAM_NUMBER_STYLE = {
+  0: "印刷条码",
+  1: "粘贴条码",
+  2: "卡号填涂"
+};
+
+export const PAPER_TYPE = {
+  0: "印刷",
+  1: "填涂"
+};

+ 2 - 6
src/main.js

@@ -6,6 +6,7 @@ import router from "./router";
 import store from "./store";
 import globalVuePlugins from "./plugins/globalVuePlugins";
 import GLOBAL from "./config";
+import { jsonBigNumberToString } from "./plugins/utils";
 
 // https://github.com/RobinCK/vue-ls
 import VueLocalStorage from "vue-ls";
@@ -53,12 +54,7 @@ var queue = [];
 // 解决js处理超过16位number时精度丢失的问题
 axios.defaults.transformResponse = [
   data => {
-    return JSON.parse(
-      data
-        .replace(/([0-9]{16,19})/g, '"$1"')
-        .replace(/\\""/g, '\\"')
-        .replace(/"\\"/g, '\\"')
-    );
+    return JSON.parse(jsonBigNumberToString(data));
   }
 ];
 axios.interceptors.request.use(

+ 2 - 2
src/modules/base/components/RuleCard.vue

@@ -153,8 +153,8 @@ export default {
   },
   methods: {
     async getCardRule() {
-      const data = await cardRuleDetail(this.$ls.get("schoolId"));
-      this.modalForm = Object.assign(this.modalForm, data[0]);
+      const data = await cardRuleDetail();
+      this.modalForm = Object.assign(this.modalForm, data);
       this.modalForm.examNumberStyle += "";
       this.modalForm.paperType += "";
       this.modalForm.examAbsent = Boolean(this.modalForm.examAbsent);

+ 9 - 4
src/modules/card/api.js

@@ -1,8 +1,5 @@
 import { $get, $post } from "@/plugins/axios";
 
-export const cardDetail = id => {
-  return $get("/api/print/card/card/detailEdit", id);
-};
 export const cardConfigInfos = () => {
   return $get("/api/print/basic/cardRule/selectBySchoolId", {});
   // return Promise.resolve({
@@ -41,10 +38,18 @@ export const cardConfigInfos = () => {
   //     "注意:必须使用黑色字迹签字笔书写;在答题区内作答,超出以下黑色矩形边框限定区域的答案无效。"
   // });
 };
-
+export const cardDetailEdit = cardId => {
+  return $get("/api/print/card/card/detailEdit", { cardId });
+};
+export const cardTempDetail = cardId => {
+  return $get("/api/print/card/card/preView", { cardId });
+};
 export const saveCard = datas => {
   return $post("/api/print/card/card/add", datas);
 };
+export const submitCard = datas => {
+  return $post("/api/print/card/submit", datas);
+};
 
 export const cardStudentInfo = ({ cardId, studentNo }) => {
   return $get("/backend/sysuser/resetPwd", { cardId, studentNo });

+ 15 - 23
src/modules/card/components/SavePage.vue

@@ -6,17 +6,11 @@
 
 <script>
 import { mapState } from "vuex";
-import { APP_VERSION } from "../enumerate";
+import { CARD_VERSION } from "../enumerate";
 import { deepCopy } from "@/plugins/utils";
-import { saveCard } from "../api";
 
 export default {
   name: "save-page",
-  props: {
-    cardId: {
-      type: String
-    }
-  },
   data() {
     return {
       fillAreaIndex: 0,
@@ -310,29 +304,27 @@ export default {
       const pw = parentNode.offsetWidth;
       const ph = parentNode.offsetHeight;
 
-      return [
+      const infos = [
         offsetLeft / pw,
         offsetTop / ph,
         dom.offsetWidth / pw,
         dom.offsetHeight / ph
       ];
+
+      return infos.map(num => num.toFixed(10) * 1);
     },
-    async save() {
-      return await saveCard({
-        id: this.cardId,
-        template: JSON.stringify(
-          {
-            version: APP_VERSION,
-            cardConfig: this.cardConfig,
-            pages: this.parsePageExchange()
-          },
-          (k, v) => (k.startsWith("_") ? undefined : v)
-        )
-      });
+    getPageModel() {
+      return JSON.stringify(
+        {
+          version: CARD_VERSION,
+          cardConfig: this.cardConfig,
+          pages: this.parsePageExchange()
+        },
+        (k, v) => (k.startsWith("_") ? undefined : v)
+      );
     },
-    async toSave() {
-      const card = await this.save();
-      this.$emit("saved", card.id);
+    save() {
+      this.$emit("confirm");
     }
   }
 };

+ 2 - 2
src/modules/card/components/elementEdit/cardHeadSpin/HeadDynamic.vue

@@ -74,8 +74,8 @@
         v-if="data.aOrBType === 'auto'"
       >
         <div class="dynamic-aorb-content" id="dynamic-aorb-barcode">
-          <img :src="aorbBarcodeSrc" alt="条形码" v-if="aorbBarcodeSrc" />
-          <img src="@/assets/images/barcode-sample.png" alt="条形码" v-else />
+          <img :src="aorbBarcodeSrc" v-if="aorbBarcodeSrc" />
+          <img src="@/assets/images/barcode-sample.png" v-else />
         </div>
       </div>
     </div>

+ 2 - 6
src/modules/card/components/elementEdit/cardHeadSpin/HeadStdno.vue

@@ -5,12 +5,8 @@
     </div>
     <div class="stdno-auto" v-if="data.examNumberStyle === 'auto'">
       <div class="stdno-auto-barcode">
-        <img
-          :src="examNumberBarcodeSrc"
-          alt="条形码"
-          v-if="examNumberBarcodeSrc"
-        />
-        <img src="@/assets/images/barcode-sample.png" alt="条形码" v-else />
+        <img :src="examNumberBarcodeSrc" v-if="examNumberBarcodeSrc" />
+        <img src="@/assets/images/barcode-sample.png" v-else />
       </div>
     </div>
     <div class="stdno-fill" v-if="data.examNumberStyle === 'fill'">

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

@@ -1 +1,56 @@
-export const APP_VERSION = "1.0.0";
+export const CARD_VERSION = "1.0.0";
+
+export const EXAM_NUMBER_STYLE = {
+  0: "印刷条码",
+  1: "粘贴条码",
+  2: "卡号填涂"
+};
+export const EXAM_NUMBER_STYLE_MAP = {
+  0: "auto",
+  1: "empty",
+  2: "fill"
+};
+
+export const PAPER_TYPE = {
+  0: "印刷",
+  1: "填涂"
+};
+
+export const PAPER_TYPE_MAP = {
+  0: "auto",
+  1: "fill"
+};
+
+export const transformField = data => {
+  const businessParams = [
+    ...JSON.parse(data.examMustColumn),
+    ...JSON.parse(data.examExtendColumn)
+  ]
+    .filter(item => item.select)
+    .map(item => {
+      return {
+        name: item.name,
+        field: item.code
+      };
+    });
+
+  const config = {
+    missAndFill: !!data.examAbsent,
+    writeSign: !!data.writeSign,
+    examNumberStyle: EXAM_NUMBER_STYLE_MAP[data.examNumberStyle], // auto:自动条码, empty:手动条码, fill:手动涂填
+    // aOrBSystem: true, // 后台附带的aOrB设置,如果有则使用这个值,如果没有则前台自动设置
+    aOrBType: PAPER_TYPE_MAP[data.paperType], // fill:手动涂填,auto:自动条码
+    schoolName: data.schoolName,
+    businessParams,
+    noticeHead: data.attention.split("\n") || [],
+    objectiveNotice: data.objectiveAttention,
+    subjectiveNotice: data.subjectiveAttention
+  };
+  return config;
+};
+
+export const getAOrBSystem = data => {
+  return data.enablePaperType
+    ? data.enablePaperType.split(",").length > 1
+    : null;
+};

+ 1191 - 0
src/modules/card/previewTemp.js

@@ -0,0 +1,1191 @@
+const css =
+  '\
+  body,\
+  div,\
+  ul,\
+  ol,\
+  li,\
+  h1,\
+  h2,\
+  h3,\
+  h4,\
+  h5,\
+  h6,\
+  input,\
+  p,\
+  tr,\
+  th,\
+  td,\
+  span,\
+  a,\
+  header,\
+  footer,\
+  i {\
+    margin: 0;\
+    padding: 0;\
+    -webkit-box-sizing: border-box;\
+    box-sizing: border-box;\
+    -webkit-tap-highlight-color: rgba(255, 255, 255, 0);\
+  }\
+\
+  li {\
+    list-style: none;\
+  }\
+\
+  em,\
+  i,\
+  u {\
+    font-style: normal;\
+  }\
+  button {\
+    font-family: "Helvetica Neue", Helvetica, "PingFang SC",\
+      "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;\
+  }\
+\
+  h1,\
+  h2,\
+  h3,\
+  h4,\
+  h5,\
+  h6 {\
+    font-size: 100%;\
+  }\
+\
+  fieldset,\
+  img {\
+    border: 0;\
+  }\
+\
+  abbr {\
+    border: 0;\
+    font-variant: normal;\
+  }\
+\
+  a {\
+    text-decoration: none;\
+    color: inherit;\
+    *color: #bbbbbb;\
+  }\
+\
+  img {\
+    vertical-align: middle;\
+  }\
+\
+  body {\
+    font-family: "Helvetica Neue", Helvetica, "PingFang SC",\
+      "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;\
+    -webkit-font-smoothing: antialiased;\
+    -moz-osx-font-smoothing: grayscale;\
+    font-size: 14px;\
+    color: #545454;\
+    font-weight: bold;\
+  }\
+\
+  .color-primary {\
+    color: #23c4b9 !important;\
+  }\
+\
+  .color-success {\
+    color: #1cd0a1;\
+  }\
+\
+  .color-warning {\
+    color: #ff9f45;\
+  }\
+\
+  .color-danger {\
+    color: #fe6c69;\
+  }\
+\
+  .color-info {\
+    color: #909399;\
+  }\
+\
+  .btn--danger.el-button--text {\
+    color: #fe6c69 !important;\
+  }\
+\
+  .btn-white {\
+    background-color: #fff !important;\
+    color: #999 !important;\
+  }\
+\
+  .font-bold {\
+    font-weight: bold;\
+  }\
+\
+  .table-head-bg th {\
+    background-color: #f6f6f6;\
+    color: #545454;\
+  }\
+\
+  .btn-act {\
+    background: #1cd0a1 !important;\
+    -webkit-box-shadow: 5px 5px 4px 0px rgba(28, 208, 161, 0.3);\
+    box-shadow: 5px 5px 4px 0px rgba(28, 208, 161, 0.3);\
+    border-radius: 10px;\
+  }\
+\
+  .card-preview {\
+    padding-top: 70px;\
+    background-color: #f0f0f0;\
+  }\
+\
+  .card-preview .page-box {\
+    margin: 10px auto;\
+    -webkit-box-shadow: 0 0 4px #ddd;\
+    box-shadow: 0 0 4px #ddd;\
+  }\
+\
+  .card-preview .element-item {\
+    width: 100% !important;\
+  }\
+\
+  .card-print {\
+    padding: 0;\
+  }\
+\
+  .card-print .page-box {\
+    margin: 0 auto;\
+    -webkit-box-shadow: none;\
+    box-shadow: none;\
+    page-break-after: always;\
+  }\
+\
+  .page-box {\
+    position: relative;\
+    width: 1587px;\
+    height: 1122px;\
+    background: #fff;\
+    margin: 0 auto;\
+    font-weight: normal;\
+  }\
+\
+  .page-box .page-main {\
+    height: 100%;\
+    position: relative;\
+    white-space: nowrap;\
+    margin: 0 -10px;\
+  }\
+\
+  .page-box .page-main-3 .page-column:first-child {\
+    width: 430px;\
+  }\
+\
+  .page-box .page-main-3 .page-column:not(:first-child) {\
+    width: 508.5px;\
+  }\
+\
+  .page-box .page-main-4 .page-column:first-child {\
+    width: 430px;\
+  }\
+\
+  .page-box .page-main-4 .page-column:not(:first-child) {\
+    width: 335.5px;\
+  }\
+\
+  .page-box-1 .page-main-3 .page-column {\
+    width: 33.33% !important;\
+  }\
+\
+  .page-box-1 .page-main-4 .page-column {\
+    width: 25% !important;\
+  }\
+\
+  .page-main-inner {\
+    position: absolute;\
+    width: 100%;\
+    height: 100%;\
+    top: 0;\
+    left: 0;\
+    padding: 106px 80px;\
+    z-index: 9;\
+    font-size: 0;\
+  }\
+\
+  .page-main-outer {\
+    position: absolute;\
+    top: 0;\
+    left: 0;\
+    right: 0;\
+    bottom: 0;\
+    z-index: 8;\
+    background-color: transparent;\
+    overflow: hidden;\
+  }\
+\
+  .page-column {\
+    display: inline-block;\
+    vertical-align: middle;\
+    position: relative;\
+    height: 100%;\
+    width: 50%;\
+    font-size: 14px;\
+    padding: 0 10px;\
+  }\
+\
+  .page-column-forbid-area {\
+    position: absolute;\
+    top: 0;\
+    left: 0;\
+    bottom: 0;\
+    right: 0;\
+    z-index: 1;\
+    border: 1px solid #333;\
+    overflow: hidden;\
+    background: linear-gradient(\
+        to top right,\
+        rgba(172, 172, 172, 0) 0%,\
+        rgba(172, 172, 172, 0) calc(50% - 1px),\
+        #acacac 50%,\
+        rgba(172, 172, 172, 0) calc(50% + 1px),\
+        rgba(172, 172, 172, 0) 100%\
+      ),\
+      linear-gradient(\
+        to bottom right,\
+        rgba(172, 172, 172, 0) 0%,\
+        rgba(172, 172, 172, 0) calc(50% - 1px),\
+        #acacac 50%,\
+        rgba(172, 172, 172, 0) calc(50% + 1px),\
+        rgba(172, 172, 172, 0) 100%\
+      );\
+  }\
+\
+  .page-column-forbid-area > p {\
+    color: #333;\
+    padding: 20px;\
+    position: absolute;\
+    top: 50%;\
+    left: 50%;\
+    -webkit-transform: translate(-50%, -50%);\
+    transform: translate(-50%, -50%);\
+    font-weight: bold;\
+    font-size: 30px;\
+    color: #999;\
+    background-color: #fff;\
+  }\
+\
+  .page-column-main {\
+    position: relative;\
+    height: 100%;\
+    overflow: hidden;\
+  }\
+\
+  .page-column-main\
+    .page-column-element:nth-of-type(1)\
+    .element-item-topic-head {\
+    margin-top: 0;\
+  }\
+\
+  .page-column-body {\
+    position: absolute;\
+    top: 0;\
+    bottom: 0;\
+    left: 0;\
+    right: 0;\
+    z-index: 9;\
+  }\
+\
+  .page-column-element .element-item {\
+    position: relative;\
+    border: 1px solid #333;\
+    border-top: 0;\
+  }\
+\
+  .page-column-element .element-item-card-head {\
+    border: 0;\
+  }\
+\
+  .page-column-element .element-item-topic-head {\
+    margin-top: 10px;\
+    border-top: 1px solid #333;\
+  }\
+\
+  .page-locators {\
+    position: absolute;\
+    top: 106px;\
+    left: 80px;\
+    right: 80px;\
+    bottom: 106px;\
+    z-index: 8;\
+  }\
+\
+  .page-locators-4 .page-locator-group:nth-of-type(2) {\
+    left: 33.3%;\
+    margin-left: -4.5mm;\
+  }\
+\
+  .page-locators-4 .page-locator-group:nth-of-type(3) {\
+    left: 66.6%;\
+    margin-left: -2.3mm;\
+  }\
+\
+  .page-locators-5 .page-locator-group:nth-of-type(2) {\
+    left: 25%;\
+    margin-left: -5.1mm;\
+  }\
+\
+  .page-locators-5 .page-locator-group:nth-of-type(3) {\
+    left: 50%;\
+    margin-left: -3.4mm;\
+  }\
+\
+  .page-locators-5 .page-locator-group:nth-of-type(4) {\
+    left: 75%;\
+    margin-left: -1.8mm;\
+  }\
+\
+  .page-locator-group {\
+    position: absolute;\
+    top: 0;\
+    bottom: 0;\
+    width: 24px;\
+  }\
+\
+  .page-locator-group:first-child {\
+    left: 0;\
+  }\
+\
+  .page-locator-group:nth-of-type(2) {\
+    left: 50%;\
+    margin-left: -12px;\
+  }\
+\
+  .page-locator-group:last-child {\
+    right: 0;\
+  }\
+\
+  .page-locator-group li {\
+    position: absolute;\
+    width: 24px;\
+    border-bottom: 16px solid #000;\
+    z-index: 99;\
+  }\
+\
+  .page-locator-group li:first-child {\
+    top: -46px;\
+  }\
+\
+  .page-locator-group li:last-child {\
+    bottom: -46px;\
+  }\
+\
+  .elem-title {\
+    padding: 10px 13px 20px;\
+    font-size: 14px;\
+    font-weight: bold;\
+    color: black;\
+    line-height: 1;\
+  }\
+\
+  .elem-body {\
+    padding: 10px;\
+  }\
+\
+  .grid-container {\
+    margin-left: -10px;\
+    margin-right: -10px;\
+  }\
+\
+  .grid-row {\
+    display: table;\
+    width: 100%;\
+    border-spacing: 10px 5px;\
+    border-collapse: separate;\
+  }\
+\
+  .grid-row .grid-col {\
+    display: table-cell;\
+    width: 50%;\
+    vertical-align: top;\
+    border: 1px solid #333;\
+  }\
+\
+  .grid-row .grid-col-dash {\
+    border-style: dashed;\
+    vertical-align: middle;\
+  }\
+\
+  .card-head-top {\
+    text-align: center;\
+  }\
+\
+  .card-head-title {\
+    font-size: 36px;\
+    font-family: "宋体";\
+    font-weight: bold;\
+    line-height: 48px;\
+  }\
+\
+  .card-head-subtitle textarea,\
+  .card-head-subtitle > p {\
+    height: 55px;\
+    padding: 0 10px;\
+    font-size: 14px;\
+    font-family: "Helvetica Neue", Helvetica, "PingFang SC",\
+      "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;\
+    font-weight: bold;\
+    line-height: 20px;\
+    text-align: center;\
+    border-color: transparent;\
+    background-color: transparent;\
+    color: #000;\
+    overflow: hidden;\
+  }\
+\
+  .card-head-body {\
+    font-weight: normal;\
+  }\
+\
+  .card-head-body .el-col {\
+    padding-top: 5px;\
+    padding-bottom: 5px;\
+  }\
+\
+  .card-head-body-spin {\
+    padding: 5px 12px;\
+    white-space: normal;\
+    word-break: break-all;\
+  }\
+\
+  .card-head-body .stdinfo-item {\
+    height: 34px;\
+    line-height: 34px;\
+    position: relative;\
+    overflow: hidden;\
+  }\
+\
+  .card-head-body .stdinfo-item::after {\
+    content: "";\
+    display: block;\
+    position: absolute;\
+    width: 100%;\
+    border-bottom: 1px solid #333;\
+    bottom: 6px;\
+    left: 0;\
+    z-index: 1;\
+  }\
+\
+  .card-head-body .stdinfo-item > span {\
+    z-index: 2;\
+    display: block;\
+    position: relative;\
+    font-weight: bold;\
+    font-size: 14px;\
+  }\
+\
+  .card-head-body .stdinfo-item > span:first-child {\
+    float: left;\
+    background-color: #fff;\
+    width: 60px;\
+    text-align: justify;\
+  }\
+\
+  .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-body .stdinfo-item > span:last-child {\
+    margin-left: 80px;\
+    height: 100%;\
+    overflow: hidden;\
+  }\
+\
+  .card-head-body .head-stdno {\
+    height: 100%;\
+    padding: 0;\
+  }\
+\
+  .card-head-body .head-stdno .stdno-empty {\
+    font-weight: bold;\
+    letter-spacing: 3px;\
+  }\
+\
+  .card-head-body .head-stdno .stdno-fill {\
+    min-height: 286px;\
+    height: 100%;\
+    position: relative;\
+  }\
+\
+  .card-head-body .head-stdno .stdno-fill-rect {\
+    font-size: 0;\
+    height: 27px;\
+    border-bottom: 1px solid #333;\
+  }\
+\
+  .card-head-body .head-stdno .stdno-fill-number {\
+    display: inline-block;\
+    vertical-align: top;\
+    width: 7.692%;\
+    height: 100%;\
+  }\
+\
+  .card-head-body .head-stdno .stdno-fill-number:not(:last-child) {\
+    border-right: 1px solid #333;\
+  }\
+\
+  .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 #333;\
+    line-height: 24px;\
+    font-size: 16px;\
+    font-weight: bold;\
+    text-align: center;\
+  }\
+\
+  .card-head-body .head-stdno .stdno-fill-body {\
+    position: absolute;\
+    top: 0;\
+    bottom: 0;\
+    padding-top: 51px;\
+    overflow: hidden;\
+    display: table;\
+    width: 100%;\
+  }\
+\
+  .card-head-body .head-stdno .stdno-fill-list {\
+    display: table-cell;\
+    width: 7.692%;\
+    padding: 3px 0;\
+  }\
+\
+  .card-head-body .head-stdno .stdno-fill-option {\
+    margin: 8px auto;\
+    width: 20px;\
+    height: 14px;\
+    font-size: 12px;\
+    line-height: 1;\
+    text-align: center;\
+    color: #666;\
+    border: 1px solid #333;\
+  }\
+\
+  .card-head-body .head-stdno .stdno-auto-barcode {\
+    height: 80px;\
+    padding: 10px 0;\
+    text-align: center;\
+  }\
+\
+  .card-head-body .head-stdno .stdno-auto-barcode > img {\
+    height: 100%;\
+    width: auto;\
+    display: inline-block;\
+    vertical-align: top;\
+  }\
+\
+  .card-head-body .head-notice > h4 {\
+    font-weight: bold;\
+    margin-bottom: 8px;\
+  }\
+\
+  .card-head-body .head-notice-cont {\
+    line-height: 1.5;\
+    font-size: 12px;\
+    margin-bottom: 5px;\
+  }\
+\
+  .card-head-body .head-notice-cont > span {\
+    display: block;\
+  }\
+\
+  .card-head-body .head-notice-cont > span:first-child {\
+    width: 20px;\
+    float: left;\
+  }\
+\
+  .card-head-body .head-notice-cont > span:last-child {\
+    margin-left: 20px;\
+  }\
+\
+  .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;\
+    width: 133px;\
+    border-right: 1px solid #000;\
+  }\
+\
+  .card-head-body .head-dynamic-miss .head-dynamic-content {\
+    height: 32px;\
+  }\
+\
+  .card-head-body .head-dynamic-miss span {\
+    display: block;\
+  }\
+\
+  .card-head-body .head-dynamic-miss .dynamic-miss-title {\
+    width: 32px;\
+    float: left;\
+  }\
+\
+  .card-head-body .head-dynamic-miss .dynamic-miss-body {\
+    margin-left: 32px;\
+    padding-top: 8px;\
+    text-align: center;\
+  }\
+\
+  .card-head-body .head-dynamic-fill {\
+    display: table-cell;\
+    vertical-align: middle;\
+    padding: 10px;\
+  }\
+\
+  .card-head-body .head-dynamic-fill p {\
+    line-height: 18px;\
+    word-wrap: normal;\
+  }\
+\
+  .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-body .head-dynamic-fill p:first-child i {\
+    width: 24px;\
+    height: 14px;\
+    background-color: #000;\
+  }\
+\
+  .card-head-body .head-dynamic-fill 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-body .head-dynamic-fill p:last-child > i:last-child {\
+    margin-right: 0;\
+  }\
+\
+  .card-head-body\
+    .head-dynamic-fill\
+    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-body\
+    .head-dynamic-fill\
+    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 .head-dynamic-rect {\
+    display: inline-block;\
+    width: 30px;\
+    height: 14px;\
+    border: 1px solid #000;\
+    font-size: 12px;\
+    text-align: center;\
+    line-height: 1;\
+    color: #666;\
+    margin: 0 5px;\
+  }\
+\
+  .card-head-body .head-dynamic-aorb {\
+    display: table;\
+    width: 100%;\
+  }\
+\
+  .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 #333;\
+  }\
+\
+  .card-head-body .head-dynamic-aorb-fill .dynamic-aorb-item:first-child {\
+    border: none;\
+  }\
+\
+  .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;\
+  }\
+\
+  .card-head-body .head-dynamic-aorb .dynamic-aorb-barcode img {\
+    display: block;\
+    padding: 10px 0;\
+    position: relative;\
+    margin: 0 auto;\
+    height: 32px;\
+  }\
+\
+  .card-head-body .head-dynamic-aorb .dynamic-aorb-rects {\
+    padding: 10px;\
+  }\
+\
+  .card-head-part {\
+    border: 1px solid #333;\
+  }\
+\
+  .card-head-part:not(:last-child) {\
+    margin-bottom: 10px;\
+  }\
+\
+  .card-head-normal .head-dynamic-1 .head-dynamic-part {\
+    height: 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: 286px;\
+  }\
+\
+  .card-head-body-auto-resize {\
+    margin-left: -5px;\
+    margin-right: -5px;\
+    display: -webkit-box;\
+    display: -ms-flexbox;\
+    display: flex;\
+  }\
+\
+  .card-head-body-auto-resize.col-item-auto-height .card-head-body-spin {\
+    height: auto;\
+  }\
+\
+  .card-head-body-auto-resize .head-dynamic-2 .head-dynamic-part {\
+    height: auto;\
+  }\
+\
+  .card-head-body-auto-resize::before {\
+    display: table;\
+    content: "";\
+  }\
+\
+  .card-head-body-auto-resize .rect-col {\
+    float: left;\
+    height: 100%;\
+    padding: 5px;\
+  }\
+\
+  .card-head-body-auto-resize .rect-col:first-child {\
+    width: 324px;\
+  }\
+\
+  .card-head-body-auto-resize .rect-col:last-child {\
+    width: 440px;\
+  }\
+\
+  .card-head-body-auto-resize .rect-col-item {\
+    border: 1px solid #333;\
+  }\
+\
+  .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;\
+  }\
+\
+  .elem-topic-head > h3 {\
+    font-size: 16px;\
+    line-height: 28px;\
+    border-bottom: 1px dotted #333;\
+  }\
+\
+  .elem-topic-head > p {\
+    font-size: 12px;\
+    line-height: 29px;\
+    white-space: nowrap;\
+    overflow: hidden;\
+    text-overflow: ellipsis;\
+  }\
+\
+  .elem-line-horizontal {\
+    height: 100%;\
+    line-height: 10px;\
+  }\
+\
+  .elem-line-horizontal .line-body {\
+    display: inline-block;\
+    vertical-align: middle;\
+    width: 100%;\
+    border-bottom: 1px solid #000;\
+  }\
+\
+  .elem-line-vertical {\
+    height: 100%;\
+    text-align: center;\
+  }\
+\
+  .elem-line-vertical .line-body {\
+    display: inline-block;\
+    vertical-align: top;\
+    height: 100%;\
+    border-left: 1px solid #000;\
+  }\
+\
+  .elem-rect .rect-body {\
+    position: absolute;\
+    width: 100%;\
+    height: 100%;\
+    top: 0;\
+    left: 0;\
+  }\
+\
+  .elem-text .text-body {\
+    padding: 5px;\
+    line-height: 1.4;\
+  }\
+\
+  .elem-text .text-body span {\
+    white-space: pre-wrap;\
+    word-wrap: normal;\
+    word-break: break-all;\
+  }\
+\
+  .elem-text .text-body span.cont-variate {\
+    color: #a0a0a0;\
+    margin: 0 2px;\
+  }\
+\
+  .elem-barcode {\
+    height: 100%;\
+    border-color: transparent;\
+    border-width: 1pt;\
+    position: relative;\
+  }\
+\
+  .elem-barcode > img {\
+    max-height: 100%;\
+    max-width: 100%;\
+    position: absolute;\
+    top: 0;\
+    bottom: 0;\
+    left: 0;\
+    right: 0;\
+    margin: auto;\
+  }\
+\
+  .elem-image {\
+    height: 100%;\
+    border-color: transparent;\
+    border-width: 1pt;\
+    position: relative;\
+  }\
+\
+  .elem-image > p {\
+    position: absolute;\
+    color: #b0b0b0;\
+    font-size: 30pt;\
+    text-align: center;\
+    left: 0;\
+    width: 100%;\
+    top: 50%;\
+    -webkit-transform: translateY(-50%);\
+    transform: translateY(-50%);\
+  }\
+\
+  .elem-image > img {\
+    max-height: 100%;\
+    max-width: 100%;\
+    position: absolute;\
+    top: 0;\
+    bottom: 0;\
+    left: 0;\
+    right: 0;\
+    margin: auto;\
+  }\
+\
+  .elem-fill-question {\
+    white-space: normal;\
+  }\
+\
+  .elem-fill-question .elem-body {\
+    padding: 10px 20px;\
+  }\
+\
+  .elem-fill-question .group-item {\
+    display: inline-block;\
+    vertical-align: top;\
+    font-size: 0;\
+    margin-bottom: 30px;\
+  }\
+\
+  .elem-fill-question .question-item {\
+    font-size: 0;\
+  }\
+\
+  .elem-fill-question .question-item:last-child {\
+    margin-bottom: 0 !important;\
+  }\
+\
+  .elem-fill-question .option-item {\
+    display: inline-block;\
+    vertical-align: middle;\
+    padding: 0;\
+    width: 24px;\
+    height: 14px;\
+    text-align: center;\
+    font-size: 12px;\
+    line-height: 1;\
+    border: 1px solid #000;\
+    color: #666;\
+    -webkit-box-sizing: border-box;\
+    box-sizing: border-box;\
+  }\
+\
+  .elem-fill-question .option-item:first-child {\
+    text-align: right;\
+    border-color: transparent;\
+    font-size: 12px;\
+    margin-right: 20px !important;\
+    color: #000;\
+  }\
+\
+  .elem-fill-question .option-item:last-child {\
+    margin-right: 0 !important;\
+  }\
+\
+  .elem-fill-question-vertical .question-item {\
+    display: inline-block;\
+    vertical-align: top;\
+  }\
+\
+  .elem-fill-question-vertical .question-item:last-child {\
+    margin-right: 0 !important;\
+  }\
+\
+  .elem-fill-question-vertical .option-item {\
+    display: block;\
+  }\
+\
+  .elem-fill-question-vertical .option-item:first-child {\
+    padding: 0;\
+    text-align: center;\
+  }\
+\
+  .elem-fill-question-vertical .option-item:last-child {\
+    margin-bottom: 0 !important;\
+  }\
+\
+  .elem-fill-area .option-item {\
+    display: inline-block;\
+    vertical-align: middle;\
+    width: 30px;\
+    height: 16px;\
+    border: 1px solid #000;\
+  }\
+\
+  .elem-fill-area .option-item:last-child {\
+    margin-right: 0 !important;\
+  }\
+\
+  .elem-fill-area-vertical .option-item {\
+    display: block;\
+  }\
+\
+  .elem-fill-area-vertical .option-item:last-child {\
+    margin-bottom: 0 !important;\
+  }\
+\
+  .elem-fill-line {\
+    white-space: normal;\
+  }\
+\
+  .elem-fill-line .elem-title {\
+    padding-bottom: 0;\
+  }\
+\
+  .elem-fill-line .elem-body {\
+    font-size: 0;\
+    padding-bottom: 30px;\
+  }\
+\
+  .elem-fill-line .elem-fill-quesiton {\
+    display: inline-block;\
+    vertical-align: top;\
+    position: relative;\
+    padding: 0 5px;\
+    font-size: 12px;\
+  }\
+\
+  .elem-fill-line .elem-fill-quesiton li {\
+    height: 50px;\
+    border-bottom: 1px solid #000;\
+    position: relative;\
+    z-index: 8;\
+  }\
+\
+  .elem-fill-line .elem-fill-quesiton > li:first-child {\
+    position: absolute;\
+    height: 100%;\
+    background-color: #fff;\
+    top: 0;\
+    left: 5px;\
+    z-index: 9;\
+    padding-top: 30px;\
+    border: none;\
+  }\
+\
+  .elem-explain-children .elem-title {\
+    padding-bottom: 0;\
+  }\
+\
+  .elem-explain-children .elem-body {\
+    min-height: 60px;\
+    position: relative;\
+  }\
+\
+  .elem-explain-children .elem-explain-no {\
+    position: absolute;\
+    left: 20px;\
+    top: 10px;\
+    font-size: 12px;\
+    z-index: 9;\
+  }\
+\
+  .elem-explain-children .elem-explain-elements {\
+    position: absolute;\
+    width: 100%;\
+    height: 100%;\
+    top: 0;\
+    left: 0;\
+    z-index: 8;\
+  }\
+\
+  .elem-explain-children .explain-children-element .explain-element {\
+    position: absolute;\
+  }\
+\
+  .elem-composition .elem-body {\
+    padding: 0;\
+  }\
+\
+  .elem-composition-lines {\
+    padding: 10px;\
+  }\
+\
+  .elem-composition-lines li {\
+    height: 50px;\
+    border-bottom: 1px solid #000;\
+  }\
+\
+  .elem-composition-elements {\
+    padding: 5px 0;\
+  }\
+\
+  .elem-composition .composition-element-item {\
+    position: relative;\
+  }\
+';
+
+export default domeStr => {
+  return `
+  <!DOCTYPE html>
+    <html>
+      <head>
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+        <meta name="viewport" content="width=device-width,initial-scale=1.0,
+        maximum-scale=1.0,minimum-scale=1.0, user-scalable=no" "="">
+        <meta name=" renderer" content="webkit|ie-comp|ie-stand" />
+        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
+        <title>教务处平台题卡</title>
+
+      </head>
+      <style>${css}</style>
+      <body>${domeStr}</body>
+    </html>
+  `;
+};

+ 1 - 0
src/modules/card/router.js

@@ -6,6 +6,7 @@ export default [
       import(/* webpackChunkName: "CardDesign" */ "./views/CardDesign.vue")
   },
   {
+    // viewType::: view:预览,print:打印,frame:iframe嵌套
     path: "/card/preview/:cardId/:viewType/:studentNo?",
     name: "CardPreview",
     component: () =>

+ 119 - 56
src/modules/card/views/CardDesign.vue

@@ -26,11 +26,8 @@
               :disabled="!pages.length"
               >预览</el-button
             >
-            <save-page
-              :card-id="cardId"
-              @saved="cardSaved"
-              ref="SavePage"
-            ></save-page>
+            <save-page @confirm="toSave" ref="SavePage"></save-page>
+            <el-button type="primary" @click="toSubmit">提交</el-button>
           </div>
           <div class="control-left">
             <el-button
@@ -86,9 +83,9 @@
             </div>
           </div>
           <!-- Develop btns -->
-          <card-config-prop-edit></card-config-prop-edit>
+          <!-- <card-config-prop-edit></card-config-prop-edit>
           <br /><br />
-          <el-button @click="initCard">新建页面</el-button>
+          <el-button @click="initCard">新建页面</el-button> -->
         </div>
       </div>
 
@@ -217,20 +214,31 @@
           </div>
         </template>
       </div>
+    </div>
 
-      <!-- element-prop-edit -->
-      <element-prop-edit></element-prop-edit>
-      <!-- right-click-menu -->
-      <right-click-menu></right-click-menu>
-      <!-- card-head-sample -->
-      <card-head-sample v-if="pages.length"></card-head-sample>
+    <!-- element-prop-edit -->
+    <element-prop-edit></element-prop-edit>
+    <!-- right-click-menu -->
+    <right-click-menu></right-click-menu>
+    <!-- card-head-sample -->
+    <card-head-sample v-if="pages.length"></card-head-sample>
+    <!-- card-view-frame -->
+    <div class="design-preview-frame" v-if="cardPreviewUrl">
+      <iframe :src="cardPreviewUrl" frameborder="0"></iframe>
     </div>
   </div>
 </template>
 
 <script>
 import { mapState, mapMutations, mapActions } from "vuex";
-import { cardConfigInfos } from "../api";
+import {
+  cardConfigInfos,
+  cardDetailEdit,
+  cardTempDetail,
+  saveCard,
+  submitCard
+} from "../api";
+import { saveWaitTask } from "@/modules/exam-center/api";
 import {
   getElementModel,
   getCardHeadModel,
@@ -239,9 +247,10 @@ import {
   ELEMENT_LIST,
   TOPIC_LIST
 } from "../elementModel";
+import { transformField, getAOrBSystem } from "../enumerate";
 import TopicElementEdit from "../components/TopicElementEdit";
 import PagePropEdit from "../components/PagePropEdit";
-import CardConfigPropEdit from "../components/CardConfigPropEdit";
+// import CardConfigPropEdit from "../components/CardConfigPropEdit";
 import ElementPropEdit from "../components/elementPropEdit/ElementPropEdit";
 import RightClickMenu from "../components/RightClickMenu";
 import CardHeadSample from "../components/elementEdit/CardHeadSample";
@@ -252,7 +261,7 @@ export default {
   components: {
     TopicElementEdit,
     PagePropEdit,
-    CardConfigPropEdit,
+    // CardConfigPropEdit,
     ElementPropEdit,
     RightClickMenu,
     CardHeadSample,
@@ -261,10 +270,13 @@ export default {
   data() {
     return {
       cardId: this.$route.params.cardId,
+      cardDetailId: this.$ls.get("cardDetailId"),
+      prepareTcPCard: this.$ls.get("prepareTcPCard", {}),
       ELEMENT_LIST,
       TOPIC_LIST,
       steps: ["添加标题", "基本设置", "试题配置", "试题配置"],
-      columnWidth: 0
+      columnWidth: 0,
+      cardPreviewUrl: ""
     };
   },
   computed: {
@@ -274,9 +286,8 @@ export default {
     }
   },
   mounted() {
-    // this.initCard();
-    // this.$store.commit("card/setPages", card.pages);
-    // this.$store.commit("card/setCardConfig", card.cardConfig);
+    this.initCard();
+    this.registWindowSubmit();
   },
   methods: {
     ...mapMutations("card", [
@@ -285,7 +296,8 @@ export default {
       "setCurElement",
       "setCardConfig",
       "setOpenElementEditDialog",
-      "setCurDragElement"
+      "setCurDragElement",
+      "setPages"
     ]),
     ...mapActions("card", [
       "removePage",
@@ -296,13 +308,22 @@ export default {
     ]),
     async initCard() {
       if (this.isEdit) {
-        // TODO:编辑页复现
+        this.getCardTempDetail();
       } else {
         await this.getCardConfig();
         this.initPageData();
       }
       this.addWatch();
     },
+    async getCardTempDetail() {
+      const detData = await cardDetailEdit(this.cardId);
+      const tempData = await cardTempDetail(this.cardId);
+      const cont = JSON.parse(tempData.content);
+      this.prepareTcPCard = Object.assign(this.prepareTcPCard, detData);
+      this.cardDetailId = tempData.id;
+      this.setPages(cont.pages);
+      this.setCardConfig(cont.cardConfig);
+    },
     initPageData() {
       this.addNewPage();
       this.addNewPage();
@@ -315,15 +336,19 @@ export default {
     },
     async getCardConfig() {
       const data = await cardConfigInfos();
-      this.setCardConfig({
-        ...data,
+      const aOrBSystem = getAOrBSystem(this.prepareTcPCard);
+      let config = {
+        ...transformField(data),
         pageSize: "A3",
         columnNumber: 2,
         columnGap: 20,
-        aOrB: !!data["aOrBSystem"],
         showForbidArea: true,
         cardName: ""
-      });
+      };
+      if (aOrBSystem !== null) config.aOrBSystem = aOrBSystem;
+      config.aOrB = !!config["aOrBSystem"];
+
+      this.setCardConfig(config);
     },
     addNewTopic(item) {
       let element = getTopicModel(item.type);
@@ -340,36 +365,6 @@ export default {
     dragstart(element) {
       this.setCurDragElement(getElementModel(element.type));
     },
-    // 操作
-    cardSaved(cardId) {
-      this.cardId = cardId;
-    },
-    async toPreview() {
-      this.$router.push({
-        name: "CardPreview",
-        params: {
-          cardId: 1,
-          viewType: "view"
-        }
-      });
-
-      return;
-
-      // const card = await this.$refs.SavePage.save();
-      // this.cardSaved(card.id);
-      // this.$router.push({
-      //   name: "CardPreview",
-      //   params: {
-      //     cardId: card.id,
-      //     viewType: "view"
-      //   }
-      // });
-    },
-    swithPage(pindex) {
-      if (this.curPageNo === pindex) return;
-      this.setCurPageNo(pindex);
-      this.setCurElement({});
-    },
     addWatch() {
       this.$watch("cardConfig", val => {
         const element = getCardHeadModel(val);
@@ -378,7 +373,75 @@ export default {
           this.rebuildPages();
         });
       });
+    },
+    // 操作
+    async toPreview() {
+      await this.toSave(this.$refs.SavePage.getPageModel());
+      window.open(`/#/card/preview/${this.cardId}/view`);
+    },
+    swithPage(pindex) {
+      if (this.curPageNo === pindex) return;
+      this.setCurPageNo(pindex);
+      this.setCurElement({});
+    },
+    // save
+    getCardData(contentTemp = "") {
+      const tcPCard = this.$objAssign(
+        {
+          examId: "",
+          enablePaperType: "",
+          paperAttachmentId: "",
+          courseName: "",
+          courseCode: "",
+          cardSource: "",
+          title: ""
+        },
+        { ...this.prepareTcPCard, title: this.cardConfig.cardName }
+      );
+
+      let data = {
+        tcPCard,
+        tcPCardDetail: {
+          content: this.$refs.SavePage.getPageModel()
+        }
+      };
+      if (this.cardDetailId) data.tcPCardDetail.id = this.cardDetailId;
+      if (contentTemp) data.tcPCardDetail.contentTemp = contentTemp;
+      return data;
+    },
+    async save() {
+      const result = await saveCard(this.getCardData());
+      this.cardDetailId = result.cardDetailId;
+      this.$ls.set("cardDetailId", this.cardDetailId);
+      this.cardId = result.cardId;
+    },
+    async toSave() {
+      await this.save();
+      this.$message.success("保存成功!");
+
+      // 自助创建时暂存任务
+      if (
+        this.prepareTcPCard.taskId &&
+        this.prepareTcPCard.cardSource === "1"
+      ) {
+        saveWaitTask({ ...this.prepareTcPCard, cardId: this.cardId });
+      }
+    },
+    registWindowSubmit() {
+      window.submitCardTemp = async cardContentTemp => {
+        await submitCard(this.getCardData(cardContentTemp));
+        this.$message.success("提交成功!");
+        this.cardPreviewUrl = "";
+      };
+    },
+    async toSubmit() {
+      await this.save();
+      this.cardPreviewUrl = `/#/card/preview/${this.cardId}/frame`;
     }
+  },
+  beforeDestroy() {
+    this.$ls.remove("cardDetailId");
+    this.$ls.remove("prepareTcPCard");
   }
 };
 </script>

+ 31 - 10
src/modules/card/views/CardPreview.vue

@@ -64,7 +64,8 @@
 
 <script>
 import TopicElementPreview from "../components/TopicElementPreview";
-import { cardDetail, cardStudentInfo } from "../api";
+import { cardTempDetail, cardStudentInfo } from "../api";
+import previewTemp from "../previewTemp";
 const JsBarcode = require("jsbarcode");
 
 export default {
@@ -72,7 +73,8 @@ export default {
   components: { TopicElementPreview },
   data() {
     return {
-      isPrint: this.$route.params.viewType === "print",
+      isPrint: this.$route.params.viewType !== "view",
+      isFrame: this.$route.params.viewType === "frame",
       studentNo: this.$route.params.studentNo,
       cardId: this.$route.params.cardId,
       cardConfig: {},
@@ -90,19 +92,38 @@ export default {
     }
   },
   mounted() {
-    this.init();
+    if (this.isFrame) {
+      this.initFrame();
+    } else {
+      this.init();
+    }
   },
   methods: {
-    async init() {
-      let pages = this.$store.state.card.pages;
-      let cardConfig = this.$store.state.card.cardConfig;
-      const fieldInfos = await this.fetchFieldInfos(cardConfig, {});
+    async initFrame() {
+      const card = await cardTempDetail(this.cardId);
+      const { cardConfig, pages } = JSON.parse(card.content);
+      let fieldInfos = {};
+      cardConfig.businessParams.map(item => {
+        fieldInfos[item.field] = "${" + item.field + "}";
+      });
+      if (cardConfig.examNumberStyle === "auto")
+        fieldInfos.examNumber = "data:image/png;base64,${examNumber}";
+
+      if (cardConfig.aOrB && cardConfig.aOrBType === "auto")
+        fieldInfos.paperType = "data:image/png;base64,${paperType}";
 
       this.cardConfig = cardConfig;
       this.pages = this.appendFieldInfo(pages, fieldInfos);
+
+      this.$nextTick(() => {
+        const cardContentTemp = previewTemp(this.$el.outerHTML);
+        window.parent &&
+          window.parent.submitCardTemp &&
+          window.parent.submitCardTemp(cardContentTemp);
+      });
     },
-    async init1() {
-      const card = await cardDetail(this.cardId);
+    async init() {
+      const card = await cardTempDetail(this.cardId);
       let stdInfo = {};
       if (this.studentNo) {
         stdInfo = await cardStudentInfo({
@@ -110,7 +131,7 @@ export default {
           studentNo: this.studentNo
         });
       }
-      const { cardConfig, pages } = JSON.parse(card.template);
+      const { cardConfig, pages } = JSON.parse(card.content);
       const fieldInfos = this.fetchFieldInfos(cardConfig, stdInfo);
 
       this.cardConfig = cardConfig;

+ 9 - 3
src/modules/exam-center/api.js

@@ -71,12 +71,18 @@ export const cardList = datas => {
 export const cardListPage = datas => {
   return $get("/api/print/card/card/listPage", datas);
 };
-export const CopyCard = cardId => {
+export const createCard = datas => {
+  return $post("/api/print/card/card/add", datas);
+};
+export const copyCard = cardId => {
   return $post("/api/print/card/card/copy", { cardId });
 };
 export const deleteCard = cardId => {
   return $post("/api/print/card/card/delete", { cardId });
 };
+export const courseByUser = () => {
+  return $get("/api/print/card/card/listCourseByUserId", {});
+};
 
 // print-manage
 export const printTaskListPage = datas => {
@@ -84,8 +90,8 @@ export const printTaskListPage = datas => {
 };
 
 // card-audit
-export const createCardAudit = (datas, headers) => {
-  return $post("/api/print/exam/exam/listPrintPage", datas, { headers });
+export const auditListPage = datas => {
+  return $get("/api/print/card/card/listAuditPage", datas);
 };
 
 // custom upload-file

+ 83 - 16
src/modules/exam-center/components/CardOptionDialog.vue

@@ -20,10 +20,10 @@
         <div class="card-type">
           <el-radio-group v-model="modalForm.cardSource">
             <el-radio
-              v-for="(val, key) in CARD_SOURCE_TYPE"
-              :key="key"
-              :label="key"
-              >{{ val }}</el-radio
+              v-for="item in cardSourceTypes"
+              :key="item.type"
+              :label="item.type"
+              >{{ item.name }}</el-radio
             >
           </el-radio-group>
         </div>
@@ -44,15 +44,32 @@
           </el-select>
           <span class="card-view" @click="toPreview">预览</span>
         </div>
+        <div class="card-select" v-if="modalForm.cardSource !== '0' && noExam">
+          <el-select
+            v-model="modalForm.courseCode"
+            style="width: 193px;"
+            placeholder="请选择科目"
+            @change="cousreChange"
+          >
+            <el-option
+              v-for="item in courses"
+              :key="item.courseCode"
+              :value="item.courseCode"
+              :label="item.courseName"
+            ></el-option>
+          </el-select>
+        </div>
       </div>
       <div slot="footer" style="text-align: right;">
-        <el-button type="primary" @click="confirm">保存</el-button>
+        <el-button type="primary" @click="confirm">确定</el-button>
         <el-button @click="cancel">返回</el-button>
       </div>
     </el-dialog>
 
     <!-- upload-sample-paper-dialog -->
     <upload-sample-paper-dialog
+      @confirm="cancel"
+      :data="modalForm"
       ref="UploadSamplePaperDialog"
     ></upload-sample-paper-dialog>
   </div>
@@ -60,18 +77,17 @@
 
 <script>
 import { CARD_SOURCE_TYPE } from "@/constants/enumerate";
-import { cardList } from "../api";
+import { cardList, courseByUser } from "../api";
 import UploadSamplePaperDialog from "./UploadSamplePaperDialog";
 
 export default {
   name: "card-option-dialog-view",
   props: {
     data: {
-      type: Object
-    },
-    noExam: {
-      type: Boolean,
-      default: false
+      type: Object,
+      default() {
+        return {};
+      }
     }
   },
   components: { UploadSamplePaperDialog },
@@ -79,20 +95,66 @@ export default {
     return {
       modalIsShow: false,
       modalForm: {
+        taskId: "",
+        examId: "",
+        enablePaperType: "",
+        paperAttachmentId: "",
+        courseName: "",
+        courseCode: "",
         cardSource: "",
         refCardId: ""
       },
       cards: [],
+      courses: [],
+      cardSourceTypes: [],
       CARD_SOURCE_TYPE
     };
   },
+  computed: {
+    noExam() {
+      return !this.data.examId;
+    }
+  },
   methods: {
     visibleChange() {
-      this.modalForm.cardSource = this.data.cardSource || "0";
-      this.getCardList();
+      this.getCardSourceTypes();
+      this.modalForm.cardSource = this.cardSourceTypes[0].type;
+      this.modalForm = this.$objAssign(this.modalForm, this.data);
+
+      if (this.noExam) {
+        this.getCourseByUser();
+      } else {
+        this.getCardList();
+      }
+    },
+    getCardSourceTypes() {
+      let cardSourceTypes = [];
+      Object.keys(CARD_SOURCE_TYPE).map(key => {
+        if (key === "0" && this.noExam) return;
+        cardSourceTypes.push({
+          type: key,
+          name: CARD_SOURCE_TYPE[key]
+        });
+      });
+      this.cardSourceTypes = cardSourceTypes;
+    },
+    cousreChange(val) {
+      const course = this.courses.find(item => item.courseCode === val);
+      this.modalForm.courseName = course.courseName;
     },
     async getCardList() {
-      this.cards = await cardList();
+      this.cards = await cardList({
+        courseNameCode: this.modalForm.courseNameCode,
+        enablePaperType: this.modalForm.enablePaperType
+      });
+    },
+    async getCourseByUser() {
+      const data = await courseByUser();
+      if (data && data.length) {
+        this.courses = data;
+        this.modalForm.courseCode = this.courses[0].courseCode;
+        this.modalForm.courseName = this.courses[0].courseName;
+      }
     },
     cancel() {
       this.modalIsShow = false;
@@ -101,6 +163,11 @@ export default {
       this.modalIsShow = true;
     },
     confirm() {
+      if (this.modalForm.cardSource !== "0" && !this.modalForm.courseCode) {
+        this.$message.error("请选择科目!");
+        return;
+      }
+
       if (this.modalForm.cardSource === "2") {
         this.$refs.UploadSamplePaperDialog.open();
         return;
@@ -108,7 +175,7 @@ export default {
 
       if (this.modalForm.cardSource === "1") {
         // 打开题卡编辑页,创建题卡,并预设需要绑定的任务
-        this.$ls.set("prepareBindTask", this.data);
+        this.$ls.set("prepareTcPCard", this.modalForm);
         this.$router.push({
           name: "CardDesign"
         });
@@ -126,7 +193,7 @@ export default {
       this.cancel();
     },
     toPreview() {
-      window.open(`/card/preview/${this.modalForm.refCardId}/view`);
+      window.open(`/#/card/preview/${this.modalForm.refCardId}/view`);
     }
   }
 };

+ 3 - 3
src/modules/exam-center/components/UploadPaperDialog.vue

@@ -68,7 +68,7 @@ export default {
     uploadSuccess(res) {
       this.$message.success("上传成功!");
       this.attachment = Object.assign(this.attachment, {
-        id: res.data.id,
+        attachmentId: res.data.id,
         filename: `${res.data.name}${res.data.type}`
       });
     },
@@ -83,11 +83,11 @@ export default {
       this.cancel();
     },
     async toPreview() {
-      if (!this.attachment.id) {
+      if (!this.attachment.attachmentId) {
         this.$message.error("请先上传附件!");
         return;
       }
-      const data = await attachmentPreview(this.attachment.id);
+      const data = await attachmentPreview(this.attachment.attachmentId);
       window.open(data.path);
     }
   }

+ 65 - 69
src/modules/exam-center/components/UploadSamplePaperDialog.vue

@@ -25,53 +25,56 @@
             placeholder="请输入文件标题"
           ></el-input>
         </el-form-item>
-        <el-form-item>
-          <el-button icon="icon icon-upload" @click="handleClick"
-            >选择上传文件</el-button
-          >
+        <el-form-item prop="paperAttachmentId">
+          <upload-button
+            btn-icon="icon icon-upload"
+            btn-type="default"
+            btn-content="选择上传文件"
+            :upload-url="uploadUrl"
+            :format="format"
+            :max-size="maxSize"
+            :upload-data="uploadData"
+            @upload-error="uplaodError"
+            @upload-success="uploadSuccess"
+            style="margin: 0;"
+          ></upload-button>
           <span style="margin-left: 10px;"
             >上传的单个试卷文件大小不超过20M</span
           >
-          <input
-            ref="fileInput"
-            type="file"
-            style="visibility:hidden;"
-            @change="handleChange"
-          />
         </el-form-item>
       </el-form>
     </div>
-    <div slot="footer" style="text-align: right">
-      <el-button type="primary" @click="confirm">保存</el-button>
+    <div slot="footer" style="text-align: right;">
+      <el-button type="primary" :disabled="isSubmit" @click="confirm"
+        >确定</el-button
+      >
       <el-button @click="cancel">返回</el-button>
     </div>
   </el-dialog>
 </template>
 
 <script>
-import { fileMD5 } from "@/plugins/md5";
-import { createCardAudit } from "../api";
+import UploadButton from "@/components/UploadButton";
+import { createCard } from "../api";
 
 export default {
   name: "upload-sample-paper-dialog",
-  props: {},
+  props: {
+    data: {
+      type: Object,
+      default() {
+        return {};
+      }
+    }
+  },
+  components: { UploadButton },
   data() {
     return {
       modalIsShow: false,
-      attachmentName: "",
-      format: ["doc", "docx"],
       modalForm: {
         title: "",
-        schoolId: this.$ls.get("schoolId"),
-        userId: this.$ls.get("user", { id: "" }).id
-      },
-      maxSize: 20 * 1024,
-      addFilenameParam: "filename",
-      loading: false,
-      uploadUrl: "/api/print/basic/sys/saveAttachment",
-      headers: {
-        token: this.$ls.get("token"),
-        md5: ""
+        cardSource: "2",
+        paperAttachmentId: ""
       },
       rules: {
         title: [
@@ -80,52 +83,39 @@ export default {
             message: "请输入文件标题",
             trigger: "change"
           }
+        ],
+        paperAttachmentId: [
+          {
+            required: true,
+            message: "请上传样卷或试卷结构文件",
+            trigger: "change"
+          }
         ]
-      }
+      },
+      isSubmit: false,
+      // upload
+      format: ["doc", "docx"],
+      uploadData: {
+        schoolId: this.$ls.get("schoolId"),
+        userId: this.$ls.get("user", { id: "" }).id
+      },
+      maxSize: 20 * 1024 * 1024,
+      uploadUrl: "/api/print/basic/sys/saveAttachment"
     };
   },
   methods: {
     visibleChange() {
       this.modalForm.title = "";
-      this.$refs.fileInput.value = "";
-    },
-    handleClick() {
-      if (this.loading) return;
-      this.$refs.fileInput.value = "";
-      this.$refs.fileInput.click();
-    },
-    async handleChange(e) {
-      let file = e.target.files[0];
-      this.modalForm[this.addFilenameParam] = file.name;
-
-      if (file.size > this.maxSize) {
-        this.handleExceededSize();
-      }
-
-      if (!this.checkFileFormat(file.name)) {
-        this.handleFormatError();
-      }
-
-      const md5 = await fileMD5(file);
-      this.headers["md5"] = md5;
-    },
-    checkFileFormat(fileType) {
-      const _file_format = fileType
-        .split(".")
-        .pop()
-        .toLocaleLowerCase();
-      return this.format.some(
-        item => item.toLocaleLowerCase() === _file_format
-      );
+      this.modalForm.cardSource = this.data.cardSource;
+      this.modalForm.paperAttachmentId = "";
     },
-    handleFormatError() {
-      const content = "只支持文件格式为" + this.format.join("/");
-      this.$message.error(content);
+    uplaodError(msg) {
+      this.$message.error(msg);
     },
-    handleExceededSize() {
-      const content =
-        "文件大小不能超过" + Math.floor(this.maxSize / 1024) + "M";
-      this.$message.error(content);
+    uploadSuccess(res) {
+      this.$message.success("上传成功!");
+      this.modalForm.paperAttachmentId = res.data.id;
+      this.$refs["ModalForm"].validateField("paperAttachmentId");
     },
     cancel() {
       this.modalIsShow = false;
@@ -137,10 +127,16 @@ export default {
       const valid = await this.$refs["ModalForm"].validate().catch(() => {});
       if (!valid) return;
 
-      this.loading = true;
-      await createCardAudit(this.modalForm, this.headers).catch(() => {});
-      this.loading = false;
-      this.$message.success("申请客户制作题卡成功!");
+      if (this.isSubmit) return;
+      this.isSubmit = true;
+      const datas = {
+        tcPCard: this.modalForm
+      };
+      const data = await createCard(datas).catch(() => {});
+      this.isSubmit = false;
+      if (!data) return;
+
+      this.$message.success("申请成功!");
       this.$emit("confirm");
       this.cancel();
     }

+ 11 - 11
src/modules/exam-center/views/CardAudit.vue

@@ -26,7 +26,7 @@
             ></el-option>
           </el-select>
         </el-form-item>
-        <el-form-item label="学院:" v-if="filter.auditingStatus == 0">
+        <!-- <el-form-item label="学院:" v-if="filter.auditingStatus == 0">
           <el-select
             v-model="filter.collegeId"
             style="width: 142px;"
@@ -40,11 +40,11 @@
               :label="item.name"
             ></el-option>
           </el-select>
-        </el-form-item>
-        <el-form-item label="标题:" label-width="55px">
+        </el-form-item> -->
+        <el-form-item label="题卡ID:" label-width="70px">
           <el-input
             style="width: 210px;"
-            v-model.trim="filter.title"
+            v-model.trim="filter.cardCode"
             placeholder="请输入内容"
             clearable
           ></el-input>
@@ -54,13 +54,13 @@
           <el-button type="primary" icon="icon icon-search" @click="toPage(1)"
             >查询</el-button
           >
-          <el-button
+          <!-- <el-button
             type="warning"
             icon="icon icon-download"
             @click="toPage(1)"
             v-if="filter.auditingStatus == 0"
             >批量下载试卷文件</el-button
-          >
+          > -->
         </el-form-item>
       </el-form>
     </div>
@@ -111,15 +111,15 @@
 
 <script>
 import { AUDITING_STATUS } from "@/constants/enumerate";
-import { printTaskListPage } from "../api";
+import { auditListPage } from "../api";
 
 export default {
   name: "card-check",
   data() {
     return {
       filter: {
-        auditingStatus: 0,
-        cardId: "",
+        auditingStatus: "0",
+        cardCode: "",
         schoolId: "",
         collegeId: ""
       },
@@ -135,7 +135,7 @@ export default {
     };
   },
   created() {
-    // this.getList();
+    this.getList();
   },
   methods: {
     async getList() {
@@ -144,7 +144,7 @@ export default {
         pageNumber: this.current,
         pageSize: this.size
       };
-      const data = await printTaskListPage(datas);
+      const data = await auditListPage(datas);
       this.examPages = data.records;
       this.total = data.total;
     },

+ 89 - 48
src/modules/exam-center/views/CardManage.vue

@@ -55,46 +55,61 @@
         </el-table-column>
         <el-table-column prop="title" label="标题"></el-table-column>
         <el-table-column prop="printTime" label="打印时间"></el-table-column>
-        <el-table-column prop="cardStatus" label="处理节点"></el-table-column>
+        <el-table-column
+          prop="cardStatusName"
+          label="处理节点"
+        ></el-table-column>
         <el-table-column prop="overtime" label="剩余时间"></el-table-column>
         <el-table-column
           prop="auditingTime"
           label="提交审核时间"
         ></el-table-column>
         <el-table-column
-          prop="auditingStatus"
+          prop="auditingStatusName"
           label="审核状态"
         ></el-table-column>
-        <el-table-column label="操作" align="center">
+        <el-table-column label="操作" align="center" width="120">
           <template slot-scope="scope">
-            <el-button
-              class="btn-table-icon"
-              type="text"
-              icon="icon icon-edit"
-              @click="toEdit(scope.row)"
-              title="确认"
-            ></el-button>
-            <el-button
-              class="btn-table-icon"
-              type="text"
-              icon="icon icon-delete"
-              @click="toDelete(scope.row)"
-              title="确认"
-            ></el-button>
-            <el-button
-              class="btn-table-icon"
-              type="text"
-              icon="icon icon-circle-share"
-              @click="toEdit(scope.row)"
-              title="确认"
-            ></el-button>
-            <el-button
-              class="btn-table-icon"
-              type="text"
-              icon="icon icon-copy"
-              @click="toEdit(scope.row)"
-              title="复制"
-            ></el-button>
+            <div v-if="scope.row.cardStatus !== 0">
+              <!-- <el-button
+                class="btn-table-icon"
+                type="text"
+                icon="icon icon-download"
+                @click="toExport(scope.row)"
+                title="导出"
+              ></el-button> -->
+              <el-button
+                class="btn-table-icon"
+                type="text"
+                icon="icon icon-copy"
+                @click="toDelete(scope.row)"
+                title="复制"
+              ></el-button>
+            </div>
+            <div v-else>
+              <el-button
+                class="btn-table-icon"
+                type="text"
+                icon="icon icon-edit"
+                @click="toEdit(scope.row)"
+                title="编辑"
+              ></el-button>
+              <el-button
+                class="btn-table-icon"
+                type="text"
+                icon="icon icon-delete"
+                @click="toDelete(scope.row)"
+                title="删除"
+              ></el-button>
+              <el-button
+                class="btn-table-icon"
+                type="text"
+                icon="icon icon-circle-share"
+                @click="toPrint(scope.row)"
+                title="印刷"
+                v-if="scope.row.auditingStatus !== 0"
+              ></el-button>
+            </div>
           </template>
         </el-table-column>
       </el-table>
@@ -110,15 +125,26 @@
         </el-pagination>
       </div>
     </div>
+
+    <!-- card-option-dialog -->
+    <card-option-dialog
+      :data="{}"
+      ref="CardOptionDialog"
+      @confirm="cardConfirm"
+    ></card-option-dialog>
   </div>
 </template>
 
 <script>
 import { AUDITING_STATUS } from "@/constants/enumerate";
-import { printTaskListPage, examList } from "../api";
+import { cardListPage, copyCard, deleteCard } from "../api";
+import CardOptionDialog from "../components/CardOptionDialog";
 
 export default {
   name: "card-check",
+  components: {
+    CardOptionDialog
+  },
   data() {
     return {
       filter: {
@@ -131,13 +157,11 @@ export default {
       total: 0,
       visible: false,
       AUDITING_STATUS,
-      exams: [],
-      cards: [],
-      curExam: {}
+      cards: []
     };
   },
   created() {
-    // this.getList();
+    this.getList();
   },
   methods: {
     async getList() {
@@ -146,33 +170,50 @@ export default {
         pageNumber: this.current,
         pageSize: this.size
       };
-      const data = await printTaskListPage(datas);
+      const data = await cardListPage(datas);
       this.cards = data.records;
       this.total = data.total;
+      // cardStatus '处理节点,0:设计题卡,1:提交印刷,2:已完成
     },
     toPage(page) {
       this.current = page;
       this.getList();
     },
-    async getExamList() {
-      const data = await examList();
-      this.exams = data.map(item => {
-        return {
-          id: item.id,
-          name: item.examName
-        };
-      });
-    },
     toAdd() {
+      this.$refs.CardOptionDialog.open();
+    },
+    cardConfirm() {
       this.$router.push({
         name: "CardDesign"
       });
     },
     toEdit(row) {
-      this.curExam = row;
+      this.$router.push({
+        name: "CardDesign",
+        params: {
+          cardId: row.id
+        }
+      });
+    },
+    toExport() {
+      // 暂时不做了
     },
+    async toCopy(row) {
+      await copyCard(row.id);
+      this.$message.success("复制成功!");
+      this.getList();
+    },
+    toPrint() {},
     toDelete(row) {
-      this.curExam = row;
+      this.$confirm("确定要删除当前题卡吗?", "删除警告", {
+        callback: async action => {
+          if (action !== "confirm") return;
+          await deleteCard(row.id);
+          this.$message.success("删除成功!");
+          // 解决最后一项删除后的问题
+          this.deletePageLastItem();
+        }
+      });
     }
   }
 };

+ 14 - 6
src/modules/exam-center/views/WaitTaskDetail.vue

@@ -3,7 +3,7 @@
     <div class="task-title">
       <h2>
         <span>考试名称: {{ task.examName }} </span>
-        <span>科目名称:{{ task.courseNameCode }}</span>
+        <span>科目名称:{{ task.courseName }}</span>
       </h2>
       <div class="task-title-infos">
         <el-checkbox v-model="pTypeEnable" @change="pTypeEnableChange"
@@ -25,10 +25,14 @@
               <i
                 :class="[
                   'icon',
-                  attachment.id ? 'icon-files-act' : 'icon-files'
+                  attachment.attachmentId ? 'icon-files-act' : 'icon-files'
                 ]"
               ></i
-              >{{ attachment.id ? attachment.filename : "点击上传试卷文件" }}
+              >{{
+                attachment.attachmentId
+                  ? attachment.filename
+                  : "点击上传试卷文件"
+              }}
             </span>
           </td>
           <td
@@ -109,7 +113,11 @@ export default {
   methods: {
     async getData() {
       const data = await waitTaskDetail(this.taskId);
-      this.task = Object.assign(this.task, data);
+      const nameCode = data.courseNameCode.split(/\(|\)/);
+      this.task = Object.assign(this.task, data, {
+        courseName: nameCode[0],
+        courseCode: nameCode[1]
+      });
       this.pTypeEnable = this.task.enablePaperType.split(",").length > 1;
       this.parsePaperAttachment();
       this.pTypeEnableChange(this.pTypeEnable);
@@ -127,7 +135,7 @@ export default {
       this.paperAttachments = this.PAPER_TYPE_FIELDS.map(paperType => {
         const paperInfo = paperDict[paperType];
         let paper = {
-          id: "",
+          attachmentId: "",
           name: paperType
         };
         return paperInfo ? Object.assign({}, paper, paperInfo) : paper;
@@ -152,7 +160,7 @@ export default {
     },
     toCreateCard() {
       if (this.task.cardId) {
-        window.open(`/card/preview/${this.task.cardId}/view`);
+        window.open(`/#/card/preview/${this.task.cardId}/view`);
         return;
       }
       this.$refs.CardOptionDialog.open();

+ 2 - 1
src/modules/login/views/Login.vue

@@ -68,7 +68,7 @@ export default {
   data() {
     return {
       loginModel: {
-        loginName: "chulin",
+        loginName: "sysadmin",
         password: "123456",
         roleCode: ""
       },
@@ -101,6 +101,7 @@ export default {
     async getRoleList() {
       const data = await roleList();
       this.roles = data.records;
+      this.loginModel.roleCode = this.roles[0].roleCode;
     },
     async submit(name) {
       const valid = await this.$refs[name].validate().catch(() => {});

+ 3 - 8
src/plugins/ajax.js

@@ -1,3 +1,5 @@
+import { jsonBigNumberToString } from "./utils";
+
 function getError(action, option, xhr) {
   let msg;
   if (xhr.response) {
@@ -14,13 +16,6 @@ function getError(action, option, xhr) {
   err.url = action;
   return err;
 }
-// 解决后台返回的数据中number位数超过16位的情况
-function bigNumberToString(text) {
-  return text
-    .replace(/([0-9]{16,19})/g, '"$1"')
-    .replace(/\\""/g, '\\"')
-    .replace(/"\\"/g, '\\"');
-}
 
 function getBody(xhr) {
   const text = xhr.responseText || xhr.response;
@@ -29,7 +24,7 @@ function getBody(xhr) {
   }
 
   try {
-    return JSON.parse(bigNumberToString(text));
+    return JSON.parse(jsonBigNumberToString(text));
   } catch (e) {
     return text;
   }

+ 1 - 1
src/plugins/axios.js

@@ -44,7 +44,7 @@ const errorDataCallback = error => {
   message = message.indexOf("###") !== -1 ? "参数错误" : message;
 
   // TODO:自定义处理逻辑,以下为epcc实例
-  if (error.code === "105" || error.code === "106") {
+  if (error.code === "105" || error.code === "106" || error.code === "102") {
     message = "身份验证失效,请重新登录";
     MessageBox.confirm(message, "重新登陆?", {
       type: "error",

+ 18 - 1
src/plugins/utils.js

@@ -212,6 +212,22 @@ function calcSum(dataList) {
   }, 0);
 }
 
+/**
+ * 解决后台返回的数据中number位数超过16位的情况
+ * @param {String} text json格式字符串
+ */
+function jsonBigNumberToString(text) {
+  return text
+    .replace(/([0-9]{16,19})/g, '"$1"')
+    .replace(/:"",/g, ":##,")
+    .replace(/""/g, '"')
+    .replace(/:##,/g, ':"",')
+    .replace(/\\""/g, '\\"')
+    .replace(/:\\"\\",/g, ":\\#\\#,")
+    .replace(/"\\"/g, '\\"')
+    .replace(/:\\#\\#,/g, ':\\"\\",');
+}
+
 export {
   objTypeOf,
   deepCopy,
@@ -224,5 +240,6 @@ export {
   localNowDateTime,
   getNumList,
   removeHtmlTag,
-  calcSum
+  calcSum,
+  jsonBigNumberToString
 };