提交 71b8abc5 authored 作者: thy's avatar thy

Merge branch 'master' into 'thy'

# Conflicts: # src/components/reportAssess/reportAssess.vue # src/services/server.js
...@@ -9,7 +9,9 @@ module.exports = { ...@@ -9,7 +9,9 @@ module.exports = {
], ],
"globals": { "globals": {
'Atomics': 'readonly', 'Atomics': 'readonly',
'SharedArrayBuffer': 'readonly' 'SharedArrayBuffer': 'readonly',
'require': true
}, },
'parserOptions': { 'parserOptions': {
'ecmaVersion': 2018, 'ecmaVersion': 2018,
......
...@@ -1727,6 +1727,11 @@ ...@@ -1727,6 +1727,11 @@
"integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
"dev": true "dev": true
}, },
"abab": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz",
"integrity": "sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4="
},
"abbrev": { "abbrev": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
...@@ -1748,6 +1753,21 @@ ...@@ -1748,6 +1753,21 @@
"integrity": "sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw==", "integrity": "sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw==",
"dev": true "dev": true
}, },
"acorn-globals": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-1.0.9.tgz",
"integrity": "sha1-VbtemGkVB7dFedBRNBMhfDgMVM8=",
"requires": {
"acorn": "^2.1.0"
},
"dependencies": {
"acorn": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-2.7.0.tgz",
"integrity": "sha1-q259nYhqrKiwhbwzEreaGYQz8Oc="
}
}
},
"acorn-jsx": { "acorn-jsx": {
"version": "5.1.0", "version": "5.1.0",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz",
...@@ -1917,6 +1937,11 @@ ...@@ -1917,6 +1937,11 @@
"integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
"dev": true "dev": true
}, },
"array-equal": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz",
"integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM="
},
"array-find-index": { "array-find-index": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
...@@ -2241,6 +2266,11 @@ ...@@ -2241,6 +2266,11 @@
} }
} }
}, },
"base64-arraybuffer": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.2.0.tgz",
"integrity": "sha512-7emyCsu1/xiBXgQZrscw/8KPRT44I4Yq9Pe6EGs3aPRTsWuggML1/1DTuZUuIaJPIm1FTDUVXl4x/yW8s0kQDQ=="
},
"base64-js": { "base64-js": {
"version": "1.3.1", "version": "1.3.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
...@@ -2762,6 +2792,24 @@ ...@@ -2762,6 +2792,24 @@
"integrity": "sha512-Vnrq+XMSHpT7E+LWoIYhs3Sne8h9lx9YJV3acH3THNCwU/9zV93/ta4xVfzTtnqd3rvnuVpVjE3DFqf56tr3aQ==", "integrity": "sha512-Vnrq+XMSHpT7E+LWoIYhs3Sne8h9lx9YJV3acH3THNCwU/9zV93/ta4xVfzTtnqd3rvnuVpVjE3DFqf56tr3aQ==",
"dev": true "dev": true
}, },
"canvg": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/canvg/-/canvg-1.5.3.tgz",
"integrity": "sha512-7Gn2IuQzvUQWPIuZuFHrzsTM0gkPz2RRT9OcbdmA03jeKk8kltrD8gqUzNX15ghY/4PV5bbe5lmD6yDLDY6Ybg==",
"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": "https://registry.npmjs.org/stackblur-canvas/-/stackblur-canvas-1.4.1.tgz",
"integrity": "sha1-hJqm+UsnL/JvZHH6QTDtH35HlVs="
}
}
},
"case-sensitive-paths-webpack-plugin": { "case-sensitive-paths-webpack-plugin": {
"version": "2.3.0", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.3.0.tgz", "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.3.0.tgz",
...@@ -3487,6 +3535,14 @@ ...@@ -3487,6 +3535,14 @@
"timsort": "^0.3.0" "timsort": "^0.3.0"
} }
}, },
"css-line-break": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-1.1.1.tgz",
"integrity": "sha512-1feNVaM4Fyzdj4mKPIQNL2n70MmuYzAXZ1aytlROFX1JsOo070OsugwGjj7nl6jnDJWHDM8zRZswkmeYVWZJQA==",
"requires": {
"base64-arraybuffer": "^0.2.0"
}
},
"css-loader": { "css-loader": {
"version": "3.4.2", "version": "3.4.2",
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.4.2.tgz", "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.4.2.tgz",
...@@ -3641,6 +3697,19 @@ ...@@ -3641,6 +3697,19 @@
"css-tree": "1.0.0-alpha.37" "css-tree": "1.0.0-alpha.37"
} }
}, },
"cssom": {
"version": "0.3.8",
"resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
"integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg=="
},
"cssstyle": {
"version": "0.2.37",
"resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz",
"integrity": "sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ=",
"requires": {
"cssom": "0.3.x"
}
},
"current-script-polyfill": { "current-script-polyfill": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/current-script-polyfill/-/current-script-polyfill-1.0.0.tgz", "resolved": "https://registry.npmjs.org/current-script-polyfill/-/current-script-polyfill-1.0.0.tgz",
...@@ -3712,8 +3781,7 @@ ...@@ -3712,8 +3781,7 @@
"deep-is": { "deep-is": {
"version": "0.1.3", "version": "0.1.3",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ="
"dev": true
}, },
"deepmerge": { "deepmerge": {
"version": "1.5.2", "version": "1.5.2",
...@@ -4319,6 +4387,26 @@ ...@@ -4319,6 +4387,26 @@
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
}, },
"escodegen": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.1.tgz",
"integrity": "sha512-Bmt7NcRySdIfNPfU2ZoXDrrXsG9ZjvDxcAlMfDUgRBjLOWTuIACXPBFJH7Z+cLb40JeQco5toikyc9t9P8E9SQ==",
"requires": {
"esprima": "^4.0.1",
"estraverse": "^4.2.0",
"esutils": "^2.0.2",
"optionator": "^0.8.1",
"source-map": "~0.6.1"
},
"dependencies": {
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"optional": true
}
}
},
"eslint": { "eslint": {
"version": "6.8.0", "version": "6.8.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz",
...@@ -4623,8 +4711,7 @@ ...@@ -4623,8 +4711,7 @@
"esprima": { "esprima": {
"version": "4.0.1", "version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
"dev": true
}, },
"esquery": { "esquery": {
"version": "1.1.0", "version": "1.1.0",
...@@ -4647,14 +4734,12 @@ ...@@ -4647,14 +4734,12 @@
"estraverse": { "estraverse": {
"version": "4.3.0", "version": "4.3.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
"integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw=="
"dev": true
}, },
"esutils": { "esutils": {
"version": "2.0.3", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="
"dev": true
}, },
"etag": { "etag": {
"version": "1.8.1", "version": "1.8.1",
...@@ -4959,8 +5044,7 @@ ...@@ -4959,8 +5044,7 @@
"fast-levenshtein": { "fast-levenshtein": {
"version": "2.0.6", "version": "2.0.6",
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
"dev": true
}, },
"faye-websocket": { "faye-websocket": {
"version": "0.10.0", "version": "0.10.0",
...@@ -5005,6 +5089,10 @@ ...@@ -5005,6 +5089,10 @@
"schema-utils": "^2.5.0" "schema-utils": "^2.5.0"
} }
}, },
"file-saver": {
"version": "github:eligrey/FileSaver.js#e865e37af9f9947ddcced76b549e27dc45c1cb2e",
"from": "github:eligrey/FileSaver.js#1.3.8"
},
"file-uri-to-path": { "file-uri-to-path": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
...@@ -6285,6 +6373,14 @@ ...@@ -6285,6 +6373,14 @@
} }
} }
}, },
"html2canvas": {
"version": "1.0.0-rc.5",
"resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.0.0-rc.5.tgz",
"integrity": "sha512-DtNqPxJNXPoTajs+lVQzGS1SULRI4GQaROeU5R41xH8acffHukxRh/NBVcTBsfCkJSkLq91rih5TpbEwUP9yWA==",
"requires": {
"css-line-break": "1.1.1"
}
},
"htmlparser2": { "htmlparser2": {
"version": "3.10.1", "version": "3.10.1",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
...@@ -6400,7 +6496,6 @@ ...@@ -6400,7 +6496,6 @@
"version": "0.4.24", "version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
"dev": true,
"requires": { "requires": {
"safer-buffer": ">= 2.1.2 < 3" "safer-buffer": ">= 2.1.2 < 3"
} }
...@@ -7002,6 +7097,42 @@ ...@@ -7002,6 +7097,42 @@
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
}, },
"jsdom": {
"version": "8.5.0",
"resolved": "https://registry.npmjs.org/jsdom/-/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": "https://registry.npmjs.org/acorn/-/acorn-2.7.0.tgz",
"integrity": "sha1-q259nYhqrKiwhbwzEreaGYQz8Oc="
},
"parse5": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz",
"integrity": "sha1-m387DeMr543CQBsXVzzK8Pb1nZQ="
}
}
},
"jsesc": { "jsesc": {
"version": "2.5.2", "version": "2.5.2",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
...@@ -7059,6 +7190,42 @@ ...@@ -7059,6 +7190,42 @@
"graceful-fs": "^4.1.6" "graceful-fs": "^4.1.6"
} }
}, },
"jspdf": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/jspdf/-/jspdf-1.5.3.tgz",
"integrity": "sha512-J9X76xnncMw+wIqb15HeWfPMqPwYxSpPY8yWPJ7rAZN/ZDzFkjCSZObryCyUe8zbrVRNiuCnIeQteCzMn7GnWw==",
"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": {
"base64-arraybuffer": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz",
"integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg="
},
"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=",
"requires": {
"base64-arraybuffer": "^0.1.5"
}
},
"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=",
"requires": {
"css-line-break": "1.0.1"
}
}
}
},
"jsprim": { "jsprim": {
"version": "1.4.1", "version": "1.4.1",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
...@@ -7188,7 +7355,6 @@ ...@@ -7188,7 +7355,6 @@
"version": "0.3.0", "version": "0.3.0",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
"integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
"dev": true,
"requires": { "requires": {
"prelude-ls": "~1.1.2", "prelude-ls": "~1.1.2",
"type-check": "~0.3.2" "type-check": "~0.3.2"
...@@ -8156,6 +8322,11 @@ ...@@ -8156,6 +8322,11 @@
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
}, },
"nwmatcher": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.4.tgz",
"integrity": "sha512-3iuY4N5dhgMpCUrOVnuAdGrgxVqV2cJpM+XNccjR2DKOB1RUP0aA+wGXEiNziG/UKboFyGBIoKOaNlJxx8bciQ=="
},
"oauth-sign": { "oauth-sign": {
"version": "0.9.0", "version": "0.9.0",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
...@@ -8279,6 +8450,11 @@ ...@@ -8279,6 +8450,11 @@
"integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==",
"dev": true "dev": true
}, },
"omggif": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.7.tgz",
"integrity": "sha1-WdLuywJj3oRjWz/riHwMmXPx5J0="
},
"on-finished": { "on-finished": {
"version": "2.3.0", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
...@@ -8339,7 +8515,6 @@ ...@@ -8339,7 +8515,6 @@
"version": "0.8.3", "version": "0.8.3",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
"integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
"dev": true,
"requires": { "requires": {
"deep-is": "~0.1.3", "deep-is": "~0.1.3",
"fast-levenshtein": "~2.0.6", "fast-levenshtein": "~2.0.6",
...@@ -9308,8 +9483,7 @@ ...@@ -9308,8 +9483,7 @@
"prelude-ls": { "prelude-ls": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
"integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ="
"dev": true
}, },
"prepend-http": { "prepend-http": {
"version": "1.0.4", "version": "1.0.4",
...@@ -9372,6 +9546,11 @@ ...@@ -9372,6 +9546,11 @@
"integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=",
"dev": true "dev": true
}, },
"promise-polyfill": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-8.1.0.tgz",
"integrity": "sha512-OzSf6gcCUQ01byV4BgwyUCswlaQQ6gzXc23aLQWhicvfX9kfsUiUhgt3CCQej8jDnl8/PhGF31JdHX2/MzF3WA=="
},
"proxy-addr": { "proxy-addr": {
"version": "2.0.5", "version": "2.0.5",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz",
...@@ -9958,6 +10137,11 @@ ...@@ -9958,6 +10137,11 @@
"integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=", "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=",
"dev": true "dev": true
}, },
"rgbcolor": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/rgbcolor/-/rgbcolor-1.0.1.tgz",
"integrity": "sha1-1lBezbMEplldom+ktDMHMGd1lF0="
},
"rimraf": { "rimraf": {
"version": "2.7.1", "version": "2.7.1",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
...@@ -10183,8 +10367,7 @@ ...@@ -10183,8 +10367,7 @@
"sax": { "sax": {
"version": "1.2.4", "version": "1.2.4",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
"dev": true
}, },
"schema-utils": { "schema-utils": {
"version": "2.6.4", "version": "2.6.4",
...@@ -10818,6 +11001,11 @@ ...@@ -10818,6 +11001,11 @@
"integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==",
"dev": true "dev": true
}, },
"stackblur-canvas": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/stackblur-canvas/-/stackblur-canvas-2.2.0.tgz",
"integrity": "sha512-5Gf8dtlf8k6NbLzuly2NkGrkS/Ahh+I5VUjO7TnFizdJtgpfpLLEdQlLe9umbcnZlitU84kfYjXE67xlSXfhfQ=="
},
"stackframe": { "stackframe": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.1.1.tgz", "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.1.1.tgz",
...@@ -11071,6 +11259,11 @@ ...@@ -11071,6 +11259,11 @@
"util.promisify": "~1.0.0" "util.promisify": "~1.0.0"
} }
}, },
"symbol-tree": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
"integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw=="
},
"table": { "table": {
"version": "5.4.6", "version": "5.4.6",
"resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz",
...@@ -11343,6 +11536,11 @@ ...@@ -11343,6 +11536,11 @@
"punycode": "^2.1.1" "punycode": "^2.1.1"
} }
}, },
"tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
},
"trim-newlines": { "trim-newlines": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
...@@ -11397,7 +11595,6 @@ ...@@ -11397,7 +11595,6 @@
"version": "0.3.2", "version": "0.3.2",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
"integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
"dev": true,
"requires": { "requires": {
"prelude-ls": "~1.1.2" "prelude-ls": "~1.1.2"
} }
...@@ -11872,6 +12069,11 @@ ...@@ -11872,6 +12069,11 @@
"defaults": "^1.0.3" "defaults": "^1.0.3"
} }
}, },
"webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
},
"webpack": { "webpack": {
"version": "4.41.6", "version": "4.41.6",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-4.41.6.tgz", "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.41.6.tgz",
...@@ -12214,6 +12416,15 @@ ...@@ -12214,6 +12416,15 @@
"integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==",
"dev": true "dev": true
}, },
"whatwg-url": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-2.0.1.tgz",
"integrity": "sha1-U5ayBD8CDub3BNnEXqhRnnJN5lk=",
"requires": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"which": { "which": {
"version": "1.3.1", "version": "1.3.1",
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
...@@ -12239,8 +12450,7 @@ ...@@ -12239,8 +12450,7 @@
"word-wrap": { "word-wrap": {
"version": "1.2.3", "version": "1.2.3",
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ=="
"dev": true
}, },
"worker-farm": { "worker-farm": {
"version": "1.7.0", "version": "1.7.0",
...@@ -12329,6 +12539,16 @@ ...@@ -12329,6 +12539,16 @@
"async-limiter": "~1.0.0" "async-limiter": "~1.0.0"
} }
}, },
"xml-name-validator": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz",
"integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU="
},
"xmldom": {
"version": "0.1.31",
"resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.31.tgz",
"integrity": "sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ=="
},
"xtend": { "xtend": {
"version": "4.0.2", "version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
......
...@@ -12,7 +12,9 @@ ...@@ -12,7 +12,9 @@
"core-js": "^3.6.4", "core-js": "^3.6.4",
"echarts": "^4.6.0", "echarts": "^4.6.0",
"element-ui": "^2.13.0", "element-ui": "^2.13.0",
"html2canvas": "^1.0.0-rc.5",
"jquery": "^3.4.1", "jquery": "^3.4.1",
"jspdf": "^1.5.3",
"moment": "^2.24.0", "moment": "^2.24.0",
"node-sass": "^4.13.1", "node-sass": "^4.13.1",
"vue": "^2.6.11", "vue": "^2.6.11",
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
<el-select v-model="classVal" @change="search('search')" placeholder="请选择" clearable> <el-select v-model="classVal" @change="search('search')" placeholder="请选择" clearable>
<el-option <el-option
v-for="item in companyClass" v-for="item in companyClass"
:key="typeCompany(item)"
:label="typeCompany(item)" :label="typeCompany(item)"
:value="typeCompany(item)"> :value="typeCompany(item)">
</el-option> </el-option>
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
<el-select v-model="classVal" @change="search('search')" placeholder="请选择" clearable> <el-select v-model="classVal" @change="search('search')" placeholder="请选择" clearable>
<el-option <el-option
v-for="item in companyClass" v-for="item in companyClass"
:key="typeCompany(item)"
:label="typeCompany(item)" :label="typeCompany(item)"
:value="typeCompany(item)"> :value="typeCompany(item)">
</el-option> </el-option>
...@@ -194,7 +195,7 @@ export default { ...@@ -194,7 +195,7 @@ export default {
}, },
// 单位准入状态转换 // 单位准入状态转换
statusCompany (row) { statusCompany (row) {
return row.status === 1 ? '已准入': '未准入' return row.status === 1 ? '已准入' : '未准入'
}, },
// 单位类别转换 // 单位类别转换
typeCompany (row) { typeCompany (row) {
......
...@@ -164,7 +164,7 @@ export default { ...@@ -164,7 +164,7 @@ export default {
}, },
// 准入状态转换 // 准入状态转换
statusChange(row) { statusChange(row) {
return row.status === 1 ? '已准入': '未准入' return row.status === 1 ? '已准入' : '未准入'
}, },
// 搜索 // 搜索
search(val) { search(val) {
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
</span> </span>
<span class="addVal"> <span class="addVal">
<span>产品组合:</span> <span>产品组合:</span>
<span v-for="item in techNameList" style="color: #666;border: 1px solid rgba(8,104,157,.3); background-color: #f5f7fa; margin-left: 8px">{{formChange(item.form)}}</span> <span v-for="item in techNameList" :key="item.form" style="color: #666;border: 1px solid rgba(8,104,157,.3); background-color: #f5f7fa; margin-left: 8px">{{formChange(item.form)}}</span>
</span> </span>
</p> </p>
</div> </div>
......
This image diff could not be displayed because it is too large. You can view the blob instead.
<template>
<div class="otherPdf">
<span class="toPdf" @click="getPdf('pdfDom')">下载pdf</span>
<div id="pdfDom">
<div class="page">
<p class="title">{{title}}</p>
<p class="title">{{systemName}}</p>
<p class="title">{{reportName}}</p>
<div>
<table border="1" cellspacing="0" style="width: 100%">
<tr v-for="item of tableContent">
<td style="width: 152px;">{{item.name}}</td>
<td style="width: 221px;">{{item.val}}</td>
</tr>
</table>
</div>
</div>
<div class="page">
<p class="list">目录</p>
<div class="listConent">
<div class="listContent" style="margin: 0" v-for="(item,index) of listContent">
<div v-if="index < 3">
<p>
<span>{{item.name}}</span>
<span class="listPage">{{item.val}}</span>
</p>
<div class="listContent" v-for="arr of item.child1" style="margin-left: 20px;">
<p>
<span>{{arr.name}}</span>
<span class="listPage">{{arr.val}}</span>
</p>
<div class="listContent" v-for="acc of arr.child2" style="margin-left: 30px;">
<p>
<span>{{acc.name}}</span>
<span class="listPage">{{acc.val}}</span>
</p>
</div>
</div>
</div>
</div>
<div class="listContent" style="margin: 0" v-for="(item,index) of listContent">
<div v-if="index ===3">
<p >
<span>{{item.name}}</span>
<span class="listPage">{{item.val}}</span>
</p>
<div class="listContent" v-for="(arr,index2) of item.child1" style="margin-left: 20px;">
<div v-if="index2 < 2">
<p>
<span>{{arr.name}}</span>
<span class="listPage">{{arr.val}}</span>
</p>
<div class="listContent" v-for="acc of arr.child2" style="margin-left: 30px;">
<p>
<span>{{acc.name}}</span>
<span class="listPage">{{acc.val}}</span>
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="page">
<div class="listContent">
<div class="listContent" style="margin: 0" v-for="(item,index) of listContent">
<div v-if="index === 3">
<div class="listContent" v-for="(arr,index2) of item.child1" style="margin-left: 20px;">
<div v-if="index2 > 1">
<p>
<span>{{arr.name}}</span>
<span class="listPage">{{arr.val}}</span>
</p>
<div class="listContent" v-for="acc of arr.child2" style="margin-left: 30px;">
<p>
<span>{{acc.name}}</span>
<span class="listPage">{{acc.val}}</span>
</p>
</div>
</div>
</div>
</div>
</div>
<div class="listContent" style="margin: 0" v-for="(item,index) of listContent">
<div v-if="index > 3">
<p>
<span>{{item.name}}</span>
<span class="listPage">{{item.val}}</span>
</p>
<div class="listContent" v-for="arr of item.child1" style="margin-left: 20px;">
<p>
<span>{{arr.name}}</span>
<span class="listPage">{{arr.val}}</span>
</p>
<div class="listContent" v-for="acc of arr.child2" style="margin-left: 30px;">
<p>
<span>{{acc.name}}</span>
<span class="listPage">{{acc.val}}</span>
</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="page">
<p class="title1">1.&nbsp;&nbsp;&nbsp;评估报告声明</p>
<p class="title2">1.1.&nbsp;&nbsp;&nbsp;报告组成</p>
<p class="contentList" v-for="item of reportComposition">{{item}}</p>
</div>
<div class="page">
<p class="title2">1.2.&nbsp;报告作用</p>
<p class="contentList" v-for="item of reportingRole">{{item}}</p>
<p class="title2">1.3.&nbsp;其他注意事项</p>
<p class="contentList" v-for="item of reportOther">{{item}}</p>
</div>
<div class="page">
<p class="contentList" v-for="item of reportOther2">{{item}}</p>
</div>
<div class="page">
<p class="title1">2.&nbsp;评估标准和方法</p>
<p class="title2">2.1.&nbsp;参照标准</p>
<p class="title3">2.1.1.&nbsp;“912工程”相关政策法规</p>
<p class="contentList" style="letter-spacing:1px; text-indent:0em;" v-for="item of regulations">{{item}}</p>
</div>
<div class="page">
<p class="contentList" style="letter-spacing:1px;text-indent:0em;" v-for="item of regulations">{{item}}</p>
<p class="contentList" style="letter-spacing:1px;text-indent:0em;color: red" v-for="item of supplement">{{item}}这里输入宁波文件</p>
<p class="title3">2.1.2.&nbsp;“912工程”相关国家标准与规范</p>
<p class="contentList" style="letter-spacing:1px;text-indent:0em;" v-for="item of nationalNorms">{{item}}</p>
</div>
<div class="page">
<p class="contentList" style="letter-spacing:1px;text-indent:0em;" v-for="item of nationalNorms2">{{item}}</p>
</div>
<div class="page">
<p class="contentList" style="letter-spacing:1px;text-indent:0em;" v-for="item of nationalNorms3">{{item}}</p>
<p class="title3">2.1.3.&nbsp;“L77软件工程”国家分类标准</p>
<p class="contentList" style="letter-spacing:1px;text-indent:0em;" v-for="item of classificationCriteria">{{item}}</p>
</div>
<div class="page">
<p class="contentList" style="letter-spacing:1px;text-indent:0em;" v-for="item of classificationCriteria2">{{item}}</p>
<p class="title3">2.1.4.&nbsp;其他编制依据</p>
<p class="contentList" style="letter-spacing:1px;text-indent:0em;" v-for="item of otherEstablishments">{{item}}</p>
</div>
<div class="page">
<p class="contentList" style="letter-spacing:1px;text-indent:0em;" v-for="item of otherEstablishments2">{{item}}</p>
<p class="title2">2.2.&nbsp;评估流程与方法</p>
<p class="title3">2.2.1.&nbsp;基本评估流程</p>
<p>
<img src="./img/1.png" style="width: 100%">
</p>
<p class="contentList" v-for="item of evaluationProcess">{{item}}</p>
</div>
<div class="page">
<p class="contentList" v-for="item of evaluationProcess2">{{item}}</p>
<p class="title3">2.2.2.&nbsp;结合国家标准L77类目下的度量说明</p>
<p class="contentList" v-for="item of metricDescription">{{item}}</p>
<p class="title4">2.2.2.1.&nbsp;规模测算</p>
<p class="contentList" v-for="item of scaleConversion">{{item}}</p>
</div>
<div class="page">
<p class="contentList">笼统的算法如下式计算:</p>
<p class="contentList" style="text-align:center;">S = US*CF</p>
<p class="contentList" v-for="item of scaleConversion2">{{item}}</p>
<p class="title4">2.2.2.2.&nbsp;工作量测算</p>
<p class="contentList">根据GB/T 36964-2018的流程,规模测算完成的结果,将指导和约束工作量测算和成本测算。</p>
<p>
<img src="./img/2.png" style="width: 100%">
</p>
<p class="contentList">工作量测算在自动化评估中采用GB/T36964-2018的方程法、类比法、类推法3种方法。包含对未知技术依赖的不确定工作量和测试</p>
</div>
<div class="page">
<p class="contentList" style="text-indent:0em;">修改的不可预见工作量。</p>
<p class="contentList" v-for="item of workloadCalculation">{{item}}</p>
</div>
<div class="page">
<p class="contentList" v-for="item of workloadCalculation2">{{item}}</p>
</div>
<div class="page">
<p class="contentList" v-for="item of workloadCalculation3">{{item}}</p>
<p class="title4">2.2.2.3.&nbsp;人工月单价测算</p>
<p class="contentList" v-for="item of unitPriceCalculation">{{item}}</p>
</div>
<div class="page">
<p class="contentList" style="text-indent:0em;">1.5万元/人工月,允许委托单位输入时补充额外金额申请。</p>
<p class="title3">2.2.3.&nbsp;递归的精度与误差说明</p>
<p class="contentList" v-for="item of recursivePrecision">{{item}}</p>
<p class="title4">2.2.3.1.&nbsp;整体类比法</p>
<p class="contentList" v-for="item of overallAnalogy">{{item}}</p>
</div>
<div class="page">
<p class="contentList" style="text-indent:0em;">码或文件。功能非相关的和功能不启用的部分,交由委托单位现场确认。确认后删除或保留。如发现完整性严重缺失,委托单位重新提交。</p>
<p class="contentList">而后二次导入,进行自动化评估。该方法将最大程度筛查和杜绝各种原因造成的调研数据错误、代码文件无关参杂的情况。也是确保评估误差可控的前提。</p>
<p class="title4">2.2.3.1.&nbsp;开发时间固定百分比法</p>
<p class="contentList" v-for="item of fixedDevelopment">{{item}}</p>
</div>
<!-- 3-->
<div class="page">
<p class="contentList" style="text-indent:0em;">推算的预算建议,将作为宁波市安可办的审核依据和预算约束。</p>
<p class="title1">3.&nbsp;原应用系统评估</p>
<p class="title2">3.1.&nbsp;原应用系统概要</p>
<p class="title3">3.1.1.&nbsp;基本信息</p>
</div>
<div v-for="(item,itemIndex) of messageList">
<div class="page" v-for="(arr,index) of item.val">
<p class="contentList" style="text-indent:0em;" v-if="index ===0">{{item.name}}</p>
<div>
<table border="1" cellspacing="0" style="margin-top: 10px;width: 100%;">
<tr v-for="acc of arr">
<td style="width: 10%">{{acc.index}}</td>
<td>{{acc.name}}</td>
<td>{{acc.value}}</td>
</tr>
</table>
</div>
<p class="pageIndex" v-for="item of messagePage">
<span v-if="item.itemIndex === itemIndex && item.arrIndex === index">{{19 + item.page}}</span>
</p>
</div>
</div>
<div class="page">
<p class="title3">3.1.2.&nbsp;原系统代码规模</p>
<div>
<table border="1" cellspacing="0" style="margin: 0px;width: 100%;">
<tr>
<td></td>
<td>数量</td>
<td>备注</td>
</tr>
<tr>
<td>代码</td>
<td>{{sysScale.codeNum}}</td>
<td></td>
</tr>
<tr>
<td>文件</td>
<td>{{sysScale.fileNum}}</td>
<td></td>
</tr>
<tr>
<td>模块</td>
<td>{{sysScale.modelNum}}</td>
<td></td>
</tr>
</table>
</div>
<p class="title2">3.2.&nbsp;关键技术依赖</p>
<p class="contentList">{{technologyDependence}}</p>
</div>
<div v-for="(item,itemInd) of optimized">
<div v-for="(arr,index) of item.val">
<div class="page" v-if="arr.length !== 0">
<p class="title3" v-if="itemInd === 0 && index === 0">3.2.1.&nbsp;可优化的项</p>
<p v-if="index === 0" style="display: flex;justify-content: space-between">
<span>关键技术:{{item.name}}</span>
<span>替换策略:
<span v-if="item.name.match(/.*\((.*)\)/)[1] == '支持'">忽略</span>
<span v-else-if="item.name.match(/.*\((.*)\)/)[1] == '不支持'">重新开发</span>
<span v-else-if="item.name.match(/.*\((.*)\)/)[1] == '未知'">修改或重新开发</span>
<span v-else-if="item.name.match(/.*\((.*)\)/)[1] == '优化'">修改</span>
<span v-else>-</span>
</span>
</p>
<table border="1" cellspacing="0" style="margin-top: 10px;">
<tr v-if="index === 0">
<td>关键字</td>
<td>所在文件</td>
<td>位置</td>
</tr>
<tr v-for="acc of arr">
<td>{{acc.keyWord}}</td>
<td>{{acc.file}}</td>
<td>{{acc.position}}</td>
</tr>
</table>
<p class="pageIndex" v-for="item of optimizedPage">
<span v-if="item.itemIndex === itemInd && item.arrIndex === index">{{20 + item.page + page1}}</span>
</p>
</div>
</div>
</div>
<div class="page" v-if="optimized.length === 0">
<p class="title3">3.2.1.&nbsp;可优化的项</p>
<p>暂无</p>
</div>
<div v-for="(item,itemInd) of replaced">
<div v-for="(arr,index) of item.val">
<div class="page" v-if="arr.length !== 0">
<p class="title3" v-if="itemInd === 0 && index === 0">3.2.2.&nbsp;必须替换的项</p>
<p v-if="index === 0" style="display: flex;justify-content: space-between">
<span>关键技术:{{item.name}}</span>
<span>替换策略:
<span v-if="item.name.match(/.*\((.*)\)/)[1] == '支持'">忽略</span>
<span v-else-if="item.name.match(/.*\((.*)\)/)[1] == '不支持'">重新开发</span>
<span v-else-if="item.name.match(/.*\((.*)\)/)[1] == '未知'">修改或重新开发</span>
<span v-else-if="item.name.match(/.*\((.*)\)/)[1] == '优化'">修改</span>
<span v-else>-</span>
</span>
</p>
<table border="1" cellspacing="0" style="margin-top: 10px">
<tr v-if="index === 0">
<td>关键字</td>
<td>所在文件</td>
<td>位置</td>
</tr>
<tr v-for="acc of arr">
<td>{{acc.keyWord}}</td>
<td>{{acc.file}}</td>
<td>{{acc.position}}</td>
</tr>
</table>
<p class="pageIndex" v-for="item of replacedPage">
<span v-if="item.itemIndex === itemInd && item.arrIndex === index && optimized.length !== 0">{{20 + item.page + page1 + page2}}</span>
<span v-if="item.itemIndex === itemInd && item.arrIndex === index && optimized.length === 0">{{20 + item.page + page1 + 1}}</span>
</p>
</div>
</div>
</div>
<div class="page" v-if="replaced.length === 0">
<p class="title3">3.2.2.&nbsp;必须替换的项</p>
<p>暂无</p>
</div>
<div v-for="(item,itemInd) of verification">
<div v-for="(arr,index) of item.val">
<div class="page" v-if="arr.length !== 0">
<p class="title3" v-if="itemInd === 0 && index === 0">3.2.3.&nbsp;需要验证修改的项</p>
<p v-if="index === 0" style="display: flex;justify-content: space-between">
<span>关键技术:{{item.name}}</span>
<span>替换策略:
<span v-if="item.name.match(/.*\((.*)\)/)[1] == '支持'">忽略</span>
<span v-else-if="item.name.match(/.*\((.*)\)/)[1] == '不支持'">重新开发</span>
<span v-else-if="item.name.match(/.*\((.*)\)/)[1] == '未知'">修改或重新开发</span>
<span v-else-if="item.name.match(/.*\((.*)\)/)[1] == '优化'">修改</span>
<span v-else>-</span>
</span>
</p>
<table border="1" cellspacing="0" style="margin-top: 10px">
<tr v-if="index === 0">
<td>关键字</td>
<td>所在文件</td>
<td>位置</td>
</tr>
<tr v-for="acc of arr">
<td>{{acc.keyWord}}</td>
<td>{{acc.file}}</td>
<td>{{acc.position}}</td>
</tr>
</table>
<p class="pageIndex" v-for="item of verificationPage">
<span v-if="item.itemIndex === itemInd && item.arrIndex === index && optimized.length !== 0 && replaced.length !== 0">{{20 + item.page + page1 + page2 + page3}}</span>
<span v-if="item.itemIndex === itemInd && item.arrIndex === index && optimized.length === 0 && replaced.length !== 0">{{20 + item.page + page1 + 1 + page3}}</span>
<span v-if="item.itemIndex === itemInd && item.arrIndex === index && optimized.length !== 0 && replaced.length === 0">{{20 + item.page + page1 + 1 + page2}}</span>
<span v-if="item.itemIndex === itemInd && item.arrIndex === index && optimized.length === 0 && replaced.length === 0">{{20 + item.page + page1 + 2}}</span>
</p>
</div>
</div>
</div>
<div class="page" v-if="verification.length === 0">
<p class="title3">3.2.3.&nbsp;需要验证修改的项</p>
<p>暂无</p>
</div>
<div class="page">
<p class="title2">3.3.&nbsp;难度系数和综合系数修正</p>
<div>
<table border="1" cellspacing="0" style="margin-top: 10px;width: 100%">
<tr>
<td></td>
<td>系统评估</td>
<td>用户额外信息</td>
<td>综合难度</td>
<td>工作量</td>
</tr>
<tr>
<td>系统架构部署难度</td>
<td v-for="item of systemStructure">{{item}}</td>
</tr>
<tr>
<td>中间件/API/微服务</td>
<td v-for="item of middleware">{{item}}</td>
</tr>
<tr>
<td>数据库</td>
<td v-for="item of dataBase">{{item}}</td>
</tr>
<tr>
<td>本地程序</td>
<td v-for="item of localProgram">{{item}}</td>
</tr>
</table>
</div>
<p class="title2">3.4.&nbsp;人工月估算</p>
<div>
<table border="1" cellspacing="0" style="margin-top: 10px;width: 100%">
<tr>
<td></td>
<td>开发量</td>
<td>修正系数</td>
</tr>
<tr>
<td>开发</td>
<td>{{monthlyEstimate.development.developmentVolume}}</td>
<td>{{monthlyEstimate.development.correctionFactor}}</td>
</tr>
<tr>
<td>测试</td>
<td>{{monthlyEstimate.test.developmentVolume}}</td>
<td>{{monthlyEstimate.test.correctionFactor}}</td>
</tr>
<tr>
<td>部署</td>
<td>{{monthlyEstimate.deploy.developmentVolume}}</td>
<td>{{monthlyEstimate.deploy.correctionFactor}}</td>
</tr>
<tr>
<td>合计</td>
<td>{{monthlyEstimate.total.developmentVolume}}</td>
<td>{{ this.monthlyEstimate.total.correctionFactor === -1 ?
this.monthlyEstimate.total.correctionFactor = '-' : this.monthlyEstimate.total.correctionFactor }}</td>
</tr>
</table>
</div>
<p class="title2">3.5.&nbsp;额外申请</p>
<div>
<table border="1" cellspacing="0" style="margin-top: 10px;width: 100%;">
<tr>
<td>费用</td>
<td>原因</td>
</tr>
<tr>
<td>{{this.newApply.cost === -1 ? '无' : this.newApply.cost}}</td>
<td>{{this.newApply.reason === '-1' ? '无' : this.newApply.reason}}</td>
</tr>
</table>
</div>
</div>
<div class="page">
<p class="title2">3.6.&nbsp;预算建议</p>
<p class="contentList">
由于不同地区、不同行业甚至不同功能项的软件开发人工月单价存在浮动,请在表格内调节该参数。调整后预算费用: {{newCost.cost.now}} 万元,
难度系数:<span v-if="degreeOfDifficulty">{{degreeOfDifficulty}}</span>
</p>
<div>
<table border="1" cellspacing="0" style="margin-top: 10px;width: 100%">
<tr>
<td></td>
<td>默认值</td>
<td>操作</td>
<td>调整后</td>
</tr>
<tr>
<td>人工单价(万元)</td>
<td>{{newCost.person.normal}}</td>
<td>{{newCost.person.operating}}</td>
<td>{{newCost.person.now}}</td>
</tr>
<tr>
<td>工作量</td>
<td>{{newCost.work.normal}}</td>
<td>{{newCost.work.operating}}</td>
<td>{{newCost.work.now}}</td>
</tr>
<tr>
<td>额外依赖服务申请(万元)</td>
<td>{{newCost.other.normal}}</td>
<td>{{newCost.other.operating}}</td>
<td>{{newCost.other.now}}</td>
</tr>
<tr>
<td>预算费用(万元)</td>
<td>{{newCost.cost.normal}}</td>
<td>{{newCost.cost.operating}}</td>
<td>{{newCost.cost.now}}</td>
</tr>
</table>
</div>
</div>
<!-- 4-->
<div class="page">
<p class="title1">4.&nbsp;评估建议</p>
<p class="title2">4.1.&nbsp;适配/改造路线选择</p>
<p class="contentList" v-for="item of routeSelection">{{item}}</p>
<p class="title2">4.2.&nbsp;关键工作与方法</p>
<p class="title3">4.2.1.&nbsp;开发框架解决方法</p>
<p class="contentList">J2EE和类似跨平台的开发框架,可通过适配和代码改造,完全移植到国产化环境下。</p>
<p class="contentList">基于.NET体系下使用VB、Delphi、VC、C++、C#等语言,完全依</p>
</div>
<div class="page">
<p class="contentList" style="text-indent:0em;">赖Window组件和库的应用系统,需要换框架重构。</p>
<p class="title3">4.2.2.&nbsp;浏览器的适配兼容性改造解决方法</p>
<p class="contentList" v-for="item of adaptationCompatible">{{item}}</p>
<p class="title3">4.2.3.&nbsp;浏览器功能组件的替换和适配解决方法</p>
<p class="contentList" v-for="item of replacementAndAdaptation">{{item}}</p>
</div>
<div class="page">
<p class="title3">4.2.4.&nbsp;B/S结构下的重构</p>
<p class="contentList">B/S结构的重构,主要是更换跨平台开发框架。其难度集中在寻找windows本地组件功能的替代品,目前UOS、麒麟OS相同功能的组件和调用方法比较成熟,整体开发风险不高。</p>
<p class="title3">4.2.5.&nbsp;C/S结构下的重构</p>
<p class="contentList">如改造后必须维持C/S结构,本地客户端程序可选择QT开发框架实现在Linux内核操作系统和Windows操作系统上的跨平台,也可选择使用JAVA Application方案中JVM、Node JS这类伪C/S本地客户端搭建。后端则建议更改为J2EE体系框架或其他跨平台框架。</p>
<p class="contentList">如改造后允许以B/S结构部署,则改造工作量和不可预见问题将大为减少。</p>
<p class="title3">4.2.6.&nbsp;部署和迁移策略</p>
<p class="contentList" v-for="item of deploymentAndMigration">{{item}}</p>
</div>
<div class="page">
<p class="contentList" v-for="item of deploymentAndMigration2" style="text-indent:0em;">{{item}}</p>
<p style="text-align: center;">
<img src="./img/3.png" style="width: 50%">
</p>
<p class="contentList" v-for="item of deploymentAndMigration3">{{item}}</p>
</div>
<div class="page">
<p class="contentList" v-for="item of deploymentAndMigration4" style="text-indent:0em;">{{item}}</p>
<p class="contentList">最后要监测解决冲突,及时对异常数据进行处理。由于数据库双向可写,需监控监测冲突,并做好对应的日志记录。当出现异常数据,例如要求插入的数据,数据库中已经存在;或者更新数据,发现数据记录并不存在,需根据预定义的规则进行相应的处理。</p>
</div>
<div class="page">
<p class="title1">5.&nbsp;附件</p>
<p class="contentList" v-for="item of annex" style="text-indent:0em;">{{item}}</p>
</div>
</div>
</div>
</template>
<script>
import $ from 'jquery'
export default {
data () {
return {
htmlTitle:'', // pdf名称
title: 'XXXXXX', // 单位名称
systemName: 'XXXXXXXXX', // 系统名称
version: 1, // 第几次评估
reportName: '在国产化安全自主可控环境下的适配/改造工作评估报告',
tableContent: [
{name: '评估机构:', val: '宁波市安可办'},
{name: '报告版本:', val: ''},
{name: '时间:', val: ''},
{name: '委托单位签字:', val: ''},
{name: '评估机构签字:', val: ''}
],
listContent: [
{name: '目录', val: 1},
{
name: '1. 评估报告声明',
val: '',
child1: [
{
name: '1.1. 报告组成',
val: '',
},
{
name: '1.2. 报告作用',
val: '',
},
{
name: '1.3. 其他注意事项',
val: '',
}
]
},
{
name: '2. 评估标准和方法',
val: '',
child1: [
{
name: '2.1. 参照标准',
val: '',
child2: [
{
name: '2.1.1. “912工程”相关政策法规',
val: ''
},
{
name: '2.1.2. “912工程”相关国家标准与规范',
val: ''
},
{
name: '2.1.3. “L77软件工程”国家分类标准',
val: ''
},
{
name: '2.1.4. 其他编制依据',
val: ''
}
]
},
{
name: '2.2. 评估流程与方法',
val: '',
child2: [
{
name: '2.2.1. 基本评估流程',
val: ''
},
{
name: '2.2.2. 结合国家标准L77类目下的度量说明',
val: ''
},
{
name: '2.2.3. 递归的精度与误差说明',
val: ''
}
]
}
]
},
{
name: '3. 原应用系统评估',
val: '',
child1: [
{
name: '3.1. 原应用系统概要',
val: '',
child2: [
{
name: '3.1.1. 基本信息',
val: '',
},
{
name: '3.1.2. 原系统代码规模',
val: '',
}
]
},
{
name: '3.2. 关键技术依赖',
val: '',
child2: [
{
name: '3.2.1. 可优化的项',
val: ''
},
{
name: '3.2.2. 必须替换的项',
val: ''
},
{
name: '3.2.3. 需要验证修改的项',
val: ''
}
]
},
{
name: '3.3. 难度系数和综合系数修正',
val: ''
},
{
name: '3.4. 人工月估算',
val: ''
},
{
name: '3.5. 额外申请',
val: ''
},
{
name: '3.6. 预算建议',
val: ''
}
]
},
{
name: '4. 评估建议',
val: '',
child1: [
{
name: '4.1. 适配/改造路线选择',
val: ''
},
{
name: '4.2. 关键工作与方法',
val: '',
child2: [
{
name: '4.2.1. 开发框架解决方法',
val: ''
},
{
name: '4.2.2. 浏览器的适配兼容性改造解决方法',
val: ''
},
{
name: '4.2.3. 浏览器功能组件的替换和适配解决方法',
val: ''
},
{
name: '4.2.4. B/S结构下的重构',
val: ''
},
{
name: '4.2.5. C/S结构下的重构',
val: ''
},
{
name: '4.2.6. 部署和迁移策略',
val: ''
}
]
}
]
},
{
name: '5. 附件',
val: ''
}
], // 目录内容
reportComposition: [
'本报告由标准、流程和方法解释、评估结果、建议等组成。',
'其中标准相关章节,涵盖了国家、省、市有关“912工程”的相关政策、法规、技术标准,以及国家分类标准“L77”软件工程类目下最新的度量、评价、技术标准。',
'其中流程和方法解释章节,只描述算法上的逻辑和误差控制逻辑,并根据宁波市实际情况设定误差范围,并提供方法解释。为防止代码文件或部署文件的作弊,不提供宁波市采用的具体算法公式、系数表、参照组参数表、知识库、对比库。',
'评估结果为应用系统在国产化安全自主可控环境下的适配/改造代码工作量和相应的预算评估。即已包含代码编写/修改、开发单位内部测试、部署3大过程和3大过程种相应的不可预见量和额外申请。不包含安可设备采购、安可数据库/中间件采购、安可操作系统采购、安可目录中的固定软件采购、过程咨询、原有数据迁移、整体系统割接的工作量和预算。',
'评估建议为指导性、参考性的方法,应由各单位根据实际情况自行判断和采纳。'
],
reportingRole: [
'评估报告的作用一:作为宁波市“912工程”各单位开展应用适配/改造的预算修正依据,作为工作量可视化的参考依据,作为对原开发单位上报方案的对照组和约束依据。',
'评估报告的作用二:在宁波市“912工程”各单位项目基本完成后,应用迁入宁波市安可云之前,作为适配/改造的结果测试对照,以及完成率的审计对照。',
'如实际项目实施超出评估报告的预算建议,请具体实施单位根据项目变更管理相关规范,向建设单位提供变更依据。'
],
reportOther: [
'本次评估的输入为调研表格和原应用的代码文件(无论封装与否),无代码文件的可提供服务器部署路径下的全部文件。不需要提供数据库部署文件和实际数据。',
'输出结果即为本报告。',
'本次评估采用的评估工具可适用于B/S、C/S、单机部署、分布式等系统的扫描,可适用于.NET体系、J2EE体系、Linux平台体系下的开发编译环境。适用于C、C++、C#、VB、Delphi、PHP、Java、Python、Go、MATLAB、Rust、Ruby、Perl等语言的扫描分析。',
'委托单位应确保调研表格和代码文件的完整性和真实性。评估过程存在对照组,如非相干性误差超出±5%,自动评估工具触发整体类比,并转入人工审核。评估报告中会列出非相干性部分,并列出人工干预后的结论。'
],
reportOther2: [
'委托单位对评估报告的相关结论如有疑议,请于7个工作日内向宁波市安可办(补充全称)提出书面申诉和补充说明材料(格式见附件)。由宁波市安可办(补充全称)另行组织评审专家采用专家评估法进行人工仲裁。专家评审相关费用由委托单位承担。'
],
regulations: [
'《关于实施党政机关电子公文系统安全可靠应用全面替代的意见》(厅字〔2019〕31号);',
'《关于贯彻落实<关于实施党政机关电子公文系统安全可靠应用全面替代的意见>的通知》(电文安组〔2019〕5号);',
'《关于印发丁薛祥同志在安可替代工程部署工作会议上讲话的通知》(电文安组〔2019〕7号);',
'《关于更新<党政机关安全可靠应用信息类产品采购名录>的通知》(电文安组〔2019〕3号);',
'《关于印发<涉密专用信息设备名录(第二期)>和<涉密专用信息设备适配软硬件名录;(第二期)>的通知》(国保发﹝2018﹞49号);',
'《关于印发<安可替代工程国家秘密事项和内部事项一览表>的通知》(电文安组〔2019〕6号);',
],
regulations2: [
'《关于加强安可替代工程廉政风险防控的通知》(电文安组〔2019〕8号);',
'《“十三五”国家信息化规划》(国发〔2016〕73号);',
'《国家电子政务内网建设和管理工作“十三五”规划》(厅字〔2016〕39号);',
'《关于进一步加强国家电子政务网络建设和应用工作的通知》(发改高技〔2012〕1986号);',
'《国家电子政务工程建设项目管理暂行办法》(发改委第55号令)',
'《政务信息资源共享管理暂行办法》(国发〔2016〕51号);',
'《关于进一步加快电子政务内网建设和保密测评审查做好发至县团级中央文件网上传递和办理支撑工作的通知》(国政网办〔2019〕3号)。'
],
supplement: [1], // 宁波补充文件
nationalNorms: [
'《党政机关电子公文系统安全可靠应用需求规范(暂行)》(电文安办〔2017〕4号)',
'《电子政务内网密钥管理基础设施建设要求》;',
'《电子政务内网电子认证基础设施技术要求》;',
'《国家电子政务内网业务信息和电子文件交换系统技术规范》;',
'《电子文件存储与交换格式版式文档》(GB/T 33190-2016);',
'《党政机关电子公文格式规范第1部分公文结构》(GB/T '
],
nationalNorms2:[
'33476.1-2016);',
'《党政机关电子公文格式规范第2部分显现》(GB/T 33476.2-2016);',
'《党政机关电子公文格式规范第3部分实施指南》(GB/T 33476.3-2016);',
'《党政机关电子公文标识规范》(GB/T 33477-2016);',
'《党政机关电子公文应用接口规范》(GB/T 33478-2016);',
'《党政机关电子公文交换接口规范》(GB/T 33479-2016);',
'《党政机关电子公文元数据规范》(GB/T 33480-2016);',
'《党政机关电子印章应用规范》(GB/T 33481-2016);',
'《党政机关电子公文系统建设规范》(GB/T 33482-2016);',
'《党政机关电子公文系统运行维护规范》(GB/T 33483-2016);',
'《涉及国家秘密的信息系统分级保护技术要求》(BMB17-2006);',
'《涉及国家秘密的信息系统分级保护管理规范》(BMB20-2007);',
'《涉及国家秘密的信息系统测评指南》(BMB22-2001);',
'《涉及国家秘密的信息系统分级保护方案设计指南》(BMB23-2008);',
'《信息安全等级保护管理办法》(公通字〔2007〕43号);',
'《计算机信息系统安全保护等级划分准则》(GB17859-1999);',
'《信息安全技术 信息安全风险评估规范》(GB/T 20984-2007);',
'《信息安全技术 网络安全等级保护定级指南》(GB/T 22240-2008);'
],
nationalNorms3: [
'《信息安全技术 网络安全等级保护基本要求》(GB/T 22239-2019);',
'《信息安全技术 网络安全等级保护安全设计技术要求》(GB/T 25070-2019);',
'《信息安全技术 网络安全等级保护测评要求》(GB/T 28448-2019);',
'《信息安全技术 网络安全等级保护测评过程指南》(GB/T 28449-2018);'
],
classificationCriteria: [
'《软件过程能力评估模型》(SJ/T 11234-2001);',
'《信息技术 系统及软件完整性级别》(GB/T 18492—2001);',
'《软件工程 软件测量过程》(GB/T 20917-2007);',
'《信息技术 软件生存周期过程》(GB/T 8566-2007);',
'《计算机软件需求规格说明规范》(GB/T 9385-2008);',
'《软件研发(造价)成本度量规范(应用指南)》(SJ/T-11463-2013);',
'《系统与软件可移植性 第1部分:指标体系》(GB/T 29833.1-2013);',
'《系统与软件可移植性 第2部分:度量方法》(GB/T 29833.2-2013);',
'《系统与软件可移植性 第3部分:测试方法》(GB/T '
],
classificationCriteria2:[
'29833.3-2013);',
'《软件工程 软件工程知识体系指南》(GB/Z 31102-2014);',
'《系统工程 GB/T 22032(系统生存周期过程)应用指南》(GB/Z 31103-2014);',
'《系统与软件工程 可信计算平台可信性度量 第1部分:概述与词汇》(GB/T 30847.1-2014);',
'《软件工程 软件评审与审核》(GB/T 32421-2015)',
'《系统与软件工程 验证与确认》(GB/T 32423-2015);',
'《软件工程 软件开发成本度量规范》试行版(GB/T 36964-2018);',
'《系统与软件工程 系统与软件质量要求和评价(SQuaRE)第41部分:开发方、需方和独立评价方评价指南》试行版(GB/T 25000.41-2018)。'
],
otherEstablishments: [
'《党政机关安全可靠应用信息类产品采购名录-1-2019(涉密专用信息设备-终端)》;',
'《党政机关安全可靠应用信息类产品采购名录-1-2019(涉密专用信息设备-服务器)》;',
'《党政机关安全可靠应用信息类产品采购名录-1-2019(涉密专用信息设备适配软硬件)》;',
'《党政机关安全可靠应用信息类产品采购名录-1-2019(基础通用信息设备)》;'
],
otherEstablishments2: [
'《党政机关安全可靠应用信息类产品采购名录-1-2019(基础通用信息适配软硬件)》;',
'《党政机关安全可靠应用信息类产品采购名录-1-2019(商用密码产品)》;'
],
evaluationProcess: [
'流程一:输入。调研表格和原应用的代码文件(无论封装与否),无代码文件的可提供服务器部署路径下的全部文件。不需要提供数据库部署文件和实际数据。'
],
evaluationProcess2: [
'流程二:自动化分析过程。该过程无人工干预,按照既定的标准和算法进行。',
'流程三:误差控制。当自动化分析过程中判断误差超出阈值,则触发误差控制流程。该过程有人工审核和委托单位确认环节。',
'流程四:输出。本评估报告即为输出结果,如发生申诉,则以专家二次评审后修正的评估报告为输出结果。'
],
metricDescription: [
'评估采用根据现行的《系统与软件可移植性 第2部分:度量方法》(GB/T 29833.2-2013)和试行的《软件工程 软件开发成本度量规范》(GB/T 36964-2018)提供的规模测算、工作量测算法、人工月单价取值,将结合宁波市的实际情况以及约束条件给予难度系数和综合系数调整。'
],
scaleConversion: [
'根据调研数据和自动化扫描分析中明确的系统边界、开发金额、开发周期和技术依赖为前提,进行评估软件规模。',
'规模测算所采用的方法,选用现行的SJ/T 11617—2016、SJ/T 11618—2016、SJ/T 11619—2016、SJ/T 11620—2016和ISO/IEC 20926:2009五种功能规模度量综合评估。'
],
scaleConversion2:[
'式中:',
'S ——调整后规模,单位为关键技术依赖点(FP)。',
'US ——未调整规模(根据扫描和调研表的内容),单位为关键技术依赖点(FP)。',
'CF ——规模变更因子(根据适配/改造的不同技术要求),取值系数范围0.3〜1.6。',
'其中精细算法和系数表不予公开。已考虑了不可预计的工作,并进行上浮折算。'
],
workloadCalculation:[
'笼统的基准数据回归方程如下式计算:',
'UE = C*S*U',
'式中:',
'UE ——初步工作量,单位为人工月(pm);',
'C ——基于代码扫描得出的基准数据的难度调整系数,单位为人工月每技术依赖点(pm/FP);',
'S ——软件规模(上一节规模计算得出的值),单位为关键技术依赖点(FP);',
'U ——基于代码扫描得出的基准数据的综合调整系数。',
'根据相关性分析、知识库、对比库、经验库确定调整后工作量计算公式按下式计算:',
'AE = UE*C2*IL*U2*T',
'式中:',
'AE ——调整后的工作量,单位为人工月(pm);',
'C2 ——二次运算后的综合调整系数;',
'IL ——根据输入数据的完整性级别,对应的误差约束百分比;',
'U2 ——二次运算后的难度调整系数;',
'T ——“912工程”应用适配/改造宁波本地工时测算误差约束百分比。',
'其中精细算法和系数表不予公开。已考虑了不可预计的工作,并进行上浮折算。'
],
workloadCalculation2:[
'评估工具已经考虑的主要因素包括(但不限于):',
'1)软件规模,除上节计算的软件规模,还考虑了委托方软件业务领域、软件应用类型、涉密与否,并给予难度系数调整,难度系数表不公开。',
'2)功能复用情况,评估工具已知的复用功能将不被计入工作量,未知的将不可预见工作量进行调整。',
'3)评估输入的完整性,调研表、代码文件或部署文件的完整度,工作量测算根据完整性分为A、B、C、D四个等级,确定的方法见GB/T 18492—2001中第7章。不同完整性造成的测算误差将被评估工具强制约束在±10%内。因此不完整输入造成评估预期偏低的结果,由委托方承担。',
'4)可移植性的要求见GB/T 29833.1-2013、GB/T 25000—2018,考虑到不同可移植性,对应的改造、重构方法不同,评估工具给予难度系数调整,难度系数表不公开。',
'5)早期开发的金额和人工月的可借鉴性,评估工具以2014为界限,2014年前开发和2014年后开发的应用均按年给予综合系数调整,综合系数表不公开。',
'6)国产化环境下应使用的技术,如开发平台、编程语言、系统架构和操作系统等。评估工具默认将调研数据、扫描结果和知识库匹配,选取Linux内核操作系统下的跨平台语言、国产化数据库、中间件的最高难度系数组合。难度系数表不公开。'
],
workloadCalculation3:[
'7)未知技术依赖的不确定替代工作量和不可预见的工作量,根据扫描结果和知识库、对比库的比对分析,不可避免存在未知技术依赖和无法直接量化的不可预见工作。评估工具将给予难度系数调整和综合系数调整。',
'8)开发团队,已考虑本地/外地区别,代码质量反映的开发成熟度区别等,评估工具将给予系数调整。对结果的影响强制约束在±1%。因此,开发单位服务能力和成熟度区别造成实际投入偏差,由委托方承担。',
'评估工具不考虑因素:安可设备采购、安可数据库/中间件采购、安可操作系统采购、安可目录中的固定软件采购、过程咨询、原有数据迁移、整体系统割接的工作量和预算。'
],
unitPriceCalculation:[
'根据GB/T36964-2018人工月单价应考虑直接人力成本估算、间接人力成本估算、间接非人力成本估算,最后采用微积分发计算。但“912工程”应用适配/改造的评估是集中在“代码工作”的评估,因此不适用于完整软件工程的人工月单价测算方法。更适合采用GB/T 25000.41-2018中对软件重构部分的费用评估,即采用软件重构基准单价+额外金额申请。',
'评估工具中针对宁波本地情况,软件重构人工月单价基准值设为'
],
recursivePrecision:[
'评估工具算法工作量依赖于扫描代码文件或部署文件来计算开发工作量,叠加难度系数、综合系数和人工月单价,推算出预算建议。',
'其算法结合宁波安可办根据“912工程”相关参考依据和GB/T36964-2018、GB/T 25000.41-2018综合后制定的算法。算法已经遍历4000种不同组合的情况进行测试。当前测试优化后的结果与专家法和Delphi法的结果误差小于10%。',
'考虑到多种情况的误差控制,以及被评估的应用系统其原开发单位可能出于多种原因对工作量结果的申诉。',
'为此,在评估工具算法基础上,再引入整体类比法和开发时间固定百分比法进行对比参照。'
],
overallAnalogy:[
'该方法用于校验非相干性误差的比例和经验值对比。',
'当调研表数据或代码文件存在缺失、错误、无关参杂的情况,其与扫描项对比超过±5%的非相干性误差。将触发评估工具调用经验库,采用整体类比法。',
'整体类比法的使用过程,首先比照经验库列出所有非相干性的工作量,人工审核找到代码文件中对应的文件或代码,现场在编译环境下逐条调试和运行。凡调试失败和路由指向缺失的部分,直接删除代'
],
fixedDevelopment:[
'该方法用于二次校对和约束开发工作量上下限。',
'评估中项目的总工作量组成,参照GB/T36964-2018中分配比例,并针对宁波市“912工程”的实际情况,默认总工作量40%给代码工作,5-7%给组件和集成测试,13-20%给系统测试,10%给接收测试(或回归测试等)。',
'评估工具会自动使用该方法。首先,扫描代码并分析开发工作量测算出理论值A1。不可预见量、难度系数、综合系数叠加运算出理论值A2,A2的加权系数为0.6。再按照使用GB/T36964-2018提供的方程法估算出对比值B1,然后使用GB/T36964-2018提供的类比法和类推法来推算并限制对比值B1,形成对比值B2。B2的加权系数为0.4。',
'如A2/B2在±10%内,取A2值;反之取A2、B2的加权平均值。',
'这种方法的精确度取决于输入调研表数据和代码文件的完整性,其结果误差在本次评估中被限定在+10%以内,对预算影响被限定在+4.5%以内。',
'综上,误差控制和误差范围可接受。本评估报告计算的工作量和'
],
routeSelection:[
'B/S应用系统的浏览器前端部分,主要面临编译结果在不同内核下标准兼容的问题,在安可操作系统上主要针对火狐浏览器(52版本)、360安全浏览器上的兼容性适配,主要工作集中在前端代码的筛查和轻度改造。',
'B/S应用系统的浏览器插件部分,主要面临Windows WEB插件依赖和驱动调用依赖。主要工作集中在依赖替换,如没有可替换则必须针对性开发。不管哪种方法,都面临同样的高额成本。',
'B/S应用系统的后端主程序、数据库、中间件部分以及C/S应用系统,一般选择代码改造方式,最关键的是将操作系统的依赖关系找到并替换,以确保在Linux内核操作系统下的编译运行和在MIPS、RISC SPARC、ARM指令集环境下的编译。',
'原有在.NET体系下的应用系统,由于对Windows操作系统的依赖不可能完全替换,则必须换开发框架进行软件重构。'
],
adaptationCompatible:[
'原有在X86指令集下只兼容IE Trident内核和Chrome WEBKIT/Blink内核的前端程序,仍需要针对Gecko、Blink内核和ARM、MIPS、RISC SPARC指令集,转换调整JS、CSS、HTML的代码。先根据评估报告中的关键技术依赖枚举,快速定位代码问题点,而后进行代码改造。再采用相应的国产化适配测试工具,完成兼容性测试。'
],
replacementAndAdaptation:[
'电子公文或OA类应用所依赖的Active X插件和其调用的Web Office组件替换。目前有三种解决方案,一是采购国产化厂家提供的文件处理插件,优点是插件和依赖程序已经过调试,替换彻底,缺点是采购价格极高,且需要按照其标准去调用后端服务,后端服务仍需进行改造。二是原有文件处理服务重构,放弃在线预览和编辑功能,退而求其次改为通过下载和上传,满足浏览和编辑需求。三是等待安可云提供统一的在线编辑插件,优点是无需适配,缺点是等待时间未知、采购价格未知。',
'打印或其他外设调用,可由外设厂商提供SDK包,通过二次开发以及封装工作,使外设调用服务可正常运行。',
'插件式文件上传/下载插件,可采用针对国产化浏览器的客户端调用程序进行替代,或重写针对国产化浏览器的扩展服务。'
],
deploymentAndMigration:[
'为了平滑过渡,新老系统需共同运行一段时间。系统迁移需将业务承载在原数据库的同时,通过引入一个中间数据库(数据中心数据库),先将数据同步至中间数据库,再由中间数据库将数据同步到目标国产数据库。一段时间内原数据库和目标国产数据库会同时对外提供访问,且在一定时间范围内保持数据完整一致。即实现异构数据库双向同步,且同步具有一定的实时性,并支持双向数据库可写。',
'以中间数据库作为数据的唯一标准,新老系统的操作通过消息中间件按照操作时间对中间数据库进行有序的进行增删改操作。由于无'
],
deploymentAndMigration2:[
'法对老系统操作源数据库之前进行任何操作(既需保证老系统正常运行),在源数据库、国产数据库同时与中间数据库进行数据同步时,需优先保证老系统完成单个操作内容。通过消息中间件的确认机制可以解决两个数据库同时修改数据的问题,从而达到新老系统同时提供服务的目的。此后,在新系统完善后,可直接移除老系统的相关应用程序,也可直接切断新系统与中间数据库之间的联系,从而达到新老系统平滑过渡的目的。'
],
deploymentAndMigration3:[
'通过日志解析获取两端数据库增量数据,并对消息中间件对增量数据进行缓存。基于消息中间件消息有序性消费的特性保证存储在数据中心数据的一致性和准确性。并且,基于数据中心与同步应用系统,可以实现两端业务库的数据同步。此外,若有需跨业务系统进行数据交换或者数据同步的需求,也可使用此套方法进行解决。',
'建议采用实时数据同步复制采用并行处理体系,实时读取主机源数据库日志,以较低的资源占用实现大批量的数据实时复制。在源端(原'
],
deploymentAndMigration4: [
'数据库)和目的端(国产化数据库),采用优化的日志扫描算法实现目标数据的快速抽取。在传输过程中,将抽取的数据通过消息中间件来进行缓存,并对传输过程中产生的问题进行记录。数据中心通过订阅的方式,与消息中间件建立长连接,不断地从消息中间件集群中拉取数据,并把数据存储进本数据中心数据库中。通过消息中间件来实现源端和目的端数据的一致性。同样,数据中心基于消息中间件与源端和目的端建立发布订阅的关系,运用同步应用程序来实现两端数据库与中心数据库数据的一致性,达到新老系统实时同步数据的目的,保证业务的连续性。'
],
annex:[],
sysScale: { // 原系统代码规模
codeNum: 0,
modelNum: 0,
fileNum: 0
},
technologyDependence: '', // 关键技术依赖
optimizedItemsList: [], // 所有的项
optimized: [], // 可优化
replaced: [], // 必须替换
verification: [], // 需要验证
systemStructure: [], // 系统架构部署难度
middleware: [], // 中间件
dataBase: [], // 数据库
localProgram: [], // 本地程序
monthlyEstimate: { // 人工月估量:开发、测试、部署、合计
development: {
developmentVolume: '',
correctionFactor: ''
},
test: {
developmentVolume: '',
correctionFactor: ''
},
deploy: {
developmentVolume: '',
correctionFactor: ''
},
total: {
developmentVolume: '',
correctionFactor: ''
}
},
newApply: { // 额外申请
cost: '',
reason: ''
},
newCost: { // 预算建议:人工、工作量、额外、预算
person: {
normal: 0,
operating: 0,
now: 0
},
work: {
normal: 0,
operating: '/',
now: 0
},
other:{
normal: 0,
operating: '同意',
now: 0
},
cost:{
normal: '/',
operating: '/',
now: 0
}
},
degreeOfDifficulty: 0, // 难度系数
messageAll: {
"arrayList": [
{
"name": "概要信息",
"remark": "备注",
"value": "填写内容",
"version": "联系方式"
},
{
"name": "单位名称",
"remark": "",
"value": "XXXXX局",
"version": "联系人:XXX\n电话:139XXXXXX"
},
{
"name": "原应用系统名称",
"remark": "",
"value": "XXXXX信息系统",
"version": "/"
},
{
"name": "原开发金额(单位:万元,精确到小数点后2位)",
"remark": "万元",
"value": "135.0",
"version": "/"
},
{
"name": "原开发周期(单位:年)",
"remark": "",
"value": "1年",
"version": "/"
},
{
"name": "已运行时间(单位:年)",
"remark": "",
"value": "4年",
"version": "/"
},
{
"name": "原开发单位是否有本地开发团队",
"remark": "",
"value": "是",
"version": "联系人:XXX\n电话:139XXXXXX"
},
{
"name": "是否为涉密应用",
"remark": "",
"value": "否",
"version": "/"
},
{
"name": "原应用是否通过等级保护/分级保护应用测评",
"remark": "",
"value": "是",
"version": "/"
},
{
"name": "原应用系统结构",
"remark": "",
"value": "B/S",
"version": "/"
},
{
"name": "原应用的部署是否具有容灾恢复能力",
"remark": "",
"value": "否",
"version": "/"
},
{
"name": "原应用系统类型",
"remark": "",
"value": "数据收集、分析、态势感知等大数据应用类",
"version": "/"
},
{
"name": "主要功能模块数",
"remark": "个",
"value": "145.0",
"version": "/"
},
{
"name": "当前数据占用的硬盘空间(单位:TB,精确到小数点后2位,所有当前数据实际使用空间)",
"remark": "TB",
"value": "45.0",
"version": "/"
},
{
"name": "国产化的替代方案",
"remark": "",
"value": "整体改造",
"version": "/"
},
{
"name": "原开发语言体系",
"remark": "版本/类型(如有)",
"value": "",
"version": "备注(可一栏填写多项,使用逗号隔开)"
},
{
"name": "原应用主要开发架构1",
"remark": "",
"value": "J2EE体系下的框架",
"version": ""
},
{
"name": "原应用主要开发架构2",
"remark": "",
"value": "Tornado",
"version": ""
},
{
"name": "原应用主要开发架构3",
"remark": "",
"value": "无",
"version": ""
},
{
"name": "原应用主要开发架构4",
"remark": "",
"value": "无",
"version": ""
},
{
"name": "原应用主要开发架构5",
"remark": "",
"value": "无",
"version": ""
}]
},
messageList:[],
page1: 0, // 3.1.1 基本信息页码数
page2: 0, // 可优化页码数
page3: 0, // 必须替换页码数
page4: 0, // 需要验证页码数
pageAll: 0, // page2,3,4所有页码数
del: 0, // page2,3,4没有数据的页码数
messagePage: [], // 基本信息页码数列
optimizedPage: [], // 可优化页码数列
replacedPage: [], // 必须替换页码数列
verificationPage: [], // 需要验证页码数列
};
},
created() {
this.init()
},
mounted: function () {
},
methods:{
// 获取页码
getPage() {
for (let i = 1; i < $('.page').length; i++) { // 遍历所有的page页面,动态加载的页无法找到,其中里面多了三页无数据页
let html = '<p class="pageIndex">' + i + '</p>'; // 创造页脚
if (i === 20) { // 20页的前两页是3.1.1基本信息的动态数据
html = '<p class="pageIndex">' + (i + this.page1) + '</p>'; // 20页 + 动态数据页码数
}
if (i > 20 && this.del !== 0) { // 20页之后是可优化项动态数据,判断不为空时
html = '<p class="pageIndex">' + (i + this.page1 + this.pageAll - this.del) + '</p>'; // 都不为空,当前页码 + 基本信息页码 + 后面三个动态数据页码 - 为空时添加的三个页码
if (i === 21 && this.page2 === 0) { // 可优化页码为空时,以创造的暂无数据页替代
html = '<p class="pageIndex">' + (i + this.page1) + '</p>';
}
if (i === 22 && this.page3 === 0 && this.page2 !== 0) { // 必须替换页面为空时
html = '<p class="pageIndex">' + (i + this.page1 + this.page2) + '</p>'; // 必须替换页面为空,可优化不为空
} else if (i === 22 && this.page3 === 0 && this.page2 === 0) { // 必须替换页面为空,可优化为空
html = '<p class="pageIndex">' + (i + this.page1 + this.page2 - 1) + '</p>'; // 加上前面所有页然后减去前面1页无数据页
}
if (i === 23 && this.page4 === 0 && this.page2 !== 0 && this.page3 !== 0) { // 需要验证页为空,可优化和必须替换不为空
html = '<p class="pageIndex">' + (i + this.page1 + this.page2 + this.page3) + '</p>'; // 当前页面加上所有动态加载的页码
} else if (i === 23 && this.page4 === 0 && this.page2 === 0 || i === 23 && this.page4 === 0 && this.page3 === 0) { // 可优化或者必须替换一个为空
html = '<p class="pageIndex">' + (i + this.page1 + this.page2 + this.page3 - 1) + '</p>'; // 加上所有页然后减去前面1页无数据页
} else if (i === 23 && this.page4 === 0 && this.page2 === 0 && this.page3 === 0) { // 全部为空时
html = '<p class="pageIndex">' + (i + this.page1 + this.page2 + this.page3 - 2) + '</p>'; // 技术所有页然后减去前面2页无数据页
}
} else if (i > 20 && this.del === 0) { // 当三个页面都为空时,只需要加上之前的基本信息页码
html = '<p class="pageIndex">' + (i + this.page1) + '</p>';
}
let other = '.page:nth-child(' + (i+1) + ')';
$(other).append(html); // 添加页脚
for (let item of this.listContent) { // 导入目录页码
if ($('.page')[i].innerText.indexOf(item.name) !== -1 && item.name !== '目录') { // 去除目录页
item.val = i;
if (item.name === '4. 评估建议' || item.name === '5. 附件') { // 判断为3之后的页面
item.val = i + this.page1 + this.pageAll - this.del; // 3之后的页面需要+所有动态加载页-无数据页面
}
}
if (item.child1 !== undefined) { // 轮询二级目录
for (let arr of item.child1) {
if ($('.page')[i].innerText.indexOf(arr.name) !== -1) {
arr.val = i;
if (arr.name === '3.2. 关键技术依赖') { // 加载在两个动态数据中间页,需要加上前一个动态数据页码
arr.val = i + this.page1;
}
// 以下为3之后的页面
if (arr.name === '3.3. 难度系数和综合系数修正' || arr.name === '3.4. 人工月估算' || arr.name === '3.5. 额外申请' || arr.name === '3.6. 预算建议' || arr.name === '4.1. 适配/改造路线选择' || arr.name === '4.2. 关键工作与方法') {
arr.val = i + this.page1 + this.pageAll - this.del; // 当前页+所有动态数据页-无数据页
}
}
if (arr.child2 !== undefined) { // 轮询三级目录
for (let acc of arr.child2) {
if ($('.page')[i].innerText.indexOf(acc.name) !== -1) {
acc.val = i;
if (acc.name === '3.1.2. 原系统代码规模' || acc.name === '3.2.1. 可优化的项') { // 夹杂在两个动态数据中间的页,需要加上前面动态数据页码
acc.val = i + this.page1
} else if (acc.name === '3.2.2. 必须替换的项' && this.page2 === 0) { // 判断优化项是否为空
acc.val = i + this.page1 // 为空只需要加之前的基本信息页码
} else if (acc.name === '3.2.2. 必须替换的项' && this.page2 !== 0) { // 优化项不为空
acc.val = i + this.page1 + this.page2; // 再加优化项的页码
} else if (acc.name === '3.2.3. 需要验证修改的项' && this.page2 !== 0 || acc.name === '3.2.3. 需要验证修改的项' && this.page3 !== 0) { // 判断优化项或者替换项其中一个为空
acc.val = i + this.page1 + this.page2 + this.page3 - 1; // 加上所有的页码 - 1个无数据页
} else if (acc.name === '3.2.3. 需要验证修改的项' && this.page2 === 0 && this.page3 === 0) { // 优化项和替换项都为空
acc.val = i + this.page1 + this.page2 + this.page3 - 2; // 加上所有页码 - 2个无数据页
} else if (acc.name === '4.2.1. 开发框架解决方法' || acc.name === '4.2.2. 浏览器的适配兼容性改造解决方法' || acc.name === '4.2.3. 浏览器功能组件的替换和适配解决方法' || acc.name === '4.2.4. B/S结构下的重构' || acc.name === '4.2.5. C/S结构下的重构' || acc.name === '4.2.6. 部署和迁移策略' ) {
acc.val = i + this.page1 + this.pageAll - this.del // 动态页面之后的子菜单,加上所有的页码 - 无数据页
}
}
}
}
}
}
}
}
},
// 获取打印时间
imeDayFilter () {
let date = new Date();
let month = date.getMonth() + 1; // 月
let strDate = date.getDate(); // 日
if (month >= 1 && month <= 9) {
month = '0' + month;
}
if (strDate >= 0 && strDate <= 9) {
strDate = '0' + strDate;
}
this.tableContent[2].val = date.getFullYear() + month + strDate; // 打印时间
this.tableContent[1].val = date.getFullYear() + month + strDate + '-' + this.version; // 打印时间-版本号
},
init() {
let val = {
name: this.$route.query.username,
id: this.$route.query.id
}
this.$server.getTechnology(val).then(res => {
// console.log('数据请求结果', res.data)
if (res.data !== 500) {
this.systemName = res.data.sysName;
this.reportName =res.data.type === 2 ? '适配' : '改造' + '工作评估报告';
this.reportName = '在国产化安全自主可控环境下的' + this.reportName;
this.htmlTitle = this.reportName;
this.sysScale.codeNum = res.data.sysScale.code.num === -1 ? '-' : res.data.sysScale.code.num;
this.sysScale.modelNum = res.data.sysScale.mode.num === -1 ? '-' : res.data.sysScale.mode.num;
this.sysScale.fileNum = res.data.sysScale.file.num === -1 ? '-' : res.data.sysScale.file.num;
this.technologyDependence = res.data.technologyList.des;
this.systemStructure.push(res.data.difficultyAssessment.frameDifficulty.systemEvaluation);
this.systemStructure.push(res.data.difficultyAssessment.frameDifficulty.message);
this.systemStructure.push(res.data.difficultyAssessment.frameDifficulty.difficulty);
this.systemStructure.push(res.data.difficultyAssessment.frameDifficulty.load);
this.middleware.push(res.data.difficultyAssessment.middlewareDifficulty.systemEvaluation);
this.middleware.push(res.data.difficultyAssessment.middlewareDifficulty.message);
this.middleware.push(res.data.difficultyAssessment.middlewareDifficulty.difficulty);
this.middleware.push(res.data.difficultyAssessment.middlewareDifficulty.load);
this.dataBase.push('/');
this.dataBase.push('/');
this.dataBase.push(res.data.difficultyAssessment.databaseDifficulty.difficulty);
this.dataBase.push(res.data.difficultyAssessment.databaseDifficulty.load);
this.localProgram.push('/');
this.localProgram.push('/');
this.localProgram.push(res.data.difficultyAssessment.programDifficulty.difficulty);
this.localProgram.push(res.data.difficultyAssessment.programDifficulty.load);
this.monthlyEstimate.development.developmentVolume = res.data.workload.development ? res.data.workload.development.developmentVolume : '';
this.monthlyEstimate.development.correctionFactor = res.data.workload.development ? res.data.workload.development.correctionFactor : '';
this.monthlyEstimate.test.developmentVolume = res.data.workload.test ? res.data.workload.test.developmentVolume : '';
this.monthlyEstimate.test.correctionFactor = res.data.workload.test ? res.data.workload.test.correctionFactor : '';
this.monthlyEstimate.deploy.developmentVolume = res.data.workload.deploy ? res.data.workload.deploy.developmentVolume : '';
this.monthlyEstimate.deploy.correctionFactor = res.data.workload.deploy ? res.data.workload.deploy.correctionFactor : '';
this.monthlyEstimate.total.developmentVolume = res.data.workload.total ? res.data.workload.total.developmentVolume : '';
this.monthlyEstimate.total.correctionFactor = res.data.workload.total ? res.data.workload.total.correctionFactor : '';
this.newApply = res.data.apply;
this.newCost.person.normal = res.data.manufacturingCost === '' ? 0 : res.data.manufacturingCost.artificial.calculation;
this.newCost.person.operating = this.$route.query.popp;
this.newCost.person.now = Number(this.newCost.person.normal) + Number(this.newCost.person.operating);
this.newCost.work.normal = res.data.manufacturingCost === '' ? 0 : res.data.manufacturingCost.workLoad.calculation;
this.newCost.work.now = res.data.manufacturingCost === '' ? 0 : res.data.manufacturingCost.workLoad.calculation;
this.newCost.other.normal = res.data.manufacturingCost === '' ? 0 : res.data.manufacturingCost.apply.calculation;
this.newCost.other.now = res.data.manufacturingCost === '' ? 0 : res.data.manufacturingCost.apply.calculation;
this.newCost.cost.now = res.data.manufacturingCost === '' ? 0 : ( ( (Number(this.newCost.person.normal) + Number(this.newCost.person.operating)) * Number(this.newCost.work.now) ) + Number(this.newCost.other.now) ).toFixed(3)
this.degreeOfDifficulty = res.data.manufacturingCost.degreeOfDifficulty.calculation;
if (res.data.technologyList.technologyReports.length !== 0) { // 轮询 3.2
for (let i = 0; i < res.data.technologyList.technologyReports.length; i++) { // 轮询出所有的表
let name = {
name: res.data.technologyList.technologyReports[i].technology,
val: [[]]
}
this.optimizedItemsList.push(name); // 把名称拿出来新增到变量中
let page = 0; // 当前页为0
for (let a = 0; a < res.data.technologyList.technologyReports[i].technologyContents.length; a++) {
if (a % 7 === 0) { // 每隔七条分一页
this.optimizedItemsList[i].val.push([[]]); // 当到了七条就新增一个数组
if (a !== 0) {
page += 1; // 当前页+1
}
}
let value = {
'file': res.data.technologyList.technologyReports[i].technologyContents[a].file,
'keyWord': res.data.technologyList.technologyReports[i].technologyContents[a].keyWord,
'position': res.data.technologyList.technologyReports[i].technologyContents[a].position
}
this.optimizedItemsList[i].val[page].push(value) // 把对应的值放到对应表和对应的页中
}
}
for (let item of this.optimizedItemsList){ // 遍历最后生成的列表
for (let i = 0; i<item.val.length; i++) {
if (item.val[i].length === 1 && item.val[i][0].length === 0) { // 去除最后一个新增的空数组页
item.val.splice(i)
}
}
if (item.name.match(/.*\((.*)\)/)[1] === '不支持'){ // 判断,目前只收取不支持,未知,优化三个表
this.replaced.push(item)
} else if (item.name.match(/.*\((.*)\)/)[1] === '未知') {
this.verification.push(item)
} else if (item.name.match(/.*\((.*)\)/)[1] === '优化') {
this.optimized.push(item)
}
}
}
this.imeDayFilter(); // 获取时间
this.init2(); // 获取基本信息数据
}
})
},
init2() {
// this.$server.getExcel('this.$route.query.id').then(res =>{
// console.log(res)
// })
for (let item in this.messageAll) { // 遍历基本信息数据
// console.log(item,this.messageAll[item]);
let array = [];
let val = {
name: '',
val: []
}
if (item === 'arrayList') {
val.name = '概要信息'
}
array.push(val); // 新增名称和对应的空数组
let page = 0; // 当前页为0
for (let a = 0; a < this.messageAll[item].length; a++) { // 遍历内容
if (a % 20 === 0) { // 二十条为一页
array[array.length - 1].val.push([]); // 当到了二十条,在对应的位置添加空数组
if (a !== 0) { // a初始为0时,page不加1
page += 1;
}
}
let value = {
index: (a+1),
name: this.messageAll.arrayList[a].name,
value: this.messageAll.arrayList[a].value
}
array[array.length - 1].val[page].push(value) // 将值放到对应的数组中
}
this.messageList = array; // 赋值
}
// 遍历内容获取新增数据的页码以及统计所有页码
let messagePa = 0; // 基本信息页码为0
for (let i = 0; i<this.messageList.length; i++) { // 遍历基本信息
this.page1 += this.messageList[i].val.length; // 基本信息总页码统计
for (let a = 0; a < this.messageList[i].val.length; a++) { // 遍历所有的表
messagePa += 1 // 统计当前页为第几页
let val = {
itemIndex: i, // 第几章表
arrIndex: a, // 对应表的第几页
page: messagePa // 当前页码
}
this.messagePage.push(val) // 放到变量中,进行动态数据页手动添加页脚
}
}
// 可优化的项,同上
let optimizedPa = 0;
if (this.optimized.length !== 0) {
for (let i = 0; i < this.optimized.length; i++) {
this.page2 += this.optimized[i].val.length;
for (let a = 0; a < this.optimized[i].val.length; a++) {
optimizedPa += 1
let val = {
itemIndex: i,
arrIndex: a,
page: optimizedPa
}
this.optimizedPage.push(val)
}
}
this.del += 1; // 可优化的页码不为空,需要删除掉一页无数据页
}
// 必须替换页码,同上
let replacedPa = 0;
if (this.replaced.length !== 0) {
for (let i = 0; i < this.replaced.length; i++) {
this.page3 += this.replaced[i].val.length;
for (let a = 0; a < this.replaced[i].val.length; a++) {
replacedPa += 1
let val = {
itemIndex: i,
arrIndex: a,
page: replacedPa
}
this.replacedPage.push(val)
}
}
this.del += 1; // 必须替换页码不为空,需要删除掉一页无数据页
}
// 需要验证页码,同上
let verificationPa = 0;
if (this.verification.length !== 0) {
for (let i = 0; i < this.verification.length; i++) {
this.page4 += this.verification[i].val.length;
for (let a = 0; a < this.verification[i].val.length; a++) {
verificationPa += 1
let val = {
itemIndex: i,
arrIndex: a,
page: verificationPa
}
this.verificationPage.push(val)
}
}
this.del += 1; // 需要验证页码不为空,需要删除掉一页无数据页
}
this.pageAll = this.page2 + this.page3 + this.page4; // 可优化的页 + 必须替换的页 + 需要验证的页
this.getPage() // 获取页码
}
}
}
</script>
<style>
.otherPdf{
background: #e8e8e8;
box-sizing: border-box;
padding: 0px 0 30px 0;
}
.otherPdf #pdfDom{
width: 595px;
background: #fff;
font-family: '仿宋GB2312';
margin: 0 auto;
}
.otherPdf .page{
height: 842px;
padding: 90px 70px;
box-sizing: border-box;
position: relative;
}
.otherPdf .title{
text-align: center;
font-size: 26px;
font-family: "黑体";
line-height: 1.5;
}
.otherPdf table{
font-size: 14px;
font-family: "黑体";
margin-top: 130px;
table-layout: fixed;
}
.otherPdf table td{
text-align: left;
line-height: 1.5;
padding: 0 0 0 10px;
word-break: break-all;
word-wrap:break-word;
}
.otherPdf .list{
margin-bottom: 15px;
font-size: 22px;
text-align: left;
line-height: 1.5;
}
.otherPdf .listContent{
line-height: 1.5;
}
.otherPdf .title1{
font-size: 22px;
line-height: 1.5;
margin: 22px 0;
}
.otherPdf .title2{
font-size: 18px;
line-height: 1.5;
margin: 18px 0;
}
.otherPdf .title3{
font-size: 16px;
line-height: 1.5;
margin: 16px 0;
}
.otherPdf .title4{
font-size: 15px;
line-height: 1.5;
margin: 15px 0;
}
.otherPdf .contentList{
font-size: 14px;
line-height: 1.5;
letter-spacing: 3px;
margin: 10px 0;
text-indent:2em;
}
.otherPdf .pageIndex{
color: #99a9bf;
font-size: 12px;
text-align: center;
position: absolute;
bottom: 15px;
left: 297px;
}
.otherPdf .listContent{
position: relative;
}
.otherPdf .listPage{
position: absolute;
right: 0;
}
.otherPdf .toPdf{
display: inline-block;
width: 100px;
height: 34px;
line-height: 34px;
text-align: center;
background: #4877e6;
cursor: pointer;
border-radius: 4px;
color: #fff;
font-size: 18px;
position: fixed;
top: 50px;
right: 50px;
}
.otherPdf .toPdf:hover{
background: rgba(72,119,230,.6);
}
</style>
...@@ -127,7 +127,7 @@ export default { ...@@ -127,7 +127,7 @@ export default {
for (let item of this.allData) { for (let item of this.allData) {
item.startTime = this.timeC(item.startTime); item.startTime = this.timeC(item.startTime);
item.endTime = this.timeC(item.endTime); item.endTime = this.timeC(item.endTime);
item.schedule = item.processMap.actual === 0 ? '新建' : item.processMap.actual === 1 ? '需求调研阶段' :item.processMap.actual === 2 ? '开发阶段' : item.processMap.actual === 3 ? '试运行阶段' : item.processMap.actual === 4 ? '终验' : ''; item.schedule = item.processMap.actual === 0 ? '新建' : item.processMap.actual === 1 ? '需求调研阶段' : item.processMap.actual === 2 ? '开发阶段' : item.processMap.actual === 3 ? '试运行阶段' : item.processMap.actual === 4 ? '终验' : '';
} }
} else { } else {
this.$message.error(res.data.msg); this.$message.error(res.data.msg);
...@@ -145,7 +145,7 @@ export default { ...@@ -145,7 +145,7 @@ export default {
for (let item of this.allData) { for (let item of this.allData) {
item.startTime = this.timeC(item.startTime); item.startTime = this.timeC(item.startTime);
item.endTime = this.timeC(item.endTime); item.endTime = this.timeC(item.endTime);
item.schedule = item.processMap.actual === 0 ? '新建' : item.processMap.actual === 1 ? '需求调研阶段' :item.processMap.actual === 2 ? '开发阶段' : item.processMap.actual === 3 ? '试运行阶段' : item.processMap.actual === 4 ? '终验' : ''; item.schedule = item.processMap.actual === 0 ? '新建' : item.processMap.actual === 1 ? '需求调研阶段' : item.processMap.actual === 2 ? '开发阶段' : item.processMap.actual === 3 ? '试运行阶段' : item.processMap.actual === 4 ? '终验' : '';
} }
} else { } else {
this.$message.error(res.data.msg); this.$message.error(res.data.msg);
......
...@@ -76,7 +76,7 @@ ...@@ -76,7 +76,7 @@
<span>当前进度</span> <span>当前进度</span>
</p> </p>
<div class="processAll"> <div class="processAll">
<p class="process" v-for="item of marker"> <p class="process" v-for="item of marker" :key="item.name">
<span>{{item.name}}</span> <span>{{item.name}}</span>
<span>{{item.time}}</span> <span>{{item.time}}</span>
<span class="processList"></span> <span class="processList"></span>
......
...@@ -882,6 +882,17 @@ export default { ...@@ -882,6 +882,17 @@ export default {
}, },
// 方法集合 // 方法集合
methods: { methods: {
jump() {
const {href} = this.$router.resolve({
path: 'otherPdf',
query: {
username: this.$route.query.username,
id: this.$route.query.id,
popp: this.popp.basic
}
});
window.open(href, '_blank');
},
goBackprev(){ goBackprev(){
this.$router.push({name:'evaluationReport', query:{ this.$router.push({name:'evaluationReport', query:{
username: this.$route.query.username, username: this.$route.query.username,
...@@ -1369,17 +1380,13 @@ export default { ...@@ -1369,17 +1380,13 @@ export default {
top: -100px; top: -100px;
/*20200318*/ /*20200318*/
border-radius: 5px; border-radius: 5px;
cursor: pointer;
} }
.lineTop>span:hover { .lineTop>span:hover {
/*background: #1E8255; */ /*20200318*/ /*background: #1E8255; */ /*20200318*/
/*20200318*/ /*20200318*/
background: #1c45a4; background: #1c45a4;
} }
/*20200309*/
.lineTop>span:first-child {
background: #cccccc;
color: #fff;
}
.lineTop>span:first-child { .lineTop>span:first-child {
right: 290px; right: 290px;
} }
......
...@@ -62,11 +62,11 @@ export default { ...@@ -62,11 +62,11 @@ export default {
mounted() { mounted() {
console.log(this.detailData) console.log(this.detailData)
if (this.modalName === '修改规则') { if (this.modalName === '修改规则') {
let row = JSON.stringify(this.detailData); //克隆影响原数据需要处理一下 let row = JSON.stringify(this.detailData); // 克隆影响原数据需要处理一下
let obj = JSON.parse(row) let obj = JSON.parse(row)
obj.suffix = obj.suffix.split(",") obj.suffix = obj.suffix.split(',')
this.oldRule = JSON.parse(row); this.oldRule = JSON.parse(row);
this.oldRule.suffix = this.oldRule.suffix.split(",") this.oldRule.suffix = this.oldRule.suffix.split(',')
this.form = { this.form = {
target:this.detailData.target, target:this.detailData.target,
suffix: obj.suffix, suffix: obj.suffix,
...@@ -104,7 +104,7 @@ export default { ...@@ -104,7 +104,7 @@ export default {
id: this.detailData.id, id: this.detailData.id,
oldRule: this.form oldRule: this.form
}; };
obj.suffix = obj.suffix.join(",") obj.suffix = obj.suffix.join(',')
console.log(this.detailData.id) console.log(this.detailData.id)
if (this.modalName === '修改规则') { if (this.modalName === '修改规则') {
this.$server.editConfigUpdate(obj).then(res => { this.$server.editConfigUpdate(obj).then(res => {
......
...@@ -12,7 +12,8 @@ Vue.prototype.$echarts = echarts; ...@@ -12,7 +12,8 @@ Vue.prototype.$echarts = echarts;
Vue.prototype.$store = store; Vue.prototype.$store = store;
Vue.prototype.$server = server; Vue.prototype.$server = server;
Vue.config.productionTip = false; Vue.config.productionTip = false;
import htmlToPdf from './tools/htmlToPdf' // 导出pdf npm install html2canvas jspdf --save
Vue.use(htmlToPdf)
new Vue({ new Vue({
router, router,
store, store,
......
...@@ -5,6 +5,11 @@ Vue.use(Router) ...@@ -5,6 +5,11 @@ Vue.use(Router)
export default new Router({ export default new Router({
routes:[ routes:[
{
path: '/otherPdf',
name: 'otherPdf',
component: resolve => require(['../components/otherPdf/otherPdf.vue'], resolve)
},
{ {
path: '/mainView', path: '/mainView',
name: 'mainView', name: 'mainView',
......
...@@ -27,7 +27,6 @@ axios.interceptors.request.use(function (config) { ...@@ -27,7 +27,6 @@ axios.interceptors.request.use(function (config) {
// 添加响应拦截器 // 添加响应拦截器
axios.interceptors.response.use(function (response) { axios.interceptors.response.use(function (response) {
console.log(response.data)
if (response.data.code === 403) { if (response.data.code === 403) {
v.$message.error(response.data.msg); v.$message.error(response.data.msg);
setTimeout(function () { setTimeout(function () {
......
...@@ -395,6 +395,11 @@ const server = { ...@@ -395,6 +395,11 @@ const server = {
method:'post', method:'post',
data:qs.stringify(data) data:qs.stringify(data)
}) })
},
getExcel(id){
return axios( assess + '/evaluation/in/excel/' + id,{
method:'get'
})
} }
} }
export default server; export default server;
// 导出页面为PDF格式
import Vue from 'vue'
let v = new Vue();
import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
export default {
install (Vue, options) {
Vue.prototype.getPdf = function () {
let title = this.htmlTitle
v.$message.info('正在生成pdf文件!请稍等')
html2Canvas(document.querySelector('#pdfDom'), {
allowTaint: true
}).then(function (canvas) {
let contentWidth = canvas.width
let contentHeight = canvas.height
let pageHeight = contentWidth / 595 * 842
let leftHeight = contentHeight
let position = 0
let imgWidth = 595
let imgHeight = 595 / contentWidth * contentHeight
let pageData = canvas.toDataURL('image/jpeg', 1.0)
let PDF = new JsPDF('', 'pt', 'a4')
if (leftHeight < pageHeight) {
PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight)
} else {
while (leftHeight > 0) {
PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
leftHeight -= pageHeight
position -= 842
if (leftHeight > 0) {
PDF.addPage()
}
}
}
PDF.save(title + '.pdf')
})
}
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论