├── .babelrc ├── .editorconfig ├── .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 ├── config ├── dev.env.js ├── index.js └── prod.env.js ├── index.html ├── package-lock.json ├── package.json ├── project.config.json ├── src ├── App.vue ├── Store │ └── store.js ├── api │ ├── api.js │ └── apiConfig.js ├── components │ └── electricityDialog.vue ├── main.js ├── pages │ ├── electricitySet │ │ ├── coupons │ │ │ ├── index.vue │ │ │ └── main.js │ │ ├── couponsDetails │ │ │ ├── index.vue │ │ │ └── main.js │ │ └── periodElectricity │ │ │ ├── index.vue │ │ │ └── main.js │ ├── home │ │ ├── electricityBills │ │ │ ├── index.vue │ │ │ └── main.js │ │ ├── electricityBillsDetails │ │ │ ├── index.vue │ │ │ └── main.js │ │ ├── moneyBills │ │ │ ├── index.vue │ │ │ └── main.js │ │ ├── moneyBillsDetails │ │ │ ├── index.vue │ │ │ └── main.js │ │ ├── useCondition │ │ │ ├── index.vue │ │ │ └── main.js │ │ └── withdrawalApply │ │ │ ├── index.vue │ │ │ └── main.js │ ├── login │ │ ├── index.vue │ │ ├── loginSuccess │ │ │ ├── index.vue │ │ │ └── main.js │ │ └── main.js │ ├── qualification │ │ ├── quality │ │ │ ├── index.vue │ │ │ └── main.js │ │ ├── qualityFailed │ │ │ ├── index.vue │ │ │ └── main.js │ │ └── submitSuccess │ │ │ ├── index.vue │ │ │ └── main.js │ ├── tabBar │ │ ├── electricitySet │ │ │ ├── index.vue │ │ │ └── main.js │ │ ├── home │ │ │ ├── index.vue │ │ │ └── main.js │ │ └── mine │ │ │ ├── index.vue │ │ │ └── main.js │ ├── useAgreement │ │ ├── index.vue │ │ └── main.js │ └── welcome │ │ ├── index.vue │ │ └── main.js └── utils │ ├── WxValidate.js │ ├── ald-stat-conf.js │ ├── ald-stat.js │ ├── index.js │ ├── md5.js │ ├── numberAnimate.js │ └── qiniuUploader.js └── static ├── .gitkeep ├── assets └── scss │ ├── btn.scss │ ├── components │ └── dialog.scss │ ├── electricitySet │ ├── coupons.scss │ ├── couponsDetails.scss │ ├── electricitySet.scss │ └── periodElectricity.scss │ ├── home │ ├── electricityBills.scss │ ├── home.scss │ ├── moneyBills.scss │ └── withdrawalApply.scss │ ├── mine │ └── mine.scss │ ├── quality │ ├── quality.scss │ └── submit.scss │ └── style.scss ├── img ├── LOGO.png ├── history_coupon │ ├── ic_expired.png │ ├── img_1-2.png │ ├── img_3.png │ └── img_coupon2.png ├── index_charge_fund │ ├── ic_Settlement.png │ ├── ic_arrow_gray.png │ ├── ic_arrow_white.png │ ├── ic_car.png │ ├── ic_expenditure.png │ ├── ic_price.png │ ├── ic_price2.png │ ├── ic_right.png │ ├── img_bg2.png │ ├── img_bg3.png │ ├── img_bg4.png │ ├── img_electric_bg.png │ ├── img_home_bg.png │ ├── img_money_bg.png │ └── img_question.png ├── login │ ├── LOGO.png │ ├── ic_ipone.png │ ├── ic_right.png │ └── ic_verification.png ├── mine │ ├── ic_station.png │ ├── img_ID.png │ └── img_license.png ├── price_set │ ├── empty.png │ ├── ic_add.png │ ├── ic_arrow.png │ ├── ic_arrow2.png │ ├── ic_arrow_orange.png │ ├── ic_del.png │ ├── ic_delete.png │ └── img_car.png ├── quality │ ├── ic_arrow.png │ ├── ic_right.png │ ├── ic_wrong.png │ ├── img_1.png │ └── img_2.png └── tab │ ├── tab_electric_n.png │ ├── tab_electric_s.png │ ├── tab_home_n.png │ ├── tab_home_s.png │ ├── tab_me_n.png │ └── tab_me_s.png └── weui └── weui.wxss /.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 | -------------------------------------------------------------------------------- /.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | "plugins": { 5 | "postcss-mpvue-wxss": {} 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # icharge-master 2 | 3 | > 充电桩站管理小程序 4 | 5 | ## Build Setup 6 | 7 | ``` bash 8 | # install dependencies 9 | npm install 10 | 11 | # serve with hot reload at localhost:8080 12 | npm run dev 13 | 14 | # build for production with minification 15 | npm run build 16 | 17 | # build for production and view the bundle analyzer report 18 | npm run build --report 19 | 20 | # get it "git clone https://github.com/fuckskyku/newlife-master.git" 21 | ``` 22 | 23 | -------------------------------------------------------------------------------- /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, '*'), 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/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/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 portfinder = require('portfinder') 14 | var webpackConfig = require('./webpack.dev.conf') 15 | 16 | // default port where dev server listens for incoming traffic 17 | var port = process.env.PORT || config.dev.port 18 | // automatically open browser, if not set will be false 19 | var autoOpenBrowser = !!config.dev.autoOpenBrowser 20 | // Define HTTP proxies to your custom API backend 21 | // https://github.com/chimurai/http-proxy-middleware 22 | var proxyTable = config.dev.proxyTable 23 | 24 | var app = express() 25 | var compiler = webpack(webpackConfig) 26 | 27 | // var devMiddleware = require('webpack-dev-middleware')(compiler, { 28 | // publicPath: webpackConfig.output.publicPath, 29 | // quiet: true 30 | // }) 31 | 32 | // var hotMiddleware = require('webpack-hot-middleware')(compiler, { 33 | // log: false, 34 | // heartbeat: 2000 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 | var _resolve 70 | var readyPromise = new Promise(resolve => { 71 | _resolve = resolve 72 | }) 73 | 74 | // console.log('> Starting dev server...') 75 | // devMiddleware.waitUntilValid(() => { 76 | // console.log('> Listening at ' + uri + '\n') 77 | // // when env is testing, don't need open it 78 | // if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') { 79 | // opn(uri) 80 | // } 81 | // _resolve() 82 | // }) 83 | 84 | module.exports = new Promise((resolve, reject) => { 85 | portfinder.basePort = port 86 | portfinder.getPortPromise() 87 | .then(newPort => { 88 | if (port !== newPort) { 89 | console.log(`${port}端口被占用,开启新端口${newPort}`) 90 | } 91 | var server = app.listen(newPort, 'localhost') 92 | // for 小程序的文件保存机制 93 | require('webpack-dev-middleware-hard-disk')(compiler, { 94 | publicPath: webpackConfig.output.publicPath, 95 | quiet: true 96 | }) 97 | resolve({ 98 | ready: readyPromise, 99 | close: () => { 100 | server.close() 101 | } 102 | }) 103 | }).catch(error => { 104 | console.log('没有找到空闲端口,请打开任务管理器杀死进程端口再试', error) 105 | }) 106 | }) 107 | -------------------------------------------------------------------------------- /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 | var postcssLoader = { 24 | loader: 'postcss-loader', 25 | options: { 26 | sourceMap: true 27 | } 28 | } 29 | 30 | var px2rpxLoader = { 31 | loader: 'px2rpx-loader', 32 | options: { 33 | baseDpr: 1, 34 | rpxUnit: 0.5 35 | } 36 | } 37 | 38 | // generate loader string to be used with extract text plugin 39 | function generateLoaders (loader, loaderOptions) { 40 | var loaders = [cssLoader, px2rpxLoader, postcssLoader] 41 | if (loader) { 42 | loaders.push({ 43 | loader: loader + '-loader', 44 | options: Object.assign({}, loaderOptions, { 45 | sourceMap: options.sourceMap 46 | }) 47 | }) 48 | } 49 | 50 | // Extract CSS when that option is specified 51 | // (which is the case during production build) 52 | if (options.extract) { 53 | return ExtractTextPlugin.extract({ 54 | use: loaders, 55 | fallback: 'vue-style-loader' 56 | }) 57 | } else { 58 | return ['vue-style-loader'].concat(loaders) 59 | } 60 | } 61 | 62 | // https://vue-loader.vuejs.org/en/configurations/extract-css.html 63 | return { 64 | css: generateLoaders(), 65 | wxss: generateLoaders(), 66 | postcss: generateLoaders(), 67 | less: generateLoaders('less'), 68 | sass: generateLoaders('sass', { indentedSyntax: true }), 69 | scss: generateLoaders('sass'), 70 | stylus: generateLoaders('stylus'), 71 | styl: generateLoaders('stylus') 72 | } 73 | } 74 | 75 | // Generate loaders for standalone style files (outside of .vue) 76 | exports.styleLoaders = function (options) { 77 | var output = [] 78 | var loaders = exports.cssLoaders(options) 79 | for (var extension in loaders) { 80 | var loader = loaders[extension] 81 | output.push({ 82 | test: new RegExp('\\.' + extension + '$'), 83 | use: loader 84 | }) 85 | } 86 | return output 87 | } 88 | -------------------------------------------------------------------------------- /build/vue-loader.conf.js: -------------------------------------------------------------------------------- 1 | var utils = require('./utils') 2 | var config = require('../config') 3 | // var isProduction = process.env.NODE_ENV === 'production' 4 | // for mp 5 | var isProduction = true 6 | 7 | module.exports = { 8 | loaders: utils.cssLoaders({ 9 | sourceMap: isProduction 10 | ? config.build.productionSourceMap 11 | : config.dev.cssSourceMap, 12 | extract: isProduction 13 | }), 14 | transformToRequire: { 15 | video: 'src', 16 | source: 'src', 17 | img: 'src', 18 | image: 'xlink:href' 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /build/webpack.base.conf.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var fs = require('fs') 3 | var utils = require('./utils') 4 | var config = require('../config') 5 | var vueLoaderConfig = require('./vue-loader.conf') 6 | var MpvuePlugin = require('webpack-mpvue-asset-plugin') 7 | var glob = require('glob') 8 | 9 | 10 | function resolve(dir) { 11 | return path.join(__dirname, '..', dir) 12 | } 13 | 14 | function getEntry(rootSrc, pattern) { 15 | var files = glob.sync(path.resolve(rootSrc, pattern)) 16 | return files.reduce((res, file) => { 17 | var info = path.parse(file) 18 | var key = info.dir.slice(rootSrc.length + 1) + '/' + info.name 19 | res[key] = path.resolve(file) 20 | return res 21 | }, {}) 22 | } 23 | 24 | const appEntry = { app: resolve('./src/main.js') } 25 | const pagesEntry = getEntry(resolve('./src'), 'pages/**/main.js') 26 | const entry = Object.assign({}, appEntry, pagesEntry) 27 | 28 | module.exports = { 29 | // 如果要自定义生成的 dist 目录里面的文件路径, 30 | // 可以将 entry 写成 {'toPath': 'fromPath'} 的形式, 31 | // toPath 为相对于 dist 的路径, 例:index/demo,则生成的文件地址为 dist/index/demo.js 32 | entry, 33 | target: require('mpvue-webpack-target'), 34 | output: { 35 | path: config.build.assetsRoot, 36 | filename: '[name].js', 37 | publicPath: process.env.NODE_ENV === 'production' 38 | ? config.build.assetsPublicPath 39 | : config.dev.assetsPublicPath 40 | }, 41 | resolve: { 42 | extensions: ['.js', '.vue', '.json'], 43 | alias: { 44 | 'vue': 'mpvue', 45 | '@': resolve('src') 46 | }, 47 | symlinks: false, 48 | aliasFields: ['mpvue', 'weapp', 'browser'], 49 | mainFields: ['browser', 'module', 'main'] 50 | }, 51 | module: { 52 | 53 | rules: [ 54 | { 55 | test: /\.vue$/, 56 | loader: 'mpvue-loader', 57 | options: vueLoaderConfig 58 | }, 59 | { 60 | test: /\.js$/, 61 | include: [resolve('src'), resolve('test')], 62 | use: [ 63 | 'babel-loader', 64 | { 65 | loader: 'mpvue-loader', 66 | options: { 67 | checkMPEntry: true 68 | } 69 | }, 70 | ] 71 | }, 72 | { 73 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, 74 | loader: 'url-loader', 75 | options: { 76 | limit: 10000, 77 | name: utils.assetsPath('img/[name].[ext]') 78 | } 79 | }, 80 | { 81 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, 82 | loader: 'url-loader', 83 | options: { 84 | limit: 10000, 85 | name: utils.assetsPath('media/[name].[ext]') 86 | } 87 | }, 88 | { 89 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 90 | loader: 'url-loader', 91 | options: { 92 | limit: 10000, 93 | name: utils.assetsPath('fonts/[name].[ext]') 94 | } 95 | }, { 96 | test: /\.scss$/, 97 | loaders: ["style", "css", "sass"] 98 | } 99 | ] 100 | }, 101 | plugins: [ 102 | new MpvuePlugin() 103 | ] 104 | } 105 | -------------------------------------------------------------------------------- /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 | // copy from ./webpack.prod.conf.js 10 | var path = require('path') 11 | var ExtractTextPlugin = require('extract-text-webpack-plugin') 12 | var CopyWebpackPlugin = require('copy-webpack-plugin') 13 | var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') 14 | 15 | // add hot-reload related code to entry chunks 16 | // Object.keys(baseWebpackConfig.entry).forEach(function (name) { 17 | // baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name]) 18 | // }) 19 | 20 | module.exports = merge(baseWebpackConfig, { 21 | module: { 22 | rules: utils.styleLoaders({ 23 | sourceMap: config.dev.cssSourceMap, 24 | extract: true 25 | }) 26 | }, 27 | // cheap-module-eval-source-map is faster for development 28 | // devtool: '#cheap-module-eval-source-map', 29 | devtool: '#source-map', 30 | output: { 31 | path: config.build.assetsRoot, 32 | // filename: utils.assetsPath('js/[name].[chunkhash].js'), 33 | // chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') 34 | filename: utils.assetsPath('js/[name].js'), 35 | chunkFilename: utils.assetsPath('js/[id].js') 36 | }, 37 | plugins: [ 38 | new webpack.DefinePlugin({ 39 | 'process.env': config.dev.env 40 | }), 41 | 42 | // copy from ./webpack.prod.conf.js 43 | // extract css into its own file 44 | new ExtractTextPlugin({ 45 | // filename: utils.assetsPath('css/[name].[contenthash].css') 46 | filename: utils.assetsPath('css/[name].wxss') 47 | }), 48 | // Compress extracted CSS. We are using this plugin so that possible 49 | // duplicated CSS from different components can be deduped. 50 | new OptimizeCSSPlugin({ 51 | cssProcessorOptions: { 52 | safe: true 53 | } 54 | }), 55 | new webpack.optimize.CommonsChunkPlugin({ 56 | name: 'vendor', 57 | minChunks: function (module, count) { 58 | // any required modules inside node_modules are extracted to vendor 59 | return ( 60 | module.resource && 61 | /\.js$/.test(module.resource) && 62 | module.resource.indexOf('node_modules') >= 0 63 | ) || count > 1 64 | } 65 | }), 66 | new webpack.optimize.CommonsChunkPlugin({ 67 | name: 'manifest', 68 | chunks: ['vendor'] 69 | }), 70 | // copy custom static assets 71 | new CopyWebpackPlugin([ 72 | { 73 | from: path.resolve(__dirname, '../static'), 74 | to: config.build.assetsSubDirectory, 75 | ignore: ['.*'] 76 | } 77 | ]), 78 | 79 | // https://github.com/glenjamin/webpack-hot-middleware#installation--usage 80 | // new webpack.HotModuleReplacementPlugin(), 81 | new webpack.NoEmitOnErrorsPlugin(), 82 | // https://github.com/ampedandwired/html-webpack-plugin 83 | // new HtmlWebpackPlugin({ 84 | // filename: 'index.html', 85 | // template: 'index.html', 86 | // inject: true 87 | // }), 88 | new FriendlyErrorsPlugin() 89 | ] 90 | }) 91 | -------------------------------------------------------------------------------- /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 UglifyJsPlugin = require('uglifyjs-webpack-plugin') 8 | var CopyWebpackPlugin = require('copy-webpack-plugin') 9 | // var HtmlWebpackPlugin = require('html-webpack-plugin') 10 | var ExtractTextPlugin = require('extract-text-webpack-plugin') 11 | var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') 12 | 13 | var env = config.build.env 14 | 15 | var webpackConfig = merge(baseWebpackConfig, { 16 | module: { 17 | rules: utils.styleLoaders({ 18 | sourceMap: config.build.productionSourceMap, 19 | extract: true 20 | }) 21 | }, 22 | devtool: config.build.productionSourceMap ? '#source-map' : false, 23 | output: { 24 | path: config.build.assetsRoot, 25 | // filename: utils.assetsPath('js/[name].[chunkhash].js'), 26 | // chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') 27 | filename: utils.assetsPath('js/[name].js'), 28 | chunkFilename: utils.assetsPath('js/[id].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 UglifyJsPlugin({ 36 | sourceMap: true 37 | }), 38 | // extract css into its own file 39 | new ExtractTextPlugin({ 40 | // filename: utils.assetsPath('css/[name].[contenthash].css') 41 | filename: utils.assetsPath('css/[name].wxss') 42 | }), 43 | // Compress extracted CSS. We are using this plugin so that possible 44 | // duplicated CSS from different components can be deduped. 45 | new OptimizeCSSPlugin({ 46 | cssProcessorOptions: { 47 | safe: true 48 | } 49 | }), 50 | // generate dist index.html with correct asset hash for caching. 51 | // you can customize output by editing /index.html 52 | // see https://github.com/ampedandwired/html-webpack-plugin 53 | // new HtmlWebpackPlugin({ 54 | // filename: config.build.index, 55 | // template: 'index.html', 56 | // inject: true, 57 | // minify: { 58 | // removeComments: true, 59 | // collapseWhitespace: true, 60 | // removeAttributeQuotes: true 61 | // // more options: 62 | // // https://github.com/kangax/html-minifier#options-quick-reference 63 | // }, 64 | // // necessary to consistently work with multiple chunks via CommonsChunkPlugin 65 | // chunksSortMode: 'dependency' 66 | // }), 67 | // keep module.id stable when vender modules does not change 68 | new webpack.HashedModuleIdsPlugin(), 69 | // split vendor js into its own file 70 | new webpack.optimize.CommonsChunkPlugin({ 71 | name: 'vendor', 72 | minChunks: function (module, count) { 73 | // any required modules inside node_modules are extracted to vendor 74 | return ( 75 | module.resource && 76 | /\.js$/.test(module.resource) && 77 | module.resource.indexOf('node_modules') >= 0 78 | ) || count > 1 79 | } 80 | }), 81 | // extract webpack runtime and module manifest to its own file in order to 82 | // prevent vendor hash from being updated whenever app bundle is updated 83 | new webpack.optimize.CommonsChunkPlugin({ 84 | name: 'manifest', 85 | chunks: ['vendor'] 86 | }), 87 | // copy custom static assets 88 | new CopyWebpackPlugin([ 89 | { 90 | from: path.resolve(__dirname, '../static'), 91 | to: config.build.assetsSubDirectory, 92 | ignore: ['.*'] 93 | } 94 | ]) 95 | ] 96 | }) 97 | 98 | // if (config.build.productionGzip) { 99 | // var CompressionWebpackPlugin = require('compression-webpack-plugin') 100 | 101 | // webpackConfig.plugins.push( 102 | // new CompressionWebpackPlugin({ 103 | // asset: '[path].gz[query]', 104 | // algorithm: 'gzip', 105 | // test: new RegExp( 106 | // '\\.(' + 107 | // config.build.productionGzipExtensions.join('|') + 108 | // ')$' 109 | // ), 110 | // threshold: 10240, 111 | // minRatio: 0.8 112 | // }) 113 | // ) 114 | // } 115 | 116 | if (config.build.bundleAnalyzerReport) { 117 | var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin 118 | webpackConfig.plugins.push(new BundleAnalyzerPlugin()) 119 | } 120 | 121 | module.exports = webpackConfig 122 | -------------------------------------------------------------------------------- /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: 'static', 10 | assetsPublicPath: '/', 11 | productionSourceMap: false, 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 | // 在小程序开发者工具中不需要自动打开浏览器 28 | autoOpenBrowser: false, 29 | assetsSubDirectory: 'static', 30 | assetsPublicPath: '/', 31 | proxyTable: {}, 32 | // CSS Sourcemaps off by default because relative paths are "buggy" 33 | // with this option, according to the CSS-Loader README 34 | // (https://github.com/webpack/css-loader#sourcemaps) 35 | // In our experience, they generally work as expected, 36 | // just be aware of this issue when enabling this option. 37 | cssSourceMap: false 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /config/prod.env.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | NODE_ENV: '"production"' 3 | } 4 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 特电 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "newlife-master", 3 | "version": "1.0.0", 4 | "description": "特电桩站管理小程序", 5 | "author": "fuckskyku <18883373625@163.com>", 6 | "private": true, 7 | "scripts": { 8 | "dev": "node build/dev-server.js", 9 | "start": "node build/dev-server.js", 10 | "build": "node build/build.js" 11 | }, 12 | "dependencies": { 13 | "babel-cli": "^6.26.0", 14 | "flyio": "^0.6.0", 15 | "marked": "^0.4.0", 16 | "mpvue": "^1.0.11", 17 | "mpvue-calendar": "^1.0.3", 18 | "mpvue-wxparse": "^0.6.5", 19 | "qs": "^6.5.2", 20 | "shell": "^0.5.0", 21 | "vuex": "^3.0.1", 22 | "vuex-persistedstate": "^2.5.4" 23 | }, 24 | "devDependencies": { 25 | "babel-core": "^6.22.1", 26 | "babel-loader": "^7.1.1", 27 | "babel-plugin-transform-runtime": "^6.22.0", 28 | "babel-preset-env": "^1.3.2", 29 | "babel-preset-stage-2": "^6.22.0", 30 | "babel-register": "^6.22.0", 31 | "chalk": "^2.4.0", 32 | "connect-history-api-fallback": "^1.3.0", 33 | "copy-webpack-plugin": "^4.5.1", 34 | "css-loader": "^0.28.11", 35 | "cssnano": "^3.10.0", 36 | "eventsource-polyfill": "^0.9.6", 37 | "express": "^4.16.3", 38 | "extract-text-webpack-plugin": "^3.0.2", 39 | "file-loader": "^1.1.11", 40 | "friendly-errors-webpack-plugin": "^1.7.0", 41 | "glob": "^7.1.2", 42 | "html-webpack-plugin": "^3.2.0", 43 | "http-proxy-middleware": "^0.18.0", 44 | "mpvue-loader": "^1.0.13", 45 | "mpvue-template-compiler": "^1.0.11", 46 | "mpvue-webpack-target": "^1.0.0", 47 | "node-sass": "^4.9.2", 48 | "optimize-css-assets-webpack-plugin": "^3.2.0", 49 | "ora": "^2.0.0", 50 | "portfinder": "^1.0.13", 51 | "postcss-loader": "^2.1.6", 52 | "postcss-mpvue-wxss": "^1.0.0", 53 | "prettier": "~1.12.1", 54 | "px2rpx-loader": "^0.1.10", 55 | "rimraf": "^2.6.0", 56 | "sass-loader": "^7.0.3", 57 | "semver": "^5.3.0", 58 | "shelljs": "^0.8.1", 59 | "uglifyjs-webpack-plugin": "^1.2.5", 60 | "url-loader": "^1.0.1", 61 | "vue-style-loader": "^4.1.0", 62 | "webpack": "^3.11.0", 63 | "webpack-bundle-analyzer": "^2.2.1", 64 | "webpack-dev-middleware-hard-disk": "^1.12.0", 65 | "webpack-merge": "^4.1.0", 66 | "webpack-mpvue-asset-plugin": "^0.0.2" 67 | }, 68 | "engines": { 69 | "node": ">= 4.0.0", 70 | "npm": ">= 3.0.0" 71 | }, 72 | "browserslist": [ 73 | "> 1%", 74 | "last 2 versions", 75 | "not ie <= 8" 76 | ] 77 | } 78 | -------------------------------------------------------------------------------- /project.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "项目配置文件。", 3 | "setting": { 4 | "urlCheck": true, 5 | "es6": true, 6 | "postcss": true, 7 | "minified": true, 8 | "newFeature": true, 9 | "autoAudits": false 10 | }, 11 | "miniprogramRoot": "dist/", 12 | "compileType": "miniprogram", 13 | "appid": "wx39cd59d2e067bfd8", 14 | "projectname": "newlife-master", 15 | "libVersion": "2.2.2", 16 | "condition": { 17 | "search": { 18 | "current": -1, 19 | "list": [] 20 | }, 21 | "conversation": { 22 | "current": -1, 23 | "list": [] 24 | }, 25 | "game": { 26 | "currentL": -1, 27 | "list": [] 28 | }, 29 | "miniprogram": { 30 | "current": -1, 31 | "list": [] 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /src/Store/store.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | import createPersistedState from 'vuex-persistedstate'; 4 | Vue.use(Vuex); 5 | //数据 6 | const state = { 7 | tasteType: '', //秘钥类型 8 | APPid: 'wx39cd59d2e067bfd8', // 9 | AppSecret: '9e15b275e3aef97a1ee8565cd4edffad', // 10 | code: '', //登录凭证 11 | token: '', 12 | userId: '', 13 | timer: '0', 14 | canIUse: true, 15 | family: { studentId: '', parentId: '', studentName: '' /*addisFull: ''*/ }, 16 | } 17 | 18 | //获取数据(或者说是自定义过滤计算) 19 | const getters = { 20 | getTasteType: state => state.tasteType, 21 | getAPPid: state => state.APPid, 22 | getAppSecret: state => state.AppSecret, 23 | getCode: state => state.code, 24 | gettoKen: state => state.token, 25 | getuserId: state => state.userId, 26 | gettimer: state => state.timer, 27 | getcanIUse: state => state.canIUse, 28 | getFamily: state => state.family 29 | } 30 | 31 | //提交方法 32 | const mutations = { 33 | //清空方法 34 | clearStore(state) { 35 | if (state) { 36 | state.tasteType = '' 37 | state.code = '' 38 | state.token = '' 39 | state.userId = '' 40 | state.canIUse = '' 41 | state.timer = '' 42 | } 43 | }, 44 | tasteType(state, value) { 45 | state.tasteType = value; 46 | }, 47 | code(state, value) { 48 | state.code = value; 49 | }, 50 | token(state, value) { 51 | state.token = value; 52 | }, 53 | userId(state, value) { 54 | state.userId = value; 55 | }, 56 | timer(state, value) { 57 | state.timer = value; 58 | }, 59 | canIUse(state, value) { 60 | state.canIUse = value; 61 | }, 62 | family(state, obj) { 63 | obj.forEach((item) => { 64 | Vue.set(state.family, item.key, item.value); 65 | }) 66 | }, 67 | 68 | }; 69 | 70 | //提交拦截 71 | const actions = { 72 | //清空方法 73 | setClearStore(state) { 74 | state.commit('clearStore'); 75 | }, 76 | setTasteType(state, value) { 77 | state.commit('tasteType', value); 78 | }, 79 | setAPPid(state, value) { 80 | state.commit('APPid', value); 81 | }, 82 | setAppSecret(state, value) { 83 | state.commit('AppSecret', value); 84 | }, 85 | setToKen(state, value) { 86 | state.commit('token', value) 87 | }, 88 | setUserId(state, value) { 89 | state.commit('userId', value) 90 | }, 91 | setTimer(state, value) { 92 | state.commit('timer', value) 93 | }, 94 | setCanIUse(state, value) { 95 | state.commit('canIUse', value) 96 | }, 97 | setFamily(state, obj) { 98 | state.commit("family", obj); 99 | }, 100 | 101 | } 102 | 103 | export default new Vuex.Store({ 104 | state, 105 | getters, 106 | actions, 107 | plugins: [createPersistedState({ 108 | storage: { 109 | getItem: key => wx.getStorageSync(key), 110 | setItem: (key, value) => wx.setStorageSync(key, value), 111 | removeItem: key => { } 112 | } 113 | })], 114 | mutations, 115 | // plugins: [vuexLocal.plugin] 116 | }) 117 | 118 | // export default Store 119 | -------------------------------------------------------------------------------- /src/api/api.js: -------------------------------------------------------------------------------- 1 | import fly from './apiConfig' 2 | import { Z_FULL_FLUSH } from 'zlib'; 3 | 4 | /* 充电桩小程序接口抛出 */ 5 | 6 | //测试接口 7 | export const GetSession = param => { 8 | return fly.get('/api/charge/GetSession', param) 9 | } 10 | 11 | //获取电站列表 12 | export const getStationtList = param => { 13 | return fly.get('/api/charge/getStationtList', param) 14 | } 15 | 16 | //获取电站信息 17 | export const getStationtInfo = param => { 18 | return fly.get('/api/charge/getStationtInfo', param) 19 | } 20 | 21 | //获取电站终端列表 22 | export const getClientList = param => { 23 | return fly.get('/api/charge/getClientList', param) 24 | } 25 | 26 | //验证用户 27 | export const checkToken = param => { 28 | return fly.post('/api/charge/checkToken', param) 29 | } 30 | 31 | //注册 32 | export const register = param => { 33 | return fly.post('/api/charge/register', param) 34 | } 35 | 36 | //登录 37 | export const login = param => { 38 | return fly.post('/api/charge/login', param) 39 | } 40 | 41 | //发送手机验证码 42 | export const getPhoneCode = param => { 43 | return fly.get('/api/charge/getPhoneCode', param) 44 | } 45 | 46 | //验证码登录 47 | export const mobileLogin = param => { 48 | return fly.post('/api/charge/mobileLogin', param) 49 | } 50 | 51 | //获取个人中心 52 | export const getUcCenter = param => { 53 | return fly.getHeader('/api/charge/getUcCenter', param) 54 | } 55 | 56 | //获取我的意见建议列表 57 | export const getSuggestionList = param => { 58 | return fly.getHeader('/api/charge/getSuggestionList', param) 59 | } 60 | 61 | //提交意见建议 62 | export const addSuggestion = param => { 63 | return fly.postHeader('/api/charge/addSuggestion', param) 64 | } 65 | 66 | //获取站内信列表 67 | export const getNoticeList = param => { 68 | return fly.getHeader('/api/charge/getNoticeList', param) 69 | } 70 | 71 | //获取站内信详情 72 | export const getnoticedetail = param => { 73 | return fly.getHeader('/api/charge/getnoticedetail', param) 74 | } 75 | 76 | //获取我的站内信未读总数 77 | export const getnewnoticecount = param => { 78 | return fly.getHeader('/api/charge/getnewnoticecount', param) 79 | } 80 | 81 | //获取预充值列表 82 | export const getprechargvaluelist = param => { 83 | return fly.get('/api/charge/getprechargvaluelist', param) 84 | } 85 | 86 | //获取优惠券列表 87 | export const getcouponlist = param => { 88 | return fly.getHeader('/api/charge/getcouponlist', param) 89 | } 90 | 91 | //领取优惠券 92 | export const receivecoupon = param => { 93 | return fly.getHeader('/api/charge/receivecoupon', param) 94 | } 95 | 96 | //获取我的优惠券列表 97 | export const getcouponlistbyuser = param => { 98 | return fly.getHeader('/api/charge/getcouponlistbyuser', param) 99 | } 100 | 101 | //获取我的优惠券详情 102 | export const getcoupondetail = param => { 103 | return fly.get('/api/charge/getcoupondetail', param) 104 | } 105 | 106 | //获取电站电价列表 107 | export const getPriceList = param => { 108 | return fly.get('/api/charge/getPriceList', param) 109 | } 110 | 111 | //用户充值获取到的最大优惠券 112 | export const getfavorablechargecouponbyuser = param => { 113 | return fly.postHeader('/api/charge/getfavorablechargecouponbyuser', param) 114 | } 115 | 116 | //支付下单 117 | export const addpayorder = param => { 118 | return fly.postHeader('/api/charge/addpayorder', param) 119 | } 120 | 121 | //获取微信支付数据签名验证字段列表 122 | export const getpaysign = param => { 123 | return fly.get('/api/wx/getpaysign', param) 124 | } 125 | 126 | //修改头像 127 | export const editAvatar = param => { 128 | return fly.postHeader('/api/charge/editAvatar', param) 129 | } 130 | 131 | //修改性别 132 | export const editGender = param => { 133 | return fly.postHeader('/api/charge/editGender', param) 134 | } 135 | 136 | //修改昵称 137 | export const editNickName = param => { 138 | return fly.postHeader('/api/charge/editNickName', param) 139 | } 140 | 141 | //开始充电 142 | export const chargeStart = param => { 143 | return fly.postHeader('/api/charge/chargeStart', param) 144 | } 145 | 146 | //结束充电 147 | export const chargeStop = param => { 148 | return fly.postHeader('/api/charge/chargeStop', param) 149 | } 150 | 151 | //获取用户资金流水列表 152 | export const getchargespendloglist = param => { 153 | return fly.getHeader('/api/charge/getchargespendloglist', param) 154 | } 155 | 156 | //获取资金流水详情 157 | export const getchargespendlogdetail = param => { 158 | return fly.getHeader('/api/charge/getchargespendlogdetail', param) 159 | } 160 | 161 | //获取七牛token 162 | export const GetQiniuToken = param => { 163 | return fly.get('/api/charge/GetQiniuToken', param) 164 | } 165 | 166 | //获取终端信息 167 | export const getClientInfo = param => { 168 | return fly.getHeader('/api/charge/getClientInfo', param) 169 | } 170 | 171 | //获取意见反馈详情 172 | export const getsuggestiondetail = param => { 173 | return fly.getHeader('/api/charge/getsuggestiondetail', param) 174 | } 175 | 176 | //获取用户余额 177 | export const getBalance = param => { 178 | return fly.getHeader('/api/charge/getBalance', param) 179 | } 180 | -------------------------------------------------------------------------------- /src/api/apiConfig.js: -------------------------------------------------------------------------------- 1 | import store from '@/Store/store' 2 | //引用工具类 3 | import utils from '../utils'; 4 | var Fly = require("flyio/dist/npm/wx") //wx.js为您下载的源码文件 5 | var fly = new Fly(); //创建fly实例 6 | 7 | //添加响应拦截器,响应拦截器会在then/catch处理之前执行 8 | fly.interceptors.response.use( 9 | (response, promise) => { 10 | // wx.showLoading({ 11 | // title: "加载中", 12 | // mask: true, 13 | // duration: 2000, 14 | // }); 15 | // return 16 | if(store.state.token){ 17 | fly.config.headers = { 18 | 'TOKEN': store.state.token 19 | } 20 | }else{ 21 | wx.clearStorageSync(); 22 | store.dispatch('setClearStore') 23 | 24 | } 25 | if (typeof (response.data) == 'string' && response.data != '') { 26 | response.data = JSON.parse(response.data); 27 | } 28 | if (response.data.code == "414" || response.data.code == "412" ) { 29 | var url = '/pages/loginOut/main' 30 | //token过期拦截 31 | // wx.removeStorageSync("token"); 32 | store.dispatch('setClearStore') 33 | wx.clearStorageSync(); 34 | wx.showToast({ 35 | title:'您尚未登录,请先登录', 36 | icon:'none', 37 | }); 38 | wx.redirectTo({ 39 | url: "/pages/index/main" 40 | }); 41 | } 42 | wx.hideLoading() 43 | }, 44 | (err, promise) => { 45 | // Do something with response error 46 | //promise.resolve("ssss") 47 | wx.showToast({ 48 | title:'网络不给力,请稍后再试!', 49 | icon:'none', 50 | }); 51 | wx.hideLoading() 52 | } 53 | ) 54 | 55 | // Set the base url 56 | fly.config.baseURL = "https://charge.xmnewlife.com/" 57 | fly.config.headers = { 58 | 'content-type': 'application/x-www-form-urlencoded', 59 | } 60 | 61 | 62 | //跨域请求是否发送第三方cookie 63 | fly.config.withCredentials = true; 64 | 65 | export default { 66 | /** 67 | * 68 | * @param {请求地址} url 69 | * @param {请求参数}} param 70 | * 71 | * 两个不带头部的请求方式 72 | */ 73 | get(url, param) { 74 | return new Promise((resolve, reject) => { 75 | fly.request(url, param, { 76 | method: 'get' 77 | }).then(res => { 78 | resolve(res) 79 | }) 80 | }) 81 | }, 82 | //post请求 83 | post(url, param) { 84 | return new Promise((resolve, reject) => { 85 | fly.request(url, param, { 86 | method: 'post' 87 | }).then(res => { 88 | resolve(res) 89 | }) 90 | }) 91 | }, 92 | 93 | /** 94 | * 95 | * @param {请求地址} url 96 | * @param {请求参数} param 97 | * 带头部参数的请求方式 98 | */ 99 | getHeader(url, param) { 100 | return new Promise((resolve, reject) => { 101 | fly.request(url, param, { 102 | method: 'get', 103 | headers: { 104 | "TOKEN": store.state.token 105 | } 106 | }).then(res => { 107 | resolve(res) 108 | }) 109 | }) 110 | }, 111 | postHeader(url, param) { 112 | return new Promise((resolve, reject) => { 113 | fly.request(url, param, { 114 | method: 'post', 115 | headers: { 116 | "TOKEN": store.state.token 117 | } 118 | }).then(res => { 119 | resolve(res) 120 | }) 121 | }) 122 | }, 123 | //这里是请求短信验证码专用接口请求 124 | getCode(url, param) { 125 | return new Promise((resolve, reject) => { 126 | fly.request(url, param, { 127 | method: 'get', 128 | headers: { 129 | "Cookie": "school_sesn_id=" + store.state.cookieId 130 | } 131 | }).then(res => { 132 | resolve(res) 133 | }) 134 | }) 135 | }, 136 | postCode(url, param) { 137 | return new Promise((resolve, reject) => { 138 | fly.request(url, param, { 139 | method: 'post', 140 | headers: { 141 | "Cookie": "school_sesn_id=" + store.state.cookieId 142 | } 143 | }).then(res => { 144 | resolve(res) 145 | }) 146 | }) 147 | } 148 | }; 149 | -------------------------------------------------------------------------------- /src/components/electricityDialog.vue: -------------------------------------------------------------------------------- 1 | 42 | 43 | 124 | 125 | 129 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import './utils/ald-stat' 2 | import './utils/ald-stat-conf' 3 | import '../static/weui/weui.wxss' 4 | 5 | import Vue from 'vue' 6 | import App from './App' 7 | 8 | import store from './Store/store' 9 | Vue.config.productionTip = false 10 | App.mpType = 'app' 11 | 12 | Vue.prototype.$store = store; 13 | const app = new Vue(App) 14 | app.$mount() 15 | 16 | export default { 17 | // 这个字段走 app.json 18 | config: { 19 | // 页面前带有 ^ 符号的,会被编译成首页,其他页面可以选填,我们会自动把 webpack entry 里面的入口页面加进去 20 | pages: [ 21 | 'pages/welcome/main', 22 | 'pages/tabBar/home/main', //首页 23 | 'pages/tabBar/electricitySet/main', //电费设置 24 | 'pages/tabBar/mine/main', //我的 25 | 'pages/home/electricityBills/main', //用电记录 26 | 'pages/home/electricityBillsDetails/main', //用电记录详情 27 | 'pages/home/moneyBills/main', //资金记录 28 | 'pages/home/withdrawalApply/main', //提现申请 29 | 'pages/home/useCondition/main', //桩站使用情况 30 | 'pages/electricitySet/coupons/main', //优惠券 31 | '^pages/electricitySet/couponsDetails/main', //优惠券详情 32 | 'pages/electricitySet/periodElectricity/main', //时段电价 33 | 'pages/qualification/quality/main', //桩站资质认证 34 | 'pages/qualification/submitSuccess/main', //桩站资质认证提交成功 35 | 'pages/electricitySet/coupons/main', //优惠券 36 | 'pages/login/main', //登录 37 | 'pages/login/loginSuccess/main', //登录成功 38 | 'pages/useAgreement/main' //协议 39 | ], 40 | "permission": { 41 | "scope.userLocation": { 42 | "desc": "你的位置信息将用于小程序位置接口的效果展示" 43 | } 44 | }, 45 | tabBar: { 46 | 'backgroundColor': "#ffffff", 47 | "selectedColor": '#14BF6D', 48 | "color": '#999999', 49 | "borderStyle": 'black', 50 | "list": [{ 51 | "pagePath": "pages/tabBar/home/main", 52 | "text": "首页", 53 | "iconPath": '/static/img/tab/tab_home_n.png', 54 | "selectedIconPath": '/static/img/tab/tab_home_s.png', 55 | },{ 56 | "pagePath": "pages/tabBar/electricitySet/main", 57 | "text": "电费设置", 58 | "iconPath": '/static/img/tab/tab_electric_n.png', 59 | "selectedIconPath": '/static/img/tab/tab_electric_s.png', 60 | },{ 61 | "pagePath": "pages/tabBar/mine/main", 62 | "text": "我的", 63 | "iconPath": '/static/img/tab/tab_me_n.png', 64 | "selectedIconPath": '/static/img/tab/tab_me_s.png', 65 | 66 | }] 67 | }, 68 | window: { 69 | backgroundTextStyle: 'dark', 70 | navigationBarBackgroundColor: '#14BF6D', 71 | navigationBarTitleText: '特电', 72 | navigationBarTextStyle: 'white', 73 | enablePullDownRefresh: true, 74 | // disableScroll: true 75 | } 76 | , networkTimeout: { 77 | request: 10000, 78 | downloadFile: 10000 79 | }, 80 | debug: false 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/pages/electricitySet/coupons/index.vue: -------------------------------------------------------------------------------- 1 | 72 | 147 | 148 | 153 | 154 | -------------------------------------------------------------------------------- /src/pages/electricitySet/coupons/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './index' 3 | 4 | const app = new Vue(App) 5 | app.$mount() 6 | 7 | export default { 8 | config: { 9 | navigationBarTitleText: '优惠券历史', 10 | "enablePullDownRefresh": false, 11 | "navigationBarBackgroundColor":'#14BF6D', 12 | "navigationBarTextStyle": 'white', 13 | } 14 | } -------------------------------------------------------------------------------- /src/pages/electricitySet/couponsDetails/index.vue: -------------------------------------------------------------------------------- 1 | 23 | 96 | 97 | 101 | -------------------------------------------------------------------------------- /src/pages/electricitySet/couponsDetails/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './index' 3 | 4 | const app = new Vue(App) 5 | app.$mount() 6 | 7 | export default { 8 | config: { 9 | navigationBarTitleText: '优惠券历史', 10 | "enablePullDownRefresh": false, 11 | "navigationBarBackgroundColor":'#14BF6D', 12 | "navigationBarTextStyle": 'white', 13 | } 14 | } -------------------------------------------------------------------------------- /src/pages/electricitySet/periodElectricity/index.vue: -------------------------------------------------------------------------------- 1 | 43 | 75 | 76 | 81 | -------------------------------------------------------------------------------- /src/pages/electricitySet/periodElectricity/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './index' 3 | 4 | const app = new Vue(App) 5 | app.$mount() 6 | 7 | 8 | export default { 9 | config: { 10 | navigationBarTitleText: '时段电价', 11 | "enablePullDownRefresh": false, 12 | "navigationBarBackgroundColor":'#14BF6D', 13 | "navigationBarTextStyle": 'white', 14 | } 15 | } -------------------------------------------------------------------------------- /src/pages/home/electricityBills/index.vue: -------------------------------------------------------------------------------- 1 | 36 | 65 | 66 | 70 | -------------------------------------------------------------------------------- /src/pages/home/electricityBills/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './index' 3 | 4 | const app = new Vue(App) 5 | app.$mount() 6 | 7 | 8 | export default { 9 | config: { 10 | navigationBarTitleText: '用电记录', 11 | "enablePullDownRefresh": false, 12 | "navigationBarBackgroundColor":'#14BF6D', 13 | "navigationBarTextStyle": 'white', 14 | } 15 | } -------------------------------------------------------------------------------- /src/pages/home/electricityBillsDetails/index.vue: -------------------------------------------------------------------------------- 1 | 68 | 95 | 96 | 100 | -------------------------------------------------------------------------------- /src/pages/home/electricityBillsDetails/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './index' 3 | 4 | const app = new Vue(App) 5 | app.$mount() 6 | 7 | 8 | export default { 9 | config: { 10 | navigationBarTitleText: '用电详情', 11 | "enablePullDownRefresh": false, 12 | "navigationBarBackgroundColor":'#14BF6D', 13 | "navigationBarTextStyle": 'white', 14 | } 15 | } -------------------------------------------------------------------------------- /src/pages/home/moneyBills/index.vue: -------------------------------------------------------------------------------- 1 | 58 | 87 | 88 | 92 | -------------------------------------------------------------------------------- /src/pages/home/moneyBills/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './index' 3 | 4 | const app = new Vue(App) 5 | app.$mount() 6 | 7 | 8 | export default { 9 | config: { 10 | navigationBarTitleText: '资金记录', 11 | "enablePullDownRefresh": false, 12 | "navigationBarBackgroundColor":'#14BF6D', 13 | "navigationBarTextStyle": 'white', 14 | } 15 | } -------------------------------------------------------------------------------- /src/pages/home/moneyBillsDetails/index.vue: -------------------------------------------------------------------------------- 1 | 93 | 120 | 121 | 125 | -------------------------------------------------------------------------------- /src/pages/home/moneyBillsDetails/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './index' 3 | 4 | const app = new Vue(App) 5 | app.$mount() 6 | 7 | 8 | export default { 9 | config: { 10 | navigationBarTitleText: '资金记录', 11 | "enablePullDownRefresh": false, 12 | "navigationBarBackgroundColor":'#14BF6D', 13 | "navigationBarTextStyle": 'white', 14 | } 15 | } -------------------------------------------------------------------------------- /src/pages/home/useCondition/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 28 | 29 | 35 | -------------------------------------------------------------------------------- /src/pages/home/useCondition/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './index' 3 | 4 | const app = new Vue(App) 5 | app.$mount() 6 | 7 | 8 | export default { 9 | config: { 10 | navigationBarTitleText: '充电桩在用情况', 11 | "enablePullDownRefresh": false, 12 | "navigationBarBackgroundColor":'#14BF6D', 13 | "navigationBarTextStyle": 'white', 14 | } 15 | } -------------------------------------------------------------------------------- /src/pages/home/withdrawalApply/index.vue: -------------------------------------------------------------------------------- 1 | 25 | 55 | 56 | 60 | -------------------------------------------------------------------------------- /src/pages/home/withdrawalApply/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './index' 3 | 4 | const app = new Vue(App) 5 | app.$mount() 6 | 7 | 8 | export default { 9 | config: { 10 | navigationBarTitleText: '提现申请', 11 | "enablePullDownRefresh": false, 12 | "navigationBarBackgroundColor":'#14BF6D', 13 | "navigationBarTextStyle": 'white', 14 | } 15 | } -------------------------------------------------------------------------------- /src/pages/login/loginSuccess/index.vue: -------------------------------------------------------------------------------- 1 | 9 | 76 | 77 | 127 | -------------------------------------------------------------------------------- /src/pages/login/loginSuccess/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './index' 3 | 4 | const app = new Vue(App) 5 | app.$mount() 6 | 7 | 8 | export default { 9 | config: { 10 | navigationBarTitleText: '账号登录', 11 | "enablePullDownRefresh": false, 12 | "navigationBarBackgroundColor":'#ffffff', 13 | "navigationBarTextStyle": 'black', 14 | } 15 | } -------------------------------------------------------------------------------- /src/pages/login/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './index' 3 | 4 | const app = new Vue(App) 5 | app.$mount() 6 | 7 | 8 | export default { 9 | config: { 10 | navigationBarTitleText: '账号登录', 11 | "enablePullDownRefresh": false, 12 | "navigationBarBackgroundColor":'#ffffff', 13 | "navigationBarTextStyle": 'black', 14 | } 15 | } -------------------------------------------------------------------------------- /src/pages/qualification/quality/index.vue: -------------------------------------------------------------------------------- 1 | 128 | 178 | 179 | 184 | -------------------------------------------------------------------------------- /src/pages/qualification/quality/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './index' 3 | 4 | const app = new Vue(App) 5 | app.$mount() 6 | 7 | 8 | export default { 9 | config: { 10 | navigationBarTitleText: '桩站资质认证', 11 | "enablePullDownRefresh": false, 12 | "navigationBarBackgroundColor":'#14BF6D', 13 | "navigationBarTextStyle": 'white', 14 | } 15 | } -------------------------------------------------------------------------------- /src/pages/qualification/qualityFailed/index.vue: -------------------------------------------------------------------------------- 1 | 124 | 174 | 175 | 180 | -------------------------------------------------------------------------------- /src/pages/qualification/qualityFailed/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './index' 3 | 4 | const app = new Vue(App) 5 | app.$mount() 6 | 7 | 8 | export default { 9 | config: { 10 | navigationBarTitleText: '桩站资质认证', 11 | "enablePullDownRefresh": false, 12 | "navigationBarBackgroundColor":'#14BF6D', 13 | "navigationBarTextStyle": 'white', 14 | } 15 | } -------------------------------------------------------------------------------- /src/pages/qualification/submitSuccess/index.vue: -------------------------------------------------------------------------------- 1 | 8 | 53 | 54 | 59 | -------------------------------------------------------------------------------- /src/pages/qualification/submitSuccess/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './index' 3 | 4 | const app = new Vue(App) 5 | app.$mount() 6 | 7 | 8 | export default { 9 | config: { 10 | navigationBarTitleText: '桩站资质认证', 11 | "enablePullDownRefresh": false, 12 | "navigationBarBackgroundColor":'#14BF6D', 13 | "navigationBarTextStyle": 'white', 14 | } 15 | } -------------------------------------------------------------------------------- /src/pages/tabBar/electricitySet/index.vue: -------------------------------------------------------------------------------- 1 | 112 | 194 | 195 | 200 | -------------------------------------------------------------------------------- /src/pages/tabBar/electricitySet/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './index' 3 | 4 | const app = new Vue(App) 5 | app.$mount() 6 | 7 | 8 | export default { 9 | config: { 10 | navigationBarTitleText: '电费设置', 11 | "enablePullDownRefresh": false, 12 | "navigationBarBackgroundColor":'#14BF6D', 13 | "navigationBarTextStyle": 'white', 14 | } 15 | } -------------------------------------------------------------------------------- /src/pages/tabBar/home/index.vue: -------------------------------------------------------------------------------- 1 | 81 | 132 | 133 | 137 | -------------------------------------------------------------------------------- /src/pages/tabBar/home/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './index' 3 | 4 | const app = new Vue(App) 5 | app.$mount() 6 | 7 | 8 | export default { 9 | config: { 10 | navigationBarTitleText: '特电-桩站端', 11 | backgroundTextStyle: 'dark', 12 | "enablePullDownRefresh": true, 13 | "navigationBarBackgroundColor":'#14BF6D', 14 | "navigationBarTextStyle": 'white', 15 | // "disableScroll": true 16 | } 17 | } -------------------------------------------------------------------------------- /src/pages/tabBar/mine/index.vue: -------------------------------------------------------------------------------- 1 | 39 | 65 | 66 | 70 | -------------------------------------------------------------------------------- /src/pages/tabBar/mine/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './index' 3 | 4 | const app = new Vue(App) 5 | app.$mount() 6 | 7 | 8 | export default { 9 | config: { 10 | navigationBarTitleText: '桩站详情信息', 11 | "enablePullDownRefresh": false, 12 | "navigationBarBackgroundColor":'#14BF6D', 13 | "navigationBarTextStyle": 'white', 14 | } 15 | } -------------------------------------------------------------------------------- /src/pages/useAgreement/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 32 | 33 | 36 | -------------------------------------------------------------------------------- /src/pages/useAgreement/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './index' 3 | 4 | const app = new Vue(App) 5 | app.$mount() 6 | 7 | export default{ 8 | config:{ 9 | "navigationBarTitleText":"协议" 10 | 11 | } 12 | } -------------------------------------------------------------------------------- /src/pages/welcome/index.vue: -------------------------------------------------------------------------------- 1 | 6 | 28 | 29 | 35 | -------------------------------------------------------------------------------- /src/pages/welcome/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './index' 3 | 4 | const app = new Vue(App) 5 | app.$mount() 6 | 7 | 8 | export default { 9 | config: { 10 | navigationBarTitleText: '', 11 | "enablePullDownRefresh": false, 12 | "navigationBarBackgroundColor":'#FFEA55', 13 | } 14 | } -------------------------------------------------------------------------------- /src/utils/WxValidate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 表单验证 3 | * 4 | * @param {Object} rules 验证字段的规则 5 | * @param {Object} messages 验证字段的提示信息 6 | * 7 | */ 8 | class WxValidate { 9 | constructor(rules = {}, messages = {}) { 10 | Object.assign(this, { 11 | data: {}, 12 | rules, 13 | messages, 14 | }) 15 | this.__init() 16 | } 17 | 18 | /** 19 | * __init 20 | */ 21 | __init() { 22 | this.__initMethods() 23 | this.__initDefaults() 24 | this.__initData() 25 | } 26 | 27 | /** 28 | * 初始化数据 29 | */ 30 | __initData() { 31 | this.form = {} 32 | this.errorList = [] 33 | } 34 | 35 | /** 36 | * 初始化默认提示信息 37 | */ 38 | __initDefaults() { 39 | this.defaults = { 40 | messages: { 41 | required: '这是必填字段。', 42 | email: '请输入有效的电子邮件地址。', 43 | tel: '请输入11位的手机号码。', 44 | url: '请输入有效的网址。', 45 | date: '请输入有效的日期。', 46 | dateISO: '请输入有效的日期(ISO),例如:2009-06-23,1998/01/22。', 47 | number: '请输入有效的数字。', 48 | digits: '只能输入数字。', 49 | idcard: '请输入18位的有效身份证。', 50 | equalTo: this.formatTpl('输入值必须和 {0} 相同。'), 51 | contains: this.formatTpl('输入值必须包含 {0}。'), 52 | minlength: this.formatTpl('最少要输入 {0} 个字符。'), 53 | maxlength: this.formatTpl('最多可以输入 {0} 个字符。'), 54 | rangelength: this.formatTpl('请输入长度在 {0} 到 {1} 之间的字符。'), 55 | min: this.formatTpl('请输入不小于 {0} 的数值。'), 56 | max: this.formatTpl('请输入不大于 {0} 的数值。'), 57 | range: this.formatTpl('请输入范围在 {0} 到 {1} 之间的数值。'), 58 | } 59 | } 60 | } 61 | 62 | /** 63 | * 初始化默认验证方法 64 | */ 65 | __initMethods() { 66 | const that = this 67 | that.methods = { 68 | /** 69 | * 验证必填元素 70 | */ 71 | required(value, param) { 72 | if (!that.depend(param)) { 73 | return 'dependency-mismatch' 74 | } else if (typeof value === 'number') { 75 | value = value.toString() 76 | } else if (typeof value === 'boolean') { 77 | return !0 78 | } 79 | 80 | return value.length > 0 81 | }, 82 | /** 83 | * 验证电子邮箱格式 84 | */ 85 | email(value) { 86 | return that.optional(value) || /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(value) 87 | }, 88 | /** 89 | * 验证手机格式 90 | */ 91 | tel(value) { 92 | return that.optional(value) || /^1[3456789]\d{9}$/.test(value) 93 | }, 94 | /** 95 | * 验证URL格式 96 | */ 97 | url(value) { 98 | return that.optional(value) || /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(value) 99 | }, 100 | /** 101 | * 验证日期格式 102 | */ 103 | date(value) { 104 | return that.optional(value) || !/Invalid|NaN/.test(new Date(value).toString()) 105 | }, 106 | /** 107 | * 验证ISO类型的日期格式 108 | */ 109 | dateISO(value) { 110 | return that.optional(value) || /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(value) 111 | }, 112 | /** 113 | * 验证十进制数字 114 | */ 115 | number(value) { 116 | return that.optional(value) || /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value) 117 | }, 118 | /** 119 | * 验证整数 120 | */ 121 | digits(value) { 122 | return that.optional(value) || /^\d+$/.test(value) 123 | }, 124 | /** 125 | * 验证身份证号码 126 | */ 127 | idcard(value) { 128 | return that.optional(value) || /^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value) 129 | }, 130 | /** 131 | * 验证两个输入框的内容是否相同 132 | */ 133 | equalTo(value, param) { 134 | return that.optional(value) || value === that.data[param] 135 | }, 136 | /** 137 | * 验证是否包含某个值 138 | */ 139 | contains(value, param) { 140 | return that.optional(value) || value.indexOf(param) >= 0 141 | }, 142 | /** 143 | * 验证最小长度 144 | */ 145 | minlength(value, param) { 146 | return that.optional(value) || value.length >= param 147 | }, 148 | /** 149 | * 验证最大长度 150 | */ 151 | maxlength(value, param) { 152 | return that.optional(value) || value.length <= param 153 | }, 154 | /** 155 | * 验证一个长度范围[min, max] 156 | */ 157 | rangelength(value, param) { 158 | return that.optional(value) || (value.length >= param[0] && value.length <= param[1]) 159 | }, 160 | /** 161 | * 验证最小值 162 | */ 163 | min(value, param) { 164 | return that.optional(value) || value >= param 165 | }, 166 | /** 167 | * 验证最大值 168 | */ 169 | max(value, param) { 170 | return that.optional(value) || value <= param 171 | }, 172 | /** 173 | * 验证一个值范围[min, max] 174 | */ 175 | range(value, param) { 176 | return that.optional(value) || (value >= param[0] && value <= param[1]) 177 | }, 178 | } 179 | } 180 | 181 | /** 182 | * 添加自定义验证方法 183 | * @param {String} name 方法名 184 | * @param {Function} method 函数体,接收两个参数(value, param),value表示元素的值,param表示参数 185 | * @param {String} message 提示信息 186 | */ 187 | addMethod(name, method, message) { 188 | this.methods[name] = method 189 | this.defaults.messages[name] = message !== undefined ? message : this.defaults.messages[name] 190 | } 191 | 192 | /** 193 | * 判断验证方法是否存在 194 | */ 195 | isValidMethod(value) { 196 | let methods = [] 197 | for (let method in this.methods) { 198 | if (method && typeof this.methods[method] === 'function') { 199 | methods.push(method) 200 | } 201 | } 202 | return methods.indexOf(value) !== -1 203 | } 204 | 205 | /** 206 | * 格式化提示信息模板 207 | */ 208 | formatTpl(source, params) { 209 | const that = this 210 | if (arguments.length === 1) { 211 | return function() { 212 | let args = Array.from(arguments) 213 | args.unshift(source) 214 | return that.formatTpl.apply(this, args) 215 | } 216 | } 217 | if (params === undefined) { 218 | return source 219 | } 220 | if (arguments.length > 2 && params.constructor !== Array) { 221 | params = Array.from(arguments).slice(1) 222 | } 223 | if (params.constructor !== Array) { 224 | params = [params] 225 | } 226 | params.forEach(function(n, i) { 227 | source = source.replace(new RegExp("\\{" + i + "\\}", "g"), function() { 228 | return n 229 | }) 230 | }) 231 | return source 232 | } 233 | 234 | /** 235 | * 判断规则依赖是否存在 236 | */ 237 | depend(param) { 238 | switch (typeof param) { 239 | case 'boolean': 240 | param = param 241 | break 242 | case 'string': 243 | param = !!param.length 244 | break 245 | case 'function': 246 | param = param() 247 | default: 248 | param = !0 249 | } 250 | return param 251 | } 252 | 253 | /** 254 | * 判断输入值是否为空 255 | */ 256 | optional(value) { 257 | return !this.methods.required(value) && 'dependency-mismatch' 258 | } 259 | 260 | /** 261 | * 获取自定义字段的提示信息 262 | * @param {String} param 字段名 263 | * @param {Object} rule 规则 264 | */ 265 | customMessage(param, rule) { 266 | const params = this.messages[param] 267 | const isObject = typeof params === 'object' 268 | if (params && isObject) return params[rule.method] 269 | } 270 | 271 | /** 272 | * 获取某个指定字段的提示信息 273 | * @param {String} param 字段名 274 | * @param {Object} rule 规则 275 | */ 276 | defaultMessage(param, rule) { 277 | let message = this.customMessage(param, rule) || this.defaults.messages[rule.method] 278 | let type = typeof message 279 | 280 | if (type === 'undefined') { 281 | message = `Warning: No message defined for ${rule.method}.` 282 | } else if (type === 'function') { 283 | message = message.call(this, rule.parameters) 284 | } 285 | 286 | return message 287 | } 288 | 289 | /** 290 | * 缓存错误信息 291 | * @param {String} param 字段名 292 | * @param {Object} rule 规则 293 | * @param {String} value 元素的值 294 | */ 295 | formatTplAndAdd(param, rule, value) { 296 | let msg = this.defaultMessage(param, rule) 297 | 298 | this.errorList.push({ 299 | param: param, 300 | msg: msg, 301 | value: value, 302 | }) 303 | } 304 | 305 | /** 306 | * 验证某个指定字段的规则 307 | * @param {String} param 字段名 308 | * @param {Object} rules 规则 309 | * @param {Object} data 需要验证的数据对象 310 | */ 311 | checkParam(param, rules, data) { 312 | 313 | // 缓存数据对象 314 | this.data = data 315 | 316 | // 缓存字段对应的值 317 | const value = data[param] !== null && data[param] !== undefined ? data[param] : '' 318 | 319 | // 遍历某个指定字段的所有规则,依次验证规则,否则缓存错误信息 320 | for (let method in rules) { 321 | 322 | // 判断验证方法是否存在 323 | if (this.isValidMethod(method)) { 324 | 325 | // 缓存规则的属性及值 326 | const rule = { 327 | method: method, 328 | parameters: rules[method] 329 | } 330 | 331 | // 调用验证方法 332 | const result = this.methods[method](value, rule.parameters) 333 | 334 | // 若result返回值为dependency-mismatch,则说明该字段的值为空或非必填字段 335 | if (result === 'dependency-mismatch') { 336 | continue 337 | } 338 | 339 | this.setValue(param, method, result, value) 340 | 341 | // 判断是否通过验证,否则缓存错误信息,跳出循环 342 | if (!result) { 343 | this.formatTplAndAdd(param, rule, value) 344 | break 345 | } 346 | } 347 | } 348 | } 349 | 350 | /** 351 | * 设置字段的默认验证值 352 | * @param {String} param 字段名 353 | */ 354 | setView(param) { 355 | this.form[param] = { 356 | $name: param, 357 | $valid: true, 358 | $invalid: false, 359 | $error: {}, 360 | $success: {}, 361 | $viewValue: ``, 362 | } 363 | } 364 | 365 | /** 366 | * 设置字段的验证值 367 | * @param {String} param 字段名 368 | * @param {String} method 字段的方法 369 | * @param {Boolean} result 是否通过验证 370 | * @param {String} value 字段的值 371 | */ 372 | setValue(param, method, result, value) { 373 | const params = this.form[param] 374 | params.$valid = result 375 | params.$invalid = !result 376 | params.$error[method] = !result 377 | params.$success[method] = result 378 | params.$viewValue = value 379 | } 380 | 381 | /** 382 | * 验证所有字段的规则,返回验证是否通过 383 | * @param {Object} data 需要验证数据对象 384 | */ 385 | checkForm(data) { 386 | this.__initData() 387 | 388 | for (let param in this.rules) { 389 | this.setView(param) 390 | this.checkParam(param, this.rules[param], data) 391 | } 392 | 393 | return this.valid() 394 | } 395 | 396 | /** 397 | * 返回验证是否通过 398 | */ 399 | valid() { 400 | return this.size() === 0 401 | } 402 | 403 | /** 404 | * 返回错误信息的个数 405 | */ 406 | size() { 407 | return this.errorList.length 408 | } 409 | 410 | /** 411 | * 返回所有错误信息 412 | */ 413 | validationErrors() { 414 | return this.errorList 415 | } 416 | } 417 | 418 | export default WxValidate 419 | -------------------------------------------------------------------------------- /src/utils/ald-stat-conf.js: -------------------------------------------------------------------------------- 1 | exports.app_key = "819928c8f9d1dcccfffdd4d8bd0edb64"; //请在此行填写从阿拉丁后台获取的appkey 2 | exports.getLocation = false; //默认不获取用户坐标位置 3 | exports.appid = "wx39cd59d2e067bfd8"; //用于用户登录、微信转发群信息、二维码等微信官方功能 4 | exports.appsecret = "";//用于用户登录、微信转发群信息、二维码等微信官方功能 5 | exports.defaultPath = 'pages/tabBar/home/main';//小程序的默认首页, 用于分享时path为空时 6 | -------------------------------------------------------------------------------- /src/utils/ald-stat.js: -------------------------------------------------------------------------------- 1 | (function(){var t="6.1.2";var a="log";var e=require("./ald-stat-conf.js");var s=0;var n=0;var r=0;var i=0;var o={};function l(t){var a="";try{a=wx.getStorageSync("aldstat_uuid")}catch(t){a="uuid-getstoragesync"}if(!a){a=""+Date.now()+Math.floor(Math.random()*1e7);try{wx.setStorageSync("aldstat_uuid",a)}catch(t){wx.setStorageSync("aldstat_uuid","uuid-getstoragesync")}t.aldstat_is_first_open=true}return a}function _(){wx.request({url:"https://"+a+".aldwx.com/config/app.json",header:{AldStat:"MiniApp-Stat"},method:"GET",success:function(t){if(t.statusCode===200){for(var a in t.data){wx.setStorageSync(a,t.data[a])}}}})}function d(t,a,e){if(t[a]){var s=t[a];t[a]=function(t){e.call(this,t,a);s.call(this,t)}}else{t[a]=function(t){e.call(this,t,a)}}}function c(t,a,e){if(t[a]){var s=t[a];t[a]=function(t){var n=s.call(this,t);e.call(this,[t,n],a);return n}}else{t[a]=function(t){e.call(this,t,a)}}}var f=function(t){if(wx.getSetting){wx.getSetting({success:function(a){if(a.authSetting["scope.userInfo"]){wx.getUserInfo({withCredentials:false,success:function(a){t(a)}})}}})}};var u=function(t,e,n){if(typeof arguments[1]==="undefined")e="GET";if(typeof arguments[2]==="undefined")n="d.html";var r=0;var i=function(){s+=1;t["rq_c"]=s;wx.request({url:"https://"+a+".aldwx.com/"+n,data:t,header:{AldStat:"MiniApp-Stat"},method:e,success:function(){},fail:function(){if(r<2){r++;t["retryTimes"]=r;i()}}})};i()};var p=function(a,s,n,r){var i={ak:e["app_key"],uu:l(a),at:a.aldstat_access_token,st:Date.now(),tp:n,ev:s,v:t};if(r){i["ct"]=r}if(a.aldstat_qr){i["qr"]=a.aldstat_qr}u(i,"GET","d.html")};var h=function(a,s,n,r){if(typeof a["aldstat_showoption"]==="undefined"){a["aldstat_showoption"]={}}var i={ak:e["app_key"],wsr:a.aldstat_showoption,uu:l(a),at:a.aldstat_access_token,st:Date.now(),tp:n,ev:s,nt:a.aldstat_network_type,pm:a.aldstat_phone_model,pr:a.aldstat_pixel_ratio,ww:a.aldstat_window_width,wh:a.aldstat_window_height,lang:a.aldstat_language,wv:a.aldstat_wechat_version,lat:a.aldstat_lat,lng:a.aldstat_lng,spd:a.aldstat_speed,v:t};if(r){i["ct"]=r}if(a.aldstat_location_name){i["ln"]=a.aldstat_location_name}if(a.aldstat_src){i["sr"]=a.aldstat_src}if(a.aldstat_qr){i["qr"]=a.aldstat_qr}u(i,"GET","d.html")};function g(t){this.app=t}g.prototype["debug"]=function(t){h(this.app,"debug",0,t)};g.prototype["warn"]=function(t){h(this.app,"debug",1,t)};g.prototype["error"]=function(t){p(this.app,"debug",2,t)};g.prototype["sendEvent"]=function(t,a){if(!D(t)){return false}if(t.length>=255){return false}if(typeof a==="object"){for(var e in a){if(!D(e)){return false}if(typeof a[e]=="object"){return false}if(!D(a[e])){return false}}h(this.app,"event",t,JSON.stringify(a))}else{if(typeof a==="string"&&a.length<=255){if(D(a)){var s=String(a);var n=new Object;n[s]=a;h(this.app,"event",t,a)}}else{h(this.app,"event",t,false)}}};var w=function(){var t=this;t.aldstat_duration+=Date.now()-t.aldstat_showtime;m(t,"app","unLaunch")};var v=function(t,a,e){if(typeof wx["getShareInfo"]!="undefined"){wx.getShareInfo({shareTicket:a,success:function(a){h(t,"event","ald_share_"+e,JSON.stringify(a))},fail:function(){h(t,"event","ald_share_"+e,"1")}})}else{h(t,"event","ald_share_"+e,"1")}};var y=function(t){_();this["aldstat"]=new g(this);var a="";try{a=wx.getStorageSync("aldstat_src")}catch(t){a="uuid-getstoragesync"}if(a){this.aldstat_src=a}var s=l(this);this.aldstat_uuid=s;this.aldstat_timestamp=Date.now();this.aldstat_showtime=Date.now();this.aldstat_duration=0;var n=this;n.aldstat_error_count=0;n.aldstat_page_count=1;n.aldstat_first_page=0;if(typeof t!="undefined"){this.aldstat_showoption=t}else{this.aldstat_showoption={}}var r=function(){wx.getNetworkType({success:function(t){n.aldstat_network_type=t["networkType"]},complete:i})};var i=function(){wx.getSystemInfo({success:function(t){n.aldstat_vsdk_version=typeof t["SDKVersion"]==="undefined"?"1.0.0":t["SDKVersion"];n.aldstat_phone_model=t["model"];n.aldstat_pixel_ratio=t["pixelRatio"];n.aldstat_window_width=t["windowWidth"];n.aldstat_window_height=t["windowHeight"];n.aldstat_language=t["language"];n.aldstat_wechat_version=t["version"];n.aldstat_sv=t["system"];n.aldstat_wvv=t["platform"]},complete:function(){if(e["getLocation"]){c()}d()}})};var d=function(){f(function(t){var a="";try{a=wx.getStorageSync("aldstat_uuid")}catch(t){a="uuid-getstoragesync"}t["userInfo"]["uu"]=a;o=t;u(t["userInfo"],"GET","u.html")})};var c=function(){wx.getLocation({type:"wgs84",success:function(t){n.aldstat_lat=t["latitude"];n.aldstat_lng=t["longitude"];n.aldstat_speed=t["speed"]}})};r();var p="";try{p=wx.getStorageSync("app_session_key_create_launch_upload")}catch(t){p=""}if(!p){n.aldstat_access_token=""+Date.now()+Math.floor(Math.random()*1e7)}else{if(p>0&&typeof p==="number"){n.aldstat_access_token=""+Date.now()+Math.floor(Math.random()*1e7)}}m(n,"app","launch")};var S=function(t,a){var e=this;if(typeof this.aldstat_error_count==="undefined"){this.aldstat_error_count=1}else{this.aldstat_error_count++}h(e,"event","ald_error_message",JSON.stringify(t))};var m=function(a,s,o){var _="";try{_=wx.getStorageSync("app_"+o+"_upload")}catch(t){_=""}if(!_&&o!=="launch"){return}if(_<1&&typeof _==="number"){return}if(typeof a.aldstat_timestamp==="undefined"){a.aldstat_timestamp=Date.now()}var d=wx.getSystemInfoSync();a.aldstat_vsdk_version=typeof d["SDKVersion"]==="undefined"?"1.0.0":d["SDKVersion"];a.aldstat_phone_model=d["model"];a.aldstat_pixel_ratio=d["pixelRatio"];a.aldstat_window_width=d["windowWidth"];a.aldstat_window_height=d["windowHeight"];a.aldstat_language=d["language"];a.aldstat_sv=d["system"];a.aldstat_wvv=d["platform"];var c={ak:e["app_key"],waid:e["appid"],wst:e["appsecret"],uu:l(a),at:a.aldstat_access_token,wsr:a.aldstat_showoption,st:a.aldstat_timestamp,dr:a.aldstat_duration,et:Date.now(),pc:a.aldstat_page_count,fp:a.aldstat_first_page,lp:a.aldstat_last_page,life:o,ec:a.aldstat_error_count,nt:a.aldstat_network_type,pm:a.aldstat_phone_model,wsdk:a.aldstat_vsdk_version,pr:a.aldstat_pixel_ratio,ww:a.aldstat_window_width,wh:a.aldstat_window_height,lang:a.aldstat_language,wv:a.aldstat_wechat_version,lat:a.aldstat_lat,lng:a.aldstat_lng,spd:a.aldstat_speed,v:t,ev:s,sv:a.aldstat_sv,wvv:a.aldstat_wvv};if(o==="launch"){n+=1}else if(o==="show"){r+=1}else{i+=1}c["la_c"]=n;c["as_c"]=r;c["ah_c"]=i;if(a.page_share_count&&typeof a.page_share_count==="number"){c["sc"]=a.page_share_count}if(a.aldstat_is_first_open){c["ifo"]="true"}if(a.aldstat_location_name){c["ln"]=a.aldstat_location_name}if(a.aldstat_src){c["sr"]=a.aldstat_src}if(a.aldstat_qr){c["qr"]=a.aldstat_qr}if(a.ald_share_src){c["usr"]=a.ald_share_src}u(c,"GET","d.html")};var x=function(t){this.aldstat_showtime=Date.now();if(typeof t!="undefined"){this.aldstat_showoption=t}else{this.aldstat_showoption={}}var a="";try{a=wx.getStorageSync("app_session_key_create_show_upload")}catch(t){a=""}if(a){if(a>0&&typeof a==="number"){this.aldstat_access_token=""+Date.now()+Math.floor(Math.random()*1e7)}}m(this,"app","show");if(typeof t!="undefined"){if(typeof t["shareTicket"]!="undefined"){v(this,t["shareTicket"],"click")}else if(typeof t["query"]!="undefined"){if(typeof t["query"]["ald_share_src"]!="undefined"){v(this,"0","click")}}}};var k=function(t,a){var e=this;if(e.aldstat_is_first_open){e.aldstat_is_first_open=false}e.aldstat_duration=Date.now()-e.aldstat_showtime;m(e,"app","hide")};function q(t){for(var a in t){return false}return true}function D(t){if(typeof t!=="string"){return false}var a=t.replace(/\s+/g,"_");if(/[~`!@/#+=\$%\^()&\*]+/g.test(a)){return false}return true}var T=function(t,a){var e=getApp();M(e,this,"hide")};var b=function(t,a){var e=getApp();M(e,this,"unload")};var A=function(t,a){var e="";try{e=wx.getStorageSync("aldstat_src")}catch(t){e=""}var s=getApp();if(typeof wx["showShareMenu"]!="undefined"){}if(e){s.aldstat_src=e}if(!q(t)){if(typeof t.aldsrc!="undefined"){if(!e){try{wx.setStorageSync("aldstat_src",t.aldsrc)}catch(t){}s.aldstat_src=t.aldsrc;s.aldstat_qr=t.aldsrc}else{s.aldstat_qr=t.aldsrc}}if(typeof t.ald_share_src!="undefined"){s.ald_share_src=t.ald_share_src}this.aldstat_page_args=JSON.stringify(t)}M(s,this,"load")};var M=function(a,s,n){var r="";try{r=wx.getStorageSync("page_"+n+"_upload")}catch(t){r=""}if(!r&&n!=="show"){return}if(r<1&&typeof r==="number"){return}s.aldstat_start_time=Date.now();s.aldstat_error_count=0;if(!a.aldstat_page_count){a.aldstat_page_count=1}else{a.aldstat_page_count++}if(!a.aldstat_first_page){a.aldstat_first_page=s["__route__"];s.aldstat_is_first_page=true}a.aldstat_last_page=s["__route__"];var i={uu:l(a),at:a.aldstat_access_token,wsr:a.aldstat_showoption,ak:e["app_key"],ev:"page",st:s.aldstat_start_time,dr:Date.now()-s.aldstat_start_time,pp:s["__route__"],life:n,sc:s.page_share_count,ec:s.aldstat_error_count,nt:a.aldstat_network_type,pm:a.aldstat_phone_model,pr:a.aldstat_pixel_ratio,ww:a.aldstat_window_width,wh:a.aldstat_window_height,lang:a.aldstat_language,wv:a.aldstat_wechat_version,lat:a.aldstat_lat,lng:a.aldstat_lng,spd:a.aldstat_speed,v:t,wsdk:a.aldstat_vsdk_version,sv:a.aldstat_sv,wvv:a.aldstat_wvv};if(s.aldstat_is_first_page){i["ifp"]="true"}if(a.aldstat_page_last_page){i["lp"]=a.aldstat_page_last_page}if(a.aldstat_location_name){i["ln"]=a.aldstat_location_name}if(s.aldstat_page_args){i["ag"]=s.aldstat_page_args}if(a.aldstat_src){i["sr"]=a.aldstat_src}if(a.aldstat_qr){i["qr"]=a.aldstat_qr}if(a.ald_share_src){i["usr"]=a.ald_share_src}a.aldstat_page_last_page=s["__route__"];u(i,"GET","d.html")};var I=function(t,a){var e=getApp();M(e,this,"show")};var E=function(t,a){var e=getApp();h(e,"event","ald_pulldownrefresh",1)};var O=function(t,a){var e=getApp();h(e,"event","ald_reachbottom",1)};var G=function(t,a){var s=this;var n=getApp();if(typeof t=="undefined"){return}if(typeof t[1]=="undefined"){return}var r="";try{r=wx.getStorageSync("aldstat_uuid")}catch(t){r="uuid-getstoragesync"}var i="";try{i=wx.getStorageSync(r)}catch(t){i="p_share_count_getst"}var o="";if(n.ald_share_src==="undefined"||!n.ald_share_src){try{o=wx.getStorageSync("aldstat_uuid")}catch(t){o="ald_share_src_getst"}}else{o=n.ald_share_src;var l=o.split(",");var _=true;for(var d=0,c=l.length;d=3){if(_){l.shift()}else{}o=l.toString()}if(o!==""&&_){o=o+","+r}}if(!t[1].path||t[1].path==="undefined"){if(e["defaultPath"]){t[1].path=e["defaultPath"]}else{t[1].path=s["__route__"]}}if(t[1].path.indexOf("?")!=-1){t[1].path+="&ald_share_src="+o}else{t[1].path+="?ald_share_src="+o}h(n,"event","ald_share_chain",{path:n.aldstat_last_page,chain:o});if(i===""||typeof i==="undefined"){try{wx.setStorageSync(r,1)}catch(t){}i=1;n.page_share_count=i}else{i=parseInt(wx.getStorageSync(r))+1;n.page_share_count=i;try{wx.setStorageSync(r,i)}catch(t){}}f(function(t){var a="";try{a=wx.getStorageSync("aldstat_uuid")}catch(t){a="uuid-getstoragesync"}t["userInfo"]["uu"]=a;u(t["userInfo"],"GET","u.html")});var g=t[1];if(typeof t[1]["success"]==="undefined"){t[1]["success"]=function(t){}}if(typeof t[1]["fail"]==="undefined"){t[1]["fail"]=function(t){}}var w=t[1]["fail"];var y=t[1]["success"];t[1]["success"]=function(t){var a=new Array;if(typeof t["shareTickets"]==="object"){for(var e=0;e { 18 | if (item.titleImgUrl != '') { 19 | count++ 20 | } 21 | }) 22 | return obj.length * 137 + count * 300 23 | } else if (isActive == 1) { 24 | //作业 25 | obj.forEach((item) => { 26 | if (item.commAttachList.length > 0) { 27 | count++ 28 | } 29 | }) 30 | return obj.length * 200 + count * 300 31 | } else if (isActive == 2) { 32 | //推荐 33 | obj.forEach((item) => { 34 | if (item.titleImgUrl != '') { 35 | count++ 36 | } 37 | }) 38 | return obj.length * 160 + count * 300 39 | } 40 | } 41 | 42 | 43 | 44 | //微信异步缓存存储 45 | /** 46 | * 47 | * @param {存储的key}}}} key 48 | * @param {存储的value}} data 49 | * @param {存储成功执行的函数回调}} fn 50 | */ 51 | 52 | 53 | export function wxSetStorage(key, data, fn) { 54 | wx.setStorage({ 55 | key: key, 56 | data: data, 57 | success: function (res) { 58 | if (res.errMsg == "setStorage:ok") { 59 | if (fn == null) { 60 | return; 61 | } else { 62 | fn(); 63 | } 64 | } 65 | }, 66 | fail: function () { 67 | console.log("保存失败") 68 | } 69 | }) 70 | } 71 | 72 | /** 73 | * 74 | * @param {存储key} key 75 | * @param {存储value} data 76 | * 微信同步存储数据 77 | */ 78 | export function wxSetStorageSync(key, data) { 79 | wx.setStorageSync(key, data); 80 | } 81 | 82 | //微信同步缓存获取 83 | /** 84 | * 85 | * @param {获取值的key} keyval 86 | */ 87 | export function wxGetStorage(keyval) { 88 | if (wx.getStorageSync(keyval) == "") { 89 | return false 90 | } else { 91 | return wx.getStorageSync(keyval) 92 | } 93 | } 94 | 95 | 96 | /** 97 | * 98 | * @param {移除key} key 99 | * 微信同步从本地缓存中移除指定 key 100 | */ 101 | export function removeStorageSync(key) { 102 | wx.removeStorageSync(key); 103 | } 104 | 105 | 106 | //提示弹出框 107 | /** 108 | * 109 | * @param {弹出的标题} keyval 110 | */ 111 | export function showDialog(keyval, fn) { 112 | wx.showToast({ 113 | title: keyval, 114 | icon: 'none', 115 | duration: 2000, 116 | mask: true 117 | }) 118 | if (fn != null) { 119 | setTimeout(() => { 120 | fn(); 121 | }, 3000) 122 | } 123 | } 124 | 125 | //替换图片路径 126 | export function formatImgUrl(imgUlr) { 127 | if (imgUlr != "" && imgUlr != "undefined" && imgUlr) { 128 | if (this.url(imgUlr)) { 129 | return imgUlr; 130 | } else { 131 | // return "https://admin.school.mseenet.com" + imgUlr; 132 | return "http://img.mseenet.com/" + imgUlr; 133 | } 134 | } 135 | return ''; 136 | } 137 | 138 | //机构图片路径转换 139 | export function formatImgUrlRetailer(imgUlr) { 140 | if (imgUlr != "" && imgUlr != "undefined" && imgUlr) { 141 | //return "https://admin.retailer.mseenet.com/" + imgUlr; 142 | return "" + imgUlr; 143 | } 144 | //return 'http://img.mseenet.com/98A1565DACAB23AFB60A0E17EF6C9C49.png'; 145 | return ''; 146 | } 147 | 148 | /** 149 | * 格式化时间 150 | * @param {String} date 原始时间格式 151 | * 格式后的时间:yyyy-mm-dd hh:mm:ss 152 | **/ 153 | export function formatTime(date) { 154 | const year = date.getFullYear() 155 | const month = date.getMonth() + 1 156 | const day = date.getDate() 157 | const hour = date.getHours() 158 | const minute = date.getMinutes() 159 | const second = date.getSeconds() 160 | 161 | const t1 = [year, month, day].map(formatNumber).join('-') 162 | const t2 = [hour, minute, second].map(formatNumber).join(':') 163 | 164 | return `${t1} ${t2}` 165 | } 166 | export function formatTimeMin(dateTimeStamp) { 167 | var date = new Date(dateTimeStamp); 168 | const year = date.getFullYear() 169 | const month = date.getMonth() + 1 170 | const day = date.getDate() 171 | 172 | const hour = date.getHours() 173 | const minute = date.getMinutes() 174 | 175 | 176 | const t1 = [year, month, day].map(formatNumber).join('-') 177 | const t2 = [hour, minute].map(formatNumber).join(':') 178 | 179 | return `${t1} ${t2}` 180 | } 181 | 182 | //格式化 转成日期部分 183 | export function formatTimeDate(date) { 184 | const year = date.getFullYear() 185 | const month = date.getMonth() + 1 186 | const day = date.getDate() 187 | const t1 = [year, month, day].map(formatNumber).join('-') 188 | 189 | return `${t1}` 190 | } 191 | //格式化 转成日期部分+星期几 192 | export function formatTimeDateDay(dateTimeStamp) { 193 | var date=this.transLocalTime(dateTimeStamp); 194 | var weekDay = ["星期天", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"]; 195 | const year = date.getFullYear() 196 | const month = date.getMonth() + 1 197 | const day = date.getDate() 198 | const day1 = weekDay[date.getDay()] 199 | const t1 = [year, month, day].map(formatNumber).join('-') 200 | 201 | return `${t1} ${day1}` 202 | } 203 | 204 | 205 | export function transLocalTime(t) { 206 | return new Date(t); 207 | } 208 | 209 | //时间转化为几分钟前 210 | export function formatTimeDiff(dateTimeStamp) { 211 | var result = ""; 212 | var minute = 1000 * 60; 213 | var hour = minute * 60; 214 | var day = hour * 24; 215 | var halfamonth = day * 15; 216 | var month = day * 30; 217 | var now = new Date().getTime(); 218 | var diffValue = now - dateTimeStamp; 219 | if (diffValue < 0) { 220 | return; 221 | } 222 | var monthC = diffValue / month; 223 | var weekC = diffValue / (7 * day); 224 | var dayC = diffValue / day; 225 | var hourC = diffValue / hour; 226 | var minC = diffValue / minute; 227 | if (monthC >= 1) { 228 | result = "" + parseInt(monthC) + "月前"; 229 | } else if (weekC >= 1) { 230 | result = "" + parseInt(weekC) + "周前"; 231 | } else if (dayC >= 1) { 232 | result = "" + parseInt(dayC) + "天前"; 233 | } else if (hourC >= 1) { 234 | result = "" + parseInt(hourC) + "小时前"; 235 | } else if (minC >= 1) { 236 | result = "" + parseInt(minC) + "分钟前"; 237 | } else 238 | result = "刚刚"; 239 | return result; 240 | } 241 | 242 | 243 | 244 | 245 | /** 246 | * 对Date的扩展,将 Date 转化为指定格式的String 247 | * 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符, 248 | * 年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字) 249 | * 例子: 250 | * (new Date()).format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423 251 | * (new Date()).format("yyyy-M-d h:m:s.S") ==> 2006-7-2 8:9:4.18 252 | */ 253 | Date.prototype.format = function (fmt) { 254 | var o = { 255 | "M+": this.getMonth() + 1, //月份 256 | "d+": this.getDate(), //日 257 | "h+": this.getHours(), //小时 258 | "m+": this.getMinutes(), //分 259 | "s+": this.getSeconds(), //秒 260 | "q+": Math.floor((this.getMonth() + 3) / 3), //季度 261 | "S": this.getMilliseconds() //毫秒 262 | }; 263 | if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); 264 | for (var k in o) 265 | if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); 266 | return fmt; 267 | } 268 | /** 269 | * 将String类型解析为Date类型. 270 | * parseDate('2006-1-1') 271 | * parseDate('2006-1-1 15:14:16') 272 | * parseDate('2006-1-1 15:14:16.254') 273 | */ 274 | export function parseDate(str) { 275 | if (typeof str == 'string') { 276 | var results = str.match(/^ *(\d{4})-(\d{1,2})-(\d{1,2}) *$/); 277 | if (results && results.length > 3) 278 | return new Date(parseInt(results[1]), parseInt(results[2]) - 1, parseInt(results[3])); 279 | results = str.match(/^ *(\d{4})-(\d{1,2})-(\d{1,2}) +(\d{1,2}):(\d{1,2}):(\d{1,2}) *$/); 280 | if (results && results.length > 6) 281 | return new Date(parseInt(results[1]), parseInt(results[2]) - 1, parseInt(results[3]), parseInt(results[4]), parseInt(results[5]), parseInt(results[6])); 282 | results = str.match(/^ *(\d{4})-(\d{1,2})-(\d{1,2}) +(\d{1,2}):(\d{1,2}):(\d{1,2})\.(\d{1,9}) *$/); 283 | if (results && results.length > 7) 284 | return new Date(parseInt(results[1]), parseInt(results[2]) - 1, parseInt(results[3]), parseInt(results[4]), parseInt(results[5]), parseInt(results[6]), parseInt(results[7])); 285 | } 286 | return null; 287 | } 288 | 289 | 290 | /** 291 | * 验证必填元素 292 | */ 293 | export function required(value, param) { 294 | if (!this.depend(param)) { 295 | return 'dependency-mismatch' 296 | } else if (typeof value === 'number') { 297 | value = value.toString() 298 | } else if (typeof value === 'boolean') { 299 | return !0 300 | } 301 | 302 | return value.length > 0 303 | } 304 | /** 305 | * 验证电子邮箱格式 306 | */ 307 | export function email(value) { 308 | return this.optional(value) || /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(value) 309 | } 310 | /** 311 | * 验证手机格式 312 | */ 313 | export function tel(value) { 314 | return this.optional(value) || /^1[3456789]\d{9}$/.test(value) 315 | } 316 | /** 317 | * 验证URL格式 318 | */ 319 | export function url(value) { 320 | return this.optional(value) || /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(value) 321 | } 322 | /** 323 | * 验证日期格式 324 | */ 325 | export function date(value) { 326 | return this.optional(value) || !/Invalid|NaN/.test(new Date(value).toString()) 327 | } 328 | /** 329 | * 验证ISO类型的日期格式 330 | */ 331 | export function dateISO(value) { 332 | return this.optional(value) || /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(value) 333 | } 334 | /** 335 | * 验证十进制数字 336 | */ 337 | export function number(value) { 338 | return this.optional(value) || /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value) 339 | } 340 | /** 341 | * 验证整数 342 | */ 343 | export function digits(value) { 344 | return this.optional(value) || /^\d+$/.test(value) 345 | } 346 | /** 347 | * 验证身份证号码 348 | */ 349 | export function idcard(value) { 350 | return this.optional(value) || /^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value) 351 | } 352 | /** 353 | * 验证两个值的内容是否相同 354 | */ 355 | export function equalTo(value, param) { 356 | return (this.optional(value) && this.optional(param)) || value == param 357 | } 358 | /** 359 | * 验证是否包含某个值 360 | */ 361 | export function contains(value, param) { 362 | return this.optional(value) || value.indexOf(param) >= 0 363 | } 364 | /** 365 | * 验证最小长度 366 | */ 367 | export function minlength(value, param) { 368 | return this.optional(value) || value.length >= param 369 | } 370 | /** 371 | * 验证最大长度 372 | */ 373 | export function maxlength(value, param) { 374 | return this.optional(value) || value.length <= param 375 | } 376 | /** 377 | * 验证一个长度范围[min, max] 378 | */ 379 | export function rangelength(value, param) { 380 | return this.optional(value) || (value.length >= param[0] && value.length <= param[1]) 381 | } 382 | /** 383 | * 验证最小值 384 | */ 385 | export function min(value, param) { 386 | return this.optional(value) || value >= param 387 | } 388 | /** 389 | * 验证最大值 390 | */ 391 | export function max(value, param) { 392 | return this.optional(value) || value <= param 393 | } 394 | /** 395 | * 验证一个值范围[min, max] 396 | */ 397 | export function range(value, param) { 398 | return this.optional(value) || (value >= param[0] && value <= param[1]) 399 | } 400 | /** 401 | * 判断规则依赖是否存在 402 | */ 403 | export function depend(param) { 404 | switch (typeof param) { 405 | case 'boolean': 406 | param = param 407 | break 408 | case 'string': 409 | param = !!param.length 410 | break 411 | case 'function': 412 | param = param() 413 | default: 414 | param = !0 415 | } 416 | return param 417 | } 418 | 419 | /** 420 | * 判断输入值是否为空 421 | */ 422 | export function optional(value) { 423 | return !this.required(value) && 'dependency-mismatch' 424 | } 425 | 426 | /** 427 | * 数组对象对比 428 | */ 429 | export function arrCompare(property){ 430 | return function(a,b){ 431 | var value1 = a[property]; 432 | var value2 = b[property]; 433 | return value1 - value2; 434 | } 435 | } 436 | 437 | export default { 438 | formatNumber, 439 | formatTime, 440 | formatTimeMin, 441 | formatTimeDate, 442 | formatTimeDateDay, 443 | wxSetStorage, 444 | wxGetStorage, 445 | wxSetStorageSync, 446 | showDialog, 447 | formatImgUrl, 448 | formatImgUrlRetailer, 449 | formatTimeDiff, 450 | transLocalTime, 451 | countHeight, 452 | parseDate, 453 | /* 验证 */ 454 | required, 455 | tel, 456 | email, 457 | url, 458 | date, 459 | dateISO, 460 | number, 461 | digits, 462 | idcard, 463 | equalTo, 464 | contains, 465 | minlength, 466 | maxlength, 467 | rangelength, 468 | min, 469 | max, 470 | range, 471 | depend, 472 | optional, 473 | /* 验证 结束*/ 474 | arrCompare, 475 | 476 | } 477 | -------------------------------------------------------------------------------- /src/utils/md5.js: -------------------------------------------------------------------------------- 1 | /* 2 | * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message 3 | * Digest Algorithm, as defined in RFC 1321. 4 | * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002. 5 | * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet 6 | * Distributed under the BSD License 7 | * See http://pajhome.org.uk/crypt/md5 for more info. 8 | */ 9 | 10 | /* 11 | * Configurable variables. You may need to tweak these to be compatible with 12 | * the server-side, but the defaults work in most cases. 13 | */ 14 | var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ 15 | var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */ 16 | var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */ 17 | 18 | /* 19 | * These are the functions you'll usually want to call 20 | * They take string arguments and return either hex or base-64 encoded strings 21 | */ 22 | export function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));} 23 | function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));} 24 | function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));} 25 | function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); } 26 | function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); } 27 | function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); } 28 | 29 | /* 30 | * Perform a simple self-test to see if the VM is working 31 | */ 32 | function md5_vm_test() 33 | { 34 | return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72"; 35 | } 36 | 37 | /* 38 | * Calculate the MD5 of an array of little-endian words, and a bit length 39 | */ 40 | function core_md5(x, len) 41 | { 42 | /* append padding */ 43 | x[len >> 5] |= 0x80 << ((len) % 32); 44 | x[(((len + 64) >>> 9) << 4) + 14] = len; 45 | 46 | var a = 1732584193; 47 | var b = -271733879; 48 | var c = -1732584194; 49 | var d = 271733878; 50 | 51 | for(var i = 0; i < x.length; i += 16) 52 | { 53 | var olda = a; 54 | var oldb = b; 55 | var oldc = c; 56 | var oldd = d; 57 | 58 | a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936); 59 | d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586); 60 | c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819); 61 | b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330); 62 | a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897); 63 | d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426); 64 | c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341); 65 | b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983); 66 | a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416); 67 | d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417); 68 | c = md5_ff(c, d, a, b, x[i+10], 17, -42063); 69 | b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162); 70 | a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682); 71 | d = md5_ff(d, a, b, c, x[i+13], 12, -40341101); 72 | c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290); 73 | b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329); 74 | 75 | a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510); 76 | d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632); 77 | c = md5_gg(c, d, a, b, x[i+11], 14, 643717713); 78 | b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302); 79 | a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691); 80 | d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083); 81 | c = md5_gg(c, d, a, b, x[i+15], 14, -660478335); 82 | b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848); 83 | a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438); 84 | d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690); 85 | c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961); 86 | b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501); 87 | a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467); 88 | d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784); 89 | c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473); 90 | b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734); 91 | 92 | a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558); 93 | d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463); 94 | c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562); 95 | b = md5_hh(b, c, d, a, x[i+14], 23, -35309556); 96 | a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060); 97 | d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353); 98 | c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632); 99 | b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640); 100 | a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174); 101 | d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222); 102 | c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979); 103 | b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189); 104 | a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487); 105 | d = md5_hh(d, a, b, c, x[i+12], 11, -421815835); 106 | c = md5_hh(c, d, a, b, x[i+15], 16, 530742520); 107 | b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651); 108 | 109 | a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844); 110 | d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415); 111 | c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905); 112 | b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055); 113 | a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571); 114 | d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606); 115 | c = md5_ii(c, d, a, b, x[i+10], 15, -1051523); 116 | b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799); 117 | a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359); 118 | d = md5_ii(d, a, b, c, x[i+15], 10, -30611744); 119 | c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380); 120 | b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649); 121 | a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070); 122 | d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379); 123 | c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259); 124 | b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551); 125 | 126 | a = safe_add(a, olda); 127 | b = safe_add(b, oldb); 128 | c = safe_add(c, oldc); 129 | d = safe_add(d, oldd); 130 | } 131 | return Array(a, b, c, d); 132 | 133 | } 134 | 135 | /* 136 | * These functions implement the four basic operations the algorithm uses. 137 | */ 138 | function md5_cmn(q, a, b, x, s, t) 139 | { 140 | return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b); 141 | } 142 | function md5_ff(a, b, c, d, x, s, t) 143 | { 144 | return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); 145 | } 146 | function md5_gg(a, b, c, d, x, s, t) 147 | { 148 | return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); 149 | } 150 | function md5_hh(a, b, c, d, x, s, t) 151 | { 152 | return md5_cmn(b ^ c ^ d, a, b, x, s, t); 153 | } 154 | function md5_ii(a, b, c, d, x, s, t) 155 | { 156 | return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); 157 | } 158 | 159 | /* 160 | * Calculate the HMAC-MD5, of a key and some data 161 | */ 162 | function core_hmac_md5(key, data) 163 | { 164 | var bkey = str2binl(key); 165 | if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz); 166 | 167 | var ipad = Array(16), opad = Array(16); 168 | for(var i = 0; i < 16; i++) 169 | { 170 | ipad[i] = bkey[i] ^ 0x36363636; 171 | opad[i] = bkey[i] ^ 0x5C5C5C5C; 172 | } 173 | 174 | var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz); 175 | return core_md5(opad.concat(hash), 512 + 128); 176 | } 177 | 178 | /* 179 | * Add integers, wrapping at 2^32. This uses 16-bit operations internally 180 | * to work around bugs in some JS interpreters. 181 | */ 182 | function safe_add(x, y) 183 | { 184 | var lsw = (x & 0xFFFF) + (y & 0xFFFF); 185 | var msw = (x >> 16) + (y >> 16) + (lsw >> 16); 186 | return (msw << 16) | (lsw & 0xFFFF); 187 | } 188 | 189 | /* 190 | * Bitwise rotate a 32-bit number to the left. 191 | */ 192 | function bit_rol(num, cnt) 193 | { 194 | return (num << cnt) | (num >>> (32 - cnt)); 195 | } 196 | 197 | /* 198 | * Convert a string to an array of little-endian words 199 | * If chrsz is ASCII, characters >255 have their hi-byte silently ignored. 200 | */ 201 | function str2binl(str) 202 | { 203 | var bin = Array(); 204 | var mask = (1 << chrsz) - 1; 205 | for(var i = 0; i < str.length * chrsz; i += chrsz) 206 | bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32); 207 | return bin; 208 | } 209 | 210 | /* 211 | * Convert an array of little-endian words to a string 212 | */ 213 | function binl2str(bin) 214 | { 215 | var str = ""; 216 | var mask = (1 << chrsz) - 1; 217 | for(var i = 0; i < bin.length * 32; i += chrsz) 218 | str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask); 219 | return str; 220 | } 221 | 222 | /* 223 | * Convert an array of little-endian words to a hex string. 224 | */ 225 | function binl2hex(binarray) 226 | { 227 | var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; 228 | var str = ""; 229 | for(var i = 0; i < binarray.length * 4; i++) 230 | { 231 | str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) + 232 | hex_tab.charAt((binarray[i>>2] >> ((i%4)*8 )) & 0xF); 233 | } 234 | return str; 235 | } 236 | 237 | /* 238 | * Convert an array of little-endian words to a base-64 string 239 | */ 240 | function binl2b64(binarray) 241 | { 242 | var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 243 | var str = ""; 244 | for(var i = 0; i < binarray.length * 4; i += 3) 245 | { 246 | var triplet = (((binarray[i >> 2] >> 8 * ( i %4)) & 0xFF) << 16) 247 | | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 ) 248 | | ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF); 249 | for(var j = 0; j < 4; j++) 250 | { 251 | if(i * 8 + j * 6 > binarray.length * 32) str += b64pad; 252 | else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F); 253 | } 254 | } 255 | return str; 256 | } 257 | -------------------------------------------------------------------------------- /src/utils/numberAnimate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by fuckskuku on 2018/01/22. 3 | */ 4 | 'use strict'; 5 | class NumberAnimate { 6 | 7 | constructor(opt) { 8 | let def = { 9 | from:50,//开始时的数字 10 | speed:1000 * 60,// 总时间 11 | refreshTime: 500,// 刷新一次的时间 12 | decimals:2,// 小数点后的位数 13 | onUpdate:function(){}, // 更新时回调函数 14 | onComplete:function(){} // 完成时回调函数 15 | } 16 | this.tempValue = 0;//累加变量值 17 | this.opt = Object.assign(def,opt);//assign传入配置参数 18 | this.loopCount = 0;//循环次数计数 19 | this.loops = Math.ceil(this.opt.speed/this.opt.refreshTime);//数字累加次数 20 | this.increment = (this.opt.from/this.loops);//每次累加的值 21 | this.interval = null;//计时器对象 22 | this.init(); 23 | } 24 | init(){ 25 | this.interval = setInterval(()=>{this.updateTimer()},this.opt.refreshTime); 26 | } 27 | 28 | updateTimer(){ 29 | 30 | this.loopCount++; 31 | this.tempValue = this.formatFloat(this.tempValue,this.increment).toFixed(this.opt.decimals); 32 | if(this.loopCount >= this.loops){ 33 | clearInterval(this.interval); 34 | this.tempValue = this.opt.from; 35 | this.opt.onComplete(); 36 | } 37 | this.opt.onUpdate(); 38 | } 39 | //解决0.1+0.2不等于0.3的小数累加精度问题 40 | formatFloat(num1, num2) { 41 | let baseNum, baseNum1, baseNum2; 42 | try { 43 | baseNum1 = num1.toString().split(".")[1].length; 44 | } catch (e) { 45 | baseNum1 = 0; 46 | } 47 | try { 48 | baseNum2 = num2.toString().split(".")[1].length; 49 | } catch (e) { 50 | baseNum2 = 0; 51 | } 52 | baseNum = Math.pow(10, Math.max(baseNum1, baseNum2)); 53 | return (num1 * baseNum + num2 * baseNum) / baseNum; 54 | }; 55 | } 56 | export default NumberAnimate; -------------------------------------------------------------------------------- /src/utils/qiniuUploader.js: -------------------------------------------------------------------------------- 1 | // created by gpake 2 | (function() { 3 | 4 | var config = { 5 | qiniuRegion: '', 6 | qiniuImageURLPrefix: '', 7 | qiniuUploadToken: '', 8 | qiniuUploadTokenURL: '', 9 | qiniuUploadTokenFunction: null, 10 | qiniuShouldUseQiniuFileName: false 11 | } 12 | 13 | module.exports = { 14 | init: init, 15 | upload: upload, 16 | } 17 | 18 | // 在整个程序生命周期中,只需要 init 一次即可 19 | // 如果需要变更参数,再调用 init 即可 20 | function init(options) { 21 | config = { 22 | qiniuRegion: '', 23 | qiniuImageURLPrefix: '', 24 | qiniuUploadToken: '', 25 | qiniuUploadTokenURL: '', 26 | qiniuUploadTokenFunction: null, 27 | qiniuShouldUseQiniuFileName: false 28 | }; 29 | updateConfigWithOptions(options); 30 | } 31 | 32 | function updateConfigWithOptions(options) { 33 | if (options.region) { 34 | config.qiniuRegion = options.region; 35 | } else { 36 | console.error('qiniu uploader need your bucket region'); 37 | } 38 | if (options.uptoken) { 39 | config.qiniuUploadToken = options.uptoken; 40 | } else if (options.uptokenURL) { 41 | config.qiniuUploadTokenURL = options.uptokenURL; 42 | } else if(options.uptokenFunc) { 43 | config.qiniuUploadTokenFunction = options.uptokenFunc; 44 | } 45 | if (options.domain) { 46 | config.qiniuImageURLPrefix = options.domain; 47 | } 48 | config.qiniuShouldUseQiniuFileName = options.shouldUseQiniuFileName 49 | } 50 | 51 | function upload(filePath, success, fail, options, progress, cancelTask) { 52 | if (null == filePath) { 53 | console.error('qiniu uploader need filePath to upload'); 54 | return; 55 | } 56 | if (options) { 57 | updateConfigWithOptions(options); 58 | } 59 | if (config.qiniuUploadToken) { 60 | doUpload(filePath, success, fail, options, progress, cancelTask); 61 | } else if (config.qiniuUploadTokenURL) { 62 | getQiniuToken(function() { 63 | doUpload(filePath, success, fail, options, progress, cancelTask); 64 | }); 65 | } else if (config.qiniuUploadTokenFunction) { 66 | config.qiniuUploadToken = config.qiniuUploadTokenFunction(); 67 | if (null == config.qiniuUploadToken && config.qiniuUploadToken.length > 0) { 68 | console.error('qiniu UploadTokenFunction result is null, please check the return value'); 69 | return 70 | } 71 | doUpload(filePath, success, fail, options, progress, cancelTask); 72 | } else { 73 | console.error('qiniu uploader need one of [uptoken, uptokenURL, uptokenFunc]'); 74 | return; 75 | } 76 | } 77 | 78 | function doUpload(filePath, success, fail, options, progress, cancelTask) { 79 | if (null == config.qiniuUploadToken && config.qiniuUploadToken.length > 0) { 80 | console.error('qiniu UploadToken is null, please check the init config or networking'); 81 | return 82 | } 83 | var url = uploadURLFromRegionCode(config.qiniuRegion); 84 | var fileName = filePath.split('//')[1]; 85 | if (options && options.key) { 86 | fileName = options.key; 87 | } 88 | var formData = { 89 | 'token': config.qiniuUploadToken 90 | }; 91 | if (!config.qiniuShouldUseQiniuFileName) { 92 | formData['key'] = fileName 93 | } 94 | var uploadTask = wx.uploadFile({ 95 | url: url, 96 | filePath: filePath, 97 | name: 'file', 98 | formData: formData, 99 | success: function (res) { 100 | var dataString = res.data 101 | if(res.data.hasOwnProperty('type') && res.data.type === 'Buffer'){ 102 | dataString = String.fromCharCode.apply(null, res.data.data) 103 | } 104 | try { 105 | var dataObject = JSON.parse(dataString); 106 | //do something 107 | var imageUrl = config.qiniuImageURLPrefix + '/' + dataObject.key; 108 | dataObject.imageURL = imageUrl; 109 | console.log(dataObject); 110 | if (success) { 111 | success(dataObject); 112 | } 113 | } catch(e) { 114 | console.log('parse JSON failed, origin String is: ' + dataString) 115 | if (fail) { 116 | fail(e); 117 | } 118 | } 119 | }, 120 | fail: function (error) { 121 | console.error(error); 122 | if (fail) { 123 | fail(error); 124 | } 125 | } 126 | }) 127 | 128 | uploadTask.onProgressUpdate((res) => { 129 | progress && progress(res) 130 | }) 131 | 132 | cancelTask && cancelTask(() => { 133 | uploadTask.abort() 134 | }) 135 | } 136 | 137 | function getQiniuToken(callback) { 138 | wx.request({ 139 | url: config.qiniuUploadTokenURL, 140 | success: function (res) { 141 | var token = res.data.uptoken; 142 | if (token && token.length > 0) { 143 | config.qiniuUploadToken = token; 144 | if (callback) { 145 | callback(); 146 | } 147 | } else { 148 | console.error('qiniuUploader cannot get your token, please check the uptokenURL or server') 149 | } 150 | }, 151 | fail: function (error) { 152 | console.error('qiniu UploadToken is null, please check the init config or networking: ' + error); 153 | } 154 | }) 155 | } 156 | 157 | function uploadURLFromRegionCode(code) { 158 | var uploadURL = null; 159 | switch(code) { 160 | case 'ECN': uploadURL = 'https://up.qbox.me'; break; 161 | case 'NCN': uploadURL = 'https://up-z1.qbox.me'; break; 162 | case 'SCN': uploadURL = 'https://up-z2.qbox.me'; break; 163 | case 'NA': uploadURL = 'https://up-na0.qbox.me'; break; 164 | case 'ASG': uploadURL = 'https://up-as0.qbox.me'; break; 165 | default: console.error('please make the region is with one of [ECN, SCN, NCN, NA, ASG]'); 166 | } 167 | return uploadURL; 168 | } 169 | 170 | })(); 171 | -------------------------------------------------------------------------------- /static/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/.gitkeep -------------------------------------------------------------------------------- /static/assets/scss/btn.scss: -------------------------------------------------------------------------------- 1 | .btn{ 2 | width: 518rpx; 3 | height: 90rpx; 4 | line-height: 90rpx; 5 | border-radius: 90rpx; 6 | border: none; 7 | outline: none; 8 | font-size: 32rpx; 9 | background: linear-gradient(to right,#75D672,#14BF6D); 10 | color: #ffffff; 11 | } 12 | .cancel{ 13 | background: #fff; 14 | color: #14BF6D; 15 | border: 1px solid #14BF6D; 16 | } 17 | .disabled{ 18 | color:rgba(255,255,255,0.6); 19 | } -------------------------------------------------------------------------------- /static/assets/scss/components/dialog.scss: -------------------------------------------------------------------------------- 1 | .container{ 2 | position: absolute; 3 | width: 100%; 4 | height: 100%; 5 | background: rgba(0, 0, 0, 0.8); 6 | } 7 | .dialog{ 8 | width: 660rpx; 9 | margin: 90rpx auto 0; 10 | background: #ffffff; 11 | border-radius: 10rpx; 12 | overflow: hidden; 13 | .title{ 14 | padding: 60rpx 0 50rpx; 15 | text-align: center; 16 | } 17 | .subTitle{ 18 | padding-left: 12rpx; 19 | margin-bottom: 20rpx; 20 | } 21 | .content{ 22 | padding: 0 30rpx; 23 | } 24 | .btn{ 25 | height: 100rpx; 26 | line-height: 100rpx; 27 | text-align: center; 28 | color: #14BF6D; 29 | font-size: 36rpx; 30 | border-top: 1rpx solid #E5E5E5; 31 | } 32 | .period{ 33 | display: flex; 34 | align-items: center; 35 | width: 97%; 36 | margin: 0 auto 36rpx; 37 | .lt{ 38 | position: relative; 39 | font-size: 30rpx; 40 | img{ 41 | width: 26rpx; 42 | height: 15rpx; 43 | position: absolute; 44 | top: 50%; 45 | right: 20rpx; 46 | margin-top: -7rpx; 47 | } 48 | } 49 | .center{ 50 | margin: 0 10rpx; 51 | } 52 | .rt{ 53 | position: relative; 54 | font-size: 30rpx; 55 | img{ 56 | width: 26rpx; 57 | height: 15rpx; 58 | position: absolute; 59 | top: 50%; 60 | right: 20rpx; 61 | margin-top: -7rpx; 62 | } 63 | } 64 | .fd{ 65 | color: #ffffff; 66 | display: flex; 67 | align-items: center; 68 | .del{ 69 | width: 44rpx; 70 | height: 44rpx; 71 | text-align: center; 72 | line-height: 44rpx; 73 | font-size: 42rpx; 74 | border-radius: 50%; 75 | -webkit-border-radius: 50%; 76 | -moz-border-radius: 50%; 77 | -ms-border-radius: 50%; 78 | -o-border-radius: 50%; 79 | background: #FF4E4D; 80 | margin: 0 15rpx; 81 | img{ 82 | width: 100%; 83 | height: 100%; 84 | } 85 | } 86 | .add{ 87 | width: 44rpx; 88 | height: 44rpx; 89 | text-align: center; 90 | line-height: 44rpx; 91 | font-size: 42rpx; 92 | border-radius: 50%; 93 | -webkit-border-radius: 50%; 94 | -moz-border-radius: 50%; 95 | -ms-border-radius: 50%; 96 | -o-border-radius: 50%; 97 | background: #14BF6D; 98 | margin: 0 15rpx; 99 | img{ 100 | width: 100%; 101 | height: 100%; 102 | } 103 | } 104 | p{ 105 | position: relative; 106 | top: -4rpx; 107 | } 108 | } 109 | input{ 110 | border: 1rpx solid #ccc; 111 | width: 190rpx; 112 | height: 70rpx; 113 | border-radius: 10rpx; 114 | padding: 0 0 0 10rpx; 115 | } 116 | .two{ 117 | input{ 118 | width: 570rpx; 119 | } 120 | } 121 | } 122 | } 123 | 124 | -------------------------------------------------------------------------------- /static/assets/scss/electricitySet/coupons.scss: -------------------------------------------------------------------------------- 1 | .coupons{ 2 | .content{ 3 | padding: 30rpx 30rpx; 4 | background: #f4f4f4; 5 | } 6 | .cell{ 7 | width: 100%; 8 | height: 242rpx; 9 | color: #14BF6D; 10 | background: #ffffff; 11 | background: url('https://charge.xmnewlife.com/images/newlife_master/history_coupon/img_coupon2.png') no-repeat; 12 | background-size: 100% 100%; 13 | } 14 | .box{ 15 | display: flex; 16 | align-items: center; 17 | border-radius: 10rpx; 18 | position: relative; 19 | top: 10rpx; 20 | z-index: 19; 21 | .img_hd{ 22 | position: absolute; 23 | top: 0; 24 | left: 0; 25 | width: 100%; 26 | height: 100%; 27 | z-index: 9; 28 | } 29 | .lt{ 30 | flex: 6; 31 | font-size: 28rpx; 32 | padding: 0 0 0 25rpx; 33 | color: #FF9C00; 34 | position: relative; 35 | top: 3rpx; 36 | p{ 37 | margin-bottom: 10rpx; 38 | } 39 | .price{ 40 | font-size: 100rpx; 41 | font-weight: bold; 42 | margin: 0 10rpx 0 -8rpx; 43 | } 44 | } 45 | .rt{ 46 | flex: 4; 47 | text-align: right; 48 | padding: 0 25rpx 0 0; 49 | .hd{ 50 | color: #FF9C00; 51 | font-size: 30rpx; 52 | // margin-top: 48rpx; 53 | } 54 | .fd{ 55 | color: #999999; 56 | font-size: 24rpx; 57 | 58 | } 59 | } 60 | 61 | } 62 | .used{ 63 | color: #999999 !important; 64 | background: url('https://charge.xmnewlife.com/images/newlife_master/history_coupon/img_coupon2.png') no-repeat; 65 | background-size: 100% 100%; 66 | position: relative; 67 | .img_mark{ 68 | width: 120rpx; 69 | height: 94rpx; 70 | position: absolute; 71 | top: 0rpx; 72 | right: 180rpx; 73 | z-index: 9999; 74 | } 75 | .lt{ 76 | color: #999999; 77 | } 78 | .rt{ 79 | .hd{ 80 | color: #999999; 81 | } 82 | .fd{ 83 | 84 | } 85 | } 86 | } 87 | .foot{ 88 | font-size: 24rpx; 89 | color: #999999; 90 | padding: 0 30rpx; 91 | border-top: 1rpx solid #E9E9E9; 92 | display: flex; 93 | align-items: center; 94 | height: 60rpx; 95 | line-height: 60rpx; 96 | padding-top: 8rpx; 97 | } 98 | } 99 | .empty{ 100 | width: 374rpx; 101 | height: 360rpx; 102 | font-size: 34rpx; 103 | color: #777; 104 | text-align:center; 105 | position: relative; 106 | margin: 0 auto; 107 | padding-bottom: 30rpx; 108 | img{ 109 | width: 374rpx; 110 | height: 288rpx; 111 | } 112 | } 113 | .weui-navbar__item.weui-bar__item_on { 114 | color: #14BF6D; 115 | } 116 | // navBar底部slider长度 117 | .weui-navbar__slider{ 118 | width: 1.2em; 119 | height: 8rpx; 120 | background-color: #14BF6D; 121 | border-radius: 8rpx; 122 | -webkit-border-radius: 8rpx; 123 | -moz-border-radius: 8rpx; 124 | -ms-border-radius: 8rpx; 125 | -o-border-radius: 8rpx; 126 | } 127 | .weui-tab__panel{ 128 | position: absolute; 129 | height: 100%; 130 | width: 100%; 131 | } 132 | // navBar定位 133 | .weui-navbar{ 134 | border-bottom: none; 135 | position: fixed; 136 | top: 0; 137 | left: 0; 138 | background: #ffffff; 139 | } 140 | .weui-tab__content{ 141 | 142 | background: #f4f4f4; 143 | } 144 | // 优惠券背景色 145 | .coupons_content{ 146 | background: #ffffff; 147 | } 148 | .child{ 149 | background: #f4f4f4; 150 | } -------------------------------------------------------------------------------- /static/assets/scss/electricitySet/couponsDetails.scss: -------------------------------------------------------------------------------- 1 | .coupons{ 2 | .content{ 3 | background: #f4f4f4; 4 | } 5 | .box{ 6 | width: 704rpx; 7 | height: 914rpx; 8 | //padding-bottom: 80rpx; 9 | border-radius: 10rpx; 10 | margin: 40rpx auto; 11 | position: relative; 12 | text-align: center; 13 | .btn{ 14 | width: 520rpx; 15 | height: 90rpx; 16 | line-height: 90rpx; 17 | border-radius: 90rpx; 18 | border: none; 19 | outline: none; 20 | background: linear-gradient(to right,#75D672,#14BF6D); 21 | color: #ffffff; 22 | margin-top: 60rpx; 23 | } 24 | .hd{ 25 | width: 100%; 26 | height: 340rpx; 27 | .price{ 28 | color: #FF9C00; 29 | font-size: 42rpx; 30 | span{ 31 | font-size: 120rpx; 32 | } 33 | } 34 | .price_desc{ 35 | color: #333333; 36 | font-size: 30rpx; 37 | } 38 | } 39 | .fd{ 40 | width: 100%; 41 | height: 620rpx; 42 | text-align: left; 43 | // padding: 52rpx 0 80rpx; 44 | p{ 45 | color: #999999; 46 | font-size: 28rpx; 47 | padding: 20rpx 86rpx; 48 | span{ 49 | color: #333333; 50 | font-size: 28rpx; 51 | } 52 | } 53 | } 54 | } 55 | .used{ 56 | color: #999999 !important; 57 | } 58 | } 59 | 60 | // overflow 61 | .parent{ 62 | position: absolute; 63 | height:100%;//高度根据需求自行设定 64 | width: 100%; 65 | background: #f4f4f4; 66 | } 67 | .child{ 68 | position:absolute; 69 | left:0; 70 | top:0; 71 | right:0; 72 | bottom:0; //left,top,right,bottom都为0,充满真个页面 73 | overflow-y:auto !important; 74 | overflow-x:hidden !important; //设置Y轴出现滚动条,X轴隐藏 75 | -webkit-overflow-scrolling: touch; 76 | } -------------------------------------------------------------------------------- /static/assets/scss/electricitySet/electricitySet.scss: -------------------------------------------------------------------------------- 1 | .weui-navbar__item.weui-bar__item_on { 2 | color: #14BF6D; 3 | } 4 | // navBar底部slider长度 5 | .weui-navbar__slider{ 6 | width: 1.2em; 7 | height: 8rpx; 8 | background-color: #14BF6D; 9 | border-radius: 8rpx; 10 | -webkit-border-radius: 8rpx; 11 | -moz-border-radius: 8rpx; 12 | -ms-border-radius: 8rpx; 13 | -o-border-radius: 8rpx; 14 | } 15 | .weui-tab__panel{ 16 | position: absolute; 17 | height: 100%; 18 | width: 100%; 19 | } 20 | // navBar定位 21 | .weui-navbar{ 22 | border-bottom: none; 23 | position: fixed; 24 | top: 0; 25 | left: 0; 26 | background: #ffffff; 27 | } 28 | .weui-tab__content{ 29 | background: #F7FFFB; 30 | } 31 | // 优惠券背景色 32 | .coupons_content{ 33 | background: #ffffff; 34 | } 35 | /* 36 | 电价设置 37 | */ 38 | .set{ 39 | .box{ 40 | padding: 75rpx 75rpx 65rpx; 41 | margin: 0 auto; 42 | .cell{ 43 | font-size: 32rpx; 44 | color: #333333; 45 | margin-bottom: 22rpx; 46 | display: flex; 47 | align-items: center; 48 | .sign{ 49 | color: #14BF6D; 50 | font-size: 50rpx; 51 | position: relative; 52 | top: 4rpx; 53 | margin-right: 8rpx; 54 | } 55 | .input{ 56 | margin-top: 16rpx; 57 | height: 80rpx; 58 | padding-left: 1em; 59 | border: 1rpx solid #999999; 60 | border-radius: 10rpx; 61 | -webkit-border-radius: 10rpx; 62 | -moz-border-radius: 10rpx; 63 | -ms-border-radius: 10rpx; 64 | -o-border-radius: 10rpx; 65 | } 66 | } 67 | } 68 | .section{ 69 | padding-bottom: 50rpx; 70 | .btn{ 71 | margin-bottom: 40rpx; 72 | } 73 | .cancel{ 74 | background: transparent; 75 | } 76 | } 77 | .footer{ 78 | width: 538rpx; 79 | height: 154rpx; 80 | margin: 0 auto; 81 | padding-bottom: 36rpx; 82 | img{ 83 | width: 538rpx; 84 | height: 154rpx; 85 | } 86 | } 87 | } 88 | 89 | /* 90 | 设置优惠券 91 | */ 92 | .coupons{ 93 | font-size: 32rpx; 94 | .header{ 95 | margin-top: 40rpx; 96 | .title{ 97 | padding: 30rpx 30rpx 14rpx; 98 | text-align: right; 99 | color: #FF8A00; 100 | font-size: 30rpx; 101 | img{ 102 | width: 22rpx; 103 | height: 24rpx; 104 | } 105 | } 106 | } 107 | .section{ 108 | .box{ 109 | padding: 0 30rpx; 110 | margin: 0 auto; 111 | .cell{ 112 | font-size: 32rpx; 113 | color: #333333; 114 | margin-bottom: 22rpx; 115 | display: flex; 116 | align-items: center; 117 | span{ 118 | position: relative; 119 | top: 2rpx; 120 | } 121 | .sign{ 122 | color: #14BF6D; 123 | font-size: 50rpx; 124 | position: relative; 125 | top: 2rpx; 126 | margin-right: 8rpx; 127 | } 128 | .input{ 129 | flex:2; 130 | margin-top: 16rpx; 131 | margin-left: 16rpx; 132 | height: 80rpx; 133 | padding-left: 1em; 134 | border: 1rpx solid #999999; 135 | border-radius: 10rpx; 136 | -webkit-border-radius: 10rpx; 137 | -moz-border-radius: 10rpx; 138 | -ms-border-radius: 10rpx; 139 | -o-border-radius: 10rpx; 140 | } 141 | } 142 | } 143 | // 144 | .warp{ 145 | padding: 30rpx 30rpx 0; 146 | margin: 0 auto; 147 | .cell{ 148 | font-size: 32rpx; 149 | color: #333333; 150 | margin-bottom: 22rpx; 151 | 152 | .sign{ 153 | color: #14BF6D; 154 | font-size: 50rpx; 155 | margin-right: 8rpx; 156 | position: relative; 157 | top: 6rpx; 158 | } 159 | .fd{ 160 | position: relative; 161 | display: flex; 162 | align-items: center; 163 | span{ 164 | position: relative; 165 | top: 2rpx; 166 | } 167 | .input{ 168 | flex: 2; 169 | margin-top: 16rpx; 170 | height: 80rpx; 171 | padding-left: 1em; 172 | border: 1rpx solid #999999; 173 | border-radius: 10rpx; 174 | -webkit-border-radius: 10rpx; 175 | -moz-border-radius: 10rpx; 176 | -ms-border-radius: 10rpx; 177 | -o-border-radius: 10rpx; 178 | margin-left: 16rpx; 179 | } 180 | .arrow{ 181 | width: 14rpx; 182 | height: 26rpx; 183 | position: absolute; 184 | right: 30rpx; 185 | top: 50%; 186 | margin-top: -11rpx; 187 | } 188 | } 189 | 190 | } 191 | } 192 | .tip{ 193 | font-size: 30rpx; 194 | color: #999999; 195 | padding: 10rpx 30rpx; 196 | } 197 | } 198 | .footer{ 199 | .btn{ 200 | margin: 40rpx auto 50rpx; 201 | } 202 | } 203 | } 204 | -------------------------------------------------------------------------------- /static/assets/scss/electricitySet/periodElectricity.scss: -------------------------------------------------------------------------------- 1 | .child{ 2 | background: #f4f4f4; 3 | } 4 | .cell{ 5 | margin-bottom: 26rpx; 6 | background: #ffffff; 7 | .hd{ 8 | display: flex; 9 | text-indent: 24rpx; 10 | position: relative; 11 | padding: 30rpx; 12 | .line{ 13 | width: 8rpx; 14 | height: 28rpx; 15 | background: #14BF6D; 16 | position: absolute; 17 | top: 50%; 18 | left: 30rpx; 19 | margin-top: -16rpx; 20 | } 21 | .lt{ 22 | flex: 1; 23 | color: #333333; 24 | } 25 | .rt{ 26 | flex: 1; 27 | text-align: right; 28 | .edit{ 29 | display: inline-block; 30 | vertical-align: middle; 31 | text-align: center; 32 | text-indent: 0rpx; 33 | padding: 0; 34 | width: 100rpx; 35 | height: 46rpx; 36 | line-height: 46rpx; 37 | color: #14BF6D; 38 | font-size: 30rpx; 39 | border: 1rpx solid #14BF6D; 40 | border-radius: 23rpx; 41 | -webkit-border-radius: 23rpx; 42 | -moz-border-radius: 23rpx; 43 | -ms-border-radius: 23rpx; 44 | -o-border-radius: 23rpx; 45 | } 46 | .del{ 47 | display: inline-block; 48 | vertical-align: middle; 49 | width: 46rpx; 50 | height: 46rpx; 51 | margin-right: 40rpx; 52 | img{ 53 | width: 46rpx; 54 | height: 46rpx; 55 | } 56 | } 57 | } 58 | } 59 | .hd::after{ 60 | width: 96%; 61 | content: ''; 62 | border-bottom: 1rpx solid #E5E5E5; 63 | position: absolute; 64 | right: 0; 65 | bottom: -1rpx; 66 | } 67 | .bd{ 68 | display: flex; 69 | font-size: 30rpx; 70 | padding: 30rpx; 71 | .lt{ 72 | flex: 4; 73 | color: #999999; 74 | font-size: 28rpx; 75 | } 76 | .rt{ 77 | flex: 6; 78 | display: flex; 79 | align-items: center; 80 | text-align: center; 81 | color: #333333; 82 | p{ 83 | flex: 1; 84 | } 85 | } 86 | } 87 | } 88 | .empty{ 89 | text-align: center; 90 | .banner{ 91 | width: 374rpx; 92 | height: 288rpx; 93 | margin: 0 auto; 94 | padding-top: 120rpx; 95 | img{ 96 | width: 100%; 97 | height: 100%; 98 | } 99 | } 100 | } 101 | 102 | .desc{ 103 | padding: 0 30rpx; 104 | background: #f4f4f4; 105 | font-size: 28rpx; 106 | color: #999999; 107 | } 108 | .btn{ 109 | margin-top: 90rpx; 110 | } -------------------------------------------------------------------------------- /static/assets/scss/home/electricityBills.scss: -------------------------------------------------------------------------------- 1 | .header{ 2 | width: 100%; 3 | height: 280rpx; 4 | background: url('https://charge.xmnewlife.com/images/newlife_master/index_charge_fund/img_electric_bg.png') no-repeat; 5 | background-size: 100% 100%; 6 | position: relative; 7 | .energy{ 8 | width: 300rpx; 9 | height: 150rpx; 10 | color: #ffffff; 11 | text-align: center; 12 | position: absolute; 13 | top: 0; 14 | bottom: 0; 15 | left: 0; 16 | right: 0; 17 | margin: auto; 18 | .title{ 19 | font-size: 34rpx; 20 | } 21 | .context{ 22 | font-size: 90rpx; 23 | position: relative; 24 | top: -10rpx; 25 | } 26 | } 27 | } 28 | .section{ 29 | background: #ffffff; 30 | .cell{ 31 | display: flex; 32 | font-size: 34rpx; 33 | position: relative; 34 | padding: 30rpx; 35 | .hd{ 36 | flex: 1; 37 | color: #333333; 38 | .subTitle{ 39 | margin-top: 20rpx; 40 | } 41 | } 42 | .fd{ 43 | flex: 1; 44 | text-align: right; 45 | .degree{ 46 | color: #14BF6D; 47 | } 48 | .time{ 49 | font-size: 24rpx; 50 | color: #666666; 51 | } 52 | } 53 | .lt{ 54 | flex: 4; 55 | color: #999999; 56 | } 57 | .rt{ 58 | flex: 6; 59 | text-align: right; 60 | color: #333333; 61 | } 62 | } 63 | .cell::after{ 64 | content: ""; 65 | width: 97%; 66 | position: absolute; 67 | right: 0; 68 | bottom: 0; 69 | border-bottom: 1rpx solid #E5E5E5; 70 | } 71 | .cell:last-child:after{ 72 | border-bottom: none; 73 | } 74 | 75 | } 76 | .child{ 77 | padding-bottom: 240rpx; 78 | background: #f4f4f4; 79 | } -------------------------------------------------------------------------------- /static/assets/scss/home/home.scss: -------------------------------------------------------------------------------- 1 | .header{ 2 | width: 100%; 3 | height: 300rpx; 4 | font-size: 50rpx; 5 | background: url('https://charge.xmnewlife.com/images/newlife_master/index_charge_fund/img_home_bg.png') no-repeat; 6 | background-size: 100% 100%; 7 | color: #ffffff; 8 | .hd{ 9 | position: relative; 10 | padding: 30rpx; 11 | font-size: 34rpx; 12 | .lt{ 13 | float: left; 14 | } 15 | .rt{ 16 | float: right; 17 | position: relative; 18 | span{ 19 | margin-right: 30rpx; 20 | } 21 | .img_arrow_white{ 22 | width: 16rpx; 23 | height: 26rpx; 24 | position: absolute; 25 | top: 50%; 26 | right: 0; 27 | margin-top: -11rpx; 28 | } 29 | } 30 | } 31 | .bd{ 32 | text-align: center; 33 | font-size: 36rpx; 34 | margin-top: 50rpx; 35 | span{ 36 | display: inline-block; 37 | font-size: 90rpx; 38 | font-weight: 600; 39 | } 40 | } 41 | } 42 | .section{ 43 | position: relative; 44 | z-index: 99; 45 | top: -30rpx; 46 | .charge{ 47 | width: 690rpx; 48 | height: 220rpx; 49 | margin: 0 auto; 50 | background: url('https://charge.xmnewlife.com/images/newlife_master/index_charge_fund/img_bg2.png') no-repeat; 51 | background-size: 100% 100%; 52 | 53 | } 54 | .use{ 55 | width: 690rpx; 56 | height: 220rpx; 57 | margin: 20rpx auto 0; 58 | background: url('https://charge.xmnewlife.com/images/newlife_master/index_charge_fund/img_bg3.png') no-repeat; 59 | background-size: 100% 100%; 60 | } 61 | .hd{ 62 | padding: 30rpx 30rpx 4rpx; 63 | position: relative; 64 | .line{ 65 | width: 10rpx; 66 | height: 32rpx; 67 | display: inline-block; 68 | vertical-align: middle; 69 | border-radius: 10rpx; 70 | background: #14BF6D; 71 | -webkit-border-radius: 10rpx; 72 | -moz-border-radius: 10rpx; 73 | -ms-border-radius: 10rpx; 74 | -o-border-radius: 10rpx; 75 | margin-right: 20rpx; 76 | } 77 | .lt{ 78 | font-size: 34rpx; 79 | color: #333333; 80 | display: inline-block; 81 | vertical-align: middle; 82 | 83 | } 84 | .rt{ 85 | float: right; 86 | position: relative; 87 | color: #999999; 88 | font-size: 40rpx; 89 | span{ 90 | margin-right: 30rpx; 91 | } 92 | } 93 | .img_arrow{ 94 | width: 18rpx; 95 | height: 28rpx; 96 | position: absolute; 97 | top: 50%; 98 | right: 0; 99 | margin-top: -11rpx; 100 | } 101 | } 102 | .bd{ 103 | color: #999999; 104 | font-size: 36rpx; 105 | .lt{ 106 | margin-left: 50rpx; 107 | display: inline-block; 108 | vertical-align: middle; 109 | } 110 | .rt{ 111 | margin-left: 90rpx; 112 | display: inline-block; 113 | vertical-align: middle; 114 | } 115 | span{ 116 | color: #14BF6D; 117 | font-size: 60rpx; 118 | font-weight: bold; 119 | } 120 | } 121 | } 122 | 123 | .footer{ 124 | .hd{ 125 | padding: 10rpx 30rpx; 126 | .tip{ 127 | width: 50rpx; 128 | height: 50rpx; 129 | vertical-align: middle; 130 | } 131 | p{ 132 | color: #333333; 133 | font-size: 34rpx; 134 | display: inline-block; 135 | vertical-align: middle; 136 | margin-left: 16rpx; 137 | } 138 | } 139 | .bd{ 140 | padding: 30rpx; 141 | .cell{ 142 | padding: 20rpx 30rpx; 143 | background: #FAFAFA; 144 | border: 1rpx solid #D8D8D8; 145 | border-radius: 10rpx; 146 | -webkit-border-radius: 10rpx; 147 | -moz-border-radius: 10rpx; 148 | -ms-border-radius: 10rpx; 149 | -o-border-radius: 10rpx; 150 | display: flex; 151 | color: #333333; 152 | font-size: 30rpx; 153 | margin-bottom: 16rpx; 154 | .lt{ 155 | flex: 1; 156 | } 157 | .center{ 158 | flex: 1; 159 | text-align: center; 160 | } 161 | .rt{ 162 | flex: 1; 163 | color: #14BF6D; 164 | text-decoration: underline; 165 | text-align: right; 166 | } 167 | } 168 | } 169 | } -------------------------------------------------------------------------------- /static/assets/scss/home/moneyBills.scss: -------------------------------------------------------------------------------- 1 | .header{ 2 | width: 100%; 3 | height: 380rpx; 4 | background: url('https://charge.xmnewlife.com/images/newlife_master/index_charge_fund/img_money_bg.png') no-repeat; 5 | background-size: 100% 100%; 6 | position: relative; 7 | color: #ffffff; 8 | .withdrawal{ 9 | position: absolute; 10 | top: 12rpx; 11 | right: 30rpx; 12 | width: 164rpx; 13 | height: 56rpx; 14 | line-height: 56rpx; 15 | font-size: 30rpx; 16 | text-align: center; 17 | border: 1rpx solid #BAFFD3; 18 | border-radius: 28rpx; 19 | -webkit-border-radius: 28rpx; 20 | -moz-border-radius: 28rpx; 21 | -ms-border-radius: 28rpx; 22 | -o-border-radius: 28rpx; 23 | } 24 | .energy{ 25 | width: 300rpx; 26 | height: 150rpx; 27 | text-align: center; 28 | position: absolute; 29 | top: 0; 30 | bottom: 0; 31 | left: 0; 32 | right: 0; 33 | margin: 80rpx auto 0; 34 | .title{ 35 | font-size: 34rpx; 36 | } 37 | .context{ 38 | font-size: 90rpx; 39 | position: relative; 40 | top: -10rpx; 41 | } 42 | } 43 | .fd{ 44 | width: 100%; 45 | height: 118rpx; 46 | position: absolute; 47 | bottom: 0; 48 | left: 0; 49 | display: flex; 50 | text-align: center; 51 | .lt{ 52 | flex: 4; 53 | } 54 | .center{ 55 | position: relative; 56 | .line{ 57 | height: 70rpx; 58 | width: 1rpx; 59 | position: absolute; 60 | top: 0; 61 | left: 0; 62 | right: 0; 63 | bottom: 0; 64 | margin: 12rpx auto 0; 65 | background: #ffffff; 66 | } 67 | } 68 | .rt{ 69 | flex: 4; 70 | } 71 | p:first-child{ 72 | font-size: 28rpx; 73 | } 74 | p:last-child{ 75 | font-size: 40rpx; 76 | } 77 | } 78 | } 79 | .section{ 80 | .cell{ 81 | display: flex; 82 | font-size: 34rpx; 83 | position: relative; 84 | padding: 30rpx; 85 | background: #ffffff; 86 | .hd{ 87 | flex: 1; 88 | color: #333333; 89 | .icon{ 90 | width: 80rpx; 91 | height: 80rpx; 92 | display: inline-block; 93 | vertical-align: middle; 94 | margin-right: 24rpx; 95 | img{ 96 | width: 100%; 97 | height: 100%; 98 | } 99 | } 100 | .context{ 101 | display: inline-block; 102 | vertical-align: middle; 103 | .title{ 104 | font-size: 30rpx; 105 | color: #999999; 106 | } 107 | .subTitle{ 108 | font-size: 36rpx; 109 | color: #333333; 110 | } 111 | } 112 | } 113 | .fd{ 114 | flex: 1; 115 | text-align: right; 116 | .desc{ 117 | color: #333333; 118 | margin-top: 10rpx; 119 | } 120 | .time{ 121 | font-size: 24rpx; 122 | color: #666666; 123 | } 124 | } 125 | .lt{ 126 | flex: 4; 127 | color: #999999; 128 | } 129 | .rt{ 130 | flex: 6; 131 | text-align: right; 132 | color: #333333; 133 | } 134 | } 135 | .cell::after{ 136 | content: ""; 137 | width: 97%; 138 | position: absolute; 139 | right: 0; 140 | bottom: 0; 141 | border-bottom: 1rpx solid #E5E5E5; 142 | } 143 | .cell:last-child:after{ 144 | border-bottom: none; 145 | } 146 | } 147 | .child{ 148 | 149 | background: #f4f4f4; 150 | } -------------------------------------------------------------------------------- /static/assets/scss/home/withdrawalApply.scss: -------------------------------------------------------------------------------- 1 | .header{ 2 | padding: 30rpx; 3 | .content{ 4 | width: 690rpx; 5 | height: 160rpx; 6 | background: url('https://charge.xmnewlife.com/images/newlife_master/index_charge_fund/img_bg4.png') no-repeat; 7 | background-size: 100% 100%; 8 | position: relative; 9 | color: #ffffff; 10 | margin: 0 auto; 11 | .title{ 12 | padding: 24rpx 30rpx 0; 13 | } 14 | .desc{ 15 | padding: 0 30rpx; 16 | } 17 | } 18 | 19 | } 20 | .section{ 21 | padding: 30rpx; 22 | .cell{ 23 | border-bottom: 1rpx solid #E5E5E5; 24 | color: #333333; 25 | .title{ 26 | font-size: 34rpx; 27 | } 28 | .container{ 29 | input{ 30 | display: inline; 31 | } 32 | } 33 | } 34 | } 35 | .tip{ 36 | padding: 10rpx 0; 37 | font-size: 24rpx; 38 | color: #999999; 39 | } -------------------------------------------------------------------------------- /static/assets/scss/mine/mine.scss: -------------------------------------------------------------------------------- 1 | .child{ 2 | background: linear-gradient(to top,#75D672,#14BF6D); 3 | } 4 | .header{ 5 | padding: 30rpx; 6 | font-size: 38rpx; 7 | color: #ffffff; 8 | overflow: hidden; 9 | img{ 10 | position: relative; 11 | top: 5rpx; 12 | width: 36rpx; 13 | height: 36rpx; 14 | } 15 | } 16 | .section{ 17 | .box{ 18 | padding: 30rpx 36rpx; 19 | width: 646rpx; 20 | background: #ffffff; 21 | margin: 0 auto 24rpx; 22 | font-size: 32rpx; 23 | border-radius: 10rpx; 24 | -webkit-border-radius: 10rpx; 25 | -moz-border-radius: 10rpx; 26 | -ms-border-radius: 10rpx; 27 | -o-border-radius: 10rpx; 28 | .title{ 29 | color: #14BF6D; 30 | .line{ 31 | display: inline-block; 32 | width: 6rpx; 33 | height: 26rpx; 34 | background: #14BF6D; 35 | margin: 0 10rpx 0 0; 36 | border-radius: 3rpx; 37 | -webkit-border-radius: 3rpx; 38 | -moz-border-radius: 3rpx; 39 | -ms-border-radius: 3rpx; 40 | -o-border-radius: 3rpx; 41 | } 42 | } 43 | .subTitle{ 44 | color: #999999; 45 | margin: 16rpx 0 6rpx; 46 | } 47 | .content{ 48 | color: #333333; 49 | img{ 50 | margin-top: 4rpx; 51 | width: 360rpx; 52 | height: 250rpx; 53 | } 54 | } 55 | } 56 | .box:last-child{ 57 | margin-bottom: 60rpx; 58 | } 59 | } -------------------------------------------------------------------------------- /static/assets/scss/quality/quality.scss: -------------------------------------------------------------------------------- 1 | /* 2 | 资质认证 3 | */ 4 | .parent{ 5 | position: absolute; 6 | height:100%;//高度根据需求自行设定 7 | width: 100%; 8 | background: #ffffff; 9 | } 10 | .child{ 11 | position:absolute; 12 | left:0; 13 | top:0; 14 | right:0; 15 | bottom:0; //left,top,right,bottom都为0,充满真个页面 16 | overflow-y:auto !important; 17 | overflow-x:hidden !important; //设置Y轴出现滚动条,X轴隐藏 18 | -webkit-overflow-scrolling: touch; 19 | } 20 | /* 21 | 审核失败提示 22 | */ 23 | .header{ 24 | background: #FFE4E4; 25 | padding: 24rpx 30rpx; 26 | font-size: 32rpx; 27 | .failed{ 28 | width: 38rpx; 29 | height: 38rpx; 30 | } 31 | } 32 | .section{ 33 | padding: 30rpx; 34 | .cell{ 35 | border-bottom: 1rpx solid #D1D1D1; 36 | .title{ 37 | font-size: 32rpx; 38 | color: #333333; 39 | margin: 26rpx 0; 40 | } 41 | .subTitle{ 42 | font-size: 32rpx; 43 | color: #333333; 44 | margin: 26rpx 0; 45 | img{ 46 | width: 360rpx; 47 | height: 250rpx; 48 | } 49 | .arrow{ 50 | width: 14rpx; 51 | height: 26rpx; 52 | position: absolute; 53 | right: 50rpx; 54 | top: 50%; 55 | margin-top: -13rpx; 56 | } 57 | .in{ 58 | width: 49%; 59 | display: inline-block; 60 | } 61 | } 62 | } 63 | .cell:first-child{ 64 | .title{ 65 | margin: 0 0 26rpx; 66 | } 67 | } 68 | .desc{ 69 | font-size: 24rpx; 70 | color: #999999; 71 | margin-top: 10rpx; 72 | } 73 | } 74 | .footer{ 75 | margin-bottom: 80rpx; 76 | } 77 | .clear_broder{ 78 | border: none !important; 79 | } 80 | .relative{ 81 | position: relative; 82 | } 83 | .border_bottom{ 84 | border-bottom: 1rpx solid #D1D1D1; 85 | } -------------------------------------------------------------------------------- /static/assets/scss/quality/submit.scss: -------------------------------------------------------------------------------- 1 | .submit{ 2 | .banner{ 3 | width: 378rpx; 4 | height: 210rpx; 5 | margin: 82rpx auto 48rpx; 6 | img{ 7 | width: 100%; 8 | height: 100%; 9 | } 10 | } 11 | .title{ 12 | padding: 0 0 40rpx; 13 | font-size: 40rpx; 14 | color: #14BF6D; 15 | text-align: center; 16 | } 17 | .subTitle{ 18 | width: 517rpx; 19 | text-align: center; 20 | font-size: 30rpx; 21 | color: #B0B0B0; 22 | margin: 0 auto; 23 | .bright{ 24 | color: #FB910C; 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /static/assets/scss/style.scss: -------------------------------------------------------------------------------- 1 | .parent{ 2 | position: absolute; 3 | height:100%;//高度根据需求自行设定 4 | width: 100%; 5 | background: #ffffff; 6 | } 7 | .child{ 8 | position:absolute; 9 | left:0; 10 | top:0; 11 | right:0; 12 | bottom:0; //left,top,right,bottom都为0,充满真个页面 13 | overflow-y:auto !important; 14 | overflow-x:hidden !important; //设置Y轴出现滚动条,X轴隐藏 15 | -webkit-overflow-scrolling: touch; 16 | } -------------------------------------------------------------------------------- /static/img/LOGO.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/LOGO.png -------------------------------------------------------------------------------- /static/img/history_coupon/ic_expired.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/history_coupon/ic_expired.png -------------------------------------------------------------------------------- /static/img/history_coupon/img_1-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/history_coupon/img_1-2.png -------------------------------------------------------------------------------- /static/img/history_coupon/img_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/history_coupon/img_3.png -------------------------------------------------------------------------------- /static/img/history_coupon/img_coupon2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/history_coupon/img_coupon2.png -------------------------------------------------------------------------------- /static/img/index_charge_fund/ic_Settlement.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/index_charge_fund/ic_Settlement.png -------------------------------------------------------------------------------- /static/img/index_charge_fund/ic_arrow_gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/index_charge_fund/ic_arrow_gray.png -------------------------------------------------------------------------------- /static/img/index_charge_fund/ic_arrow_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/index_charge_fund/ic_arrow_white.png -------------------------------------------------------------------------------- /static/img/index_charge_fund/ic_car.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/index_charge_fund/ic_car.png -------------------------------------------------------------------------------- /static/img/index_charge_fund/ic_expenditure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/index_charge_fund/ic_expenditure.png -------------------------------------------------------------------------------- /static/img/index_charge_fund/ic_price.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/index_charge_fund/ic_price.png -------------------------------------------------------------------------------- /static/img/index_charge_fund/ic_price2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/index_charge_fund/ic_price2.png -------------------------------------------------------------------------------- /static/img/index_charge_fund/ic_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/index_charge_fund/ic_right.png -------------------------------------------------------------------------------- /static/img/index_charge_fund/img_bg2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/index_charge_fund/img_bg2.png -------------------------------------------------------------------------------- /static/img/index_charge_fund/img_bg3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/index_charge_fund/img_bg3.png -------------------------------------------------------------------------------- /static/img/index_charge_fund/img_bg4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/index_charge_fund/img_bg4.png -------------------------------------------------------------------------------- /static/img/index_charge_fund/img_electric_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/index_charge_fund/img_electric_bg.png -------------------------------------------------------------------------------- /static/img/index_charge_fund/img_home_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/index_charge_fund/img_home_bg.png -------------------------------------------------------------------------------- /static/img/index_charge_fund/img_money_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/index_charge_fund/img_money_bg.png -------------------------------------------------------------------------------- /static/img/index_charge_fund/img_question.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/index_charge_fund/img_question.png -------------------------------------------------------------------------------- /static/img/login/LOGO.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/login/LOGO.png -------------------------------------------------------------------------------- /static/img/login/ic_ipone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/login/ic_ipone.png -------------------------------------------------------------------------------- /static/img/login/ic_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/login/ic_right.png -------------------------------------------------------------------------------- /static/img/login/ic_verification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/login/ic_verification.png -------------------------------------------------------------------------------- /static/img/mine/ic_station.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/mine/ic_station.png -------------------------------------------------------------------------------- /static/img/mine/img_ID.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/mine/img_ID.png -------------------------------------------------------------------------------- /static/img/mine/img_license.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/mine/img_license.png -------------------------------------------------------------------------------- /static/img/price_set/empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/price_set/empty.png -------------------------------------------------------------------------------- /static/img/price_set/ic_add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/price_set/ic_add.png -------------------------------------------------------------------------------- /static/img/price_set/ic_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/price_set/ic_arrow.png -------------------------------------------------------------------------------- /static/img/price_set/ic_arrow2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/price_set/ic_arrow2.png -------------------------------------------------------------------------------- /static/img/price_set/ic_arrow_orange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/price_set/ic_arrow_orange.png -------------------------------------------------------------------------------- /static/img/price_set/ic_del.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/price_set/ic_del.png -------------------------------------------------------------------------------- /static/img/price_set/ic_delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/price_set/ic_delete.png -------------------------------------------------------------------------------- /static/img/price_set/img_car.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/price_set/img_car.png -------------------------------------------------------------------------------- /static/img/quality/ic_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/quality/ic_arrow.png -------------------------------------------------------------------------------- /static/img/quality/ic_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/quality/ic_right.png -------------------------------------------------------------------------------- /static/img/quality/ic_wrong.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/quality/ic_wrong.png -------------------------------------------------------------------------------- /static/img/quality/img_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/quality/img_1.png -------------------------------------------------------------------------------- /static/img/quality/img_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/quality/img_2.png -------------------------------------------------------------------------------- /static/img/tab/tab_electric_n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/tab/tab_electric_n.png -------------------------------------------------------------------------------- /static/img/tab/tab_electric_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/tab/tab_electric_s.png -------------------------------------------------------------------------------- /static/img/tab/tab_home_n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/tab/tab_home_n.png -------------------------------------------------------------------------------- /static/img/tab/tab_home_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/tab/tab_home_s.png -------------------------------------------------------------------------------- /static/img/tab/tab_me_n.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/tab/tab_me_n.png -------------------------------------------------------------------------------- /static/img/tab/tab_me_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fuckskyku/icharge-master/1c1521d6095dbec6ea02bda32976c5fe5815b02b/static/img/tab/tab_me_s.png --------------------------------------------------------------------------------