Browse Source

Merge branch 'develop' of http://192.168.4.246:3000/zhangs/surveyMaker into develop

zhangwf 5 years ago
parent
commit
f22bb5da03

+ 417 - 11
package-lock.json

@@ -4,6 +4,182 @@
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
+    "@antv/adjust": {
+      "version": "0.2.2",
+      "resolved": "http://r.cnpmjs.org/@antv/adjust/download/@antv/adjust-0.2.2.tgz",
+      "integrity": "sha1-Vp/5NyE9FKgDsX8FTL4dsGgFxQg=",
+      "requires": {
+        "@antv/util": "~2.0.0",
+        "tslib": "^1.10.0"
+      }
+    },
+    "@antv/attr": {
+      "version": "0.3.2",
+      "resolved": "http://r.cnpmjs.org/@antv/attr/download/@antv/attr-0.3.2.tgz",
+      "integrity": "sha1-5YZrZIcMYvOpwluKYfZUuiv9oFE=",
+      "requires": {
+        "@antv/color-util": "^2.0.1",
+        "@antv/util": "~2.0.0",
+        "tslib": "^1.10.0"
+      }
+    },
+    "@antv/color-util": {
+      "version": "2.0.4",
+      "resolved": "http://r.cnpmjs.org/@antv/color-util/download/@antv/color-util-2.0.4.tgz",
+      "integrity": "sha1-Q+JlA8zZRV0sFCdYxwGLI0sxw+o=",
+      "requires": {
+        "@antv/util": "^2.0.7",
+        "tslib": "^1.10.0"
+      }
+    },
+    "@antv/component": {
+      "version": "0.5.6",
+      "resolved": "http://r.cnpmjs.org/@antv/component/download/@antv/component-0.5.6.tgz",
+      "integrity": "sha1-UMJt2N5NBCSRIIuYlXclS036e1o=",
+      "requires": {
+        "@antv/dom-util": "~2.0.1",
+        "@antv/g-base": "~0.4.0",
+        "@antv/matrix-util": "~2.0.4",
+        "@antv/path-util": "~2.0.7",
+        "@antv/scale": "~0.3.1",
+        "@antv/util": "~2.0.0",
+        "tslib": "^1.10.0"
+      }
+    },
+    "@antv/coord": {
+      "version": "0.2.6",
+      "resolved": "http://r.cnpmjs.org/@antv/coord/download/@antv/coord-0.2.6.tgz",
+      "integrity": "sha1-qrux0y4PQEtjlUZQ0hGmk7cPEQM=",
+      "requires": {
+        "@antv/matrix-util": "~2.0.1-beta.1",
+        "@antv/util": "~2.0.3",
+        "tslib": "^1.10.0"
+      }
+    },
+    "@antv/dom-util": {
+      "version": "2.0.2",
+      "resolved": "http://r.cnpmjs.org/@antv/dom-util/download/@antv/dom-util-2.0.2.tgz",
+      "integrity": "sha1-THsKGV4CflVXBDWmglzsVt+wtZA=",
+      "requires": {
+        "tslib": "^1.10.0"
+      }
+    },
+    "@antv/event-emitter": {
+      "version": "0.1.2",
+      "resolved": "http://r.cnpmjs.org/@antv/event-emitter/download/@antv/event-emitter-0.1.2.tgz",
+      "integrity": "sha1-oXt8uG5tBxiA3Gv7IydW+IYk7Lw="
+    },
+    "@antv/g-base": {
+      "version": "0.4.0",
+      "resolved": "http://r.cnpmjs.org/@antv/g-base/download/@antv/g-base-0.4.0.tgz",
+      "integrity": "sha1-n9hc6rMnotwYSsEuzT+rFCKzph8=",
+      "requires": {
+        "@antv/event-emitter": "^0.1.1",
+        "@antv/g-math": "^0.1.1",
+        "@antv/matrix-util": "^2.0.4",
+        "@antv/path-util": "~2.0.5",
+        "@antv/util": "~2.0.0",
+        "@types/d3-timer": "^1.0.9",
+        "d3-ease": "^1.0.5",
+        "d3-interpolate": "^1.3.2",
+        "d3-timer": "^1.0.9"
+      }
+    },
+    "@antv/g-canvas": {
+      "version": "0.4.2",
+      "resolved": "http://r.cnpmjs.org/@antv/g-canvas/download/@antv/g-canvas-0.4.2.tgz",
+      "integrity": "sha1-OGUjVsKp0SYOdggjD4EgkjRSaNU=",
+      "requires": {
+        "@antv/g-base": "^0.4.0",
+        "@antv/g-math": "^0.1.1",
+        "@antv/gl-matrix": "~2.7.1",
+        "@antv/path-util": "~2.0.5",
+        "@antv/util": "~2.0.0"
+      }
+    },
+    "@antv/g-math": {
+      "version": "0.1.1",
+      "resolved": "http://r.cnpmjs.org/@antv/g-math/download/@antv/g-math-0.1.1.tgz",
+      "integrity": "sha1-OgDsYHs0xMXeK4rSUGmyXB9ZYmo=",
+      "requires": {
+        "@antv/gl-matrix": "~2.7.1",
+        "@antv/util": "~2.0.0"
+      }
+    },
+    "@antv/g-svg": {
+      "version": "0.4.0",
+      "resolved": "http://r.cnpmjs.org/@antv/g-svg/download/@antv/g-svg-0.4.0.tgz",
+      "integrity": "sha1-Pf0TQjp6FiwTfAvb6ekxclJr3i8=",
+      "requires": {
+        "@antv/g-base": "^0.4.0",
+        "@antv/g-math": "^0.1.1",
+        "@antv/util": "~2.0.0",
+        "detect-browser": "^4.6.0"
+      }
+    },
+    "@antv/g2": {
+      "version": "4.0.5",
+      "resolved": "http://r.cnpmjs.org/@antv/g2/download/@antv/g2-4.0.5.tgz",
+      "integrity": "sha1-m7UpZQ6CNmw8/oISe0tNXh/MUu8=",
+      "requires": {
+        "@antv/adjust": "^0.2.1",
+        "@antv/attr": "^0.3.1",
+        "@antv/color-util": "^2.0.2",
+        "@antv/component": "^0.5.0",
+        "@antv/coord": "^0.2.6",
+        "@antv/event-emitter": "~0.1.0",
+        "@antv/g-base": "^0.4.0",
+        "@antv/g-canvas": "^0.4.0",
+        "@antv/g-svg": "^0.4.0",
+        "@antv/matrix-util": "^2.0.4",
+        "@antv/path-util": "^2.0.3",
+        "@antv/scale": "^0.3.1",
+        "@antv/util": "~2.0.5",
+        "tslib": "^1.10.0"
+      }
+    },
+    "@antv/gl-matrix": {
+      "version": "2.7.1",
+      "resolved": "http://r.cnpmjs.org/@antv/gl-matrix/download/@antv/gl-matrix-2.7.1.tgz",
+      "integrity": "sha1-rLjjf3qz3wE0WrpDcteUK+QuuhQ="
+    },
+    "@antv/matrix-util": {
+      "version": "2.0.5",
+      "resolved": "http://r.cnpmjs.org/@antv/matrix-util/download/@antv/matrix-util-2.0.5.tgz",
+      "integrity": "sha1-b8hRlWyngQo4B3j0hbC/4vc4eBs=",
+      "requires": {
+        "@antv/gl-matrix": "^2.7.1",
+        "@antv/util": "^2.0.7",
+        "tslib": "^1.10.0"
+      }
+    },
+    "@antv/path-util": {
+      "version": "2.0.7",
+      "resolved": "http://r.cnpmjs.org/@antv/path-util/download/@antv/path-util-2.0.7.tgz",
+      "integrity": "sha1-eacCyeadU+8JqEjJAbi+klspb9I=",
+      "requires": {
+        "@antv/util": "^2.0.7",
+        "tslib": "^1.10.0"
+      }
+    },
+    "@antv/scale": {
+      "version": "0.3.1",
+      "resolved": "http://r.cnpmjs.org/@antv/scale/download/@antv/scale-0.3.1.tgz",
+      "integrity": "sha1-8QiFgnXKjCfXrz6zdXq3PyY2KZw=",
+      "requires": {
+        "@antv/util": "~2.0.3",
+        "fecha": "~3.0.3",
+        "tslib": "^1.10.0"
+      }
+    },
+    "@antv/util": {
+      "version": "2.0.7",
+      "resolved": "http://r.cnpmjs.org/@antv/util/download/@antv/util-2.0.7.tgz",
+      "integrity": "sha1-uWRmvKfUFDwg3OSFOWzZe1+rchQ=",
+      "requires": {
+        "tslib": "^1.10.0"
+      }
+    },
     "@gulp-sourcemaps/map-sources": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz",
@@ -60,6 +236,11 @@
         "commander": "*"
       }
     },
+    "@types/d3-timer": {
+      "version": "1.0.9",
+      "resolved": "http://r.cnpmjs.org/@types/d3-timer/download/@types/d3-timer-1.0.9.tgz",
+      "integrity": "sha1-rtG94M8Ykg0z9dRIOdc945NjP9M="
+    },
     "@types/node": {
       "version": "10.9.4",
       "resolved": "https://registry.npmjs.org/@types/node/-/node-10.9.4.tgz",
@@ -85,6 +266,11 @@
         "through": ">=2.2.7 <3"
       }
     },
+    "abab": {
+      "version": "1.0.4",
+      "resolved": "http://r.cnpmjs.org/abab/download/abab-1.0.4.tgz",
+      "integrity": "sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4="
+    },
     "abbrev": {
       "version": "1.0.9",
       "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz",
@@ -113,6 +299,21 @@
         "acorn": "^5.0.0"
       }
     },
+    "acorn-globals": {
+      "version": "1.0.9",
+      "resolved": "http://r.cnpmjs.org/acorn-globals/download/acorn-globals-1.0.9.tgz",
+      "integrity": "sha1-VbtemGkVB7dFedBRNBMhfDgMVM8=",
+      "requires": {
+        "acorn": "^2.1.0"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "2.7.0",
+          "resolved": "http://r.cnpmjs.org/acorn/download/acorn-2.7.0.tgz",
+          "integrity": "sha1-q259nYhqrKiwhbwzEreaGYQz8Oc="
+        }
+      }
+    },
     "acorn-jsx": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz",
@@ -331,6 +532,11 @@
       "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
       "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg=="
     },
+    "array-equal": {
+      "version": "1.0.0",
+      "resolved": "http://r.cnpmjs.org/array-equal/download/array-equal-1.0.0.tgz",
+      "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM="
+    },
     "array-find-index": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
@@ -1569,6 +1775,7 @@
       "version": "2.10.1",
       "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
       "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
+      "optional": true,
       "requires": {
         "hoek": "2.x.x"
       }
@@ -1996,6 +2203,24 @@
       "integrity": "sha512-7uo4mQgSWK9lmGKpuXhW1HYfOOF3le+coG/h0Op/AAEvjOuVO9mQQo4EW2WrtOZgxgnLIxVVr57aKT8G5woFoQ==",
       "dev": true
     },
+    "canvg": {
+      "version": "1.5.3",
+      "resolved": "http://r.cnpmjs.org/canvg/download/canvg-1.5.3.tgz",
+      "integrity": "sha1-qtF5FfMzaL+OuAsl0SnjrpIt3F8=",
+      "requires": {
+        "jsdom": "^8.1.0",
+        "rgbcolor": "^1.0.1",
+        "stackblur-canvas": "^1.4.1",
+        "xmldom": "^0.1.22"
+      },
+      "dependencies": {
+        "stackblur-canvas": {
+          "version": "1.4.1",
+          "resolved": "http://r.cnpmjs.org/stackblur-canvas/download/stackblur-canvas-1.4.1.tgz",
+          "integrity": "sha1-hJqm+UsnL/JvZHH6QTDtH35HlVs="
+        }
+      }
+    },
     "caseless": {
       "version": "0.12.0",
       "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
@@ -2805,11 +3030,18 @@
       "dev": true
     },
     "css-line-break": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-1.0.1.tgz",
-      "integrity": "sha1-GfIGOjPpX7KDG4ZEbAuAwYivRQo=",
+      "version": "1.1.1",
+      "resolved": "http://r.cnpmjs.org/css-line-break/download/css-line-break-1.1.1.tgz",
+      "integrity": "sha1-1em90peEAJnrBQPHMQ/TSSegJu8=",
       "requires": {
-        "base64-arraybuffer": "^0.1.5"
+        "base64-arraybuffer": "^0.2.0"
+      },
+      "dependencies": {
+        "base64-arraybuffer": {
+          "version": "0.2.0",
+          "resolved": "http://r.cnpmjs.org/base64-arraybuffer/download/base64-arraybuffer-0.2.0.tgz",
+          "integrity": "sha1-S5RPrAGRqlkHr+LYyZnMxXzoD0U="
+        }
       }
     },
     "css-loader": {
@@ -2949,6 +3181,19 @@
         }
       }
     },
+    "cssom": {
+      "version": "0.3.8",
+      "resolved": "http://r.cnpmjs.org/cssom/download/cssom-0.3.8.tgz",
+      "integrity": "sha1-nxJ29bK0Y/IRTT8sdSUK+MGjb0o="
+    },
+    "cssstyle": {
+      "version": "0.2.37",
+      "resolved": "http://r.cnpmjs.org/cssstyle/download/cssstyle-0.2.37.tgz",
+      "integrity": "sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ=",
+      "requires": {
+        "cssom": "0.3.x"
+      }
+    },
     "currently-unhandled": {
       "version": "0.4.1",
       "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
@@ -2972,6 +3217,29 @@
         "es5-ext": "^0.10.9"
       }
     },
+    "d3-color": {
+      "version": "1.4.0",
+      "resolved": "http://r.cnpmjs.org/d3-color/download/d3-color-1.4.0.tgz",
+      "integrity": "sha1-icRamV7Xc7EzFPBkYN8m1gug7K8="
+    },
+    "d3-ease": {
+      "version": "1.0.6",
+      "resolved": "http://r.cnpmjs.org/d3-ease/download/d3-ease-1.0.6.tgz",
+      "integrity": "sha1-69ttoi36wKIiIvLU2gb2bEFqDsA="
+    },
+    "d3-interpolate": {
+      "version": "1.4.0",
+      "resolved": "http://r.cnpmjs.org/d3-interpolate/download/d3-interpolate-1.4.0.tgz",
+      "integrity": "sha1-Um554tgNqjg/ngwcHH3MDwWD6Yc=",
+      "requires": {
+        "d3-color": "1"
+      }
+    },
+    "d3-timer": {
+      "version": "1.0.10",
+      "resolved": "http://r.cnpmjs.org/d3-timer/download/d3-timer-1.0.10.tgz",
+      "integrity": "sha1-3+dripF0iDGxO22ceT/71QjdneU="
+    },
     "dashdash": {
       "version": "1.14.1",
       "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
@@ -3181,6 +3449,11 @@
       "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
       "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
     },
+    "detect-browser": {
+      "version": "4.8.0",
+      "resolved": "http://r.cnpmjs.org/detect-browser/download/detect-browser-4.8.0.tgz",
+      "integrity": "sha1-HXO9iMF76GaQGVDOCqrh7QYJAsY="
+    },
     "detect-indent": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz",
@@ -4365,6 +4638,11 @@
         "pend": "~1.2.0"
       }
     },
+    "fecha": {
+      "version": "3.0.3",
+      "resolved": "http://r.cnpmjs.org/fecha/download/fecha-3.0.3.tgz",
+      "integrity": "sha1-+rvUFkl2SaQsJNNL+nJrV5IDoeI="
+    },
     "figures": {
       "version": "1.7.0",
       "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
@@ -4394,6 +4672,10 @@
         "loader-utils": "~0.2.5"
       }
     },
+    "file-saver": {
+      "version": "github:eligrey/FileSaver.js#e865e37af9f9947ddcced76b549e27dc45c1cb2e",
+      "from": "github:eligrey/FileSaver.js#1.3.8"
+    },
     "file-type": {
       "version": "3.9.0",
       "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz",
@@ -6021,11 +6303,11 @@
       }
     },
     "html2canvas": {
-      "version": "1.0.0-alpha.12",
-      "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.0.0-alpha.12.tgz",
-      "integrity": "sha1-OxmS48mz9WBjw1/WIElPN+uohRM=",
+      "version": "1.0.0-rc.5",
+      "resolved": "http://r.cnpmjs.org/html2canvas/download/html2canvas-1.0.0-rc.5.tgz",
+      "integrity": "sha1-TuPKyfbiCg+gwvNab5nJYK5+xME=",
       "requires": {
-        "css-line-break": "1.0.1"
+        "css-line-break": "1.1.1"
       }
     },
     "htmlescape": {
@@ -6846,6 +7128,42 @@
       "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
       "optional": true
     },
+    "jsdom": {
+      "version": "8.5.0",
+      "resolved": "http://r.cnpmjs.org/jsdom/download/jsdom-8.5.0.tgz",
+      "integrity": "sha1-1Nj12/J2hjW2KmKCO5R89wcevJg=",
+      "requires": {
+        "abab": "^1.0.0",
+        "acorn": "^2.4.0",
+        "acorn-globals": "^1.0.4",
+        "array-equal": "^1.0.0",
+        "cssom": ">= 0.3.0 < 0.4.0",
+        "cssstyle": ">= 0.2.34 < 0.3.0",
+        "escodegen": "^1.6.1",
+        "iconv-lite": "^0.4.13",
+        "nwmatcher": ">= 1.3.7 < 2.0.0",
+        "parse5": "^1.5.1",
+        "request": "^2.55.0",
+        "sax": "^1.1.4",
+        "symbol-tree": ">= 3.1.0 < 4.0.0",
+        "tough-cookie": "^2.2.0",
+        "webidl-conversions": "^3.0.1",
+        "whatwg-url": "^2.0.1",
+        "xml-name-validator": ">= 2.0.1 < 3.0.0"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "2.7.0",
+          "resolved": "http://r.cnpmjs.org/acorn/download/acorn-2.7.0.tgz",
+          "integrity": "sha1-q259nYhqrKiwhbwzEreaGYQz8Oc="
+        },
+        "parse5": {
+          "version": "1.5.1",
+          "resolved": "http://r.cnpmjs.org/parse5/download/parse5-1.5.1.tgz",
+          "integrity": "sha1-m387DeMr543CQBsXVzzK8Pb1nZQ="
+        }
+      }
+    },
     "jsesc": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
@@ -6941,6 +7259,42 @@
       "resolved": "https://registry.npmjs.org/jspack/-/jspack-0.0.4.tgz",
       "integrity": "sha1-Mt01x/3LPjRWwY+7fvntC8YjgXc="
     },
+    "jspdf": {
+      "version": "1.5.3",
+      "resolved": "http://r.cnpmjs.org/jspdf/download/jspdf-1.5.3.tgz",
+      "integrity": "sha1-WhLAEUed76vvVzXeVckTBg7SGfI=",
+      "requires": {
+        "canvg": "1.5.3",
+        "file-saver": "github:eligrey/FileSaver.js#1.3.8",
+        "html2canvas": "1.0.0-alpha.12",
+        "omggif": "1.0.7",
+        "promise-polyfill": "8.1.0",
+        "stackblur-canvas": "2.2.0"
+      },
+      "dependencies": {
+        "css-line-break": {
+          "version": "1.0.1",
+          "resolved": "http://r.cnpmjs.org/css-line-break/download/css-line-break-1.0.1.tgz",
+          "integrity": "sha1-GfIGOjPpX7KDG4ZEbAuAwYivRQo=",
+          "requires": {
+            "base64-arraybuffer": "^0.1.5"
+          }
+        },
+        "html2canvas": {
+          "version": "1.0.0-alpha.12",
+          "resolved": "http://r.cnpmjs.org/html2canvas/download/html2canvas-1.0.0-alpha.12.tgz",
+          "integrity": "sha1-OxmS48mz9WBjw1/WIElPN+uohRM=",
+          "requires": {
+            "css-line-break": "1.0.1"
+          }
+        },
+        "promise-polyfill": {
+          "version": "8.1.0",
+          "resolved": "http://r.cnpmjs.org/promise-polyfill/download/promise-polyfill-8.1.0.tgz",
+          "integrity": "sha1-MAWdpU0TWM6QWsWB8ofhhK7fmV0="
+        }
+      }
+    },
     "jsprim": {
       "version": "1.4.1",
       "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
@@ -9160,6 +9514,11 @@
       "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
       "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
     },
+    "nwmatcher": {
+      "version": "1.4.4",
+      "resolved": "http://r.cnpmjs.org/nwmatcher/download/nwmatcher-1.4.4.tgz",
+      "integrity": "sha1-IoVjHzSpXw0Dlc2QDJbtObWPNG4="
+    },
     "oauth-sign": {
       "version": "0.8.2",
       "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
@@ -9192,6 +9551,11 @@
         "is-extendable": "^0.1.1"
       }
     },
+    "omggif": {
+      "version": "1.0.7",
+      "resolved": "http://r.cnpmjs.org/omggif/download/omggif-1.0.7.tgz",
+      "integrity": "sha1-WdLuywJj3oRjWz/riHwMmXPx5J0="
+    },
     "on-finished": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
@@ -11108,6 +11472,11 @@
         "onetime": "^1.0.0"
       }
     },
+    "rgbcolor": {
+      "version": "1.0.1",
+      "resolved": "http://r.cnpmjs.org/rgbcolor/download/rgbcolor-1.0.1.tgz",
+      "integrity": "sha1-1lBezbMEplldom+ktDMHMGd1lF0="
+    },
     "right-align": {
       "version": "0.1.3",
       "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
@@ -11313,8 +11682,7 @@
     "sax": {
       "version": "1.2.4",
       "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
-      "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
-      "dev": true
+      "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
     },
     "scss-tokenizer": {
       "version": "0.2.3",
@@ -11868,6 +12236,11 @@
         }
       }
     },
+    "stackblur-canvas": {
+      "version": "2.2.0",
+      "resolved": "http://r.cnpmjs.org/stackblur-canvas/download/stackblur-canvas-2.2.0.tgz",
+      "integrity": "sha1-ysxZJKB0Sz4YPrLmwdhVnBoXwm4="
+    },
     "statuses": {
       "version": "1.5.0",
       "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
@@ -12163,6 +12536,11 @@
         }
       }
     },
+    "symbol-tree": {
+      "version": "3.2.4",
+      "resolved": "http://r.cnpmjs.org/symbol-tree/download/symbol-tree-3.2.4.tgz",
+      "integrity": "sha1-QwY30ki6d+B4iDlR+5qg7tfGP6I="
+    },
     "syntax-error": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz",
@@ -12430,11 +12808,15 @@
       "version": "2.3.4",
       "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz",
       "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==",
-      "optional": true,
       "requires": {
         "punycode": "^1.4.1"
       }
     },
+    "tr46": {
+      "version": "0.0.3",
+      "resolved": "http://r.cnpmjs.org/tr46/download/tr46-0.0.3.tgz",
+      "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
+    },
     "trim-newlines": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
@@ -12480,6 +12862,11 @@
         }
       }
     },
+    "tslib": {
+      "version": "1.11.1",
+      "resolved": "http://r.cnpmjs.org/tslib/download/tslib-1.11.1.tgz",
+      "integrity": "sha1-6xXRKIJ/vuKEFUnhcfRe0zisfjU="
+    },
     "tty-browserify": {
       "version": "0.0.1",
       "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz",
@@ -13207,6 +13594,11 @@
         "argparse": "^1.0.6"
       }
     },
+    "webidl-conversions": {
+      "version": "3.0.1",
+      "resolved": "http://r.cnpmjs.org/webidl-conversions/download/webidl-conversions-3.0.1.tgz",
+      "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
+    },
     "webpack": {
       "version": "1.15.0",
       "resolved": "https://registry.npmjs.org/webpack/-/webpack-1.15.0.tgz",
@@ -13423,6 +13815,15 @@
         }
       }
     },
+    "whatwg-url": {
+      "version": "2.0.1",
+      "resolved": "http://r.cnpmjs.org/whatwg-url/download/whatwg-url-2.0.1.tgz",
+      "integrity": "sha1-U5ayBD8CDub3BNnEXqhRnnJN5lk=",
+      "requires": {
+        "tr46": "~0.0.3",
+        "webidl-conversions": "^3.0.0"
+      }
+    },
     "whet.extend": {
       "version": "0.9.9",
       "resolved": "https://registry.npmjs.org/whet.extend/-/whet.extend-0.9.9.tgz",
@@ -13510,6 +13911,11 @@
       "integrity": "sha1-OS2LotDxw00e4tYw8V0O+2jhBIo=",
       "dev": true
     },
+    "xml-name-validator": {
+      "version": "2.0.1",
+      "resolved": "http://r.cnpmjs.org/xml-name-validator/download/xml-name-validator-2.0.1.tgz",
+      "integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU="
+    },
     "xmldom": {
       "version": "0.1.27",
       "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz",

+ 3 - 1
package.json

@@ -12,6 +12,7 @@
     "uat": "cross-env NODE_ENV=uat node build/build.js"
   },
   "dependencies": {
+    "@antv/g2": "^4.0.5",
     "acorn": "^5.1.1",
     "animate.css": "^3.5.2",
     "art-template": "^3.0.3",
@@ -36,12 +37,13 @@
     "formidable": "^1.2.1",
     "github-markdown-css": "^2.4.1",
     "hbs": "~4.0.1",
-    "html2canvas": "^1.0.0-alpha.12",
+    "html2canvas": "^1.0.0-rc.5",
     "iconv-lite": "~ 0.4.4",
     "install.js": "^1.0.1",
     "jquery": "^3.3.1",
     "jsonwebtoken": "^7.1.9",
     "jspack": "~ 0.0.3",
+    "jspdf": "^1.5.3",
     "less-middleware": "~2.2.0",
     "lodash": "~ 2.4",
     "lrz": "^4.9.40",

+ 0 - 1
src/api/editor.js

@@ -48,7 +48,6 @@ const cncTestDetail = (data) => {
 const createTest = (data) => {
   return http.post('/testTheme/createTest', data)
 }
-
 module.exports = {
   houseList, cncTestDetail, createTest,
   getUserThemeList, saveTheme, updateTheme, uploadPic, uploadPsd, getPageByThemeId, getPicListByThemeId, delTheme, cncTestcaseList

+ 18 - 1
src/api/test.js

@@ -18,6 +18,23 @@ const queryTestTheme = (param) => {
   return http.post('/testTheme/queryTestTheme', param)
 }
 
+// 报表导出
+const exportExcelPath = (param) => {
+  return http.post('/excel/exportExcelPath', param)
+}
+
+const answerData = (data) => {
+  return http.post('/analyse/answerData', data)
+}
+const saveAnalyseBag = (data) => {
+  return http.post('/analyse/saveAnalyseBag', data)
+}
+const condition = (data) => {
+  return http.post('/analyse/condition', data)
+}
+const crossAnalyse = (data) => {
+  return http.post('/analyse/crossAnalyse', data)
+}
 module.exports = {
-  testList, deleteTest, copyTest, queryTestTheme
+  testList, deleteTest, copyTest, queryTestTheme, exportExcelPath, answerData, saveAnalyseBag, condition, crossAnalyse
 }

BIN
src/assets/images/more_nor.png


BIN
src/assets/images/more_sel.png


+ 73 - 0
src/components/HeaderData.vue

@@ -0,0 +1,73 @@
+<template>
+  <div class="header">
+    <div class="tag">
+      <div class="left">
+        <span @click="home" style="cursor: pointer;">首页</span> > 数据
+      </div>
+      <div class="right">
+        <div class="operational-data" @click="handleExport">下载PDF</div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {};
+  },
+  methods: {
+    home() {
+      this.$router.push({ path: "/" });
+    },
+    handleExport() {
+      this.$parent.goToPreviewPage();
+    }
+  }
+};
+</script>
+
+<style lang="less" scoped>
+.header {
+  z-index: 1;
+  position: fixed;
+  top: 0px;
+  width: 100%;
+  height: 60px;
+  box-shadow: 0 2px 8px 0 rgba(62, 67, 116, 0.1);
+  border-bottom: 0;
+  display: flex;
+  flex-direction: row;
+  justify-content: center;
+  align-items: center;
+  padding: 0px 50px;
+  .tag {
+    max-width: 1180px;
+    width: 100%;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    font-size: 14px;
+    font-family: Helvetica;
+    color: rgba(51, 51, 51, 1);
+    line-height: 17px;
+  }
+  .right {
+    display: flex;
+    flex-direction: row;
+    .operational-data {
+      width: 88px;
+      height: 30px;
+      font-size: 12px;
+      font-family: STYuanti-SC-Regular, STYuanti-SC;
+      font-weight: 400;
+      color: rgba(255, 255, 255, 1);
+      background: rgba(78, 93, 255, 1);
+      border-radius: 15px;
+      line-height: 30px;
+      text-align: center;
+      cursor: pointer;
+    }
+  }
+}
+</style>

+ 4 - 16
src/components/HeaderEdit.vue

@@ -7,21 +7,11 @@
     </div>
     <div class="tools">
       <div class="next_return">
-        <div
-          class="return"
-          title="撤销"
-          @click="revocation"
-          :style="`opacity:${operationList.length>1?'1':'.3'}`"
-        >
+        <div class="return" title="撤销" @click="revocation" :style="`opacity:${operationList.length>1?'1':'.3'}`">
           <img class="retutn_icon" src="../assets/images/button_return.png" alt />
           <span>撤销</span>
         </div>
-        <div
-          class="return"
-          title="恢复"
-          @click="recover"
-          :style="`opacity:${nextList.length>0?'1':'.3'}`"
-        >
+        <div class="return" title="恢复" @click="recover" :style="`opacity:${nextList.length>0?'1':'.3'}`">
           <img class="retutn_icon" src="../assets/images/button_next.png" alt />
           <span>恢复</span>
         </div>
@@ -37,11 +27,9 @@
           <img class="size" @click="zoom(false)" src="../assets/images/subtraction.png"></img>
           <div class="zoom-num">
             <span
-              style="font-size:14px;font-family:MicrosoftYaHei;color:rgba(100,107,129,1);line-height:19px"
-            >{{zoomNum*100}}%</span>
+              style="font-size:14px;font-family:MicrosoftYaHei;color:rgba(100,107,129,1);line-height:19px">{{zoomNum*100}}%</span>
             <span
-              style="font-size:14px;font-family:MicrosoftYaHei;color:rgba(100,107,129,1);line-height:19px;"
-            >缩放</span>
+              style="font-size:14px;font-family:MicrosoftYaHei;color:rgba(100,107,129,1);line-height:19px;">缩放</span>
           </div>
           <img class="size" @click="zoom(true)" src="../assets/images/add.png"></img>
         </div>

+ 6 - 2
src/components/HeaderMain.vue

@@ -3,7 +3,7 @@
     <div class="logo" @click="home">
       <img class="logo-img" src="../assets/images/diaoyanbao-log.png" alt="">调研宝</div>
     <div class="right">
-      <div class="operational-data">去“看板”查看测试运营数据</div>
+      <div class="operational-data" @click="testData">查看数据</div>
       <el-dropdown placement="bottom" trigger="click">
         <div class="userinfo">用户名 <i class="el-icon-caret-bottom"></i></div>
         <el-dropdown-menu slot="dropdown">
@@ -23,6 +23,9 @@ export default {
   methods: {
     home() {
       this.$router.push({ path: "/" });
+    },
+    testData() {
+      this.$router.push({ path: "/testData" });
     }
   }
 };
@@ -58,7 +61,7 @@ export default {
     display: flex;
     flex-direction: row;
     .operational-data {
-      width: 240px;
+      width: 119px;
       height: 34px;
       background: #e6edff;
       border-radius: 17px;
@@ -67,6 +70,7 @@ export default {
       line-height: 34px;
       text-align: center;
       margin-right: 46px;
+      cursor: pointer;
     }
     .userinfo {
       width: 132px;

+ 81 - 0
src/components/HistogramHorizontal.vue

@@ -0,0 +1,81 @@
+<!-- 水平方向的柱状图 -->
+<template>
+  <div :id="chartId"></div>
+</template>
+<script>
+import { Chart } from "@antv/g2";
+import superHorizontal from "./SuperComponent";
+export default {
+  name: "chart",
+  data() {
+    return {
+      ...superHorizontal.rootComponent.data(),
+      chart: null
+    };
+  },
+  props: superHorizontal.rootComponent.props,
+  mounted() {
+    this.drawChart();
+  },
+  watch: {
+    chartData: function(val) {
+      this.chart.changeData(val); // 动态更新数据
+    }
+  },
+  methods: {
+    drawChart: function() {
+      // Step 1: 创建 Chart 对象
+      this.chart = new Chart({
+        container: this.chartId, // 指定图表容器 ID
+        autoFit: true,
+        height: 400
+      });
+
+      this.chart.data(this.chartData);
+      this.chart.scale({
+        sold: {
+          max: 100,
+          min: 0,
+          alias: "占该题总答题人数百分比"
+        }
+      });
+      this.chart.axis("sold", {
+        label: null,
+        title: {
+          offset: 30,
+          style: {
+            fontSize: 12,
+            fontWeight: 300
+          }
+        }
+      });
+      this.chart.legend(false);
+      this.chart.coordinate().transpose();
+      this.chart
+        .interval()
+        .position("genre*sold")
+        .label("sold", {
+          style: {
+            fill: "#8d8d8d"
+          },
+          offset: 10,
+          content: originData => {
+            return originData.sold + "%";
+          }
+        })
+        .tooltip("genre*sold", (genre, sold) => {
+          return {
+            name: genre,
+            value: sold + "%"
+          };
+        });
+
+      this.chart.interaction("active-region");
+      this.chart.render();
+    }
+  }
+};
+</script>
+
+<style scoped>
+</style>

+ 82 - 0
src/components/HistogramHorizontals.vue

@@ -0,0 +1,82 @@
+<!-- 水平方向的柱状图 -->
+<template>
+  <div :id="chartId"></div>
+</template>
+<script>
+import { Chart } from "@antv/g2";
+import superHorizontal from "./SuperComponent";
+export default {
+  name: "chart",
+  data() {
+    return {
+      ...superHorizontal.rootComponent.data(),
+      chart: null
+    };
+  },
+  props: superHorizontal.rootComponent.props,
+  mounted() {
+    this.drawChart();
+  },
+  watch: {
+    chartData: function(val) {
+      this.chart.changeData(val); // 动态更新数据
+    }
+  },
+  methods: {
+    drawChart: function() {
+      // Step 1: 创建 Chart 对象
+      this.chart = new Chart({
+        container: this.chartId,
+        autoFit: true,
+        height: 500
+      });
+      this.chart.data(this.chartData);
+
+      this.chart.axis("time", {
+        tickLine: null
+      });
+
+      this.chart.legend({
+        position: "bottom"
+      });
+
+      this.chart.tooltip({
+        shared: true,
+        showMarkers: false
+      });
+      this.chart.interaction("active-region");
+
+      this.chart
+        .interval()
+        .adjust("stack")
+        .position("time*value")
+        .color("type", ["#F3CC1C", "#1890ff", "#6190FF", "#36CFAA"])
+        .tooltip("type*value*total", (type, value, total) => {
+          return {
+            name: type,
+            value: value + " (" + total + "%)"
+          };
+        })
+        .label("value", val => {
+          if (val < 10) {
+            return null;
+          }
+          return {
+            position: "middle",
+            offset: 0,
+            content: originData => {
+              return originData.total + "%";
+            },
+            style: {
+              stroke: "#fff"
+            }
+          };
+        });
+      this.chart.render();
+    }
+  }
+};
+</script>
+
+<style scoped>
+</style>

+ 42 - 0
src/components/ShareSetting.vue

@@ -34,6 +34,14 @@
         </div>
         <input type="text" id="releaseUrl" v-model="releaseUrl" style="height:0px;border: 0;">
       </div>
+      <div class="mark">
+        <div class="mark-title">添加备注</div>
+        <div class="content">
+          <el-input class="input" type="textarea" :rows="6" placeholder="请输入内容" v-model="shareModel.remark"
+            maxlength="500" show-word-limit>
+          </el-input>
+        </div>
+      </div>
       <div class="qrcode-title">渠道二维码
         <div class="qrcode-copy" @click="copy">
           <img class="qrcode-copy-img" src="../assets/images/qrcode-copy.png" alt="">
@@ -119,6 +127,19 @@ export default {
         }
       });
       console.log("XXXX", this.currItem);
+      this.saveRemarks();
+    },
+    saveRemarks() {
+      let param = {
+        id: this.shareModel.id,
+        remark: this.shareModel.remark,
+        updator: "admin"
+      };
+      editorApi.saveTheme(param).then(res => {
+        if (res.success) {
+          this.$emit("child-event", this.shareModel.remark);
+        }
+      });
     }
   },
   mounted() {
@@ -371,5 +392,26 @@ export default {
       cursor: pointer;
     }
   }
+  .mark {
+    overflow: auto;
+    width: 446px;
+    background: #fff;
+    .mark-title {
+      margin: 20px 0px 10px 18px;
+      font-size: 16px;
+      font-family: PingFangSC-Regular;
+      font-weight: 400;
+      color: rgba(0, 0, 0, 1);
+      line-height: 22px;
+    }
+    .content {
+      display: flex;
+      position: relative;
+      .input {
+        width: 415px;
+        margin-left: 15px;
+      }
+    }
+  }
 }
 </style>

+ 22 - 0
src/components/SuperComponent.js

@@ -0,0 +1,22 @@
+const rootComponent = {
+  data() {
+    return {
+      chart: null
+    }
+  },
+  props: {
+    chartData: {
+      type: Array,
+      default: function () {
+        return {
+          data: []
+        }
+      }
+    },
+    id: String,
+    chartId: String
+  }
+}
+export default {
+  rootComponent
+}

+ 2 - 0
src/main.js

@@ -21,6 +21,8 @@ Vue.use(VueRouter)
 Vue.use(Vuex)
 Vue.use(ElementUI)
 
+import htmlToPdf from './util/htmlToPdf' // 路径仅为示例
+Vue.use(htmlToPdf)
 // 全局样式
 import 'normalize.css'
 import 'element-ui/lib/theme-chalk/index.css'

+ 8 - 0
src/routers.js

