@ -0,0 +1,18 @@ | |||
{ | |||
"presets": [ | |||
["env", { | |||
"modules": false, | |||
"targets": { | |||
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"] | |||
} | |||
}], | |||
"stage-2" | |||
], | |||
"plugins": ["transform-vue-jsx", "transform-runtime"], | |||
"env": { | |||
"test": { | |||
"presets": ["env", "stage-2"], | |||
"plugins": ["transform-vue-jsx", "transform-es2015-modules-commonjs", "dynamic-import-node"] | |||
} | |||
} | |||
} |
@ -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 |
@ -0,0 +1,5 @@ | |||
/build/ | |||
/config/ | |||
/dist/ | |||
/*.js | |||
/test/unit/coverage/ |
@ -0,0 +1,29 @@ | |||
// https://eslint.org/docs/user-guide/configuring | |||
module.exports = { | |||
root: true, | |||
parserOptions: { | |||
parser: 'babel-eslint' | |||
}, | |||
env: { | |||
browser: true, | |||
}, | |||
extends: [ | |||
// https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention | |||
// consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules. | |||
'plugin:vue/essential', | |||
// https://github.com/standard/standard/blob/master/docs/RULES-en.md | |||
'standard' | |||
], | |||
// required to lint *.vue files | |||
plugins: [ | |||
'vue' | |||
], | |||
// add your custom rules here | |||
rules: { | |||
// allow async-await | |||
'generator-star-spacing': 'off', | |||
// allow debugger during development | |||
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off' | |||
} | |||
} |
@ -0,0 +1,17 @@ | |||
.DS_Store | |||
node_modules/ | |||
/dist/ | |||
npm-debug.log* | |||
yarn-debug.log* | |||
yarn-error.log* | |||
/test/unit/coverage/ | |||
/test/e2e/reports/ | |||
selenium-debug.log | |||
# Editor directories and files | |||
.idea | |||
.vscode | |||
*.suo | |||
*.ntvs* | |||
*.njsproj | |||
*.sln |
@ -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": {} | |||
} | |||
} |
@ -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' | |||
)) | |||
}) | |||
}) |
@ -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) | |||
} | |||
} |
@ -0,0 +1,101 @@ | |||
'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'), | |||
sass: generateLoaders('sass', { indentedSyntax: true }), | |||
scss: generateLoaders('sass'), | |||
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') | |||
}) | |||
} | |||
} |
@ -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' | |||
} | |||
} |
@ -0,0 +1,92 @@ | |||
'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) | |||
} | |||
const createLintingRule = () => ({ | |||
test: /\.(js|vue)$/, | |||
loader: 'eslint-loader', | |||
enforce: 'pre', | |||
include: [resolve('src'), resolve('test')], | |||
options: { | |||
formatter: require('eslint-friendly-formatter'), | |||
emitWarning: !config.dev.showEslintErrorsInOverlay | |||
} | |||
}) | |||
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: [ | |||
...(config.dev.useEslint ? [createLintingRule()] : []), | |||
{ | |||
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]') | |||
} | |||
} | |||
] | |||
}, | |||
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' | |||
} | |||
} |
@ -0,0 +1,96 @@ | |||
'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({ | |||
favicon:path.resolve('src/assets/M.jpg'), | |||
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) | |||
} | |||
}) | |||
}) |
@ -0,0 +1,150 @@ | |||
'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 = process.env.NODE_ENV === 'testing' | |||
? require('../config/test.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: process.env.NODE_ENV === 'testing' | |||
? 'index.html' | |||
: config.build.index, | |||
template: 'index.html', | |||
favicon:path.resolve('src/assets/M.jpg'), | |||
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 |
@ -0,0 +1,7 @@ | |||
'use strict' | |||
const merge = require('webpack-merge') | |||
const prodEnv = require('./prod.env') | |||
module.exports = merge(prodEnv, { | |||
NODE_ENV: '"development"' | |||
}) |
@ -0,0 +1,83 @@ | |||
'use strict' | |||
// Template version: 1.3.1 | |||
// see http://vuejs-templates.github.io/webpack for documentation. | |||
const path = require('path') | |||
module.exports = { | |||
dev: { | |||
// Paths | |||
assetsSubDirectory: 'static', | |||
assetsPublicPath: '/', | |||
proxyTable: { | |||
'/cross': { | |||
target: 'http://113.31.111.226',//后端接口地址 | |||
changeOrigin: true,//是否允许跨越 | |||
pathRewrite: { | |||
'^/cross': '/cross',//重写, | |||
} | |||
}, | |||
}, | |||
// Various Dev Server settings | |||
host: 'localhost', // can be overwritten by process.env.HOST | |||
port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined | |||
autoOpenBrowser: false, | |||
errorOverlay: true, | |||
notifyOnErrors: true, | |||
poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- | |||
// Use Eslint Loader? | |||
// If true, your code will be linted during bundling and | |||
// linting errors and warnings will be shown in the console. | |||
useEslint: false, | |||
// If true, eslint errors and warnings will also be shown in the error overlay | |||
// in the browser. | |||
showEslintErrorsInOverlay: false, | |||
/** | |||
* Source Maps | |||
*/ | |||
// https://webpack.js.org/configuration/devtool/#development | |||
devtool: 'cheap-module-eval-source-map', | |||
// If you have problems debugging vue-files in devtools, | |||
// set this to false - it *may* help | |||
// https://vue-loader.vuejs.org/en/options.html#cachebusting | |||
cacheBusting: true, | |||
cssSourceMap: true | |||
}, | |||
build: { | |||
// Template for index.html | |||
index: path.resolve(__dirname, '../dist/index.html'), | |||
// Paths | |||
assetsRoot: path.resolve(__dirname, '../dist'), | |||
assetsSubDirectory: 'static', | |||
assetsPublicPath: './', | |||
/** | |||
* Source Maps | |||
*/ | |||
productionSourceMap: true, | |||
// https://webpack.js.org/configuration/devtool/#production | |||
devtool: '#source-map', | |||
// Gzip off by default as many popular static hosts such as | |||
// Surge or Netlify already gzip all static assets for you. | |||
// Before setting to `true`, make sure to: | |||
// npm install --save-dev compression-webpack-plugin | |||
productionGzip: false, | |||
productionGzipExtensions: ['js', 'css'], | |||
// Run the build command with an extra argument to | |||
// View the bundle analyzer report after build finishes: | |||
// `npm run build --report` | |||
// Set to `true` or `false` to always turn it on or off | |||
bundleAnalyzerReport: process.env.npm_config_report | |||
} | |||
} |
@ -0,0 +1,4 @@ | |||
'use strict' | |||
module.exports = { | |||
NODE_ENV: '"production"' | |||
} |
@ -0,0 +1,7 @@ | |||
'use strict' | |||
const merge = require('webpack-merge') | |||
const devEnv = require('./dev.env') | |||
module.exports = merge(devEnv, { | |||
NODE_ENV: '"testing"' | |||
}) |
@ -0,0 +1,12 @@ | |||
<!DOCTYPE html> | |||
<html> | |||
<head> | |||
<meta charset="utf-8"> | |||
<meta name="viewport" content="width=device-width,initial-scale=1.0"> | |||
<title>demo</title> | |||
</head> | |||
<body> | |||
<div id="app"></div> | |||
<!-- built files will be auto injected --> | |||
</body> | |||
</html> |
@ -0,0 +1,91 @@ | |||
{ | |||
"name": "demo", | |||
"version": "1.0.0", | |||
"description": "A Vue.js project", | |||
"author": "10195101478 <10195101478@stu.ecnu.edu.cn>", | |||
"private": true, | |||
"scripts": { | |||
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", | |||
"start": "npm run dev", | |||
"unit": "jest --config test/unit/jest.conf.js --coverage", | |||
"e2e": "node test/e2e/runner.js", | |||
"test": "npm run unit && npm run e2e", | |||
"lint": "eslint --ext .js,.vue src test/unit test/e2e/specs", | |||
"build": "node build/build.js" | |||
}, | |||
"dependencies": { | |||
"axios": "^0.21.1", | |||
"element-ui": "^2.14.1", | |||
"qs": "^6.9.4", | |||
"vue": "^2.5.2", | |||
"vue-axios": "^3.2.2", | |||
"vue-router": "^3.0.1" | |||
}, | |||
"devDependencies": { | |||
"autoprefixer": "^7.1.2", | |||
"babel-core": "^6.22.1", | |||
"babel-eslint": "^8.2.1", | |||
"babel-helper-vue-jsx-merge-props": "^2.0.3", | |||
"babel-jest": "^21.0.2", | |||
"babel-loader": "^7.1.1", | |||
"babel-plugin-dynamic-import-node": "^1.2.0", | |||
"babel-plugin-syntax-jsx": "^6.18.0", | |||
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.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", | |||
"babel-register": "^6.22.0", | |||
"chalk": "^2.0.1", | |||
"chromedriver": "^2.27.2", | |||
"copy-webpack-plugin": "^4.0.1", | |||
"cross-spawn": "^5.0.1", | |||
"css-loader": "^0.28.0", | |||
"eslint": "^4.15.0", | |||
"eslint-config-standard": "^10.2.1", | |||
"eslint-friendly-formatter": "^3.0.0", | |||
"eslint-loader": "^1.7.1", | |||
"eslint-plugin-import": "^2.7.0", | |||
"eslint-plugin-node": "^5.2.0", | |||
"eslint-plugin-promise": "^3.4.0", | |||
"eslint-plugin-standard": "^3.0.1", | |||
"eslint-plugin-vue": "^4.0.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", | |||
"jest": "^22.0.4", | |||
"jest-serializer-vue": "^0.3.0", | |||
"nightwatch": "^0.9.12", | |||
"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", | |||
"selenium-server": "^3.0.1", | |||
"semver": "^5.3.0", | |||
"shelljs": "^0.7.6", | |||
"uglifyjs-webpack-plugin": "^1.1.1", | |||
"url-loader": "^0.5.8", | |||
"vue-jest": "^1.0.2", | |||
"vue-loader": "^13.3.0", | |||
"vue-style-loader": "^3.0.1", | |||
"vue-template-compiler": "^2.5.2", | |||
"webpack": "^3.6.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" | |||
] | |||
} |
@ -0,0 +1,27 @@ | |||
<template> | |||
<div id="app"> | |||
<router-view/> | |||
<router-view name="Head"/> | |||
<router-view name="Layout"/> | |||
<router-view name="Code"/> | |||
</div> | |||
</template> | |||
<script> | |||
export default { | |||
name: 'App' | |||
} | |||
</script> | |||
<style> | |||
#app { | |||
font-family: 'Avenir', Helvetica, Arial, sans-serif; | |||
-webkit-font-smoothing: antialiased; | |||
-moz-osx-font-smoothing: grayscale; | |||
text-align: center; | |||
color: #2c3e50; | |||
margin-top: 60px; | |||
} | |||
</style> |
@ -0,0 +1,415 @@ | |||
<template> | |||
<div> | |||
<el-collapse v-model="activeNames" @change="handleChange" class="Style1"> | |||
<el-collapse-item | |||
title="Mobject:数学物品" | |||
name="1" | |||
@click.native="getData_Mobject" | |||
> | |||
<el-collapse v-model="activeNames" @change="handleChange"> | |||
<el-collapse-item title="types:物体基类" name="1-1"> | |||
<el-collapse-item title="image_mobject:图像物品" name="1-1-1"> | |||
<div v-html="image_mobject"></div> | |||
</el-collapse-item> | |||
<el-collapse-item title="vectorized_mobject:矢量物品" name="1-1-2"> | |||
<div v-html="vectorized_mobject"></div> | |||
</el-collapse-item> | |||
<el-collapse-item title="point_cloud_mobject:点云物品" name="1-1-3"> | |||
<div v-html="point_cloud_mobject"></div> | |||
</el-collapse-item> | |||
</el-collapse-item> | |||
<el-collapse-item title="changing:改变" name="1-2"> | |||
<div v-html="changing"></div> | |||
</el-collapse-item> | |||
<el-collapse-item title="vector_field:向量" name="1-3"> | |||
<div v-html="vector_field"></div> | |||
</el-collapse-item> | |||
<el-collapse-item title="geometry:几何" name="1-4"> | |||
<div v-html="geometry"></div> | |||
</el-collapse-item> | |||
<el-collapse-item title="svg:可伸缩图形" name="1-5"> | |||
<el-collapse-item title="drawings:图画" name="1-5-1"> | |||
<div v-html="drawings"></div> | |||
</el-collapse-item> | |||
<el-collapse-item title="brace:曲柄" name="1-5-2"> | |||
<div v-html="brace"></div> | |||
</el-collapse-item> | |||
<el-collapse-item title="tex_mobject:支数物品" name="1-5-3"> | |||
<div v-html="tex_mobject"></div> | |||
</el-collapse-item> | |||
<el-collapse-item title="code_mobject:代码物品" name="1-5-4"> | |||
<div v-html="code_mobject"></div> | |||
</el-collapse-item> | |||
<el-collapse-item title="text_mobject:文本物品" name="1-5-5"> | |||
<div v-html="text_mobject"></div> | |||
</el-collapse-item> | |||
<el-collapse-item title="svg_mobject:伸缩物品" name="1-5-6"> | |||
<div v-html="svg_mobject"></div> | |||
</el-collapse-item> | |||
</el-collapse-item> | |||
<el-collapse-item title="coordinate_systems:有序系统" name="1-6"> | |||
<div v-html="coordinate_systems"></div> | |||
</el-collapse-item> | |||
<el-collapse-item title="shape_matchers:形状匹配" name="1-7"> | |||
<div v-html="shape_matchers"></div> | |||
</el-collapse-item> | |||
<el-collapse-item title="probability:可能性" name="1-8"> | |||
<div v-html="probability"></div> | |||
</el-collapse-item> | |||
<el-collapse-item title="value_tracker:价值追踪" name="1-9"> | |||
<div v-html="value_tracker"></div> | |||
</el-collapse-item> | |||
<el-collapse-item title="three_dimensions:三维" name="1-10"> | |||
<div v-html="three_dimensions"></div> | |||
</el-collapse-item> | |||
<el-collapse-item title="matrix:方阵" name="1-11"> | |||
<div v-html="matrix"></div> | |||
</el-collapse-item> | |||
<el-collapse-item title="numbers:数值" name="1-12"> | |||
<div v-html="mobject_numbers"></div> | |||
</el-collapse-item> | |||
<el-collapse-item title="frame:框架" name="1-13"> | |||
<div v-html="frame"></div> | |||
</el-collapse-item> | |||
<el-collapse-item title="functions:功能" name="1-14"> | |||
<div v-html="functions"></div> | |||
</el-collapse-item> | |||
<el-collapse-item title="mobject:物件" name="1-15"> | |||
<div v-html="mobject"></div> | |||
</el-collapse-item> | |||
<el-collapse-item title="number_line:数字列表" name="1-16"> | |||
<div v-html="number_line"></div> | |||
</el-collapse-item> | |||
</el-collapse> | |||
</el-collapse-item> | |||
<el-collapse-item | |||
title="Animation:动画" | |||
name="2" | |||
@click.native="getData_Animation" | |||
> | |||
<el-collapse v-model="activeNames" @change="handleChange"> | |||
<el-collapse-item title="creation:创造" name="2-1"> | |||
<div v-html="creation"></div> | |||
</el-collapse-item> | |||
<el-collapse-item title="animation:动画" name="2-2"> | |||
<div v-html="animation"></div> | |||
</el-collapse-item> | |||
<el-collapse-item title="composition:结合" name="2-3"> | |||
<div v-html="composition"></div> | |||
</el-collapse-item> | |||
<el-collapse-item title="indication:指示" name="2-4"> | |||
<div v-html="indication"></div> | |||
</el-collapse-item> | |||
<el-collapse-item title="image_mobject:图像物品" name="2-5"> | |||
<div v-html="transform"></div> | |||
</el-collapse-item> | |||
<el-collapse-item title="specialized:特例化" name="2-6"> | |||
<div v-html="specialized"></div> | |||
</el-collapse-item> | |||
<el-collapse-item title="numbers:数字" name="2-7"> | |||
<div v-html="animation_numbers"></div> | |||
</el-collapse-item> | |||
<el-collapse-item title="movement:运动" name="2-8"> | |||
<div v-html="movement"></div> | |||
</el-collapse-item> | |||
<el-collapse-item title="fading:消失" name="2-9"> | |||
<div v-html="fading"></div> | |||
</el-collapse-item> | |||
<el-collapse-item title="growing:出现" name="2-10"> | |||
<div v-html="growing"></div> | |||
</el-collapse-item> | |||
<el-collapse-item title="update:更新" name="2-11"> | |||
<div v-html="update"></div> | |||
</el-collapse-item> | |||
<el-collapse-item title="rotation:旋转" name="2-12"> | |||
<div v-html="rotation"></div> | |||
</el-collapse-item> | |||
</el-collapse> | |||
</el-collapse-item> | |||
</el-collapse> | |||
</div> | |||
</template> | |||
<script> | |||
import axios from "axios"; | |||
export default { | |||
name: "my-first-vue", | |||
data: function () { | |||
return { | |||
activeNames: ["1"], | |||
serverResponse: "resp", | |||
image_mobject: "", | |||
vectorized_mobject: "", | |||
point_cloud_mobject: "", | |||
changing: "", | |||
vector_field: "", | |||
geometry: "", | |||
drawings: "", | |||
brace: "", | |||
tex_mobject: "", | |||
code_mobject: "", | |||
text_mobject: "", | |||
svg_mobject: "", | |||
coordinate_systems: "", | |||
shape_matchers: "", | |||
probability: "", | |||
value_tracker: "", | |||
three_dimensions: "", | |||
matrix: "", | |||
mobject_numbers: "", | |||
frame: "", | |||
functions: "", | |||
mobject: "", | |||
number_line: "", | |||
creation: "", | |||
animation: "", | |||
composition: "", | |||
indication: "", | |||
transform: "", | |||
specialized: "", | |||
animation_numbers: "", | |||
movement: "", | |||
fading: "", | |||
growing: "", | |||
update: "", | |||
rotation: "", | |||
}; | |||
}, | |||
methods: { | |||
getData_Mobject() { | |||
var that = this; | |||
const path_mobject = "/class"; | |||
axios | |||
.get(path_mobject) | |||
.then(function (response) { | |||
var msg = response.data; | |||
that.image_mobject = ""; | |||
that.vectorized_mobject = ""; | |||
that.point_cloud_mobject = ""; | |||
that.changing = ""; | |||
that.vector_field = ""; | |||
that.geometry = ""; | |||
that.drawings = ""; | |||
that.brace = ""; | |||
that.tex_mobject = ""; | |||
that.code_mobject = ""; | |||
that.text_mobject = ""; | |||
that.svg_mobject = ""; | |||
that.coordinate_systems = ""; | |||
that.shape_matchers = ""; | |||
that.probability = ""; | |||
that.value_tracker = ""; | |||
that.three_dimensions = ""; | |||
that.matrix = ""; | |||
that.mobject_numbers = ""; | |||
that.frame = ""; | |||
that.functions = ""; | |||
that.mobject = ""; | |||
that.number_line = ""; | |||
for ( | |||
var i = 0; | |||
i < msg.manimlib.mobject.types.image_mobject.length; | |||
i++ | |||
) | |||
that.image_mobject += | |||
msg.manimlib.mobject.types.image_mobject[i] + "<br>"; | |||
for ( | |||
var i = 0; | |||
i < msg.manimlib.mobject.types.vectorized_mobject.length; | |||
i++ | |||
) | |||
that.vectorized_mobject += | |||
msg.manimlib.mobject.types.vectorized_mobject[i] + "<br>"; | |||
for ( | |||
var i = 0; | |||
i < msg.manimlib.mobject.types.point_cloud_mobject.length; | |||
i++ | |||
) | |||
that.point_cloud_mobject += | |||
msg.manimlib.mobject.types.point_cloud_mobject[i] + "<br>"; | |||
for (var i = 0; i < msg.manimlib.mobject.changing.length; i++) | |||
that.changing += msg.manimlib.mobject.changing[i] + "<br>"; | |||
for (var i = 0; i < msg.manimlib.mobject.vector_field.length; i++) | |||
that.vector_field += msg.manimlib.mobject.vector_field[i] + "<br>"; | |||
for (var i = 0; i < msg.manimlib.mobject.geometry.length; i++) | |||
that.geometry += msg.manimlib.mobject.geometry[i] + "<br>"; | |||
for (var i = 0; i < msg.manimlib.mobject.svg.drawings.length; i++) | |||
that.drawings += msg.manimlib.mobject.svg.drawings[i] + "<br>"; | |||
for (var i = 0; i < msg.manimlib.mobject.svg.brace.length; i++) | |||
that.brace += msg.manimlib.mobject.svg.brace[i] + "<br>"; | |||
for (var i = 0; i < msg.manimlib.mobject.svg.tex_mobject.length; i++) | |||
that.tex_mobject += | |||
msg.manimlib.mobject.svg.tex_mobject[i] + "<br>"; | |||
for (var i = 0; i < msg.manimlib.mobject.svg.code_mobject.length; i++) | |||
that.code_mobject += | |||
msg.manimlib.mobject.svg.code_mobject[i] + "<br>"; | |||
for (var i = 0; i < msg.manimlib.mobject.svg.text_mobject.length; i++) | |||
that.text_mobject += | |||
msg.manimlib.mobject.svg.text_mobject[i] + "<br>"; | |||
for (var i = 0; i < msg.manimlib.mobject.svg.svg_mobject.length; i++) | |||
that.svg_mobject += | |||
msg.manimlib.mobject.svg.svg_mobject[i] + "<br>"; | |||
for ( | |||
var i = 0; | |||
i < msg.manimlib.mobject.coordinate_systems.length; | |||
i++ | |||
) | |||
that.coordinate_systems += | |||
msg.manimlib.mobject.coordinate_systems[i] + "<br>"; | |||
for (var i = 0; i < msg.manimlib.mobject.shape_matchers.length; i++) | |||
that.shape_matchers += | |||
msg.manimlib.mobject.shape_matchers[i] + "<br>"; | |||
for (var i = 0; i < msg.manimlib.mobject.probability.length; i++) | |||
that.probability += msg.manimlib.mobject.probability[i] + "<br>"; | |||
for (var i = 0; i < msg.manimlib.mobject.value_tracker.length; i++) | |||
that.value_tracker += | |||
msg.manimlib.mobject.value_tracker[i] + "<br>"; | |||
for (var i = 0; i < msg.manimlib.mobject.three_dimensions.length; i++) | |||
that.three_dimensions += | |||
msg.manimlib.mobject.three_dimensions[i] + "<br>"; | |||
for (var i = 0; i < msg.manimlib.mobject.matrix.length; i++) | |||
that.matrix += msg.manimlib.mobject.matrix[i] + "<br>"; | |||
for (var i = 0; i < msg.manimlib.mobject.numbers.length; i++) | |||
that.mobject_numbers += msg.manimlib.mobject.numbers[i] + "<br>"; | |||
for (var i = 0; i < msg.manimlib.mobject.frame.length; i++) | |||
that.frame += msg.manimlib.mobject.frame[i] + "<br>"; | |||
for (var i = 0; i < msg.manimlib.mobject.functions.length; i++) | |||
that.functions += msg.manimlib.mobject.functions[i] + "<br>"; | |||
for (var i = 0; i < msg.manimlib.mobject.mobject.length; i++) | |||
that.mobject += msg.manimlib.mobject.mobject[i] + "<br>"; | |||
for (var i = 0; i < msg.manimlib.mobject.number_line.length; i++) | |||
that.number_line += msg.manimlib.mobject.number_line[i] + "<br>"; | |||
}) | |||
.catch(function (error) { | |||
alert("Error " + error); | |||
}); | |||
}, | |||
getData_Animation() { | |||
var that = this; | |||
const path_animation = "/class"; | |||
axios | |||
.get(path_animation) | |||
.then(function (response) { | |||
var msg = response.data; | |||
that.creation = ""; | |||
that.animation = ""; | |||
that.composition = ""; | |||
that.indication = ""; | |||
that.transform = ""; | |||
that.specialized = ""; | |||
that.animation_numbers = ""; | |||
that.movement = ""; | |||
that.fading = ""; | |||
that.growing = ""; | |||
that.update = ""; | |||
that.rotation = ""; | |||
for (var i = 0; i < msg.manimlib.animation.creation.length; i++) | |||
that.creation += msg.manimlib.animation.creation[i] + "<br>"; | |||
for (var i = 0; i < msg.manimlib.animation.animation.length; i++) | |||
that.animation += msg.manimlib.animation.animation[i] + "<br>"; | |||
for (var i = 0; i < msg.manimlib.animation.composition.length; i++) | |||
that.composition += msg.manimlib.animation.composition[i] + "<br>"; | |||
for (var i = 0; i < msg.manimlib.animation.indication.length; i++) | |||
that.indication += msg.manimlib.animation.indication[i] + "<br>"; | |||
for (var i = 0; i < msg.manimlib.animation.transform.length; i++) | |||
that.transform += msg.manimlib.animation.transform[i] + "<br>"; | |||
for (var i = 0; i < msg.manimlib.animation.specialized.length; i++) | |||
that.specialized += msg.manimlib.animation.specialized[i] + "<br>"; | |||
for (var i = 0; i < msg.manimlib.animation.numbers.length; i++) | |||
that.animation_numbers += msg.manimlib.animation.numbers[i] + "<br>"; | |||
for (var i = 0; i < msg.manimlib.animation.movement.length; i++) | |||
that.movement += msg.manimlib.animation.movement[i] + "<br>"; | |||
for (var i = 0; i < msg.manimlib.animation.fading.length; i++) | |||
that.fading += msg.manimlib.animation.fading[i] + "<br>"; | |||
for (var i = 0; i < msg.manimlib.animation.growing.length; i++) | |||
that.growing += msg.manimlib.animation.growing[i] + "<br>"; | |||
for (var i = 0; i < msg.manimlib.animation.update.length; i++) | |||
that.update += msg.manimlib.animation.update[i] + "<br>"; | |||
for (var i = 0; i < msg.manimlib.animation.rotation.length; i++) | |||
that.rotation += msg.manimlib.animation.rotation[i] + "<br>"; | |||
}) | |||
.catch(function (error) { | |||
alert("Error " + error); | |||
}); | |||
}, | |||
handleChange(val) { | |||
console.log(val); | |||
}, | |||
}, | |||
}; | |||
</script> | |||
<style scoped> | |||
.Style1 { | |||
float: right; | |||
width: 300px; | |||
} | |||
</style> |
@ -0,0 +1,118 @@ | |||
<template> | |||
<div> | |||
<el-row> | |||
<el-col :span="12" :offset="6"> | |||
<div>以下为python代码生成动画</div> | |||
<div> | |||
<el-input v-model="input" placeholder="请输入画布名称"></el-input> | |||
<el-select v-model="value" placeholder="请选择画质"> | |||
<el-option | |||
v-for="item in options" | |||
:key="item.value" | |||
:label="item.label" | |||
:value="item.value" | |||
> | |||
</el-option> | |||
</el-select> | |||
<el-input | |||
type="textarea" | |||
:autosize="{ minRows: 6, maxRows: 20 }" | |||
placeholder="请输入代码" | |||
v-model="textarea" | |||
class="Style1" | |||
> | |||
</el-input> | |||
<el-button type="primary" @click.native="submit">提交</el-button> | |||
</div> | |||
</el-col> | |||
</el-row> | |||
</div> | |||
</template> | |||
<script> | |||
export default { | |||
data() { | |||
return { | |||
options: [ | |||
{ | |||
value: "w", | |||
label: "2560*1440", | |||
}, | |||
{ | |||
value: "h", | |||
label: "1920*1080", | |||
}, | |||
{ | |||
value: "m", | |||
label: "1280*720", | |||
}, | |||
{ | |||
value: "l", | |||
label: "854*480", | |||
}, | |||
], | |||
value: "", | |||
textarea: "", | |||
input: "", | |||
ID:"", | |||
}; | |||
}, | |||
methods: { | |||
submit() { | |||
var that = this; | |||
var final_submit = { | |||
username: "", | |||
scene_name: "", | |||
quality: "", | |||
mode: "", | |||
codes: "", | |||
}; | |||
console.log(that.ID); | |||
final_submit.username = this.ID; | |||
final_submit.scene_name = that.input; | |||
final_submit.quality = that.value; | |||
final_submit.mode = "python"; | |||
final_submit.codes = this.textarea; | |||
console.log(final_submit.codes); | |||
this.axios({ | |||
method: "POST", | |||
url: "/generate", | |||
data: final_submit, | |||
}).then((res) => { | |||
console.log(res); | |||
if (res.data.status == "successful") { | |||
this.$message({ | |||
message: "动画生成成功", | |||
type: "success", | |||
} | |||
); | |||
var pos = | |||
"/video?username=" + | |||
final_submit.username + | |||
"&scene_name=" + | |||
final_submit.scene_name + | |||
"&quality=" + | |||
final_submit.quality; | |||
console.log(pos); | |||
window.location.href = pos; | |||
} else { | |||
this.$message({ | |||
message: "选择错误,动画生成失败", | |||
type: "error", | |||
}); | |||
} | |||
}); | |||
}, | |||
}, | |||
mounted:function(){ | |||
this.ID=this.$route.query.userID; | |||
console.log(this.ID); | |||
}, | |||
}; | |||
</script> | |||
<style scoped> | |||
.Style1 { | |||
text-align: center; | |||
} | |||
</style> |
@ -0,0 +1,65 @@ | |||
<template> | |||
<el-row> | |||
<div class="hello"> | |||
<img src="@/assets/manim.jpg" /> | |||
<el-col :span="8" :offset="5"> | |||
<h1>{{ msg }}</h1> | |||
</el-col> | |||
<el-col :span="8" :offset="5"> | |||
<h2>Essential Links</h2> | |||
<ul> | |||
<li> | |||
<a href="https://github.com/cai-hust/manim-tutorial-CN" target="_blank"> | |||
official_document | |||
</a> | |||
</li> | |||
<li> | |||
<a href="https://manim.ml/" target="_blank"> Document Type Tutorial </a> | |||
</li> | |||
<li> | |||
<a | |||
href="https://www.bilibili.com/video/BV1W4411Z7Zt?from=search&seid=6580109186460276345" | |||
target="_blank" | |||
> | |||
Video tutorial | |||
</a> | |||
</li> | |||
</ul> | |||
</el-col> | |||
</div> | |||
</el-row> | |||
</template> | |||
<script> | |||
export default { | |||
name: "HelloWorld", | |||
data() { | |||
return { | |||
msg: "Welcome to The Manim's Web Design", | |||
}; | |||
}, | |||
}; | |||
</script> | |||
<style scoped> | |||
h1, | |||
h2 { | |||
font-weight: normal; | |||
} | |||
ul { | |||
list-style-type: none; | |||
padding: 0; | |||
} | |||
li { | |||
display: inline-block; | |||
margin: 0 10px; | |||
} | |||
a { | |||
color: #42b983; | |||
} | |||
img { | |||
float: left; | |||
width: 300px; | |||
height: 120px; | |||
} | |||
</style> |
@ -0,0 +1,161 @@ | |||
<template> | |||
<div> | |||
<div class="background"> | |||
<div class="front"> | |||
<el-row type="flex" align="middle" justify="center"> | |||
<el-col :span="10"> | |||
<el-card shadow="never"> | |||
<p style="font-size: 40px">MANIM LAB</p> | |||
<el-form> | |||
<el-form-item> | |||
<el-input | |||
v-model="userIOM" | |||
clearable | |||
placeholder="请输入用户名" | |||
@change="setUser" | |||
></el-input> | |||
</el-form-item> | |||
<el-form-item> | |||
<el-input | |||
v-model="password" | |||
type="password" | |||
placeholder="请输入密码" | |||
></el-input> | |||
</el-form-item> | |||
</el-form> | |||
<el-row type="flex" justify="center"> | |||
<el-col :span="8"> | |||
<el-button @click.native="login" type="primary" | |||
>登录</el-button | |||
></el-col | |||
> | |||
<el-col :span="5"> </el-col> | |||
<el-col :span="8"> | |||
<el-button @click.native="register" type="primary" | |||
>注册</el-button | |||
></el-col | |||
> | |||
</el-row> | |||
</el-card> | |||
</el-col> | |||
</el-row> | |||
</div> | |||
</div> | |||
</div> | |||
</template> | |||
<script> | |||
import qs from "qs"; | |||
import axios from "axios"; | |||
export default { | |||
name: "Login", | |||
data() { | |||
return { | |||
userIOM: "", | |||
password: "", | |||
}; | |||
}, | |||
methods: { | |||
is_Email(str) { | |||
var reg = /^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$/; | |||
return reg.test(str); | |||
}, | |||
login() { | |||
var that = this; | |||
if (this.$options.methods.is_Email(this.userIOM)) { | |||
var url = | |||
"/login?username=" + | |||
that.userIOM + | |||
"&password=" + | |||
that.password; | |||
this.axios({ | |||
method: "GET", | |||
url: "/login", | |||
data: { | |||
mail: this.userIOM, | |||
password: this.password, | |||
}, | |||
}) | |||
.then((res) => { | |||
console.log(res); | |||
if (res.data.status == "successful") { | |||
let userId = res.data.id; | |||
console.log(userId); | |||
this.$message({ | |||
message: "登录成功", | |||
type: "success", | |||
}); | |||
this.$router.push({ | |||
path: "/main", | |||
query: { userID: that.userIOM}, | |||
}); | |||
} else { | |||
this.$message({ | |||
message: "登录失败", | |||
type: "error", | |||
}); | |||
} | |||
}) | |||
.catch((err) => { | |||
console.log(err); | |||
}); | |||
} else { | |||
var url = | |||
"/login?username=" + | |||
that.userIOM + | |||
"&password=" + | |||
that.password; | |||
axios | |||
.get(url) | |||
.then((res) => { | |||
console.log(res); | |||
if (res.data.status == "successful") { | |||
let userId = res.data.id; | |||
console.log(userId); | |||
this.$message({ | |||
message: "登录成功", | |||
type: "success", | |||
}); | |||
this.$router.push({ | |||
path: "/main", | |||
query: { userID: that.userIOM}, | |||
}); | |||
} else { | |||
this.$message({ | |||
message: "登录失败", | |||
type: "error", | |||
}); | |||
} | |||
}) | |||
.catch((err) => { | |||
console.log(err); | |||
}); | |||
} | |||
}, | |||
register() { | |||
this.$router.push({ path: "/register" }); | |||
}, | |||
setUser: function () { | |||
this.$emit("transferUser", this.userIOM); | |||
}, | |||
}, | |||
}; | |||
</script> | |||
<style scoped> | |||
.background { | |||
position: absolute; | |||
background-image: url(../assets/background.jpg); | |||
width: 100%; | |||
height: 100%; | |||
min-width: 1000px; | |||
z-index: -1; | |||
background-repeat: no-repeat; | |||
background-size: cover; | |||
} | |||
.front { | |||
text-align: center; | |||
position: relative; | |||
} | |||
</style> |
@ -0,0 +1,121 @@ | |||
<template> | |||
<div class="register_page"> | |||
<p style="font-size: 40px">MANIM LAB</p> | |||
<el-row type="flex" align="middle" justify="center"> | |||
<el-col :span="10"> | |||
<el-card shadow="always"> | |||
<el-form :model="infoForm" status-icon :rules="rules" ref="infoForm"> | |||
<el-form-item | |||
label="用户名" | |||
:rules="[ | |||
{ required: true, message: '用户名不能为空', trigger: 'blur' }, | |||
]" | |||
prop="userName" | |||
> | |||
<el-input | |||
v-model="infoForm.userName" | |||
clearable | |||
placeholder="请输入用户名" | |||
autocomplete="off" | |||
></el-input> | |||
</el-form-item> | |||
<el-form-item label="密码" prop="pass"> | |||
<el-input | |||
v-model="infoForm.password" | |||
type="password" | |||
placeholder="请输入密码" | |||
autocomplete="off" | |||
></el-input> | |||
</el-form-item> | |||
<el-form-item label="确认密码" prop="checkPass"> | |||
<el-input | |||
v-model="infoForm.rePassword" | |||
type="password" | |||
placeholder="请确认密码" | |||
autocomplete="off" | |||
></el-input> | |||
</el-form-item> | |||
</el-form> | |||
<el-button | |||
class="register_btn" | |||
@click="register('infoForm')" | |||
type="primary" | |||
>注册</el-button | |||
> | |||
</el-card> | |||
</el-col> | |||
</el-row> | |||
</div> | |||
</template> | |||
<script> | |||
import axios from 'axios'; | |||
export default { | |||
data() { | |||
var validatePass = (rule, value, callback) => { | |||
if (this.infoForm.password === "") { | |||
callback(new Error("请输入密码")); | |||
} else { | |||
if (this.infoForm.rePassword !== "") { | |||
this.$refs.infoForm.validateField("checkPass"); | |||
} | |||
callback(); | |||
} | |||
}; | |||
var validatePass2 = (rule, value, callback) => { | |||
if (this.infoForm.rePassword === "") { | |||
callback(new Error("请再次输入密码")); | |||
} else if (this.infoForm.rePassword !== this.infoForm.password) { | |||
callback(new Error("两次输入密码不一致")); | |||
} else { | |||
callback(); | |||
} | |||
}; | |||
return { | |||
infoForm: { | |||
userName: "", | |||
mail: "", | |||
password: "", | |||
rePassword: "", | |||
}, | |||
rules: { | |||
pass: [{ validator: validatePass, trigger: "blur" }], | |||
checkPass: [{ validator: validatePass2, trigger: "blur" }], | |||
}, | |||
}; | |||
}, | |||
methods: { | |||
register(aForm) { | |||
this.$refs[aForm].validate((valid) => { | |||
if (valid) { | |||
var url="/register?username="+this.infoForm.userName+"&password="+this.infoForm.password; | |||
axios.get(url) | |||
.then((res) => { | |||
console.log(res); | |||
if (res.data.status == "successful") { | |||
this.$message({ | |||
message: "注册成功", | |||
type: "success", | |||
}); | |||
let userId = res.data.id; | |||
this.$router.push({ path: "/" }); | |||
} else { | |||
this.$message({ | |||
message: "注册失败", | |||
type: "error", | |||
}); | |||
} | |||
}) | |||
.catch((err) => { | |||
console.log(err); | |||
}); | |||
} else { | |||
console.log("错误"); | |||
} | |||
}); | |||
}, | |||
}, | |||
}; | |||
</script> |
@ -0,0 +1,5 @@ | |||
<template> | |||
<div v-html="html"> | |||
</div> | |||
</template> |
@ -0,0 +1,25 @@ | |||
// The Vue build version to load with the `import` command | |||
// (runtime-only or standalone) has been set in webpack.base.conf with an alias. | |||
import Vue from 'vue' | |||
import App from './App' | |||
import router from './router' | |||
import axios from 'axios' | |||
import VueAxios from 'vue-axios' | |||
import ElementUI from 'element-ui'; | |||
import 'element-ui/lib/theme-chalk/index.css' | |||
import VueRouter from 'vue-router' | |||
Vue.use(ElementUI) | |||
Vue.use(VueAxios, axios) | |||
Vue.use(VueRouter) | |||
Vue.prototype.$axios = axios | |||
Vue.config.productionTip = false | |||
axios.defaults.baseURL='/' | |||
/* eslint-disable no-new */ | |||
new Vue({ | |||
el: '#app', | |||
router, | |||
components: { App }, | |||
template: '<App/>' | |||
}) |
@ -0,0 +1,30 @@ | |||
import Vue from 'vue' | |||
import Router from 'vue-router' | |||
import Ajax from '@/components/Ajax' | |||
import Layout from '@/components/Layout' | |||
import Head from '@/components/Head' | |||
import Code from '@/components/Code' | |||
import Login from '@/components/Login' | |||
import Register from '@/components/Register' | |||
Vue.use(Router) | |||
export default new Router({ | |||
routes: [ | |||
{ | |||
path:'/', | |||
name:'login', | |||
component:Login, | |||
}, | |||
{ | |||
path:'/register', | |||
name:'Register', | |||
component:Register, | |||
}, | |||
{ | |||
path: '/main', | |||
name: 'HelloWorld', | |||
components: {Head,Ajax,Layout,Code}, | |||
}, | |||
], | |||
mode:'hash', | |||
}) |
@ -0,0 +1,27 @@ | |||
// A custom Nightwatch assertion. | |||
// The assertion name is the filename. | |||
// Example usage: | |||
// | |||
// browser.assert.elementCount(selector, count) | |||
// | |||
// For more information on custom assertions see: | |||
// http://nightwatchjs.org/guide#writing-custom-assertions | |||
exports.assertion = function (selector, count) { | |||
this.message = 'Testing if element <' + selector + '> has count: ' + count | |||
this.expected = count | |||
this.pass = function (val) { | |||
return val === this.expected | |||
} | |||
this.value = function (res) { | |||
return res.value | |||
} | |||
this.command = function (cb) { | |||
var self = this | |||
return this.api.execute(function (selector) { | |||
return document.querySelectorAll(selector).length | |||
}, [selector], function (res) { | |||
cb.call(self, res) | |||
}) | |||
} | |||
} |
@ -0,0 +1,46 @@ | |||
require('babel-register') | |||
var config = require('../../config') | |||
// http://nightwatchjs.org/gettingstarted#settings-file | |||
module.exports = { | |||
src_folders: ['test/e2e/specs'], | |||
output_folder: 'test/e2e/reports', | |||
custom_assertions_path: ['test/e2e/custom-assertions'], | |||
selenium: { | |||
start_process: true, | |||
server_path: require('selenium-server').path, | |||
host: '127.0.0.1', | |||
port: 4444, | |||
cli_args: { | |||
'webdriver.chrome.driver': require('chromedriver').path | |||
} | |||
}, | |||
test_settings: { | |||
default: { | |||
selenium_port: 4444, | |||
selenium_host: 'localhost', | |||
silent: true, | |||
globals: { | |||
devServerURL: 'http://localhost:' + (process.env.PORT || config.dev.port) | |||
} | |||
}, | |||
chrome: { | |||
desiredCapabilities: { | |||
browserName: 'chrome', | |||
javascriptEnabled: true, | |||
acceptSslCerts: true | |||
} | |||
}, | |||
firefox: { | |||
desiredCapabilities: { | |||
browserName: 'firefox', | |||
javascriptEnabled: true, | |||
acceptSslCerts: true | |||
} | |||
} | |||
} | |||
} |
@ -0,0 +1,48 @@ | |||
// 1. start the dev server using production config | |||
process.env.NODE_ENV = 'testing' | |||
const webpack = require('webpack') | |||
const DevServer = require('webpack-dev-server') | |||
const webpackConfig = require('../../build/webpack.prod.conf') | |||
const devConfigPromise = require('../../build/webpack.dev.conf') | |||
let server | |||
devConfigPromise.then(devConfig => { | |||
const devServerOptions = devConfig.devServer | |||
const compiler = webpack(webpackConfig) | |||
server = new DevServer(compiler, devServerOptions) | |||
const port = devServerOptions.port | |||
const host = devServerOptions.host | |||
return server.listen(port, host) | |||
}) | |||
.then(() => { | |||
// 2. run the nightwatch test suite against it | |||
// to run in additional browsers: | |||
// 1. add an entry in test/e2e/nightwatch.conf.js under "test_settings" | |||
// 2. add it to the --env flag below | |||
// or override the environment flag, for example: `npm run e2e -- --env chrome,firefox` | |||
// For more information on Nightwatch's config file, see | |||
// http://nightwatchjs.org/guide#settings-file | |||
let opts = process.argv.slice(2) | |||
if (opts.indexOf('--config') === -1) { | |||
opts = opts.concat(['--config', 'test/e2e/nightwatch.conf.js']) | |||
} | |||
if (opts.indexOf('--env') === -1) { | |||
opts = opts.concat(['--env', 'chrome']) | |||
} | |||
const spawn = require('cross-spawn') | |||
const runner = spawn('./node_modules/.bin/nightwatch', opts, { stdio: 'inherit' }) | |||
runner.on('exit', function (code) { | |||
server.close() | |||
process.exit(code) | |||
}) | |||
runner.on('error', function (err) { | |||
server.close() | |||
throw err | |||
}) | |||
}) |
@ -0,0 +1,19 @@ | |||
// For authoring Nightwatch tests, see | |||
// http://nightwatchjs.org/guide#usage | |||
module.exports = { | |||
'default e2e tests': function (browser) { | |||
// automatically uses dev Server port from /config.index.js | |||
// default: http://localhost:8080 | |||
// see nightwatch.conf.js | |||
const devServer = browser.globals.devServerURL | |||
browser | |||
.url(devServer) | |||
.waitForElementVisible('#app', 5000) | |||
.assert.elementPresent('.hello') | |||
.assert.containsText('h1', 'Welcome to Your Vue.js App') | |||
.assert.elementCount('img', 1) | |||
.end() | |||
} | |||
} |
@ -0,0 +1,7 @@ | |||
{ | |||
"env": { | |||
"jest": true | |||
}, | |||
"globals": { | |||
} | |||
} |
@ -0,0 +1,30 @@ | |||
const path = require('path') | |||
module.exports = { | |||
rootDir: path.resolve(__dirname, '../../'), | |||
moduleFileExtensions: [ | |||
'js', | |||
'json', | |||
'vue' | |||
], | |||
moduleNameMapper: { | |||
'^@/(.*)$': '<rootDir>/src/$1' | |||
}, | |||
transform: { | |||
'^.+\\.js$': '<rootDir>/node_modules/babel-jest', | |||
'.*\\.(vue)$': '<rootDir>/node_modules/vue-jest' | |||
}, | |||
testPathIgnorePatterns: [ | |||
'<rootDir>/test/e2e' | |||
], | |||
snapshotSerializers: ['<rootDir>/node_modules/jest-serializer-vue'], | |||
setupFiles: ['<rootDir>/test/unit/setup'], | |||
mapCoverage: true, | |||
coverageDirectory: '<rootDir>/test/unit/coverage', | |||
collectCoverageFrom: [ | |||
'src/**/*.{js,vue}', | |||
'!src/main.js', | |||
'!src/router/index.js', | |||
'!**/node_modules/**' | |||
] | |||
} |
@ -0,0 +1,3 @@ | |||
import Vue from 'vue' | |||
Vue.config.productionTip = false |
@ -0,0 +1,11 @@ | |||
import Vue from 'vue' | |||
import HelloWorld from '@/components/HelloWorld' | |||
describe('HelloWorld.vue', () => { | |||
it('should render correct contents', () => { | |||
const Constructor = Vue.extend(HelloWorld) | |||
const vm = new Constructor().$mount() | |||
expect(vm.$el.querySelector('.hello h1').textContent) | |||
.toEqual('Welcome to Your Vue.js App') | |||
}) | |||
}) |