├── .babelrc
├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── .postcssrc.js
├── README.md
├── build.old
├── 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
├── build
├── setup-dev-server.js
├── utils.js
├── vue-loader.config.js
├── webpack.base.config.js
├── webpack.client.config.js
└── webpack.server.config.js
├── config
├── dev.env.js
├── prod.env.js
└── test.env.js
├── package-lock.json
├── package.json
├── public
└── logo-48.png
├── server.js
├── src
├── App.vue
├── app.js
├── assets
│ ├── css
│ │ ├── index.css
│ │ ├── marginPadding.css
│ │ ├── project.css
│ │ ├── projectVar.css
│ │ ├── reset.css
│ │ └── var.css
│ ├── iconfont
│ │ ├── iconfont.css
│ │ ├── iconfont.eot
│ │ ├── iconfont.svg
│ │ ├── iconfont.ttf
│ │ └── iconfont.woff
│ └── images
│ │ ├── erweima.jpg
│ │ ├── google.png
│ │ ├── left_bg.jpg
│ │ ├── logo.png
│ │ ├── logo_icon.png
│ │ ├── logo_white.png
│ │ └── safe.png
├── components
│ ├── BankSelect.vue
│ ├── DatePicker.vue
│ ├── Filtrate.vue
│ ├── SearchTable.vue
│ └── Tab.vue
├── config
│ ├── api.js
│ └── index.js
├── entry-client.js
├── entry-server.js
├── index.template.html
├── main.js
├── mock.js
├── pages
│ ├── 404.vue
│ ├── Deal.vue
│ ├── Login.vue
│ ├── Main.vue
│ ├── News.vue
│ ├── Notices.vue
│ ├── Other.vue
│ ├── Register.vue
│ ├── Reset.vue
│ ├── UserCenter.vue
│ ├── deal
│ │ └── Order.vue
│ ├── finance
│ │ ├── CapitalAccount.vue
│ │ ├── CarbonAccount.vue
│ │ └── Pandect.vue
│ ├── message
│ │ └── message.vue
│ ├── other
│ │ ├── AccountGuide.vue
│ │ ├── Authentication.vue
│ │ ├── DealGuide.vue
│ │ ├── Help.vue
│ │ ├── Illustrate.vue
│ │ ├── Recharge.vue
│ │ └── lawer.vue
│ └── security
│ │ ├── CapitalPwd.vue
│ │ ├── Center.vue
│ │ ├── Company.vue
│ │ ├── Email.vue
│ │ ├── Google.vue
│ │ ├── Identity.vue
│ │ ├── LoginPwd.vue
│ │ └── Phone.vue
├── router
│ └── index.js
├── store
│ ├── index.js
│ └── modules
│ │ ├── account.js
│ │ ├── assets.js
│ │ ├── deal.js
│ │ └── user.js
└── util
│ ├── api.js
│ ├── common.js
│ ├── getData.js
│ ├── inter.js
│ ├── pageData.js
│ └── title.js
├── static
└── .gitkeep
└── 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 | ["env", {
4 | "modules": false,
5 | "targets": {
6 | "browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
7 | }
8 | }],
9 | "stage-2"
10 | ],
11 | "plugins": ["transform-runtime"],
12 | "env": {
13 | "test": {
14 | "presets": ["env", "stage-2"],
15 | "plugins": ["istanbul"]
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/.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/standard/standard/blob/master/docs/RULES-en.md
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 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | dist/
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | test/unit/coverage
8 | test/e2e/reports
9 | selenium-debug.log
10 | config/index.js
11 |
12 | # Editor directories and files
13 | .idea
14 | *.suo
15 | *.ntvs*
16 | *.njsproj
17 | *.sln
18 |
--------------------------------------------------------------------------------
/.postcssrc.js:
--------------------------------------------------------------------------------
1 | // https://github.com/michael-ciniawsky/postcss-load-config
2 |
3 | module.exports = {
4 | "plugins": {
5 | // to edit target browsers: use "browserslist" field in package.json
6 | "postcss-import": {},
7 | "postcss-for": {},
8 | "postcss-cssnext": {},
9 | // "postcss-nested": {},
10 | "postcss-remove-root": {}
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # carbon
2 |
3 | > 碳交所
4 |
5 | ## 构建步骤
6 |
7 | ``` bash
8 | # 安装依赖
9 | npm install
10 |
11 | # 启动开发环境(服务运行在localhost:8080,配有热更新)
12 | npm run dev
13 |
14 | # 构建生产环境
15 | npm run build
16 |
17 | # 运行项目
18 | npm run start
19 | ```
20 |
21 | ## 目录结构
22 |
23 | ``` bash
24 | build # 构建目录
25 | setup-dev-server.js # 配置构建开发环境
26 | utils.js # 封装的工具方法
27 | vue-loader.config.js # vue文件的loader配置
28 | webpack.base.config.js # 公用的webpack配置
29 | webpack.client.config.js # 客户端的webpack配置
30 | webpack.server.config.js # 服务器端的webpack配置
31 | src # 开发目录
32 | assets # 静态资源目录
33 | css
34 | index.css # main.js中引入
35 | var.css # 多项目变量
36 | project.css # 该项目复用样式
37 | projectVar.css # 该项目变量
38 | reset.css # reset样式
39 | ... # 多项目复用样式
40 | iconfont # 字体图标(阿里图标库http://www.iconfont.cn)
41 | images # 图片
42 | components # 可复用组件
43 | config # 项目自定义配置目录
44 | api.js # 接口地址
45 | index.js # 配置
46 | pages # 页面级组件(路由级组件)
47 | Login.vue... # 登录页面
48 | router # 路由目录
49 | index.js # 路由配置
50 | store # vuex目录
51 | modules # store模块
52 | index.js # 根store(app.js中引入,文件太大时,可将 action、mutation 和 getter 分割到单独的文件)
53 | util # 工具目录
54 | api.js # axios发送请求(发送和返回数据处理,状态码处理...)
55 | common.js # 封装的函数
56 | getData.js # get请求的封装(是否取用store中的数据...)
57 | inter.js # 不需要保存在store中的数据的接口
58 | pageData.js # 页面需要存储的数据(分页等,可选localStorage和query)
59 | title.js # 页面title控制
60 | App.vue # 根组件
61 | app.js # 公用入口
62 | entry-client.js # 客户端入口
63 | entry-server.js # 服务器端入口
64 | index.template.html # 页面模板
65 | .babelrc # babel配置
66 | .eslintignore # eslint忽略项配置
67 | .eslintrc.js # eslint配置(使用standard标准)
68 | .gitignore # git忽略项配置
69 | .postcssrc.js # postcss配置
70 | package.json # 项目配置
71 | server.js # 项目启动文件
72 | ```
--------------------------------------------------------------------------------
/build.old/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 | if (stats.hasErrors()) {
30 | console.log(chalk.red(' Build failed with errors.\n'))
31 | process.exit(1)
32 | }
33 |
34 | console.log(chalk.cyan(' Build complete.\n'))
35 | console.log(chalk.yellow(
36 | ' Tip: built files are meant to be served over an HTTP server.\n' +
37 | ' Opening index.html over file:// won\'t work.\n'
38 | ))
39 | })
40 | })
41 |
--------------------------------------------------------------------------------
/build.old/check-versions.js:
--------------------------------------------------------------------------------
1 | var chalk = require('chalk')
2 | var semver = require('semver')
3 | var packageConfig = require('../package.json')
4 | var shell = require('shelljs')
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 |
17 | if (shell.which('npm')) {
18 | versionRequirements.push({
19 | name: 'npm',
20 | currentVersion: exec('npm --version'),
21 | versionRequirement: packageConfig.engines.npm
22 | })
23 | }
24 |
25 | module.exports = function () {
26 | var warnings = []
27 | for (var i = 0; i < versionRequirements.length; i++) {
28 | var mod = versionRequirements[i]
29 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
30 | warnings.push(mod.name + ': ' +
31 | chalk.red(mod.currentVersion) + ' should be ' +
32 | chalk.green(mod.versionRequirement)
33 | )
34 | }
35 | }
36 |
37 | if (warnings.length) {
38 | console.log('')
39 | console.log(chalk.yellow('To use this template, you must update following to modules:'))
40 | console.log()
41 | for (var i = 0; i < warnings.length; i++) {
42 | var warning = warnings[i]
43 | console.log(' ' + warning)
44 | }
45 | console.log()
46 | process.exit(1)
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/build.old/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.old/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' || process.env.NODE_ENV === 'production')
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: false,
35 | heartbeat: 2000
36 | })
37 | // force page reload when html-webpack-plugin template changes
38 | compiler.plugin('compilation', function (compilation) {
39 | compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
40 | hotMiddleware.publish({ action: 'reload' })
41 | cb()
42 | })
43 | })
44 |
45 | // proxy api requests
46 | Object.keys(proxyTable).forEach(function (context) {
47 | var options = proxyTable[context]
48 | if (typeof options === 'string') {
49 | options = { target: options }
50 | }
51 | app.use(proxyMiddleware(options.filter || context, options))
52 | })
53 |
54 | // handle fallback for HTML5 history API
55 | app.use(require('connect-history-api-fallback')())
56 |
57 | // serve webpack bundle output
58 | app.use(devMiddleware)
59 |
60 | // enable hot-reload and state-preserving
61 | // compilation error display
62 | app.use(hotMiddleware)
63 |
64 | // serve pure static assets
65 | var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)
66 | app.use(staticPath, express.static('./static'))
67 |
68 | var uri = 'http://localhost:' + port
69 |
70 | var _resolve
71 | var readyPromise = new Promise(resolve => {
72 | _resolve = resolve
73 | })
74 |
75 | console.log('> Starting dev server...')
76 | devMiddleware.waitUntilValid(() => {
77 | console.log('> Listening at ' + uri + '\n')
78 | // when env is testing, don't need open it
79 | if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') {
80 | opn(uri)
81 | }
82 | _resolve()
83 | })
84 |
85 | var server = app.listen(port)
86 |
87 | module.exports = {
88 | ready: readyPromise,
89 | close: () => {
90 | server.close()
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/build.old/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 | // https://vue-loader.vuejs.org/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 | if (extension === 'css') {
66 | loader.push('postcss-loader')
67 | }
68 | output.push({
69 | test: new RegExp('\\.' + extension + '$'),
70 | use: loader
71 | })
72 | }
73 | return output
74 | }
75 |
--------------------------------------------------------------------------------
/build.old/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 | transformToRequire: {
13 | video: 'src',
14 | source: 'src',
15 | img: 'src',
16 | image: 'xlink:href'
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/build.old/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 | options: {
53 | limit: 10000,
54 | name: utils.assetsPath('img/[name].[hash:7].[ext]')
55 | }
56 | },
57 | {
58 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
59 | loader: 'url-loader',
60 | options: {
61 | limit: 10000,
62 | name: utils.assetsPath('media/[name].[hash:7].[ext]')
63 | }
64 | },
65 | {
66 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
67 | loader: 'url-loader',
68 | options: {
69 | limit: 10000,
70 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
71 | }
72 | }
73 | ]
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/build.old/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.old/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 | const VueSSRClientPlugin = require('vue-server-renderer/client-plugin')
12 |
13 | var env = process.env.NODE_ENV === 'testing'
14 | ? require('../config/test.env')
15 | : config.build.env
16 |
17 | var webpackConfig = merge(baseWebpackConfig, {
18 | module: {
19 | rules: utils.styleLoaders({
20 | sourceMap: config.build.productionSourceMap,
21 | extract: true
22 | })
23 | },
24 | devtool: config.build.productionSourceMap ? '#source-map' : false,
25 | output: {
26 | path: config.build.assetsRoot,
27 | filename: utils.assetsPath('js/[name].[chunkhash].js'),
28 | chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
29 | },
30 | plugins: [
31 | // http://vuejs.github.io/vue-loader/en/workflow/production.html
32 | new webpack.DefinePlugin({
33 | 'process.env': env
34 | }),
35 | new webpack.optimize.UglifyJsPlugin({
36 | compress: {
37 | warnings: false
38 | },
39 | sourceMap: true
40 | }),
41 | // extract css into its own file
42 | new ExtractTextPlugin({
43 | filename: utils.assetsPath('css/[name].[contenthash].css')
44 | }),
45 | // Compress extracted CSS. We are using this plugin so that possible
46 | // duplicated CSS from different components can be deduped.
47 | new OptimizeCSSPlugin({
48 | cssProcessorOptions: {
49 | safe: true
50 | }
51 | }),
52 | // generate dist index.html with correct asset hash for caching.
53 | // you can customize output by editing /index.html
54 | // see https://github.com/ampedandwired/html-webpack-plugin
55 | new HtmlWebpackPlugin({
56 | filename: process.env.NODE_ENV === 'testing'
57 | ? 'index.html'
58 | : config.build.index,
59 | template: 'index.html',
60 | inject: true,
61 | minify: {
62 | removeComments: true,
63 | collapseWhitespace: true,
64 | removeAttributeQuotes: true
65 | // more options:
66 | // https://github.com/kangax/html-minifier#options-quick-reference
67 | },
68 | // necessary to consistently work with multiple chunks via CommonsChunkPlugin
69 | chunksSortMode: 'dependency'
70 | }),
71 | // keep module.id stable when vender modules does not change
72 | new webpack.HashedModuleIdsPlugin(),
73 | // split vendor js into its own file
74 | new webpack.optimize.CommonsChunkPlugin({
75 | name: 'vendor',
76 | minChunks: function (module, count) {
77 | // any required modules inside node_modules are extracted to vendor
78 | return (
79 | module.resource &&
80 | /\.js$/.test(module.resource) &&
81 | module.resource.indexOf(
82 | path.join(__dirname, '../node_modules')
83 | ) === 0
84 | )
85 | }
86 | }),
87 | // extract webpack runtime and module manifest to its own file in order to
88 | // prevent vendor hash from being updated whenever app bundle is updated
89 | new webpack.optimize.CommonsChunkPlugin({
90 | name: 'manifest',
91 | chunks: Infinity
92 | }),
93 | new VueSSRClientPlugin(),
94 | // copy custom static assets
95 | new CopyWebpackPlugin([
96 | {
97 | from: path.resolve(__dirname, '../static'),
98 | to: config.build.assetsSubDirectory,
99 | ignore: ['.*']
100 | }
101 | ])
102 | ]
103 | })
104 |
105 | if (config.build.productionGzip) {
106 | var CompressionWebpackPlugin = require('compression-webpack-plugin')
107 |
108 | webpackConfig.plugins.push(
109 | new CompressionWebpackPlugin({
110 | asset: '[path].gz[query]',
111 | algorithm: 'gzip',
112 | test: new RegExp(
113 | '\\.(' +
114 | config.build.productionGzipExtensions.join('|') +
115 | ')$'
116 | ),
117 | threshold: 10240,
118 | minRatio: 0.8
119 | })
120 | )
121 | }
122 |
123 | if (config.build.bundleAnalyzerReport) {
124 | var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
125 | webpackConfig.plugins.push(new BundleAnalyzerPlugin())
126 | }
127 |
128 | module.exports = webpackConfig
129 |
--------------------------------------------------------------------------------
/build.old/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 | resolveLoader: {
15 | alias: {
16 | // necessary to to make lang="scss" work in test when using vue-loader's ?inject option
17 | // see discussion at https://github.com/vuejs/vue-loader/issues/724
18 | 'scss-loader': 'sass-loader'
19 | }
20 | },
21 | plugins: [
22 | new webpack.DefinePlugin({
23 | 'process.env': require('../config/test.env')
24 | })
25 | ]
26 | })
27 |
28 | // no need for app entry during tests
29 | delete webpackConfig.entry
30 |
31 | module.exports = webpackConfig
32 |
--------------------------------------------------------------------------------
/build/setup-dev-server.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const path = require('path')
3 | const MFS = require('memory-fs')
4 | const webpack = require('webpack')
5 | const chokidar = require('chokidar')
6 | const clientConfig = require('./webpack.client.config')
7 | const serverConfig = require('./webpack.server.config')
8 |
9 | const readFile = (fs, file) => {
10 | try {
11 | return fs.readFileSync(path.join(clientConfig.output.path, file), 'utf-8')
12 | } catch (e) {}
13 | }
14 |
15 | module.exports = function setupDevServer (app, templatePath, cb) {
16 | let bundle
17 | let template
18 | let clientManifest
19 |
20 | let ready
21 | const readyPromise = new Promise(r => { ready = r })
22 | const update = () => {
23 | if (bundle && clientManifest) {
24 | ready()
25 | cb(bundle, {
26 | template,
27 | clientManifest
28 | })
29 | }
30 | }
31 |
32 | // read template from disk and watch
33 | template = fs.readFileSync(templatePath, 'utf-8')
34 | chokidar.watch(templatePath).on('change', () => {
35 | template = fs.readFileSync(templatePath, 'utf-8')
36 | console.log('index.html template updated.')
37 | update()
38 | })
39 |
40 | // modify client config to work with hot middleware
41 | clientConfig.entry.app = ['webpack-hot-middleware/client', clientConfig.entry.app]
42 | clientConfig.output.filename = '[name].js'
43 | clientConfig.plugins.push(
44 | new webpack.HotModuleReplacementPlugin(),
45 | // new webpack.NoEmitOnErrorsPlugin()
46 | )
47 |
48 | // dev middleware
49 | const clientCompiler = webpack(clientConfig)
50 | const devMiddleware = require('webpack-dev-middleware')(clientCompiler, {
51 | publicPath: clientConfig.output.publicPath,
52 | noInfo: true
53 | })
54 | app.use(devMiddleware)
55 | clientCompiler.plugin('done', stats => {
56 | stats = stats.toJson()
57 | stats.errors.forEach(err => console.error(err))
58 | stats.warnings.forEach(err => console.warn(err))
59 | if (stats.errors.length) return
60 | clientManifest = JSON.parse(readFile(
61 | devMiddleware.fileSystem,
62 | 'vue-ssr-client-manifest.json'
63 | ))
64 | update()
65 | })
66 |
67 | // hot middleware
68 | app.use(require('webpack-hot-middleware')(clientCompiler, { heartbeat: 5000 }))
69 |
70 | // watch and update server renderer
71 | const serverCompiler = webpack(serverConfig)
72 | const mfs = new MFS()
73 | serverCompiler.outputFileSystem = mfs
74 | serverCompiler.watch({}, (err, stats) => {
75 | if (err) throw err
76 | stats = stats.toJson()
77 | if (stats.errors.length) return
78 |
79 | // read bundle generated by vue-ssr-webpack-plugin
80 | bundle = JSON.parse(readFile(mfs, 'vue-ssr-server-bundle.json'))
81 | update()
82 | })
83 |
84 | return readyPromise
85 | }
86 |
--------------------------------------------------------------------------------
/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 | // https://vue-loader.vuejs.org/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 | if (extension === 'css') {
66 | loader.push('postcss-loader')
67 | }
68 | output.push({
69 | test: new RegExp('\\.' + extension + '$'),
70 | use: loader
71 | })
72 | }
73 | return output
74 | }
75 |
--------------------------------------------------------------------------------
/build/vue-loader.config.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 | transformToRequire: {
13 | video: 'src',
14 | source: 'src',
15 | img: 'src',
16 | image: 'xlink:href'
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/build/webpack.base.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | const webpack = require('webpack')
3 | const vueConfig = require('./vue-loader.config')
4 | const ExtractTextPlugin = require('extract-text-webpack-plugin')
5 | const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
6 | const UglifyJSPlugin = require('uglifyjs-webpack-plugin')
7 | const utils = require('./utils')
8 |
9 | const isProd = process.env.NODE_ENV === 'production'
10 |
11 | module.exports = {
12 | devtool: isProd
13 | ? false
14 | : '#cheap-module-source-map',
15 | output: {
16 | path: path.resolve(__dirname, '../dist'),
17 | publicPath: '/dist/',
18 | filename: '[name].[chunkhash].js'
19 | },
20 | resolve: {
21 | extensions: ['.js', '.vue', '.json'],
22 | alias: {
23 | 'public': path.resolve(__dirname, '../public'),
24 | '@': path.resolve('src')
25 | }
26 | },
27 | module: {
28 | noParse: /es6-promise\.js$/, // avoid webpack shimming process
29 | rules: [
30 | {
31 | test: /\.vue$/,
32 | loader: 'vue-loader',
33 | options: vueConfig
34 | },
35 | {
36 | test: /\.js$/,
37 | loader: 'babel-loader',
38 | exclude: /node_modules/
39 | },
40 | {
41 | test: /\.(png|jpg|gif|svg)$/,
42 | loader: 'url-loader',
43 | options: {
44 | limit: 10000,
45 | name: '[name].[ext]?[hash]'
46 | }
47 | },
48 | {
49 | test: /\.css$/,
50 | use: isProd
51 | ? ExtractTextPlugin.extract({
52 | use: ['css-loader?minimize', 'postcss-loader'],
53 | fallback: 'vue-style-loader'
54 | })
55 | : ['vue-style-loader', 'css-loader', 'postcss-loader']
56 | },
57 | {
58 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
59 | loader: 'url-loader',
60 | options: {
61 | limit: 10000,
62 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
63 | }
64 | }
65 | ]
66 | },
67 | performance: {
68 | maxEntrypointSize: 300000,
69 | hints: isProd ? 'warning' : false
70 | },
71 | plugins: isProd
72 | ? [
73 | // new webpack.optimize.UglifyJsPlugin({
74 | // compress: { warnings: false }
75 | // }),
76 | // new webpack.optimize.AggressiveSplittingPlugin({
77 | // minSize: 30000,
78 | // maxSize: 50000,
79 | // chunkOverhead: 0,
80 | // entryChunkMultiplicator: 2
81 | // }),
82 | new UglifyJSPlugin(),
83 | new webpack.optimize.ModuleConcatenationPlugin(),
84 | new ExtractTextPlugin({
85 | filename: 'common.[chunkhash].css',
86 | allChunks: true
87 | })
88 | ]
89 | : [
90 | new FriendlyErrorsPlugin()
91 | ]
92 | }
--------------------------------------------------------------------------------
/build/webpack.client.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack')
2 | const merge = require('webpack-merge')
3 | const base = require('./webpack.base.config')
4 | const SWPrecachePlugin = require('sw-precache-webpack-plugin')
5 | const VueSSRClientPlugin = require('vue-server-renderer/client-plugin')
6 |
7 | const config = merge(base, {
8 | entry: {
9 | app: './src/entry-client.js'
10 | },
11 | resolve: {
12 | alias: {
13 | 'create-api': './create-api-client.js'
14 | }
15 | },
16 | plugins: [
17 | // strip dev-only code in Vue source
18 | new webpack.DefinePlugin({
19 | 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'),
20 | 'process.env.VUE_ENV': '"client"'
21 | }),
22 | // extract vendor chunks for better caching
23 | new webpack.optimize.CommonsChunkPlugin({
24 | name: 'vendor',
25 | minChunks: function (module) {
26 | // a module is extracted into the vendor chunk if...
27 | return (
28 | // it's inside node_modules
29 | /node_modules/.test(module.context) &&
30 | // and not a CSS file (due to extract-text-webpack-plugin limitation)
31 | !/\.css$/.test(module.request)
32 | )
33 | }
34 | }),
35 | // extract webpack runtime & manifest to avoid vendor chunk hash changing
36 | // on every build.
37 | new webpack.optimize.CommonsChunkPlugin({
38 | name: 'manifest'
39 | }),
40 | new VueSSRClientPlugin()
41 | ]
42 | })
43 |
44 | if (process.env.NODE_ENV === 'production') {
45 | //TODO:
46 | config.plugins.push(
47 | // auto generate service worker
48 | new SWPrecachePlugin({
49 | cacheId: 'vue-hn',
50 | filename: 'service-worker.js',
51 | minify: true,
52 | dontCacheBustUrlsMatching: /./,
53 | staticFileGlobsIgnorePatterns: [/\.map$/, /\.json$/],
54 | runtimeCaching: [
55 | {
56 | urlPattern: '/',
57 | handler: 'networkFirst'
58 | },
59 | {
60 | urlPattern: /\/(top|new|show|ask|jobs)/,
61 | handler: 'networkFirst'
62 | },
63 | {
64 | urlPattern: '/item/:id',
65 | handler: 'networkFirst'
66 | },
67 | {
68 | urlPattern: '/user/:id',
69 | handler: 'networkFirst'
70 | }
71 | ]
72 | })
73 | )
74 | }
75 |
76 | module.exports = config
--------------------------------------------------------------------------------
/build/webpack.server.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack')
2 | const merge = require('webpack-merge')
3 | const base = require('./webpack.base.config')
4 | const nodeExternals = require('webpack-node-externals')
5 | const VueSSRServerPlugin = require('vue-server-renderer/server-plugin')
6 |
7 | module.exports = merge(base, {
8 | target: 'node',
9 | devtool: '#source-map',
10 | entry: './src/entry-server.js',
11 | output: {
12 | filename: 'server-bundle.js',
13 | libraryTarget: 'commonjs2'
14 | },
15 | resolve: {
16 | alias: {
17 | 'create-api': './create-api-server.js'
18 | }
19 | },
20 | // https://webpack.js.org/configuration/externals/#externals
21 | // https://github.com/liady/webpack-node-externals
22 | externals: nodeExternals({
23 | // do not externalize CSS files in case we need to import it from a dep
24 | whitelist: [/\.css$/, /\.vue$/]
25 | }),
26 | plugins: [
27 | new webpack.DefinePlugin({
28 | 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'),
29 | 'process.env.VUE_ENV': '"server"'
30 | }),
31 | new VueSSRServerPlugin()
32 | ]
33 | })
--------------------------------------------------------------------------------
/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/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 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "carbon",
3 | "version": "1.0.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "node server",
7 | "start": "cross-env NODE_ENV=production node server",
8 | "build": "rimraf dist && npm run build:client && npm run build:server",
9 | "build:client": "cross-env NODE_ENV=production webpack --config build/webpack.client.config.js --progress --hide-modules",
10 | "build:server": "cross-env NODE_ENV=production webpack --config build/webpack.server.config.js --progress --hide-modules"
11 | },
12 | "dependencies": {
13 | "axios": "^0.16.2",
14 | "compression": "^1.7.1",
15 | "element-ui": "^1.4.7",
16 | "iview": "^2.4.0",
17 | "route-cache": "^0.4.3",
18 | "serve-favicon": "^2.4.5",
19 | "sw-precache-webpack-plugin": "^0.11.4",
20 | "vue": "^2.5.2",
21 | "vue-router": "^3.0.1",
22 | "vue-server-renderer": "^2.5.2",
23 | "vuex": "^3.0.0",
24 | "vuex-router-sync": "^5.0.0"
25 | },
26 | "devDependencies": {
27 | "autoprefixer": "^7.1.2",
28 | "axios-mock-adapter": "^1.9.0",
29 | "babel-core": "^6.22.1",
30 | "babel-eslint": "^7.1.1",
31 | "babel-loader": "^7.1.1",
32 | "babel-plugin-istanbul": "^4.1.1",
33 | "babel-plugin-transform-runtime": "^6.22.0",
34 | "babel-preset-env": "^1.3.2",
35 | "babel-preset-stage-2": "^6.22.0",
36 | "babel-register": "^6.22.0",
37 | "chai": "^3.5.0",
38 | "chalk": "^2.0.1",
39 | "chromedriver": "^2.33.1",
40 | "connect-history-api-fallback": "^1.3.0",
41 | "copy-webpack-plugin": "^4.0.1",
42 | "cross-env": "^5.0.1",
43 | "cross-spawn": "^5.0.1",
44 | "css-loader": "^0.28.0",
45 | "cssnano": "^3.10.0",
46 | "eslint": "^3.19.0",
47 | "eslint-config-standard": "^6.2.1",
48 | "eslint-friendly-formatter": "^3.0.0",
49 | "eslint-loader": "^1.7.1",
50 | "eslint-plugin-html": "^3.0.0",
51 | "eslint-plugin-promise": "^3.4.0",
52 | "eslint-plugin-standard": "^2.0.1",
53 | "eventsource-polyfill": "^0.9.6",
54 | "express": "^4.16.2",
55 | "extract-text-webpack-plugin": "^3.0.1",
56 | "file-loader": "^0.11.1",
57 | "friendly-errors-webpack-plugin": "^1.1.3",
58 | "html-webpack-plugin": "^2.28.0",
59 | "http-proxy-middleware": "^0.17.3",
60 | "inject-loader": "^3.0.0",
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-phantomjs-shim": "^1.4.0",
66 | "karma-sinon-chai": "^1.3.1",
67 | "karma-sourcemap-loader": "^0.3.7",
68 | "karma-spec-reporter": "0.0.31",
69 | "karma-webpack": "^2.0.2",
70 | "mocha": "^3.2.0",
71 | "mockjs": "^1.0.1-beta3",
72 | "nightwatch": "^0.9.12",
73 | "opn": "^5.1.0",
74 | "optimize-css-assets-webpack-plugin": "^3.2.0",
75 | "ora": "^1.2.0",
76 | "phantomjs-prebuilt": "^2.1.14",
77 | "postcss-cssnext": "^3.0.2",
78 | "postcss-for": "^2.1.1",
79 | "postcss-import": "^11.0.0",
80 | "postcss-loader": "^2.0.6",
81 | "postcss-remove-root": "0.0.2",
82 | "rimraf": "^2.6.0",
83 | "selenium-server": "^3.0.1",
84 | "semver": "^5.3.0",
85 | "shelljs": "^0.7.6",
86 | "sinon": "^2.1.0",
87 | "sinon-chai": "^2.8.0",
88 | "uglifyjs-webpack-plugin": "^1.0.0-beta.3",
89 | "url-loader": "^0.5.8",
90 | "vue-loader": "^13.0.4",
91 | "vue-style-loader": "^3.0.1",
92 | "vue-template-compiler": "^2.5.2",
93 | "webpack": "^3.8.1",
94 | "webpack-bundle-analyzer": "^2.9.0",
95 | "webpack-dev-middleware": "^1.12.0",
96 | "webpack-hot-middleware": "^2.20.0",
97 | "webpack-merge": "^4.1.0",
98 | "webpack-node-externals": "^1.6.0"
99 | },
100 | "engines": {
101 | "node": ">= 4.0.0",
102 | "npm": ">= 3.0.0"
103 | },
104 | "browserslist": [
105 | "> 1%",
106 | "last 2 versions",
107 | "not ie <= 8"
108 | ]
109 | }
110 |
--------------------------------------------------------------------------------
/public/logo-48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liurongliurong/vue/260ea54c82bc2742ea0fc9b9705133ae8db256f5/public/logo-48.png
--------------------------------------------------------------------------------
/server.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const path = require('path')
3 | const LRU = require('lru-cache')
4 | const express = require('express')
5 | const favicon = require('serve-favicon')
6 | const compression = require('compression')
7 | const microcache = require('route-cache')
8 | const resolve = file => path.resolve(__dirname, file)
9 | const { createBundleRenderer } = require('vue-server-renderer')
10 |
11 | const isProd = process.env.NODE_ENV === 'production'
12 | const useMicroCache = process.env.MICRO_CACHE !== 'false'
13 | const serverInfo =
14 | `express/${require('express/package.json').version} ` +
15 | `vue-server-renderer/${require('vue-server-renderer/package.json').version}`
16 |
17 | const app = express()
18 |
19 | function createRenderer (bundle, options) {
20 | // https://github.com/vuejs/vue/blob/dev/packages/vue-server-renderer/README.md#why-use-bundlerenderer
21 | return createBundleRenderer(bundle, Object.assign(options, {
22 | // for component caching
23 | cache: LRU({
24 | max: 1000,
25 | maxAge: 1000 * 60 * 15
26 | }),
27 | // this is only needed when vue-server-renderer is npm-linked
28 | basedir: resolve('./dist'),
29 | // recommended for performance
30 | runInNewContext: false
31 | }))
32 | }
33 |
34 | let renderer
35 | let readyPromise
36 | const templatePath = resolve('./src/index.template.html')
37 | if (isProd) {
38 | // In production: create server renderer using template and built server bundle.
39 | // The server bundle is generated by vue-ssr-webpack-plugin.
40 | const template = fs.readFileSync(templatePath, 'utf-8')
41 | const bundle = require('./dist/vue-ssr-server-bundle.json')
42 | // The client manifests are optional, but it allows the renderer
43 | // to automatically infer preload/prefetch links and directly add
92 |
93 |
226 |
--------------------------------------------------------------------------------
/src/app.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 | import ElementUI from 'element-ui'
4 | import 'element-ui/lib/theme-default/index.css'
5 | import { sync } from 'vuex-router-sync'
6 | import titleMixin from './util/title'
7 | import './assets/css/index.css'
8 | import './assets/iconfont/iconfont.css'
9 | import { createStore } from './store'
10 | import { createRouter } from './router'
11 |
12 | Vue.use(ElementUI)
13 |
14 | Vue.directive('number', {
15 | bind (el, binding, vnode) {
16 | let key = binding.expression
17 | let num = parseInt(binding.arg) > 0 ? parseInt(binding.arg) : 0
18 | let value = el.value
19 | let flag = true
20 | el.addEventListener('input', () => {
21 | let nowValue = el.value
22 | if (nowValue !== '') {
23 | if (num === 0) {
24 | if (nowValue.search(/^[0-9]+$/) === -1 || nowValue === '') {
25 | el.value = value
26 | }
27 | } else {
28 | let re = new RegExp('^[0-9]+(.[0-9]{0,' + num + '})?$')
29 | if (nowValue.search(re) === -1) {
30 | el.value = value
31 | }
32 | }
33 | }
34 | value = el.value
35 | flag = false
36 | vnode.context[key] = el.value
37 | })
38 |
39 | vnode.context.$watch(key, (val, oldVal) => {
40 | if (!flag) {
41 | flag = true
42 | return false
43 | }
44 | if (!Number.isNaN(val)) {
45 | if (num === 0) {
46 | el.value = parseInt(val)
47 | } else {
48 | el.value = parseFloat(val).toFixed(2)
49 | }
50 | }
51 | })
52 | }
53 | })
54 |
55 | // mixin for handling title
56 | Vue.mixin(titleMixin)
57 |
58 | // Expose a factory function that creates a fresh set of store, router,
59 | // app instances on each call (which is called for each SSR request)
60 | export function createApp () {
61 | // create store and router instances
62 | const store = createStore()
63 | const router = createRouter()
64 |
65 | // sync the router with the vuex store.
66 | // this registers `store.state.route`
67 | sync(store, router)
68 |
69 | // create the app instance.
70 | // here we inject the router, store and ssr context to all child components,
71 | // making them available everywhere as `this.$router` and `this.$store`.
72 | const app = new Vue({
73 | router,
74 | store,
75 | render: h => h(App)
76 | })
77 |
78 | // expose the app, the router and the store.
79 | // note we are not mounting the app here, since bootstrapping will be
80 | // different depending on whether we are in a browser or on the server.
81 | return { app, router, store }
82 | }
83 |
--------------------------------------------------------------------------------
/src/assets/css/index.css:
--------------------------------------------------------------------------------
1 | @import './var.css';
2 | @import './reset.css';
3 | @import './marginPadding.css';
4 | @import './project.css';
5 |
6 | html{
7 | overflow-x: hidden;
8 | }
9 |
10 | body{
11 | min-width: var(--contentWidth);
12 | font-size: 14px;
13 | margin-right: calc(100% - 100vw);
14 | font-family: '微软雅黑';
15 | }
16 |
17 | .container{
18 | width: var(--contentWidth);
19 | margin: 0 auto;
20 | }
21 |
22 | a{
23 | text-decoration: none;
24 | }
25 |
26 | ::-webkit-scrollbar {
27 | width: 6px;
28 | }
29 |
30 | ::-webkit-scrollbar-thumb {
31 | background-color: #6e6e6e;
32 | outline: 1px solid #333;
33 | }
34 |
35 | .overflow{
36 | // overflow: hidden;
37 | &:after{
38 | clear: both;
39 | display: block;
40 | content: ''
41 | }
42 | }
43 |
44 | .float-left{
45 | float: left;
46 | }
47 |
48 | .float-right{
49 | float: right;
50 | }
51 |
52 | .cursor-pointer{
53 | cursor: pointer;
54 | }
55 |
56 | .bold{
57 | font-weight: bold;
58 | }
59 |
60 | .relative{
61 | position: relative;
62 | }
63 |
64 | .inline-block{
65 | display: inline-block;
66 | }
67 |
68 | .ivu-loading-bar {
69 | width: 100%;
70 | position: fixed;
71 | top: 0;
72 | left: 0;
73 | right: 0;
74 | z-index: 2000;
75 | }
76 |
77 | .ivu-loading-bar-inner {
78 | transition: width .2s linear;
79 | }
80 |
81 | .ivu-loading-bar-inner-color-primary {
82 | background-color: #2d8cf0;
83 | }
84 |
85 | .ivu-loading-bar-inner-failed-color-error {
86 | background-color: #ed3f14;
87 | }
88 |
--------------------------------------------------------------------------------
/src/assets/css/marginPadding.css:
--------------------------------------------------------------------------------
1 | @for $i from 10 to 60 by 5{
2 | .mt-$i { margin-top: $(i)px; }
3 | .ml-$i { margin-left: $(i)px; }
4 | .mb-$i { margin-bottom: $(i)px; }
5 | .mr-$i { margin-right: $(i)px; }
6 | }
--------------------------------------------------------------------------------
/src/assets/css/project.css:
--------------------------------------------------------------------------------
1 | .el-table,
2 | /* .el-table th,
3 | .el-table th>.cell, */
4 | .el-table td,
5 | .el-table th.is-leaf,
6 | .el-table::after,
7 | .el-table::before{
8 | background-color: #fff;
9 | border: none;
10 | }
11 |
12 | .el-table th>.cell{
13 | padding-top: 20px;
14 | padding-bottom: 20px;
15 | }
16 |
17 | .el-table td>.cell{
18 | white-space: nowrap;
19 | overflow: hidden;
20 | text-overflow: ellipsis;
21 | }
22 |
23 | .el-table td{
24 | padding-bottom: 10px;
25 | padding-top: 10px;
26 | border-bottom: 1px solid #eee;
27 | }
28 |
29 | .el-table--enable-row-hover .el-table__body tr:hover>td{
30 | /* background-color: rgb(251,251,252); */
31 | background-color: #f5f5f5;
32 | }
33 |
34 | .el-menu{
35 | background-color: #fff;
36 | }
37 |
38 | .el-button{
39 | min-width: 65px;
40 | }
41 |
42 | .el-button--success{
43 | background-color: var(--mainColor);
44 | color: #fff;
45 | border: none;
46 | &:focus,
47 | &:hover{
48 | background-color: #3BD89C;
49 | color: #fff;
50 | }
51 | &:active{
52 | background-color: #1CB57A;
53 | color: #fff;
54 | }
55 | }
56 |
57 | .el-button--danger{
58 | background-color: var(--redColor);
59 | color: #fff;
60 | &:focus,
61 | &:hover{
62 | background-color: #F94553;
63 | color: #fff;
64 | }
65 | &:active{
66 | background-color: #DD1423;
67 | color: #fff;
68 | }
69 | }
70 |
71 | .el-button--success.is-plain.is-hover {
72 | background: #fff;
73 | border-color: #13ce66;
74 | color: #13ce66;
75 | }
76 |
77 | .el-button.btn-block{
78 | display: block;
79 | width: 100%;
80 | }
81 |
82 | .el-dialog__header{
83 | padding: 23px 32px 16px;
84 | background-color: #f9f9f9;
85 | & .el-dialog__close{
86 | color: #333;
87 | font-size: 12px;
88 | }
89 | }
90 |
91 | .el-pagination{
92 | text-align: right;
93 | margin-top: 22px;
94 | }
95 |
96 | .el-pagination__total,
97 | .el-pagination__sizes{
98 | float: left;
99 | }
100 |
101 | .el-form-item__label:before{
102 | display: none;
103 | }
104 |
105 | .el-form{
106 | & .el-input,
107 | & .el-select,
108 | & .el-input-number{
109 | width: 260px;
110 | }
111 | }
112 |
113 | .code-input{
114 | width: 164px !important;
115 | & .el-input__inner{
116 | border-top-right-radius: 0;
117 | border-bottom-right-radius: 0;
118 | border-right: none;
119 | }
120 | }
121 |
122 | #app .send-code{
123 | width: 97px;
124 | font-size: 12px;
125 | height: 36px;
126 | border-top-left-radius: 0;
127 | border-bottom-left-radius: 0;
128 | vertical-align: middle;
129 | }
130 |
131 | .bank-select{
132 | & .el-select-dropdown__list{
133 | padding: 0;
134 | }
135 | & .el-select-dropdown__item{
136 | height: auto;
137 | }
138 | & .el-scrollbar__wrap{
139 | overflow: auto;
140 | }
141 | }
142 |
143 | html,
144 | body,
145 | #app{
146 | height: 100%;
147 | }
148 |
149 | body{
150 | background-color: #f2f2f2;
151 | padding-right: 0 !important;
152 | }
153 |
154 | .title1{
155 | font-size: 18px;
156 | margin-bottom: 20px;
157 | border-bottom: 2px solid rgb(238,238,238);
158 | &.normal{
159 | font-size: 16px;
160 | }
161 | & .right{
162 | float: right;
163 | font-size: 14px;
164 | color: #999;
165 | font-weight: normal;
166 | margin-top: 11px;
167 | }
168 | &>span{
169 | display: inline-block;
170 | padding: 11px 0;
171 | border-bottom: 2px solid var(--mainColor);
172 | margin-bottom: -2px;
173 | }
174 | }
175 |
176 | .title2{
177 | font-size: 16px;
178 | font-weight: bold;
179 | padding: 23px 0 20px;
180 | border-bottom: 1px solid #ddd;
181 | & .right{
182 | float: right;
183 | }
184 | &.normal{
185 | font-weight: normal;
186 | }
187 | }
188 |
189 | .title3{
190 | border-bottom: 1px solid #ddd;
191 | font-size: 16px;
192 | padding-bottom: 10px;
193 | &>span:first-child{
194 | border-left: 2px solid var(--mainColor);
195 | padding-left: 8px;
196 | font-weight: bold;
197 | }
198 | }
199 |
200 | .title4{
201 | font-size: 18px;
202 | padding-left: 10px;
203 | border-left: 2px solid var(--mainColor);
204 | }
205 |
206 | .content{
207 | background-color: #f0f2f5;
208 | min-height: calc(100vh - 386px);
209 | overflow: hidden;
210 | }
211 |
212 | .tab1{
213 | overflow: visible;
214 | background-color: #f9f9f9;
215 | border-bottom: 1px solid #e1e1e1;
216 | border-top: 1px solid #e1e1e1;
217 | & .tab-item{
218 | cursor: pointer;
219 | display: inline-block;
220 | vertical-align: top;
221 | padding: 17px 24px;
222 | color: #333;
223 | font-size: 16px;
224 | border: 1px solid transparent;
225 | border-bottom: none;
226 | border-top-width: 3px;
227 | &.active{
228 | font-weight: bold;
229 | border-top-color: var(--mainColor);
230 | border-left-color: #e1e1e1;
231 | border-right-color: #e1e1e1;
232 | background-color: #fff;
233 | position: relative;
234 | &:before{
235 | content: '';
236 | position: absolute;
237 | bottom: -1px;
238 | left: 0;
239 | width: 100%;
240 | height: 1px;
241 | border-bottom: 1px solid #fff;
242 | }
243 | }
244 | }
245 | }
246 |
247 | .tab2{
248 | margin-top: 22px;
249 | overflow: visible;
250 | border-bottom: 1px solid #ddd;
251 | & .tab-item{
252 | color: #333;
253 | cursor: pointer;
254 | display: inline-block;
255 | vertical-align: top;
256 | padding: 17px 24px;
257 | font-size: 16px;
258 | border: 1px solid transparent;
259 | border-bottom: none;
260 | border-top-width: 3px;
261 | &.active{
262 | font-weight: bold;
263 | border-top-color: var(--mainColor);
264 | color: var(--mainColor);
265 | border-left-color: #ddd;
266 | border-right-color: #ddd;
267 | background-color: #fff;
268 | position: relative;
269 | &:before{
270 | content: '';
271 | position: absolute;
272 | bottom: -1px;
273 | left: 0;
274 | width: 100%;
275 | height: 1px;
276 | border-bottom: 1px solid #fff;
277 | }
278 | }
279 | }
280 | }
281 |
282 | .list-table{
283 | margin-top: 38px;
284 | margin-bottom: 31px;
285 | width: 100%;
286 | & th{
287 | color: #999;
288 | font-size: 12px;
289 | text-align: left;
290 | padding-bottom: 15px;
291 | }
292 | & td{
293 | &:first-child{
294 | color: var(--mainColor);
295 | }
296 | font-size: 20px;
297 | color: #1d1d1d;
298 | }
299 | }
300 |
301 | .search-table{
302 | border-bottom: 1px dotted #ddd;
303 | & th>.cell{
304 | background-color: #f9f9f9;
305 | line-height: 1;
306 | padding: 16px 18px 15px;
307 | border-bottom: 1px solid #ddd;
308 | }
309 | & td{
310 | border-bottom: 1px dotted #ddd;
311 | }
312 | }
313 |
314 | .filtrate{
315 | margin-top: 19px;
316 | margin-bottom: 10px;
317 | & .filtrate-item{
318 | margin-bottom: 15px;
319 | }
320 | & .item{
321 | display: inline-block;
322 | padding: 6px 14px;
323 | cursor: pointer;
324 | margin-right: 20px;
325 | &.active{
326 | background-color: var(--mainColor);
327 | border-radius: 2px;
328 | color: #fff;
329 | }
330 | }
331 | }
332 |
333 | .btn{
334 | background: #20a0ff;
335 | font-size: 14px;
336 | height: 36px;
337 | line-height: 36px;
338 | color: #fff;
339 | cursor: pointer;
340 | border-radius: 4px;
341 | &:hover{
342 | background-color: #4db3ff;
343 | }
344 | }
345 |
346 | .form-btn-block{
347 | width: 260px;
348 | }
349 |
350 | .btn-grey{
351 | background-color: #ddd;
352 | color: #999;
353 | border: none;
354 | &:hover{
355 | color: #fff;
356 | }
357 | }
358 |
359 | .btn-dark{
360 | background-color: #4D5C6F;
361 | color: #fff;
362 | border: none;
363 | &:hover{
364 | color: #fff;
365 | }
366 | }
367 |
368 | .btn-orange{
369 | background-color: #ff7200;
370 | color: #fff;
371 | border: none;
372 | &:hover{
373 | color: #fff;
374 | }
375 | }
376 |
377 | .icon-zhongguoyinhang,
378 | .icon-zhongguoyouzhengchuxuyinhang,
379 | .icon-nongyeyinhang,
380 | .icon-jiansheyinhang,
381 | .icon-jiaotongyinhang,
382 | .icon-gongshangyinhang{
383 | &.iconfont{
384 | font-size: 22px;
385 | margin-left: 14px;
386 | margin-right: 8px;
387 | vertical-align: middle;
388 | }
389 | }
390 |
391 | .icon-zhongguoyinhang{
392 | color: rgb(151, 32, 48);
393 | }
394 |
395 | .icon-zhongguoyouzhengchuxuyinhang{
396 | color: rgb(0, 126, 62);
397 | }
398 |
399 | .icon-nongyeyinhang{
400 | color: rgb(0, 133, 102);
401 | }
402 |
403 | .icon-jiansheyinhang{
404 | color: rgb(5, 61, 143);
405 | }
406 |
407 | .icon-jiaotongyinhang{
408 | color: rgb(29, 32, 135);
409 | }
410 |
411 | .icon-gongshangyinhang{
412 | color: rgb(210, 0, 0);
413 | }
414 |
415 | .form-box1{
416 | width: 400px;
417 | margin: 0 auto;
418 | & .head{
419 | font-size: 20px;
420 | font-weight: bold;
421 | text-align: center;
422 | padding-top: 50px;
423 | margin-bottom: 45px;
424 | }
425 | & .el-form-item{
426 | position: relative;
427 | }
428 | & .form{
429 | & .el-form-item__label{
430 | position: absolute;
431 | z-index: 1;
432 | padding-left: 17px;
433 | height: 47px;
434 | line-height: 47px;
435 | padding-top: 0;
436 | padding-bottom: 0;
437 | }
438 | & .el-input,
439 | & .el-select{
440 | width: 100%;
441 | &.form-code-input{
442 | width: 280px;
443 | }
444 | }
445 | & .el-input__inner{
446 | padding-left: 117px;
447 | height: 47px;
448 | }
449 | & .el-input__inner::placeholder,
450 | & .el-input__inner::-webkit-input-placeholder{
451 | color: #cfcfcf;
452 | }
453 | }
454 | & .send-code-btn{
455 | display: inline-block;
456 | height: 47px;
457 | line-height: 47px;
458 | width: 110px;
459 | border-radius: 4px;
460 | color: #666;
461 | background-color: #f8f9fb;
462 | border: 1px solid #ddd;
463 | vertical-align: middle;
464 | text-align: center;
465 | margin-left: 10px;
466 | cursor: pointer;
467 | }
468 | }
469 |
470 | .breadcrumb{
471 | & a{
472 | color: #1d1d1d;
473 | font-weight: normal;
474 | }
475 | & .angle{
476 | display: inline-block;
477 | margin: 0 10px;
478 | font-weight: normal;
479 | }
480 | }
--------------------------------------------------------------------------------
/src/assets/css/projectVar.css:
--------------------------------------------------------------------------------
1 | :root {
2 | /* css next */
3 | --mainColor: #29c086;
4 | --redColor: #F52F3E;
5 | --headerTopHeight: 36px;
6 | --headerTopBgColor: #4a4a4a;
7 | --contentWidth: 1180px;
8 | --contentHorizontalPadding: 30px;
9 | --contentVerticalPadding: 39px;
10 | }
11 |
--------------------------------------------------------------------------------
/src/assets/css/reset.css:
--------------------------------------------------------------------------------
1 | html, body, div, span, object, iframe,
2 | h1, h2, h3, h4, h5, h6, p, blockquote, pre,
3 | abbr, address, cite, code,
4 | del, dfn, em, img, ins, kbd, q, samp,
5 | small, strong, sub, sup, var,
6 | b, i,
7 | dl, dt, dd, ol, ul, li,
8 | fieldset, form, label, legend,
9 | table, caption, tbody, tfoot, thead, tr, th, td,
10 | article, aside, canvas, details, figcaption, figure,
11 | footer, header, hgroup, menu, nav, section, summary,
12 | time, mark, audio, video {
13 | margin:0;
14 | padding:0;
15 | border:0;
16 | outline:0;
17 | font-size:100%;
18 | vertical-align:baseline;
19 | background:transparent;
20 | box-sizing: border-box;
21 | }
22 |
23 | body {
24 | line-height:1;
25 | }
26 |
27 | :focus {
28 | outline: 1;
29 | }
30 |
31 | article,aside,canvas,details,figcaption,figure,
32 | footer,header,hgroup,menu,nav,section,summary {
33 | display:block;
34 | }
35 |
36 | nav ul {
37 | list-style:none;
38 | }
39 |
40 | blockquote, q {
41 | quotes:none;
42 | }
43 |
44 | blockquote:before, blockquote:after,
45 | q:before, q:after {
46 | content:'';
47 | content:none;
48 | }
49 |
50 | a {
51 | margin:0;
52 | padding:0;
53 | border:0;
54 | font-size:100%;
55 | vertical-align:baseline;
56 | background:transparent;
57 | }
58 |
59 | ins {
60 | background-color:#ff9;
61 | color:#000;
62 | text-decoration:none;
63 | }
64 |
65 | mark {
66 | background-color:#ff9;
67 | color:#000;
68 | font-style:italic;
69 | font-weight:bold;
70 | }
71 |
72 | del {
73 | text-decoration: line-through;
74 | }
75 |
76 | abbr[title], dfn[title] {
77 | border-bottom:1px dotted #000;
78 | cursor:help;
79 | }
80 |
81 | table {
82 | border-collapse:collapse;
83 | border-spacing:0;
84 | }
85 |
86 | hr {
87 | display:block;
88 | height:1px;
89 | border:0;
90 | border-top:1px solid #cccccc;
91 | margin:1em 0;
92 | padding:0;
93 | }
94 |
95 | input, select {
96 | vertical-align:middle;
97 | box-sizing: border-box;
98 | outline: none;
99 | }
--------------------------------------------------------------------------------
/src/assets/css/var.css:
--------------------------------------------------------------------------------
1 | @import './projectVar.css';
2 |
3 | :root {
4 |
5 | }
--------------------------------------------------------------------------------
/src/assets/iconfont/iconfont.css:
--------------------------------------------------------------------------------
1 |
2 | @font-face {font-family: "iconfont";
3 | src: url('iconfont.eot?t=1508481610089'); /* IE9*/
4 | src: url('iconfont.eot?t=1508481610089#iefix') format('embedded-opentype'), /* IE6-IE8 */
5 | url('data:application/x-font-woff;charset=utf-8;base64,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') format('woff'),
6 | url('iconfont.ttf?t=1508481610089') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
7 | url('iconfont.svg?t=1508481610089#iconfont') format('svg'); /* iOS 4.1- */
8 | }
9 |
10 | .iconfont {
11 | font-family:"iconfont" !important;
12 | font-size:16px;
13 | font-style:normal;
14 | -webkit-font-smoothing: antialiased;
15 | -moz-osx-font-smoothing: grayscale;
16 | }
17 |
18 | .icon-jiahao:before { content: "\ead8"; }
19 |
20 | .icon-zhengquetianchong:before { content: "\e6e3"; }
21 |
22 | .icon-dengyu:before { content: "\e601"; }
23 |
24 | .icon-cheng:before { content: "\e612"; }
25 |
26 | .icon-jiaotongyinhang:before { content: "\e67f"; }
27 |
28 | .icon-gongshangyinhang:before { content: "\e640"; }
29 |
30 | .icon-jiansheyinhang:before { content: "\e602"; }
31 |
32 | .icon-copy_icon:before { content: "\e659"; }
33 |
34 | .icon-message_icon:before { content: "\e65b"; }
35 |
36 | .icon-nongyeyinhang:before { content: "\e603"; }
37 |
38 | .icon-warning:before { content: "\e600"; }
39 |
40 | .icon-business_license_ico:before { content: "\e6a7"; }
41 |
42 | .icon-salary_icon:before { content: "\e6b9"; }
43 |
44 | .icon-zhongguoyouzhengchuxuyinhang:before { content: "\e84e"; }
45 |
46 | .icon-zhongguoyinhang:before { content: "\e62d"; }
47 |
48 |
--------------------------------------------------------------------------------
/src/assets/iconfont/iconfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liurongliurong/vue/260ea54c82bc2742ea0fc9b9705133ae8db256f5/src/assets/iconfont/iconfont.eot
--------------------------------------------------------------------------------
/src/assets/iconfont/iconfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liurongliurong/vue/260ea54c82bc2742ea0fc9b9705133ae8db256f5/src/assets/iconfont/iconfont.ttf
--------------------------------------------------------------------------------
/src/assets/iconfont/iconfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liurongliurong/vue/260ea54c82bc2742ea0fc9b9705133ae8db256f5/src/assets/iconfont/iconfont.woff
--------------------------------------------------------------------------------
/src/assets/images/erweima.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liurongliurong/vue/260ea54c82bc2742ea0fc9b9705133ae8db256f5/src/assets/images/erweima.jpg
--------------------------------------------------------------------------------
/src/assets/images/google.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liurongliurong/vue/260ea54c82bc2742ea0fc9b9705133ae8db256f5/src/assets/images/google.png
--------------------------------------------------------------------------------
/src/assets/images/left_bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liurongliurong/vue/260ea54c82bc2742ea0fc9b9705133ae8db256f5/src/assets/images/left_bg.jpg
--------------------------------------------------------------------------------
/src/assets/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liurongliurong/vue/260ea54c82bc2742ea0fc9b9705133ae8db256f5/src/assets/images/logo.png
--------------------------------------------------------------------------------
/src/assets/images/logo_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liurongliurong/vue/260ea54c82bc2742ea0fc9b9705133ae8db256f5/src/assets/images/logo_icon.png
--------------------------------------------------------------------------------
/src/assets/images/logo_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liurongliurong/vue/260ea54c82bc2742ea0fc9b9705133ae8db256f5/src/assets/images/logo_white.png
--------------------------------------------------------------------------------
/src/assets/images/safe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/liurongliurong/vue/260ea54c82bc2742ea0fc9b9705133ae8db256f5/src/assets/images/safe.png
--------------------------------------------------------------------------------
/src/components/BankSelect.vue:
--------------------------------------------------------------------------------
1 |
2 |
可用余额(元) | 10 |提现冻结(元) | 11 |交易冻结(元) | 12 |
---|---|---|
{{capitalAccount.balance}} | 17 |{{capitalAccount.withdrawFreeze}} | 18 |{{capitalAccount.dealFreeze}} | 19 |
可用余额(元) | 10 |提现冻结(元) | 11 |交易冻结(元) | 12 |
---|---|---|
{{carbonAccount.balance}} | 17 |{{carbonAccount.withdrawFreeze}} | 18 |{{carbonAccount.dealFreeze}} | 19 |
可用余额(元) | 10 |提现冻结(元) | 11 |交易冻结(元) | 12 |
---|---|---|
{{capitalAccount.balance}} | 17 |{{capitalAccount.withdrawFreeze}} | 18 |{{capitalAccount.dealFreeze}} | 19 |
可用余额(千克) | 29 |提现冻结(千克) | 30 |
---|---|
{{carbonAccount.balance}} | 35 |{{carbonAccount.withdrawFreeze}} | 36 |
碳金融
9 |碳金融
9 |碳金融
9 |碳金融
9 |碳金融
9 |碳金融
9 |碳金融
9 |