@@ -45,6 +45,14 @@ const router = new Router({
     path: '/cncTestLists',
     name: "cncTestLists",
     component: require('./views/cnctestlists/cncTestLists.vue')
+  }, {
+    path: '/testData',
+    name: "testData",
+    component: require('./views/testData/testData.vue')
+  }, {
+    path: '/previewPage',
+    name: "previewPage",
+    component: require('./views/previewPage/previewPage.vue')
   }]
 })
 router.beforeEach((to, from, next) => {

+ 2 - 2
src/util/appConst.js

@@ -9,7 +9,7 @@ if (process.env.NODE_ENV === 'test') {
   QINIU_DOMAIN = 'https://gatewaytest.elab-plus.com'
   DIAOYANBAO_PATH = 'http://h5test.elab-plus.com/diaoyanbao/#/preview?mgid='
 } else if (process.env.NODE_ENV === 'development') {//开发
-  BACKEND_DOMAIN = 'http://192.168.0.16:5318'
+  BACKEND_DOMAIN = 'http://43.254.221.77:5555/elab-diaoyanbao'
   DIAOYANBAO_PATH = 'http://192.168.4.249:8080/#/preview?mgid='
   QINIU_DOMAIN = 'https://gatewaytest.elab-plus.com'
   // BACKEND_DOMAIN = 'http://gatewaytest.elab-plus.com/elab-diaoyanbao'
@@ -19,7 +19,7 @@ if (process.env.NODE_ENV === 'test') {
   DIAOYANBAO_PATH = 'http://192.168.4.249:8080/#/preview?mgid='
 } else {//PROD
   //生产PROD
-   BACKEND_DOMAIN = 'https://dm-api.elab-plus.cn/elab-diaoyanbao'
+  BACKEND_DOMAIN = 'https://dm-api.elab-plus.cn/elab-diaoyanbao'
   DIAOYANBAO_PATH = 'https://dm-mng3.elab-plus.cn/diaoyanbao/#/preview?mgid='
 }
 export default {

+ 38 - 0
src/util/htmlToPdf.js

@@ -0,0 +1,38 @@
+// 导出页面为PDF格式
+import html2Canvas from 'html2canvas'
+import JsPDF from 'jspdf'
+export default {
+  install(Vue, options) {
+    Vue.prototype.$appName = 'My App';
+    Vue.prototype.$getPdf = function () {
+      let title = this.htmlTitle
+      html2Canvas(document.querySelector('#pdfDom'), {
+        allowTaint: true
+      }).then(function (canvas) {
+        let contentWidth = canvas.width
+        let contentHeight = canvas.height
+        let pageHeight = contentWidth / 592.28 * 841.89
+        let leftHeight = contentHeight
+        let position = 0
+        const imgWidth = 595.28
+        let imgHeight = 592.28 / contentWidth * contentHeight
+        let pageData = canvas.toDataURL('image/jpeg', 1.0)
+        let PDF = new JsPDF('', 'pt', 'a4')
+        if (leftHeight < pageHeight) {
+          PDF.addImage(pageData, 'JPEG', 0, 10, imgWidth, imgHeight)
+        } else {
+          while (leftHeight > 0) {
+            PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
+            leftHeight -= pageHeight
+            position -= 841.89
+            if (leftHeight > 0) {
+              PDF.addPage()
+            }
+          }
+        }
+        PDF.save(title + '.pdf')
+      }
+      )
+    }
+  }
+}

+ 20 - 1
src/util/time.js

@@ -31,6 +31,25 @@ const dateStr = (date) => {
     return date.getFullYear() + "/" + (date.getMonth() + 1) + "/" + date.getDate();
   }
 }
+
+
+
+const getNowFormatDate = () => {
+  var date = new Date();
+  var year = date.getFullYear();
+  var month = date.getMonth() + 1;
+  var strDate = date.getDate();
+  if (month >= 1 && month <= 9) {
+    month = '0' + month;
+  }
+  if (strDate >= 0 && strDate <= 9) {
+    strDate = '0' + strDate;
+  }
+  var currentdate = year + '-' + month + '-' + strDate + ":" + date.getHours() + ":" + date.getMinutes();
+
+  console.log("XXXXXX", currentdate);
+  return currentdate;
+}
 export default {
-  dateStr
+  dateStr, getNowFormatDate
 }

+ 29 - 86
src/views/h5editor/overview.vue

@@ -2,18 +2,10 @@
   <div class="overview">
     <!-- 顶部tag -->
     <div class="preview-tag">
-      <div
-        class="page-tag-btn tagPage"
-        :class="{ active: viewState === 0 }"
-        @click="function () { viewState = 0 }"
-      >
+      <div class="page-tag-btn tagPage" :class="{ active: viewState === 0 }" @click="function () { viewState = 0 }">
         <div class="page-tag-btn-tip">页面</div>
       </div>
-      <div
-        class="page-tag-btn tagElement"
-        :class="{ active: viewState === 1 }"
-        @click="function () { viewState = 1 }"
-      >
+      <div class="page-tag-btn tagElement" :class="{ active: viewState === 1 }" @click="function () { viewState = 1 }">
         <div class="page-tag-btn-tip">元素</div>
       </div>
     </div>
@@ -25,21 +17,12 @@
           <div class="page_preview_tag_title">封面</div>
           <div class="item-page" v-for="(page,index) in pages" v-show="index==0">
             <span>1</span>
-            <div
-              class="page"
-              :class="{ active: page === editingPage }"
+            <div class="page" :class="{ active: page === editingPage }"
               :style="{ width: 70 + 4 + 'px', height: (70 / canvasWidth) * canvasHeight + 4 + 'px' }"
-              @click="setEditingPage(page,0)"
-              @click.right="rightEvent()"
-            >
-              <Page
-                :isOverView="true"
-                class="content"
-                :hideFoot="true"
+              @click="setEditingPage(page,0)" @click.right="rightEvent()">
+              <Page :isOverView="true" class="content" :hideFoot="true"
                 :style="{ width: canvasWidth + 'px', height: canvasHeight + 'px', transform: 'scale(' + 70 / canvasWidth +')',backgroundColor: bodyBackgroundColor }"
-                :elements="page.elements"
-                type="see"
-              />
+                :elements="page.elements" type="see" />
             </div>
           </div>
         </li>
@@ -48,27 +31,15 @@
           <div class="page_preview_tag_title">题目</div>
           <div class="item-page" v-for="(page,index) in pages" v-show="isShow(index)">
             <span>{{index + 1 }}</span>
-            <div
-              class="page"
-              :class="{ active: page === editingPage }"
+            <div class="page" :class="{ active: page === editingPage }"
               :style="{ width: 70 + 4 + 'px', height: (70 / canvasWidth) * canvasHeight + 4 + 'px' }"
-              @click="setEditingPage(page,index)"
-            >
-              <Page
-                :isOverView="true"
-                class="content"
-                :hideFoot="true"
+              @click="setEditingPage(page,index)">
+              <Page :isOverView="true" class="content" :hideFoot="true"
                 :style="{ width: canvasWidth + 'px', height: canvasHeight + 'px', transform: 'scale(' + 70 / canvasWidth +')',backgroundColor: bodyBackgroundColor }"
-                :elements="page.elements"
-                type="see"
-              />
+                :elements="page.elements" type="see" />
             </div>
-            <el-dropdown
-              placement="bottom"
-              trigger="click"
-              class="operation"
-              @command="command=>operationCommand(command, page, index)"
-            >
+            <el-dropdown placement="bottom" trigger="click" class="operation"
+              @command="command=>operationCommand(command, page, index)">
               <div class="operation_img"></div>
               <el-dropdown-menu slot="dropdown">
                 <el-dropdown-item command="insertBottom">向下插入新页面</el-dropdown-item>
@@ -84,27 +55,15 @@
           <div class="page_preview_tag_title">结论</div>
           <div class="item-page" v-for="(page,index) in pages" v-show="isShowResult(index)">
             <span>{{index + 1}}</span>
-            <div
-              class="page"
-              :class="{ active: page === editingPage }"
+            <div class="page" :class="{ active: page === editingPage }"
               :style="{ width: 70 + 4 + 'px', height: (70 / canvasWidth) * canvasHeight + 4 + 'px' }"
-              @click="setEditingPage(page,index)"
-            >
-              <Page
-                :isOverView="true"
-                class="content"
-                :hideFoot="true"
+              @click="setEditingPage(page,index)">
+              <Page :isOverView="true" class="content" :hideFoot="true"
                 :style="{ width: canvasWidth + 'px', height: canvasHeight + 'px', transform: 'scale(' + 70 / canvasWidth +')',backgroundColor: bodyBackgroundColor }"
-                :elements="page.elements"
-                type="see"
-              />
+                :elements="page.elements" type="see" />
             </div>
-            <el-dropdown
-              placement="bottom"
-              trigger="click"
-              class="operation"
-              @command="command=>operationCommand(command, page, index)"
-            >
+            <el-dropdown placement="bottom" trigger="click" class="operation"
+              @command="command=>operationCommand(command, page, index)">
               <div class="operation_img"></div>
               <el-dropdown-menu slot="dropdown">
                 <el-dropdown-item command="del">删除</el-dropdown-item>
@@ -116,31 +75,18 @@
       </ul>
     </div>
     <!-- 图层 -->
-    <div
-      class="list custom-scrollbar"
-      style="z-index: 2;"
-      v-show="viewState === 1"
-      :class="{ dragging: dragState === 1 }"
-    >
+    <div class="list custom-scrollbar" style="z-index: 2;" v-show="viewState === 1"
+      :class="{ dragging: dragState === 1 }">
       <ul>
         <li v-for="(layer, index) in layersNoBg" :key="index">
-          <div
-            class="layer"
-            :class="{ active: editingLayer === layer}"
-            @mousedown="moveLayer($event,layer)"
-          >
+          <div class="layer" :class="{ active: editingLayer === layer}" @mousedown="moveLayer($event,layer)">
             <span class="thumb" :style="{ backgroundImage: 'url(' + layer.imgSrc + ')' }"></span>
             {{ layer.type }}
           </div>
         </li>
       </ul>
-      <div
-        v-for="(layer, index) in layersBg"
-        :key="index"
-        class="layer"
-        :class="{ active: editingLayer === layer}"
-        @click="setEditingLayer(layer)"
-      >
+      <div v-for="(layer, index) in layersBg" :key="index" class="layer" :class="{ active: editingLayer === layer}"
+        @click="setEditingLayer(layer)">
         <span class="thumb" :style="{ backgroundImage: 'url(' + layer.imgSrc + ')' }"></span>
         {{ layer.type }}
       </div>
@@ -154,14 +100,8 @@
       <el-collapse-transition>
         <div v-show="showTopic">
           <div class="topic-group">
-            <el-checkbox
-              v-model="item.isChecked"
-              v-for="(item, index) in questionList"
-              :label="item.name"
-              :key="index"
-              @change="checked=>selectCheckbox(checked,item,index)"
-              :disabled="isDisabled(index)"
-            ></el-checkbox>
+            <el-checkbox v-model="item.isChecked" v-for="(item, index) in questionList" :label="item.name" :key="index"
+              @change="checked=>selectCheckbox(checked,item,index)" :disabled="isDisabled(index)"></el-checkbox>
           </div>
         </div>
       </el-collapse-transition>
@@ -260,7 +200,7 @@ export default {
         this.$store.state.editor.editorTheme.bodyBackgroundColor ||
         "rgba(255,255,255,0)";
       if (isTop) {
-        var position = index ;
+        var position = index;
       } else {
         var position = index + 1;
       }
@@ -764,6 +704,7 @@ export default {
     margin-left: 10px;
     border: 2px solid rgba(255, 255, 255, 1);
     background: #fff;
+    padding: 0px;
     &.active {
       border-color: rgba(78, 93, 255, 1);
       box-shadow: 0px 2px 4px 0px rgba(78, 93, 255, 1);
@@ -875,6 +816,8 @@ export default {
       display: flex;
       flex-direction: column;
       margin-left: 24px;
+      overflow-y: scroll;
+      max-height: 300px;
       .el-checkbox {
         padding-top: 10px;
         padding-bottom: 10px;

+ 73 - 6
src/views/myHistoryTest/myHistoryTest.html

@@ -21,6 +21,15 @@
           </el-dropdown-item>
         </el-dropdown-menu>
       </el-dropdown>
+      <el-dropdown trigger="click" @command="orderStatus">
+        <el-button type="primary">{{currOrderStatus}} <i class="el-icon-caret-bottom icon-right"></i>
+        </el-button>
+        <el-dropdown-menu slot="dropdown">
+          <el-dropdown-item v-for="(item,index) in statusList" :key="item.orderStatus" :command="item">
+            {{item.orderName}}
+          </el-dropdown-item>
+        </el-dropdown-menu>
+      </el-dropdown>
     </div>
     <div class="right">
       <el-button type="primary" icon="el-icon-circle-plus-outline" @click="createTest">创建测试</el-button>
@@ -28,26 +37,60 @@
   </div>
   <!-- 列表 -->
   <div class="test-list" v-infinite-scroll="getTestList" infinite-scroll-disabled="disabled">
-    <div class="item" v-for="(item,index) in dataList" :key="item.created" :class="{ itemCopy: isCopy && index == 0 }">
+    <div class="item" v-for="(item,index) in dataList" :key="item.created"
+      :class="[ (isCopy && index == 0) ? itemCopyClass :'', item.isMore ? morehoverClass : '' ]"
+      @mouseenter="enterssss(item)" @mouseleave="leave" @mousemove="updateXY">
       <!-- <img  mode="" :src="" alt=""> -->
-      <el-image class="item-img" :src="item.coverImg" fit="cover">
+      <el-image class="item-img1" :src="item.coverImg" fit="cover">
         <div slot="error" class="outline">
           <img class="item-img-outline" src="../../assets/images/picture-error.png" alt="">
           <!-- <i class="el-icon-picture-outline"></i> -->
         </div>
       </el-image>
       <div class="tools">
-        <div v-if="item.canDelete" class="item-img delete" src="" alt="" @click="deleteTest(item,index)"></div>
+        <el-dropdown placement="bottom" trigger="click" class="item-img"
+          @command="command=>operationCommand(command, item, index)" @visible-change="isShow=>more(isShow,item,index)">
+          <div class="more"></div>
+          <el-dropdown-menu slot="dropdown">
+            <el-dropdown-item command="download" v-if="!item.canDelete">下载数据表格</el-dropdown-item>
+            <el-dropdown-item command="share">设置分享链接</el-dropdown-item>
+            <el-dropdown-item command="del" v-if="item.canDelete">删除</el-dropdown-item>
+          </el-dropdown-menu>
+        </el-dropdown>
+        <!-- <div v-if="item.canDelete" class="item-img delete" src="" alt="" @click="deleteTest(item,index)"></div>
+        <div class="item-img copy" src="" alt="" @click="copyTest(item)"></div> -->
+        <!-- <div class="item-img share" src="" alt="" @click="shareTest(item)"></div> -->
+        <!-- <div v-if="item.canDelete == false" class="item-img share" src="" alt="" @click="excelReport(item)"></div> -->
         <div class="item-img copy" src="" alt="" @click="copyTest(item)"></div>
-        <div class="item-img share" src="" alt="" @click="shareTest(item)"></div>
         <div class="item-img edit" @click="editTest(item)" style="float:right;margin-right:10px;"></div>
       </div>
-      <div class="title">{{item.title}}</div>
+      <div class="title" style="display: -webkit-box;
+      -webkit-box-orient: vertical;
+      -webkit-line-clamp: 2;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      word-break: break-all;
+      word-wrap: break-word;">{{item.title}}</div>
       <div class="desc">{{item.ownHouseName}}</div>
       <div class="bottom">
         <span>共{{item.questionCount}}题</span>
         <span>{{dataformat(item.created)}}</span>
       </div>
+      <!-- <div class="remarkBg">
+        <span class="remark" style="display: -webkit-box;
+        -webkit-box-orient: vertical;
+        -webkit-line-clamp: 2;
+        overflow: hidden;
+        font-size: 12px;
+        font-family: MicrosoftYaHei;
+        color: #75797D;
+        text-overflow: ellipsis;
+        word-break: break-all;
+        word-wrap: break-word;">备注:{{item.remark || '无'}}</span>
+        <div class="remBottom">
+          <span class="editBtn" @click='clickEditBtn(item,index)'>编辑备注</span>
+        </div>
+      </div> -->
     </div>
     <div class="item add" @click="createTest">
       <i class="el-icon-circle-plus add-icon"></i>
@@ -57,5 +100,29 @@
   <div v-if="loading" class="loading">加载中...</div>
   <div v-if="noMore" class="loading">没有更多了</div>
   <!-- 分享设置 -->
-  <ShareSetting v-if="isShareSetting" :close="closeShare" :shareModel="shareModel"></ShareSetting>
+  <ShareSetting v-if="isShareSetting" :close="closeShare" :shareModel="shareModel" @child-event="refreshItem">
+  </ShareSetting>
+  <el-dialog class=" popView" :visible.sync="showDialog" top='0' :show-close='false' :close-on-click-modal='false'
+    :close-on-press-escape='false'>
+    <div class="content">
+      <div class="main">
+        <div class="title">编辑&查看备注</div>
+        <el-input class="textarea" type="textarea" placeholder="请输入备注" v-model="remark" maxlength="500"
+          show-word-limit />
+      </div>
+      <div class="btns">
+        <div class="okBtn Btn" @click='saveRemark'>确认</div>
+        <div class="cancleBtn Btn" @click='showDialog=false'>取消</div>
+      </div>
+    </div>
+  </el-dialog>
+  <div v-show="seen" class="hover_con" :style="positionStyle">
+    <div class="text" style="display: -webkit-box;
+    -webkit-box-orient: vertical;
+    -webkit-line-clamp: 3;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    word-break: break-all;
+    word-wrap: break-word;">{{currRemark}}</div>
+  </div>
 </div>

+ 138 - 4
src/views/myHistoryTest/myHistoryTest.js

@@ -37,10 +37,24 @@ export default {
       orderList: [{ orderName: "按创建时间排序", orderType: "created" }, { orderName: "按更新时间排序", orderType: "updated" }],
       currOrderName: "更新时间",
       currOrderType: "",
+      currOrderStatus: "项目状态",
+      selOrderType: "",
+      statusList: [{ orderName: "已收到数据", orderStatus: "1" }, { orderName: "未收到数据", orderStatus: "0" }],
       shareModel: "",
       pageNo: 1,
       dataList: [],
-      total: 0
+      total: 0,
+      itemCopyClass: "itemCopy",
+      morehoverClass: "morehover",
+      showDialog: false,
+      remark: '',
+      clickIndex: -1,
+      clickItem: null,
+      seen: false,
+      x: 0,
+      y: 0,
+      positionStyle: { top: '20px', left: '20px' },
+      currRemark: "",
     }
   },
   computed: {
@@ -73,6 +87,23 @@ export default {
     this.getTestList(true);
   },
   methods: {
+    more(isShow, item, index) {
+      item.isMore = isShow;
+      this.dataList.splice(index, 1, item);
+    },
+    operationCommand(command, item, index) {
+      if (command == "download") {
+        console.log("下载");
+        this.download(item);
+      } else if (command == "share") {
+        console.log("分享");
+        this.clickIndex = index;
+        this.shareTest(item);
+      } else if (command == "del") {
+        console.log("删除");
+        this.deleteTest(item, index);
+      }
+    },
     dataformat(val) {
       return timeFormat.dateStr(val);
     },
@@ -87,7 +118,8 @@ export default {
         "orderType": this.currOrderType,
         "ownHouseName": this.ownHouseName == "所属项目" ? '' : this.ownHouseName,
         "pageNo": this.pageNo++,
-        "pageSize": isFirst ? 39 : 40
+        "pageSize": isFirst ? 39 : 40,
+        "houseAnswerStatus": this.selOrderType
       }
       api.testList(data).then((res) => {
         if (res.success) {
@@ -125,9 +157,39 @@ export default {
       this.currOrderType = command.orderType;
       this.getTestList(true);
     },
+    orderStatus(command) {
+      console.log(command);
+      this.currOrderStatus = command.orderName;
+      this.selOrderType = command.orderStatus;
+      this.getTestList(true);
+    },
     createTest() {
       this.$router.push({ path: '/cncTestLists' });
     },
+    download(item) {
+      let data = {
+        "id": item._id
+      }
+      console.log("下载数据", data);
+      api.exportExcelPath(data).then((res) => {
+        if (res.success) {
+          console.log("下载数据", res);
+          this.$message.success("下载成功");
+          var tempLink = document.createElement("a");
+          tempLink.style.display = "none";
+          tempLink.href = res.single;
+          tempLink.setAttribute("download", "用户来源导出表");
+          if (typeof tempLink.download === "undefined") {
+            tempLink.setAttribute("target", "_blank");
+          }
+          document.body.appendChild(tempLink);
+          tempLink.click();
+          document.body.removeChild(tempLink);
+        } else {
+          this.$message.error("下载失败,请重试");
+        }
+      })
+    },
     deleteTest(item, index) {
       const h = this.$createElement;
       this.$msgbox({
@@ -199,7 +261,8 @@ export default {
             shareTitle: res.single.shareTitle,
             shareContent: res.single.shareContent,
             shareImg: res.single.shareImg,
-            shareUrl: res.single.shareUrl
+            shareUrl: res.single.shareUrl,
+            remark: item.remark
           };
           this.isShareSetting = true;
         } else {
@@ -207,9 +270,80 @@ export default {
         }
       })
     },
+    excelReport(item) {
+      console.log(item);
+      let maindata = {
+        houseId: this.houseId
+      };
+      console.log("***expot***", maindata);
+      editorApi.exportStaffSource(maindata).then((res) => {
+        if (res.success) {
+          var tempLink = document.createElement("a");
+          tempLink.style.display = "none";
+          tempLink.href = result.data.single.url;
+          tempLink.setAttribute("download", "用户来源导出表");
+          if (typeof tempLink.download === "undefined") {
+            tempLink.setAttribute("target", "_blank");
+          }
+          document.body.appendChild(tempLink);
+          tempLink.click();
+          document.body.removeChild(tempLink);
+        } else {
+          this.$message.error(result.data.message);
+        }
+      })
+    },
     closeShare() {
       this.currItem = "";
       this.isShareSetting = false;
-    }
+      this.clickIndex = -1;
+    },
+    clickEditBtn(item, index) {
+      this.showDialog = true;
+      this.remark = item.remark || '';
+      this.clickIndex = index;
+      this.clickItem = item;
+    },
+    saveRemark() {
+      let param = {
+        id: this.clickItem._id,
+        remark: this.remark,
+        updator: "admin"
+      };
+      editorApi.saveTheme(param).then(res => {
+        if (res.success) {
+          this.$message.success("保存成功");
+          this.dataList[this.clickIndex].remark = this.remark;
+          this.clickCancleBtn();
+        } else {
+          this.$message.error("数据加载失败,请重试");
+          this.clickCancleBtn();
+        }
+      });
+    },
+    refreshItem(remark) {
+      this.dataList[this.clickIndex].remark = remark;
+      this.clickIndex = -1;
+    },
+    clickCancleBtn() {
+      this.remark = '';
+      this.clickIndex = -1;
+      this.showDialog = false;
+    },
+    enterssss(item) {
+      if (item.remark) {
+        this.seen = true;
+        this.currRemark = item.remark;
+      }
+    },
+    leave: function () {
+      this.seen = false;
+      this.currRemark = "";
+    },
+    updateXY: function (event) {
+      this.x = event.pageX;
+      this.y = event.pageY;
+      this.positionStyle = { top: this.y + 20 + 'px', left: this.x + 20 + 'px' };
+    },
   },
 }

+ 145 - 4
src/views/myHistoryTest/myHistoryTest.scss

@@ -4,6 +4,21 @@
   height: 100%;
   background: rgba(237,239,247,1);
 }
+.hover_con {
+  position: absolute;
+  background: rgba(0,0,0,0.8);
+  box-sizing: border-box;
+  max-width: 160px;
+  font-size: 12px;
+  max-height: 70px;
+  color: #FFFFFF;
+
+}
+.text {
+  padding: 5px;
+  max-height: 62px;
+  line-height: 18px;
+}
 
 .history-tools {
   width: 1180px;
@@ -63,7 +78,7 @@
   .item {
     position: relative;
     width: 220px;
-    height: 270px;
+    height: 260px;
     background: #FFFFFF;
     box-shadow: 0 5px 11px 0 rgba(78,93,255,0.14);
     border-radius: 6px;
@@ -72,6 +87,11 @@
     display: flex;
     flex-direction: column;
     color:rgba(153,160,182,1);
+    .morelist{
+      position: absolute;
+      top: 40px;
+      left: 0px;
+    }
     .tools {
       display: none;
       position:absolute;
@@ -84,7 +104,18 @@
         height: 28px;
         cursor:pointer;
         margin-right: 5px;
+        .more{
+          width: 28px;
+          height: 28px;
+          background: url(../../assets/images/more_nor.png) center no-repeat;
+          background-size: cover;
+        }
+        .more:hover {
+          background: url(../../assets/images/more_sel.png) center no-repeat;
+          background-size: cover;
+        }
       }
+      
       .delete {
         background: url(../../assets/images/delete_nor.png) center no-repeat;
         background-size: cover;
@@ -118,9 +149,10 @@
         background-size: cover;
       }
     }
-    .item-img {
+    .item-img1 {
       width: 100%;
-      height:156px;
+      min-height:141px;
+      max-height: 141px;
       border-radius:6px 6px 0px 0px;
       object-fit: cover;
       display: flex;
@@ -140,6 +172,8 @@
       color:rgba(51,51,51,1);
       line-height:21px;
       font-size: 16px;
+      max-height: 42px;
+      min-height: 42px;
     }
     .desc {
       margin: 10px;
@@ -152,6 +186,42 @@
       flex-direction: row;
       justify-content: space-between;
     }
+    .remarkBg{
+      margin: 0 10px 10px; 
+      border: 1px solid #EDEFF7;
+      border-radius: 3px;
+      padding: 10px 5px 5px;  
+      .remark{
+        height: 34px;
+        line-height: 17px;
+        margin-bottom: 5px;
+      }
+      .remBottom{
+        display: flex;
+        justify-content: flex-end;
+        .editBtn{
+          border: 1px solid #4F5DFF;
+          border-radius: 10px;
+          font-size: 10px;
+          color: #000000;
+          padding: 0 5px;
+          height: 20px;
+          line-height: 20px;
+          text-align: center;
+          cursor: pointer;
+        }
+      }
+      
+    }
+  }
+  .morehover {
+    box-shadow:0px 5px 11px 0px rgba(78,93,255,0.42);
+    .tools {
+      display: block;
+    }
+    .title {
+      color: rgba(78,93,255,1);
+    }
   }
   .item:hover{
     box-shadow:0px 5px 11px 0px rgba(78,93,255,0.42);
@@ -206,4 +276,75 @@
   height: 40px;
   line-height: 40px;
   color: #4E5DFF;
-}
+}
+.popView{
+  display: flex;
+    justify-content: center;
+    align-items: center;
+    .el-dialog {
+      max-width: 600px;
+      max-height: 400px;
+      padding: 30px 40px 40px;
+      box-sizing: border-box;
+      border-radius: 15px;
+      // background-color:red;
+      .el-dialog__header,
+      .el-dialog__footer {
+        display: none;
+      }
+      .el-dialog__body {
+        padding: 0;
+        .content {
+          width: 100%;
+          .main {
+            width: 100%;
+            .title {
+              width: 100%;
+              font-size: 20px;
+              line-height: 28px;
+              color: #000;
+            }
+            .textarea{
+              margin-top: 15px;
+              .el-textarea__inner{
+                padding: 10px 20px 30px;
+                color: #75797D;
+                font-size: 14px;
+                line-height: 26px;
+                box-sizing: border-box;
+                height: 212px;
+                width: 100%;
+                resize: none;
+              }
+            }
+            
+          }
+          .btns{
+            display: flex;
+            margin-top: 30px;
+            justify-content: center;
+            align-items: center;
+            .Btn {
+              width: 102px;
+              height: 44px;
+              font-size: 20px;
+              line-height: 44px;
+              border-radius: 22px;
+              text-align: center;
+              cursor: pointer;
+            }
+            .okBtn {
+              background-color: #4F5DFF ;
+              color: #fff;
+            }
+            .cancleBtn {
+              background-color: #EAECF5;
+              color: #56616D;
+              margin-left: 20px;
+              
+            }
+          }
+        }
+      }
+    }
+  }

+ 1 - 1
src/views/myHistoryTest/myHistoryTest.vue

@@ -2,6 +2,6 @@
 </template>
 <script src="./myHistoryTest.js">
 </script>
-<style scoped lang="scss">
+<style lang="scss">
 @import "./myHistoryTest.scss";
 </style>

+ 91 - 0
src/views/previewPage/previewPage.html

@@ -0,0 +1,91 @@
+<div class="content">
+  <div @click="xxxxx" class="dowload"> 下载到本地 </div>
+  <div id="pdfDom" class="pdfContent">
+    <div class="pHeader">
+      <div class="projectTitle">项目答题数据</div>
+      <div class="testList"> <span v-for="(item, index) in options" :key="index">【{{item.label}}】</span></div>
+      <div class="tip">截止到{{currentDate}},问卷共{{answerData.answerJoin || 0}}人参与,完成全部题目的有{{answerData.answerAll || 0}}人。
+      </div>
+    </div>
+    <div class="filterResult" v-if="filterStr">已为您筛选出【{{filterStr}}】共{{answerData.answerCondition}}人,此条件下的用户题目答题情况如下:
+    </div>
+    <div v-if="!isCrossAnalyse">
+      <!-- 答题统计->表格 -->
+      <div class="result" v-if="isShowTable">
+        <div class="resultItem" v-for="(item, index) in answerData.questionList" :key="index">
+          <div class="testLable"
+            v-if="index == 0 || answerData.questionList[index-1].belongTestOrder != answerData.questionList[index].belongTestOrder">
+            测试{{item.belongTestOrder}}:{{item.lable}}</div>
+          <div class="resultTitle"><img v-if="item.isFilter" style="width: 32px;height: 17px;margin-right: 5px;"
+              src="https://dm.static.elab-plus.com/diaoyanbao/%E6%9D%A1%E4%BB%B6%E6%A0%87%E8%AE%B0@2x.png" alt="">
+            题目{{index+1}}:{{item.content}}[{{item.chooseType == '1'? '单选':'多选'}}]<span
+              v-if="item.testOrderList.length">(包含测试<span v-for="(testOrder,textIndex) in item.testOrderList"
+                :key="index">{{testOrder}}<span
+                  v-if="textIndex!=(item.testOrderList.length-1)">、</span></span>中的数据)</span></div>
+          <div class="resultTable">
+            <div class="tableHeader">
+              <div class="option">选项</div>
+              <div class="numbers">答题人数</div>
+              <div class="percent">占该题总答题人数百分比</div>
+            </div>
+            <div class="tableRow" v-for="(optionItem, optionIndex) in item.optionList" :key="optionIndex">
+              <div class="option">{{optionItem.content}}</div>
+              <div class="numbers">{{optionItem.answerCount}}</div>
+              <div class="percent">
+                <div style="width: 100%;">
+                  <el-progress
+                    :percentage="parseInt(item.answerTotal==0?0:((optionItem.answerCount/item.answerTotal)*100).toFixed(0))"
+                    color="#4E5DFF" :stroke-width="8">
+                  </el-progress>
+                </div>
+              </div>
+            </div>
+            <div class="tableRow">
+              <div class="option">总计</div>
+              <div class="numbers">{{item.answerTotal}}</div>
+              <div class="percent">_ _</div>
+            </div>
+          </div>
+        </div>
+      </div>
+      <div class="chart" v-if="!isShowTable">
+        <div class="chartItem" v-for="(item, index) in chartData" :key="index">
+          <div class="chartTitle"><span v-if="item.isFilter"
+              class="filterTag">条件</span>题目{{index+1}}:{{item.content}}[{{item.chooseType == '1'? '单选':'多选'}}]<span
+              v-if="item.testOrderList.length">(包含测试<span v-for="(testOrder,textIndex) in item.testOrderList"
+                :key="index">{{testOrder}}<span
+                  v-if="textIndex!=(item.testOrderList.length-1)">、</span></span>中的数据)</span>
+          </div>
+          <div class="chartData">
+            <HistogramHorizontal :id="'c1'" :chartId="'c'+item.questionId" :chart-data="item.data">
+            </HistogramHorizontal>
+          </div>
+        </div>
+      </div>
+    </div>
+    <div v-if="isCrossAnalyse" class="crossAnalyse">
+      <div class="crossAnalyseTable" v-for="(item, index) in crossAnalyse" :key="index">
+        <div class="crossAnalyseTitle">题目{{index+1}}:{{item.name}}</div>
+        <div class="crossAnalyseChart">
+          <HistogramHorizontals :id="'c2'" :chartId="'caaaaa'+index" :chart-data="item.data">
+          </HistogramHorizontals>
+        </div>
+        <div class="table">
+          <div class="caTable">
+            <div class="headerRow" style="width: 100px;">X\Y</div>
+            <div class="headerRow" v-for="(item1,index1) in item.table[0].title" :key="index1" v-if="index1"
+              :style="`width:${740/(item.table[0].title.length-1 || 1)}px`">{{item1}}</div>
+            <div class="headerRow" style="width: 100px;">总计(人次)</div>
+          </div>
+          <div class="caTable" v-for="(items,indexs) in item.table" :key="indexs">
+            <div class="tabkeRow" style="width: 100px;">{{items.name}}</div>
+            <div class="tabkeRow" v-for="(item0,index0) in items.value" :key="index0" v-if="index0"
+              :style="`width:${740/(items.value.length-1 || 1)}px`">
+              {{item0}} ({{items.value[0]==0?0:((item0 / items.value[0]) * 100).toFixed(0)}}%)</div>
+            <div class="tabkeRow" style="width: 100px;">{{items.value[0]}}</div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</div>

+ 40 - 0
src/views/previewPage/previewPage.js

@@ -0,0 +1,40 @@
+import timeFormat from '../../util/time'
+import HistogramHorizontal from "../../components/HistogramHorizontal";
+import HistogramHorizontals from "../../components/HistogramHorizontals";
+export default {
+  components: {
+    HistogramHorizontal, HistogramHorizontals
+  },
+
+  data() {
+    return {
+      currentDate: null,
+      answerData: null,
+      chartData: null,
+      options: null,
+      filterStr: null,
+      isShowTable: null,
+      isCrossAnalyse: null,
+      crossAnalyse: null,
+    }
+  },
+  created() {
+    this.chartData = this.$route.params.chartData
+    this.currentDate = this.$route.params.currentDate
+    this.answerData = this.$route.params.answerData
+    this.options = this.$route.params.options
+    this.filterStr = this.$route.params.filterStr
+    this.isShowTable = this.$route.params.isShowTable
+    this.isCrossAnalyse = this.$route.params.isCrossAnalyse
+    this.crossAnalyse = this.$route.params.crossAnalyse
+    console.log("xXXXX", this.$route.params);
+
+    const routerParams = this.$route.query.filterStr;
+    console.log("接受的pdf的值:", routerParams);
+  },
+  methods: {
+    xxxxx() {
+      this.$getPdf('exportBox', '测试截屏');
+    }
+  },
+}

+ 361 - 0
src/views/previewPage/previewPage.scss

@@ -0,0 +1,361 @@
+.content {
+  background: #edeff7;
+  padding: 0px;
+}
+.dowload {
+  width:100px;
+  height:30px;
+  background:rgba(78,93,255,1);
+  border-radius:15px;
+  font-size:12px;
+  font-family:STYuanti-SC-Regular,STYuanti-SC;
+  font-weight:400;
+  color:rgba(255,255,255,1);
+  line-height:30px;
+  text-align: center;
+  margin: 0 auto;
+  cursor: pointer;
+  position: fixed;
+  top: 20px;
+  right: 20px;
+}
+.pdfContent {
+  width: 1180px;
+  margin: 0 auto;
+  background: white;
+  .pHeader{
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    border-bottom: 1px solid #E8E8E8;
+    .projectTitle {
+      margin-top: 86px;
+      margin-bottom: 16px;
+      font-size:36px;
+      font-family:PingFangSC-Medium,PingFang SC;
+      font-weight:500;
+      color:rgba(51,51,51,1);
+      line-height:50px;
+    }
+    .testList {
+      font-size:18px;
+      font-family:PingFangSC-Regular,PingFang SC;
+      font-weight:400;
+      color:rgba(51,51,51,1);
+      line-height:25px;
+    }
+    .tip {
+      font-size:18px;
+      font-family:PingFangSC-Medium,PingFang SC;
+      font-weight:500;
+      color:rgba(51,51,51,1);
+      line-height:25px;
+      margin-bottom: 23px;
+    }
+  }
+  .filterResult {
+    width: 960px;
+    margin: 0 auto;
+    font-size:14px;
+    font-family:PingFangSC-Regular,PingFang SC;
+    font-weight:400;
+    color:rgba(51,51,51,1);
+    line-height:20px;
+    border-bottom: 1px dashed #E8E8E8;
+    padding-top: 23px;
+    padding-bottom: 15px;
+  }
+  .result {
+    margin-top: 30px;
+    padding: 0px 120px;
+    box-sizing: border-box;
+    .resultItem {
+      margin-top: 36px;
+      padding-bottom: 20px;
+      border-bottom:1px dashed rgba(202,204,210,1);
+      .testLable {
+        font-size:18px;
+        font-family:PingFangSC-Medium,PingFang SC;
+        font-weight:500;
+        color:rgba(78,93,255,1);
+        line-height:25px;
+        margin-bottom: 10px;
+        padding-bottom: 10px;
+        width: 100%;
+        border-bottom: 1px dashed #E8E8E8;
+      }
+      .resultTitle {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        font-size:18px;
+        font-family:PingFangSC-Medium,PingFang SC;
+        font-weight:500;
+        color:rgba(51,51,51,1);
+        line-height:25px;
+      }
+      .resultTable {
+
+        border-radius:4px;
+        border:1px solid rgba(232,232,232,1);
+        margin-top: 8px;
+      }
+      .tableHeader {
+        display: flex;
+        flex-direction: row;
+        height: 32px;
+        background:rgba(250,250,250,1);
+        border-radius:4px 0px 0px 0px;
+        font-size:14px;
+        font-family:PingFangSC-Medium,PingFang SC;
+        font-weight:500;
+        color:rgba(0,0,0,0.85);
+        line-height:21px;
+        align-items:flex-end;
+        .option {
+         flex-grow: 2;
+         padding-left: 25px;
+         box-sizing: border-box;
+        }
+        .numbers {
+          width:236px;
+          height: 100%;
+          padding-top: 8px;
+          padding-left: 25px;
+          box-sizing: border-box;
+          border-left:1px solid rgba(232,232,232,1);
+          border-right:1px solid rgba(232,232,232,1);
+        }
+        .percent {
+          width: 408px;
+          padding-left: 25px;
+          box-sizing: border-box;
+        }
+      }
+      .tableRow {
+        display: flex;
+        flex-direction: row;
+        min-height: 32px;
+        font-size:14px;
+        font-family:PingFangSC-Regular,PingFang SC;
+        font-weight:400;
+        color:rgba(0,0,0,0.65);
+        line-height:21px;
+        .option {
+         flex-grow: 2;
+         height: 100%;
+         padding-top: 8px;
+         padding-left: 25px;
+         box-sizing: border-box;
+         border-top:1px solid rgba(232,232,232,1);
+        padding: 8px 15px;
+        }
+        .numbers {
+          width:236px;
+          min-height: 100%;
+          padding: 0px 15px;
+          padding-left: 25px;
+          box-sizing: border-box;
+          border-left:1px solid rgba(232,232,232,1);
+          border-right:1px solid rgba(232,232,232,1);
+          border-top:1px solid rgba(232,232,232,1);
+          flex-shrink: 0;
+          display: flex;
+          align-items: center;
+        }
+        .percent {
+          width: 408px;
+          min-height: 100%;
+          padding-left: 25px;
+          box-sizing: border-box;
+          border-top:1px solid rgba(232,232,232,1);
+          flex-shrink: 0;
+          display: flex;
+          align-items: center;
+        }
+      }
+    }
+  }
+  .chart {
+    display: flex;
+    flex-direction: column;
+    margin-top: 30px;
+    padding: 0px 120px;
+    box-sizing: border-box;
+    .chartItem {
+      display: flex;
+      flex-direction: column;
+      .chartTitle {
+        font-size:18px;
+        font-family:PingFangSC-Medium,PingFang SC;
+        font-weight:500;
+        color:rgba(51,51,51,1);
+        line-height:25px;
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        .filterTag{
+          display: block;
+          width: 32px;
+          height: 16px;
+          background:rgba(255,106,106,1);
+          border-radius:8px;
+          font-size:12px;
+          font-family:PingFangSC-Regular,PingFang SC;
+          font-weight:400;
+          color:rgba(255,255,255,1);
+          line-height:16px;
+          text-align: center;
+          margin-right: 5px;
+        }
+      }
+      .chartData {
+        width: 100%;
+        margin: 10px 0px;
+      }
+    }
+  }
+  .crossAnalyse {
+    width: 100%;
+    background: white;
+    border-radius:6px;
+    padding: 24px 120px;
+    box-sizing: border-box;
+    .crossFilter{
+      background:rgba(250,250,250,1);
+      border-radius:6px;
+      display: flex;
+      flex-direction: row;
+      justify-content: center;
+      flex-wrap:wrap;
+      .xyFilter {
+        width: 360px;
+        .el-cascader {
+          width: 320px;
+          background:rgba(241,241,241,1);
+          line-height: 30px;
+          font-size:14px;
+          color:rgba(51,51,51,1);
+          .el-input__inner {
+            height: 30px;
+            line-height: 30px;
+            background:rgba(241,241,241,1);
+          }
+          .el-input__icon {
+            line-height: 30px;
+          }
+        }
+        .addfilter{
+          width:320px;
+          height:30px;
+          border:1px dashed rgba(202,204,210,1);
+          margin-top: 8px;
+          display: flex;
+          flex-direction: row;
+          justify-content: center;
+          align-items: center;
+          cursor: pointer;
+          .addfilterIcon {
+            width: 74px;
+            height: 18px;
+          }
+        }
+      }
+      .crossFilterTitle {
+        font-size:14px;
+        font-family:PingFangSC-Medium,PingFang SC;
+        font-weight:500;
+        color:rgba(51,51,51,1);
+        line-height:20px;
+      }
+      .crossFilterSubTitle {
+        font-size:12px;
+        font-family:PingFangSC-Regular,PingFang SC;
+        font-weight:400;
+        color:rgba(51,51,51,1);
+        line-height:20px;
+      }
+      .analyse {
+        width: 100%;
+        margin: 16px 0px;
+        display: flex;
+        flex-direction: row;
+        .startAnalyse {
+          margin-left: 90px;
+          width:80px;
+          height:28px;
+          background:rgba(78,93,255,1);
+          border-radius:14px;
+          font-size:14px;
+          font-family:PingFangSC-Medium,PingFang SC;
+          font-weight:500;
+          color:rgba(255,255,255,1);
+          line-height:28px;
+          text-align: center;
+          cursor: pointer;
+        }
+        .analyseTip {
+          font-size:12px;
+          font-family:PingFangSC-Regular,PingFang SC;
+          font-weight:400;
+          color:rgba(255,0,0,1);
+          line-height:28px;
+          margin-left: 8px;
+        }
+      }
+    }
+    .crossAnalyseTable {
+      .crossAnalyseTitle {
+        font-size:18px;
+        font-family:PingFangSC-Medium,PingFang SC;
+        font-weight:500;
+        color:rgba(51,51,51,1);
+        line-height:25px;
+        margin-top: 32px;
+      }
+      .crossAnalyseChart {
+        width: 100%;
+        margin: 8px 0px;
+      }
+      .table{
+        border-radius:4px;
+        border-top:1px solid rgba(232,232,232,1); 
+        border-left:1px solid rgba(232,232,232,1); 
+      }
+      .caTable {
+        display: flex;
+        flex-direction: row;
+        .headerRow {
+          background:rgba(250,250,250,1);
+          border-radius:4px 0px 0px 0px;
+          font-size:14px;
+          font-family:PingFangSC-Medium,PingFang SC;
+          font-weight:500;
+          color:rgba(0,0,0,0.85);
+          line-height:21px;
+          align-items:flex-end;
+          padding-top: 8px;
+          padding-bottom: 12px;
+          box-sizing: border-box;
+          border-bottom: 1px solid #E8E8E8;
+          border-right: 1px solid #E8E8E8;
+        }
+        .tabkeRow {
+          font-size:14px;
+          font-family:PingFangSC-Regular,PingFang SC;
+          font-weight:400;
+          color:rgba(0,0,0,0.65);
+          line-height:21px;
+          align-items:flex-end;
+          padding-top: 8px;
+          padding-bottom: 1px;
+          padding-left: 5px;
+          box-sizing: border-box;
+          border-bottom: 1px solid #E8E8E8;
+          border-right: 1px solid #E8E8E8;
+        }
+        
+      }
+    }
+  }
+}

+ 7 - 0
src/views/previewPage/previewPage.vue

@@ -0,0 +1,7 @@
+<template src='./previewPage.html'>
+</template>
+<script src="./previewPage.js">
+</script>
+<style lang="scss">
+@import "./previewPage.scss";
+</style>

+ 228 - 0
src/views/testData/testData.html

@@ -0,0 +1,228 @@
+<div class="page" style="overflow:auto">
+  <!-- 头部 -->
+  <HeaderData></HeaderData>
+  <!-- 题目筛选 -->
+  <div class="testData">
+    <div class="testList">
+      <div class="testProject">
+        <el-dropdown trigger="click" @command="projectCommand">
+          <el-button type="primary">{{ownHouseName}} <i class="el-icon-caret-bottom icon-right"></i>
+          </el-button>
+          <el-dropdown-menu slot="dropdown">
+            <el-dropdown-item>全部</el-dropdown-item>
+            <el-dropdown-item v-for="(item,index) in houseList" :key="item.houseId" :command="item">
+              {{item.houseName}}</el-dropdown-item>
+          </el-dropdown-menu>
+        </el-dropdown>
+      </div>
+      <div class="testItem">
+        <div class="itemArrow"><i class="el-icon-arrow-left"></i></div>
+        <div class="testContent">
+          <div class="testTopic" :class="{testTopicSel:item.isSelected}" v-for="(item,index) in dataList"
+            :key="item.created">
+            <div id></div>
+            <div style="display: -webkit-box;
+            -webkit-box-orient: vertical;
+            -webkit-line-clamp: 3;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            word-break: break-all;
+            word-wrap: break-word;">{{index+1}}.{{item.title}}</div>
+            <img v-if="item.isSelected" class="testSel" src="
+              https://dm.static.elab-plus.com/diaoyanbao/%E5%A4%9A%E9%80%89-%E9%80%89%E4%B8%AD@2x.png" alt=""
+              @click="changeTest(item)">
+            <img v-if="!item.isSelected" class="testSel"
+              src="https://dm.static.elab-plus.com/diaoyanbao/%E5%A4%9A%E9%80%89-%E6%9C%AA%E9%80%89@2x.png" alt=""
+              @click="changeTest(item)">
+          </div>
+        </div>
+        <div class="itemArrow"><i class="el-icon-arrow-right"></i></div>
+      </div>
+    </div>
+    <div class="testTip">
+      <div v-if="!isCrossAnalyse"><span
+          v-if="currentDate">截止到{{currentDate}},问卷共{{answerData.answerJoin || 0}}人参与,完成全部题目的有{{answerData.answerAll || 0}}人。</span>
+      </div>
+      <div v-if="isCrossAnalyse" style="display: flex;align-items:center;">
+        <div class="analyseBag">
+          <div class="analyseBagTitle">
+            <el-dropdown trigger="click" @command="analyseCommand">
+              <el-button type="primary">{{analyseCommandSel}}<i class="el-icon-caret-bottom icon-right"></i>
+              </el-button>
+              <el-dropdown-menu slot="dropdown">
+                <el-dropdown-item command="-1">全部</el-dropdown-item>
+                <el-dropdown-item command="0">数据包</el-dropdown-item>
+                <el-dropdown-item command="1">区域</el-dropdown-item>
+              </el-dropdown-menu>
+            </el-dropdown>
+          </div>
+          <div class="analyseBagList">
+            <el-cascader v-model="analyseValue" :options="analyseOptions"
+              :props="{ checkStrictly: analyseCommandSel== '区域' ? true : false }"
+              @change="handleAnalyseChange(analyseValue)">
+            </el-cascader>
+          </div>
+        </div>
+        <div class="addBag" @click="isCrossAnalyse=false"><i class="el-icon-circle-plus-outline"></i><span> 新建数据包</span>
+        </div>
+      </div>
+      <div class="switchItem">
+        <div class="switch" :class="{ switchSelected: !isCrossAnalyse}" @click="isCrossAnalyse=false">答题统计</div>
+        <div class="switch" :class="{ switchSelected: isCrossAnalyse}" @click="isCrossAnalyse=true">交叉分析</div>
+      </div>
+    </div>
+    <div class="answer" v-if="!isCrossAnalyse">
+      <div class="filter">
+        <img v-if="isFilter" class="filterIcon"
+          src="https://dm.static.elab-plus.com/diaoyanbao/%E5%8F%96%E6%B6%88%E7%AD%9B%E9%80%89%E6%8C%89%E9%92%AE@2x.png"
+          alt="" @click="isFilter=false">
+        <img v-if="!isFilter" class="filterIcon"
+          src="https://dm.static.elab-plus.com/diaoyanbao/%E7%AD%9B%E9%80%89%E6%8C%89%E9%92%AE@2x.png" alt=""
+          @click="isFilter=true">
+        <div class="rightFilter">
+          <div class="rightFilterItem" :class="{ rightFilterItemSel: !isShowTable}" @click="isShowTable=false">图形</div>
+          <div class="rightFilterItem" :class="{ rightFilterItemSel: isShowTable}" @click="isShowTable=true">表格</div>
+        </div>
+      </div>
+      <div class="filterContent" v-if="isFilter">
+        <div class="filterView">
+          <div class="filterItem" v-for="(items, indexs) in filterList" :key="indexs">
+            <div class="filterTitle"><span v-if="indexs==0">选择条件</span></div>
+            <div class="filterAnswer">
+              <el-cascader v-model="value[indexs]" :options="options" @change="handleChange(value[indexs],indexs)">
+              </el-cascader>
+            </div>
+            <div class="filterReply" v-if="questionListSel[indexs]">
+              <el-checkbox-group v-model="checkList[indexs]">
+                <el-checkbox v-for="(item, index) in questionListSel[indexs].optionList" :label="item.content"
+                  :key="index" @change="checked=>changequestionChild(checked,item, indexs)">
+                </el-checkbox>
+              </el-checkbox-group>
+            </div>
+            <div class="filterDel" @click="delFilter(indexs)"><i class="el-icon-delete"></i>
+            </div>
+          </div>
+          <div class="addfilter" @click="addFilter">
+            <img class="addfilterIcon"
+              src="https://dm.static.elab-plus.com/diaoyanbao/%E6%B7%BB%E5%8A%A0%E6%9D%A1%E4%BB%B6%E6%8C%89%E9%92%AE@2x.png"
+              alt="">
+          </div>
+          <div class="filterSave">
+            <div class="saveLocation" @click="getAnswerData">筛选</div>
+            <div class="saveOnLine" @click="saveOnLine">保存此筛选条件作为数据包</div>
+          </div>
+        </div>
+        <div class="filterResult">已为您筛选出【{{filterStr}}】共{{answerData.answerCondition}}人,此条件下的用户题目答题情况如下:</div>
+      </div>
+      <!-- 答题统计->表格 -->
+      <div class="result" v-if="isShowTable">
+        <div class="resultItem" v-for="(item, index) in answerData.questionList" :key="index">
+          <div class="testLable"
+            v-if="index == 0 || answerData.questionList[index-1].belongTestOrder != answerData.questionList[index].belongTestOrder">
+            测试{{item.belongTestOrder}}:{{item.lable}}</div>
+          <div class="resultTitle"><img v-if="item.isFilter" style="width: 32px;height: 17px;margin-right: 5px;"
+              src="https://dm.static.elab-plus.com/diaoyanbao/%E6%9D%A1%E4%BB%B6%E6%A0%87%E8%AE%B0@2x.png" alt="">
+            题目{{index+1}}:{{item.content}}[{{item.chooseType == '1'? '单选':'多选'}}]<span
+              v-if="item.testOrderList.length">(包含测试<span v-for="(testOrder,textIndex) in item.testOrderList"
+                :key="index">{{testOrder}}<span
+                  v-if="textIndex!=(item.testOrderList.length-1)">、</span></span>中的数据)</span></div>
+          <div class="resultTable">
+            <div class="tableHeader">
+              <div class="option">选项</div>
+              <div class="numbers">答题人数</div>
+              <div class="percent">占该题总答题人数百分比</div>
+            </div>
+            <div class="tableRow" v-for="(optionItem, optionIndex) in item.optionList" :key="optionIndex">
+              <div class="option">{{optionItem.content}}</div>
+              <div class="numbers">{{optionItem.answerCount}}</div>
+              <div class="percent">
+                <div style="width: 100%;">
+                  <el-progress
+                    :percentage="parseInt(item.answerTotal==0?0:((optionItem.answerCount/item.answerTotal)*100).toFixed(0))"
+                    color="#4E5DFF" :stroke-width="8">
+                  </el-progress>
+                </div>
+              </div>
+            </div>
+            <div class="tableRow">
+              <div class="option">总计</div>
+              <div class="numbers">{{item.answerTotal}}</div>
+              <div class="percent">_ _</div>
+            </div>
+          </div>
+        </div>
+      </div>
+      <!-- 答题统计->图形 -->
+      <div class="chart" v-if="!isShowTable">
+        <div class="chartItem" v-for="(item, index) in chartData" :key="index">
+          <div class="chartTitle">题目{{index+1}}:{{item.content}}[{{item.chooseType == '1'? '单选':'多选'}}]<span
+              v-if="item.testOrderList.length">(包含测试<span v-for="(testOrder,textIndex) in item.testOrderList"
+                :key="index">{{testOrder}}<span
+                  v-if="textIndex!=(item.testOrderList.length-1)">、</span></span>中的数据)</span>
+          </div>
+          <div class="chartData">
+            <HistogramHorizontal :id="'c1'" :chartId="'c'+item.questionId" :chart-data="item.data">
+            </HistogramHorizontal>
+          </div>
+        </div>
+      </div>
+    </div>
+    <div v-if="isCrossAnalyse" class="crossAnalyse">
+      <div class="crossFilter">
+        <div class="xyFilter">
+          <div><span class="crossFilterTitle">自变量 X</span><span
+              class="crossFilterSubTitle">(一般为样本属性,例如性别,年龄等。限2题)</span></div>
+          <div style="margin-top: 8px;" v-for="(items, indexs) in filterXList" :key="indexs">
+            <el-cascader v-model="optionsXValue[indexs]" :options="optionsX"
+              @change="handleChangeX(optionsXValue[indexs],indexs)">
+            </el-cascader>
+          </div>
+          <div class="addfilter" @click="addfilterX" v-if="filterXList.length<2">
+            <img class="addfilterIcon"
+              src="https://dm.static.elab-plus.com/diaoyanbao/%E6%B7%BB%E5%8A%A0%E6%9D%A1%E4%BB%B6%E6%8C%89%E9%92%AE@2x.png"
+              alt="">
+          </div>
+        </div>
+        <div class="xyFilter" style="margin-left: 40px;">
+          <div><span class="crossFilterTitle">因变量 Y</span><span class="crossFilterSubTitle">(您要分析的目标题目)</span></div>
+          <div style="margin-top: 8px;" v-for="(items, indexs) in filterYList" :key="indexs">
+            <el-cascader v-model="optionsYValue[indexs]" :options="optionsY"
+              @change="handleChangeY(optionsYValue[indexs],indexs)">
+            </el-cascader>
+          </div>
+          <div class="addfilter" @click="addfilterY">
+            <img class="addfilterIcon"
+              src="https://dm.static.elab-plus.com/diaoyanbao/%E6%B7%BB%E5%8A%A0%E6%9D%A1%E4%BB%B6%E6%8C%89%E9%92%AE@2x.png"
+              alt="">
+          </div>
+        </div>
+        <div class="analyse">
+          <div class="startAnalyse" @click="getCrossAnalyse">开始分析</div>
+          <div class="analyseTip">*不可选择同样的题目</div>
+        </div>
+      </div>
+      <div class="crossAnalyseTable" v-for="(item, index) in crossAnalyse" :key="index">
+        <div class="crossAnalyseTitle">题目{{index+1}}:{{item.name}}</div>
+        <div class="crossAnalyseChart">
+          <HistogramHorizontals :id="'c2'" :chartId="'caaaaa'+index" :chart-data="item.data">
+          </HistogramHorizontals>
+        </div>
+        <div class="table">
+          <div class="caTable">
+            <div class="headerRow" style="width: 100px;">X\Y</div>
+            <div class="headerRow" v-for="(item1,index1) in item.table[0].title" :key="index1" v-if="index1"
+              :style="`width:${740/(item.table[0].title.length-1 || 1)}px`">{{item1}}</div>
+            <div class="headerRow" style="width: 100px;">总计(人次)</div>
+          </div>
+          <div class="caTable" v-for="(items,indexs) in item.table" :key="indexs">
+            <div class="tabkeRow" style="width: 100px;">{{items.name}}</div>
+            <div class="tabkeRow" v-for="(item0,index0) in items.value" :key="index0" v-if="index0"
+              :style="`width:${740/(items.value.length-1 || 1)}px`">
+              {{item0}} ({{items.value[0]==0?0:((item0 / items.value[0]) * 100).toFixed(0)}}%)</div>
+            <div class="tabkeRow" style="width: 100px;">{{items.value[0]}}</div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</div>

+ 745 - 0
src/views/testData/testData.js

@@ -0,0 +1,745 @@
+import HeaderData from "../../components/HeaderData";
+import HistogramHorizontal from "../../components/HistogramHorizontal";
+import HistogramHorizontals from "../../components/HistogramHorizontals";
+import api from '../../api/test'
+import editorApi from '../../api/editor'
+import timeFormat from '../../util/time'
+import { format } from "util";
+export default {
+  components: {
+    HeaderData, HistogramHorizontal, HistogramHorizontals
+  },
+  data() {
+    return {
+      isCopy: false,
+      houseList: [],
+      ownHouseName: "所属项目",
+      dataList: [],
+      isFilter: false,
+      isShowTable: true,
+      checkList: [[]],
+      data: [],
+      value: [],
+      oldValue: [],
+      options: [],
+      questionList: [],
+      questionListSel: [],
+      filterList: [""],
+      questionChilds: [],
+      answerData: [],
+      currentDate: null,
+      filterStr: "",
+      chartData: [],
+      isCrossAnalyse: false,
+      condition: [],
+      analyseCommandSel: "全部",
+      analyseOptions: [],
+      analyseValue: [],
+      crossAnalyse: [],
+      optionsX: [],
+      optionsXValue: [],
+      optionsXOldValue: [],
+      optionsY: [],
+      optionsYValue: [],
+      optionsYOldValue: [],
+
+      filterXList: [""],
+      filterYList: [""],
+      selectedDataList: [],
+    }
+  },
+  watch: {
+    answerData: function (val) {
+      var questionList = val.questionList;
+      this.chartData = []
+      for (var i = 0; i < questionList.length; i++) {
+        var question = questionList[i];
+        var data = []
+        var optionList = question.optionList;
+        for (var j = 0; j < optionList.length; j++) {
+          var sold = question.answerTotal == 0 ? 0 : ((optionList[j].answerCount / question.answerTotal) * 100).toFixed(0)
+          data.push({ genre: optionList[j].content, sold: parseInt(sold) })
+        }
+        var conditionQuestion = { data: data, ...question }
+        this.chartData.push(conditionQuestion);
+      }
+    },
+    analyseCommandSel: function (val) {
+      this.analyseOptions = [];
+      this.analyseValue = [];
+      if (val == "全部") {
+
+      } else if (val == "数据包") {
+        var bagList = this.condition.bagList;
+        for (var i = 0; i < bagList.length; i++) {
+          this.analyseOptions.push({ value: bagList[i].analyseBagId, label: bagList[i].title, disabled: false })
+        }
+      } else {
+        var locationList = this.condition.locationList;
+        let locationTemp = []
+        for (var i = 0; i < locationList.length; i++) {
+          var item = locationList[i]
+          if (item.city == "") {
+            item.city = item.province;
+          }
+          locationTemp.push(item)
+        }
+        locationList = locationTemp;
+        let result = Object.values(locationList.reduce((m, n) => {
+          if (!m[n.province]) {
+            m[n.province] = { value: n.province, children: [] }
+          }
+          m[n.province].children.push(n)
+          return m
+        }, {}))
+        console.log("XXXX:result:", result)
+        var arr = []
+        for (var i = 0; i < result.length; i++) {
+
+          var list = result[i].children;
+          let results = Object.values(list.reduce((m, n) => {
+            if (!m[n.city]) {
+              m[n.city] = { value: n.city, label: n.city, children: [] }
+            }
+            m[n.city].children.push({ value: n.district, label: n.district })
+            return m
+          }, {}))
+          arr.push({ value: result[i].value, label: result[i].value, children: results })
+        }
+
+        this.analyseOptions = arr;
+      }
+    },
+    options: function (val) {
+      if (val) {
+        this.getCondition();
+      }
+    }
+  },
+  created() {
+    this.houseList = [];
+    editorApi.houseList().then((res) => {
+      if (res.success) {
+        this.houseList = res.list;
+      }
+    });
+    this.getTestList();
+  },
+  methods: {
+    async changeTest(item) {
+      console.log("XXXXXX1", item);
+      var list = []
+      for (var i = 0; i < this.dataList.length; i++) {
+        var element = this.dataList[i]
+        if (item._id == element._id) {
+          element.isSelected = !element.isSelected;
+        }
+        list.push(element)
+      }
+      console.log("XXXxXXX", list);
+      this.dataList = list;
+
+      this.analyseOptions = [];
+      this.analyseValue = [];
+
+      this.answerData = [];
+      this.options = []
+      this.questionList = []
+      var testThemesList = [];
+      for (var i = 0; i < this.dataList.length; i++) {
+        var element = this.dataList[i]
+        if (element.isSelected) {
+          this.getCNCTestDetail(element)
+          testThemesList.push(element);
+        }
+      }
+      this.getCNCTestDetails(testThemesList);
+
+      this.optionsX = []
+      for (var i = 0; i < this.dataList.length; i++) {
+        var element = this.dataList[i]
+        if (element.isSelected) {
+          this.getCNCTestDetailX(element)
+        }
+      }
+
+      this.optionsY = []
+      for (var i = 0; i < this.dataList.length; i++) {
+        var element = this.dataList[i]
+        if (element.isSelected) {
+          this.getCNCTestDetailY(element)
+        }
+      }
+    },
+    async getCondition() {
+      var testThemesIdList = [];
+      for (var i = 0; i < this.options.length; i++) {
+        var element = this.options[i]
+        testThemesIdList.push(element.id);
+      }
+      let data = {
+        testThemesIdList: testThemesIdList
+      }
+      api.condition(data).then((res) => {
+        if (res.success) {
+          console.log("success", res.single);
+          this.condition = res.single;
+        } else {
+          console.log("error");
+        }
+      });
+    },
+    async getCNCTestDetails(testThemesList) {
+      this.currentDate = timeFormat.getNowFormatDate();
+      var testThemesIdList = [];
+      for (var i = 0; i < testThemesList.length; i++) {
+        var element = testThemesList[i]
+        testThemesIdList.push(element._id);
+      }
+      let data = {
+        testThemesIdList: testThemesIdList
+      }
+      api.answerData(data).then((res) => {
+        if (res.success) {
+          console.log("success", res);
+          var answerData = res.single;
+          for (var i = 0; i < answerData.questionList.length; i++) {
+            var element = answerData.questionList[i]
+            if (element.belongTestOrder <= testThemesIdList.length) {
+              element.lable = testThemesList[element.belongTestOrder - 1].title;
+            }
+          }
+          console.log("answerData", answerData);
+          this.answerData = answerData;
+        } else {
+          console.log("error");
+        }
+      });
+    },
+    async getCNCTestDetail(item) {
+      let data = {
+        testThemesIdList: [item._id]
+      }
+      api.answerData(data).then((res) => {
+        if (res.success) {
+          console.log("success", res);
+          var questionList = res.single.questionList;
+          var children = []
+          for (var i = 0; i < questionList.length; i++) {
+            var question = questionList[i];
+            var disabled = false;
+            const found = this.value.find(element => element[1] == question.questionId);
+            if (found) {
+              disabled = true
+            }
+            children.push({ value: question.questionId, label: question.content, disabled: disabled })
+          }
+          var element = { value: item._id, label: item.title, children: children, id: item._id };
+          this.options.push(element);
+          this.questionList.push(questionList);
+        } else {
+          console.log("error");
+        }
+      });
+    },
+    async getCNCTestDetailX(item) {
+      let data = {
+        testThemesIdList: [item._id]
+      }
+      api.answerData(data).then((res) => {
+        if (res.success) {
+          console.log("success", res);
+          var questionList = res.single.questionList;
+          var children = []
+          for (var i = 0; i < questionList.length; i++) {
+            var question = questionList[i];
+            var disabled = false;
+
+            const foundX = this.optionsXValue.find(element => element[1] == question.questionId);
+            if (foundX) {
+              disabled = true
+            }
+            const foundY = this.optionsYValue.find(element => element[1] == question.questionId);
+            if (foundY) {
+              disabled = true
+            }
+            children.push({ value: question.questionId, label: question.content, disabled: disabled })
+          }
+          var element = { value: item._id, label: item.title, children: children, id: item._id };
+          this.optionsX.push(element);
+        } else {
+          console.log("error");
+        }
+      });
+    },
+    async getCNCTestDetailY(item) {
+      let data = {
+        testThemesIdList: [item._id]
+      }
+      api.answerData(data).then((res) => {
+        if (res.success) {
+          console.log("success", res);
+          var questionList = res.single.questionList;
+          var children = []
+          for (var i = 0; i < questionList.length; i++) {
+            var question = questionList[i];
+            var disabled = false;
+
+            const foundX = this.optionsXValue.find(element => element[1] == question.questionId);
+            if (foundX) {
+              disabled = true
+            }
+            const foundY = this.optionsYValue.find(element => element[1] == question.questionId);
+            if (foundY) {
+              disabled = true
+            }
+            children.push({ value: question.questionId, label: question.content, disabled: disabled })
+          }
+          var element = { value: item._id, label: item.title, children: children, id: item._id };
+          this.optionsY.push(element);
+        } else {
+          console.log("error");
+        }
+      });
+    },
+    handleChange(value, index) {
+      console.log(value, index, this.oldValue);
+      for (var i = 0; i < this.questionList.length; i++) {
+        var questionList = this.questionList[i]
+        for (var j = 0; j < questionList.length; j++) {
+          if (value[1] == questionList[j].questionId) {
+            if (this.oldValue.length >= index + 1) {
+              console.log("XXXXXXXXXXXXX");
+              this.setOptionsDisabled(this.oldValue[index], false);
+            }
+            this.questionListSel[index] = questionList[j];
+          }
+        }
+      }
+      this.setOptionsDisabled(value, true);
+
+      this.value[index] = value;
+      this.oldValue[index] = value;
+      this.checkList.splice(index, 1, []);
+      this.questionChilds.splice(index, 1, []);
+    },
+    handleChangeX(value, index) {
+      console.log("handleChangeX", value, index, this.optionsXOldValue);
+      for (var i = 0; i < this.questionList.length; i++) {
+        if (value[1] == this.questionList[i].questionId) {
+          if (this.optionsXOldValue.length >= index + 1) {
+            console.log("XXXXXXXXXXXXX");
+            this.setOptionsDisabledXY(this.optionsXOldValue[index], false, 0);
+            this.setOptionsDisabledXY(this.optionsYOldValue[index], false, 1);
+          }
+        }
+      }
+
+      this.setOptionsDisabledXY(value, true, 1);
+      this.setOptionsDisabledXY(value, true, 0);
+
+      this.optionsXValue[index] = value;
+      this.optionsXOldValue[index] = value;
+    },
+    handleChangeY(value, index) {
+      console.log("handleChangeX", value, index, this.optionsYOldValue);
+      for (var i = 0; i < this.questionList.length; i++) {
+        var questionList = this.questionList[i];
+        for (var j = 0; j < questionList.length; j++) {
+          if (value[1] == questionList[j].questionId) {
+            if (this.optionsYOldValue.length >= index + 1) {
+              this.setOptionsDisabledXY(this.optionsYOldValue[index], false, 1);
+              this.setOptionsDisabledXY(this.optionsYOldValue[index], false, 0);
+            }
+          }
+        }
+      }
+      this.setOptionsDisabledXY(value, true, 1);
+      this.setOptionsDisabledXY(value, true, 0);
+
+      this.optionsYValue[index] = value;
+      this.optionsYOldValue[index] = value;
+    },
+    addfilterX() {
+      this.filterXList.push('');
+    },
+    addfilterY() {
+      this.filterYList.push('');
+    },
+    handleAnalyseChange(value) {
+      console.log(value);
+    },
+    setOptionsDisabledXY(value, disabled, type = 0) {
+      var newOptions = [];
+      console.log("XXXXXXX", value)
+      var options = type == 0 ? this.optionsX : this.optionsY;
+      for (var i = 0; i < options.length; i++) {
+        var item = options[i];
+        if (item.value == value[0]) {
+          for (var j = 0; j < options[i].children.length; j++) {
+            var children = []
+            var element = options[i].children[j];
+            if (element.value == value[1]) {
+              element.disabled = disabled
+            }
+            children.push(element)
+          }
+        }
+        newOptions.push(item)
+      }
+      if (type == 0) {
+        this.optionsX = newOptions;
+      } else {
+        this.optionsY = newOptions;
+      }
+
+    },
+    setOptionsDisabled(value, disabled) {
+      var newOptions = [];
+      console.log("XXXXXXX", value)
+      for (var i = 0; i < this.options.length; i++) {
+        var item = this.options[i];
+        if (item.value == value[0]) {
+          for (var j = 0; j < this.options[i].children.length; j++) {
+            var children = []
+            var element = this.options[i].children[j];
+            if (element.value == value[1]) {
+              element.disabled = disabled
+            }
+            children.push(element)
+          }
+        }
+        newOptions.push(item)
+      }
+      this.options = newOptions;
+    },
+    addFilter() {
+      this.filterList.push('');
+      this.checkList.push([]);
+    },
+    delFilter(index) {
+      if (this.value[index]) {
+        this.setOptionsDisabled(this.value[index], false);
+      }
+
+      this.filterList.splice(index, 1);
+      this.value.splice(index, 1);
+
+      this.questionListSel.splice(index, 1);
+      this.questionChilds.splice(index, 1);
+      this.checkList.splice(index, 1);
+    },
+    projectCommand(command) {
+      if (this.houseList.indexOf(command) == -1) {
+        console.log("不存在");
+        this.ownHouseName = "所属项目";
+      } else {
+        console.log("存在", command.houseName);
+        this.ownHouseName = command.houseName;
+      }
+      this.getTestList();
+    },
+    analyseCommand(command) {
+      console.log("XXXXXXX", command)
+      if (command == -1) {
+        this.analyseCommandSel = "全部";
+      } else if (command == 0) {
+        this.analyseCommandSel = "数据包";
+      } else {
+        this.analyseCommandSel = "区域";
+      }
+      // this.getTestList();
+    },
+    changequestionChild(checked, value, index) {
+      console.log("XXXXXX", value, index, checked);
+
+      var arr = this.questionChilds;
+      if (this.questionChilds.length <= index) { // 没有
+        if (checked) {
+          console.log("选中");
+          for (var i = 0; i < this.filterList.length; i++) {
+            if (i < index) {
+              if (this.questionChilds.length < index) {
+                this.questionChilds.push([]);
+              }
+            }
+          }
+          this.questionChilds.push([value]);
+        } else {
+          console.log("取消选中")
+        }
+      } else { // 有
+        console.log("有")
+        var questionList = this.questionChilds[index];
+        if (checked) {
+          questionList.push(value)
+        } else {
+          var arr = questionList;
+          for (var i = 0; i < questionList.length; i++) {
+            var option = questionList[i];
+            if (option.optionId == value.optionId) {
+              arr.splice(i, 1);
+            }
+          }
+          questionList = arr;
+        }
+        this.questionChilds[index] = questionList;
+      }
+
+    },
+    getTestList() {
+
+      let data = {
+        "orderType": "",
+        "ownHouseName": this.ownHouseName == "所属项目" ? '' : this.ownHouseName,
+        "pageNo": 1,
+        "pageSize": 100,
+        "houseAnswerStatus": ""
+      }
+      api.testList(data).then((res) => {
+        if (res.success) {
+          this.total = res.pageModel.total;
+          this.dataList = [];
+          this.dataList.push(...res.pageModel.resultSet);
+          this.dataList.forEach(element => {
+            element.isSelected = false
+          });
+          console.log("success", this.dataList, res.pageModel);
+        } else {
+          console.log("error");
+        }
+      });
+    },
+    async getAnswerData() {
+      this.filterStr = "";
+
+      var conditionQuestionList = [];
+      var testThemesIdList = [];
+      for (var i = 0; i < this.questionChilds.length; i++) {
+        var question = this.questionChilds[i];
+        var value = this.value[i];
+        var optionList = [];
+        for (var j = 0; j < question.length; j++) {
+          optionList.push({ optionId: question[j].optionId })
+          this.filterStr += question[j].content + "/";
+        }
+        var conditionQuestion = { questionId: value[1], optionList: optionList }
+        conditionQuestionList.push(conditionQuestion);
+      }
+
+      for (var i = 0; i < this.options.length; i++) {
+        testThemesIdList.push(this.options[i].id);
+      }
+      this.filterStr = this.filterStr.substr(0, this.filterStr.length - 1)
+      let data = {
+        conditionQuestionList: conditionQuestionList,
+        testThemesIdList: testThemesIdList
+      }
+      api.answerData(data).then((res) => {
+        if (res.success) {
+          console.log("success", res);
+          var answerData = res.single;
+          for (var i = 0; i < answerData.questionList.length; i++) {
+            var element = answerData.questionList[i]
+            console.log("found", found);
+            if (element.belongTestOrder <= this.options.length) {
+              element.lable = this.options[element.belongTestOrder - 1].label;
+            }
+
+            const found = conditionQuestionList.find(element => element.questionId == element.questionId);
+            if (found) {
+              if (found.questionId == element.questionId) {
+                element.isFilter = true
+              } else {
+                element.isFilter = false
+              }
+            }
+          }
+          console.log("answerData", answerData);
+          this.answerData = answerData;
+        } else {
+          console.log("error");
+        }
+      });
+    },
+    saveOnLine() {
+      var checkList = [];
+
+      for (var i = 0; i < this.questionChilds.length; i++) {
+        var question = this.questionChilds[i]
+        for (var j = 0; j < question.length; j++) {
+          var option = question[j];
+          var questionObj = this.questionListSel[i];
+          checkList.push({ subOptionContent: option.content, subOptionId: option.optionId, subQuestionContent: questionObj.content, subQuestionId: questionObj.questionId })
+        }
+      }
+
+      console.log("编辑数据包", checkList);
+      this.$prompt("请数据包名称", "提保存筛选条件作为数据包", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        inputPattern: /^[\s\S]*.*[^\s][\s\S]*$/,
+        inputErrorMessage: "数据包名称不为空",
+        inputValue: this.title
+      })
+        .then(({ value }) => {
+          let param = {
+            checkList: checkList,
+            analyseBagTitle: value,
+            operator: "admin"
+          };
+          api.saveAnalyseBag(param).then(res => {
+            if (res.success) {
+              this.$message.success("保存成功");
+            } else {
+              this.$message.error("数据加载失败,请重试");
+            }
+          });
+        })
+        .catch(() => { });
+    },
+    async getCrossAnalyse() {
+
+      var analyseBagIdList = [];
+      var province = ""
+      var city = ""
+      var district = ""
+
+      if (this.analyseCommandSel == "数据包") {
+        if (this.analyseValue.length > 0) {
+          analyseBagIdList.push(this.analyseValue[0])
+        }
+      } else if (this.analyseCommandSel == "区域") {
+        if (this.analyseValue.length > 0) {
+          province = this.analyseValue[0]
+        } else if (this.analyseValue.length > 1) {
+          city = this.analyseValue[1]
+        } else if (this.analyseValue.length > 2) {
+          district = this.analyseValue[2]
+        }
+      }
+      var testThemesIdList = [];
+      for (var i = 0; i < this.options.length; i++) {
+        testThemesIdList.push(this.options[i].id);
+      }
+      var xlist = [];
+      var ylist = [];
+      for (var i = 0; i < this.questionList.length; i++) {
+        var item = this.questionList[i];
+        for (var j = 0; j < item.length; j++) {
+          for (var m = 0; m < this.optionsXValue.length; m++) {
+            var element = this.optionsXValue[m];
+            if (item[j].questionId == element[1]) {
+              xlist.push(item[j]);
+            }
+          }
+          for (var n = 0; n < this.optionsYValue.length; n++) {
+            var element = this.optionsYValue[n];
+            if (item[j].questionId == element[1]) {
+              ylist.push(item[j]);
+            }
+          }
+        }
+      }
+
+      let data = {
+        province: province,
+        city: city,
+        district: district,
+        analyseBagIdList: analyseBagIdList,
+        testThemesIdList: testThemesIdList,
+        xlist: xlist,
+        ylist: ylist
+      }
+      console.log("XXXXXX", data);
+      api.crossAnalyse(data).then((res) => {
+        if (res.success) {
+          console.log("success", res.list);
+          var crossAnalyse = res.list;
+          this.crossAnalyse = []
+          var result = [];
+          var rowArr = [];
+          for (var n = 0; n < crossAnalyse.length; n++) {
+            var arrs = []
+            var crossResult = crossAnalyse[n].crossResult;
+            console.log("XXXXX", Object.keys(crossResult), Object.values(crossResult))
+            rowArr = Object.keys(crossResult);
+            var values = Object.values(crossResult)
+            for (var m = 0; m < values.length; m++) {
+              console.log("SSSSS", Object.keys(values[m]), Object.values(values[m]))
+              arrs.push({ name: Object.keys(values[m]), value: Object.values(values[m]) })
+            }
+            result.push(arrs);
+          }
+
+          // console.log("AAAAAA", result);
+
+          for (var x = 0; x < result.length; x++) {
+            var qqq = result[x];
+            var sss = [];
+            for (var q = 0; q < qqq.length; q++) {
+              sss.push({ name: rowArr[q], title: qqq[q].name, value: qqq[q].value })
+            }
+            this.crossAnalyse.push({ table: sss, data: [], question: null, name: null });
+          }
+          // console.log("SSSSS", this.crossAnalyse);
+
+          for (var x = 0; x < this.crossAnalyse.length; x++) {
+            var data = [];
+            var top = this.crossAnalyse[x].table;
+            for (var y = 0; y < top.length; y++) {
+              var one = top[y].value;
+              // console.log("one", top[y].name)
+              var total = 0;
+              for (var z = 0; z < one.length; z++) {
+                var two = one[z];
+                var p = total == 0 ? 0 : ((two / total) * 100).toFixed(0)
+                if (top[y].title[z] != "total") {
+                  data.push({ time: top[y].name, type: top[y].title[z], value: two, total: p })
+                } else {
+                  total = two
+                }
+              }
+            }
+
+            this.crossAnalyse[x].data = data;
+            this.crossAnalyse[x].question = data;
+
+            const found = this.optionsY.find(element => element.id == this.optionsYValue[x][0]);
+            // console.log("XXXXXXXXXfound", found);
+            if (found) {
+              const children = found.children.find(element => element.value == this.optionsYValue[x][1]);
+              // console.log("XXXXXXXXXchildren", children);
+              if (children) {
+                this.crossAnalyse[x].name = children.label
+              }
+            }
+
+          }
+          console.log("data", this.crossAnalyse);
+
+        } else {
+          console.log("error");
+        }
+      });
+    },
+    goToPreviewPage() {
+
+      this.$router.push({
+        name: 'previewPage',
+        params: {
+          chartData: this.chartData,
+          answerData: this.answerData,
+          currentDate: this.currentDate,
+          options: this.options,
+          filterStr: this.filterStr,
+          isShowTable: this.isShowTable,
+          isCrossAnalyse: this.isCrossAnalyse,
+          crossAnalyse: this.crossAnalyse
+        }
+      })
+    }
+
+
+  },
+}

+ 622 - 0
src/views/testData/testData.scss

@@ -0,0 +1,622 @@
+.page {
+  padding: 60px 0px;
+  width: 100%;
+  height: 100%;
+  background: rgba(237,239,247,1);
+}
+.testData {
+  width: 1180px;  
+  margin: 0 auto;
+  display: flex;
+  flex-direction: column;
+  .testList {
+    width: 100%;
+    height: 148px;
+    background: white;
+    margin-top: 16px;
+    border-radius:6px;
+    .testProject {
+      margin-top: 16px;
+      margin-left: 135px;
+      .el-button{
+        padding: 7px 20px;
+        position: relative
+      }
+      .el-button--primary{
+        width: 144px;
+        height: 32px;
+        border-radius: 17px;
+        font-size: 14px;
+        color: #4E5DFF;
+        background:rgba(245,248,255,1);
+        border-color: #fff;
+      }
+      .el-button--primary:focus,.el-button--primary:hover {
+        background: #4E5DFF;
+        border-color: #4E5DFF;
+        color: #fff;
+      }
+    }
+    .testItem {
+      width: calc(100% - 200px);
+      height: 84px;
+      display: flex;
+      flex-direction: row;
+      margin-left: 100px;
+      margin-top: 16px;
+      .itemArrow {
+        width: 30px;
+        height: 100%;
+        margin-top: 20px;
+        cursor: pointer;
+        font-size: 30px;
+        color: #999999;
+      }
+      .testContent {
+        flex-grow: 2;
+        display: flex;
+        flex-direction: row;
+        overflow-x: auto;
+        .testTopic {
+          width: 145px;
+          height: 68px;
+          margin:0px 5px;
+          flex-shrink: 0;
+          background:rgba(237,237,237,1);
+          border-radius:2px;
+          font-size:14px;
+          font-family:PingFangSC-Medium,PingFang SC;
+          font-weight:500;
+          color:rgba(100,107,129,1);
+          line-height:20px;
+          padding: 5px;
+          box-sizing: border-box;
+          position: relative;
+          .testSel {
+            position: absolute;
+            bottom: 2px;
+            right: 2px;
+            width: 16px;
+            height: 16px;
+            cursor: pointer;
+          }
+        }
+        .testTopicSel {
+          background:rgba(78,93,255,1);
+          color:rgba(255,255,255,1);
+        }
+      }
+    }
+  }
+  .testTip {
+    width: 100%;
+    height: 80px;
+    line-height: 80px;
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    align-items: center;
+    font-size:18px;
+    font-family:PingFangSC-Medium,PingFang SC;
+    font-weight:500;
+    color:rgba(51,51,51,1);
+    .switchItem {
+      display: flex;
+      flex-direction: row;
+      height: 40px;
+      background:rgba(255,255,255,1);
+      border-radius:20px;
+      .switch {
+        width: 80px;
+        height: 40px;
+        line-height: 40px;
+        background:rgba(255,255,255,1);
+        border-radius:20px;
+        text-align: center;
+        font-size:14px;
+        font-family:PingFangSC-Regular,PingFang SC;
+        font-weight:400;
+        color:rgba(78,93,255,1);
+        cursor: pointer;
+      }
+      .switchSelected {
+        color:rgba(255,255,255,1);
+        background:rgba(78,93,255,1);
+      }
+    }
+    .analyseBag {
+      display: flex;
+      flex-direction: row;
+      width:340px;
+      height:34px;
+      background:rgba(255,255,255,1);
+      border-radius:17px;
+      .analyseBagTitle {
+        width:64px;
+        height:34px;
+        border-radius:17px;
+        text-align: center;
+        font-size:14px;
+        font-family:PingFangSC-Regular,PingFang SC;
+        font-weight:400;
+        color:rgba(255,255,255,1);
+        line-height:34px;
+        .el-button{
+          padding: 7px 0px;
+          position: relative
+        }
+        .el-button--primary{
+          width:64px;
+          height:34px;
+          border-radius: 17px;
+          font-size: 14px;
+          color: #fff;
+          background: #4E5DFF;
+          border-color: #fff;
+        }
+        .el-button--primary:focus,.el-button--primary:hover {
+          background: #4E5DFF;
+          border-color: #4E5DFF;
+          color: #fff;
+        }
+      }
+      .analyseBagList {
+        height: 34px;
+        margin-top: -24px;
+        .el-cascader {
+          width: 260px;
+          background:rgba(241,241,241,1);
+          line-height: 34px;
+          font-size:14px;
+          color:rgba(51,51,51,1);
+          .el-input__inner {
+            height: 34px;
+            line-height: 34px;
+            background:rgba(255,255,255,1);
+            border: 0px;
+          }
+          .el-input__icon {
+            line-height: 34px;
+          }
+        }
+      }
+    }
+    .addBag {
+      font-size:12px;
+      font-family:PingFangSC-Regular,PingFang SC;
+      font-weight:400;
+      color:rgba(100,107,129,1);
+      line-height:17px;
+      cursor: pointer;
+      padding-left: 10px;
+    }
+  }
+  .answer {
+    width: 100%;
+    background: white;
+    border-radius:6px;
+    padding: 24px 120px;
+    box-sizing: border-box;
+    .filter {
+      width: 100%;
+      height: 40px;
+      display: flex;
+      flex-direction: row;
+      justify-content: space-between;
+      .filterIcon {
+        width: 100px;
+        height: 40px;
+        cursor: pointer;
+      }
+      .rightFilter {
+        display: flex;
+        flex-direction: row;
+        .rightFilterItem {
+          width: 48px;
+          height: 24px;
+          font-size:12px;
+          font-family:PingFangSC-Regular,PingFang SC;
+          font-weight:400;
+          color:rgba(153,160,182,1);
+          line-height:24px;
+          border-radius:14px;
+          border:1px solid rgba(153,160,182,1);
+          text-align: center;
+          margin: 0px 4px;
+          cursor: pointer;
+        }
+        .rightFilterItemSel {
+          color:rgba(78,93,255,1);
+          border:1px solid rgba(78,93,255,1);
+        }
+      }
+    }
+    .filterContent {
+      width: 100%;
+      .filterView {
+        background:rgba(250,250,250,1);
+        border-radius:6px;
+        padding: 24px 16px;
+      }
+      .filterItem {
+        width: 100%;
+        margin: 4px 0px;
+        display: flex;
+        flex-direction: row;
+        box-sizing: border-box;
+        .filterTitle {
+          margin-top: 5px;
+          margin-left: 8px;
+          font-size:14px;
+          font-family:PingFangSC-Regular,PingFang SC;
+          font-weight:400;
+          color:rgba(51,51,51,1);
+          line-height:20px;
+          flex-shrink: 0;
+          width: 57px;
+        }
+        .filterAnswer {
+          margin-left: 10px;
+          flex-shrink: 0;
+          margin-right: 10px;
+          .el-cascader {
+            width: 320px;
+            background:rgba(241,241,241,1);
+            line-height: 30px;
+            font-size:14px;
+            color:rgba(51,51,51,1);
+            .el-input__inner {
+              height: 30px;
+              line-height: 30px;
+              background:rgba(241,241,241,1);
+            }
+            .el-input__icon {
+              line-height: 30px;
+            }
+          }
+        }
+        .filterReply {
+          display: flex;
+          align-items:center;
+        }
+      }
+      .addfilter{
+        width:320px;
+        height:30px;
+        border:1px dashed rgba(202,204,210,1);
+        margin-left: 74px;
+        margin-top: 8px;
+        display: flex;
+        flex-direction: row;
+        justify-content: center;
+        align-items: center;
+        cursor: pointer;
+        .addfilterIcon {
+          width: 74px;
+          height: 18px;
+        }
+      }
+      .filterDel {
+        cursor: pointer;
+        display: flex;
+        align-items:center;
+        color: #646B81;
+        margin-left: 10px;
+      }
+      .filterSave {
+        height: 28px;
+        margin-left: 74px;
+        margin-top: 16px;
+        display: flex;
+        text-align: center;
+        .saveLocation {
+          width:80px;
+          height:28px;
+          background:rgba(78,93,255,1);
+          border-radius:14px;
+          font-size:14px;
+          font-family:PingFangSC-Medium,PingFang SC;
+          font-weight:500;
+          color:rgba(255,255,255,1);
+          line-height:28px;
+          cursor: pointer;
+        }
+        .saveOnLine {
+          margin-left: 16px;
+          font-size:14px;
+          font-family:PingFangSC-Medium,PingFang SC;
+          font-weight:500;
+          color:rgba(78,93,255,1);
+          line-height:28px;
+          width:200px;
+          height:28px;
+          border-radius:14px;
+          border:1px solid rgba(78,93,255,1);
+          cursor: pointer;
+        }
+      }
+      .filterResult {
+        font-size:14px;
+        font-family:PingFangSC-Regular,PingFang SC;
+        font-weight:400;
+        color:rgba(51,51,51,1);
+        line-height:20px;
+        border-bottom: 1px dashed #E8E8E8;
+        padding-top: 4px;
+        padding-bottom: 15px;
+      }
+    }
+    .result {
+      .resultItem {
+        margin-top: 36px;
+        padding-bottom: 20px;
+        border-bottom:1px dashed rgba(202,204,210,1);
+        .testLable {
+          font-size:18px;
+          font-family:PingFangSC-Medium,PingFang SC;
+          font-weight:500;
+          color:rgba(78,93,255,1);
+          line-height:25px;
+          margin-bottom: 10px;
+          padding-bottom: 10px;
+          width: 100%;
+          border-bottom: 1px dashed #E8E8E8;
+        }
+        .resultTitle {
+          display: flex;
+          flex-direction: row;
+          align-items: center;
+          font-size:18px;
+          font-family:PingFangSC-Medium,PingFang SC;
+          font-weight:500;
+          color:rgba(51,51,51,1);
+          line-height:25px;
+        }
+        .resultTable {
+
+          border-radius:4px;
+          border:1px solid rgba(232,232,232,1);
+          margin-top: 8px;
+        }
+        .tableHeader {
+          display: flex;
+          flex-direction: row;
+          height: 32px;
+          background:rgba(250,250,250,1);
+          border-radius:4px 0px 0px 0px;
+          font-size:14px;
+          font-family:PingFangSC-Medium,PingFang SC;
+          font-weight:500;
+          color:rgba(0,0,0,0.85);
+          line-height:21px;
+          align-items:flex-end;
+          .option {
+           flex-grow: 2;
+           padding-left: 25px;
+           box-sizing: border-box;
+          }
+          .numbers {
+            width:236px;
+            height: 100%;
+            padding-top: 8px;
+            padding-left: 25px;
+            box-sizing: border-box;
+            border-left:1px solid rgba(232,232,232,1);
+            border-right:1px solid rgba(232,232,232,1);
+          }
+          .percent {
+            width: 408px;
+            padding-left: 25px;
+            box-sizing: border-box;
+          }
+        }
+        .tableRow {
+          display: flex;
+          flex-direction: row;
+          min-height: 32px;
+          font-size:14px;
+          font-family:PingFangSC-Regular,PingFang SC;
+          font-weight:400;
+          color:rgba(0,0,0,0.65);
+          line-height:21px;
+          .option {
+           flex-grow: 2;
+           height: 100%;
+           padding-top: 8px;
+           padding-left: 25px;
+           box-sizing: border-box;
+           border-top:1px solid rgba(232,232,232,1);
+          padding: 8px 15px;
+          }
+          .numbers {
+            width:236px;
+            min-height: 100%;
+            padding: 0px 15px;
+            padding-left: 25px;
+            box-sizing: border-box;
+            border-left:1px solid rgba(232,232,232,1);
+            border-right:1px solid rgba(232,232,232,1);
+            border-top:1px solid rgba(232,232,232,1);
+            flex-shrink: 0;
+            display: flex;
+            align-items: center;
+          }
+          .percent {
+            width: 408px;
+            min-height: 100%;
+            padding-left: 25px;
+            box-sizing: border-box;
+            border-top:1px solid rgba(232,232,232,1);
+            flex-shrink: 0;
+            display: flex;
+            align-items: center;
+          }
+        }
+      }
+    }
+    .chart {
+      display: flex;
+      flex-direction: column;
+      margin-top: 30px;
+      .chartItem {
+        display: flex;
+        flex-direction: column;
+        .chartTitle {
+          font-size:18px;
+          font-family:PingFangSC-Medium,PingFang SC;
+          font-weight:500;
+          color:rgba(51,51,51,1);
+          line-height:25px;
+        }
+        .chartData {
+          width: 100%;
+          margin: 10px 0px;
+        }
+      }
+    }
+    
+  }
+  .crossAnalyse {
+    width: 100%;
+    background: white;
+    border-radius:6px;
+    padding: 24px 120px;
+    box-sizing: border-box;
+    .crossFilter{
+      background:rgba(250,250,250,1);
+      border-radius:6px;
+      display: flex;
+      flex-direction: row;
+      justify-content: center;
+      flex-wrap:wrap;
+      .xyFilter {
+        width: 360px;
+        .el-cascader {
+          width: 320px;
+          background:rgba(241,241,241,1);
+          line-height: 30px;
+          font-size:14px;
+          color:rgba(51,51,51,1);
+          .el-input__inner {
+            height: 30px;
+            line-height: 30px;
+            background:rgba(241,241,241,1);
+          }
+          .el-input__icon {
+            line-height: 30px;
+          }
+        }
+        .addfilter{
+          width:320px;
+          height:30px;
+          border:1px dashed rgba(202,204,210,1);
+          margin-top: 8px;
+          display: flex;
+          flex-direction: row;
+          justify-content: center;
+          align-items: center;
+          cursor: pointer;
+          .addfilterIcon {
+            width: 74px;
+            height: 18px;
+          }
+        }
+      }
+      .crossFilterTitle {
+        font-size:14px;
+        font-family:PingFangSC-Medium,PingFang SC;
+        font-weight:500;
+        color:rgba(51,51,51,1);
+        line-height:20px;
+      }
+      .crossFilterSubTitle {
+        font-size:12px;
+        font-family:PingFangSC-Regular,PingFang SC;
+        font-weight:400;
+        color:rgba(51,51,51,1);
+        line-height:20px;
+      }
+      .analyse {
+        width: 100%;
+        margin: 16px 0px;
+        display: flex;
+        flex-direction: row;
+        .startAnalyse {
+          margin-left: 90px;
+          width:80px;
+          height:28px;
+          background:rgba(78,93,255,1);
+          border-radius:14px;
+          font-size:14px;
+          font-family:PingFangSC-Medium,PingFang SC;
+          font-weight:500;
+          color:rgba(255,255,255,1);
+          line-height:28px;
+          text-align: center;
+          cursor: pointer;
+        }
+        .analyseTip {
+          font-size:12px;
+          font-family:PingFangSC-Regular,PingFang SC;
+          font-weight:400;
+          color:rgba(255,0,0,1);
+          line-height:28px;
+          margin-left: 8px;
+        }
+      }
+    }
+    .crossAnalyseTable {
+      .crossAnalyseTitle {
+        font-size:18px;
+        font-family:PingFangSC-Medium,PingFang SC;
+        font-weight:500;
+        color:rgba(51,51,51,1);
+        line-height:25px;
+        margin-top: 32px;
+      }
+      .crossAnalyseChart {
+        width: 100%;
+        margin: 8px 0px;
+      }
+      .table{
+        border-radius:4px;
+        border-top:1px solid rgba(232,232,232,1); 
+        border-left:1px solid rgba(232,232,232,1); 
+      }
+      .caTable {
+        display: flex;
+        flex-direction: row;
+        .headerRow {
+          background:rgba(250,250,250,1);
+          border-radius:4px 0px 0px 0px;
+          font-size:14px;
+          font-family:PingFangSC-Medium,PingFang SC;
+          font-weight:500;
+          color:rgba(0,0,0,0.85);
+          line-height:21px;
+          align-items:flex-end;
+          padding-top: 8px;
+          padding-bottom: 12px;
+          box-sizing: border-box;
+          border-bottom: 1px solid #E8E8E8;
+          border-right: 1px solid #E8E8E8;
+        }
+        .tabkeRow {
+          font-size:14px;
+          font-family:PingFangSC-Regular,PingFang SC;
+          font-weight:400;
+          color:rgba(0,0,0,0.65);
+          line-height:21px;
+          align-items:flex-end;
+          padding-top: 8px;
+          padding-bottom: 1px;
+          padding-left: 5px;
+          box-sizing: border-box;
+          border-bottom: 1px solid #E8E8E8;
+          border-right: 1px solid #E8E8E8;
+        }
+        
+      }
+    }
+  }
+}

+ 7 - 0
src/views/testData/testData.vue

@@ -0,0 +1,7 @@
+<template src='./testData.html'>
+</template>
+<script src="./testData.js">
+</script>
+<style lang="scss">
+@import "./testData.scss";
+</style>