Commit 13f38dc8 by golton_gao

update: code init

parents
Showing with 4833 additions and 0 deletions
{
"presets": [
["env", {
"modules": false,
"targets": {
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}],
"stage-2"
],
"plugins": ["transform-runtime"],
"env": {
"test": {
"presets": ["env", "stage-2"],
"plugins": ["istanbul"]
}
}
}
// http://eslint.org/docs/user-guide/configuring
module.exports = {
root: true,
parser: 'babel-eslint',
parserOptions: {
sourceType: 'module'
},
env: {
browser: true,
},
// https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style
extends: 'standard',
// required to lint *.vue files
plugins: [
'html'
],
// add your custom rules here
'rules': {
// 关闭全等
'eqeqeq': [0],
'no-unused-vars': [2, {
// 允许声明未使用变量
'vars': 'local',
// 参数不检查
'args': 'none'
}],
// 关闭语句强制分号结尾
'semi': [0],
// 空行最多不能超过100行
'no-multiple-empty-lines': [0, { 'max': 100 }],
// 关闭禁止混用tab和空格
'no-mixed-spaces-and-tabs': [0],
// 关闭检测是否是驼峰写法
'camelcase': 0,
// 关闭禁用不必要的转义
'no-useless-escape': 0,
// 关闭禁用抛出异常字面量
'no-throw-literal': 0,
// 关闭禁止重新声明变量
'no-redeclare': 0,
// allow paren-less arrow functions
'arrow-parens': 0,
// allow async-await
'generator-star-spacing': 0,
// allow debugger during development
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
'indent': [2, 2, {
'SwitchCase': 1 // switch case 缩进2个空格
}]
}
}
\ No newline at end of file
.DS_Store
node_modules/
dist/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
// https://github.com/michael-ciniawsky/postcss-load-config
module.exports = {
"plugins": {
// to edit target browsers: use "browserlist" field in package.json
"autoprefixer": {}
}
}
{
"name": "交房模块",
"identifier": "com.jffc.vcd.module.deliveryhouse",
"build": 2,
"version": "1.0.1",
"releaseNote": "交房独立模块,添加显示加载菊花"
}
# vue-cordova-demo
> A VueCordova Project
## Build Setup
``` bash
# install dependencies
npm install
# serve with hot reload at localhost:8080
npm run dev
# build for production with minification
npm run build
# build for production and view the bundle analyzer report
npm run build --report
# build for production and view the bundle
npm run jffc-build
# check for cordova requirements
npm run jffc-check
# build for ios production with cordova
npm run jffc-ios
# build for android production with cordova
npm run jffc-android
# build for web production with cordova & serve with hot reload at localhost:3040
npm run jffc-browser
# build V+ H5 production
npm run jffc-vbuild
# add cordova platforms ios
npm run jffc-add-ios
# add cordova platforms android
npm run jffc-add-android
# add cordova platforms browser
npm run jffc-add-browser
# save for cordova plugins
npm run jffc-save
# add cordova plugin camera
npm run jffc-add-camera
# add cordova plugin console
npm run jffc-add-console
# add cordova plugin device
npm run jffc-add-device
# add cordova plugin sqlite-storage
npm run jffc-add-sqlite
# add cordova plugin file
npm run jffc-add-file
# add cordova plugin dialogs
npm run jffc-add-dialogs
# add cordova plugin splashscreen
npm run jffc-add-splashscreen
# add cordova plugin statusbar
npm run jffc-add-statusbar
```
For detailed explanation on how things work, checkout the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader).
require('./check-versions')()
process.env.NODE_ENV = 'production'
var ora = require('ora')
var rm = require('rimraf')
var path = require('path')
var chalk = require('chalk')
var webpack = require('webpack')
var config = require('../config')
var webpackConfig = require('./webpack.prod.conf')
// 设置package.json的name与version跟随config.xml里配置 @add by evanxu 2017-06-29
// 改变package版本号
var fs = require('fs')
var xml2js = require('xml2js')
var parser = new xml2js.Parser({explicitArray: false})
var versiony = require('versiony')
var xml = fs.readFileSync(process.cwd() + '/config.xml', {encoding: 'utf-8'}).toString()
parser.parseString(xml, (err, result) => {
if (err) throw err
versiony.version(result.widget.$.version).major().to('package.json')
})
console.log(chalk.yellow(
' Tip: built files are meant to be served over an HTTP server.\n' +
' Opening index.html over file:// won\'t work.\n'
))
var spinner = ora('building for production...')
spinner.start()
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
if (err) throw err
webpack(webpackConfig, function (err, stats) {
spinner.stop()
if (err) throw err
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false,
chunks: false,
chunkModules: false
}) + '\n\n')
if (stats.hasErrors()) {
console.log(chalk.red(' Build failed with errors.\n'))
process.exit(1)
}
console.log(chalk.cyan(' Build complete.\n'))
})
})
var chalk = require('chalk')
var semver = require('semver')
var packageConfig = require('../package.json')
var shell = require('shelljs')
function exec (cmd) {
return require('child_process').execSync(cmd).toString().trim()
}
var versionRequirements = [
{
name: 'node',
currentVersion: semver.clean(process.version),
versionRequirement: packageConfig.engines.node
},
]
if (shell.which('npm')) {
versionRequirements.push({
name: 'npm',
currentVersion: exec('npm --version'),
versionRequirement: packageConfig.engines.npm
})
}
module.exports = function () {
var warnings = []
for (var i = 0; i < versionRequirements.length; i++) {
var mod = versionRequirements[i]
if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
warnings.push(mod.name + ': ' +
chalk.red(mod.currentVersion) + ' should be ' +
chalk.green(mod.versionRequirement)
)
}
}
if (warnings.length) {
console.log('')
console.log(chalk.yellow('To use this template, you must update following to modules:'))
console.log()
for (var i = 0; i < warnings.length; i++) {
var warning = warnings[i]
console.log(' ' + warning)
}
console.log()
process.exit(1)
}
}
/* eslint-disable */
require('eventsource-polyfill')
var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')
hotClient.subscribe(function (event) {
if (event.action === 'reload') {
window.location.reload()
}
})
require('./check-versions')()
var config = require('../config')
if (!process.env.NODE_ENV) {
process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)
}
var opn = require('opn')
var path = require('path')
var express = require('express')
var webpack = require('webpack')
var proxyMiddleware = require('http-proxy-middleware')
var webpackConfig = require('./webpack.dev.conf')
// default port where dev server listens for incoming traffic
var port = process.env.PORT || config.dev.port
// automatically open browser, if not set will be false
var autoOpenBrowser = !!config.dev.autoOpenBrowser
// Define HTTP proxies to your custom API backend
// https://github.com/chimurai/http-proxy-middleware
var proxyTable = config.dev.proxyTable
var app = express()
var compiler = webpack(webpackConfig)
var devMiddleware = require('webpack-dev-middleware')(compiler, {
publicPath: webpackConfig.output.publicPath,
quiet: true
})
var hotMiddleware = require('webpack-hot-middleware')(compiler, {
log: () => {}
})
// force page reload when html-webpack-plugin template changes
compiler.plugin('compilation', function (compilation) {
compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
hotMiddleware.publish({ action: 'reload' })
cb()
})
})
// proxy api requests
Object.keys(proxyTable).forEach(function (context) {
var options = proxyTable[context]
if (typeof options === 'string') {
options = { target: options }
}
app.use(proxyMiddleware(options.filter || context, options))
})
// handle fallback for HTML5 history API
app.use(require('connect-history-api-fallback')())
// serve webpack bundle output
app.use(devMiddleware)
// enable hot-reload and state-preserving
// compilation error display
app.use(hotMiddleware)
// serve pure static assets
var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)
app.use(staticPath, express.static('./static'))
var uri = 'http://localhost:' + port
var _resolve
var readyPromise = new Promise(resolve => {
_resolve = resolve
})
console.log('> Starting dev server...')
devMiddleware.waitUntilValid(() => {
console.log('> Listening at ' + uri + '\n')
// when env is testing, don't need open it
if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') {
opn(uri)
}
_resolve()
})
var server = app.listen(port)
module.exports = {
ready: readyPromise,
close: () => {
server.close()
}
}
var path = require('path')
var config = require('../config')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
exports.assetsPath = function (_path) {
var assetsSubDirectory = process.env.NODE_ENV === 'production'
? config.build.assetsSubDirectory
: config.dev.assetsSubDirectory
return path.posix.join(assetsSubDirectory, _path)
}
exports.cssLoaders = function (options) {
options = options || {}
var cssLoader = {
loader: 'css-loader',
options: {
minimize: process.env.NODE_ENV === 'production',
sourceMap: options.sourceMap
}
}
// generate loader string to be used with extract text plugin
function generateLoaders (loader, loaderOptions) {
var loaders = [cssLoader]
if (loader) {
loaders.push({
loader: loader + '-loader',
options: Object.assign({}, loaderOptions, {
sourceMap: options.sourceMap
})
})
}
// Extract CSS when that option is specified
// (which is the case during production build)
if (options.extract) {
return ExtractTextPlugin.extract({
use: loaders,
fallback: 'vue-style-loader'
})
} else {
return ['vue-style-loader'].concat(loaders)
}
}
// https://vue-loader.vuejs.org/en/configurations/extract-css.html
return {
css: generateLoaders(),
postcss: generateLoaders(),
less: generateLoaders('less'),
sass: generateLoaders('sass', { indentedSyntax: true }),
scss: generateLoaders('sass'),
stylus: generateLoaders('stylus'),
styl: generateLoaders('stylus')
}
}
// Generate loaders for standalone style files (outside of .vue)
exports.styleLoaders = function (options) {
var output = []
var loaders = exports.cssLoaders(options)
for (var extension in loaders) {
var loader = loaders[extension]
output.push({
test: new RegExp('\\.' + extension + '$'),
use: loader
})
}
return output
}
require('./check-versions')()
process.env.NODE_ENV = 'production'
var ora = require('ora')
var rm = require('rimraf')
var path = require('path')
var chalk = require('chalk')
var webpack = require('webpack')
var config = require('../config')
var webpackConfig = require('./webpack.prov.conf')
// 设置package.json的name与version跟随config.xml里配置 @add by evanxu 2017-06-29
// 改变package版本号
var fs = require('fs')
var xml2js = require('xml2js')
var parser = new xml2js.Parser({explicitArray: false})
var versiony = require('versiony')
var xml = fs.readFileSync(process.cwd() + '/config.xml', {encoding: 'utf-8'}).toString()
parser.parseString(xml, (err, result) => {
if (err) throw err
versiony.version(result.widget.$.version).major().to('package.json')
})
console.log(chalk.yellow(
' Tip: built files are meant to be served over an HTTP server.\n' +
' Opening index.html over file:// won\'t work.\n'
))
var spinner = ora('building for V+Production...')
spinner.start()
rm(path.join(config.prov.assetsRoot, config.prov.assetsSubDirectory), err => {
if (err) throw err
webpack(webpackConfig, function (err, stats) {
spinner.stop()
if (err) throw err
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false,
chunks: false,
chunkModules: false
}) + '\n\n')
if (stats.hasErrors()) {
console.log(chalk.red(' V+Build failed with errors.\n'))
process.exit(1)
}
console.log(chalk.cyan(' V+Build complete.\n'))
})
})
var utils = require('./utils')
var config = require('../config')
var isProduction = process.env.NODE_ENV === 'production'
module.exports = {
loaders: utils.cssLoaders({
sourceMap: isProduction
? config.build.productionSourceMap
: config.dev.cssSourceMap,
extract: isProduction
})
}
var path = require('path')
var utils = require('./utils')
var config = require('../config')
var vueLoaderConfig = require('./vue-loader.conf')
const vuxLoader = require('vux-loader')
function resolve (dir) {
return path.join(__dirname, '..', dir)
}
const webpackConfig = {
entry: {
app: ['babel-polyfill', './src/main.js']
},
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src')
}
},
module: {
rules: [
{
test: /\.(js|vue)$/,
loader: 'eslint-loader',
enforce: 'pre',
include: [resolve('src'), resolve('test')],
options: {
formatter: require('eslint-friendly-formatter')
}
},
// {
// test: /\.less$/,
// loader: 'style-loader!css-loader!less-loader'
// },
{
test: /\.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig
},
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test')]
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
]
}
}
module.exports = vuxLoader.merge(webpackConfig, {
options: {},
plugins: [{
name: 'vux-ui'
}]
})
var utils = require('./utils')
var webpack = require('webpack')
var config = require('../config')
var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
// 设置package.json的name与version跟随config.xml里配置 @add by evanxu 2017-06-29
// 设置版本号、时间
var exdate = require('exdate')
var fs = require('fs')
var xml2js = require('xml2js')
var parser = new xml2js.Parser({explicitArray: false})
var xml = fs.readFileSync(process.cwd() + '/config.xml', {encoding: 'utf-8'}).toString()
var versions;
parser.parseString(xml, (err, result) => {
if (err) {
throw err
}
versions = result.widget.$.version
})
var ds = new Date()
var dates = exdate.format(ds, 'yyyy-MM-dd HH:mm')
// add hot-reload related code to entry chunks
Object.keys(baseWebpackConfig.entry).forEach(function (name) {
baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
})
module.exports = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })
},
// cheap-module-eval-source-map is faster for development
devtool: '#cheap-module-eval-source-map',
plugins: [
new webpack.DefinePlugin({
'process.env': config.dev.env,
'process.vers': JSON.stringify(versions),
'process.dates': JSON.stringify(dates)
}),
// https://github.com/glenjamin/webpack-hot-middleware#installation--usage
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
// https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true
}),
new FriendlyErrorsPlugin()
]
})
var path = require('path')
var utils = require('./utils')
var webpack = require('webpack')
var config = require('../config')
var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
var CopyWebpackPlugin = require('copy-webpack-plugin')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
// 设置package.json的name与version跟随config.xml里配置 @add by evanxu 2017-06-29
// 设置版本号、时间
var exdate = require('exdate')
var fs = require('fs')
var xml2js = require('xml2js')
var parser = new xml2js.Parser({explicitArray: false})
var xml = fs.readFileSync(process.cwd() + '/config.xml', {encoding: 'utf-8'}).toString()
var versions;
parser.parseString(xml, (err, result) => {
if (err) {
throw err
}
versions = result.widget.$.version
})
var ds = new Date()
var dates = exdate.format(ds, 'yyyy-MM-dd HH:mm')
var env = config.build.env
var webpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({
sourceMap: config.build.productionSourceMap,
extract: true
})
},
devtool: config.build.productionSourceMap ? '#source-map' : false,
output: {
path: config.build.assetsRoot,
filename: utils.assetsPath('js/[name].[chunkhash].js'),
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
},
plugins: [
// http://vuejs.github.io/vue-loader/en/workflow/production.html
new webpack.DefinePlugin({
'process.env': env,
'process.vers': JSON.stringify(versions),
'process.dates': JSON.stringify(dates)
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
sourceMap: true
}),
// extract css into its own file
new ExtractTextPlugin({
filename: utils.assetsPath('css/[name].[contenthash].css')
}),
// Compress extracted CSS. We are using this plugin so that possible
// duplicated CSS from different components can be deduped.
new OptimizeCSSPlugin({
cssProcessorOptions: {
safe: true
}
}),
// generate dist index.html with correct asset hash for caching.
// you can customize output by editing /index.html
// see https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: config.build.index,
template: 'index.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
},
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
chunksSortMode: 'dependency'
}),
// split vendor js into its own file
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: function (module, count) {
// any required modules inside node_modules are extracted to vendor
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, '../node_modules')
) === 0
)
}
}),
// extract webpack runtime and module manifest to its own file in order to
// prevent vendor hash from being updated whenever app bundle is updated
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
chunks: ['vendor']
}),
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.build.assetsSubDirectory,
ignore: ['.*']
}
])
]
})
if (config.build.productionGzip) {
var CompressionWebpackPlugin = require('compression-webpack-plugin')
webpackConfig.plugins.push(
new CompressionWebpackPlugin({
asset: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp(
'\\.(' +
config.build.productionGzipExtensions.join('|') +
')$'
),
threshold: 10240,
minRatio: 0.8
})
)
}
if (config.build.bundleAnalyzerReport) {
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}
module.exports = webpackConfig
var path = require('path')
var utils = require('./utils')
var webpack = require('webpack')
var config = require('../config')
var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
var CopyWebpackPlugin = require('copy-webpack-plugin')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var ZipPlugin = require('zip-webpack-plugin')
var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
// 设置版本号、时间
var exdate = require('exdate')
var fs = require('fs')
var xml2js = require('xml2js')
var parser = new xml2js.Parser({explicitArray: false})
var xml = fs.readFileSync(process.cwd() + '/config.xml', {encoding: 'utf-8'}).toString()
var versions;
parser.parseString(xml, (err, result) => {
if (err) {
throw err
}
versions = result.widget.$.version
})
var ds = new Date()
var dates = exdate.format(ds, 'yyyy-MM-dd HH:mm')
var env = config.prov.env
var webpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({
sourceMap: config.prov.productionSourceMap,
extract: true
})
},
devtool: config.prov.productionSourceMap ? '#source-map' : false,
output: {
path: config.prov.assetsRoot,
filename: utils.assetsPath('js/[name].[chunkhash].js'),
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
},
plugins: [
// http://vuejs.github.io/vue-loader/en/workflow/production.html
new webpack.DefinePlugin({
'process.env': env,
'process.vers': JSON.stringify(versions),
'process.dates': JSON.stringify(dates)
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
sourceMap: true
}),
// extract css into its own file
new ExtractTextPlugin({
filename: utils.assetsPath('css/[name].[contenthash].css')
}),
// Compress extracted CSS. We are using this plugin so that possible
// duplicated CSS from different components can be deduped.
new OptimizeCSSPlugin({
cssProcessorOptions: {
safe: true
}
}),
// generate dist index.html with correct asset hash for caching.
// you can customize output by editing /index.html
// see https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: config.prov.index,
template: 'index.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
},
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
chunksSortMode: 'dependency'
}),
// split vendor js into its own file
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: function (module, count) {
// any required modules inside node_modules are extracted to vendor
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, '../node_modules')
) === 0
)
}
}),
// extract webpack runtime and module manifest to its own file in order to
// prevent vendor hash from being updated whenever app bundle is updated
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
chunks: ['vendor']
}),
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.prov.assetsSubDirectory,
ignore: ['.*']
},
// 设置文件复制粘贴
{
from: path.resolve(path.join(__dirname, '../', config.prov.appConfFile)),
to: path.resolve(path.join(config.prov.assetsRoot, config.prov.appConfFile)),
toType: 'file',
force: true,
flatten: true
}
])
]
})
if (config.prov.productionGzip) {
var CompressionWebpackPlugin = require('compression-webpack-plugin')
webpackConfig.plugins.push(
new CompressionWebpackPlugin({
asset: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp(
'\\.(' +
config.prov.productionGzipExtensions.join('|') +
')$'
),
threshold: 10240,
minRatio: 0.8
})
)
}
// 设置压缩打包
if (config.prov.packToZip) {
webpackConfig.plugins.push(
new ZipPlugin({
path: config.prov.assetsRoot,
filename: 'vpackage.zip'
})
)
}
if (config.prov.bundleAnalyzerReport) {
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}
module.exports = webpackConfig
<?xml version='1.0' encoding='utf-8'?>
<widget id="com.jffc.vcd.module.deliveryhouse" version="1.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>DeliveryHouse</name>
<description>
建发交房模块
</description>
<author email="evanxuyi@gmail.com" href="http://cordova.io">
Core Team
</author>
<content src="index.html" />
<access origin="*" />
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<allow-intent href="tel:*" />
<allow-intent href="sms:*" />
<allow-intent href="mailto:*" />
<allow-intent href="geo:*" />
<platform name="android">
<allow-intent href="market:*" />
</platform>
<platform name="ios">
<allow-intent href="itms:*" />
<allow-intent href="itms-apps:*" />
<preference name="DisallowOverscroll" value="true" />
<preference name="BackupWebStorage" value="local" />
</platform>
<preference name="StatusBarBackgroundColor" value="#2c3e50" />
<preference name="StatusBarOverlaysWebView" value="false" />
<preference name="FadeSplashScreen" value="false" />
<preference name="SplashScreenDelay" value="1000" />
<preference name="ShowSplashScreenSpinner" value="false" />
<plugin name="cordova-plugin-whitelist" spec="1" />
<plugin name="cordova-plugin-camera" spec="~2.4.1" />
<plugin name="cordova-plugin-statusbar" spec="~2.2.3" />
<plugin name="cordova-plugin-splashscreen" spec="~4.0.3" />
<plugin name="cordova-plugin-dialogs" spec="~1.3.3" />
<plugin name="cordova-plugin-file" spec="~4.3.3" />
<plugin name="cordova-sqlite-storage" spec="~2.0.4" />
<plugin name="cordova-plugin-device" spec="~1.1.6" />
<plugin name="cordova-plugin-console" spec="~1.0.7" />
<engine name="browser" spec="^5.0.3" />
<engine name="ios" spec="^4.4.0" />
<engine name="android" spec="^6.2.3" />
</widget>
var merge = require('webpack-merge')
var prodEnv = require('./prod.env')
module.exports = merge(prodEnv, {
NODE_ENV: '"development"'
})
// see http://vuejs-templates.github.io/webpack for documentation.
var path = require('path')
module.exports = {
build: {
env: require('./prod.env'),
index: path.resolve(__dirname, '../www/index.html'),
assetsRoot: path.resolve(__dirname, '../www'),
assetsSubDirectory: 'static',
assetsPublicPath: '',
productionSourceMap: true,
// Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you.
// Before setting to `true`, make sure to:
// npm install --save-dev compression-webpack-plugin
productionGzip: false,
productionGzipExtensions: ['js', 'css'],
// Run the build command with an extra argument to
// View the bundle analyzer report after build finishes:
// `npm run build --report`
// Set to `true` or `false` to always turn it on or off
bundleAnalyzerReport: process.env.npm_config_report
},
dev: {
env: require('./dev.env'),
port: 8080,
autoOpenBrowser: true,
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {},
// CSS Sourcemaps off by default because relative paths are "buggy"
// with this option, according to the CSS-Loader README
// (https://github.com/webpack/css-loader#sourcemaps)
// In our experience, they generally work as expected,
// just be aware of this issue when enabling this option.
cssSourceMap: false
},
// 2017-11-21 新增集成V+ @evanxu
prov: {
env: require('./prov.env'),
index: path.resolve(__dirname, '../dist/index.html'),
assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: 'static',
assetsPublicPath: '',
productionSourceMap: false,
appConfFile: 'CubeModule.json',
eslint: true,
autoRoutes: true,
autoImportStyle: true,
friendlyErrorsPlugin: false,
packToZip: true,
// Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you.
// Before setting to `true`, make sure to:
// npm install --save-dev compression-webpack-plugin
productionGzip: false,
productionGzipExtensions: ['js', 'css'],
// Run the build command with an extra argument to
// View the bundle analyzer report after build finishes:
// `npm run build --report`
// Set to `true` or `false` to always turn it on or off
bundleAnalyzerReport: process.env.npm_config_report
/* 本地调试 */
// port: 3041,
// autoOpenBrowser: true,
// assetsSubDirectory: 'static',
// assetsPublicPath: '/',
// proxyTable: {},
// cssSourceMap: false
}
}
module.exports = {
NODE_ENV: '"production"'
}
var merge = require('webpack-merge')
var prodEnv = require('./prod.env')
module.exports = merge(prodEnv, {
NODE_ENV: '"provt"'
})
<!--
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
-->
# Cordova Hooks
Cordova Hooks represent special scripts which could be added by application and plugin developers or even by your own build system to customize cordova commands. See Hooks Guide for more details: http://cordova.apache.org/docs/en/edge/guide_appdev_hooks_index.md.html#Hooks%20Guide.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no,width=device-width">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="jf">
<meta name="apple-mobile-web-app-title" content="contact">
<meta name="format-detection" content="telephone=no,email=no,adress=no" />
<meta name="mobile-web-app-capable" content="jf">
<title>建发交房模块</title>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected 通过集成V+埋点 cordova.js 无需再自己添加 -->
</body>
</html>
This diff could not be displayed because it is too large.
{
"name": "delivery_house",
"version": "1.0.1",
"description": "建发交房模块",
"author": "Evan Xu <evanxuyi@gmail.com>, Weshine Chen <80368178@qq.com>",
"private": true,
"scripts": {
"dev": "node build/dev-server.js",
"start": "node build/dev-server.js",
"build": "node build/build.js",
"lint": "eslint --ext .js,.vue src",
"jffc-check": "cordova requirements",
"jffc-build": "node build/build.js",
"jffc-ios": "cordova build ios",
"jffc-android": "cordova build android",
"jffc-browser": "cordova prepare browser && cross-env PORT=3004 node build/dev-server.js",
"jffc-vbuild": "node build/vt-build.js",
"jffc-save": "cordova plugin save",
"jffc-add-ios": "cordova platforms add ios@4.4.0",
"jffc-add-android": "cordova platforms add android@6.2.3",
"jffc-add-browser": "cordova platforms add browser",
"jffc-add-camera": "cordova plugin add cordova-plugin-camera",
"jffc-add-console": "cordova plugin add cordova-plugin-console",
"jffc-add-device": "cordova plugin add cordova-plugin-device",
"jffc-add-sqlite": "cordova plugin add cordova-sqlite-storage",
"jffc-add-file": "cordova plugin add cordova-plugin-file",
"jffc-add-dialogs": "cordova plugin add cordova-plugin-dialogs",
"jffc-add-splashscreen": "cordova plugin add cordova-plugin-splashscreen",
"jffc-add-statusbar": "cordova plugin add cordova-plugin-statusbar"
},
"dependencies": {
"axios": "^0.16.2",
"babel-polyfill": "^6.23.0",
"cordova-android": "^6.2.3",
"cordova-browser": "^5.0.3",
"cordova-ios": "^4.4.0",
"cordova-plugin-camera": "~2.4.1",
"cordova-plugin-console": "~1.0.7",
"cordova-plugin-device": "~1.1.6",
"cordova-plugin-dialogs": "~1.3.3",
"cordova-plugin-file": "~4.3.3",
"cordova-plugin-splashscreen": "~4.0.3",
"cordova-plugin-statusbar": "~2.2.3",
"cordova-plugin-whitelist": "1",
"cordova-sqlite-storage": "~2.0.4",
"date-time-picker": "^0.5.2",
"echarts": "^4.1.0",
"exdate": "0.0.4",
"vue": "^2.3.3",
"vue-router": "^2.3.1",
"vuex": "^2.3.1",
"vux": "^2.9.2"
},
"devDependencies": {
"autoprefixer": "^6.7.2",
"babel-core": "^6.22.1",
"babel-eslint": "^7.1.1",
"babel-loader": "^6.2.10",
"babel-plugin-transform-runtime": "^6.22.0",
"babel-preset-env": "^1.3.2",
"babel-preset-stage-2": "^6.22.0",
"babel-register": "^6.22.0",
"chalk": "^1.1.3",
"connect-history-api-fallback": "^1.3.0",
"copy-webpack-plugin": "^4.0.1",
"cross-env": "^5.0.1",
"css-loader": "^0.28.0",
"eslint": "^3.19.0",
"eslint-config-standard": "^6.2.1",
"eslint-friendly-formatter": "^2.0.7",
"eslint-loader": "^1.7.1",
"eslint-plugin-html": "^2.0.0",
"eslint-plugin-promise": "^3.4.0",
"eslint-plugin-standard": "^2.0.1",
"eventsource-polyfill": "^0.9.6",
"express": "^4.14.1",
"extract-text-webpack-plugin": "^2.0.0",
"file-loader": "^0.11.1",
"friendly-errors-webpack-plugin": "^1.1.3",
"html-webpack-plugin": "^2.28.0",
"http-proxy-middleware": "^0.17.3",
"less": "^3.8.1",
"less-loader": "^4.1.0",
"mockjs": "^1.0.1-beta3",
"opn": "^4.0.2",
"optimize-css-assets-webpack-plugin": "^1.3.0",
"ora": "^1.2.0",
"rimraf": "^2.6.0",
"semver": "^5.3.0",
"shelljs": "^0.7.6",
"url-loader": "^0.5.8",
"versiony": "^2.0.1",
"vue-loader": "^12.1.0",
"vue-style-loader": "^3.0.1",
"vue-template-compiler": "^2.3.3",
"vux-loader": "^1.2.9",
"webpack": "^2.6.1",
"webpack-bundle-analyzer": "^2.2.1",
"webpack-dev-middleware": "^1.10.0",
"webpack-hot-middleware": "^2.18.0",
"webpack-merge": "^4.1.0",
"xml2js": "^0.4.19",
"zip-webpack-plugin": "^1.1.0"
},
"engines": {
"node": ">= 4.0.0",
"npm": ">= 3.0.0"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
],
"cordova": {
"platforms": [
"browser",
"ios",
"android"
],
"plugins": {
"cordova-plugin-camera": {
"CAMERA_USAGE_DESCRIPTION": " ",
"PHOTOLIBRARY_USAGE_DESCRIPTION": " "
},
"cordova-plugin-console": {},
"cordova-plugin-device": {},
"cordova-plugin-dialogs": {},
"cordova-plugin-splashscreen": {},
"cordova-plugin-statusbar": {},
"cordova-plugin-whitelist": {},
"cordova-plugin-file": {},
"cordova-sqlite-storage": {}
}
}
}
\ No newline at end of file
<template>
<div id="app">
<transition :name="this.$router.isBack ? 'page-out' : 'page-in'">
<router-view></router-view>
</transition>
</div>
</template>
<script>
export default {
name: 'app',
created () {
if (process.env.NODE_ENV === 'provt') {
// 兼容V+模块
console.log('当前环境:', process.env.NODE_ENV)
// todo:1、获取V+用户信息 this.$nativeApi.account.getUser()
// 2、根据用户信息,设置vuex,方便调用 this.$store.dispatch()
// 3、跳转至首页 this.$router.push('/') or 退出 this.$nativeApi.navigator.exit()
this.$nativeApi.system.statusBarColor([205, 61, 61])
this.$nativeApi.system.statusBarStyle([1])
this.$nativeApi.system.setBounces([0])
} else {
// APP模块(生产环境、开发环境)
console.log('当前环境:', process.env.NODE_ENV)
// todo:1、获取当前用户信息
// 2、根据用户信息,设置vuex,方便调用 this.$store.dispatch()
// 3、跳转至首页 this.$router.push('/') or 退出 this.$router.back()
}
}
}
</script>
<style scoped>
#app {
height: 100%;
}
</style>
.page-out-enter-active,
.page-out-leave-active,
.page-in-enter-active,
.page-in-leave-active {
will-change: transform;
transition: all 500ms;
height: 100%;
width: 100%;
top: 0;
position: absolute;
backface-visibility: visible;
perspective: 1000;
}
/* 页面退出动画效果 */
.page-out-enter {
opacity: 0;
transform: translate3d(-100%, 0, 0);
-webkit-transform: translate3d(-100%, 0, 0);
}
.page-out-enter-to {
opacity: 1;
}
.page-out-leave-active {
opacity: 0.5;
transform: translate3d(100%, 0, 0);
-webkit-transform: translate3d(100%, 0, 0);
}
/* 页面进入动画效果 */
.page-in-enter {
transform: translate3d(100%, 0, 0);
-webkit-transform: translate3d(100%, 0, 0);
}
.page-in-enter-to {
-webkit-transform: translateX(0);
transform: translateX(0);
}
.page-in-leave-active {
opacity: 0.5;
}
.list-out-enter-active,
.list-out-leave-active,
.list-in-enter-active,
.list-in-leave-active {
will-change: transform;
transition: all 300ms;
width: 100%;
backface-visibility: visible;
perspective: 1000;
}
/* 页面进入动画效果 */
.list-in-enter {
transform: translate3d(100%, 0, 0);
-webkit-transform: translate3d(100%, 0, 0);
}
.list-in-enter-to {
-webkit-transform: translateX(0);
transform: translateX(0);
}
.list-in-leave-active {
opacity: 0;
transform: translate3d(100%, 0, 0);
-webkit-transform: translate3d(100%, 0, 0);
}
/* 页面退出动画效果 */
.list-out-enter {
opacity: 1;
background-color: #0e1721;
}
.list-out-enter-to {
opacity: 1;
background-color: red;
transform: translate3d(100%, 0, 0);
-webkit-transform: translate3d(100%, 0, 0);
}
.list-out-leave-active {
background-color: blue;
opacity: 1;
}
.margin-left-normal {
margin-left: 0.2rem;
}
.padding-left-normal {
padding-left: 0.2rem;
}
.margin-bottom-normal {
margin-bottom: 0.2rem;
}
.margin-top-normal {
margin-top: 0.2rem;
}
.flexCenter {
align-items: center;
}
.flexStart {
align-items: flex-start;
}
.flexEnd {
align-items: flex-end;
}
.textLeft {
text-align: left;
}
.textRight {
text-align: right;
}
.textCenter {
text-align: center;
}
.flex-1 {
flex: 1;
}
.right-arrow {
background-image: url(../images/ic_arrow_left@2x.png);
background-repeat: no-repeat;
background-size: 100% 100%;
width: 0.4rem;
height: 0.4rem;
}
.riskWarn1 {
background-image: url(../images/ic_warn_1@2x.png);
background-repeat: no-repeat;
background-size: 100% 100%;
}
.riskWarn2 {
background-image: url(../images/ic_warn_2@2x.png);
background-repeat: no-repeat;
background-size: 100% 100%;
}
.infoIcon {
background-image: url(../images/ic_explain@2x.png);
background-repeat: no-repeat;
background-size: 100% 100%;
width: 0.4rem;
height: 0.4rem;
}
.alignLeft {
text-align: left;
}
.fontColor1 {
color: #6b6f7b;
}
.fontColor2 {
color: #333333;
}
.fontColor3 {
color: #cd0001;
}
.fontColor4 {
color: #0e1721;
}
.fontColor5 {
color: #cd3d3d;
}
.white {
background: white;
}
.bgColor1 {
background-color: #cd3d3d;
}
.bgColor2 {
background-color: white;
}
.bgColor3 {
background-color: #f9f9fb;
}
.bgColor4 {
background-color: #cd3d3d;
}
.font14 {
font-size: 14px;
}
.visibility {
visibility: visible;
}
.inVisibility {
display: none;
}
.hidden {
visibility: hidden;
}
.container {
height: 100%;
display: flex;
flex-direction: column;
}
/*
框架 全局 基础样式
** 可写在这 **
*/
* {
list-style: none;
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
*:not(input,textarea) {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
ul,
li,
div,
span,
em,
a,
i {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, form, fieldset, input, textarea, p, blockquote, th, td{margin:0;padding:0;}
fieldset, img, input, textarea{border:0;}
address, caption, cite, code, dfn, em, th, var{font-style:normal; font-weight:normal;}
ol, ul{list-style:none;}
h1, h2, h3, h4, h5, h6{font-size:100%; font-weight:normal;}
html,body{-webkit-user-select:none;-moz-user-select:none;user-select:none;height:100%;}
a:active,
a:hover {
text-decoration: underline;
}
a,img{-webkit-touch-callout:none}
img{ width: 100%; vertical-align:middle;}
ol,
ul {
margin: 0;
}
input {
outline: none;
border: 0;
}
button {
border: 0;
margin: 0;
padding: 0;
}
body {
font-size: 16px;
background: #f3f5f6;
-webkit-overflow-scrolling: touch;
}
a {
text-decoration: none;
}
a,button,input,textarea{
-webkit-tap-highlight-color: rgba(0,0,0,0);
outline:0;
}
.flex {
display: flex;
display: -webkit-flex;
}
/* 排列方法 row=从左到右,column=从上到下 */
/* wrap=换行排列 */
.flex-flow-r-w {
flex-flow: row wrap;
}
.flex-flow-c-n {
flex-flow: column nowrap;
}
.flex-flow-c-w {
flex-flow: column wrap;
}
.flex-in {
display: -webkit-flex;
display: inline-flex;
}
.flex-wrap {
flex-wrap: wrap;
}
.flex-wrap-r {
flex-wrap: wrap-reverse;
}
.flex-l {
align-items: flex-start;
}
.flex-l-l {
justify-content: flex-start;
}
.flex-c {
align-items: center;
}
.flex-c-c {
justify-content: center;
}
.flex-r {
align-items: flex-end;
}
.flex-r-r {
justify-content: flex-end;
}
.flex-item-gsb-1 {
flex: 1 1 auto;
}
.flex-item-gsb-0 {
flex: 0 0 auto;
}
/* 元素左对齐布局 */
.flex-self-l {
align-self: flex-start;
}
/* 元素中间齐布局 */
.flex-self-c {
align-self: center;
}
/* 元素右对齐布局 */
.flex-self-r {
align-self: flex-end;
}
/* 子元素换行布局 */
.flex-dir-column {
flex-direction: column;
}
.pl-li-del {
width: 0.4rem;
height: 0.4rem;
background: url(../images/ic_cancel_selected@2x.png) no-repeat center/80%;
}
/* 自适应 */
@media screen and (max-width: 10000px) {
html {
font-size: 100px;
}
}
@media screen and (max-width: 750px) {
html {
font-size: 100px;
}
}
@media screen and (max-width: 720px) {
html {
font-size: 96px;
}
}
@media screen and (max-width: 414px) {
html {
font-size: 55.2px;
}
}
@media screen and (max-width: 412px) {
html {
font-size: 54.933333px;
}
}
@media screen and (max-width: 384px) {
html {
font-size: 51.2px;
}
}
@media screen and (max-width: 375px) {
html {
font-size: 50px;
}
}
@media screen and (max-width: 360px) {
html {
font-size: 48px;
}
}
@media screen and (max-width: 320px) {
html {
font-size: 42.66667px;
}
}
import nativeApi from './cordova/index'
export default {
install (Vue, config) {
var nativeApiObj = nativeApi(config)
Vue.$nativeApi = nativeApiObj
Vue.prototype.$nativeApi = nativeApiObj
}
}
'use strict'
import NativeApi from '../native/nativeApi'
import { sleep } from '../native/utils'
/**
* 底座模块名称
* @type {{MIDEA_COMMON: string, MIDEA_USER: string, MIDEA_BARCODE: string, MIDEA_MAP: string, MIDEA_ANNTO: string, MIDEA_SALE: string}}
*/
const MODULE_NAMES = {
MIDEA_COMMON: 'MideaCommon',
MIDEA_USER: 'MideaUser',
MIDEA_BARCODE: 'MideaBarcode',
MIDEA_MAP: 'MideaMap',
MIDEA_ANNTO: 'MideaAnnto',
MIDEA_SALE: 'MideaSale'
}
/**
* Cordova Api父类,包含基本配置和基本入口方法
* @extends NativeApi
*/
export default class CordovaApi extends NativeApi {
constructor (conf) {
conf = conf || {}
conf.platform = 'cordova'
super(conf)
if (typeof window !== 'undefined' && typeof window.document !== 'undefined') {
var self = this
if (!window.document.getElementById('cordovaJS')) {
var script = window.document.createElement('script')
script.id = 'cordovaJS'
script.src = 'cordova.js'
script.type = 'text/javascript'
script.async = false
script.onload = function () {
console.log('Loading Cordova Plugin...')
window.document.addEventListener('deviceready', function () {
self.doReady(self)
}, false)
}
script.onerror = function () {
console.error('Cannot Load Cordova Plugin!')
}
window.document.body.appendChild(script)
}
}
}
set methods (methods) {
this._methods = methods
}
get methods () {
return this._methods
}
get moduleNames () {
return MODULE_NAMES
}
/**
* 调用cordova对象的exec方法
* @param module 所属模块
* @param method 方法名称
* @param params 附带参数
* @return {Promise}
*/
callApi (module, method, params) {
let self = this
self.log(module, method, params)
return new Promise((resolve, reject) => {
(async function () {
for (var i = 0; i < self.maxRetryTimes; i++) {
if (!self.ready || !window.cordova) {
if (i === self.maxRetryTimes - 1) {
reject('Cordova is not ready, no retry')
} else {
await sleep(self.retrySleepTime * (i + 1))
console.error('Cordova is not ready, retry later')
}
}
}
try {
window.cordova.exec(function (msg) {
resolve(msg)
}, function (msg) {
reject(msg)
}, module, method, params || [])
} catch (e) {
reject(e)
}
})()
})
}
}
import CordovaApi from './cordovaApi'
import System from './modules/system'
import GeoLocation from './modules/geoLocation'
import UserInteraction from './modules/userInteraction'
import Account from './modules/account'
import Navigator from './modules/navigator'
import DataInteraction from './modules/DataInteraction'
export default function (config) {
return new CordovaApi(config)
.setModules(
System,
GeoLocation,
UserInteraction,
Account,
Navigator,
DataInteraction
)
}
/** @module extend/common **/
import * as types from '../types'
import BaseModel from '../../native/BaseModel'
/**
* 用户账户
* @extends BaseModel
*/
export default class Account extends BaseModel {
static get moduleName () {
return types.MODULE_NAME_ACCOUNT
}
/**
* 获取当前应用登录的用户的信息
* @param {Array=} params 无参数
* @return {Promise}
* @result cn: 中文名, cookie: 用户的cookie, departmentName: 完整的部门名称, employeenumber: 员工号, gender: 性别(0 女, 1男), mail: 邮箱, mobile: 手机号码, ou: 组织架构的部门模块名, positionName: 岗位, sessionkey: 用户的sessionKey, ssoToken: 用户的ssoToken, telephonenumber: 固定电话, uid: 用户uid, uniqueIdentifier: 用户的唯一标识, userIcon: 用户头像
*/
getUser (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_USER, 'getUser', params)
}
/**
* 获取用户是否登录
* @param {Array=} params 无参数
* @return {Promise}
* @result {isLogin: 是否登录}
*/
isLogin (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_USER, 'isLogin', params)
}
/**
* 注销当前用户
* @param {Array=} params 无参数
* @return {Promise}
* @result #
*/
logout (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_USER, 'logout', params)
}
/**
* 验证密码当前用户的密码。优先验证二阶段密码,如手势、语音、人脸识别等。验证失败两次将退出当前打开的应用
* @param {Array=} params 无参数
* @return {Promise}
* @result 1:成功 0:失败
*/
authPassword (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_USER, 'authPassword', params)
}
/**
* 获取当前用户的密码
* @param {Array=} params 无参数
* @return {Promise}
* @result password 密码
*/
getUserPassword (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_USER, 'getUserPassword', params)
}
/**
* 跳转到页面
* @param {Array=} params 跳转到登录页面
* @return {Promise}
* @result #
*/
toLogin (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_USER, 'toLogin', params)
}
}
/** @module extend/common **/
import * as types from '../types'
import BaseModel from '../../native/BaseModel'
/**
* 原生与h5数据交互相关
* @extends BaseModel
*/
export default class DataInteraction extends BaseModel {
static get moduleName () {
return types.MODULE_NAME_DATA_INTERACTION
}
/**
* 获取H5信息
* @param {Array=} params ['key'] key为想要获得的参数
* @return {Promise}
* @result 参数key的值
*/
getH5Info (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_COMMON, 'getH5Info', params)
}
/**
* 保存H5信息
* @param {Array=} params ['key', 'value'] 保存参数的key,参数的值
* @return {Promise}
* @result #
*/
saveH5Info (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_COMMON, 'saveH5Info', params)
}
/**
* 获取模块或用户的未读消息(美信、美的通identifier)
* @param {Array=} params 第一次参数:应用模块名称(例如:com.midea.demo)或者用户id(xxx或者xxx@midea.com.cn),如果第一个参数传的是用户Id,则一定要传第二个参数;第二个参数固定为“IM”,如果传了第二个参数,则第一个参数必定是用户id,
* @return {Promise}
* @result 返回代表未读消息数目的int类型数据
*/
getMessageUnread (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_COMMON, 'getMessageUnread', params)
}
/**
* 获取扩展字段
* @param {Array=} params 模块名 com.midea.demo
* @return {Promise}
* @result 返回拓展字段,{extra: {action: 'xxx'}} 需要和底座商量决定action的值
*/
getExtra (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_COMMON, 'getExtra', params)
}
/**
* 获取设备信息
* @return {Promise}
* @result 返回相关设备信息的object类型数据
*/
getDeviceInfo (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_COMMON, 'getDeviceInfo', params)
}
}
/** @module extend/common **/
import * as types from '../types'
import BaseModel from '../../native/BaseModel'
/**
* 地图定位导航相关接口
* @extends BaseModel
*/
export default class GeoLocation extends BaseModel {
static get moduleName () {
return types.MODULE_NAME_GEO_LOCATION
}
/**
* 持续定位,每隔指定时间返回定位信息
* @param {Array=} params [间隔时间(ms)]
* @return {Promise}
* @result #
*/
startUpdatingLocation (params) {
return this.nativeApi.callApi('MideaMap', 'startUpdatingLocation', params)
}
/**
* 停止持续定位
* @param {Array=} params 无参数
* @return {Promise}
* @result #
*/
stopUpdatingLocation (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_MAP, 'stopUpdatingLocation', params)
}
/**
* 周边搜索
* @param {Array=} params 无参数
* @return {Promise}
* @result [{"citycode": 区号,"title": 标题,"poiId": "B02F50X8AR","address": 详细地址,"province": 省份,"longitude": 经度,"latitude": 维度,"city": 城市}]
*/
getPois (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_MAP, 'getPois', params)
}
/**
* 获取经纬度
* @param {Array=} params 无参数
* @return {Promise}
* @result {address: 详细地址city: 城市citycode: 区号district: 区latitude: 维度longitude: 经度province: 省份street: 街道}
*/
location (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_MAP, 'location', params)
}
/**
* 从目的地开始路线导航
* @param {Array=} params 无参数
* @return {Promise}
* @result #
*/
selectWidget (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_MAP, 'selectWidget', params)
}
/**
* 从目的地开始路线导航
* @param {Array=} params params ["113.2045723720553", "23.033276740700192", "112.84994614670291", "23.193689802924411", "广州2"]==>["终点的经度", "终点的纬度", "起始点的经度", "起始点的纬度", "要去的位置"]
* @return {Promise}
* @result #
*/
navToWithFrom (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_MAP, 'navToWithFrom', params)
}
}
/** @module extend/common **/
import * as types from '../types'
import BaseModel from '../../native/BaseModel'
/**
* 应用导航器
* @extends BaseModel
*/
export default class Navigator extends BaseModel {
static get moduleName () {
return types.MODULE_NAME_NAVIGATOR
}
/**
* 从当前页面跳转到设置页面
* @param {Array=} params 无参数
* @return {Promise}
* @result #
*/
showSetView (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_COMMON, 'showSetView', params)
}
/**
* 从当前页面跳转到我的页面
* @param {Array=} params 无参数
* @return {Promise}
* @result #
*/
showMyView (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_COMMON, 'showMyView', params)
}
/**
* 跳转到页面
* @param {Array=} params ['messageView'] 从当前页面跳转到消息页面(不支持美信),["messageListView", "com.midea.demo"] 跳转到消息List二级页面(美信、美的通)
* @return {Promise}
* @result #
*/
showAppView (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_COMMON, 'showAppView', params)
}
/**
* 启动指定App的指定应用
* @param {Array=} params ['包名', 'AppKey'] (demo) ['com.midea.maptest', '1779d8c8fd110fd5f7caf31652d82e8c']
* @return {Promise}
* @result #
*/
startApp (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_COMMON, 'startApp', params)
}
/**
* 跳转到个人信息页面(支持美信,新版美的通)
* @param {Array=} params ['用户ID'] 精确
* @return {Promise}
* @result #
*/
vcard (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_USER, 'vcard', params)
}
/**
* 跳转到指定应用
* @param {Array=} params ['widgetKey', params]
* @return {Promise}
* @result #
*/
showWidget (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_COMMON, 'showWidget', params)
}
/**
* 选择应用
* @param {Array=} params 无
* @return {Promise}
* @result #
*/
selectWidget (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_COMMON, 'selectWidget', params)
}
/**
* 退出应用
* @param {Array=} params 无
* @return {Promise}
* @result #
*/
exit (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_COMMON, 'exit', params)
}
/**
* 用系统浏览器打开网址
* @param {Array=} params ['网址']
* @return {Promise}
* @result #
*/
openSysBrowser (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_COMMON, 'openSysBrowser', params)
}
}
/** @module extend/common **/
import * as types from '../types'
import BaseModel from '../../native/BaseModel'
/**
* 系统通用接口
* @extends BaseModel
*/
export default class System extends BaseModel {
static get moduleName () {
return types.MODULE_NAME_SYSTEM
}
/**
* 跳转到手机通讯录系统页面,选择后返回json对象
* @param {Array=} params 无参数
* @return {Promise}
* @result {Object} {"name":"aaa","phone":"95079"}
*/
getContact (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_USER, 'getContact', params)
}
/**
* 获取手机当前系统语言
* @param {Array=} params 无参数
* @return {Promise}
* @result {String} language=cn
*/
language (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_COMMON, 'language', params)
}
/**
* 显示导航控件
* @param {Array=} params 无参数
* @return {Promise}
* @result #
*/
showNav (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_COMMON, 'showNav', params)
}
/**
* 隐藏导航控件
* @param {Array=} params 无参数
* @return {Promise}
* @result #
*/
hideNav (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_COMMON, 'hideNav', params)
}
/**
* 显示底部控件
* @param {Array=} params 无参数
* @return {Promise}
* @result #
*/
showMenu (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_COMMON, 'showMenu', params)
}
/**
* 弹出输入键盘
* @param {Array=} params 无参数
* @return {Promise}
* @result #
*/
showInput (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_COMMON, 'showInput', params)
}
/**
* 输入键盘消失
* @param {Array=} params 无参数
* @return {Promise}
* @result #
*/
hideInput (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_COMMON, 'hideInput', params)
}
/**
* 切换键盘到中午输入法
* @param {Array=} params 无参数
* @return {Promise}
* @result #
*/
toggleInput (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_COMMON, 'toggleInput', params)
}
/**
* 显示浮动按钮
* @param {Array=} params 无参数
* @return {Promise}
* @result #
*/
showFloat (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_COMMON, 'showFloat', params)
}
/**
* 隐藏浮动按钮
* @param {Array=} params 无参数
* @return {Promise}
* @result #
*/
hideFloat (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_COMMON, 'hideFloat', params)
}
/**
* 改变状态栏背景色
* @param {Array=} params [230, 130, 80, 1] [Red,Green,Blue,Alpha]
* @return {Promise}
* @result #
*/
statusBarColor (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_COMMON, 'statusBarColor', params)
}
/**
* 设置状态栏样式 1 为白色字体 0 为黑色字体
*/
statusBarStyle (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_COMMON, 'statusContentStyle', params)
}
/**
* 复制
* @param {Array=} params ["xxx"] 复制内容xxx到剪切板
* @return {Promise}
* @result #
*/
copy (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_COMMON, 'copy', params)
}
/**
* 粘贴结果
* @param {Array=} params 无参数
* @return {Promise}
* @result 返回字符串为剪切板(复制)的内容
*/
paste (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_COMMON, 'paste', params)
}
/**
* 检查是否安装指定apk请求参数
* @param {Array=} params 安装版名称 com.midea.mlearning.in.test
* @return {Promise}
* @result 若安装了则返回true,否则返回false
*/
apk (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_COMMON, 'apk', params)
}
/**
* 安卓和ios拨打电话
* @param {Array=} params [tel, '电话号码']
* @return {Promise}
* @result #
*/
callPhone (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_COMMON, 'callPhone', params)
}
/**
* 获取webview的宽度和高度
* @param {Array=} params 无
* @return {Promise}
* @result {webviewWidth: 宽, webviewHeigh: 高}
*/
webview (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_COMMON, 'webview', params)
}
/**
* 获取指定url图片的Base64编码数据
* @param {Array=} params ['url']
* @return {Promise}
* @result {base64: 图片数据}
*/
getBase64s (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_COMMON, 'getBase64s', params)
}
/**
* 弹出扫码框
* @param {Array=} params 无参数
* @return {Promise}
* @result 弹出扫码框,扫码并返回结果
*/
scan (params) {
return this.nativeApi.callApi('MideaBarcode', 'scan', params)
}
/**
* 统计的事件
* @param {Array=} params [{ 'key': 'event', 'value': '测试样例' }] key是统计事件的名称,value是事件的值
* @return {Promise}
* @result #
*/
onEvent (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_COMMON, 'onEvent', params)
}
setBounces (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_COMMON, 'setBounces', params)
}
}
/** @module extend/common **/
import * as types from '../types'
import BaseModel from '../../native/BaseModel'
/**
* 用户交互相关
* @extends BaseModel
*/
export default class UserInteraction extends BaseModel {
static get moduleName () {
return types.MODULE_NAME_USER_INTERACTION
}
/**
* 切换屏幕方向
* @param {Array=} params [0|1|2|3] 0-竖屏 1-横屏 2-开启自动旋转 3-关闭自动旋转
* @return {Promise}
* @result #
*/
orientation (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_COMMON, 'orientation', params)
}
/**
* 开启响应摇动手机,如果不调用停止响应摇动接口,会一直监听,直到调用停止接口或者kill手机进程
* @param {Array=} params 无
* @return {Promise}
* @result #
*/
shake (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_COMMON, 'shake', params)
}
/**
* 停止响应摇动手机
* @param {Array=} params 无
* @return {Promise}
* @result #
*/
shakeStop (params) {
return this.nativeApi.callApi(this.nativeApi.moduleNames.MIDEA_COMMON, 'shakeStop', params)
}
}
export const MODULE_NAME_NAVIGATOR = 'navigator'
export const MODULE_NAME_SYSTEM = 'system'
export const MODULE_NAME_USER_INTERACTION = 'userInteraction'
export const MODULE_NAME_DATA_INTERACTION = 'dataInteraction'
export const MODULE_NAME_ACCOUNT = 'account'
export const MODULE_NAME_GEO_LOCATION = 'geoLocation'
export function throwError (msg, name = '') {
const e = new Error()
e.message = msg
if (name) {
e.name = name
}
throw e
}
'use strict'
export default class BaseModel {
constructor (nativeApi) {
this.nativeApi = nativeApi
}
static get moduleName () {
return ''
}
get nativeApi () {
return this._nativeApi
}
set nativeApi (nativeApi) {
this._nativeApi = nativeApi
}
get config () {
return this.nativeApi.config
}
get debug () {
return this.nativeApi.debug
}
get platform () {
return this.nativeApi.platform
}
get ready () {
return this.nativeApi.ready
}
log () {
this.nativeApi.log()
}
debugLog () {
this.nativeApi.debugLog()
}
error () {
this.nativeApi.error()
}
info () {
this.nativeApi.info()
}
warn () {
this.nativeApi.warn()
}
}
'use strict'
import { printLog, singleInstance } from './utils'
import { throwError } from '../log'
let __instance = singleInstance()
export default class NativeApi {
constructor (conf) {
if (__instance()) return __instance()
this.config = conf
__instance(this)
}
get config () {
return this._config || {}
}
set config (conf) {
this._config = conf
}
get debug () {
return this.config.debug || false
}
get platform () {
return this.config.platform || 'native'
}
get maxRetryTimes () {
return typeof this.config.maxRetryTimes === 'number' ? this.config.maxRetryTimes : 5
}
get retrySleepTime () {
return typeof this.config.retrySleepTime === 'number' ? this.config.retrySleepTime : 100
}
get ready () {
return this.config.ready || false
}
set ready (isReady) {
this.config.ready = isReady
}
doReady (self) {
self.ready = true
}
setModule (Module, name = Module.moduleName || Module.name) {
// console.log('native api: ' + Module.toString())
// console.log(Module.moduleName)
// console.log(Module.name)
// console.log(name)
if (!name) {
const str = Module.toString()
const arr1 = str.match(/class\s+(.*?)\s+[\S\s]*\{/i)
const arr2 = str.match(/function\s+(.*?)\s*\(.*?\)[\S\s]*\{/i)
// console.log(str)
// console.log(arr1)
// console.log(arr2[1])
name = arr1 && arr1.length > 1
? arr1[1]
: (
arr2 && arr2.length > 1
? arr2[1]
: ''
)
}
name = name
? name.slice(0, 1).toLowerCase() + name.slice(1)
: ''
console.log(name)
if (!name || name.length <= 3) {
throwError('Cannot found Module Name: ' + name + '\n' + Module.toString(), 'MissedModule')
}
this.addModuleName(name)
this[name] = new Module(this)
return this
}
setModules () {
const len = arguments.length
const args = len > 0
? arguments
: []
for (let i = 0; i < len; i++) {
this.setModule(args[i])
}
return this
}
set moduleList (moduleList) {
this.config.moduleList = moduleList
}
get moduleList () {
return this.config.moduleList || []
}
addModuleName (name) {
let moduleList = this.moduleList
moduleList.push(name)
this.moduleList = moduleList
}
log () {
printLog(arguments, this.debug, 'log')
}
debugLog () {
printLog(arguments, this.debug, 'debug')
}
error () {
printLog(arguments, this.debug, 'error')
}
info () {
printLog(arguments, this.debug, 'info')
}
warn () {
printLog(arguments, this.debug, 'warn')
}
}
'use strict'
export async function sleep (timeout) {
return new Promise((resolve, reject) => {
setTimeout(function () {
resolve()
}, timeout)
})
}
export function singleInstance () {
let instance
return (newInstance) => {
if (newInstance) {
instance = newInstance
}
return instance
}
}
export function printLog (_arguments, debug = true, level = 'log') {
if (debug) {
let console = window.console || {}
let logFn = console[level] || console.log
let args = []
let length = _arguments.length
if (length > 0 && typeof _arguments[0] === 'number') {
args = _arguments
} else {
for (let i = 0; i < length; i++) {
args.push(_arguments[i])
if (i === 0 && length > 1) {
args.push('=>')
} else if (i < length - 1) {
args.push(',')
}
}
}
logFn.apply(console, args)
}
}
// 获取设备信息id
import VMT from '@/main'
/* global VMT,device:true */
const getDeviceid = () => {
return new Promise((resolve, reject) => {
if (process.env.NODE_ENV === 'provt') {
VMT.$nativeApi.dataInteraction.getDeviceInfo().then(data => {
// alert('data:' + JSON.stringify(data))
resolve(data.deviceId)
}).catch(err => {
// alert('err:' + JSON.stringify(err))
console.log(err)
const deviceid = 'DEVICEERR' + parseInt(Math.random() * 100)
reject(deviceid)
})
} else if (process.env.NODE_ENV === 'production') {
resolve(device.uuid)
} else {
const deviceid = 'DEVICETEST' + parseInt(Math.random() * 100)
reject(deviceid)
}
})
}
export default getDeviceid
// 弹窗方法api
const Alert = (title, func) => {
const titl = title
if (process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'provt') {
navigator.notification.alert(titl, func, '', '确定');
} else {
window.alert(titl)
func()
}
}
const Confirm = (title, func) => {
const tit = title
if (process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'provt') {
navigator.notification.confirm(tit, function (buttonIndex) {
if (buttonIndex == 1) {
func(true)
} else {
func(false)
}
}, '', ['确定', '取消'])
} else {
let res = window.confirm(tit)
if (res) {
func(true)
} else {
func(false)
}
}
}
export default {
Alert,
Confirm
}
/*
封装 定义 数据请求API
*/
let URL_API = {};
// API接口
let API = {
// 服务器host
Host: 'http://csm.cndrealty.com/csm/staticfactionReport',
TestHost: 'http://csmtest.cndrealty.com/csm/staticfactionReport',
// 2. 公共模块
// 2.1. 登录
// Login: 'app/loginNew',
// 2.2. 登出url
LogOut: 'loginout',
// --------------- 满意度接口 开始 ---------------
// 获取本月、集团累计以及去年标杆满意度数据
GroupSatisfaction: '/getGroupSatisfaction',
// 获取总体满意度排名数据
OverallSatisfaction: '/getOverAllSatisfaction',
// 获取集团均值、去年集团均值以及去年标杆
GroupSatisfactionAvg: '/getGroupSatisfactionAvg',
// 获取二级指标数据
TwoIndicators: '/getTwoIndicators',
// 获取交房情况数据
HouseSituation: '/getHouseSituation',
// 获取交房情况数据
RoomData: '/getRoomData',
// 获取项目交房信息
ProjectInfoToRoom: '/getProjectInfoToRoom',
// 获取项目风险预警信息
ProjectInfoToRisk: '/getProjectInfoRisk'
// --------------- 满意度接口 结束 ---------------
};
for (let key in API) {
if (API.hasOwnProperty(key)) {
const KEY = key.toUpperCase();
URL_API[KEY] = API[key];
}
}
export default URL_API;
/**
* [setStorage 设置本地存储,避免多次调用JSON.stringify方法,并对数据类型做了判断,避免字符串数据的多次转化]
* @param {[String]} key [key识别]
* @param {[Unknown]} data [存储的数据]
*/
export const setStorage = (key, data) => {
var toString = Object.prototype.toString
var notString = toString.call(data) !== '[object String]'
// console.log(data)
// estimate the type of data
if (notString) {
localStorage.setItem(key, JSON.stringify(data))
} else {
localStorage.setItem(key, data)
}
}
/**
* [getStorage 获取本地存储]
* @param {[String]} key [key识别]
* @return {[type]} [description]
*/
export const getStorage = (key) => {
var data = localStorage.getItem(key)
try {
return JSON.parse(data)
} catch (e) {
return data
}
}
/**
* [removeStorage]
* @param {[type]} key [description]
* @return {[type]} [description]
*/
export const removeStorage = (key) => {
key && localStorage.removeItem(key)
}
function Base64 () {
// private property
var _keyStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
// public method for encoding
this.encode = function (input) {
var output = '';
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = _utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
_keyStr.charAt(enc1) + _keyStr.charAt(enc2) +
_keyStr.charAt(enc3) + _keyStr.charAt(enc4);
}
return output;
}
// public method for decoding
this.decode = function (input) {
var output = '';
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, '');
while (i < input.length) {
enc1 = _keyStr.indexOf(input.charAt(i++));
enc2 = _keyStr.indexOf(input.charAt(i++));
enc3 = _keyStr.indexOf(input.charAt(i++));
enc4 = _keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = _utf8_decode(output);
return output;
}
// private method for UTF-8 encoding
var _utf8_encode = function (string) {
string = string.replace(/\r\n/g, '\n');
var utftext = '';
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
} else if ((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
} else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
}
// private method for UTF-8 decoding
var _utf8_decode = function (utftext) {
var string = '';
var i = 0;
var c = 0;
var c2 = 0;
while (i < utftext.length) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
} else if ((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i + 1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
} else {
c2 = utftext.charCodeAt(i + 1);
var c3 = utftext.charCodeAt(i + 2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
}
var b = new Base64()
export default b
/*
连接服务器数据接口,返回数据
*/
import APIPath from './APIPath'
import { postJson } from '../utils/http'
// --------------- 满意度接口 开始 ---------------
// 获取本月、集团累计、去年标杆满意度
export async function GroupSatisfaction (params) {
const { orgId, orgMonth } = params
let res = await postJson(APIPath.GROUPSATISFACTION, { orgId, orgMonth })
// console.log(res)
return checkCode(checkStatus(res))
}
// 获取总体满意度排名数据
export async function OverallSatisfaction (params) {
const { orgId, quotaCode, orgMonth } = params
let res = await postJson(APIPath.OVERALLSATISFACTION, { orgId, quotaCode, orgMonth })
// console.log(res)
return checkCode(checkStatus(res))
}
// 获取二级指标
export async function TwoIndicators (params) {
const { orgId, orgMonth } = params
let res = await postJson(APIPath.TWOINDICATORS, { orgId, orgMonth })
return checkCode(checkStatus(res))
}
// 获取集团均值、去年集团均值以及去年标杆
export async function GroupSatisfactionAvg (params) {
const { orgId, orgMonth } = params
let res = await postJson(APIPath.GROUPSATISFACTIONAVG, { orgId, orgMonth })
return checkCode(checkStatus(res))
}
// 获取交房情况数据
// projectId, batchNum 不传,默认查询集团,查询项目需要传值
export async function HouseSituation (params) {
const { projectId, batchNum, userId } = params
// console.log(params)
let res = await postJson(APIPath.HOUSESITUATION, { projectId, batchNum, userId })
return checkCode(checkStatus(res))
}
// 获取交房(已交房、未交房)数据
export async function RoomData (params) {
const { type } = params
let res = await postJson(APIPath.ROOMDATA, { type })
return checkCode(checkStatus(res))
}
// 获取项目交房信息
export async function ProjectInfoToRoom (params) {
const { projectId, batchNum, type } = params
let res = await postJson(APIPath.PROJECTINFOTOROOM, { projectId, batchNum, type })
return checkCode(checkStatus(res))
}
// 获取项目风险预警信息
export async function ProjectInfoToRisk (params) {
const { projectId, batchNum, orgId } = params
let res = await postJson(APIPath.PROJECTINFOTORISK, { projectId, batchNum, orgId })
return checkCode(checkStatus(res))
}
// --------------- 满意度接口 结束 ---------------
export const RESULT_OK = 0
// 处理来自网络或者服务器掉错误
function checkStatus (response) {
if (response.status === 200) {
return response.data
}
// 返回的数据格式跟接口文档规定的格式相同
return {
code: -404,
message: response.statusText,
data: response.statusText
}
}
// 处理来自接口响应成功返回的错误
function checkCode (data) {
return new Promise((resolve, reject) => {
if (data.code != RESULT_OK) {
reject(data.message)
} else {
resolve(data.data)
}
})
}
import * as Storage from './Storage'
import APIPath from './APIPath'
import * as Fetch from './request'
import DateTimePicker from 'date-time-picker'
/*
时间选择配置
*/
const dateOptions = (del) => {
if (del) {
const { defs, min } = del
return {
lang: 'zh-CN',
format: 'yyyy-MM-dd',
default: defs,
min
}
} else {
return {
lang: 'zh-CN',
format: 'yyyy-MM-dd'
}
}
}
const timeOptions = {
lang: 'EN',
format: 'HH:mm',
minuteStep: 5,
min: '00:00',
max: '23:59'
}
const dateConfig = {
day: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'],
shortDay: ['日', '一', '二', '三', '四', '五', '六'],
MDW: 'M月d日D',
YM: 'yyyy年M月',
OK: '确定',
CANCEL: '取消'
}
/*
参数过滤
*/
const paramFormat = (data) => {
return data.replace(/\//g, '~2F').replace(/\+/g, '~2B').replace(/=/g, '~3D')
}
export {
Storage,
APIPath,
Fetch,
DateTimePicker,
dateOptions,
timeOptions,
dateConfig,
paramFormat
}
/*
封装 定义 连接方法、返回数据格式
*/
// import qs from 'qs';
import axios from 'axios';
const fetchPath = (options) => {
let {
method,
data,
header,
url
} = options;
switch (method.toLowerCase()) {
case 'get':
return axios({
method,
url,
headers: { 'Authorization': header },
params: data
});
case 'post':
return axios({
method,
url,
headers: { 'Authorization': header },
data
})
default:
return axios(options);
}
};
/**
* Requests a URL, returning a promise.
*
* @param {string} url The URL we want to request
* @param {object} [options] The options we want to pass to "fetch"
* @return {object} An object containing either "data" or "err"
*/
export default function request (options) {
return fetchPath(options).then((response) => {
const { data } = response
const { status, msg } = data
return {
statusMsg: msg,
statusCode: status,
...data
};
}).catch((error) => {
const { message } = error
return {
statusMsg: message,
statusCode: -1000
};
});
}
<template>
<div class="base-page">
<title-bar :title="title" />
<loading ref="loading" :show="this.$store.state.showLoading" />
<div class="main">
<slot></slot>
</div>
</div>
</template>
<script>
import Loading from '@/components/Loading'
export default {
name: 'BasePage',
props: ['title'],
components: {
'loading': Loading
}
}
</script>
<style scoped>
.base-page {
display: flex;
flex-direction: column;
height: 100%;
background-color: rgb(245, 245, 247);
}
.title-bar {
position: fixed;
top: 0;
width: 100%;
z-index: 999;
}
.main {
margin-top: 1rem;
overflow: auto;
flex: 1;
display: flex;
flex-direction: column;
}
</style>
<template>
<div class="datetime"><span class="fontColor2">{{date}}</span></div>
</template>
<script>
export default {
name: 'DateTime',
props: ['date']
}
</script>
<style scoped>
.datetime {
background: white;
height: 0.9rem;
min-height: 0.9rem;
font-weight: bold;
font-size: 14px;
display: flex;
align-items: center;
padding-left: 0.2rem;
}
</style>
<template>
<div class="delivery-info">
<div v-transfer-dom>
<previewer ref="previewer" :list="previewerList" :options="options" @on-close="closePreview"></previewer>
</div>
<item-title title="交房情况">
<button v-show="type=='group'" @click="showPlay" class="bgColor1">年度交房计划</button>
</item-title>
<div class="houseTotalNum">
<span class="normal-font">项目住宅总户数</span>
<br />
<span class="totalNum">{{totalNum}}</span>
<div v-show="type=='project'">
<span class="normal-font">项目集中交付时间为</span>
<br />
<span class="normal-font">{{focusDate}}</span>
</div>
</div>
<div class="chart">
<div id="deliverychart" ref="deliverychart"></div>
<div class="legend">
<span class="square color1"></span>
<span class="normal-font col1">符合交房条件(户)</span>
<span class="normal-font col2">{{meetHandoverNum}}</span>
<span class="normal-font col3">{{meetHandoverRate}}</span>
</div>
<div class="legend">
<span class="square color2"></span>
<span class="normal-font col1">累计实际交付(户)</span>
<span class="normal-font col2">{{handoverNum}}</span>
<span class="normal-font col3">{{handoverRate}}</span>
</div>
<div class="legend">
<span class="square color3"></span>
<span class="normal-font col1">累计报修(户)</span>
<span class="normal-font col2">{{repairNum}}</span>
<span class="normal-font col3">{{repairRate}}</span>
</div>
</div>
</div>
</template>
<script>
/**
* 交房情况
*/
import ItemTitle from './ItemTitle'
import * as echarts from 'echarts'
import { Previewer, TransferDom } from 'vux'
import { mapGetters } from 'vuex'
export default {
name: 'DeliveryInfo',
directives: {
TransferDom
},
props: {
info: {
type: Object,
default: function () {
return {}
}
},
type: String,
focusDate: String
},
data () {
return {
options: {
maxSpreadZoom: 5, // 最大放大倍数
fullscreenEl: false, // 关闭全屏按钮
pinchToClose: false, // 缩放退出
closeOnScroll: false, // 滚动退出
closeOnVerticalDrag: false, // 垂直拖动退出
tapToClose: false, // 点击退出
tapToToggleControls: false, // 单击控制模式切换
escKey: false, // ESC按键退出
history: false // back按键退出
}
}
},
computed: {
...mapGetters('deliveryHouse', [
'showPreview'
]),
previewerList () {
return [
{
src: this.info.imgUrl
}
]
},
totalNum () {
return isNaN(this.info.totalNum) ? '' : Number(this.info.totalNum)
},
meetHandoverNum () {
return isNaN(this.info.meetHandoverNum) ? '' : Number(this.info.meetHandoverNum)
},
meetHandoverRate () {
return this.info.meetHandoverRate
},
handoverNum () {
return isNaN(this.info.handoverNum) ? '' : Number(this.info.handoverNum)
},
handoverRate () {
return this.info.handoverRate
},
repairNum () {
return isNaN(this.info.repairNum) ? '' : Number(this.info.repairNum)
},
repairRate () {
return this.info.repairRate
},
chartOpt () {
return {
backgroundColor: 'white',
angleAxis: {
max: this.totalNum,
axisLine: {
lineStyle: {
color: '#708ca6',
width: 1
}
},
axisTick: {
length: 4,
lineStyle: {
width: 0.5
}
},
splitLine: {
lineStyle: {
width: 0.5,
opacity: 0.5
}
}
},
radiusAxis: {
axisLabel: {
show: false
},
axisTick: {
show: false
},
axisLine: {
show: false
},
type: 'category',
data: ['累计报修', '累计实际交付', '符合交房条件'],
z: 10
},
polar: {
radius: '80%'
},
series: [
{
type: 'bar',
data: [this.repairNum, 0, 0],
silent: true,
coordinateSystem: 'polar',
stack: 'a',
name: '累计报修(户)',
color: ['#FD694B']
},
{
type: 'bar',
data: [0, this.handoverNum, 0],
silent: true,
coordinateSystem: 'polar',
stack: 'a',
name: '累计实际交付(户)',
color: ['#7179CA']
},
{
type: 'bar',
data: [0, 0, this.meetHandoverNum],
silent: true,
coordinateSystem: 'polar',
stack: 'a',
name: '符合交房条件(户)',
color: ['#4ECEFF']
}
],
color: ['#FD694B', '#7179CA', '#4ECEFF']
}
}
},
components: {
'item-title': ItemTitle,
'previewer': Previewer
},
watch: {
info: function (val, oldVal) {
this.updateChartData()
},
showPreview: function (val, oldVal) {
if (val) {
this.$refs.previewer.show(0)
} else if (this.$refs.previewer) {
this.$refs.previewer.close()
}
}
},
mounted () {
this.$echart = echarts.init(this.$refs.deliverychart)
this.$echart.setOption(this.chartOpt)
},
methods: {
updateChartData () {
this.$echart.setOption({
angleAxis: {
max: this.totalNum
},
series: [
{
type: 'bar',
data: [this.repairNum, 0, 0]
},
{
type: 'bar',
data: [0, this.handoverNum, 0]
},
{
type: 'bar',
data: [0, 0, this.meetHandoverNum]
}
]
})
},
showPlay () {
this.$store.commit('deliveryHouse/showPreview', true)
},
closePreview () {
this.$store.commit('deliveryHouse/showPreview', false)
}
}
}
</script>
<style scoped>
.delivery-info {
background: white;
padding-bottom: 0.3rem;
}
button {
height: 0.6rem;
padding-left: 0.15rem;
padding-right: 0.15rem;
border-radius: 5px;
color: white;
position: absolute;
right: 0.2rem;
top: 0.15rem;
}
.houseTotalNum {
border-bottom: 1px solid #ebeff3;
padding-top: 0.3rem;
padding-bottom: 0.3rem;
margin-left: 0.2rem;
margin-right: 0.2rem;
}
.normal-font {
font-size: 14px;
color: #6b6f7b;
}
.totalNum {
color: #0e1721;
font-weight: bold;
font-size: 28px;
}
.chart {
margin-top: 0.3rem;
background: white;
}
#deliverychart {
height: 4.2rem;
width: 100%;
margin-bottom: 0.3rem;
}
.legend {
display: flex;
justify-content: flex-start;
align-items: center;
padding-right: 0.2rem;
}
.square {
width: 0.2rem;
height: 0.2rem;
margin-left: 0.2rem;
margin-right: 0.2rem;
border-radius: 2px;
}
.color1 {
background: #4ECEFF;
}
.color2 {
background: #7179CA;
}
.color3 {
background: #FD694B;
}
.col1 {
flex: 1;
text-align: left;
}
.col2 {
width: 1.5rem;
text-align: left;
}
.col3 {
width: 1.5rem;
text-align: right;
}
</style>
<template>
<div class="delivery-list">
<ul>
<li class="table-header">
<span class="col1 padding-left-normal">组织/项目</span>
<span class="col2">交房集中期</span>
<span class="col3">天数</span>
<span class="col4">风险</span>
</li>
<li v-for="(it, index) in list" :key="index" class="table-body" @click="itemClick(it)">
<div class="col1 orgProject padding-left-normal">
<span class="orgName">{{it.orgName}}</span>
<span class="projectName">{{it.projectName}}</span>
</div>
<div class="col2 datezoom">
<span>{{startDate(it.focusDate)}}</span>
<span></span>
<span>{{endDate(it.focusDate)}}</span>
</div>
<span class="col3 dateNum">{{dayCount(it.dayCount)}}</span>
<span class="col4" @click.stop="alertInfo(it.lightRemark)">
<img class="risk" :src="getIcon(it.risk)" alt="">
</span>
</li>
</ul>
</div>
</template>
<script>
const riskWarn1 = require('../assets/images/ic_warn_1@2x.png')
const riskWarn2 = require('../assets/images/ic_warn_2@2x.png')
const riskWarn3 = require('../assets/images/ic_warn_3@2x.png')
/**
* 交房、未交房列表
*/
export default {
name: 'DeliveryList',
props: {
list: {
type: Array
}
},
data () {
return {
riskWarn1Icon: riskWarn1,
riskWarn2Icon: riskWarn2,
riskWarn3Icon: riskWarn3
}
},
methods: {
getIcon (risk) {
switch (risk) {
case '1':
return this.riskWarn2Icon
case '2':
return this.riskWarn3Icon
default:
return this.riskWarn1Icon
}
},
alertInfo (info) {
this.$dialog.Alert(info || '暂无', function () {})
},
itemClick (item) {
this.$emit('itemClick', item)
},
dayCount (dayCount) {
return isNaN(dayCount) ? '' : Number(dayCount)
},
startDate (focusDate) {
let dateArr = focusDate.split('-')
if (dateArr.length >= 3) {
return `${dateArr[0]}.${dateArr[1]}.${dateArr[2]}`
} else {
return '-'
}
},
endDate (focusDate) {
let dateArr = focusDate.split('-')
if (dateArr.length >= 6) {
return `${dateArr[3]}.${dateArr[4]}.${dateArr[5]}`
} else {
return '-'
}
}
}
}
</script>
<style scoped>
.delivery-list {
background: white;
}
ul {
margin: auto 0.2rem;
}
.table-header {
display: flex;
border-bottom: #f0f0f2 solid 1px;
height: 0.9rem;
align-items: center;
}
.table-header span {
font-size: 14px;
color: #333333;
font-weight: bold;
}
.col1 {
flex: 1;
}
.col2 {
width: 2rem;
}
.col3, .col4 {
width: 1rem;
}
.table-header span:first-child {
text-align: left;
}
.table-body {
display: flex;
color: #6B6F7B;
align-items: center;
height: 1rem;
}
.table-body:nth-child(odd) {
background: #F9F9FB;
}
.orgProject {
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-start;
}
.orgName, .dateNum {
font-size: 13px;
font-weight: bold;
color: #6B6F7B;
}
.projectName {
font-size: 11px;
color: #6B6F7B;
}
.datezoom {
display: flex;
flex-direction: column;
align-items: center;
}
.datezoom span {
font-size: 10px;
color: #6B6F7B;
}
.risk {
width: 0.4rem;
height: 0.41rem;
align-self: center;
}
</style>
<template>
<div class="room-num">
<item-title title="交房数量"></item-title>
<div class="roomNumInfo">
<span>本次预计交房数</span>
<span class="roomNum">{{countNum}}</span>
</div>
<ul>
<li v-for="(it, index) in list" :key="index"><span>{{it.buildingName}}</span></li>
</ul>
</div>
</template>
<script>
/**
* 交房数量
*/
import { mapGetters } from 'vuex'
import ItemTitle from './ItemTitle'
export default {
name: 'DeliveryRoomNum',
components: {
'item-title': ItemTitle
},
data () {
return {
}
},
computed: {
...mapGetters('deliveryHouse', [
'projectRoomInfo'
]),
countNum () {
return this.projectRoomInfo ? this.projectRoomInfo.countNum : ''
},
list () {
return this.projectRoomInfo ? this.projectRoomInfo.list : []
}
}
}
</script>
<style scoped>
.room-num {
background: white;
}
.roomNumInfo {
display: flex;
justify-content: space-between;
margin-left: 0.2rem;
margin-right: 0.2rem;
height: 0.9rem;
border-bottom: 1px solid #ebeff3;
align-items: center;
}
.roomNumInfo span:first-child {
color: #333333;
font-size: 15px;
}
.roomNum {
color: #cd0001;
font-size: 16px;
}
ul {
border-top: 1px solid #F6F8FA;
margin-left: 0.2rem;
margin-right: 0.2rem;
flex: 1;
overflow: auto;
}
li {
display: flex;
justify-content: space-between;
align-items: center;
}
li span {
font-size: 14px;
color: #6b6f7b;
height: 0.9rem;
line-height: 0.9rem;
}
</style>
<template>
<div class="item-title">
<span class="indicate"> </span>
<span class="title">{{title}}</span>
<slot></slot>
</div>
</template>
<script>
export default {
name: 'ItemTitle',
props: ['title']
}
</script>
<style scoped>
.item-title {
position: relative;
display: flex;
border-bottom: 1px solid #ebeff3;
align-items: center;
height: 0.9rem;
}
.indicate {
background: #cd3d3d;
width: 4px;
height: 18px;
margin-left: 0.2rem;
margin-right: 0.1rem;
}
.title {
color: #333333;
font-weight: bold;
font-size: 16px;
height: 16px;
line-height: 16px;
align-self: center;
}
</style>
<template>
<transition :name="transition">
<div
class="weui-loading_toast vux-loading"
:class="!text ? 'vux-loading-no-text' : ''"
v-show="show">
<div class="weui-mask_transparent"></div>
<div
class="weui-toast"
:style="{
position: position
}">
<i class="weui-loading weui-icon_toast"></i>
<p class="weui-toast__content" v-if="text">{{ text || 'loading' }}</p>
</div>
</div>
</transition>
</template>
<script>
// 根据vux loading组件修改
export default {
name: 'loading',
model: {
prop: 'show',
event: 'change'
},
props: {
show: {
type: Boolean,
default: true
},
text: {
type: String,
default: '加载中...'
},
position: {
type: String,
default: 'fixed'
},
transition: {
type: String,
default: 'vux-mask'
}
},
watch: {
show (val) {
this.$emit('update:show', val)
}
}
}
</script>
<style scoped>
.loading {
position: fixed;
width: 30vw;
height: 30vw;
z-index: 9999;
background: rgba(0, 0, 0, 0.7);
display: flex;
flex-direction: column;
vertical-align: middle;
text-align: center;
}
.weui-toast {
position: fixed;
width: 7.6em;
min-height: 7.6em;
top: calc(50% - 7.6em / 2.0);
left: 50%;
margin-left: -3.8em;
background: rgba(17,17,17,0.7);
text-align: center;
border-radius: 5px;
color: #FFFFFF;
}
.weui-toast__content {
margin: 0 0 15px;
color: #FFFFFF;
}
.vux-loading .weui-toast {
z-index: 999;
}
.weui-icon_toast.weui-loading {
margin: 30px 0 0;
width: 38px;
height: 38px;
vertical-align: baseline;
display: inline-block;
}
.vux-mask-enter, .vux-mask-leave-active,
.vux-mask-leave-active, .vux-mask-enter-active {
position: relative;
z-index: 1;
}
.vux-mask-enter, .vux-mask-leave-active {
opacity: 0;
}
.vux-mask-leave-active, .vux-mask-enter-active {
transition: opacity 300ms;
}
.vux-loading-no-text .weui-toast {
min-height: 98px;
}
.weui-mask {
position: fixed;
z-index: 1000;
top: 0;
right: 0;
left: 0;
bottom: 0;
background: rgba(0, 0, 0, .6);
}
/** 透明遮罩层 预留顶部标题栏高度,阻止页面上下滚动 */
.weui-mask_transparent{
position: fixed;
z-index: 1000;
top: 1rem;
right: 0;
left: 0;
bottom: 0;
}
.weui-loading {
width: 20px;
height: 20px;
display: inline-block;
vertical-align: middle;
animation: weuiLoading 1s steps(12, end) infinite;
background: transparent url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAiIGhlaWdodD0iMTIwIiB2aWV3Qm94PSIwIDAgMTAwIDEwMCI+PHBhdGggZmlsbD0ibm9uZSIgZD0iTTAgMGgxMDB2MTAwSDB6Ii8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjRTlFOUU5IiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAgLTMwKSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iIzk4OTY5NyIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgzMCAxMDUuOTggNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjOUI5OTlBIiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKDYwIDc1Ljk4IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0EzQTFBMiIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSg5MCA2NSA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNBQkE5QUEiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoMTIwIDU4LjY2IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0IyQjJCMiIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgxNTAgNTQuMDIgNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjQkFCOEI5IiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKDE4MCA1MCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNDMkMwQzEiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTE1MCA0NS45OCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNDQkNCQ0IiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTEyMCA0MS4zNCA2NSkiLz48cmVjdCB3aWR0aD0iNyIgaGVpZ2h0PSIyMCIgeD0iNDYuNSIgeT0iNDAiIGZpbGw9IiNEMkQyRDIiIHJ4PSI1IiByeT0iNSIgdHJhbnNmb3JtPSJyb3RhdGUoLTkwIDM1IDY1KSIvPjxyZWN0IHdpZHRoPSI3IiBoZWlnaHQ9IjIwIiB4PSI0Ni41IiB5PSI0MCIgZmlsbD0iI0RBREFEQSIgcng9IjUiIHJ5PSI1IiB0cmFuc2Zvcm09InJvdGF0ZSgtNjAgMjQuMDIgNjUpIi8+PHJlY3Qgd2lkdGg9IjciIGhlaWdodD0iMjAiIHg9IjQ2LjUiIHk9IjQwIiBmaWxsPSIjRTJFMkUyIiByeD0iNSIgcnk9IjUiIHRyYW5zZm9ybT0icm90YXRlKC0zMCAtNS45OCA2NSkiLz48L3N2Zz4=") no-repeat;
background-size: 100%;
}
.weui-loading.weui-loading_transparent{
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxMjAnIGhlaWdodD0nMTIwJyB2aWV3Qm94PScwIDAgMTAwIDEwMCc+PHBhdGggZmlsbD0nbm9uZScgZD0nTTAgMGgxMDB2MTAwSDB6Jy8+PHJlY3QgeG1sbnM9J2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJyB3aWR0aD0nNycgaGVpZ2h0PScyMCcgeD0nNDYuNScgeT0nNDAnIGZpbGw9J3JnYmEoMjU1LDI1NSwyNTUsLjU2KScgcng9JzUnIHJ5PSc1JyB0cmFuc2Zvcm09J3RyYW5zbGF0ZSgwIC0zMCknLz48cmVjdCB3aWR0aD0nNycgaGVpZ2h0PScyMCcgeD0nNDYuNScgeT0nNDAnIGZpbGw9J3JnYmEoMjU1LDI1NSwyNTUsLjUpJyByeD0nNScgcnk9JzUnIHRyYW5zZm9ybT0ncm90YXRlKDMwIDEwNS45OCA2NSknLz48cmVjdCB3aWR0aD0nNycgaGVpZ2h0PScyMCcgeD0nNDYuNScgeT0nNDAnIGZpbGw9J3JnYmEoMjU1LDI1NSwyNTUsLjQzKScgcng9JzUnIHJ5PSc1JyB0cmFuc2Zvcm09J3JvdGF0ZSg2MCA3NS45OCA2NSknLz48cmVjdCB3aWR0aD0nNycgaGVpZ2h0PScyMCcgeD0nNDYuNScgeT0nNDAnIGZpbGw9J3JnYmEoMjU1LDI1NSwyNTUsLjM4KScgcng9JzUnIHJ5PSc1JyB0cmFuc2Zvcm09J3JvdGF0ZSg5MCA2NSA2NSknLz48cmVjdCB3aWR0aD0nNycgaGVpZ2h0PScyMCcgeD0nNDYuNScgeT0nNDAnIGZpbGw9J3JnYmEoMjU1LDI1NSwyNTUsLjMyKScgcng9JzUnIHJ5PSc1JyB0cmFuc2Zvcm09J3JvdGF0ZSgxMjAgNTguNjYgNjUpJy8+PHJlY3Qgd2lkdGg9JzcnIGhlaWdodD0nMjAnIHg9JzQ2LjUnIHk9JzQwJyBmaWxsPSdyZ2JhKDI1NSwyNTUsMjU1LC4yOCknIHJ4PSc1JyByeT0nNScgdHJhbnNmb3JtPSdyb3RhdGUoMTUwIDU0LjAyIDY1KScvPjxyZWN0IHdpZHRoPSc3JyBoZWlnaHQ9JzIwJyB4PSc0Ni41JyB5PSc0MCcgZmlsbD0ncmdiYSgyNTUsMjU1LDI1NSwuMjUpJyByeD0nNScgcnk9JzUnIHRyYW5zZm9ybT0ncm90YXRlKDE4MCA1MCA2NSknLz48cmVjdCB3aWR0aD0nNycgaGVpZ2h0PScyMCcgeD0nNDYuNScgeT0nNDAnIGZpbGw9J3JnYmEoMjU1LDI1NSwyNTUsLjIpJyByeD0nNScgcnk9JzUnIHRyYW5zZm9ybT0ncm90YXRlKC0xNTAgNDUuOTggNjUpJy8+PHJlY3Qgd2lkdGg9JzcnIGhlaWdodD0nMjAnIHg9JzQ2LjUnIHk9JzQwJyBmaWxsPSdyZ2JhKDI1NSwyNTUsMjU1LC4xNyknIHJ4PSc1JyByeT0nNScgdHJhbnNmb3JtPSdyb3RhdGUoLTEyMCA0MS4zNCA2NSknLz48cmVjdCB3aWR0aD0nNycgaGVpZ2h0PScyMCcgeD0nNDYuNScgeT0nNDAnIGZpbGw9J3JnYmEoMjU1LDI1NSwyNTUsLjE0KScgcng9JzUnIHJ5PSc1JyB0cmFuc2Zvcm09J3JvdGF0ZSgtOTAgMzUgNjUpJy8+PHJlY3Qgd2lkdGg9JzcnIGhlaWdodD0nMjAnIHg9JzQ2LjUnIHk9JzQwJyBmaWxsPSdyZ2JhKDI1NSwyNTUsMjU1LC4xKScgcng9JzUnIHJ5PSc1JyB0cmFuc2Zvcm09J3JvdGF0ZSgtNjAgMjQuMDIgNjUpJy8+PHJlY3Qgd2lkdGg9JzcnIGhlaWdodD0nMjAnIHg9JzQ2LjUnIHk9JzQwJyBmaWxsPSdyZ2JhKDI1NSwyNTUsMjU1LC4wMyknIHJ4PSc1JyByeT0nNScgdHJhbnNmb3JtPSdyb3RhdGUoLTMwIC01Ljk4IDY1KScvPjwvc3ZnPgo=");
}
@-webkit-keyframes weuiLoading {
0% {
transform: rotate3d(0, 0, 1, 0deg);
}
100% {
transform: rotate3d(0, 0, 1, 360deg);
}
}
@keyframes weuiLoading {
0% {
transform: rotate3d(0, 0, 1, 0deg);
}
100% {
transform: rotate3d(0, 0, 1, 360deg);
}
}
</style>
<template>
<div class="risk-warning">
<item-title title="风险预警" >
<img class="risk" :src="riskWarnIcon" alt="" @click="alertInfo('risk')">
</item-title>
<ul>
<li>
<span class="label">交付评估得分</span>
<div class="flex flexCenter">
<span class="value">{{this.formatResult(compositeScore)}}</span>
<span class="toAlertIcon" @click="alertInfo('composite')"><img :src="alertIcon" alt=""></span>
</div>
</li>
<li><span class="label">满意度累计得分</span><span class="value">{{satisfactionScore}}</span></li>
<li><span class="label">集中整改率</span><span class="value">{{rectificationRate}}</span></li>
<li><span class="label">备注</span><span class="toAlertIcon"><img :src="alertIcon" alt="" @click="alertInfo('remark')"></span></li>
</ul>
</div>
</template>
<script>
/**
* 风险预警
*/
import { mapGetters } from 'vuex'
import ItemTitle from './ItemTitle'
const riskWarn1 = require('../assets/images/ic_warn_1@2x.png')
const riskWarn2 = require('../assets/images/ic_warn_2@2x.png')
const riskWarn3 = require('../assets/images/ic_warn_3@2x.png')
const alertIcon = require('../assets/images/ic_arrow_left_2@2x.png')
export default {
name: 'RiskWarning',
components: {
'item-title': ItemTitle
},
data () {
return {
alertIcon: alertIcon
}
},
computed: {
...mapGetters('deliveryHouse', [
'projectRiskInfo'
]),
riskWarnIcon: function () {
return this.risk == '1' ? riskWarn2 : this.risk == '2' ? riskWarn3 : riskWarn1
},
compositeScore () {
return this.projectRiskInfo ? this.projectRiskInfo.compositeScore : ''
},
antiSeepScore () {
return this.projectRiskInfo ? this.projectRiskInfo.antiseepScore : ''
},
functionScore () {
return this.projectRiskInfo ? this.projectRiskInfo.functionScore : ''
},
scheduleScore () {
return this.projectRiskInfo ? this.projectRiskInfo.scheduleScore : ''
},
lightRemark () {
return this.projectRiskInfo ? this.projectRiskInfo.lightRemark : ''
},
rectificationRate () {
return this.projectRiskInfo ? this.projectRiskInfo.rectificationRate : '暂无'
},
risk () {
return this.projectRiskInfo ? this.projectRiskInfo.risk : ''
},
projectRemark () {
return this.projectRiskInfo ? this.projectRiskInfo.projectRemark : ''
},
satisfactionScore () {
return this.projectRiskInfo ? this.projectRiskInfo.satisfactionScore : '暂无'
}
},
methods: {
alertInfo (type) {
if (type == 'composite') {
this.$dialog.Alert(this.formatResult(this.antiSeepScore + this.functionScore + this.scheduleScore), function () {})
} else if (type == 'risk') {
this.$dialog.Alert(this.formatResult(this.lightRemark), function () {})
} else if (type == 'remark') {
this.$dialog.Alert(this.formatResult(this.projectRemark), function () {})
}
},
formatResult (value) {
if (isNaN(value)) { // 非数字
return value
} else if (Number(value) == 0) {
return '暂无'
} else {
return Number(value)
}
}
}
}
</script>
<style scoped>
.risk-warning {
background: white;
}
ul {
padding-left: 0.1rem;
padding-right: 0.1rem;
}
li {
display: flex;
justify-content: space-between;
padding-left: 0.1rem;
padding-right: 0.1rem;
height: 0.9rem;
align-items: center;
}
li:nth-child(even) {
background: #F9F9FB;
}
.label {
font-size: 14px;
color: #6b6f7b;
}
.value {
font-size: 13px;
color: #6b6f7b;
align-self: center;
}
.risk {
width: 0.4rem;
height: 0.41rem;
position: absolute;
right: 0.2rem;
top: 0.245rem;
}
span.label + span.value::after {
content: "";
padding-right: 0.5rem;
width: 0.4rem;
height: 0.4rem;
}
.toAlertIcon {
width: 0.4rem;
height: 0.4rem;
display: flex;
padding-top: 0.2rem;
padding-bottom: 0.2rem;
padding-left: 0.1rem;
}
</style>
<template>
<div class="title-bar">
<span class="back" v-if="isShowBack" @click="back"><img :src="backIcon"/></span>
<span class="title">{{title}}</span>
</div>
</template>
<script>
import backIcon from '../assets/images/ic_back@2x.png'
export default {
name: 'TitleBar',
props: {
title: String,
isShowBack: {
type: Boolean,
default: true
},
backIcon: {
type: String,
default: backIcon
},
backHandle: {
type: Function
}
},
methods: {
back () {
if (this.backHandle) {
this.backHandle()
} else {
this.$router.back()
}
}
}
}
</script>
<style scoped>
.title-bar {
background: #CD3D3D;
height: 1rem;
min-height: 1rem;
display: flex;
justify-content: center;
align-items: center;
}
.title-bar span {
color: white;
vertical-align: center;
}
.back {
position: absolute;
left: 0px;
padding-left: 0.2rem;
padding-right: 0.2rem;
height: 1rem;
line-height: 1rem;
}
.back img {
width: 0.5rem;
height: 0.5rem;
}
.title {
font-size: 20px;
}
</style>
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from '@/App'
import router from '@/router'
import store from '@/vuex/store'
import TitleBar from '@/components/TitleBar'
import BasePage from '@/components/BasePage'
import axios from 'axios'
import { APIPath } from './common'
import Dialog from '@/base/plugins/dialog'
// 全局axios默认配置
axios.defaults.baseURL = APIPath.HOST
Vue.prototype.$axios = axios
// 获取屏幕宽高
Vue.prototype.getViewportSize = function () {
return {
width: window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
height: window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
}
}
/* V+兼容 */
import nativeApi from './base/NativeApi/cordova'
Vue.use(nativeApi, Object.assign({ debug: true, maxRetryTimes: 10, retrySleepTime: 100 }))
// 判断是否V+模块
Vue.prototype.$vPlusModule = process.env.NODE_ENV === 'provt'
Vue.config.productionTip = false
Vue.component('title-bar', TitleBar) // 全局注册标题栏
Vue.component('page', BasePage)
Vue.prototype.$dialog = Dialog // 全局的对话框
let VMT
/* eslint-disable no-new */
if (process.env.NODE_ENV === 'production') {
document.addEventListener('deviceready', function () {
VMT = new Vue({
el: '#app',
router,
store,
render: h => h(App)
})
})
} else {
VMT = new Vue({
el: '#app',
router,
store,
render: h => h(App)
})
}
export default VMT
import Vue from 'vue'
import Router from 'vue-router'
import HouseDelivery from '@/screen/HouseDelivery'
import ProjectDelivery from '@/screen/ProjectDelivery'
Vue.use(Router)
const router = new Router({
routes: [{
path: '/',
name: 'HouseDelivery',
component: HouseDelivery
},
{
path: '/projectdelivery',
name: 'ProjectDelivery',
component: ProjectDelivery
}]
})
// 手动维护路由记录
router.myHistory = []
Router.prototype.isBack = false
router.afterEach((to, from) => {
if (router.myHistory.indexOf(to.fullPath) == -1) {
router.isBack = false
router.myHistory.push(to.fullPath)
} else {
if (router.myHistory[router.myHistory.length - 1] == from.fullPath) {
router.isBack = true
router.myHistory.pop()
}
}
})
export default router
<template>
<div class="container">
<title-bar :title="title" :isShowBack="this.$vPlusModule" :backHandle="backHandle" />
<loading ref="loading" :show="this.$store.state.showLoading" />
<delivery-info class="marginBottom" :info="groupHouseInfo" type='group'/>
<div>
<div class="tab-container">
<button :class="['tab', {tabSelected: isCheckOut}]"
@click="onTabChange(true)">
已交房
</button>
<button :class="['tab', {tabSelected: !isCheckOut}]"
@click="onTabChange(false)">
未交房
</button>
</div>
<div class="delivery-list">
<delivery-list v-if="isCheckOut" @itemClick="itemClickHandler" :list="checkOutList"/>
<transition name="list-in">
<keep-alive key="chart">
<delivery-list v-if="!isCheckOut" @itemClick="itemClickHandler" :list="notCheckOutList"/>
</keep-alive>
</transition>
</div>
</div>
</div>
</template>
<script>
/** 集团交房页面 */
import '@/assets/css/base.css'
import '@/assets/css/app.css'
import { mapActions, mapGetters, mapMutations } from 'vuex'
import DeliveryInfo from '@/components/DeliveryInfo'
import DeliveryList from '@/components/DeliveryList'
import Loading from '@/components/Loading'
export default {
name: 'HouseDelivery',
components: {
'delivery-info': DeliveryInfo,
'delivery-list': DeliveryList,
'loading': Loading
},
created () {
console.log('is v+ module: ' + this.$vPlusModule)
if (this.$vPlusModule) {
this.getUserInfo()
}
if (!this.$router.isBack) {
this.fetchData()
} else {
this.$store.commit('deliveryHouse/resetProject')
}
},
data () {
return {
title: '集团交房',
chartOpt: {
angleAxis: {
},
radiusAxis: {
type: 'category',
data: ['累计保修', '累计实际交付', '符合交房条件'],
z: 10
},
polar: {
},
series: [{
type: 'bar',
data: [57, 0, 0],
coordinateSystem: 'polar',
stack: 'a',
name: '累计保修(户)'
}, {
type: 'bar',
data: [0, 143, 0],
coordinateSystem: 'polar',
stack: 'a',
name: '累计实际交付(户)'
}, {
type: 'bar',
data: [0, 0, 275],
coordinateSystem: 'polar',
stack: 'a',
name: '符合交房条件(户)'
}],
color: ['#D53A35', '#334B5C', '#6AB0B8']
}
}
},
computed: {
...mapGetters('deliveryHouse', [
'groupHouseInfo',
'isCheckOut',
'checkOutList',
'notCheckOutList',
'showPreview'
]),
...mapGetters('user', [
'userId'
])
},
methods: {
...mapActions('deliveryHouse', [
'getHouseSituation',
'getRoomData'
]),
...mapActions('user', [
'getUserInfo'
]),
...mapMutations([
'showLoading'
]),
fetchData () {
this.showLoading(true)
this.$axios.all([
this.getHouseSituation({projectId: '', batchNum: '', userId: ''}),
this.getRoomData({type: 1}),
this.getRoomData({type: 2})
])
.then(this.$axios.spread(() => {
this.showLoading(false)
}))
.catch(error => {
this.showLoading(false)
this.$dialog.Alert(error, function () {})
})
},
onTabChange (isCheckOut) {
this.$store.commit('deliveryHouse/isCheckOut', isCheckOut)
},
itemClickHandler (item) {
this.showLoading(true)
this.getHouseSituation({projectId: item.projectId, batchNum: item.batchNum, userId: this.userId})
.then(_ => {
this.showLoading(false)
this.$store.commit('deliveryHouse/setProjectInfo', item)
this.$router.push({name: 'ProjectDelivery', params: item})
})
.catch(error => {
this.showLoading(false)
this.$dialog.Alert(error, function () {})
})
},
backHandle () {
if (this.$vPlusModule) {
this.$nativeApi.navigator.exit()
} else {
this.$router.back()
}
}
},
beforeRouteLeave (to, from, next) {
if (!this.showPreview) {
next()
} else {
this.$store.commit('deliveryHouse/showPreview', false)
next(false)
}
}
}
</script>
<style scoped>
.marginBottom {
margin-bottom: 0.2rem;
}
.tab-container {
display: flex;
}
.tab {
flex: 1;
font-size: 15px;
cursor: pointer;
border-bottom: solid #f0f0f2 1px;
background: white;
height: 0.8rem;
color: #6b6f7b;
}
.tabSelected {
color: #cd3d3d;
border-bottom: solid #cd3d3d 3px;
}
.delivery-list {
overflow-x: hidden;
}
</style>
<template>
<div class="container">
<title-bar :title="projectName" />
<loading ref="loading" :show="this.$store.state.showLoading" />
<delivery-info v-if="projectHouseInfo" class="margin-bottom-normal"
:focusDate="focusDate"
:info="projectHouseInfo" type='project'/>
<risk-warning class="margin-bottom-normal" />
</div>
</template>
<script>
/**
* 项目、组织交房页面
*/
import { mapActions, mapGetters, mapMutations } from 'vuex'
import DeliveryInfo from '../components/DeliveryInfo'
import RiskWarning from '../components/RiskWarning'
import DeliveryRoomNum from '../components/DeliveryRoomNum'
export default {
name: 'ProjectDelivery',
components: {
'delivery-info': DeliveryInfo,
'risk-warning': RiskWarning,
'delivery-room-num': DeliveryRoomNum
},
created () {
this.fetchData()
},
computed: {
...mapGetters('deliveryHouse', [
'projectInfo',
'isCheckOut',
'projectHouseInfo'
]),
projectName () {
return this.projectInfo ? this.projectInfo.projectName : ''
},
projectId () {
return this.projectInfo ? this.projectInfo.projectId : ''
},
batchNum () {
return this.projectInfo ? this.projectInfo.batchNum : ''
},
orgId () {
return this.projectInfo ? this.projectInfo.orgId : ''
},
type () {
return this.isCheckOut ? 1 : 2
},
focusDate () {
if (this.$route.params.focusDate) {
let dateArr = this.$route.params.focusDate.split('-')
if (dateArr.length >= 6) {
return `${dateArr[0]}${dateArr[1]}${dateArr[2]}日-${dateArr[3]}${dateArr[4]}${dateArr[5]}日`
} else if (dateArr.length >= 3) {
return `${dateArr[0]}${dateArr[1]}${dateArr[2]}日-`
} else {
return this.$route.params.focusDate
}
}
}
},
methods: {
...mapActions('deliveryHouse', [
'getHouseSituation',
'getProjectInfoToRoom',
'getProjectInfoToRisk'
]),
...mapMutations([
'showLoading'
]),
fetchData () {
this.showLoading(true)
this.$axios.all([
this.getProjectInfoToRisk({projectId: this.projectId, batchNum: this.batchNum, orgId: this.orgId})
])
.then(this.$axios.spread(() => {
this.showLoading(false)
}))
.catch(error => {
this.showLoading(false)
this.$dialog.Alert(error, function () {})
})
}
}
}
</script>
/*
封装 定义 连接方法、返回数据格式
*/
// import qs from 'qs';
import axios from 'axios';
// import {APIPath} from '../common'
// import Dialog from '@/base/plugins/dialog'
// 全局axios默认配置
// axios.defaults.baseURL = APIPath.HOST
// axios.defaults.baseURL = APIPath.TESTHOST
axios.defaults.headers = {
'X-Requested-With': 'XMLHttpRequest',
'Authorization': 'Basic c21zc2VydmljZXVzZXI6ZmRjVXNlcjY1NCNAIQ=='// 正式环境 账号 smsserviceuser 密码 fdcUser654#@! // todo 获取登录后的账号密码进行封装 'Basic c21zc2VydmljZXVzZXI6ZmRjVXNlcjY1NCNAIQ=='
// 'Authorization': 'Basic bGl1eW1AZWhvbWVvbC5jbjppdGFk' // 测试环境
}
axios.defaults.timeout = 60 * 1000
// 传json格式参数,不需要
// axios.defaults.transformRequest = [function (params) {
// console.log(params)
// 数据序列化
// return qs.stringify(params)
// }]
let cancel
let promiseArr = {}
const CancelToken = axios.CancelToken
// axios拦截器
axios.interceptors.request.use(config => {
let params = JSON.stringify(config.data)
let key = config.url + '?' + params
// 同一个URL,但是参数不同
if (promiseArr[key]) {
promiseArr[key]('操作取消')
promiseArr[key] = cancel
} else {
promiseArr[key] = cancel
}
return config
}, error => {
return Promise.reject(error)
})
axios.interceptors.response.use(response => {
return response
}, error => {
return Promise.reject(error)
})
export function get (url, params = {}) {
return new Promise((resolve, reject) => {
axios({
method: 'get',
url,
params,
cancelToken: new CancelToken(c => {
cancel = c
})
}).then(res => {
resolve(res)
})
})
}
export function post (url, params = {}) {
return new Promise((resolve, reject) => {
axios({
method: 'post',
url: url,
data: params,
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
},
cancelToken: new CancelToken(c => {
cancel = c
})
}).then(res => {
resolve(res)
})
})
}
export function postJson (url, params = {}) {
return new Promise((resolve, reject) => {
axios({
method: 'post',
url: url,
data: params,
dataType: 'json',
headers: {
'Content-Type': 'application/json; charset=UTF-8'
},
cancelToken: new CancelToken(c => {
cancel = c
})
}).then(res => {
resolve(res)
}).catch(err => {
// errorHandle(errorParse(err))
reject(errorParse(err))
})
})
}
/**
* 解析错误类型,返回错误信息
* @param {*} error
*/
function errorParse (error) {
let message = error
if (error.code == 'ECONNABORTED') { // 请求超时
message = '请求超时!请检查网络连接是否正常!'
return message
}
if (error.message != '操作取消') {
if (error.response) {
switch (error.response.status) {
case 404:
message = '404错误!请检查url是否拼写正确!\n' + error.request.responseURL
break
case 400:
message = '请求错误(400)'
break
case 401:
message = '未授权,请重新登录(401)'
break
case 403:
message = '拒绝访问(403)'
break
case 408:
message = '请求超时(408)'
break
case 500:
message = '服务器错误(500)'
break
case 501:
message = '服务未实现(501)'
break
case 502:
message = '网络错误(502)'
break
case 503:
message = '服务不可用(503)'
break
case 504:
message = '网络超时(504)'
break
case 505:
message = 'HTTP版本不受支持(505)'
break
default:
message = error
}
}
}
return message
}
// function errorHandle (error) {
// Dialog.Alert(error, function () {})
// }
/*
actions.js
封装 获取相应 数据、状态值 方法
*/
/* global cordova:true */
// 引入接口
// import * as Connect from '@/common/connect'
import Base64 from '@/common/base64'
import axios from 'axios'
/*
测试数据分配,10: 房产,20: 物业。
*/
const TESTTYPES = 10
/* V+集成登录获取信息 */
export const getVUserInfo = ({ commit }, data) => {
return new Promise((resolve, reject) => {
const { uname, pwd, host } = data.data
const datas = {
username: uname,
password: Base64.encode(pwd)
}
axios({
method: 'post',
url: host + 'app/loginNew',
data: datas
}).then(res => {
console.log('comein:' + JSON.stringify(res.data))
if (res.data.status === 200) {
// 设置用户数据 userInfo
const dats = res.data.record
// 设置httpHead
const b2v = 'Basic ' + Base64.encode(uname + ':' + pwd)
const datas = {
userInfo: dats,
host,
header: b2v
}
commit('getInfos', { data: datas })
resolve()
} else {
reject(res.data.exception)
}
}).catch(error => {
console.log('fail:' + JSON.stringify(error))
reject(error)
})
})
}
/* 获取用户信息 */
export const getUserInfo = ({ commit }, data) => {
return new Promise((resolve, reject) => {
// console.log('function ' + JSON.stringify(data))
// 同步到state
if (process.env.NODE_ENV === 'production') {
cordova.exec(function (result) {
const dats = JSON.parse(result)
commit('getInfo', { data: dats, type: data.type })
resolve()
}, function (error) {
navigator.notification.alert(error)
resolve()
}, 'YFPlugin', data.type, [])
} else {
// 房产
const adf = {
'username': '邴博',
'cell': '13506027389',
'fid': 'DzmkcfSZQ\/CdF77ixahmwxO33n8=',
'userId': 'bingb@cndrealty.com'
}
// 物业
const adw = {
'username': '刘燕美',
'cell': '1',
'fid': 'dsG2\/e2wTMOehOmJU3HQ3hO33n8=',
'userId': 'liuym@ehomeol.cn'
}
commit('getInfo', {
data: TESTTYPES === 10 ? adf : adw,
type: data.type
})
resolve()
}
})
}
/* 获取hosts */
export const getHttpHost = ({ commit }, data) => {
return new Promise((resolve, reject) => {
// console.log('function ' + JSON.stringify(data))
// 同步到state
if (process.env.NODE_ENV === 'production') {
cordova.exec(function (result) {
commit('getInfo', { data: result, type: data.type })
resolve()
}, function (error) {
navigator.notification.alert(error)
resolve()
}, 'YFPlugin', data.type, [])
} else {
commit('getInfo', { data: 'http://csmtest.cndrealty.com/csm/', type: data.type })
resolve()
}
})
}
/* 获取httpHead */
export const getHttpHeadValue = ({ commit }, data) => {
return new Promise((resolve, reject) => {
// console.log('function ' + JSON.stringify(data))
// 同步到state
if (process.env.NODE_ENV === 'production') {
cordova.exec(function (result) {
commit('getInfo', { data: result, type: data.type })
resolve()
}, function (error) {
navigator.notification.alert(error)
resolve()
}, 'YFPlugin', data.type, [])
} else {
TESTTYPES === 10 ? commit('getInfo', { data: 'Basic YmluZ2JAY25kcmVhbHR5LmNvbTppdGFk', type: data.type }) : commit('getInfo', { data: 'Basic bGl1eW1AZWhvbWVvbC5jbjppdGFk', type: data.type })
resolve()
}
})
}
/*
清除Vuex缓存设置
*/
export const clearVuexData = ({ commit, state }, data) => {
const { userInfo, HttpHeadValue, HttpHost } = state
const datas = {
userInfo,
HttpHeadValue,
HttpHost
}
commit('reSetStateData', datas)
}
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment