完成下载附件,完成统计的页面和接口
This commit is contained in:
parent
30809c3896
commit
80a4e88a62
|
|
@ -36,6 +36,9 @@ pnpm build
|
||||||
4.导出功能的依赖
|
4.导出功能的依赖
|
||||||
```shell
|
```shell
|
||||||
npm install xlsx file-saver
|
npm install xlsx file-saver
|
||||||
|
5.展示图标的依赖
|
||||||
|
```shell
|
||||||
|
npm install echarts
|
||||||
|
|
||||||
|
|
||||||
## 技术栈
|
## 技术栈
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,8 @@
|
||||||
"crypto-js": "^4.2.0",
|
"crypto-js": "^4.2.0",
|
||||||
"dayjs": "^1.11.10",
|
"dayjs": "^1.11.10",
|
||||||
"docx": "^8.5.0",
|
"docx": "^8.5.0",
|
||||||
"echarts": "^5.4.3",
|
"echarts": "^5.6.0",
|
||||||
|
"element-plus": "^2.9.7",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"mockjs": "^1.1.0",
|
"mockjs": "^1.1.0",
|
||||||
|
|
@ -840,6 +841,24 @@
|
||||||
"vue": "^3.0.11"
|
"vue": "^3.0.11"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@ctrl/tinycolor": {
|
||||||
|
"version": "3.6.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz",
|
||||||
|
"integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@element-plus/icons-vue": {
|
||||||
|
"version": "2.3.1",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@element-plus/icons-vue/-/icons-vue-2.3.1.tgz",
|
||||||
|
"integrity": "sha512-XxVUZv48RZAd87ucGS48jPf6pKu0yV5UCg9f4FFwtrYxXOwWuVJo6wOvSLKEoMQKjv8GsX/mhP6UsC1lRwbUWg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"vue": "^3.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@emotion/hash": {
|
"node_modules/@emotion/hash": {
|
||||||
"version": "0.8.0",
|
"version": "0.8.0",
|
||||||
"resolved": "https://registry.npmmirror.com/@emotion/hash/-/hash-0.8.0.tgz",
|
"resolved": "https://registry.npmmirror.com/@emotion/hash/-/hash-0.8.0.tgz",
|
||||||
|
|
@ -1261,6 +1280,31 @@
|
||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@floating-ui/core": {
|
||||||
|
"version": "1.6.9",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@floating-ui/core/-/core-1.6.9.tgz",
|
||||||
|
"integrity": "sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@floating-ui/utils": "^0.2.9"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@floating-ui/dom": {
|
||||||
|
"version": "1.6.13",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@floating-ui/dom/-/dom-1.6.13.tgz",
|
||||||
|
"integrity": "sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@floating-ui/core": "^1.6.0",
|
||||||
|
"@floating-ui/utils": "^0.2.9"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@floating-ui/utils": {
|
||||||
|
"version": "0.2.9",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@floating-ui/utils/-/utils-0.2.9.tgz",
|
||||||
|
"integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@gradio/client": {
|
"node_modules/@gradio/client": {
|
||||||
"version": "0.14.0",
|
"version": "0.14.0",
|
||||||
"resolved": "https://registry.npmmirror.com/@gradio/client/-/client-0.14.0.tgz",
|
"resolved": "https://registry.npmmirror.com/@gradio/client/-/client-0.14.0.tgz",
|
||||||
|
|
@ -1523,6 +1567,17 @@
|
||||||
"integrity": "sha512-2LuNTFBIO0m7kKIQvvPHN6UE63VjpmL9rnEEaOOaiSPbZK+zUOYIzBAWcED+3XYzhYsd/0mD57VdxAEqqV52CQ==",
|
"integrity": "sha512-2LuNTFBIO0m7kKIQvvPHN6UE63VjpmL9rnEEaOOaiSPbZK+zUOYIzBAWcED+3XYzhYsd/0mD57VdxAEqqV52CQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@popperjs/core": {
|
||||||
|
"name": "@sxzz/popperjs-es",
|
||||||
|
"version": "2.11.7",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz",
|
||||||
|
"integrity": "sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/popperjs"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@rollup/pluginutils": {
|
"node_modules/@rollup/pluginutils": {
|
||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-5.1.0.tgz",
|
"resolved": "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-5.1.0.tgz",
|
||||||
|
|
@ -1608,14 +1663,12 @@
|
||||||
"node_modules/@types/lodash": {
|
"node_modules/@types/lodash": {
|
||||||
"version": "4.14.202",
|
"version": "4.14.202",
|
||||||
"resolved": "https://registry.npmmirror.com/@types/lodash/-/lodash-4.14.202.tgz",
|
"resolved": "https://registry.npmmirror.com/@types/lodash/-/lodash-4.14.202.tgz",
|
||||||
"integrity": "sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==",
|
"integrity": "sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/@types/lodash-es": {
|
"node_modules/@types/lodash-es": {
|
||||||
"version": "4.17.12",
|
"version": "4.17.12",
|
||||||
"resolved": "https://registry.npmmirror.com/@types/lodash-es/-/lodash-es-4.17.12.tgz",
|
"resolved": "https://registry.npmmirror.com/@types/lodash-es/-/lodash-es-4.17.12.tgz",
|
||||||
"integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==",
|
"integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/lodash": "*"
|
"@types/lodash": "*"
|
||||||
}
|
}
|
||||||
|
|
@ -2796,8 +2849,7 @@
|
||||||
"node_modules/async-validator": {
|
"node_modules/async-validator": {
|
||||||
"version": "4.2.5",
|
"version": "4.2.5",
|
||||||
"resolved": "https://registry.npmmirror.com/async-validator/-/async-validator-4.2.5.tgz",
|
"resolved": "https://registry.npmmirror.com/async-validator/-/async-validator-4.2.5.tgz",
|
||||||
"integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==",
|
"integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/asynckit": {
|
"node_modules/asynckit": {
|
||||||
"version": "0.4.0",
|
"version": "0.4.0",
|
||||||
|
|
@ -4090,9 +4142,10 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/dayjs": {
|
"node_modules/dayjs": {
|
||||||
"version": "1.11.10",
|
"version": "1.11.13",
|
||||||
"resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.10.tgz",
|
"resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.13.tgz",
|
||||||
"integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ=="
|
"integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==",
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/debug": {
|
"node_modules/debug": {
|
||||||
"version": "4.3.4",
|
"version": "4.3.4",
|
||||||
|
|
@ -4416,12 +4469,13 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/echarts": {
|
"node_modules/echarts": {
|
||||||
"version": "5.4.3",
|
"version": "5.6.0",
|
||||||
"resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.4.3.tgz",
|
"resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.6.0.tgz",
|
||||||
"integrity": "sha512-mYKxLxhzy6zyTi/FaEbJMOZU1ULGEQHaeIeuMR5L+JnJTpz+YR03mnnpBhbR4+UYJAgiXgpyTVLffPAjOTLkZA==",
|
"integrity": "sha512-oTbVTsXfKuEhxftHqL5xprgLoc0k7uScAwtryCgWF6hPYFLRwOUHiFmHGCBKP5NPFNkDVopOieyUqYGH8Fa3kA==",
|
||||||
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tslib": "2.3.0",
|
"tslib": "2.3.0",
|
||||||
"zrender": "5.4.4"
|
"zrender": "5.6.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/editor": {
|
"node_modules/editor": {
|
||||||
|
|
@ -4451,6 +4505,126 @@
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/element-plus": {
|
||||||
|
"version": "2.9.7",
|
||||||
|
"resolved": "https://registry.npmmirror.com/element-plus/-/element-plus-2.9.7.tgz",
|
||||||
|
"integrity": "sha512-6vjZh5SXBncLhUwJGTVKS5oDljfgGMh6J4zVTeAZK3YdMUN76FgpvHkwwFXocpJpMbii6rDYU3sgie64FyPerQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@ctrl/tinycolor": "^3.4.1",
|
||||||
|
"@element-plus/icons-vue": "^2.3.1",
|
||||||
|
"@floating-ui/dom": "^1.0.1",
|
||||||
|
"@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.7",
|
||||||
|
"@types/lodash": "^4.14.182",
|
||||||
|
"@types/lodash-es": "^4.17.6",
|
||||||
|
"@vueuse/core": "^9.1.0",
|
||||||
|
"async-validator": "^4.2.5",
|
||||||
|
"dayjs": "^1.11.13",
|
||||||
|
"escape-html": "^1.0.3",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
|
"lodash-es": "^4.17.21",
|
||||||
|
"lodash-unified": "^1.0.2",
|
||||||
|
"memoize-one": "^6.0.0",
|
||||||
|
"normalize-wheel-es": "^1.2.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"vue": "^3.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/element-plus/node_modules/@types/web-bluetooth": {
|
||||||
|
"version": "0.0.16",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz",
|
||||||
|
"integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/element-plus/node_modules/@vueuse/core": {
|
||||||
|
"version": "9.13.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@vueuse/core/-/core-9.13.0.tgz",
|
||||||
|
"integrity": "sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/web-bluetooth": "^0.0.16",
|
||||||
|
"@vueuse/metadata": "9.13.0",
|
||||||
|
"@vueuse/shared": "9.13.0",
|
||||||
|
"vue-demi": "*"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/antfu"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/element-plus/node_modules/@vueuse/core/node_modules/vue-demi": {
|
||||||
|
"version": "0.14.10",
|
||||||
|
"resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.10.tgz",
|
||||||
|
"integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"vue-demi-fix": "bin/vue-demi-fix.js",
|
||||||
|
"vue-demi-switch": "bin/vue-demi-switch.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/antfu"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@vue/composition-api": "^1.0.0-rc.1",
|
||||||
|
"vue": "^3.0.0-0 || ^2.6.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@vue/composition-api": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/element-plus/node_modules/@vueuse/metadata": {
|
||||||
|
"version": "9.13.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@vueuse/metadata/-/metadata-9.13.0.tgz",
|
||||||
|
"integrity": "sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/antfu"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/element-plus/node_modules/@vueuse/shared": {
|
||||||
|
"version": "9.13.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/@vueuse/shared/-/shared-9.13.0.tgz",
|
||||||
|
"integrity": "sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"vue-demi": "*"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/antfu"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/element-plus/node_modules/@vueuse/shared/node_modules/vue-demi": {
|
||||||
|
"version": "0.14.10",
|
||||||
|
"resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.10.tgz",
|
||||||
|
"integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"vue-demi-fix": "bin/vue-demi-fix.js",
|
||||||
|
"vue-demi-switch": "bin/vue-demi-switch.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/antfu"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@vue/composition-api": "^1.0.0-rc.1",
|
||||||
|
"vue": "^3.0.0-0 || ^2.6.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@vue/composition-api": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/emoji-regex": {
|
"node_modules/emoji-regex": {
|
||||||
"version": "8.0.0",
|
"version": "8.0.0",
|
||||||
"resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
"resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||||
|
|
@ -4573,8 +4747,7 @@
|
||||||
"node_modules/escape-html": {
|
"node_modules/escape-html": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz",
|
"resolved": "https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz",
|
||||||
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
|
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/escape-string-regexp": {
|
"node_modules/escape-string-regexp": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
|
|
@ -6882,14 +7055,24 @@
|
||||||
"node_modules/lodash": {
|
"node_modules/lodash": {
|
||||||
"version": "4.17.21",
|
"version": "4.17.21",
|
||||||
"resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz",
|
"resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz",
|
||||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/lodash-es": {
|
"node_modules/lodash-es": {
|
||||||
"version": "4.17.21",
|
"version": "4.17.21",
|
||||||
"resolved": "https://registry.npmmirror.com/lodash-es/-/lodash-es-4.17.21.tgz",
|
"resolved": "https://registry.npmmirror.com/lodash-es/-/lodash-es-4.17.21.tgz",
|
||||||
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
|
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="
|
||||||
},
|
},
|
||||||
|
"node_modules/lodash-unified": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmmirror.com/lodash-unified/-/lodash-unified-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/lodash-es": "*",
|
||||||
|
"lodash": "*",
|
||||||
|
"lodash-es": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/lodash.camelcase": {
|
"node_modules/lodash.camelcase": {
|
||||||
"version": "4.3.0",
|
"version": "4.3.0",
|
||||||
"resolved": "https://registry.npmmirror.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
|
"resolved": "https://registry.npmmirror.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
|
||||||
|
|
@ -7260,6 +7443,12 @@
|
||||||
"integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==",
|
"integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/memoize-one": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/memoize-one/-/memoize-one-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/meow": {
|
"node_modules/meow": {
|
||||||
"version": "8.1.2",
|
"version": "8.1.2",
|
||||||
"resolved": "https://registry.npmmirror.com/meow/-/meow-8.1.2.tgz",
|
"resolved": "https://registry.npmmirror.com/meow/-/meow-8.1.2.tgz",
|
||||||
|
|
@ -7709,6 +7898,12 @@
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/normalize-wheel-es": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==",
|
||||||
|
"license": "BSD-3-Clause"
|
||||||
|
},
|
||||||
"node_modules/npm-run-path": {
|
"node_modules/npm-run-path": {
|
||||||
"version": "4.0.1",
|
"version": "4.0.1",
|
||||||
"resolved": "https://registry.npmmirror.com/npm-run-path/-/npm-run-path-4.0.1.tgz",
|
"resolved": "https://registry.npmmirror.com/npm-run-path/-/npm-run-path-4.0.1.tgz",
|
||||||
|
|
@ -11496,9 +11691,10 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/zrender": {
|
"node_modules/zrender": {
|
||||||
"version": "5.4.4",
|
"version": "5.6.1",
|
||||||
"resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.4.4.tgz",
|
"resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.6.1.tgz",
|
||||||
"integrity": "sha512-0VxCNJ7AGOMCWeHVyTrGzUgrK4asT4ml9PEkeGirAkKNYXYzoPJCLvmyfdoOXcjTHPs10OZVMfD1Rwg16AZyYw==",
|
"integrity": "sha512-OFXkDJKcrlx5su2XbzJvj/34Q3m6PvyCZkVPHGYpcCJ52ek4U/ymZyfuV1nKE23AyBJ51E/6Yr0mhZ7xGTO4ag==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tslib": "2.3.0"
|
"tslib": "2.3.0"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,8 @@
|
||||||
"crypto-js": "^4.2.0",
|
"crypto-js": "^4.2.0",
|
||||||
"dayjs": "^1.11.10",
|
"dayjs": "^1.11.10",
|
||||||
"docx": "^8.5.0",
|
"docx": "^8.5.0",
|
||||||
"echarts": "^5.4.3",
|
"echarts": "^5.6.0",
|
||||||
|
"element-plus": "^2.9.7",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"mockjs": "^1.1.0",
|
"mockjs": "^1.1.0",
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -91,5 +91,6 @@ export default {
|
||||||
updateSetup:(data)=>request.post('/problem/updateSetup',data),
|
updateSetup:(data)=>request.post('/problem/updateSetup',data),
|
||||||
findStudentSubmit:(data)=>request.post('/problem/findStudentSubmit',data),
|
findStudentSubmit:(data)=>request.post('/problem/findStudentSubmit',data),
|
||||||
addTime:(data)=>request.post('/problem/addTime',data),
|
addTime:(data)=>request.post('/problem/addTime',data),
|
||||||
|
findProblemReview:(data)=>request.post('/problem/findProblemReview',data),
|
||||||
|
findScore:(data)=>request.post('/problem/findScore',data),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -254,7 +254,7 @@ const onReviewProblem = async (problemid)=>{
|
||||||
await router.push({name:
|
await router.push({name:
|
||||||
'AdminProblemStudent',
|
'AdminProblemStudent',
|
||||||
query:
|
query:
|
||||||
{classId:ProblemInfoValue.value.classId,problemId:id}})
|
{classId:ProblemInfoValue.value.classId,problemId:id,courseId:courseId}})
|
||||||
}
|
}
|
||||||
// const search=async ()=>{
|
// const search=async ()=>{
|
||||||
// // ProblemInfoRef.value?.validate(async (errors) => {
|
// // ProblemInfoRef.value?.validate(async (errors) => {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
label-placement="left"style="margin-top: 15px;margin-left: 2%">
|
label-placement="left"style="margin-top: 15px;margin-left: 2%">
|
||||||
<n-form
|
<n-form
|
||||||
ref="problemInfoRef"
|
ref="problemInfoRef"
|
||||||
:model="problemInfoValue"
|
:model="problemReviewValue"
|
||||||
:rules="problemAddRules"
|
:rules="problemAddRules"
|
||||||
label-placement="left"
|
label-placement="left"
|
||||||
label-align="right"
|
label-align="right"
|
||||||
|
|
@ -12,40 +12,44 @@
|
||||||
:show-require-mark="false"
|
:show-require-mark="false"
|
||||||
>
|
>
|
||||||
<div class="exam-name-div">
|
<div class="exam-name-div">
|
||||||
|
<div style='display:flex;margin-left: 30px'>
|
||||||
<n-h2
|
<n-h2
|
||||||
class="show-problem-name">
|
class="show-problem-name">
|
||||||
{{ problemName }}
|
{{ problemReviewValue.title }}
|
||||||
</n-h2>
|
</n-h2></div>
|
||||||
|
|
||||||
<div style='display:flex;margin-left: 30px'>
|
<div style='display:flex;margin-left: 30px'>
|
||||||
<n-form-item>{{problemDescription }}</n-form-item> </div>
|
<n-form-item>{{problemReviewValue.description
|
||||||
|
}}</n-form-item> </div>
|
||||||
|
|
||||||
<div flex>
|
<div flex>
|
||||||
<n-form-item
|
<n-form-item
|
||||||
style='margin-left: 30px'>{{
|
style='margin-left: 30px'>{{
|
||||||
studentMessage.studentNo}} </n-form-item>
|
problemReviewValue.studentNo}} </n-form-item>
|
||||||
<n-form-item style='margin-left: 30px'>{{studentMessage
|
<n-form-item style='margin-left:
|
||||||
.name}}</n-form-item>
|
30px'>{{problemReviewValue
|
||||||
|
.chineseName}}</n-form-item>
|
||||||
<n-form-item style='margin-left: 30px'>
|
<n-form-item style='margin-left: 30px'>
|
||||||
{{studentMessage.class}}:</n-form-item>
|
{{problemReviewValue
|
||||||
|
.banji}}:</n-form-item>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div flex>
|
<div flex>
|
||||||
<n-form-item style='margin-left: 30px'>
|
<n-form-item style='margin-left: 30px'>
|
||||||
<a :href="docUrl" download="example.doc" target="_blank">
|
<n-button type="primary" @click="down" style="cursor: pointer;margin-right: 40px">
|
||||||
点击这里下载附件
|
下载附件
|
||||||
</a></n-form-item>
|
</n-button></n-form-item>
|
||||||
</div>
|
</div>
|
||||||
<div flex>
|
<div flex>
|
||||||
<n-form-item style='margin-left:
|
<n-form-item style='margin-left:
|
||||||
30px;width: 50%'>
|
30px;width: 50%'>
|
||||||
<label>自动评分:{{submitReport
|
<label>自动评分:{{problemReviewValue
|
||||||
.autoscore}}</label>
|
.autoscore}}</label>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item style='width: 20%'>
|
<n-form-item style='width: 20%'>
|
||||||
<label style='width: 100px'>教师评分:
|
<label style='width: 100px'>教师评分:
|
||||||
</label>
|
</label>
|
||||||
<n-input v-model="submitReport.score"
|
<n-input v-model="problemReviewValue.score"
|
||||||
/>
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -64,13 +68,13 @@
|
||||||
<n-form-item style='margin-left:
|
<n-form-item style='margin-left:
|
||||||
30px;width: 50%'>
|
30px;width: 50%'>
|
||||||
<pre
|
<pre
|
||||||
style='white-space: normal;word-wrap: break-word'>{{submitReport.aotocomment }}</pre>
|
style='white-space: normal;word-wrap: break-word'>{{problemReviewValue.autocomment }}</pre>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
<n-form-item
|
<n-form-item
|
||||||
style='width: 50%;margin-left: 30px'>
|
style='width: 50%;margin-left: 30px'>
|
||||||
<n-input
|
<n-input
|
||||||
type="textarea"
|
type="textarea"
|
||||||
v-model="submitReport.comment"
|
v-model="problemReviewValue.comment"
|
||||||
rows="6"
|
rows="6"
|
||||||
:autosize="{ minRows: 6, maxRows: 10 }"
|
:autosize="{ minRows: 6, maxRows: 10 }"
|
||||||
/>
|
/>
|
||||||
|
|
@ -106,7 +110,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import {useRouter} from "vue-router";
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import {ref} from "vue";
|
import {ref} from "vue";
|
||||||
import api from "@/api/admin";
|
import api from "@/api/admin";
|
||||||
import { useTagsStore } from '@/store'
|
import { useTagsStore } from '@/store'
|
||||||
|
|
@ -118,53 +122,86 @@ const tagsStore = useTagsStore()
|
||||||
const path=ref('')
|
const path=ref('')
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const rules=ref(null)
|
const rules=ref(null)
|
||||||
|
const route = useRoute()
|
||||||
|
const { classId,problemId,courseId,studentId,history } = route.query
|
||||||
const docUrl = ref('path/to/your/document.doc'); // 替换为你的 DOC 文件路径
|
const docUrl = ref('path/to/your/document.doc'); // 替换为你的 DOC 文件路径
|
||||||
const problemInfoValue = ref({
|
|
||||||
name: '',
|
|
||||||
timeFrom: [],
|
|
||||||
timeTo: [],
|
|
||||||
allow:true
|
|
||||||
});
|
|
||||||
const problemInfoRef = ref(null)
|
const problemInfoRef = ref(null)
|
||||||
|
const loading = ref(false)
|
||||||
const descEditorHeight = ref('160px')
|
const descEditorHeight = ref('160px')
|
||||||
const problemName = ref('作业标题')
|
const problemReviewValue=ref({
|
||||||
const problemDescription=ref('题目描述')
|
title:'',
|
||||||
const studentMessage=ref({
|
description:'',
|
||||||
studentNo:'211310509',
|
studentNo:'',
|
||||||
name:'zlm',
|
chineseName:'',
|
||||||
class:'c++班级'
|
banji:'',
|
||||||
})
|
|
||||||
const submitReport=ref({
|
|
||||||
autoscore:90,
|
autoscore:90,
|
||||||
aotocomment:`角色分为管理员、用户、商家,管理员在后台可以进行用户管理、商家管理、商品类型管理、商品信息管理、商品购买管理、交流信息管理、交流回复管理、留言板管理、系统管理;商家在后台可以进行商品类型管理、商品信息管理、商品购买管理、交流信息管理和交流回复管理;用户在后台可以进行商品购买管理、交流信息管理、交流回复管理、我的收藏管理、留言板管理。`,
|
autocomment:``,
|
||||||
score:'',
|
score:'',
|
||||||
comment:''
|
comment:'',
|
||||||
|
attachment:''
|
||||||
})
|
})
|
||||||
const cancel = ()=>{
|
|
||||||
tagsStore.removeTag(path.value)
|
const down = async() =>{
|
||||||
router.push({path: 'problem-list'})
|
|
||||||
}
|
|
||||||
const onAdd = ()=>{
|
|
||||||
router.push({name: 'AdminProblemPostClass'})
|
|
||||||
}
|
|
||||||
const submit =async ()=>{
|
|
||||||
if(problemInfoValue.value.name!==''){
|
|
||||||
try {
|
try {
|
||||||
await api.Addproblem({
|
const res = await api.download({
|
||||||
...problemInfoValue.value
|
fileName: problemReviewValue.value.attachment
|
||||||
})
|
})
|
||||||
$message.success("添加课程成功")
|
const contentDisposition = res.headers["content-disposition"]
|
||||||
tagsStore.removeTag(path.value)
|
let original_fileName = ""
|
||||||
await router.push({name: 'AdminProblemList'})
|
if(contentDisposition) {
|
||||||
} catch (err) {
|
const uri = res.headers["content-disposition"].split("=")[1]
|
||||||
tagsStore.removeTag(path.value)
|
original_fileName = window.decodeURI(uri)
|
||||||
await router.push({name: 'AdminProblemList'})
|
|
||||||
}
|
}
|
||||||
}else {
|
const blob = new Blob([res.data], {type: "application/vnd.ms-excel"});
|
||||||
$message.error("作业名称不能为空")
|
if(window.navigator && window.navigator.msSaveOrOpenBlob) {
|
||||||
|
const fileName = original_fileName;
|
||||||
|
window.navigator.msSaveOrOpenBlob(blob, fileName);
|
||||||
|
} else{
|
||||||
|
const fileName = original_fileName;
|
||||||
|
const elink = document.createElement('a')
|
||||||
|
document.body.appendChild(elink)
|
||||||
|
elink.download= fileName;
|
||||||
|
elink.style.display ="none"
|
||||||
|
elink.href = window.URL.createObjectURL(blob)
|
||||||
|
elink.click()
|
||||||
|
window.URL.revokeObjectURL(elink.href)
|
||||||
|
document.body.removeChild(elink)
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// const submit =async ()=>{
|
||||||
|
// if(problemInfoValue.value.name!==''){
|
||||||
|
// try {
|
||||||
|
// await api.Addproblem({
|
||||||
|
// ...problemInfoValue.value
|
||||||
|
// })
|
||||||
|
// $message.success("添加课程成功")
|
||||||
|
// tagsStore.removeTag(path.value)
|
||||||
|
// await router.push({name: 'AdminProblemList'})
|
||||||
|
// } catch (err) {
|
||||||
|
// tagsStore.removeTag(path.value)
|
||||||
|
// await router.push({name: 'AdminProblemList'})
|
||||||
|
// }
|
||||||
|
// }else {
|
||||||
|
// $message.error("作业名称不能为空")
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
const queryByPage = async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const res = await api.findProblemReview({
|
||||||
|
problemId:problemId,
|
||||||
|
studentId:studentId
|
||||||
|
})
|
||||||
|
problemReviewValue.value=res.data
|
||||||
|
} catch (err) {
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onMounted(()=>{
|
onMounted(()=>{
|
||||||
path.value=router.currentRoute.value.fullPath
|
path.value=router.currentRoute.value.fullPath
|
||||||
|
queryByPage()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -60,8 +60,8 @@
|
||||||
<n-form-item v-else style='margin-left: 10px;margin-right: 20px'>
|
<n-form-item v-else style='margin-left: 10px;margin-right: 20px'>
|
||||||
<n-button type="primary"
|
<n-button type="primary"
|
||||||
style="margin-right: 10px" @click="exportScores">导出成绩</n-button>
|
style="margin-right: 10px" @click="exportScores">导出成绩</n-button>
|
||||||
<n-button type="primary"
|
<!-- <n-button type="primary"-->
|
||||||
style="margin-right: 10px" @click="exportAttachments">导出作业附件</n-button>
|
<!-- style="margin-right: 10px" @click="exportAttachments">导出作业附件</n-button>-->
|
||||||
<n-button type="primary"
|
<n-button type="primary"
|
||||||
style="margin-right: 10px" @click="tongji">统计</n-button>
|
style="margin-right: 10px" @click="tongji">统计</n-button>
|
||||||
</n-form-item> </div>
|
</n-form-item> </div>
|
||||||
|
|
@ -92,7 +92,9 @@ import {onMounted, reactive, ref, watch} from "vue";
|
||||||
import { saveAs } from 'file-saver';
|
import { saveAs } from 'file-saver';
|
||||||
import * as XLSX from 'xlsx';
|
import * as XLSX from 'xlsx';
|
||||||
import {useRoute, useRouter} from 'vue-router'
|
import {useRoute, useRouter} from 'vue-router'
|
||||||
|
import { useUserStore } from '@/store';
|
||||||
import api from "@/api/admin";
|
import api from "@/api/admin";
|
||||||
|
const userStore = useUserStore()
|
||||||
import ProblemStudentAction
|
import ProblemStudentAction
|
||||||
from '@/views/admin/problem/components/problem-student-action.vue'
|
from '@/views/admin/problem/components/problem-student-action.vue'
|
||||||
import {formatDateTime} from '@/utils';
|
import {formatDateTime} from '@/utils';
|
||||||
|
|
@ -114,7 +116,7 @@ const submitList =
|
||||||
ref([])
|
ref([])
|
||||||
const studentList =
|
const studentList =
|
||||||
reactive([])
|
reactive([])
|
||||||
const { classId,problemId, history } = route.query
|
const { classId,problemId,courseId, history } = route.query
|
||||||
const paginationReactive = reactive({
|
const paginationReactive = reactive({
|
||||||
page: 1,
|
page: 1,
|
||||||
pageSize: 50,
|
pageSize: 50,
|
||||||
|
|
@ -283,10 +285,9 @@ const onAddTime=async (studentId)=>{
|
||||||
'AdminProblemAddTime', query: {classId:
|
'AdminProblemAddTime', query: {classId:
|
||||||
classId,problemId:problemId,studentId:id}})
|
classId,problemId:problemId,studentId:id}})
|
||||||
}
|
}
|
||||||
const onReview=async ()=>{
|
const onReview=async (studentId)=>{
|
||||||
// const {id} = classId
|
const {id} = studentId
|
||||||
const id=1
|
await router.push({name: 'AdminProblemReview', query:{classId: classId,problemId:problemId,courseId:courseId,studentId:id}})
|
||||||
await router.push({name: 'AdminProblemReview', params: {clId: id}, query: {id: clId}})
|
|
||||||
}
|
}
|
||||||
const onDeleteClass = async (classId)=>{
|
const onDeleteClass = async (classId)=>{
|
||||||
try {
|
try {
|
||||||
|
|
@ -378,7 +379,12 @@ const exportWeijiaoTable = () => {
|
||||||
});
|
});
|
||||||
const blob = new Blob([excelBuffer], { type: 'application/octet-stream' });
|
const blob = new Blob([excelBuffer], { type: 'application/octet-stream' });
|
||||||
saveAs(blob, '导出未交名单.xlsx');
|
saveAs(blob, '导出未交名单.xlsx');
|
||||||
};
|
}
|
||||||
|
const tongji=async (studentId)=>{
|
||||||
|
const {id} = studentId
|
||||||
|
await router.push({name: 'AdminProblemScore',
|
||||||
|
query:{classId: classId,problemId:problemId,courseId:courseId,studentId:id}})
|
||||||
|
}
|
||||||
const rowKey = (rowData) => {
|
const rowKey = (rowData) => {
|
||||||
return rowData.id
|
return rowData.id
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,130 @@
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted, reactive } from 'vue'
|
||||||
|
import * as echarts from 'echarts';
|
||||||
|
import api from '@/api/admin'
|
||||||
|
import {useRoute, useRouter} from 'vue-router'
|
||||||
|
const route = useRoute()
|
||||||
|
const loading = ref(false)
|
||||||
|
const { classId,problemId,courseId, history } = route.query
|
||||||
|
// 模拟从后端获取的分数数据
|
||||||
|
const scoreList = ref([])
|
||||||
|
const selectedStatus=ref('yijiao')
|
||||||
|
// 统计不同分数段的人数
|
||||||
|
let scoreRanges =[
|
||||||
|
{ range: '0-59', count: 0 },
|
||||||
|
{ range: '60-69', count: 0 },
|
||||||
|
{ range: '70-79', count: 0 },
|
||||||
|
{ range: '80-89', count: 0 },
|
||||||
|
{ range: '90-100', count: 0 },
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
// 获取图表 DOM 元素
|
||||||
|
const chart = ref(null);
|
||||||
|
// const studentInfoValue = ref({
|
||||||
|
// id:0,
|
||||||
|
// studentNo:'',
|
||||||
|
// chineseName:'',
|
||||||
|
// readTime:[],
|
||||||
|
// submitTime:[],
|
||||||
|
// submissionStatus:'',
|
||||||
|
// score:0,
|
||||||
|
// pageNum:paginationReactive.page,
|
||||||
|
// pageSize:paginationReactive.pageSize
|
||||||
|
// });
|
||||||
|
const queryByPage = async ()=>{
|
||||||
|
// loading.value = true;
|
||||||
|
// studentInfoValue.value.pageNum=currentPage
|
||||||
|
// studentInfoValue.value.pageSize=paginationReactive.pageSize
|
||||||
|
// const res1=await
|
||||||
|
// api.findProblemById({id:problemId});
|
||||||
|
// problem.value=res1.data
|
||||||
|
const res = await
|
||||||
|
api.findScore(
|
||||||
|
{
|
||||||
|
classId:classId,
|
||||||
|
problemId:problemId,
|
||||||
|
selectedStatus:selectedStatus.value,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const {pageNum, pageSize, total, list} = res.data
|
||||||
|
// paginationReactive.page = pageNum
|
||||||
|
// paginationReactive.pageSize = pageSize
|
||||||
|
// paginationReactive.itemCount = total
|
||||||
|
scoreList.value =res.data
|
||||||
|
const scores = scoreList.value.map(score =>
|
||||||
|
parseFloat(score));
|
||||||
|
scores.forEach(score => {
|
||||||
|
if (score < 60) {
|
||||||
|
scoreRanges[0].count++;
|
||||||
|
} else if (score < 70) {
|
||||||
|
scoreRanges[1].count++;
|
||||||
|
} else if (score < 80) {
|
||||||
|
scoreRanges[2].count++;
|
||||||
|
} else if (score < 90) {
|
||||||
|
scoreRanges[3].count++;
|
||||||
|
} else {
|
||||||
|
scoreRanges[4].count++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
console.log(scores)
|
||||||
|
console.log(scoreRanges)
|
||||||
|
const myChart = echarts.init(chart.value);
|
||||||
|
|
||||||
|
const option = {
|
||||||
|
title: {
|
||||||
|
text: '分数段统计',
|
||||||
|
left: 'center',
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
axisPointer: {
|
||||||
|
type: 'shadow',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
data: scoreRanges.map(item => item.range),
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'value',
|
||||||
|
name: '人数',
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: '人数',
|
||||||
|
type: 'bar',
|
||||||
|
data: scoreRanges.map(item => item.count),
|
||||||
|
itemStyle: {
|
||||||
|
color: '#5470C6', // 柱状图颜色
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
myChart.setOption(option);
|
||||||
|
}
|
||||||
|
// 初始化图表
|
||||||
|
onMounted(() => {
|
||||||
|
queryByPage()
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<n-scrollbar x-scrollable style="max-height: 100vh">
|
||||||
|
<CommonPage>
|
||||||
|
<div>
|
||||||
|
<!-- <h1>分数统计</h1>-->
|
||||||
|
<div ref="chart" style="width: 600px;
|
||||||
|
height: 400px;margin-left: 300px"></div>
|
||||||
|
</div>
|
||||||
|
</CommonPage>
|
||||||
|
</n-scrollbar>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
h1 {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -30,6 +30,7 @@ export default {
|
||||||
{
|
{
|
||||||
name: 'AdminProblem',
|
name: 'AdminProblem',
|
||||||
path: 'problem',
|
path: 'problem',
|
||||||
|
isHidden: true,
|
||||||
redirect: '/admin/problem/problem-list',
|
redirect: '/admin/problem/problem-list',
|
||||||
meta: {
|
meta: {
|
||||||
title: '作业管理',
|
title: '作业管理',
|
||||||
|
|
@ -78,6 +79,19 @@ export default {
|
||||||
keepAlive: true,
|
keepAlive: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'AdminProblemScore',
|
||||||
|
path: 'tongji',
|
||||||
|
isHidden: true,
|
||||||
|
component: () => import('@/views/admin/problem/tongji.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '统计成绩',
|
||||||
|
icon: 'ic:baseline-add',
|
||||||
|
role: ['admin', 'teacher'],
|
||||||
|
requireAuth: true,
|
||||||
|
keepAlive: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'AdminProblemEdit',
|
name: 'AdminProblemEdit',
|
||||||
path: 'problem-edit',
|
path: 'problem-edit',
|
||||||
|
|
|
||||||
|
|
@ -284,7 +284,20 @@ public class ProblemController {
|
||||||
return RespBean.ok("获取学生提交报告列表成功!",
|
return RespBean.ok("获取学生提交报告列表成功!",
|
||||||
dataGrid);
|
dataGrid);
|
||||||
}
|
}
|
||||||
|
@PostMapping("findScore")
|
||||||
|
public RespBean findScore(@RequestBody PMStudentSubmit pmStudentSubmit){
|
||||||
|
List<Float> scoreList=
|
||||||
|
problemServiceI.findScoreList(pmStudentSubmit);
|
||||||
|
return RespBean.ok("获取分数列表成功!",
|
||||||
|
scoreList);
|
||||||
|
}
|
||||||
|
@PostMapping("findProblemReview")
|
||||||
|
public RespBean findProblemReview(@RequestBody PMReviewMessage pmReviewMessage){
|
||||||
|
PMReviewMessage reviewMessage=
|
||||||
|
problemServiceI.findProblemReview(pmReviewMessage);
|
||||||
|
return RespBean.ok("获取批阅报告成功!",
|
||||||
|
reviewMessage);
|
||||||
|
}
|
||||||
|
|
||||||
//根据作业id和学生id获取学生当前报告成绩排名
|
//根据作业id和学生id获取学生当前报告成绩排名
|
||||||
@GetMapping("/getStudentRank")
|
@GetMapping("/getStudentRank")
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package com.example.aes.problem.dao;
|
package com.example.aes.problem.dao;
|
||||||
|
|
||||||
|
import com.example.aes.problem.model.PMReviewMessage;
|
||||||
import com.example.aes.problem.model.PMStudentSubmit;
|
import com.example.aes.problem.model.PMStudentSubmit;
|
||||||
import com.example.aes.problem.model.SubmitReport;
|
import com.example.aes.problem.model.SubmitReport;
|
||||||
import com.example.aes.user.dao.BaseDaoI;
|
import com.example.aes.user.dao.BaseDaoI;
|
||||||
|
|
@ -11,5 +12,7 @@ public interface SubmitReportDaoI extends BaseDaoI<SubmitReport> {
|
||||||
public List<Object[]> findWeijiaoList(PMStudentSubmit pmStudentSubmit);
|
public List<Object[]> findWeijiaoList(PMStudentSubmit pmStudentSubmit);
|
||||||
public List<Object[]> findYijiaoList(PMStudentSubmit pmStudentSubmit);
|
public List<Object[]> findYijiaoList(PMStudentSubmit pmStudentSubmit);
|
||||||
public int updateAddTime(LocalDateTime addTime,int problemId,int studentId);
|
public int updateAddTime(LocalDateTime addTime,int problemId,int studentId);
|
||||||
|
public List<Object[]> findProblemReview(PMReviewMessage pmReviewMessage);
|
||||||
|
public List<Object[]> findScoreList(PMStudentSubmit pmStudentSubmit);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ import com.example.aes.user.dao.impl.BaseDaoImpl;
|
||||||
import com.example.aes.user.model.Classstudents;
|
import com.example.aes.user.model.Classstudents;
|
||||||
import org.hibernate.Query;
|
import org.hibernate.Query;
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
import com.ibm.jvm.trace.format.api.TraceContext;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.dao.DataAccessException;
|
import org.springframework.dao.DataAccessException;
|
||||||
import org.springframework.jdbc.core.BeanPropertyRowMapper;
|
import org.springframework.jdbc.core.BeanPropertyRowMapper;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.example.aes.problem.dao.impl;
|
package com.example.aes.problem.dao.impl;
|
||||||
|
|
||||||
import com.example.aes.problem.dao.SubmitReportDaoI;
|
import com.example.aes.problem.dao.SubmitReportDaoI;
|
||||||
|
import com.example.aes.problem.model.PMReviewMessage;
|
||||||
import com.example.aes.problem.model.PMStudentSubmit;
|
import com.example.aes.problem.model.PMStudentSubmit;
|
||||||
import com.example.aes.problem.model.SubmitReport;
|
import com.example.aes.problem.model.SubmitReport;
|
||||||
import com.example.aes.user.dao.impl.BaseDaoImpl;
|
import com.example.aes.user.dao.impl.BaseDaoImpl;
|
||||||
|
|
@ -122,4 +123,67 @@ String chineseName=
|
||||||
|
|
||||||
return query.getResultList();
|
return query.getResultList();
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public List<Object[]> findScoreList(PMStudentSubmit pmStudentSubmit){
|
||||||
|
int classId= pmStudentSubmit.getClassId();
|
||||||
|
int problemId= pmStudentSubmit.getProblemId();
|
||||||
|
// String studentNo=
|
||||||
|
// '%'+pmStudentSubmit.getStudentNo()+'%';
|
||||||
|
// String chineseName=
|
||||||
|
// '%'+pmStudentSubmit.getChineseName()+'%';
|
||||||
|
String hql="SELECT u.chineseName," +
|
||||||
|
"u.studentNo, sr" +
|
||||||
|
".submissionTime," +
|
||||||
|
"sr.submissionStatus," +
|
||||||
|
" COALESCE(sr.score," +
|
||||||
|
" sr.autoscore) " +
|
||||||
|
"AS finalScore ,u.id " +
|
||||||
|
"FROM Classstudents cs left " +
|
||||||
|
"join Users u on cs" +
|
||||||
|
".userId=u.id "+
|
||||||
|
"left join PostProblem pp on cs" +
|
||||||
|
".classId=pp.classId "+
|
||||||
|
"left JOIN"+
|
||||||
|
" SubmitReport sr ON " +
|
||||||
|
"sr" +
|
||||||
|
".studentId=u.id"+
|
||||||
|
" WHERE cs.classId=:classId " +
|
||||||
|
"and " +
|
||||||
|
"pp.problemId " +
|
||||||
|
"=:problemId" +
|
||||||
|
" and sr.problemId=:problemId" +
|
||||||
|
" and sr" +
|
||||||
|
".submissionTime is not null";
|
||||||
|
Query<Object[]> query =
|
||||||
|
this.getCurrentSession().createQuery(hql,Object[].class);
|
||||||
|
query.setParameter("classId", classId);
|
||||||
|
query.setParameter("problemId", problemId);
|
||||||
|
return query.getResultList();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public List<Object[]> findProblemReview(PMReviewMessage pmReviewMessage){
|
||||||
|
int studentId= pmReviewMessage.getStudentId();
|
||||||
|
int problemId= pmReviewMessage.getProblemId();
|
||||||
|
String hql="select p.title," +
|
||||||
|
"p.description,u.chineseName," +
|
||||||
|
"u.studentNo,u.banji," +
|
||||||
|
"sr.attachment," +
|
||||||
|
"sr.autoscore,sr.autocomment," +
|
||||||
|
"sr.score," +
|
||||||
|
"sr.comment " +
|
||||||
|
"from Problem p " +
|
||||||
|
"left join SubmitReport sr " +
|
||||||
|
"on sr.problemId=p.id " +
|
||||||
|
"inner join Users u " +
|
||||||
|
"on sr.studentId=u.id " +
|
||||||
|
"where u.id=:studentId " +
|
||||||
|
"and" +
|
||||||
|
" " +
|
||||||
|
"p.id=:problemId";
|
||||||
|
Query<Object[]> query =
|
||||||
|
this.getCurrentSession().createQuery(hql,Object[].class);
|
||||||
|
query.setParameter("studentId", studentId);
|
||||||
|
query.setParameter("problemId", problemId);
|
||||||
|
return query.getResultList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.example.aes.problem.model;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class PMReviewMessage {
|
||||||
|
private int studentId;
|
||||||
|
private int problemId;
|
||||||
|
private String title;
|
||||||
|
private String description;
|
||||||
|
private String chineseName;
|
||||||
|
private String studentNo;
|
||||||
|
private String banji;
|
||||||
|
private String attachment;
|
||||||
|
private float autoscore;
|
||||||
|
private String autocomment;
|
||||||
|
private float score;
|
||||||
|
private String comment;
|
||||||
|
}
|
||||||
|
|
@ -367,6 +367,14 @@ public class ProblemServiceImpl implements ProblemServiceI {
|
||||||
postProblemDao.findPostProblem(problemId,classId);
|
postProblemDao.findPostProblem(problemId,classId);
|
||||||
return postProblems;
|
return postProblems;
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public PMReviewMessage findProblemReview(PMReviewMessage pmReviewMessage){
|
||||||
|
List<Object[]> objects=
|
||||||
|
studentSubmitDao.findProblemReview(pmReviewMessage);
|
||||||
|
List<PMReviewMessage> pmReviewMessageList=new ArrayList<>();
|
||||||
|
changeModel6(pmReviewMessageList,objects);
|
||||||
|
return pmReviewMessageList.get(0);
|
||||||
|
}
|
||||||
@Autowired
|
@Autowired
|
||||||
public void setStudentSubmitDao(SubmitReportDaoI studentSubmitDao) {
|
public void setStudentSubmitDao(SubmitReportDaoI studentSubmitDao) {
|
||||||
this.studentSubmitDao = studentSubmitDao;
|
this.studentSubmitDao = studentSubmitDao;
|
||||||
|
|
@ -447,6 +455,15 @@ public class ProblemServiceImpl implements ProblemServiceI {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
|
public List<Float> findScoreList(PMStudentSubmit pmStudentSubmit){
|
||||||
|
List<Float> scoreList=new ArrayList<>();
|
||||||
|
List<Object[]> theSubmitList=
|
||||||
|
studentSubmitDao.findScoreList(pmStudentSubmit);
|
||||||
|
for(Object[] object:theSubmitList){
|
||||||
|
scoreList.add((float)object[4]);
|
||||||
|
}return scoreList;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
public int editPostProblem(int classId,
|
public int editPostProblem(int classId,
|
||||||
int problemId,LocalDateTime startTime,LocalDateTime endTime,boolean allow){
|
int problemId,LocalDateTime startTime,LocalDateTime endTime,boolean allow){
|
||||||
int n=0;
|
int n=0;
|
||||||
|
|
@ -549,4 +566,25 @@ public class ProblemServiceImpl implements ProblemServiceI {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private void changeModel6(List<PMReviewMessage> pmReviewMessages,
|
||||||
|
List<Object[]> pmObject) {
|
||||||
|
if (pmObject != null && pmObject.size() > 0) {
|
||||||
|
for (Object[] p : pmObject) {
|
||||||
|
PMReviewMessage pmReviewMessage=
|
||||||
|
new PMReviewMessage();
|
||||||
|
pmReviewMessage.setTitle((String) p[0]);
|
||||||
|
pmReviewMessage.setDescription(((String) p[1]).replaceAll("<\\/?.*?>", "").trim());
|
||||||
|
pmReviewMessage.setChineseName((String) p[2]);
|
||||||
|
pmReviewMessage.setStudentNo((String) p[3]);
|
||||||
|
pmReviewMessage.setBanji((String) p[4]);
|
||||||
|
pmReviewMessage.setAttachment((String) p[5]);
|
||||||
|
pmReviewMessage.setAutoscore((float) p[6]);
|
||||||
|
pmReviewMessage.setAutocomment((String)p[7]);
|
||||||
|
if(p[8]!=null)
|
||||||
|
pmReviewMessage.setScore((float)p[8]);
|
||||||
|
pmReviewMessage.setComment((String) p[9]);
|
||||||
|
pmReviewMessages.add(pmReviewMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,5 +49,7 @@ public interface ProblemServiceI {
|
||||||
LocalDateTime startTime,LocalDateTime endTime,boolean allow);
|
LocalDateTime startTime,LocalDateTime endTime,boolean allow);
|
||||||
public DataGrid findWeijiaoList(PMStudentSubmit pmStudentSubmit);
|
public DataGrid findWeijiaoList(PMStudentSubmit pmStudentSubmit);
|
||||||
public DataGrid findYijiaoList(PMStudentSubmit pmStudentSubmit);
|
public DataGrid findYijiaoList(PMStudentSubmit pmStudentSubmit);
|
||||||
|
public PMReviewMessage findProblemReview(PMReviewMessage pmReviewMessage);
|
||||||
public int editSubmitReport(LocalDateTime addTime,int problemId,int studentId);
|
public int editSubmitReport(LocalDateTime addTime,int problemId,int studentId);
|
||||||
|
public List<Float> findScoreList(PMStudentSubmit pmStudentSubmit);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -274,7 +274,6 @@ public class importClassStudentsFileController{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public boolean decodeFile(String fileName, int classId) // 解析csv文件
|
public boolean decodeFile(String fileName, int classId) // 解析csv文件
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ server.port=8082
|
||||||
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
|
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
|
||||||
jdbc_url=jdbc:mysql://localhost:3306/aes?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false&allowPublicKeyRetrieval=True
|
jdbc_url=jdbc:mysql://localhost:3306/aes?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false&allowPublicKeyRetrieval=True
|
||||||
jdbc_username=root
|
jdbc_username=root
|
||||||
jdbc_password=13661744518xh
|
jdbc_password=123456
|
||||||
#spring.datasource.url=jdbc:mysql://localhost:3306/aes?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false&allowPublicKeyRetrieval=True
|
#spring.datasource.url=jdbc:mysql://localhost:3306/aes?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false&allowPublicKeyRetrieval=True
|
||||||
#spring.datasource.username=root
|
#spring.datasource.username=root
|
||||||
#spring.datasource.password=123456
|
#spring.datasource.password=123456
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue