commit a6e1d65eb95c30f31dde19d600da00573e167d88
Author: Cyh Name <2308880173@qq.com>
Date: Mon Dec 16 21:53:08 2024 +0800
完成成绩统计页面
diff --git a/.babelrc b/.babelrc
new file mode 100644
index 0000000..3a280ba
--- /dev/null
+++ b/.babelrc
@@ -0,0 +1,12 @@
+{
+ "presets": [
+ ["env", {
+ "modules": false,
+ "targets": {
+ "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
+ }
+ }],
+ "stage-2"
+ ],
+ "plugins": ["transform-vue-jsx", "transform-runtime"]
+}
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..9d08a1a
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,9 @@
+root = true
+
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 2
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..3dfac44
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,25 @@
+.DS_Store
+node_modules
+/dist
+
+
+# local env files
+.env.local
+.env.*.local
+
+# Log files
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+
+# Editor directories and files`
+ `
+
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/.npmrc b/.npmrc
new file mode 100644
index 0000000..a6ef790
--- /dev/null
+++ b/.npmrc
@@ -0,0 +1 @@
+registry=https://registry.npm.taobao.org/
diff --git a/.postcssrc.js b/.postcssrc.js
new file mode 100644
index 0000000..eee3e92
--- /dev/null
+++ b/.postcssrc.js
@@ -0,0 +1,10 @@
+// https://github.com/michael-ciniawsky/postcss-load-config
+
+module.exports = {
+ "plugins": {
+ "postcss-import": {},
+ "postcss-url": {},
+ // to edit target browsers: use "browserslist" field in package.json
+ "autoprefixer": {}
+ }
+}
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..f691033
--- /dev/null
+++ b/README.md
@@ -0,0 +1,12 @@
+# 项目介绍及启动说明
+
+### 启动项目
+``` bash
+# 切换镜像
+npm config set registry https://registry.npm.taobao.org
+
+# 安装依赖,对应node的版本是16.13.2
+npm install --force
+
+# 启动项目
+npm run dev
diff --git a/build/build.js b/build/build.js
new file mode 100644
index 0000000..8f2ad8a
--- /dev/null
+++ b/build/build.js
@@ -0,0 +1,41 @@
+'use strict'
+require('./check-versions')()
+
+process.env.NODE_ENV = 'production'
+
+const ora = require('ora')
+const rm = require('rimraf')
+const path = require('path')
+const chalk = require('chalk')
+const webpack = require('webpack')
+const config = require('../config')
+const webpackConfig = require('./webpack.prod.conf')
+
+const spinner = ora('building for production...')
+spinner.start()
+
+rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
+ if (err) throw err
+ webpack(webpackConfig, (err, stats) => {
+ spinner.stop()
+ if (err) throw err
+ process.stdout.write(stats.toString({
+ colors: true,
+ modules: false,
+ children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
+ chunks: false,
+ chunkModules: false
+ }) + '\n\n')
+
+ if (stats.hasErrors()) {
+ console.log(chalk.red(' Build failed with errors.\n'))
+ process.exit(1)
+ }
+
+ console.log(chalk.cyan(' Build complete.\n'))
+ console.log(chalk.yellow(
+ ' Tip: built files are meant to be served over an HTTP server.\n' +
+ ' Opening index.html over file:// won\'t work.\n'
+ ))
+ })
+})
diff --git a/build/check-versions.js b/build/check-versions.js
new file mode 100644
index 0000000..3ef972a
--- /dev/null
+++ b/build/check-versions.js
@@ -0,0 +1,54 @@
+'use strict'
+const chalk = require('chalk')
+const semver = require('semver')
+const packageConfig = require('../package.json')
+const shell = require('shelljs')
+
+function exec (cmd) {
+ return require('child_process').execSync(cmd).toString().trim()
+}
+
+const versionRequirements = [
+ {
+ name: 'node',
+ currentVersion: semver.clean(process.version),
+ versionRequirement: packageConfig.engines.node
+ }
+]
+
+if (shell.which('npm')) {
+ versionRequirements.push({
+ name: 'npm',
+ currentVersion: exec('npm --version'),
+ versionRequirement: packageConfig.engines.npm
+ })
+}
+
+module.exports = function () {
+ const warnings = []
+
+ for (let i = 0; i < versionRequirements.length; i++) {
+ const mod = versionRequirements[i]
+
+ if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
+ warnings.push(mod.name + ': ' +
+ chalk.red(mod.currentVersion) + ' should be ' +
+ chalk.green(mod.versionRequirement)
+ )
+ }
+ }
+
+ if (warnings.length) {
+ console.log('')
+ console.log(chalk.yellow('To use this template, you must update following to modules:'))
+ console.log()
+
+ for (let i = 0; i < warnings.length; i++) {
+ const warning = warnings[i]
+ console.log(' ' + warning)
+ }
+
+ console.log()
+ process.exit(1)
+ }
+}
diff --git a/build/logo.png b/build/logo.png
new file mode 100644
index 0000000..4356b65
Binary files /dev/null and b/build/logo.png differ
diff --git a/build/utils.js b/build/utils.js
new file mode 100644
index 0000000..a873f7d
--- /dev/null
+++ b/build/utils.js
@@ -0,0 +1,99 @@
+'use strict'
+const path = require('path')
+const config = require('../config')
+const ExtractTextPlugin = require('extract-text-webpack-plugin')
+const packageConfig = require('../package.json')
+
+exports.assetsPath = function (_path) {
+ const assetsSubDirectory = process.env.NODE_ENV === 'production'
+ ? config.build.assetsSubDirectory
+ : config.dev.assetsSubDirectory
+
+ return path.posix.join(assetsSubDirectory, _path)
+}
+
+exports.cssLoaders = function (options) {
+ options = options || {}
+
+ const cssLoader = {
+ loader: 'css-loader',
+ options: {
+ sourceMap: options.sourceMap
+ }
+ }
+
+ const postcssLoader = {
+ loader: 'postcss-loader',
+ options: {
+ sourceMap: options.sourceMap
+ }
+ }
+
+ // generate loader string to be used with extract text plugin
+ function generateLoaders (loader, loaderOptions) {
+ const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
+
+ if (loader) {
+ loaders.push({
+ loader: loader + '-loader',
+ options: Object.assign({}, loaderOptions, {
+ sourceMap: options.sourceMap
+ })
+ })
+ }
+
+ // Extract CSS when that option is specified
+ // (which is the case during production build)
+ if (options.extract) {
+ return ExtractTextPlugin.extract({
+ use: loaders,
+ fallback: 'vue-style-loader'
+ })
+ } else {
+ return ['vue-style-loader'].concat(loaders)
+ }
+ }
+
+ // https://vue-loader.vuejs.org/en/configurations/extract-css.html
+ return {
+ css: generateLoaders(),
+ postcss: generateLoaders(),
+ less: generateLoaders('less'),
+ stylus: generateLoaders('stylus'),
+ styl: generateLoaders('stylus')
+ }
+}
+
+// Generate loaders for standalone style files (outside of .vue)
+exports.styleLoaders = function (options) {
+ const output = []
+ const loaders = exports.cssLoaders(options)
+
+ for (const extension in loaders) {
+ const loader = loaders[extension]
+ output.push({
+ test: new RegExp('\\.' + extension + '$'),
+ use: loader
+ })
+ }
+
+ return output
+}
+
+exports.createNotifierCallback = () => {
+ const notifier = require('node-notifier')
+
+ return (severity, errors) => {
+ if (severity !== 'error') return
+
+ const error = errors[0]
+ const filename = error.file && error.file.split('!').pop()
+
+ notifier.notify({
+ title: packageConfig.name,
+ message: severity + ': ' + error.name,
+ subtitle: filename || '',
+ icon: path.join(__dirname, 'logo.png')
+ })
+ }
+}
diff --git a/build/vue-loader.conf.js b/build/vue-loader.conf.js
new file mode 100644
index 0000000..33ed58b
--- /dev/null
+++ b/build/vue-loader.conf.js
@@ -0,0 +1,22 @@
+'use strict'
+const utils = require('./utils')
+const config = require('../config')
+const isProduction = process.env.NODE_ENV === 'production'
+const sourceMapEnabled = isProduction
+ ? config.build.productionSourceMap
+ : config.dev.cssSourceMap
+
+module.exports = {
+ loaders: utils.cssLoaders({
+ sourceMap: sourceMapEnabled,
+ extract: isProduction
+ }),
+ cssSourceMap: sourceMapEnabled,
+ cacheBusting: config.dev.cacheBusting,
+ transformToRequire: {
+ video: ['src', 'poster'],
+ source: 'src',
+ img: 'src',
+ image: 'xlink:href'
+ }
+}
diff --git a/build/webpack.base.conf.js b/build/webpack.base.conf.js
new file mode 100644
index 0000000..e1cb26a
--- /dev/null
+++ b/build/webpack.base.conf.js
@@ -0,0 +1,99 @@
+'use strict'
+const path = require('path')
+const utils = require('./utils')
+const config = require('../config')
+const vueLoaderConfig = require('./vue-loader.conf')
+
+function resolve (dir) {
+ return path.join(__dirname, '..', dir)
+}
+
+
+
+module.exports = {
+ context: path.resolve(__dirname, '../'),
+ entry: {
+ app: './src/main.js'
+ },
+ output: {
+ path: config.build.assetsRoot,
+ filename: '[name].js',
+ publicPath: process.env.NODE_ENV === 'production'
+ ? config.build.assetsPublicPath
+ : config.dev.assetsPublicPath
+ },
+ resolve: {
+ extensions: ['.js', '.vue', '.json'],
+ alias: {
+ 'vue$': 'vue/dist/vue.esm.js',
+ '@': resolve('src'),
+ }
+ },
+ module: {
+ rules: [
+ {
+ test: /\.less$/,
+ loader: "style-loader!css-loader!less-loader"
+ },
+ {
+ test: /\.vue$/,
+ loader: 'vue-loader',
+ options: vueLoaderConfig
+ },
+ {
+ test: /\.js$/,
+ loader: 'babel-loader',
+ include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
+ },
+ {
+ test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
+ loader: 'url-loader',
+ options: {
+ limit: 10000,
+ name: utils.assetsPath('img/[name].[hash:7].[ext]')
+ }
+ },
+ {
+ test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
+ loader: 'url-loader',
+ options: {
+ limit: 10000,
+ name: utils.assetsPath('media/[name].[hash:7].[ext]')
+ }
+ },
+ {
+ test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
+ loader: 'url-loader',
+ options: {
+ limit: 10000,
+ name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
+ }
+ },
+ // {
+ // test: /node_modules[\\\/]vis[\\\/].*\.js$/,
+ // loader: 'babel-loader',
+ // query: {
+ // cacheDirectory: true,
+ // presets: [ "babel-preset-es2015" ].map(require.resolve),
+ // plugins: [
+ // "transform-es3-property-literals", // #2452
+ // "transform-es3-member-expression-literals", // #2566
+ // "transform-runtime" // #2566
+ // ]
+ // }
+ // }
+ ]
+ },
+ node: {
+ // prevent webpack from injecting useless setImmediate polyfill because Vue
+ // source contains it (although only uses it if it's native).
+ setImmediate: false,
+ // prevent webpack from injecting mocks to Node native modules
+ // that does not make sense for the client
+ dgram: 'empty',
+ fs: 'empty',
+ net: 'empty',
+ tls: 'empty',
+ child_process: 'empty'
+ }
+}
diff --git a/build/webpack.dev.conf.js b/build/webpack.dev.conf.js
new file mode 100644
index 0000000..070ae22
--- /dev/null
+++ b/build/webpack.dev.conf.js
@@ -0,0 +1,95 @@
+'use strict'
+const utils = require('./utils')
+const webpack = require('webpack')
+const config = require('../config')
+const merge = require('webpack-merge')
+const path = require('path')
+const baseWebpackConfig = require('./webpack.base.conf')
+const CopyWebpackPlugin = require('copy-webpack-plugin')
+const HtmlWebpackPlugin = require('html-webpack-plugin')
+const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
+const portfinder = require('portfinder')
+
+const HOST = process.env.HOST
+const PORT = process.env.PORT && Number(process.env.PORT)
+
+const devWebpackConfig = merge(baseWebpackConfig, {
+ module: {
+ rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
+ },
+ // cheap-module-eval-source-map is faster for development
+ devtool: config.dev.devtool,
+
+ // these devServer options should be customized in /config/index.js
+ devServer: {
+ clientLogLevel: 'warning',
+ historyApiFallback: {
+ rewrites: [
+ { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
+ ],
+ },
+ hot: true,
+ contentBase: false, // since we use CopyWebpackPlugin.
+ compress: true,
+ host: HOST || config.dev.host,
+ port: PORT || config.dev.port,
+ open: config.dev.autoOpenBrowser,
+ overlay: config.dev.errorOverlay
+ ? { warnings: false, errors: true }
+ : false,
+ publicPath: config.dev.assetsPublicPath,
+ proxy: config.dev.proxyTable,
+ quiet: true, // necessary for FriendlyErrorsPlugin
+ watchOptions: {
+ poll: config.dev.poll,
+ }
+ },
+ plugins: [
+ new webpack.DefinePlugin({
+ 'process.env': require('../config/dev.env')
+ }),
+ new webpack.HotModuleReplacementPlugin(),
+ new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
+ new webpack.NoEmitOnErrorsPlugin(),
+ // https://github.com/ampedandwired/html-webpack-plugin
+ new HtmlWebpackPlugin({
+ filename: 'index.html',
+ template: 'index.html',
+ inject: true
+ }),
+ // copy custom static assets
+ new CopyWebpackPlugin([
+ {
+ from: path.resolve(__dirname, '../static'),
+ to: config.dev.assetsSubDirectory,
+ ignore: ['.*']
+ }
+ ])
+ ]
+})
+
+module.exports = new Promise((resolve, reject) => {
+ portfinder.basePort = process.env.PORT || config.dev.port
+ portfinder.getPort((err, port) => {
+ if (err) {
+ reject(err)
+ } else {
+ // publish the new Port, necessary for e2e tests
+ process.env.PORT = port
+ // add port to devServer config
+ devWebpackConfig.devServer.port = port
+
+ // Add FriendlyErrorsPlugin
+ devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
+ compilationSuccessInfo: {
+ messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
+ },
+ onErrors: config.dev.notifyOnErrors
+ ? utils.createNotifierCallback()
+ : undefined
+ }))
+
+ resolve(devWebpackConfig)
+ }
+ })
+})
diff --git a/build/webpack.prod.conf.js b/build/webpack.prod.conf.js
new file mode 100644
index 0000000..d9f99f6
--- /dev/null
+++ b/build/webpack.prod.conf.js
@@ -0,0 +1,145 @@
+'use strict'
+const path = require('path')
+const utils = require('./utils')
+const webpack = require('webpack')
+const config = require('../config')
+const merge = require('webpack-merge')
+const baseWebpackConfig = require('./webpack.base.conf')
+const CopyWebpackPlugin = require('copy-webpack-plugin')
+const HtmlWebpackPlugin = require('html-webpack-plugin')
+const ExtractTextPlugin = require('extract-text-webpack-plugin')
+const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
+const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
+
+const env = require('../config/prod.env')
+
+const webpackConfig = merge(baseWebpackConfig, {
+ module: {
+ rules: utils.styleLoaders({
+ sourceMap: config.build.productionSourceMap,
+ extract: true,
+ usePostCSS: true
+ })
+ },
+ devtool: config.build.productionSourceMap ? config.build.devtool : false,
+ output: {
+ path: config.build.assetsRoot,
+ filename: utils.assetsPath('js/[name].[chunkhash].js'),
+ chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
+ },
+ plugins: [
+ // http://vuejs.github.io/vue-loader/en/workflow/production.html
+ new webpack.DefinePlugin({
+ 'process.env': env
+ }),
+ new UglifyJsPlugin({
+ uglifyOptions: {
+ compress: {
+ warnings: false
+ }
+ },
+ sourceMap: config.build.productionSourceMap,
+ parallel: true
+ }),
+ // extract css into its own file
+ new ExtractTextPlugin({
+ filename: utils.assetsPath('css/[name].[contenthash].css'),
+ // Setting the following option to `false` will not extract CSS from codesplit chunks.
+ // Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
+ // It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
+ // increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
+ allChunks: true,
+ }),
+ // Compress extracted CSS. We are using this plugin so that possible
+ // duplicated CSS from different components can be deduped.
+ new OptimizeCSSPlugin({
+ cssProcessorOptions: config.build.productionSourceMap
+ ? { safe: true, map: { inline: false } }
+ : { safe: true }
+ }),
+ // generate dist index.html with correct asset hash for caching.
+ // you can customize output by editing /index.html
+ // see https://github.com/ampedandwired/html-webpack-plugin
+ new HtmlWebpackPlugin({
+ filename: config.build.index,
+ template: 'index.html',
+ inject: true,
+ minify: {
+ removeComments: true,
+ collapseWhitespace: true,
+ removeAttributeQuotes: true
+ // more options:
+ // https://github.com/kangax/html-minifier#options-quick-reference
+ },
+ // necessary to consistently work with multiple chunks via CommonsChunkPlugin
+ chunksSortMode: 'dependency'
+ }),
+ // keep module.id stable when vendor modules does not change
+ new webpack.HashedModuleIdsPlugin(),
+ // enable scope hoisting
+ new webpack.optimize.ModuleConcatenationPlugin(),
+ // split vendor js into its own file
+ new webpack.optimize.CommonsChunkPlugin({
+ name: 'vendor',
+ minChunks (module) {
+ // any required modules inside node_modules are extracted to vendor
+ return (
+ module.resource &&
+ /\.js$/.test(module.resource) &&
+ module.resource.indexOf(
+ path.join(__dirname, '../node_modules')
+ ) === 0
+ )
+ }
+ }),
+ // extract webpack runtime and module manifest to its own file in order to
+ // prevent vendor hash from being updated whenever app bundle is updated
+ new webpack.optimize.CommonsChunkPlugin({
+ name: 'manifest',
+ minChunks: Infinity
+ }),
+ // This instance extracts shared chunks from code splitted chunks and bundles them
+ // in a separate chunk, similar to the vendor chunk
+ // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
+ new webpack.optimize.CommonsChunkPlugin({
+ name: 'app',
+ async: 'vendor-async',
+ children: true,
+ minChunks: 3
+ }),
+
+ // copy custom static assets
+ new CopyWebpackPlugin([
+ {
+ from: path.resolve(__dirname, '../static'),
+ to: config.build.assetsSubDirectory,
+ ignore: ['.*']
+ }
+ ])
+ ]
+})
+
+if (config.build.productionGzip) {
+ const CompressionWebpackPlugin = require('compression-webpack-plugin')
+
+ webpackConfig.plugins.push(
+ new CompressionWebpackPlugin({
+ asset: '[path].gz[query]',
+ algorithm: 'gzip',
+ test: new RegExp(
+ '\\.(' +
+ config.build.productionGzipExtensions.join('|') +
+ ')$'
+ ),
+ threshold: 10240,
+ minRatio: 0.8
+ })
+ )
+}
+
+if (config.build.bundleAnalyzerReport) {
+ const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
+ webpackConfig.plugins.push(new BundleAnalyzerPlugin())
+}
+
+module.exports = webpackConfig
diff --git a/config/dev.env.js b/config/dev.env.js
new file mode 100644
index 0000000..1e22973
--- /dev/null
+++ b/config/dev.env.js
@@ -0,0 +1,7 @@
+'use strict'
+const merge = require('webpack-merge')
+const prodEnv = require('./prod.env')
+
+module.exports = merge(prodEnv, {
+ NODE_ENV: '"development"'
+})
diff --git a/config/index.js b/config/index.js
new file mode 100644
index 0000000..463630c
--- /dev/null
+++ b/config/index.js
@@ -0,0 +1,54 @@
+/*
+ * index
+ *
+ * @Author: ShanZhu
+ * @Date: 2023-11-23
+ */
+'use strict'
+const path = require('path')
+
+module.exports = {
+ dev: {
+
+ // Paths
+ assetsSubDirectory: 'static',
+ assetsPublicPath: '/',
+ proxyTable: {
+ '/api': {
+ target: 'http://localhost:8087',//本地地址
+ changeOrigin: true,
+ pathRewrite: {
+ '^/api': ''//这里理解成用‘/api’代替target里面的地址,后面组件中我们掉接口时直接用api代替 比如我要调用'http://40.00.100.100:3002/user/add',直接写‘/api/user/add’即可
+ }
+ }
+ },
+
+ host: 'localhost',
+ port: 8088,
+ autoOpenBrowser: false,
+ errorOverlay: true,
+ notifyOnErrors: true,
+ poll: false,
+ devtool: 'cheap-module-eval-source-map',
+ cacheBusting: true,
+ cssSourceMap: true
+ },
+
+ build: {
+ index: path.resolve(__dirname, '../dist/index.html'),
+
+ // Paths
+ assetsRoot: path.resolve(__dirname, '../dist'),
+ assetsSubDirectory: 'static',
+ assetsPublicPath: '/',
+
+
+ productionSourceMap: true,
+ // https://webpack.js.org/configuration/devtool/#production
+ devtool: '#source-map',
+
+ productionGzip: false,
+ productionGzipExtensions: ['js', 'css'],
+ bundleAnalyzerReport: process.env.npm_config_report
+ }
+}
diff --git a/config/prod.env.js b/config/prod.env.js
new file mode 100644
index 0000000..a6f9976
--- /dev/null
+++ b/config/prod.env.js
@@ -0,0 +1,4 @@
+'use strict'
+module.exports = {
+ NODE_ENV: '"production"'
+}
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..c5af441
--- /dev/null
+++ b/index.html
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+ 在线考试系统
+
+
+
+
+
+
+
+
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..3a61963
--- /dev/null
+++ b/package.json
@@ -0,0 +1,75 @@
+{
+ "name": "vue-init",
+ "version": "1.0.0",
+ "description": "vue demo",
+ "author": "",
+ "private": true,
+ "scripts": {
+ "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
+ "start": "npm run dev",
+ "build": "node build/build.js"
+ },
+ "dependencies": {
+ "@babel/preset-es2015": "^7.0.0-beta.53",
+ "axios": "^0.18.0",
+ "echarts": "^4.2.0-rc.2",
+ "element-ui": "^2.4.11",
+ "global": "^4.4.0",
+ "vis": "^4.21.0",
+ "vue": "^2.5.2",
+ "vue-cookies": "^1.5.12",
+ "vue-router": "^3.0.1",
+ "vuex": "^3.0.1",
+ "vuex-persistedstate": "^2.5.4"
+ },
+ "devDependencies": {
+ "less": "^4.1.3",
+ "less-loader": "5.0.0",
+ "@babel/core": "^7.2.2",
+ "@babel/preset-env": "^7.2.3",
+ "autoprefixer": "^7.1.2",
+ "babel-core": "^6.22.1",
+ "babel-helper-vue-jsx-merge-props": "^2.0.3",
+ "babel-loader": "^7.1.5",
+ "babel-plugin-syntax-jsx": "^6.18.0",
+ "babel-plugin-transform-runtime": "^6.22.0",
+ "babel-plugin-transform-vue-jsx": "^3.5.0",
+ "babel-preset-env": "^1.3.2",
+ "babel-preset-stage-2": "^6.22.0",
+ "chalk": "^2.0.1",
+ "copy-webpack-plugin": "^4.0.1",
+ "css-loader": "^0.28.0",
+ "extract-text-webpack-plugin": "^3.0.0",
+ "file-loader": "^1.1.4",
+ "friendly-errors-webpack-plugin": "^1.6.1",
+ "html-webpack-plugin": "^2.30.1",
+ "node-notifier": "^5.1.2",
+ "optimize-css-assets-webpack-plugin": "^3.2.0",
+ "ora": "^1.2.0",
+ "portfinder": "^1.0.13",
+ "postcss-import": "^11.0.0",
+ "postcss-loader": "^2.0.8",
+ "postcss-url": "^7.2.1",
+ "rimraf": "^2.6.0",
+ "semver": "^5.3.0",
+ "shelljs": "^0.7.6",
+ "uglifyjs-webpack-plugin": "^1.1.1",
+ "url-loader": "^0.5.8",
+ "vue-loader": "^13.3.0",
+ "vue-style-loader": "^3.0.1",
+ "vue-template-compiler": "^2.5.2",
+ "webpack": "^3.12.0",
+ "webpack-bundle-analyzer": "^2.9.0",
+ "webpack-dev-server": "^2.9.1",
+ "webpack-merge": "^4.1.0"
+ },
+ "engines": {
+ "node": ">= 6.0.0",
+ "npm": ">= 3.0.0"
+ },
+ "browserslist": [
+ "> 1%",
+ "last 2 versions",
+ "not ie <= 8"
+ ]
+}
diff --git a/src/App.vue b/src/App.vue
new file mode 100644
index 0000000..9df61f2
--- /dev/null
+++ b/src/App.vue
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/homepage.png b/src/assets/homepage.png
new file mode 100644
index 0000000..643ff6f
Binary files /dev/null and b/src/assets/homepage.png differ
diff --git a/src/assets/img/evening.png b/src/assets/img/evening.png
new file mode 100644
index 0000000..4645b0d
Binary files /dev/null and b/src/assets/img/evening.png differ
diff --git a/src/assets/img/icon.png b/src/assets/img/icon.png
new file mode 100644
index 0000000..4356b65
Binary files /dev/null and b/src/assets/img/icon.png differ
diff --git a/src/assets/img/loginbg.png b/src/assets/img/loginbg.png
new file mode 100644
index 0000000..2af181d
Binary files /dev/null and b/src/assets/img/loginbg.png differ
diff --git a/src/assets/img/loginicon.png b/src/assets/img/loginicon.png
new file mode 100644
index 0000000..2d0fcae
Binary files /dev/null and b/src/assets/img/loginicon.png differ
diff --git a/src/assets/img/userimg.png b/src/assets/img/userimg.png
new file mode 100644
index 0000000..2d0fcae
Binary files /dev/null and b/src/assets/img/userimg.png differ
diff --git a/src/assets/logo.png b/src/assets/logo.png
new file mode 100644
index 0000000..4356b65
Binary files /dev/null and b/src/assets/logo.png differ
diff --git a/src/components/charts/grade.vue b/src/components/charts/grade.vue
new file mode 100644
index 0000000..40efed4
--- /dev/null
+++ b/src/components/charts/grade.vue
@@ -0,0 +1,99 @@
+
+
+
+
+
+
+
+
diff --git a/src/components/charts/scorePart.vue b/src/components/charts/scorePart.vue
new file mode 100644
index 0000000..97503d6
--- /dev/null
+++ b/src/components/charts/scorePart.vue
@@ -0,0 +1,122 @@
+
+
+
+
+
+ 该门考试还没人参考哦,请提醒学生参加考试。
+
+
+
+
+
+
+
+
+
diff --git a/src/components/student/answer.vue b/src/components/student/answer.vue
new file mode 100644
index 0000000..5701f3e
--- /dev/null
+++ b/src/components/student/answer.vue
@@ -0,0 +1,956 @@
+
+
+
+
+
+
+ -
+
+
+ - {{ examData.type }}-{{ examData.source }}
+ -
+
+
+
姓名:{{ userInfo.name }}
+
准考证号: {{ userInfo.id }}
+
+
+
+
+
+
+
+
+
+
+ -
+
+ 当前
+
+ -
+
+ 未答
+
+ -
+
+ 已答
+
+ -
+
+ 标记
+
+
+
+
+
+
+
+
+
+
{{ title }}
+
+
全卷共{{ topicCount[0] + topicCount[1] + topicCount[2] }}题
+
+ 倒计时:{{ time }}分钟
+
+
+
+
+ {{ number }}{{ showQuestion }}
+
+
+
+ {{ showAnswer.answerA }}
+ {{ showAnswer.answerB }}
+ {{ showAnswer.answerC }}
+ {{ showAnswer.answerD }}
+
+
+
+ -
+ 正确答案:{{ reduceAnswer.rightAnswer }}
+
+ - 题目解析:
+ -
+ {{
+ reduceAnswer.analysis == null
+ ? "暂无解析"
+ : reduceAnswer.analysis
+ }}
+
+
+
+
+
+
+
+
+
+
+
+ -
+ 正确答案:{{ topic[2][index].answer }}
+
+ - 题目解析:
+ -
+ {{
+ topic[2][index].analysis == null
+ ? "暂无解析"
+ : topic[2][index].analysis
+ }}
+
+
+
+
+
+
+ 正确
+ 错误
+
+
+
+ -
+ 正确答案:{{ topic[3][index].answer=='T'?'正确':'错误' }}
+
+ - 题目解析:
+ -
+ {{
+ topic[3][index].analysis == null
+ ? "暂无解析"
+ : topic[3][index].analysis
+ }}
+
+
+
+
+
+
+
+ -
+ 上一题
+
+ -
+ 标记
+
+ -
+ 下一题
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/student/answerScore.vue b/src/components/student/answerScore.vue
new file mode 100644
index 0000000..ed9551f
--- /dev/null
+++ b/src/components/student/answerScore.vue
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+ 本次考试成绩
+
+
+
+ - 开始时间 {{startTime}}
+ - 结束时间 {{endTime}}
+
+
+
+
+
+
+
+
+
diff --git a/src/components/student/examMsg.vue b/src/components/student/examMsg.vue
new file mode 100644
index 0000000..931809b
--- /dev/null
+++ b/src/components/student/examMsg.vue
@@ -0,0 +1,274 @@
+
+
+
+
+ 试卷列表
+ / {{examData.source}}
+
+
+
+
+ - 更新于{{examData.examDate}}
+ - 来自 {{examData.institute}}
+ - {{examData.type}}
+ - {{$store.state.isPractice==true?'开始练习':'开始考试'}}
+
+
+
+
+
+
+
+
+
+
+
+ {{examData.tips}}
+
+
+
+
+
+
+
+
diff --git a/src/components/student/index.vue b/src/components/student/index.vue
new file mode 100644
index 0000000..753ac5f
--- /dev/null
+++ b/src/components/student/index.vue
@@ -0,0 +1,152 @@
+
+
+
+
+
+
+
+
diff --git a/src/components/student/manager.vue b/src/components/student/manager.vue
new file mode 100644
index 0000000..5f2baaf
--- /dev/null
+++ b/src/components/student/manager.vue
@@ -0,0 +1,111 @@
+
+
+
+
+ 修改你的密码
+
+
+
+
+
+
+
+ 提交
+ 重置
+
+
+
+
+
+
+
+
diff --git a/src/components/student/message.vue b/src/components/student/message.vue
new file mode 100644
index 0000000..5762544
--- /dev/null
+++ b/src/components/student/message.vue
@@ -0,0 +1,264 @@
+
+
+
+
交流区
+
+
+
+
+
+
+
+
+
+
+ 提交留言
+
+
+
+ -
+
{{data.title}}
+ {{data.content}}
+ {{data.time}}
+
+
+
+ 回复
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/student/myExam.vue b/src/components/student/myExam.vue
new file mode 100644
index 0000000..16de009
--- /dev/null
+++ b/src/components/student/myExam.vue
@@ -0,0 +1,218 @@
+
+
+
+
考试中心
+
+
+
+ -
+
{{item.source}}
+ {{item.source}}-{{item.description}}
+
+ {{item.examDate.substr(0,10)}}
+ 限时{{item.totalTime}}分钟
+ 满分{{item.totalScore}}分
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/student/myFooter.vue b/src/components/student/myFooter.vue
new file mode 100644
index 0000000..be7f22d
--- /dev/null
+++ b/src/components/student/myFooter.vue
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
diff --git a/src/components/student/scoreTable.vue b/src/components/student/scoreTable.vue
new file mode 100644
index 0000000..509321a
--- /dev/null
+++ b/src/components/student/scoreTable.vue
@@ -0,0 +1,132 @@
+
+
+
+
我的分数
+
+
+
+
+
+
+ {{scope.row.subject}}
+
+
+
+
+
+ {{scope.row.etScore >= 60 ? "及格" : "不及格"}}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/student/startExam.vue b/src/components/student/startExam.vue
new file mode 100644
index 0000000..19a0d46
--- /dev/null
+++ b/src/components/student/startExam.vue
@@ -0,0 +1,313 @@
+
+
+
+
试卷练习
+
+
+
+ -
+
{{item.source}}
+ {{item.source}}-{{item.description}}
+
+ {{item.examDate.substr(0,10)}}
+ 限时{{item.totalTime}}分钟
+ 满分{{item.totalScore}}分
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main.js b/src/main.js
new file mode 100644
index 0000000..8fcd795
--- /dev/null
+++ b/src/main.js
@@ -0,0 +1,32 @@
+/*
+ * 主函数
+ *
+ * @Author: cyh
+ * @Date: 2024-10-11
+ */
+import Vue from 'vue'
+import App from './App'
+import router from './router'
+import echarts from 'echarts'
+import axios from 'axios'
+import ElementUI from 'element-ui'
+import 'element-ui/lib/theme-chalk/index.css'
+import VueCookies from 'vue-cookies'
+import store from '@/vuex/store'
+
+Vue.use(ElementUI)
+Vue.use(VueCookies)
+
+Vue.config.productionTip = false
+Vue.prototype.bus = new Vue()
+Vue.prototype.$echarts = echarts
+Vue.prototype.$axios = axios
+
+new Vue({
+ el: '#app',
+ router,
+ store,
+ render: h => h(App),
+ components: { App },
+ template: ''
+})
diff --git a/src/router/index.js b/src/router/index.js
new file mode 100644
index 0000000..0d36301
--- /dev/null
+++ b/src/router/index.js
@@ -0,0 +1,109 @@
+import Vue from 'vue'
+import Router from 'vue-router'
+Vue.use(Router)
+
+
+
+const VueRouterPush = Router.prototype.push
+
+Router.prototype.push = function push (to) {
+ return VueRouterPush.call(this, to).catch(err => err)
+}
+
+export default new Router({
+ routes: [
+ {
+ path: '/',
+ name: 'login', //登录界面
+ component: () => import('@/components/common/login')
+ },
+ {
+ path: '/index', //教师主页
+ component: () => import('@/components/admin/index'),
+ children: [
+ {
+ path: '/', //首页默认路由
+ component: () => import('@/components/common/hello')
+ },
+ {
+ path:'/grade', //学生成绩
+ component: () => import('@/components/charts/grade')
+ },
+ {
+ path: '/selectExamToPart', //学生分数段
+ component: () => import('@/components/teacher/selectExamToPart')
+ },
+ {
+ path: '/scorePart',
+ component: () => import('@/components/charts/scorePart')
+ },
+ {
+ path: '/allStudentsGrade', //所有学生成绩统计
+ component: () => import('@/components/teacher/allStudentsGrade')
+ },
+ // {
+ // path: '/examDescription', //考试管理功能描述
+ // component: () => import('@/components/teacher/examDescription')
+ // },
+ {
+ path: '/selectExam', //查询所有考试
+ component: () => import('@/components/teacher/selectExam')
+ },
+ {
+ path: '/addExam', //添加考试
+ component: () => import('@/components/teacher/addExam')
+ },
+ // {
+ // path: '/answerDescription', //题库管理功能介绍
+ // component: ()=> import('@/components/teacher/answerDescription')
+ // },
+ {
+ path: '/selectAnswer', //查询所有题库
+ component: () => import('@/components/teacher/selectAnswer')
+ },
+ {
+ path: '/addAnswer', //增加题库主界面
+ component: () => import('@/components/teacher/addAnswer')
+ },
+ {
+ path: '/editAnswerChildren', //编辑题库主界面
+ component: () => import('@/components/teacher/editAnswerChildren')
+ },
+ {
+ path: '/addAnswerChildren', //点击试卷跳转到添加题库页面
+ component: () => import('@/components/teacher/addAnswerChildren')
+ },
+ {
+ path: '/studentManage', //学生管理界面
+ component: () => import('@/components/teacher/studentManage')
+ },
+ {
+ path: '/addStudent', //添加学生
+ component: () => import('@/components/teacher/addStudent')
+ },
+ {
+ path: '/teacherManage',
+ component: () => import('@/components/admin/tacherManage')
+ },
+ {
+ path: '/addTeacher',
+ component: () => import ('@/components/admin/addTeacher')
+ }
+ ]
+ },
+ {
+ path: '/student',
+ component: () => import('@/components/student/index'),
+ children: [
+ {path:"/",component: ()=> import('@/components/student/myExam')},
+ {path:'/startExam', component: () => import('@/components/student/startExam')},
+ {path: '/manager', component: () => import('@/components/student/manager')},
+ {path: '/examMsg', component: () => import('@/components/student/examMsg')},
+ {path: '/message', component: () => import('@/components/student/message')},
+ {path: '/studentScore', component: () => import("@/components/student/answerScore")},
+ {path: '/scoreTable', component: () => import("@/components/student/scoreTable")}
+ ]
+ },
+ {path: '/answer',component: () => import('@/components/student/answer')}
+ ]
+})
diff --git a/src/vuex/store.js b/src/vuex/store.js
new file mode 100644
index 0000000..2bb4f73
--- /dev/null
+++ b/src/vuex/store.js
@@ -0,0 +1,64 @@
+import VUE from 'vue'
+import VUEX from 'vuex'
+
+VUE.use(VUEX)
+
+const state = {
+ isPractice: false, //练习模式标志
+ flag: false, //菜单栏左右滑动标志
+ userInfo: null,
+ menu: [{
+ index: '1',
+ title: '考试管理',
+ icon: 'icon-kechengbiao',
+ content: [{ item2: '考试查询', path: 'selectExam' }, { item3: '添加考试', path: '/addExam' }],
+ },
+ {
+ index: '2',
+ title: '题库管理',
+ icon: 'icon-tiku',
+ content: [{ item2: '所有题库', path: '/selectAnswer' }, { item3: '增加题库', path: '/addAnswer' }, { path: '/addAnswerChildren' }],
+ },
+ {
+ index: '3',
+ title: '成绩查询',
+ icon: 'icon-performance',
+ content: [{ item1: '学生成绩查询', path: '/allStudentsGrade' }, { path: '/grade' }, { item2: '成绩分段查询', path: '/selectExamToPart' }, { path: '/scorePart' }],
+ },
+ {
+ index: '4',
+ title: '学生管理',
+ icon: 'icon-role',
+ content: [{ item1: '学生管理', path: '/studentManage' }, { item2: '添加学生', path: '/addStudent' }],
+ },
+ ],
+}
+const mutations = {
+ practice(state, status) {
+ state.isPractice = status
+ },
+ toggle(state) {
+ state.flag = !state.flag
+ },
+ changeUserInfo(state, info) {
+ state.userInfo = info
+ }
+}
+const getters = {
+
+}
+const actions = {
+ getUserInfo(context, info) {
+ context.commit('changeUserInfo', info)
+ },
+ getPractice(context, status) {
+ context.commit('practice', status)
+ }
+}
+export default new VUEX.Store({
+ state,
+ mutations,
+ getters,
+ actions,
+ // store
+})
diff --git a/static/img/icon.png b/static/img/icon.png
new file mode 100644
index 0000000..4356b65
Binary files /dev/null and b/static/img/icon.png differ
diff --git a/static/img/userimg.png b/static/img/userimg.png
new file mode 100644
index 0000000..4356b65
Binary files /dev/null and b/static/img/userimg.png differ