├── .babelrc ├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .postcssrc.js ├── README.md ├── build ├── build.js ├── check-versions.js ├── dev-client.js ├── dev-server.js ├── utils.js ├── vue-loader.conf.js ├── webpack.base.conf.js ├── webpack.dev.conf.js ├── webpack.prod.conf.js └── webpack.test.conf.js ├── config ├── dev.env.js ├── index.js ├── prod.env.js └── test.env.js ├── index.html ├── logo.png ├── package.json ├── src ├── App.vue ├── assets │ ├── css │ │ └── commond.css │ ├── images │ │ ├── 2017-03-18_111001.png │ │ ├── 2017-03-18_164100.png │ │ ├── LOGO Text.png │ │ ├── Worm.png │ │ ├── alipay.png │ │ ├── alipayma.png │ │ ├── checked.png │ │ ├── goods.jpg │ │ ├── index-class_03.jpg │ │ ├── index-class_05.png │ │ ├── index-class_08.jpg │ │ ├── index-class_11.png │ │ ├── index-hd_03.png │ │ ├── index-sp_03.png │ │ ├── index-sp_05.png │ │ ├── index-sp_10.png │ │ ├── left.png │ │ ├── middle.png │ │ ├── right.png │ │ ├── shequ_06.png │ │ ├── tj-li_03.png │ │ ├── tj-li_05.png │ │ ├── tj-li_07.png │ │ ├── uncheck.png │ │ ├── weixin.png │ │ ├── weixinma.png │ │ ├── weixinpay.png │ │ └── 支付成功.png │ ├── js │ │ ├── ajax.js │ │ ├── jquery-1.10.2.min.js │ │ ├── jquery.qrcode.js │ │ ├── qrcode.js │ │ └── serverUrl.js │ └── logo.png ├── components │ ├── Buy.vue │ ├── Classify.vue │ ├── Goods.vue │ ├── Index.vue │ ├── Lgcontent.vue │ ├── Loginbox.vue │ ├── Lwy.vue │ ├── Order.vue │ ├── Pay.vue │ └── er-qart.vue ├── main.js └── router │ └── index.js ├── static ├── .gitkeep ├── QR.js └── logo.png └── test ├── e2e ├── custom-assertions │ └── elementCount.js ├── nightwatch.conf.js ├── runner.js └── specs │ └── test.js └── unit ├── .eslintrc ├── index.js ├── karma.conf.js └── specs └── Hello.spec.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["latest", { 4 | "es2015": { "modules": false } 5 | }], 6 | "stage-2" 7 | ], 8 | "plugins": ["transform-runtime"], 9 | "comments": false, 10 | "env": { 11 | "test": { 12 | "presets": ["latest", "stage-2"], 13 | "plugins": [ "istanbul" ] 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | build/*.js 2 | config/*.js 3 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | // http://eslint.org/docs/user-guide/configuring 2 | 3 | module.exports = { 4 | root: true, 5 | parser: 'babel-eslint', 6 | parserOptions: { 7 | sourceType: 'module' 8 | }, 9 | env: { 10 | browser: true, 11 | }, 12 | // https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style 13 | extends: 'standard', 14 | // required to lint *.vue files 15 | plugins: [ 16 | 'html' 17 | ], 18 | // add your custom rules here 19 | 'rules': { 20 | // allow paren-less arrow functions 21 | 'arrow-parens': 0, 22 | // allow async-await 23 | 'generator-star-spacing': 0, 24 | // allow debugger during development 25 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /.postcssrc.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hj624608494/vue-shopping-mall/0b7fb8ec5de776aef3935187e4b3357c369455e7/.postcssrc.js -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hj624608494/vue-shopping-mall/0b7fb8ec5de776aef3935187e4b3357c369455e7/README.md -------------------------------------------------------------------------------- /build/build.js: -------------------------------------------------------------------------------- 1 | require('./check-versions')() 2 | 3 | process.env.NODE_ENV = 'production' 4 | 5 | var ora = require('ora') 6 | var rm = require('rimraf') 7 | var path = require('path') 8 | var chalk = require('chalk') 9 | var webpack = require('webpack') 10 | var config = require('../config') 11 | var webpackConfig = require('./webpack.prod.conf') 12 | 13 | var spinner = ora('building for production...') 14 | spinner.start() 15 | 16 | rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { 17 | if (err) throw err 18 | webpack(webpackConfig, function (err, stats) { 19 | spinner.stop() 20 | if (err) throw err 21 | process.stdout.write(stats.toString({ 22 | colors: true, 23 | modules: false, 24 | children: false, 25 | chunks: false, 26 | chunkModules: false 27 | }) + '\n\n') 28 | 29 | console.log(chalk.cyan(' Build complete.\n')) 30 | console.log(chalk.yellow( 31 | ' Tip: built files are meant to be served over an HTTP server.\n' + 32 | ' Opening index.html over file:// won\'t work.\n' 33 | )) 34 | }) 35 | }) 36 | -------------------------------------------------------------------------------- /build/check-versions.js: -------------------------------------------------------------------------------- 1 | var chalk = require('chalk') 2 | var semver = require('semver') 3 | var packageConfig = require('../package.json') 4 | 5 | function exec (cmd) { 6 | return require('child_process').execSync(cmd).toString().trim() 7 | } 8 | 9 | var versionRequirements = [ 10 | { 11 | name: 'node', 12 | currentVersion: semver.clean(process.version), 13 | versionRequirement: packageConfig.engines.node 14 | }, 15 | { 16 | name: 'npm', 17 | currentVersion: exec('npm --version'), 18 | versionRequirement: packageConfig.engines.npm 19 | } 20 | ] 21 | 22 | module.exports = function () { 23 | var warnings = [] 24 | for (var i = 0; i < versionRequirements.length; i++) { 25 | var mod = versionRequirements[i] 26 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { 27 | warnings.push(mod.name + ': ' + 28 | chalk.red(mod.currentVersion) + ' should be ' + 29 | chalk.green(mod.versionRequirement) 30 | ) 31 | } 32 | } 33 | 34 | if (warnings.length) { 35 | console.log('') 36 | console.log(chalk.yellow('To use this template, you must update following to modules:')) 37 | console.log() 38 | for (var i = 0; i < warnings.length; i++) { 39 | var warning = warnings[i] 40 | console.log(' ' + warning) 41 | } 42 | console.log() 43 | process.exit(1) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /build/dev-client.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | require('eventsource-polyfill') 3 | var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true') 4 | 5 | hotClient.subscribe(function (event) { 6 | if (event.action === 'reload') { 7 | window.location.reload() 8 | } 9 | }) 10 | -------------------------------------------------------------------------------- /build/dev-server.js: -------------------------------------------------------------------------------- 1 | require('./check-versions')() 2 | 3 | var config = require('../config') 4 | if (!process.env.NODE_ENV) { 5 | process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV) 6 | } 7 | 8 | var opn = require('opn') 9 | var path = require('path') 10 | var express = require('express') 11 | var webpack = require('webpack') 12 | var proxyMiddleware = require('http-proxy-middleware') 13 | var webpackConfig = process.env.NODE_ENV === 'testing' 14 | ? require('./webpack.prod.conf') 15 | : require('./webpack.dev.conf') 16 | 17 | // default port where dev server listens for incoming traffic 18 | var port = process.env.PORT || config.dev.port 19 | // automatically open browser, if not set will be false 20 | var autoOpenBrowser = !!config.dev.autoOpenBrowser 21 | // Define HTTP proxies to your custom API backend 22 | // https://github.com/chimurai/http-proxy-middleware 23 | var proxyTable = config.dev.proxyTable 24 | 25 | var app = express() 26 | var compiler = webpack(webpackConfig) 27 | 28 | var devMiddleware = require('webpack-dev-middleware')(compiler, { 29 | publicPath: webpackConfig.output.publicPath, 30 | quiet: true 31 | }) 32 | 33 | var hotMiddleware = require('webpack-hot-middleware')(compiler, { 34 | log: () => {} 35 | }) 36 | // force page reload when html-webpack-plugin template changes 37 | compiler.plugin('compilation', function (compilation) { 38 | compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) { 39 | hotMiddleware.publish({ action: 'reload' }) 40 | cb() 41 | }) 42 | }) 43 | 44 | // proxy api requests 45 | Object.keys(proxyTable).forEach(function (context) { 46 | var options = proxyTable[context] 47 | if (typeof options === 'string') { 48 | options = { target: options } 49 | } 50 | app.use(proxyMiddleware(options.filter || context, options)) 51 | }) 52 | 53 | // handle fallback for HTML5 history API 54 | app.use(require('connect-history-api-fallback')()) 55 | 56 | // serve webpack bundle output 57 | app.use(devMiddleware) 58 | 59 | // enable hot-reload and state-preserving 60 | // compilation error display 61 | app.use(hotMiddleware) 62 | 63 | // serve pure static assets 64 | var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory) 65 | app.use(staticPath, express.static('./static')) 66 | 67 | var uri = 'http://localhost:' + port 68 | 69 | devMiddleware.waitUntilValid(function () { 70 | console.log('> Listening at ' + uri + '\n') 71 | }) 72 | 73 | module.exports = app.listen(port, function (err) { 74 | if (err) { 75 | console.log(err) 76 | return 77 | } 78 | 79 | // when env is testing, don't need open it 80 | if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') { 81 | opn(uri) 82 | } 83 | }) 84 | -------------------------------------------------------------------------------- /build/utils.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var config = require('../config') 3 | var ExtractTextPlugin = require('extract-text-webpack-plugin') 4 | 5 | exports.assetsPath = function (_path) { 6 | var assetsSubDirectory = process.env.NODE_ENV === 'production' 7 | ? config.build.assetsSubDirectory 8 | : config.dev.assetsSubDirectory 9 | return path.posix.join(assetsSubDirectory, _path) 10 | } 11 | 12 | exports.cssLoaders = function (options) { 13 | options = options || {} 14 | 15 | var cssLoader = { 16 | loader: 'css-loader', 17 | options: { 18 | minimize: process.env.NODE_ENV === 'production', 19 | sourceMap: options.sourceMap 20 | } 21 | } 22 | 23 | // generate loader string to be used with extract text plugin 24 | function generateLoaders (loader, loaderOptions) { 25 | var loaders = [cssLoader] 26 | if (loader) { 27 | loaders.push({ 28 | loader: loader + '-loader', 29 | options: Object.assign({}, loaderOptions, { 30 | sourceMap: options.sourceMap 31 | }) 32 | }) 33 | } 34 | 35 | // Extract CSS when that option is specified 36 | // (which is the case during production build) 37 | if (options.extract) { 38 | return ExtractTextPlugin.extract({ 39 | use: loaders, 40 | fallback: 'vue-style-loader' 41 | }) 42 | } else { 43 | return ['vue-style-loader'].concat(loaders) 44 | } 45 | } 46 | 47 | // http://vuejs.github.io/vue-loader/en/configurations/extract-css.html 48 | return { 49 | css: generateLoaders(), 50 | postcss: generateLoaders(), 51 | less: generateLoaders('less'), 52 | sass: generateLoaders('sass', { indentedSyntax: true }), 53 | scss: generateLoaders('sass'), 54 | stylus: generateLoaders('stylus'), 55 | styl: generateLoaders('stylus') 56 | } 57 | } 58 | 59 | // Generate loaders for standalone style files (outside of .vue) 60 | exports.styleLoaders = function (options) { 61 | var output = [] 62 | var loaders = exports.cssLoaders(options) 63 | for (var extension in loaders) { 64 | var loader = loaders[extension] 65 | output.push({ 66 | test: new RegExp('\\.' + extension + '$'), 67 | use: loader 68 | }) 69 | } 70 | return output 71 | } 72 | -------------------------------------------------------------------------------- /build/vue-loader.conf.js: -------------------------------------------------------------------------------- 1 | var utils = require('./utils') 2 | var config = require('../config') 3 | var isProduction = process.env.NODE_ENV === 'production' 4 | 5 | module.exports = { 6 | loaders: utils.cssLoaders({ 7 | sourceMap: isProduction 8 | ? config.build.productionSourceMap 9 | : config.dev.cssSourceMap, 10 | extract: isProduction 11 | }) 12 | } 13 | -------------------------------------------------------------------------------- /build/webpack.base.conf.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var utils = require('./utils') 3 | var config = require('../config') 4 | var vueLoaderConfig = require('./vue-loader.conf') 5 | 6 | function resolve (dir) { 7 | return path.join(__dirname, '..', dir) 8 | } 9 | 10 | module.exports = { 11 | entry: { 12 | app: './src/main.js' 13 | }, 14 | output: { 15 | path: config.build.assetsRoot, 16 | filename: '[name].js', 17 | publicPath: process.env.NODE_ENV === 'production' 18 | ? config.build.assetsPublicPath 19 | : config.dev.assetsPublicPath 20 | }, 21 | resolve: { 22 | extensions: ['.js', '.vue', '.json'], 23 | alias: { 24 | 'vue$': 'vue/dist/vue.esm.js', 25 | '@': resolve('src'), 26 | } 27 | }, 28 | module: { 29 | rules: [ 30 | // { 31 | // test: /\.(js|vue)$/, 32 | // loader: 'eslint-loader', 33 | // enforce: "pre", 34 | // include: [resolve('src'), resolve('test')], 35 | // options: { 36 | // formatter: require('eslint-friendly-formatter') 37 | // } 38 | // }, 39 | { 40 | test: /\.vue$/, 41 | loader: 'vue-loader', 42 | options: vueLoaderConfig 43 | }, 44 | { 45 | test: /\.js$/, 46 | loader: 'babel-loader', 47 | include: [resolve('src'), resolve('test')] 48 | }, 49 | { 50 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, 51 | loader: 'url-loader', 52 | query: { 53 | limit: 10000, 54 | name: utils.assetsPath('img/[name].[hash:7].[ext]') 55 | } 56 | }, 57 | { 58 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 59 | loader: 'url-loader', 60 | query: { 61 | limit: 10000, 62 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]') 63 | } 64 | }, 65 | //iview 66 | { test: /iview.src.*?js$/, loader: 'babel-loader' }, 67 | { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ } 68 | ] 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /build/webpack.dev.conf.js: -------------------------------------------------------------------------------- 1 | var utils = require('./utils') 2 | var webpack = require('webpack') 3 | var config = require('../config') 4 | var merge = require('webpack-merge') 5 | var baseWebpackConfig = require('./webpack.base.conf') 6 | var HtmlWebpackPlugin = require('html-webpack-plugin') 7 | var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') 8 | 9 | // add hot-reload related code to entry chunks 10 | Object.keys(baseWebpackConfig.entry).forEach(function (name) { 11 | baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name]) 12 | }) 13 | 14 | module.exports = merge(baseWebpackConfig, { 15 | module: { 16 | rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap }) 17 | }, 18 | // cheap-module-eval-source-map is faster for development 19 | devtool: '#cheap-module-eval-source-map', 20 | plugins: [ 21 | new webpack.DefinePlugin({ 22 | 'process.env': config.dev.env 23 | }), 24 | // https://github.com/glenjamin/webpack-hot-middleware#installation--usage 25 | new webpack.HotModuleReplacementPlugin(), 26 | new webpack.NoEmitOnErrorsPlugin(), 27 | // https://github.com/ampedandwired/html-webpack-plugin 28 | new HtmlWebpackPlugin({ 29 | filename: 'index.html', 30 | template: 'index.html', 31 | inject: true 32 | }), 33 | new FriendlyErrorsPlugin() 34 | ] 35 | }) 36 | -------------------------------------------------------------------------------- /build/webpack.prod.conf.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var utils = require('./utils') 3 | var webpack = require('webpack') 4 | var config = require('../config') 5 | var merge = require('webpack-merge') 6 | var baseWebpackConfig = require('./webpack.base.conf') 7 | var CopyWebpackPlugin = require('copy-webpack-plugin') 8 | var HtmlWebpackPlugin = require('html-webpack-plugin') 9 | var ExtractTextPlugin = require('extract-text-webpack-plugin') 10 | var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') 11 | 12 | var env = process.env.NODE_ENV === 'testing' 13 | ? require('../config/test.env') 14 | : config.build.env 15 | 16 | var webpackConfig = merge(baseWebpackConfig, { 17 | module: { 18 | rules: utils.styleLoaders({ 19 | sourceMap: config.build.productionSourceMap, 20 | extract: true 21 | }) 22 | }, 23 | devtool: config.build.productionSourceMap ? '#source-map' : false, 24 | output: { 25 | path: config.build.assetsRoot, 26 | filename: utils.assetsPath('js/[name].[chunkhash].js'), 27 | chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') 28 | }, 29 | plugins: [ 30 | // http://vuejs.github.io/vue-loader/en/workflow/production.html 31 | new webpack.DefinePlugin({ 32 | 'process.env': env 33 | }), 34 | new webpack.optimize.UglifyJsPlugin({ 35 | compress: { 36 | warnings: false 37 | }, 38 | sourceMap: true 39 | }), 40 | // extract css into its own file 41 | new ExtractTextPlugin({ 42 | filename: utils.assetsPath('css/[name].[contenthash].css') 43 | }), 44 | // Compress extracted CSS. We are using this plugin so that possible 45 | // duplicated CSS from different components can be deduped. 46 | new OptimizeCSSPlugin(), 47 | // generate dist index.html with correct asset hash for caching. 48 | // you can customize output by editing /index.html 49 | // see https://github.com/ampedandwired/html-webpack-plugin 50 | new HtmlWebpackPlugin({ 51 | filename: process.env.NODE_ENV === 'testing' 52 | ? 'index.html' 53 | : config.build.index, 54 | template: 'index.html', 55 | inject: true, 56 | minify: { 57 | removeComments: true, 58 | collapseWhitespace: true, 59 | removeAttributeQuotes: true 60 | // more options: 61 | // https://github.com/kangax/html-minifier#options-quick-reference 62 | }, 63 | // necessary to consistently work with multiple chunks via CommonsChunkPlugin 64 | chunksSortMode: 'dependency' 65 | }), 66 | // split vendor js into its own file 67 | new webpack.optimize.CommonsChunkPlugin({ 68 | name: 'vendor', 69 | minChunks: function (module, count) { 70 | // any required modules inside node_modules are extracted to vendor 71 | return ( 72 | module.resource && 73 | /\.js$/.test(module.resource) && 74 | module.resource.indexOf( 75 | path.join(__dirname, '../node_modules') 76 | ) === 0 77 | ) 78 | } 79 | }), 80 | // extract webpack runtime and module manifest to its own file in order to 81 | // prevent vendor hash from being updated whenever app bundle is updated 82 | new webpack.optimize.CommonsChunkPlugin({ 83 | name: 'manifest', 84 | chunks: ['vendor'] 85 | }), 86 | // copy custom static assets 87 | new CopyWebpackPlugin([ 88 | { 89 | from: path.resolve(__dirname, '../static'), 90 | to: config.build.assetsSubDirectory, 91 | ignore: ['.*'] 92 | } 93 | ]) 94 | ] 95 | }) 96 | 97 | if (config.build.productionGzip) { 98 | var CompressionWebpackPlugin = require('compression-webpack-plugin') 99 | 100 | webpackConfig.plugins.push( 101 | new CompressionWebpackPlugin({ 102 | asset: '[path].gz[query]', 103 | algorithm: 'gzip', 104 | test: new RegExp( 105 | '\\.(' + 106 | config.build.productionGzipExtensions.join('|') + 107 | ')$' 108 | ), 109 | threshold: 10240, 110 | minRatio: 0.8 111 | }) 112 | ) 113 | } 114 | 115 | if (config.build.bundleAnalyzerReport) { 116 | var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin 117 | webpackConfig.plugins.push(new BundleAnalyzerPlugin()) 118 | } 119 | 120 | module.exports = webpackConfig 121 | -------------------------------------------------------------------------------- /build/webpack.test.conf.js: -------------------------------------------------------------------------------- 1 | // This is the webpack config used for unit tests. 2 | 3 | var utils = require('./utils') 4 | var webpack = require('webpack') 5 | var merge = require('webpack-merge') 6 | var baseConfig = require('./webpack.base.conf') 7 | 8 | var webpackConfig = merge(baseConfig, { 9 | // use inline sourcemap for karma-sourcemap-loader 10 | module: { 11 | rules: utils.styleLoaders() 12 | }, 13 | devtool: '#inline-source-map', 14 | plugins: [ 15 | new webpack.DefinePlugin({ 16 | 'process.env': require('../config/test.env') 17 | }) 18 | ] 19 | }) 20 | 21 | // no need for app entry during tests 22 | delete webpackConfig.entry 23 | 24 | module.exports = webpackConfig 25 | -------------------------------------------------------------------------------- /config/dev.env.js: -------------------------------------------------------------------------------- 1 | var merge = require('webpack-merge') 2 | var prodEnv = require('./prod.env') 3 | 4 | module.exports = merge(prodEnv, { 5 | NODE_ENV: '"development"' 6 | }) 7 | -------------------------------------------------------------------------------- /config/index.js: -------------------------------------------------------------------------------- 1 | // see http://vuejs-templates.github.io/webpack for documentation. 2 | var path = require('path') 3 | 4 | module.exports = { 5 | build: { 6 | env: require('./prod.env'), 7 | index: path.resolve(__dirname, '../dist/index.html'), 8 | assetsRoot: path.resolve(__dirname, '../dist'), 9 | assetsSubDirectory: 'index', 10 | assetsPublicPath: '/', 11 | productionSourceMap: true, 12 | // Gzip off by default as many popular static hosts such as 13 | // Surge or Netlify already gzip all static assets for you. 14 | // Before setting to `true`, make sure to: 15 | // npm install --save-dev compression-webpack-plugin 16 | productionGzip: false, 17 | productionGzipExtensions: ['js', 'css'], 18 | // Run the build command with an extra argument to 19 | // View the bundle analyzer report after build finishes: 20 | // `npm run build --report` 21 | // Set to `true` or `false` to always turn it on or off 22 | bundleAnalyzerReport: process.env.npm_config_report 23 | }, 24 | dev: { 25 | env: require('./dev.env'), 26 | port: 8080, 27 | autoOpenBrowser: true, 28 | assetsSubDirectory: 'static', 29 | assetsPublicPath: '/', 30 | proxyTable: {}, 31 | // CSS Sourcemaps off by default because relative paths are "buggy" 32 | // with this option, according to the CSS-Loader README 33 | // (https://github.com/webpack/css-loader#sourcemaps) 34 | // In our experience, they generally work as expected, 35 | // just be aware of this issue when enabling this option. 36 | cssSourceMap: false 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /config/prod.env.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | NODE_ENV: '"production"' 3 | } 4 | -------------------------------------------------------------------------------- /config/test.env.js: -------------------------------------------------------------------------------- 1 | var merge = require('webpack-merge') 2 | var devEnv = require('./dev.env') 3 | 4 | module.exports = merge(devEnv, { 5 | NODE_ENV: '"testing"' 6 | }) 7 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 窝创 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sky", 3 | "version": "1.0.0", 4 | "description": "A Vue.js project", 5 | "author": "sky", 6 | "private": true, 7 | "scripts": { 8 | "dev": "node build/dev-server.js", 9 | "build": "node build/build.js", 10 | "unit": "cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run", 11 | "e2e": "node test/e2e/runner.js", 12 | "test": "npm run unit && npm run e2e", 13 | "lint": "eslint --ext .js,.vue src test/unit/specs test/e2e/specs" 14 | }, 15 | "dependencies": { 16 | "axios": "^0.15.3", 17 | "iview": "^2.0.0-rc.6", 18 | "qart": "^0.0.2", 19 | "qartjs": "^1.1.1", 20 | "vue": "^2.2.1", 21 | "vue-progressbar": "^0.7.1", 22 | "vue-qart": "^2.0.0", 23 | "vue-router": "^2.2.0", 24 | "webpack-zepto": "^0.0.1" 25 | }, 26 | "devDependencies": { 27 | "autoprefixer": "^6.7.2", 28 | "axios": "^0.15.3", 29 | "babel-core": "^6.22.1", 30 | "babel-eslint": "^7.1.1", 31 | "babel-loader": "^6.2.10", 32 | "babel-plugin-istanbul": "^3.1.2", 33 | "babel-plugin-transform-runtime": "^6.22.0", 34 | "babel-preset-latest": "^6.22.0", 35 | "babel-preset-stage-2": "^6.22.0", 36 | "babel-register": "^6.22.0", 37 | "chai": "^3.5.0", 38 | "chalk": "^1.1.3", 39 | "chromedriver": "^2.27.2", 40 | "connect-history-api-fallback": "^1.3.0", 41 | "copy-webpack-plugin": "^4.0.1", 42 | "cross-env": "^3.1.4", 43 | "cross-spawn": "^5.0.1", 44 | "css-loader": "^0.26.1", 45 | "eslint": "^3.14.1", 46 | "eslint-config-standard": "^6.2.1", 47 | "eslint-friendly-formatter": "^2.0.7", 48 | "eslint-loader": "^1.6.1", 49 | "eslint-plugin-html": "^2.0.0", 50 | "eslint-plugin-promise": "^3.4.0", 51 | "eslint-plugin-standard": "^2.0.1", 52 | "eventsource-polyfill": "^0.9.6", 53 | "express": "^4.14.1", 54 | "extract-text-webpack-plugin": "^2.0.0", 55 | "file-loader": "^0.10.0", 56 | "friendly-errors-webpack-plugin": "^1.1.3", 57 | "function-bind": "^1.1.0", 58 | "html-webpack-plugin": "^2.28.0", 59 | "http-proxy-middleware": "^0.17.3", 60 | "inject-loader": "^2.0.1", 61 | "karma": "^1.4.1", 62 | "karma-coverage": "^1.1.1", 63 | "karma-mocha": "^1.3.0", 64 | "karma-phantomjs-launcher": "^1.0.2", 65 | "karma-sinon-chai": "^1.2.4", 66 | "karma-sourcemap-loader": "^0.3.7", 67 | "karma-spec-reporter": "0.0.26", 68 | "karma-webpack": "^2.0.2", 69 | "lolex": "^1.5.2", 70 | "mocha": "^3.2.0", 71 | "nightwatch": "^0.9.12", 72 | "node-sass": "^4.5.0", 73 | "opn": "^4.0.2", 74 | "optimize-css-assets-webpack-plugin": "^1.3.0", 75 | "ora": "^1.1.0", 76 | "phantomjs-prebuilt": "^2.1.14", 77 | "rimraf": "^2.6.0", 78 | "sass-loader": "^6.0.2", 79 | "selenium-server": "^3.0.1", 80 | "semver": "^5.3.0", 81 | "sinon": "^1.17.7", 82 | "sinon-chai": "^2.8.0", 83 | "url-loader": "^0.5.8", 84 | "vue-loader": "^11.0.0", 85 | "vue-style-loader": "^2.0.0", 86 | "vue-template-compiler": "^2.2.1", 87 | "webpack": "^2.2.1", 88 | "webpack-bundle-analyzer": "^2.2.1", 89 | "webpack-dev-middleware": "^1.10.0", 90 | "webpack-hot-middleware": "^2.16.1", 91 | "webpack-merge": "^2.6.1" 92 | }, 93 | "engines": { 94 | "node": ">= 4.0.0", 95 | "npm": ">= 3.0.0" 96 | }, 97 | "browserlist": [ 98 | "> 1%", 99 | "last 2 versions", 100 | "not ie <= 8" 101 | ], 102 | "main": ".eslintrc.js", 103 | "directories": { 104 | "test": "test" 105 | }, 106 | "license": "ISC" 107 | } 108 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sky", 3 | "version": "1.0.0", 4 | "description": "A Vue.js project", 5 | "author": "sky", 6 | "private": true, 7 | "scripts": { 8 | "dev": "node build/dev-server.js", 9 | "build": "node build/build.js", 10 | "unit": "cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run", 11 | "e2e": "node test/e2e/runner.js", 12 | "test": "npm run unit && npm run e2e", 13 | "lint": "eslint --ext .js,.vue src test/unit/specs test/e2e/specs" 14 | }, 15 | "dependencies": { 16 | "axios": "^0.15.3", 17 | "iview": "^2.0.0-rc.6", 18 | "qart": "^0.0.2", 19 | "qartjs": "^1.1.1", 20 | "vue": "^2.2.1", 21 | "vue-progressbar": "^0.7.1", 22 | "vue-qart": "^2.0.0", 23 | "vue-router": "^2.2.0", 24 | "webpack-zepto": "^0.0.1" 25 | }, 26 | "devDependencies": { 27 | "autoprefixer": "^6.7.2", 28 | "axios": "^0.15.3", 29 | "babel-core": "^6.22.1", 30 | "babel-eslint": "^7.1.1", 31 | "babel-loader": "^6.2.10", 32 | "babel-plugin-istanbul": "^3.1.2", 33 | "babel-plugin-transform-runtime": "^6.22.0", 34 | "babel-preset-latest": "^6.22.0", 35 | "babel-preset-stage-2": "^6.22.0", 36 | "babel-register": "^6.22.0", 37 | "chai": "^3.5.0", 38 | "chalk": "^1.1.3", 39 | "chromedriver": "^2.27.2", 40 | "connect-history-api-fallback": "^1.3.0", 41 | "copy-webpack-plugin": "^4.0.1", 42 | "cross-env": "^3.1.4", 43 | "cross-spawn": "^5.0.1", 44 | "css-loader": "^0.26.1", 45 | "eslint": "^3.14.1", 46 | "eslint-config-standard": "^6.2.1", 47 | "eslint-friendly-formatter": "^2.0.7", 48 | "eslint-loader": "^1.6.1", 49 | "eslint-plugin-html": "^2.0.0", 50 | "eslint-plugin-promise": "^3.4.0", 51 | "eslint-plugin-standard": "^2.0.1", 52 | "eventsource-polyfill": "^0.9.6", 53 | "express": "^4.14.1", 54 | "extract-text-webpack-plugin": "^2.0.0", 55 | "file-loader": "^0.10.0", 56 | "friendly-errors-webpack-plugin": "^1.1.3", 57 | "function-bind": "^1.1.0", 58 | "html-webpack-plugin": "^2.28.0", 59 | "http-proxy-middleware": "^0.17.3", 60 | "inject-loader": "^2.0.1", 61 | "karma": "^1.4.1", 62 | "karma-coverage": "^1.1.1", 63 | "karma-mocha": "^1.3.0", 64 | "karma-phantomjs-launcher": "^1.0.2", 65 | "karma-sinon-chai": "^1.2.4", 66 | "karma-sourcemap-loader": "^0.3.7", 67 | "karma-spec-reporter": "0.0.26", 68 | "karma-webpack": "^2.0.2", 69 | "lolex": "^1.5.2", 70 | "mocha": "^3.2.0", 71 | "nightwatch": "^0.9.12", 72 | "node-sass": "^4.5.0", 73 | "opn": "^4.0.2", 74 | "optimize-css-assets-webpack-plugin": "^1.3.0", 75 | "ora": "^1.1.0", 76 | "phantomjs-prebuilt": "^2.1.14", 77 | "rimraf": "^2.6.0", 78 | "sass-loader": "^6.0.2", 79 | "selenium-server": "^3.0.1", 80 | "semver": "^5.3.0", 81 | "sinon": "^1.17.7", 82 | "sinon-chai": "^2.8.0", 83 | "url-loader": "^0.5.8", 84 | "vue-loader": "^11.0.0", 85 | "vue-style-loader": "^2.0.0", 86 | "vue-template-compiler": "^2.2.1", 87 | "webpack": "^2.2.1", 88 | "webpack-bundle-analyzer": "^2.2.1", 89 | "webpack-dev-middleware": "^1.10.0", 90 | "webpack-hot-middleware": "^2.16.1", 91 | "webpack-merge": "^2.6.1" 92 | }, 93 | "engines": { 94 | "node": ">= 4.0.0", 95 | "npm": ">= 3.0.0" 96 | }, 97 | "browserlist": [ 98 | "> 1%", 99 | "last 2 versions", 100 | "not ie <= 8" 101 | ], 102 | "main": ".eslintrc.js", 103 | "directories": { 104 | "test": "test" 105 | }, 106 | "license": "ISC" 107 | } 108 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 53 | 152 | 153 | 240 | -------------------------------------------------------------------------------- /src/assets/css/commond.css: -------------------------------------------------------------------------------- 1 | body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, dl, dt, dd, ul, ol, li, pre, form, fieldset, legend, button, input, textarea, th, td { margin:0; padding:0; box-sizing: border-box;background-repeat:no-repeat;} 2 | body, button, input, select, textarea { font:12px/1.5tahoma, arial, \5b8b\4f53; } 3 | h1, h2, h3, h4, h5, h6{ font-size:100%; } 4 | address, cite, dfn, em, var { font-style:normal; } 5 | code, kbd, pre, samp { font-family:couriernew, courier, monospace; } 6 | small{ font-size:12px; } 7 | ul, ol { list-style:none; } 8 | a {color:#555; text-decoration:none; } 9 | a:hover,a:link,a:visited{color:#555; text-decoration:none; } 10 | sup { vertical-align:text-top; } 11 | sub{ vertical-align:text-bottom; } 12 | legend { color:#000; } 13 | fieldset, img { border:0; } 14 | button, input, select, textarea { font-size:100%; } 15 | table { border-collapse:collapse; border-spacing:0; } 16 | *{box-sizing: border-box;} 17 | ::-webkit-input-placeholder{color:#888888;} 18 | .w-960{ 19 | width:960px; 20 | margin:0 auto; 21 | } 22 | .ui-login{ 23 | position:fixed; 24 | left:0; 25 | right:0; 26 | top:0; 27 | bottom:0; 28 | background-color:rgba(0,0,0,.6); 29 | z-index:200; 30 | } 31 | .ui-over-h{ 32 | overflow: hidden; 33 | } 34 | .ui-t-j{ 35 | text-align: justify; 36 | } 37 | .ui-login>.ui-login-box{ 38 | background-color:#fff; 39 | position:absolute; 40 | top:45%; 41 | left:50%; 42 | transform:translate(-50%,-50%); 43 | z-index: 201; 44 | padding:45px 30px 30px; 45 | 46 | } 47 | .ui-pos-r{position:relative;} 48 | .ui-pos-a{position:absolute;} 49 | .ui-pos-f{position:fixed;} 50 | .ui-just::after{ 51 | content:""; 52 | width:100%; 53 | height:0; 54 | display:inline-block; 55 | text-align:justify; 56 | } 57 | .ui-ver-md{vertical-align: middle} 58 | .ui-ver-m::after{ 59 | content:""; 60 | width:0; 61 | height:100%; 62 | display:inline-block; 63 | vertical-align: middle; 64 | } 65 | .ui-clear::after{ 66 | content:""; 67 | width:0; 68 | height:0; 69 | display:block; 70 | clear:both; 71 | } 72 | 73 | .ui-fl{float:left;} 74 | .ui-fr{float:right;} 75 | .ui-dis-ib{display:inline-block;} 76 | .ui-dis-i{display:inline;} 77 | .ui-dis-b{display:block;} 78 | /*加载中占位*/ 79 | .ld,.ld-30,.ld-50,.ld-70,.ld-100,.ld-200,.ld-300,.ld-400,.ld-500,.ld-600,.ld-1000{ 80 | background-color:#f8f8f8 !important; 81 | } 82 | .ld-30{ 83 | height:30px !important; 84 | } 85 | .ld-50{ 86 | height: 50px !important; 87 | } 88 | .ld-70{ 89 | height: 70px !important; 90 | } 91 | .ld-100{ 92 | height: 100px !important; 93 | } 94 | .ld-200{ 95 | height: 200px !important; 96 | } 97 | .ld-300{ 98 | height: 300px !important; 99 | } 100 | .ld-400{ 101 | height: 400px !important; 102 | } 103 | .ld-500{ 104 | height: 500px !important; 105 | } 106 | .ld-600{ 107 | height: 600PX !important; 108 | } 109 | .ld-1000{ 110 | height: 1000px !important; 111 | } 112 | -------------------------------------------------------------------------------- /src/assets/images/2017-03-18_111001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hj624608494/vue-shopping-mall/0b7fb8ec5de776aef3935187e4b3357c369455e7/src/assets/images/2017-03-18_111001.png -------------------------------------------------------------------------------- /src/assets/images/2017-03-18_164100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hj624608494/vue-shopping-mall/0b7fb8ec5de776aef3935187e4b3357c369455e7/src/assets/images/2017-03-18_164100.png -------------------------------------------------------------------------------- /src/assets/images/LOGO Text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hj624608494/vue-shopping-mall/0b7fb8ec5de776aef3935187e4b3357c369455e7/src/assets/images/LOGO Text.png -------------------------------------------------------------------------------- /src/assets/images/Worm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hj624608494/vue-shopping-mall/0b7fb8ec5de776aef3935187e4b3357c369455e7/src/assets/images/Worm.png -------------------------------------------------------------------------------- /src/assets/images/alipay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hj624608494/vue-shopping-mall/0b7fb8ec5de776aef3935187e4b3357c369455e7/src/assets/images/alipay.png -------------------------------------------------------------------------------- /src/assets/images/alipayma.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hj624608494/vue-shopping-mall/0b7fb8ec5de776aef3935187e4b3357c369455e7/src/assets/images/alipayma.png -------------------------------------------------------------------------------- /src/assets/images/checked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hj624608494/vue-shopping-mall/0b7fb8ec5de776aef3935187e4b3357c369455e7/src/assets/images/checked.png -------------------------------------------------------------------------------- /src/assets/images/goods.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hj624608494/vue-shopping-mall/0b7fb8ec5de776aef3935187e4b3357c369455e7/src/assets/images/goods.jpg -------------------------------------------------------------------------------- /src/assets/images/index-class_03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hj624608494/vue-shopping-mall/0b7fb8ec5de776aef3935187e4b3357c369455e7/src/assets/images/index-class_03.jpg -------------------------------------------------------------------------------- /src/assets/images/index-class_05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hj624608494/vue-shopping-mall/0b7fb8ec5de776aef3935187e4b3357c369455e7/src/assets/images/index-class_05.png -------------------------------------------------------------------------------- /src/assets/images/index-class_08.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hj624608494/vue-shopping-mall/0b7fb8ec5de776aef3935187e4b3357c369455e7/src/assets/images/index-class_08.jpg -------------------------------------------------------------------------------- /src/assets/images/index-class_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hj624608494/vue-shopping-mall/0b7fb8ec5de776aef3935187e4b3357c369455e7/src/assets/images/index-class_11.png -------------------------------------------------------------------------------- /src/assets/images/index-hd_03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hj624608494/vue-shopping-mall/0b7fb8ec5de776aef3935187e4b3357c369455e7/src/assets/images/index-hd_03.png -------------------------------------------------------------------------------- /src/assets/images/index-sp_03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hj624608494/vue-shopping-mall/0b7fb8ec5de776aef3935187e4b3357c369455e7/src/assets/images/index-sp_03.png -------------------------------------------------------------------------------- /src/assets/images/index-sp_05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hj624608494/vue-shopping-mall/0b7fb8ec5de776aef3935187e4b3357c369455e7/src/assets/images/index-sp_05.png -------------------------------------------------------------------------------- /src/assets/images/index-sp_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hj624608494/vue-shopping-mall/0b7fb8ec5de776aef3935187e4b3357c369455e7/src/assets/images/index-sp_10.png -------------------------------------------------------------------------------- /src/assets/images/left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hj624608494/vue-shopping-mall/0b7fb8ec5de776aef3935187e4b3357c369455e7/src/assets/images/left.png -------------------------------------------------------------------------------- /src/assets/images/middle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hj624608494/vue-shopping-mall/0b7fb8ec5de776aef3935187e4b3357c369455e7/src/assets/images/middle.png -------------------------------------------------------------------------------- /src/assets/images/right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hj624608494/vue-shopping-mall/0b7fb8ec5de776aef3935187e4b3357c369455e7/src/assets/images/right.png -------------------------------------------------------------------------------- /src/assets/images/shequ_06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hj624608494/vue-shopping-mall/0b7fb8ec5de776aef3935187e4b3357c369455e7/src/assets/images/shequ_06.png -------------------------------------------------------------------------------- /src/assets/images/tj-li_03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hj624608494/vue-shopping-mall/0b7fb8ec5de776aef3935187e4b3357c369455e7/src/assets/images/tj-li_03.png -------------------------------------------------------------------------------- /src/assets/images/tj-li_05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hj624608494/vue-shopping-mall/0b7fb8ec5de776aef3935187e4b3357c369455e7/src/assets/images/tj-li_05.png -------------------------------------------------------------------------------- /src/assets/images/tj-li_07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hj624608494/vue-shopping-mall/0b7fb8ec5de776aef3935187e4b3357c369455e7/src/assets/images/tj-li_07.png -------------------------------------------------------------------------------- /src/assets/images/uncheck.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hj624608494/vue-shopping-mall/0b7fb8ec5de776aef3935187e4b3357c369455e7/src/assets/images/uncheck.png -------------------------------------------------------------------------------- /src/assets/images/weixin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hj624608494/vue-shopping-mall/0b7fb8ec5de776aef3935187e4b3357c369455e7/src/assets/images/weixin.png -------------------------------------------------------------------------------- /src/assets/images/weixinma.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hj624608494/vue-shopping-mall/0b7fb8ec5de776aef3935187e4b3357c369455e7/src/assets/images/weixinma.png -------------------------------------------------------------------------------- /src/assets/images/weixinpay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hj624608494/vue-shopping-mall/0b7fb8ec5de776aef3935187e4b3357c369455e7/src/assets/images/weixinpay.png -------------------------------------------------------------------------------- /src/assets/images/支付成功.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hj624608494/vue-shopping-mall/0b7fb8ec5de776aef3935187e4b3357c369455e7/src/assets/images/支付成功.png -------------------------------------------------------------------------------- /src/assets/js/ajax.js: -------------------------------------------------------------------------------- 1 | import Qs from 'qs'; 2 | import cf from "./serverUrl" 3 | export default{ 4 | /*格式化 5 | encodeURIComponent()编码 6 | decodeURIComponent()解码 7 | */ 8 | parse(obj){ 9 | if(!obj)return; 10 | let arr=[]; 11 | for(let key in obj){ 12 | arr.push(key+"="+obj[key]); 13 | } 14 | return arr.join("&"); 15 | }, 16 | decode(str){ 17 | let obj={}; 18 | let a=str.split("&"); 19 | a.forEach(function(val,index){ 20 | obj[val.split("=")[0]]=val.split("=")[1]; 21 | }); 22 | return obj; 23 | }, 24 | //配置axios 25 | http(t,obj){ 26 | if(!obj)return; 27 | let config={ 28 | url:obj.url.trim()||'', 29 | method:obj.type||'get', 30 | // 基本路径 31 | baseURL:cf.baseURL, 32 | transformRequest:[function(data){ 33 | return Qs.stringify(data); 34 | }], 35 | transformResponse:[function(data){ 36 | return Qs.parse(data); 37 | }], 38 | headers: { 39 | 'Content-Type': 'application/x-www-form-urlencoded', 40 | }, 41 | params:obj.params||null, 42 | paramsSerializer: function(params) { 43 | return Qs.stringify(params, {arrayFormat: 'brackets'}) 44 | }, 45 | data:obj.data||{}, 46 | timeout:5000, 47 | withCredentials :false, 48 | responseType:obj.dataType || "json", 49 | maxContentLength:2000, 50 | validateStatus:function(status){ 51 | return status>=200 && status<300; 52 | } 53 | } 54 | return t.axios(config); 55 | }, 56 | get(t,obj){ 57 | let tt=this; 58 | let par=obj.params||null; 59 | let _url=obj.url+(par?'?'+tt.parse(par):''); 60 | return t.axios.get(_url); 61 | }, 62 | //并行请求 63 | all(t,arr){ 64 | if(arr&&(arr.length<1||!arr[0].url))return; 65 | let a=[]; 66 | let _this=this; 67 | arr.forEach(function(val,key){ 68 | a.push(val.url+(val.params?"?"+_this.parse(val.params):'')) 69 | }) 70 | a=a.map(function(val){ 71 | return t.axios.get(val); 72 | }) 73 | 74 | return t.axios.all(a); 75 | }, 76 | $http(t,obj,cb,error){ 77 | let tt=this; 78 | tt.http(t,obj).then(function(resp){ 79 | let _resp=resp.data; 80 | // console.log(resp) 81 | cb&&cb(_resp); 82 | }).catch(function(err){ 83 | console.log(err) 84 | error&&error(err); 85 | }) 86 | }, 87 | $get(t,obj,cb,error){ 88 | let tt=this; 89 | tt.get(t,obj).then(function(resp){ 90 | let _resp=resp.data; 91 | cb&&cb(_resp) 92 | }).catch(function(err){ 93 | console.log(err) 94 | error&&error(err); 95 | }) 96 | 97 | } 98 | } -------------------------------------------------------------------------------- /src/assets/js/jquery.qrcode.js: -------------------------------------------------------------------------------- 1 | import $$ from 'webpack-zepto' 2 | (function( $ ){ 3 | 4 | $.fn.qrcode = function(options) { 5 | // if options is string, 6 | if( typeof options === 'string' ){ 7 | options = { text: options }; 8 | } 9 | 10 | // set default values 11 | // typeNumber < 1 for automatic calculation 12 | options = $.extend( {}, { 13 | render : "canvas", 14 | width : 256, 15 | height : 256, 16 | typeNumber : -1, 17 | correctLevel : QRErrorCorrectLevel.H, 18 | background : "#ffffff", 19 | foreground : "#000000" 20 | }, options); 21 | 22 | var createCanvas = function(){ 23 | // create the qrcode itself 24 | var qrcode = new QRCode(options.typeNumber, options.correctLevel); 25 | qrcode.addData(options.text); 26 | qrcode.make(); 27 | 28 | // create canvas element 29 | var canvas = document.createElement('canvas'); 30 | canvas.width = options.width; 31 | canvas.height = options.height; 32 | var ctx = canvas.getContext('2d'); 33 | 34 | // compute tileW/tileH based on options.width/options.height 35 | var tileW = options.width / qrcode.getModuleCount(); 36 | var tileH = options.height / qrcode.getModuleCount(); 37 | 38 | // draw in the canvas 39 | for( var row = 0; row < qrcode.getModuleCount(); row++ ){ 40 | for( var col = 0; col < qrcode.getModuleCount(); col++ ){ 41 | ctx.fillStyle = qrcode.isDark(row, col) ? options.foreground : options.background; 42 | var w = (Math.ceil((col+1)*tileW) - Math.floor(col*tileW)); 43 | var h = (Math.ceil((row+1)*tileW) - Math.floor(row*tileW)); 44 | ctx.fillRect(Math.round(col*tileW),Math.round(row*tileH), w, h); 45 | } 46 | } 47 | // return just built canvas 48 | return canvas; 49 | } 50 | 51 | // from Jon-Carlos Rivera (https://github.com/imbcmdth) 52 | var createTable = function(){ 53 | // create the qrcode itself 54 | var qrcode = new QRCode(options.typeNumber, options.correctLevel); 55 | qrcode.addData(options.text); 56 | qrcode.make(); 57 | 58 | // create table element 59 | var $table = $('
') 60 | .css("width", options.width+"px") 61 | .css("height", options.height+"px") 62 | .css("border", "0px") 63 | .css("border-collapse", "collapse") 64 | .css('background-color', options.background); 65 | 66 | // compute tileS percentage 67 | var tileW = options.width / qrcode.getModuleCount(); 68 | var tileH = options.height / qrcode.getModuleCount(); 69 | 70 | // draw in the table 71 | for(var row = 0; row < qrcode.getModuleCount(); row++ ){ 72 | var $row = $('').css('height', tileH+"px").appendTo($table); 73 | 74 | for(var col = 0; col < qrcode.getModuleCount(); col++ ){ 75 | $('') 76 | .css('width', tileW+"px") 77 | .css('background-color', qrcode.isDark(row, col) ? options.foreground : options.background) 78 | .appendTo($row); 79 | } 80 | } 81 | // return just built canvas 82 | return $table; 83 | } 84 | 85 | 86 | return this.each(function(){ 87 | var element = options.render == "canvas" ? createCanvas() : createTable(); 88 | $(element).appendTo(this); 89 | }); 90 | }; 91 | module.exports=$; 92 | })($$); 93 | 94 | -------------------------------------------------------------------------------- /src/assets/js/qrcode.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hj624608494/vue-shopping-mall/0b7fb8ec5de776aef3935187e4b3357c369455e7/src/assets/js/qrcode.js -------------------------------------------------------------------------------- /src/assets/js/serverUrl.js: -------------------------------------------------------------------------------- 1 | export default{ 2 | url(u){ 3 | let t=this; 4 | return t.baseURL.trim()+t[u.trim()].trim(); 5 | }, 6 | baseURL:"http://127.0.0.1/wochuang/public", 7 | // 登录注册 8 | loginOrNot:"/index/Index/loginOrNot", 9 | doLogin:"/index/user/doLogin", 10 | doRegister :"/index/user/doRegister", 11 | doExit :" /index/user/doExit", 12 | doModifyPwd :"/index/user/doModifyPwd", 13 | emailVerify :"/index/user/email", 14 | 15 | //查询订单 16 | weitPay :" /index/Ordercontroller/weitPay", 17 | weitSend :"/index/Ordercontroller/weitSend", 18 | Receive :"/index/Ordercontroller/Receive", 19 | cancelOrder :"/index/Ordercontroller/cancelOrder", 20 | // 商品相关 21 | //首页顶部幻灯片 22 | getSlider :"/index/Slide/getSlider", 23 | getClassify :"/index/Classifycontroller/getClassify", 24 | getClassifyById :"/index/Classifycontroller/getClassifyById", 25 | getSale :"/index/Salecontroller/getSale", 26 | getSaleById :"/index/Salecontroller/getSaleById", 27 | getGoodsByClass :"/index/Goodscontroller/getGoodsByClass", 28 | getGoodsById :"/index/Goodscontroller/getGoodsById", 29 | getGoods:"/index/Goodscontroller/getGoods", 30 | //首页中部幻灯片 31 | getSliderCenter:"/index/Slide/getSliderCenter", 32 | //首页底部幻灯片 33 | getSliderBottom:"/index/Slide/getSliderBottom", 34 | // 订单相关 35 | getAddress :"/index/Addresscontroller/getAddress", 36 | addAddress :"/index/Addresscontroller/addAddress", 37 | modifyAddress :"/index/Addresscontroller/modifyAddress", 38 | delAddress :"/index/Addresscontroller/delAddress", 39 | addOrder :"/index/Ordercontroller/addOrder", 40 | QR : "/index/index/pingpp", 41 | queryPayStatus : "/index/index/chargeCondition", 42 | paySuccessNotice : "/index/Ordercontroller/paySuccess", 43 | // 本地存储相关 44 | setItem(key,item){ 45 | let _item=typeof item == 'string'?item:JSON.stringify(item); 46 | return localStorage.setItem(key,_item); 47 | }, 48 | getItem(key,type){ 49 | let local=localStorage.getItem(key); 50 | return local; 51 | }, 52 | userId:'wochuang_logining_uid', 53 | usermsg:'wochuang_user_msg' 54 | 55 | } -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hj624608494/vue-shopping-mall/0b7fb8ec5de776aef3935187e4b3357c369455e7/src/assets/logo.png -------------------------------------------------------------------------------- /src/components/Buy.vue: -------------------------------------------------------------------------------- 1 | 70 | 71 | 180 | 181 | 339 | -------------------------------------------------------------------------------- /src/components/Classify.vue: -------------------------------------------------------------------------------- 1 | 31 | 92 | -------------------------------------------------------------------------------- /src/components/Goods.vue: -------------------------------------------------------------------------------- 1 | 55 | 245 | -------------------------------------------------------------------------------- /src/components/Index.vue: -------------------------------------------------------------------------------- 1 | 102 | 249 | -------------------------------------------------------------------------------- /src/components/Lgcontent.vue: -------------------------------------------------------------------------------- 1 | 57 | 229 | -------------------------------------------------------------------------------- /src/components/Loginbox.vue: -------------------------------------------------------------------------------- 1 | 9 | 13 | -------------------------------------------------------------------------------- /src/components/Lwy.vue: -------------------------------------------------------------------------------- 1 | 46 | 51 | 52 | -------------------------------------------------------------------------------- /src/components/Order.vue: -------------------------------------------------------------------------------- 1 | 86 | 266 | -------------------------------------------------------------------------------- /src/components/Pay.vue: -------------------------------------------------------------------------------- 1 | 45 | 190 | -------------------------------------------------------------------------------- /src/components/er-qart.vue: -------------------------------------------------------------------------------- 1 | 6 | 26 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | // The Vue build version to load with the `import` command 2 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias. 3 | import Vue from 'vue' 4 | import axios from 'axios' 5 | Vue.prototype.axios = axios; 6 | import App from './App' 7 | import router from './router' 8 | // import iView from 'iview' 9 | import 'iview/dist/styles/iview.css'; 10 | import './assets/css/commond.css' 11 | Vue.config.productionTip = false; 12 | 13 | import VueProgressBar from 'vue-progressbar' 14 | 15 | Vue.use(VueProgressBar, { 16 | color: 'rgb(51,153,255)', 17 | failedColor: 'red', 18 | thickness: '2.5px' 19 | }) 20 | 21 | router.beforeEach((to, from, next) => { 22 | window.scrollTo(0,0); 23 | next(); 24 | }) 25 | 26 | /* eslint-disable no-new */ 27 | new Vue({ 28 | el: '#app', 29 | router, 30 | template: '', 31 | components: { App } 32 | }) 33 | -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Router from 'vue-router' 3 | import Index from '@/components/Index' 4 | import Classify from '@/components/Classify' 5 | import Goods from '@/components/Goods' 6 | import Order from '@/components/Order' 7 | import Pay from '@/components/Pay' 8 | import Buy from '@/components/Buy' 9 | 10 | Vue.use(Router) 11 | 12 | export default new Router({ 13 | routes: [ 14 | { 15 | path: '/', 16 | name: 'Index', 17 | component: Index 18 | }, 19 | { 20 | path: '/classify', 21 | name: 'classify', 22 | component: Classify 23 | }, 24 | { 25 | path: '/goods', 26 | name: 'goods', 27 | component: Goods 28 | }, 29 | { 30 | path: '/order', 31 | name: 'Order', 32 | component: Order 33 | }, 34 | { 35 | path: '/pay', 36 | name: 'Pay', 37 | component: Pay 38 | }, 39 | { 40 | path: '/buy', 41 | name: 'buy', 42 | component: Buy 43 | } 44 | ] 45 | }) 46 | -------------------------------------------------------------------------------- /static/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hj624608494/vue-shopping-mall/0b7fb8ec5de776aef3935187e4b3357c369455e7/static/.gitkeep -------------------------------------------------------------------------------- /static/QR.js: -------------------------------------------------------------------------------- 1 | /*from tccdn minify at 2014-6-4 14:59:43,file:/cn/c/c/qrcode.js*/ 2 | /** 3 | * @fileoverview 4 | * - Using the 'QRCode for Javascript library' 5 | * - Fixed dataset of 'QRCode for Javascript library' for support full-spec. 6 | * - this library has no dependencies. 7 | * 8 | * @author davidshimjs 9 | * @see http://www.d-project.com/ 10 | * @see http://jeromeetienne.github.com/jquery-qrcode/ 11 | */ 12 | var QRCode; 13 | 14 | (function () { 15 | //--------------------------------------------------------------------- 16 | // QRCode for JavaScript 17 | // 18 | // Copyright (c) 2009 Kazuhiko Arase 19 | // 20 | // URL: http://www.d-project.com/ 21 | // 22 | // Licensed under the MIT license: 23 | // http://www.opensource.org/licenses/mit-license.php 24 | // 25 | // The word "QR Code" is registered trademark of 26 | // DENSO WAVE INCORPORATED 27 | // http://www.denso-wave.com/qrcode/faqpatent-e.html 28 | // 29 | //--------------------------------------------------------------------- 30 | function QR8bitByte(data) { 31 | this.mode = QRMode.MODE_8BIT_BYTE; 32 | this.data = data; 33 | this.parsedData = []; 34 | 35 | // Added to support UTF-8 Characters 36 | for (var i = 0, l = this.data.length; i < l; i++) { 37 | var byteArray = []; 38 | var code = this.data.charCodeAt(i); 39 | 40 | if (code > 0x10000) { 41 | byteArray[0] = 0xF0 | ((code & 0x1C0000) >>> 18); 42 | byteArray[1] = 0x80 | ((code & 0x3F000) >>> 12); 43 | byteArray[2] = 0x80 | ((code & 0xFC0) >>> 6); 44 | byteArray[3] = 0x80 | (code & 0x3F); 45 | } else if (code > 0x800) { 46 | byteArray[0] = 0xE0 | ((code & 0xF000) >>> 12); 47 | byteArray[1] = 0x80 | ((code & 0xFC0) >>> 6); 48 | byteArray[2] = 0x80 | (code & 0x3F); 49 | } else if (code > 0x80) { 50 | byteArray[0] = 0xC0 | ((code & 0x7C0) >>> 6); 51 | byteArray[1] = 0x80 | (code & 0x3F); 52 | } else { 53 | byteArray[0] = code; 54 | } 55 | 56 | this.parsedData.push(byteArray); 57 | } 58 | 59 | this.parsedData = Array.prototype.concat.apply([], this.parsedData); 60 | 61 | if (this.parsedData.length != this.data.length) { 62 | this.parsedData.unshift(191); 63 | this.parsedData.unshift(187); 64 | this.parsedData.unshift(239); 65 | } 66 | } 67 | 68 | QR8bitByte.prototype = { 69 | getLength: function (buffer) { 70 | return this.parsedData.length; 71 | }, 72 | write: function (buffer) { 73 | for (var i = 0, l = this.parsedData.length; i < l; i++) { 74 | buffer.put(this.parsedData[i], 8); 75 | } 76 | } 77 | }; 78 | 79 | function QRCodeModel(typeNumber, errorCorrectLevel) { 80 | this.typeNumber = typeNumber; 81 | this.errorCorrectLevel = errorCorrectLevel; 82 | this.modules = null; 83 | this.moduleCount = 0; 84 | this.dataCache = null; 85 | this.dataList = []; 86 | } 87 | 88 | function QRPolynomial(num, shift) { 89 | if (num.length == undefined) throw new Error(num.length + "/" + shift); 90 | var offset = 0; 91 | while (offset < num.length && num[offset] == 0) offset++; 92 | this.num = new Array(num.length - offset + shift); 93 | for (var i = 0; i < num.length - offset; i++) this.num[i] = num[i + offset]; 94 | } 95 | 96 | function QRRSBlock(totalCount, dataCount) { 97 | this.totalCount = totalCount, this.dataCount = dataCount; 98 | } 99 | 100 | function QRBitBuffer() { 101 | this.buffer = [], this.length = 0; 102 | } 103 | 104 | QRCodeModel.prototype = { 105 | "addData": function(data) { 106 | var newData = new QR8bitByte(data); 107 | this.dataList.push(newData), this.dataCache = null; 108 | }, 109 | "isDark": function(row, col) { 110 | if (row < 0 || this.moduleCount <= row || col < 0 || this.moduleCount <= col) throw new Error(row + "," + col); 111 | return this.modules[row][col]; 112 | }, 113 | "getModuleCount": function() { 114 | return this.moduleCount; 115 | }, 116 | "make": function() { 117 | this.makeImpl(!1, this.getBestMaskPattern()); 118 | }, 119 | "makeImpl": function(test, maskPattern) { 120 | this.moduleCount = this.typeNumber * 4 + 17, this.modules = new Array(this.moduleCount); 121 | for (var row = 0; row < this.moduleCount; row++) { 122 | this.modules[row] = new Array(this.moduleCount); 123 | for (var col = 0; col < this.moduleCount; col++) this.modules[row][col] = null; 124 | } 125 | this.setupPositionProbePattern(0, 0), 126 | this.setupPositionProbePattern(this.moduleCount - 7, 0), 127 | this.setupPositionProbePattern(0, this.moduleCount - 7), 128 | this.setupPositionAdjustPattern(), this.setupTimingPattern(), 129 | this.setupTypeInfo(test, maskPattern), 130 | this.typeNumber >= 7 && this.setupTypeNumber(test), 131 | this.dataCache == null && (this.dataCache = QRCodeModel.createData(this.typeNumber, this.errorCorrectLevel, this.dataList)), this.mapData(this.dataCache, maskPattern); 132 | }, 133 | "setupPositionProbePattern": function(row, col) { 134 | for (var r = -1; r <= 7; r++) { 135 | if (row + r <= -1 || this.moduleCount <= row + r) continue; 136 | for (var c = -1; c <= 7; c++) { 137 | if (col + c <= -1 || this.moduleCount <= col + c) continue; 138 | 0 <= r && r <= 6 && (c == 0 || c == 6) || 0 <= c && c <= 6 && (r == 0 || r == 6) || 2 <= r && r <= 4 && 2 <= c && c <= 4 ? this.modules[row + r][col + c] = !0 : this.modules[row + r][col + c] = !1; 139 | } 140 | } 141 | }, 142 | "getBestMaskPattern": function() { 143 | var minLostPoint = 0, pattern = 0; 144 | for (var i = 0; i < 8; i++) { 145 | this.makeImpl(!0, i); 146 | var lostPoint = QRUtil.getLostPoint(this); 147 | if (i == 0 || minLostPoint > lostPoint) minLostPoint = lostPoint, pattern = i; 148 | } 149 | return pattern; 150 | }, 151 | "createMovieClip": function(target_mc, instance_name, depth) { 152 | var qr_mc = target_mc.createEmptyMovieClip(instance_name, depth), cs = 1; 153 | this.make(); 154 | for (var row = 0; row < this.modules.length; row++) { 155 | var y = row * cs; 156 | for (var col = 0; col < this.modules[row].length; col++) { 157 | var x = col * cs, dark = this.modules[row][col]; 158 | dark && (qr_mc.beginFill(0, 100), qr_mc.moveTo(x, y), qr_mc.lineTo(x + cs, y), qr_mc.lineTo(x + cs, y + cs), qr_mc.lineTo(x, y + cs), qr_mc.endFill()); 159 | } 160 | } 161 | return qr_mc; 162 | }, 163 | "setupTimingPattern": function() { 164 | for (var r = 8; r < this.moduleCount - 8; r++) { 165 | if (this.modules[r][6] != null) continue; 166 | this.modules[r][6] = r % 2 == 0; 167 | } 168 | for (var c = 8; c < this.moduleCount - 8; c++) { 169 | if (this.modules[6][c] != null) continue; 170 | this.modules[6][c] = c % 2 == 0; 171 | } 172 | }, 173 | "setupPositionAdjustPattern": function() { 174 | var pos = QRUtil.getPatternPosition(this.typeNumber); 175 | for (var i = 0; i < pos.length; i++) for (var j = 0; j < pos.length; j++) { 176 | var row = pos[i], col = pos[j]; 177 | if (this.modules[row][col] != null) continue; 178 | for (var r = -2; r <= 2; r++) for (var c = -2; c <= 2; c++) r == -2 || r == 2 || c == -2 || c == 2 || r == 0 && c == 0 ? this.modules[row + r][col + c] = !0 : this.modules[row + r][col + c] = !1; 179 | } 180 | }, 181 | "setupTypeNumber": function(test) { 182 | var bits = QRUtil.getBCHTypeNumber(this.typeNumber); 183 | for (var i = 0; i < 18; i++) { 184 | var mod = !test && (bits >> i & 1) == 1; 185 | this.modules[Math.floor(i / 3)][i % 3 + this.moduleCount - 8 - 3] = mod; 186 | } 187 | for (var i = 0; i < 18; i++) { 188 | var mod = !test && (bits >> i & 1) == 1; 189 | this.modules[i % 3 + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod; 190 | } 191 | }, 192 | "setupTypeInfo": function(test, maskPattern) { 193 | var data = this.errorCorrectLevel << 3 | maskPattern, bits = QRUtil.getBCHTypeInfo(data); 194 | for (var i = 0; i < 15; i++) { 195 | var mod = !test && (bits >> i & 1) == 1; 196 | i < 6 ? this.modules[i][8] = mod : i < 8 ? this.modules[i + 1][8] = mod : this.modules[this.moduleCount - 15 + i][8] = mod; 197 | } 198 | for (var i = 0; i < 15; i++) { 199 | var mod = !test && (bits >> i & 1) == 1; 200 | i < 8 ? this.modules[8][this.moduleCount - i - 1] = mod : i < 9 ? this.modules[8][15 - i - 1 + 1] = mod : this.modules[8][15 - i - 1] = mod; 201 | } 202 | this.modules[this.moduleCount - 8][8] = !test; 203 | }, 204 | "mapData": function(data, maskPattern) { 205 | var inc = -1, row = this.moduleCount - 1, bitIndex = 7, byteIndex = 0; 206 | for (var col = this.moduleCount - 1; col > 0; col -= 2) { 207 | col == 6 && col--; 208 | for (;;) { 209 | for (var c = 0; c < 2; c++) if (this.modules[row][col - c] == null) { 210 | var dark = !1; 211 | byteIndex < data.length && (dark = (data[byteIndex] >>> bitIndex & 1) == 1); 212 | var mask = QRUtil.getMask(maskPattern, row, col - c); 213 | mask && (dark = !dark), this.modules[row][col - c] = dark, bitIndex--, bitIndex == -1 && (byteIndex++, bitIndex = 7); 214 | } 215 | row += inc; 216 | if (row < 0 || this.moduleCount <= row) { 217 | row -= inc, inc = -inc; 218 | break; 219 | } 220 | } 221 | } 222 | } 223 | }, QRCodeModel.PAD0 = 236, QRCodeModel.PAD1 = 17, QRCodeModel.createData = function(typeNumber, errorCorrectLevel, dataList) { 224 | var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel), buffer = new QRBitBuffer; 225 | for (var i = 0; i < dataList.length; i++) { 226 | var data = dataList[i]; 227 | buffer.put(data.mode, 4), buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber)), data.write(buffer); 228 | } 229 | var totalDataCount = 0; 230 | for (var i = 0; i < rsBlocks.length; i++) totalDataCount += rsBlocks[i].dataCount; 231 | if (buffer.getLengthInBits() > totalDataCount * 8) throw new Error("code length overflow. (" + buffer.getLengthInBits() + ">" + totalDataCount * 8 + ")"); 232 | buffer.getLengthInBits() + 4 <= totalDataCount * 8 && buffer.put(0, 4); 233 | while (buffer.getLengthInBits() % 8 != 0) buffer.putBit(!1); 234 | for (;;) { 235 | if (buffer.getLengthInBits() >= totalDataCount * 8) break; 236 | buffer.put(QRCodeModel.PAD0, 8); 237 | if (buffer.getLengthInBits() >= totalDataCount * 8) break; 238 | buffer.put(QRCodeModel.PAD1, 8); 239 | } 240 | return QRCodeModel.createBytes(buffer, rsBlocks); 241 | }, QRCodeModel.createBytes = function(buffer, rsBlocks) { 242 | var offset = 0, maxDcCount = 0, maxEcCount = 0, dcdata = new Array(rsBlocks.length), ecdata = new Array(rsBlocks.length); 243 | for (var r = 0; r < rsBlocks.length; r++) { 244 | var dcCount = rsBlocks[r].dataCount, ecCount = rsBlocks[r].totalCount - dcCount; 245 | maxDcCount = Math.max(maxDcCount, dcCount), maxEcCount = Math.max(maxEcCount, ecCount), dcdata[r] = new Array(dcCount); 246 | for (var i = 0; i < dcdata[r].length; i++) dcdata[r][i] = 255 & buffer.buffer[i + offset]; 247 | offset += dcCount; 248 | var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount), rawPoly = new QRPolynomial(dcdata[r], rsPoly.getLength() - 1), modPoly = rawPoly.mod(rsPoly); 249 | ecdata[r] = new Array(rsPoly.getLength() - 1); 250 | for (var i = 0; i < ecdata[r].length; i++) { 251 | var modIndex = i + modPoly.getLength() - ecdata[r].length; 252 | ecdata[r][i] = modIndex >= 0 ? modPoly.get(modIndex) : 0; 253 | } 254 | } 255 | var totalCodeCount = 0; 256 | for (var i = 0; i < rsBlocks.length; i++) totalCodeCount += rsBlocks[i].totalCount; 257 | var data = new Array(totalCodeCount), index = 0; 258 | for (var i = 0; i < maxDcCount; i++) for (var r = 0; r < rsBlocks.length; r++) i < dcdata[r].length && (data[index++] = dcdata[r][i]); 259 | for (var i = 0; i < maxEcCount; i++) for (var r = 0; r < rsBlocks.length; r++) i < ecdata[r].length && (data[index++] = ecdata[r][i]); 260 | return data; 261 | }; 262 | 263 | var QRMode = { 264 | "MODE_NUMBER": 1, 265 | "MODE_ALPHA_NUM": 2, 266 | "MODE_8BIT_BYTE": 4, 267 | "MODE_KANJI": 8 268 | }, QRErrorCorrectLevel = { 269 | "L": 1, 270 | "M": 0, 271 | "Q": 3, 272 | "H": 2 273 | }, QRMaskPattern = { 274 | "PATTERN000": 0, 275 | "PATTERN001": 1, 276 | "PATTERN010": 2, 277 | "PATTERN011": 3, 278 | "PATTERN100": 4, 279 | "PATTERN101": 5, 280 | "PATTERN110": 6, 281 | "PATTERN111": 7 282 | }, QRUtil = { 283 | "PATTERN_POSITION_TABLE": [ [], [ 6, 18 ], [ 6, 22 ], [ 6, 26 ], [ 6, 30 ], [ 6, 34 ], [ 6, 22, 38 ], [ 6, 24, 42 ], [ 6, 26, 46 ], [ 6, 28, 50 ], [ 6, 30, 54 ], [ 6, 32, 58 ], [ 6, 34, 62 ], [ 6, 26, 46, 66 ], [ 6, 26, 48, 70 ], [ 6, 26, 50, 74 ], [ 6, 30, 54, 78 ], [ 6, 30, 56, 82 ], [ 6, 30, 58, 86 ], [ 6, 34, 62, 90 ], [ 6, 28, 50, 72, 94 ], [ 6, 26, 50, 74, 98 ], [ 6, 30, 54, 78, 102 ], [ 6, 28, 54, 80, 106 ], [ 6, 32, 58, 84, 110 ], [ 6, 30, 58, 86, 114 ], [ 6, 34, 62, 90, 118 ], [ 6, 26, 50, 74, 98, 122 ], [ 6, 30, 54, 78, 102, 126 ], [ 6, 26, 52, 78, 104, 130 ], [ 6, 30, 56, 82, 108, 134 ], [ 6, 34, 60, 86, 112, 138 ], [ 6, 30, 58, 86, 114, 142 ], [ 6, 34, 62, 90, 118, 146 ], [ 6, 30, 54, 78, 102, 126, 150 ], [ 6, 24, 50, 76, 102, 128, 154 ], [ 6, 28, 54, 80, 106, 132, 158 ], [ 6, 32, 58, 84, 110, 136, 162 ], [ 6, 26, 54, 82, 110, 138, 166 ], [ 6, 30, 58, 86, 114, 142, 170 ] ], 284 | "G15": 1335, 285 | "G18": 7973, 286 | "G15_MASK": 21522, 287 | "getBCHTypeInfo": function(data) { 288 | var d = data << 10; 289 | while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) d ^= QRUtil.G15 << QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15); 290 | return (data << 10 | d) ^ QRUtil.G15_MASK; 291 | }, 292 | "getBCHTypeNumber": function(data) { 293 | var d = data << 12; 294 | while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) d ^= QRUtil.G18 << QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18); 295 | return data << 12 | d; 296 | }, 297 | "getBCHDigit": function(data) { 298 | var digit = 0; 299 | while (data != 0) digit++, data >>>= 1; 300 | return digit; 301 | }, 302 | "getPatternPosition": function(typeNumber) { 303 | return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1]; 304 | }, 305 | "getMask": function(maskPattern, i, j) { 306 | switch (maskPattern) { 307 | case QRMaskPattern.PATTERN000: 308 | return (i + j) % 2 == 0; 309 | case QRMaskPattern.PATTERN001: 310 | return i % 2 == 0; 311 | case QRMaskPattern.PATTERN010: 312 | return j % 3 == 0; 313 | case QRMaskPattern.PATTERN011: 314 | return (i + j) % 3 == 0; 315 | case QRMaskPattern.PATTERN100: 316 | return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 == 0; 317 | case QRMaskPattern.PATTERN101: 318 | return i * j % 2 + i * j % 3 == 0; 319 | case QRMaskPattern.PATTERN110: 320 | return (i * j % 2 + i * j % 3) % 2 == 0; 321 | case QRMaskPattern.PATTERN111: 322 | return (i * j % 3 + (i + j) % 2) % 2 == 0; 323 | default: 324 | throw new Error("bad maskPattern:" + maskPattern); 325 | } 326 | }, 327 | "getErrorCorrectPolynomial": function(errorCorrectLength) { 328 | var a = new QRPolynomial([ 1 ], 0); 329 | for (var i = 0; i < errorCorrectLength; i++) a = a.multiply(new QRPolynomial([ 1, QRMath.gexp(i) ], 0)); 330 | return a; 331 | }, 332 | "getLengthInBits": function(mode, type) { 333 | if (1 <= type && type < 10) switch (mode) { 334 | case QRMode.MODE_NUMBER: 335 | return 10; 336 | case QRMode.MODE_ALPHA_NUM: 337 | return 9; 338 | case QRMode.MODE_8BIT_BYTE: 339 | return 8; 340 | case QRMode.MODE_KANJI: 341 | return 8; 342 | default: 343 | throw new Error("mode:" + mode); 344 | } else if (type < 27) switch (mode) { 345 | case QRMode.MODE_NUMBER: 346 | return 12; 347 | case QRMode.MODE_ALPHA_NUM: 348 | return 11; 349 | case QRMode.MODE_8BIT_BYTE: 350 | return 16; 351 | case QRMode.MODE_KANJI: 352 | return 10; 353 | default: 354 | throw new Error("mode:" + mode); 355 | } else { 356 | if (!(type < 41)) throw new Error("type:" + type); 357 | switch (mode) { 358 | case QRMode.MODE_NUMBER: 359 | return 14; 360 | case QRMode.MODE_ALPHA_NUM: 361 | return 13; 362 | case QRMode.MODE_8BIT_BYTE: 363 | return 16; 364 | case QRMode.MODE_KANJI: 365 | return 12; 366 | default: 367 | throw new Error("mode:" + mode); 368 | } 369 | } 370 | }, 371 | "getLostPoint": function(qrCode) { 372 | var moduleCount = qrCode.getModuleCount(), lostPoint = 0; 373 | for (var row = 0; row < moduleCount; row++) for (var col = 0; col < moduleCount; col++) { 374 | var sameCount = 0, dark = qrCode.isDark(row, col); 375 | for (var r = -1; r <= 1; r++) { 376 | if (row + r < 0 || moduleCount <= row + r) continue; 377 | for (var c = -1; c <= 1; c++) { 378 | if (col + c < 0 || moduleCount <= col + c) continue; 379 | if (r == 0 && c == 0) continue; 380 | dark == qrCode.isDark(row + r, col + c) && sameCount++; 381 | } 382 | } 383 | sameCount > 5 && (lostPoint += 3 + sameCount - 5); 384 | } 385 | for (var row = 0; row < moduleCount - 1; row++) for (var col = 0; col < moduleCount - 1; col++) { 386 | var count = 0; 387 | qrCode.isDark(row, col) && count++, qrCode.isDark(row + 1, col) && count++, qrCode.isDark(row, col + 1) && count++, qrCode.isDark(row + 1, col + 1) && count++; 388 | if (count == 0 || count == 4) lostPoint += 3; 389 | } 390 | for (var row = 0; row < moduleCount; row++) for (var col = 0; col < moduleCount - 6; col++) qrCode.isDark(row, col) && !qrCode.isDark(row, col + 1) && qrCode.isDark(row, col + 2) && qrCode.isDark(row, col + 3) && qrCode.isDark(row, col + 4) && !qrCode.isDark(row, col + 5) && qrCode.isDark(row, col + 6) && (lostPoint += 40); 391 | for (var col = 0; col < moduleCount; col++) for (var row = 0; row < moduleCount - 6; row++) qrCode.isDark(row, col) && !qrCode.isDark(row + 1, col) && qrCode.isDark(row + 2, col) && qrCode.isDark(row + 3, col) && qrCode.isDark(row + 4, col) && !qrCode.isDark(row + 5, col) && qrCode.isDark(row + 6, col) && (lostPoint += 40); 392 | var darkCount = 0; 393 | for (var col = 0; col < moduleCount; col++) for (var row = 0; row < moduleCount; row++) qrCode.isDark(row, col) && darkCount++; 394 | var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5; 395 | return lostPoint += ratio * 10, lostPoint; 396 | } 397 | }, QRMath = { 398 | "glog": function(n) { 399 | if (n < 1) throw new Error("glog(" + n + ")"); 400 | return QRMath.LOG_TABLE[n]; 401 | }, 402 | "gexp": function(n) { 403 | while (n < 0) n += 255; 404 | while (n >= 256) n -= 255; 405 | return QRMath.EXP_TABLE[n]; 406 | }, 407 | "EXP_TABLE": new Array(256), 408 | "LOG_TABLE": new Array(256) 409 | }; 410 | 411 | for (var i = 0; i < 8; i++) QRMath.EXP_TABLE[i] = 1 << i; 412 | 413 | for (var i = 8; i < 256; i++) QRMath.EXP_TABLE[i] = QRMath.EXP_TABLE[i - 4] ^ QRMath.EXP_TABLE[i - 5] ^ QRMath.EXP_TABLE[i - 6] ^ QRMath.EXP_TABLE[i - 8]; 414 | 415 | for (var i = 0; i < 255; i++) QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]] = i; 416 | 417 | QRPolynomial.prototype = { 418 | "get": function(index) { 419 | return this.num[index]; 420 | }, 421 | "getLength": function() { 422 | return this.num.length; 423 | }, 424 | "multiply": function(e) { 425 | var num = new Array(this.getLength() + e.getLength() - 1); 426 | for (var i = 0; i < this.getLength(); i++) for (var j = 0; j < e.getLength(); j++) num[i + j] ^= QRMath.gexp(QRMath.glog(this.get(i)) + QRMath.glog(e.get(j))); 427 | return new QRPolynomial(num, 0); 428 | }, 429 | "mod": function(e) { 430 | if (this.getLength() - e.getLength() < 0) return this; 431 | var ratio = QRMath.glog(this.get(0)) - QRMath.glog(e.get(0)), num = new Array(this.getLength()); 432 | for (var i = 0; i < this.getLength(); i++) num[i] = this.get(i); 433 | for (var i = 0; i < e.getLength(); i++) num[i] ^= QRMath.gexp(QRMath.glog(e.get(i)) + ratio); 434 | return (new QRPolynomial(num, 0)).mod(e); 435 | } 436 | }, QRRSBlock.RS_BLOCK_TABLE = [ [ 1, 26, 19 ], [ 1, 26, 16 ], [ 1, 26, 13 ], [ 1, 26, 9 ], [ 1, 44, 34 ], [ 1, 44, 28 ], [ 1, 44, 22 ], [ 1, 44, 16 ], [ 1, 70, 55 ], [ 1, 70, 44 ], [ 2, 35, 17 ], [ 2, 35, 13 ], [ 1, 100, 80 ], [ 2, 50, 32 ], [ 2, 50, 24 ], [ 4, 25, 9 ], [ 1, 134, 108 ], [ 2, 67, 43 ], [ 2, 33, 15, 2, 34, 16 ], [ 2, 33, 11, 2, 34, 12 ], [ 2, 86, 68 ], [ 4, 43, 27 ], [ 4, 43, 19 ], [ 4, 43, 15 ], [ 2, 98, 78 ], [ 4, 49, 31 ], [ 2, 32, 14, 4, 33, 15 ], [ 4, 39, 13, 1, 40, 14 ], [ 2, 121, 97 ], [ 2, 60, 38, 2, 61, 39 ], [ 4, 40, 18, 2, 41, 19 ], [ 4, 40, 14, 2, 41, 15 ], [ 2, 146, 116 ], [ 3, 58, 36, 2, 59, 37 ], [ 4, 36, 16, 4, 37, 17 ], [ 4, 36, 12, 4, 37, 13 ], [ 2, 86, 68, 2, 87, 69 ], [ 4, 69, 43, 1, 70, 44 ], [ 6, 43, 19, 2, 44, 20 ], [ 6, 43, 15, 2, 44, 16 ], [ 4, 101, 81 ], [ 1, 80, 50, 4, 81, 51 ], [ 4, 50, 22, 4, 51, 23 ], [ 3, 36, 12, 8, 37, 13 ], [ 2, 116, 92, 2, 117, 93 ], [ 6, 58, 36, 2, 59, 37 ], [ 4, 46, 20, 6, 47, 21 ], [ 7, 42, 14, 4, 43, 15 ], [ 4, 133, 107 ], [ 8, 59, 37, 1, 60, 38 ], [ 8, 44, 20, 4, 45, 21 ], [ 12, 33, 11, 4, 34, 12 ], [ 3, 145, 115, 1, 146, 116 ], [ 4, 64, 40, 5, 65, 41 ], [ 11, 36, 16, 5, 37, 17 ], [ 11, 36, 12, 5, 37, 13 ], [ 5, 109, 87, 1, 110, 88 ], [ 5, 65, 41, 5, 66, 42 ], [ 5, 54, 24, 7, 55, 25 ], [ 11, 36, 12 ], [ 5, 122, 98, 1, 123, 99 ], [ 7, 73, 45, 3, 74, 46 ], [ 15, 43, 19, 2, 44, 20 ], [ 3, 45, 15, 13, 46, 16 ], [ 1, 135, 107, 5, 136, 108 ], [ 10, 74, 46, 1, 75, 47 ], [ 1, 50, 22, 15, 51, 23 ], [ 2, 42, 14, 17, 43, 15 ], [ 5, 150, 120, 1, 151, 121 ], [ 9, 69, 43, 4, 70, 44 ], [ 17, 50, 22, 1, 51, 23 ], [ 2, 42, 14, 19, 43, 15 ], [ 3, 141, 113, 4, 142, 114 ], [ 3, 70, 44, 11, 71, 45 ], [ 17, 47, 21, 4, 48, 22 ], [ 9, 39, 13, 16, 40, 14 ], [ 3, 135, 107, 5, 136, 108 ], [ 3, 67, 41, 13, 68, 42 ], [ 15, 54, 24, 5, 55, 25 ], [ 15, 43, 15, 10, 44, 16 ], [ 4, 144, 116, 4, 145, 117 ], [ 17, 68, 42 ], [ 17, 50, 22, 6, 51, 23 ], [ 19, 46, 16, 6, 47, 17 ], [ 2, 139, 111, 7, 140, 112 ], [ 17, 74, 46 ], [ 7, 54, 24, 16, 55, 25 ], [ 34, 37, 13 ], [ 4, 151, 121, 5, 152, 122 ], [ 4, 75, 47, 14, 76, 48 ], [ 11, 54, 24, 14, 55, 25 ], [ 16, 45, 15, 14, 46, 16 ], [ 6, 147, 117, 4, 148, 118 ], [ 6, 73, 45, 14, 74, 46 ], [ 11, 54, 24, 16, 55, 25 ], [ 30, 46, 16, 2, 47, 17 ], [ 8, 132, 106, 4, 133, 107 ], [ 8, 75, 47, 13, 76, 48 ], [ 7, 54, 24, 22, 55, 25 ], [ 22, 45, 15, 13, 46, 16 ], [ 10, 142, 114, 2, 143, 115 ], [ 19, 74, 46, 4, 75, 47 ], [ 28, 50, 22, 6, 51, 23 ], [ 33, 46, 16, 4, 47, 17 ], [ 8, 152, 122, 4, 153, 123 ], [ 22, 73, 45, 3, 74, 46 ], [ 8, 53, 23, 26, 54, 24 ], [ 12, 45, 15, 28, 46, 16 ], [ 3, 147, 117, 10, 148, 118 ], [ 3, 73, 45, 23, 74, 46 ], [ 4, 54, 24, 31, 55, 25 ], [ 11, 45, 15, 31, 46, 16 ], [ 7, 146, 116, 7, 147, 117 ], [ 21, 73, 45, 7, 74, 46 ], [ 1, 53, 23, 37, 54, 24 ], [ 19, 45, 15, 26, 46, 16 ], [ 5, 145, 115, 10, 146, 116 ], [ 19, 75, 47, 10, 76, 48 ], [ 15, 54, 24, 25, 55, 25 ], [ 23, 45, 15, 25, 46, 16 ], [ 13, 145, 115, 3, 146, 116 ], [ 2, 74, 46, 29, 75, 47 ], [ 42, 54, 24, 1, 55, 25 ], [ 23, 45, 15, 28, 46, 16 ], [ 17, 145, 115 ], [ 10, 74, 46, 23, 75, 47 ], [ 10, 54, 24, 35, 55, 25 ], [ 19, 45, 15, 35, 46, 16 ], [ 17, 145, 115, 1, 146, 116 ], [ 14, 74, 46, 21, 75, 47 ], [ 29, 54, 24, 19, 55, 25 ], [ 11, 45, 15, 46, 46, 16 ], [ 13, 145, 115, 6, 146, 116 ], [ 14, 74, 46, 23, 75, 47 ], [ 44, 54, 24, 7, 55, 25 ], [ 59, 46, 16, 1, 47, 17 ], [ 12, 151, 121, 7, 152, 122 ], [ 12, 75, 47, 26, 76, 48 ], [ 39, 54, 24, 14, 55, 25 ], [ 22, 45, 15, 41, 46, 16 ], [ 6, 151, 121, 14, 152, 122 ], [ 6, 75, 47, 34, 76, 48 ], [ 46, 54, 24, 10, 55, 25 ], [ 2, 45, 15, 64, 46, 16 ], [ 17, 152, 122, 4, 153, 123 ], [ 29, 74, 46, 14, 75, 47 ], [ 49, 54, 24, 10, 55, 25 ], [ 24, 45, 15, 46, 46, 16 ], [ 4, 152, 122, 18, 153, 123 ], [ 13, 74, 46, 32, 75, 47 ], [ 48, 54, 24, 14, 55, 25 ], [ 42, 45, 15, 32, 46, 16 ], [ 20, 147, 117, 4, 148, 118 ], [ 40, 75, 47, 7, 76, 48 ], [ 43, 54, 24, 22, 55, 25 ], [ 10, 45, 15, 67, 46, 16 ], [ 19, 148, 118, 6, 149, 119 ], [ 18, 75, 47, 31, 76, 48 ], [ 34, 54, 24, 34, 55, 25 ], [ 20, 45, 15, 61, 46, 16 ] ], QRRSBlock.getRSBlocks = function(typeNumber, errorCorrectLevel) { 437 | var rsBlock = QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel); 438 | if (rsBlock == undefined) throw new Error("bad rs block @ typeNumber:" + typeNumber + "/errorCorrectLevel:" + errorCorrectLevel); 439 | var length = rsBlock.length / 3, list = []; 440 | for (var i = 0; i < length; i++) { 441 | var count = rsBlock[i * 3 + 0], totalCount = rsBlock[i * 3 + 1], dataCount = rsBlock[i * 3 + 2]; 442 | for (var j = 0; j < count; j++) list.push(new QRRSBlock(totalCount, dataCount)); 443 | } 444 | return list; 445 | }, QRRSBlock.getRsBlockTable = function(typeNumber, errorCorrectLevel) { 446 | switch (errorCorrectLevel) { 447 | case QRErrorCorrectLevel.L: 448 | return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0]; 449 | case QRErrorCorrectLevel.M: 450 | return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1]; 451 | case QRErrorCorrectLevel.Q: 452 | return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2]; 453 | case QRErrorCorrectLevel.H: 454 | return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3]; 455 | default: 456 | return undefined; 457 | } 458 | }, QRBitBuffer.prototype = { 459 | "get": function(index) { 460 | var bufIndex = Math.floor(index / 8); 461 | return (this.buffer[bufIndex] >>> 7 - index % 8 & 1) == 1; 462 | }, 463 | "put": function(num, length) { 464 | for (var i = 0; i < length; i++) this.putBit((num >>> length - i - 1 & 1) == 1); 465 | }, 466 | "getLengthInBits": function() { 467 | return this.length; 468 | }, 469 | "putBit": function(bit) { 470 | var bufIndex = Math.floor(this.length / 8); 471 | this.buffer.length <= bufIndex && this.buffer.push(0), bit && (this.buffer[bufIndex] |= 128 >>> this.length % 8), this.length++; 472 | } 473 | }; 474 | var QRCodeLimitLength=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]]; 475 | 476 | function _isSupportCanvas() { 477 | return typeof CanvasRenderingContext2D != "undefined"; 478 | } 479 | 480 | // android 2.x doesn't support Data-URI spec 481 | function _getAndroid() { 482 | var android = false; 483 | var sAgent = navigator.userAgent; 484 | 485 | if (/android/i.test(sAgent)) { // android 486 | android = true; 487 | aMat = sAgent.toString().match(/android ([0-9]\.[0-9])/i); 488 | 489 | if (aMat && aMat[1]) { 490 | android = parseFloat(aMat[1]); 491 | } 492 | } 493 | 494 | return android; 495 | } 496 | 497 | var svgDrawer = (function() { 498 | 499 | var Drawing = function (el, htOption) { 500 | this._el = el; 501 | this._htOption = htOption; 502 | }; 503 | 504 | Drawing.prototype.draw = function (oQRCode) { 505 | var _htOption = this._htOption; 506 | var _el = this._el; 507 | var nCount = oQRCode.getModuleCount(); 508 | var nWidth = Math.floor(_htOption.width / nCount); 509 | var nHeight = Math.floor(_htOption.height / nCount); 510 | 511 | this.clear(); 512 | 513 | function makeSVG(tag, attrs) { 514 | var el = document.createElementNS('http://www.w3.org/2000/svg', tag); 515 | for (var k in attrs) 516 | if (attrs.hasOwnProperty(k)) el.setAttribute(k, attrs[k]); 517 | return el; 518 | } 519 | 520 | var svg = makeSVG("svg" , {'viewBox': '0 0 ' + String(nCount) + " " + String(nCount), 'width': '100%', 'height': '100%', 'fill': _htOption.colorLight}); 521 | svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink"); 522 | _el.appendChild(svg); 523 | 524 | svg.appendChild(makeSVG("rect", {"fill": _htOption.colorDark, "width": "1", "height": "1", "id": "template"})); 525 | 526 | for (var row = 0; row < nCount; row++) { 527 | for (var col = 0; col < nCount; col++) { 528 | if (oQRCode.isDark(row, col)) { 529 | var child = makeSVG("use", {"x": String(row), "y": String(col)}); 530 | child.setAttributeNS("http://www.w3.org/1999/xlink", "href", "#template") 531 | svg.appendChild(child); 532 | } 533 | } 534 | } 535 | }; 536 | Drawing.prototype.clear = function () { 537 | while (this._el.hasChildNodes()) 538 | this._el.removeChild(this._el.lastChild); 539 | }; 540 | return Drawing; 541 | })(); 542 | 543 | var useSVG = document.documentElement.tagName.toLowerCase() === "svg"; 544 | 545 | // Drawing in DOM by using Table tag 546 | var Drawing = useSVG ? svgDrawer : !_isSupportCanvas() ? (function () { 547 | var Drawing = function (el, htOption) { 548 | this._el = el; 549 | this._htOption = htOption; 550 | }; 551 | 552 | /** 553 | * Draw the QRCode 554 | * 555 | * @param {QRCode} oQRCode 556 | */ 557 | Drawing.prototype.draw = function (oQRCode) { 558 | var _htOption = this._htOption; 559 | var _el = this._el; 560 | var nCount = oQRCode.getModuleCount(); 561 | var nWidth = Math.floor(_htOption.width / nCount); 562 | var nHeight = Math.floor(_htOption.height / nCount); 563 | var aHTML = ['']; 564 | 565 | for (var row = 0; row < nCount; row++) { 566 | aHTML.push(''); 567 | 568 | for (var col = 0; col < nCount; col++) { 569 | aHTML.push(''); 570 | } 571 | 572 | aHTML.push(''); 573 | } 574 | 575 | aHTML.push('
'); 576 | _el.innerHTML = aHTML.join(''); 577 | 578 | // Fix the margin values as real size. 579 | var elTable = _el.childNodes[0]; 580 | var nLeftMarginTable = (_htOption.width - elTable.offsetWidth) / 2; 581 | var nTopMarginTable = (_htOption.height - elTable.offsetHeight) / 2; 582 | if (nLeftMarginTable > 0 && nTopMarginTable > 0) { 583 | elTable.style.margin = nTopMarginTable + "px " + nLeftMarginTable + "px"; 584 | } 585 | }; 586 | 587 | /** 588 | * Clear the QRCode 589 | */ 590 | Drawing.prototype.clear = function () { 591 | this._el.innerHTML = ''; 592 | }; 593 | 594 | return Drawing; 595 | })() : (function () { // Drawing in Canvas 596 | function _onMakeImage() { 597 | this._elImage.src = this._elCanvas.toDataURL("image/png"); 598 | this._elImage.style.display = "block"; 599 | this._elCanvas.style.display = "none"; 600 | } 601 | 602 | // Android 2.1 bug workaround 603 | // http://code.google.com/p/android/issues/detail?id=5141 604 | if (this._android && this._android <= 2.1) { 605 | var factor = 1 / window.devicePixelRatio; 606 | var drawImage = CanvasRenderingContext2D.prototype.drawImage; 607 | CanvasRenderingContext2D.prototype.drawImage = function (image, sx, sy, sw, sh, dx, dy, dw, dh) { 608 | if (("nodeName" in image) && /img/i.test(image.nodeName)) { 609 | for (var i = arguments.length - 1; i >= 1; i--) { 610 | arguments[i] = arguments[i] * factor; 611 | } 612 | } else if (typeof dw == "undefined") { 613 | arguments[1] *= factor; 614 | arguments[2] *= factor; 615 | arguments[3] *= factor; 616 | arguments[4] *= factor; 617 | } 618 | 619 | drawImage.apply(this, arguments); 620 | }; 621 | } 622 | 623 | /** 624 | * Check whether the user's browser supports Data URI or not 625 | * 626 | * @private 627 | * @param {Function} fSuccess Occurs if it supports Data URI 628 | * @param {Function} fFail Occurs if it doesn't support Data URI 629 | */ 630 | function _safeSetDataURI(fSuccess, fFail) { 631 | var self = this; 632 | self._fFail = fFail; 633 | self._fSuccess = fSuccess; 634 | 635 | // Check it just once 636 | if (self._bSupportDataURI === null) { 637 | var el = document.createElement("img"); 638 | var fOnError = function() { 639 | self._bSupportDataURI = false; 640 | 641 | if (self._fFail) { 642 | _fFail.call(self); 643 | } 644 | }; 645 | var fOnSuccess = function() { 646 | self._bSupportDataURI = true; 647 | 648 | if (self._fSuccess) { 649 | self._fSuccess.call(self); 650 | } 651 | }; 652 | 653 | el.onabort = fOnError; 654 | el.onerror = fOnError; 655 | el.onload = fOnSuccess; 656 | el.src = "data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="; // the Image contains 1px data. 657 | return; 658 | } else if (self._bSupportDataURI === true && self._fSuccess) { 659 | self._fSuccess.call(self); 660 | } else if (self._bSupportDataURI === false && self._fFail) { 661 | self._fFail.call(self); 662 | } 663 | }; 664 | 665 | /** 666 | * Drawing QRCode by using canvas 667 | * 668 | * @constructor 669 | * @param {HTMLElement} el 670 | * @param {Object} htOption QRCode Options 671 | */ 672 | var Drawing = function (el, htOption) { 673 | this._bIsPainted = false; 674 | this._android = _getAndroid(); 675 | 676 | this._htOption = htOption; 677 | this._elCanvas = document.createElement("canvas"); 678 | this._elCanvas.width = htOption.width; 679 | this._elCanvas.height = htOption.height; 680 | el.appendChild(this._elCanvas); 681 | this._el = el; 682 | this._oContext = this._elCanvas.getContext("2d"); 683 | this._bIsPainted = false; 684 | this._elImage = document.createElement("img"); 685 | this._elImage.alt = "Scan me!"; 686 | this._elImage.style.display = "none"; 687 | this._el.appendChild(this._elImage); 688 | this._bSupportDataURI = null; 689 | }; 690 | 691 | /** 692 | * Draw the QRCode 693 | * 694 | * @param {QRCode} oQRCode 695 | */ 696 | Drawing.prototype.draw = function (oQRCode) { 697 | var _elImage = this._elImage; 698 | var _oContext = this._oContext; 699 | var _htOption = this._htOption; 700 | 701 | var nCount = oQRCode.getModuleCount(); 702 | var nWidth = _htOption.width / nCount; 703 | var nHeight = _htOption.height / nCount; 704 | var nRoundedWidth = Math.round(nWidth); 705 | var nRoundedHeight = Math.round(nHeight); 706 | 707 | _elImage.style.display = "none"; 708 | this.clear(); 709 | 710 | for (var row = 0; row < nCount; row++) { 711 | for (var col = 0; col < nCount; col++) { 712 | var bIsDark = oQRCode.isDark(row, col); 713 | var nLeft = col * nWidth; 714 | var nTop = row * nHeight; 715 | _oContext.strokeStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight; 716 | _oContext.lineWidth = 1; 717 | _oContext.fillStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight; 718 | _oContext.fillRect(nLeft, nTop, nWidth, nHeight); 719 | 720 | // 안티 앨리어싱 방지 처리 721 | _oContext.strokeRect( 722 | Math.floor(nLeft) + 0.5, 723 | Math.floor(nTop) + 0.5, 724 | nRoundedWidth, 725 | nRoundedHeight 726 | ); 727 | 728 | _oContext.strokeRect( 729 | Math.ceil(nLeft) - 0.5, 730 | Math.ceil(nTop) - 0.5, 731 | nRoundedWidth, 732 | nRoundedHeight 733 | ); 734 | } 735 | } 736 | 737 | this._bIsPainted = true; 738 | }; 739 | 740 | /** 741 | * Make the image from Canvas if the browser supports Data URI. 742 | */ 743 | Drawing.prototype.makeImage = function () { 744 | if (this._bIsPainted) { 745 | _safeSetDataURI.call(this, _onMakeImage); 746 | } 747 | }; 748 | 749 | /** 750 | * Return whether the QRCode is painted or not 751 | * 752 | * @return {Boolean} 753 | */ 754 | Drawing.prototype.isPainted = function () { 755 | return this._bIsPainted; 756 | }; 757 | 758 | /** 759 | * Clear the QRCode 760 | */ 761 | Drawing.prototype.clear = function () { 762 | this._oContext.clearRect(0, 0, this._elCanvas.width, this._elCanvas.height); 763 | this._bIsPainted = false; 764 | }; 765 | 766 | /** 767 | * @private 768 | * @param {Number} nNumber 769 | */ 770 | Drawing.prototype.round = function (nNumber) { 771 | if (!nNumber) { 772 | return nNumber; 773 | } 774 | 775 | return Math.floor(nNumber * 1000) / 1000; 776 | }; 777 | 778 | return Drawing; 779 | })(); 780 | 781 | /** 782 | * Get the type by string length 783 | * 784 | * @private 785 | * @param {String} sText 786 | * @param {Number} nCorrectLevel 787 | * @return {Number} type 788 | */ 789 | function _getTypeNumber(sText, nCorrectLevel) { 790 | var nType = 1; 791 | var length = _getUTF8Length(sText); 792 | 793 | for (var i = 0, len = QRCodeLimitLength.length; i <= len; i++) { 794 | var nLimit = 0; 795 | 796 | switch (nCorrectLevel) { 797 | case QRErrorCorrectLevel.L : 798 | nLimit = QRCodeLimitLength[i][0]; 799 | break; 800 | case QRErrorCorrectLevel.M : 801 | nLimit = QRCodeLimitLength[i][1]; 802 | break; 803 | case QRErrorCorrectLevel.Q : 804 | nLimit = QRCodeLimitLength[i][2]; 805 | break; 806 | case QRErrorCorrectLevel.H : 807 | nLimit = QRCodeLimitLength[i][3]; 808 | break; 809 | } 810 | 811 | if (length <= nLimit) { 812 | break; 813 | } else { 814 | nType++; 815 | } 816 | } 817 | 818 | if (nType > QRCodeLimitLength.length) { 819 | throw new Error("Too long data"); 820 | } 821 | 822 | return nType; 823 | } 824 | 825 | function _getUTF8Length(sText) { 826 | var replacedText = encodeURI(sText).toString().replace(/\%[0-9a-fA-F]{2}/g, 'a'); 827 | return replacedText.length + (replacedText.length != sText ? 3 : 0); 828 | } 829 | 830 | /** 831 | * @class QRCode 832 | * @constructor 833 | * @example 834 | * new QRCode(document.getElementById("test"), "http://jindo.dev.naver.com/collie"); 835 | * 836 | * @example 837 | * var oQRCode = new QRCode("test", { 838 | * text : "http://naver.com", 839 | * width : 128, 840 | * height : 128 841 | * }); 842 | * 843 | * oQRCode.clear(); // Clear the QRCode. 844 | * oQRCode.makeCode("http://map.naver.com"); // Re-create the QRCode. 845 | * 846 | * @param {HTMLElement|String} el target element or 'id' attribute of element. 847 | * @param {Object|String} vOption 848 | * @param {String} vOption.text QRCode link data 849 | * @param {Number} [vOption.width=256] 850 | * @param {Number} [vOption.height=256] 851 | * @param {String} [vOption.colorDark="#000000"] 852 | * @param {String} [vOption.colorLight="#ffffff"] 853 | * @param {QRCode.CorrectLevel} [vOption.correctLevel=QRCode.CorrectLevel.H] [L|M|Q|H] 854 | */ 855 | QRCode = function (el, vOption) { 856 | this._htOption = { 857 | width : 256, 858 | height : 256, 859 | typeNumber : 4, 860 | colorDark : "#000000", 861 | colorLight : "#ffffff", 862 | correctLevel : QRErrorCorrectLevel.H 863 | }; 864 | 865 | if (typeof vOption === 'string') { 866 | vOption = { 867 | text : vOption 868 | }; 869 | } 870 | 871 | // Overwrites options 872 | if (vOption) { 873 | for (var i in vOption) { 874 | this._htOption[i] = vOption[i]; 875 | } 876 | } 877 | 878 | if (typeof el == "string") { 879 | el = document.getElementById(el); 880 | } 881 | 882 | this._android = _getAndroid(); 883 | this._el = el; 884 | this._oQRCode = null; 885 | this._oDrawing = new Drawing(this._el, this._htOption); 886 | 887 | if (this._htOption.text) { 888 | this.makeCode(this._htOption.text); 889 | } 890 | }; 891 | 892 | /** 893 | * Make the QRCode 894 | * 895 | * @param {String} sText link data 896 | */ 897 | QRCode.prototype.makeCode = function (sText) { 898 | this._oQRCode = new QRCodeModel(_getTypeNumber(sText, this._htOption.correctLevel), this._htOption.correctLevel); 899 | this._oQRCode.addData(sText); 900 | this._oQRCode.make(); 901 | this._el.title = sText; 902 | this._oDrawing.draw(this._oQRCode); 903 | this.makeImage(); 904 | }; 905 | 906 | /** 907 | * Make the Image from Canvas element 908 | * - It occurs automatically 909 | * - Android below 3 doesn't support Data-URI spec. 910 | * 911 | * @private 912 | */ 913 | QRCode.prototype.makeImage = function () { 914 | if (typeof this._oDrawing.makeImage == "function" && (!this._android || this._android >= 3)) { 915 | this._oDrawing.makeImage(); 916 | } 917 | }; 918 | 919 | /** 920 | * Clear the QRCode 921 | */ 922 | QRCode.prototype.clear = function () { 923 | this._oDrawing.clear(); 924 | }; 925 | 926 | /** 927 | * @name QRCode.CorrectLevel 928 | */ 929 | QRCode.CorrectLevel = QRErrorCorrectLevel; 930 | })(); -------------------------------------------------------------------------------- /static/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hj624608494/vue-shopping-mall/0b7fb8ec5de776aef3935187e4b3357c369455e7/static/logo.png -------------------------------------------------------------------------------- /test/e2e/custom-assertions/elementCount.js: -------------------------------------------------------------------------------- 1 | // A custom Nightwatch assertion. 2 | // the name of the method is the filename. 3 | // can be used in tests like this: 4 | // 5 | // browser.assert.elementCount(selector, count) 6 | // 7 | // for how to write custom assertions see 8 | // http://nightwatchjs.org/guide#writing-custom-assertions 9 | exports.assertion = function (selector, count) { 10 | this.message = 'Testing if element <' + selector + '> has count: ' + count 11 | this.expected = count 12 | this.pass = function (val) { 13 | return val === this.expected 14 | } 15 | this.value = function (res) { 16 | return res.value 17 | } 18 | this.command = function (cb) { 19 | var self = this 20 | return this.api.execute(function (selector) { 21 | return document.querySelectorAll(selector).length 22 | }, [selector], function (res) { 23 | cb.call(self, res) 24 | }) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/e2e/nightwatch.conf.js: -------------------------------------------------------------------------------- 1 | require('babel-register') 2 | var config = require('../../config') 3 | 4 | // http://nightwatchjs.org/guide#settings-file 5 | module.exports = { 6 | src_folders: ['test/e2e/specs'], 7 | output_folder: 'test/e2e/reports', 8 | custom_assertions_path: ['test/e2e/custom-assertions'], 9 | 10 | selenium: { 11 | start_process: true, 12 | server_path: require('selenium-server').path, 13 | host: '127.0.0.1', 14 | port: 4444, 15 | cli_args: { 16 | 'webdriver.chrome.driver': require('chromedriver').path 17 | } 18 | }, 19 | 20 | test_settings: { 21 | default: { 22 | selenium_port: 4444, 23 | selenium_host: 'localhost', 24 | silent: true, 25 | globals: { 26 | devServerURL: 'http://localhost:' + (process.env.PORT || config.dev.port) 27 | } 28 | }, 29 | 30 | chrome: { 31 | desiredCapabilities: { 32 | browserName: 'chrome', 33 | javascriptEnabled: true, 34 | acceptSslCerts: true 35 | } 36 | }, 37 | 38 | firefox: { 39 | desiredCapabilities: { 40 | browserName: 'firefox', 41 | javascriptEnabled: true, 42 | acceptSslCerts: true 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /test/e2e/runner.js: -------------------------------------------------------------------------------- 1 | // 1. start the dev server using production config 2 | process.env.NODE_ENV = 'testing' 3 | var server = require('../../build/dev-server.js') 4 | 5 | // 2. run the nightwatch test suite against it 6 | // to run in additional browsers: 7 | // 1. add an entry in test/e2e/nightwatch.conf.json under "test_settings" 8 | // 2. add it to the --env flag below 9 | // or override the environment flag, for example: `npm run e2e -- --env chrome,firefox` 10 | // For more information on Nightwatch's config file, see 11 | // http://nightwatchjs.org/guide#settings-file 12 | var opts = process.argv.slice(2) 13 | if (opts.indexOf('--config') === -1) { 14 | opts = opts.concat(['--config', 'test/e2e/nightwatch.conf.js']) 15 | } 16 | if (opts.indexOf('--env') === -1) { 17 | opts = opts.concat(['--env', 'chrome']) 18 | } 19 | 20 | var spawn = require('cross-spawn') 21 | var runner = spawn('./node_modules/.bin/nightwatch', opts, { stdio: 'inherit' }) 22 | 23 | runner.on('exit', function (code) { 24 | server.close() 25 | process.exit(code) 26 | }) 27 | 28 | runner.on('error', function (err) { 29 | server.close() 30 | throw err 31 | }) 32 | -------------------------------------------------------------------------------- /test/e2e/specs/test.js: -------------------------------------------------------------------------------- 1 | // For authoring Nightwatch tests, see 2 | // http://nightwatchjs.org/guide#usage 3 | 4 | module.exports = { 5 | 'default e2e tests': function (browser) { 6 | // automatically uses dev Server port from /config.index.js 7 | // default: http://localhost:8080 8 | // see nightwatch.conf.js 9 | const devServer = browser.globals.devServerURL 10 | 11 | browser 12 | .url(devServer) 13 | .waitForElementVisible('#app', 5000) 14 | .assert.elementPresent('.hello') 15 | .assert.containsText('h1', 'Welcome to Your Vue.js App') 16 | .assert.elementCount('img', 1) 17 | .end() 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test/unit/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "mocha": true 4 | }, 5 | "globals": { 6 | "expect": true, 7 | "sinon": true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/unit/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | Vue.config.productionTip = false 3 | 4 | // Polyfill fn.bind() for PhantomJS 5 | /* eslint-disable no-extend-native */ 6 | Function.prototype.bind = require('function-bind') 7 | 8 | // require all test files (files that ends with .spec.js) 9 | const testsContext = require.context('./specs', true, /\.spec$/) 10 | testsContext.keys().forEach(testsContext) 11 | 12 | // require all src files except main.js for coverage. 13 | // you can also change this to match only the subset of files that 14 | // you want coverage for. 15 | const srcContext = require.context('../../src', true, /^\.\/(?!main(\.js)?$)/) 16 | srcContext.keys().forEach(srcContext) 17 | -------------------------------------------------------------------------------- /test/unit/karma.conf.js: -------------------------------------------------------------------------------- 1 | // This is a karma config file. For more details see 2 | // http://karma-runner.github.io/0.13/config/configuration-file.html 3 | // we are also using it with karma-webpack 4 | // https://github.com/webpack/karma-webpack 5 | 6 | var webpackConfig = require('../../build/webpack.test.conf') 7 | 8 | module.exports = function (config) { 9 | config.set({ 10 | // to run in additional browsers: 11 | // 1. install corresponding karma launcher 12 | // http://karma-runner.github.io/0.13/config/browsers.html 13 | // 2. add it to the `browsers` array below. 14 | browsers: ['PhantomJS'], 15 | frameworks: ['mocha', 'sinon-chai'], 16 | reporters: ['spec', 'coverage'], 17 | files: ['./index.js'], 18 | preprocessors: { 19 | './index.js': ['webpack', 'sourcemap'] 20 | }, 21 | webpack: webpackConfig, 22 | webpackMiddleware: { 23 | noInfo: true 24 | }, 25 | coverageReporter: { 26 | dir: './coverage', 27 | reporters: [ 28 | { type: 'lcov', subdir: '.' }, 29 | { type: 'text-summary' } 30 | ] 31 | } 32 | }) 33 | } 34 | -------------------------------------------------------------------------------- /test/unit/specs/Hello.spec.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Hello from '@/components/Hello' 3 | 4 | describe('Hello.vue', () => { 5 | it('should render correct contents', () => { 6 | const Constructor = Vue.extend(Hello) 7 | const vm = new Constructor().$mount() 8 | expect(vm.$el.querySelector('.hello h1').textContent) 9 | .to.equal('Welcome to Your Vue.js App') 10 | }) 11 | }) 12 | --------------------------------------------------------------------------------