Commit a20ca34c authored by JingChao's avatar JingChao

home

parent 97d1a062
*.min.css
iconfont.css
// https://stylelint.io/user-guide/configuration
module.exports = {
defaultSeverity: 'warning',
extends: 'stylelint-config-standard',
rules: {
'rule-empty-line-before': null,
'selector-list-comma-newline-after': 'always-multi-line',
},
};
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
......@@ -35,7 +35,6 @@ exports.cssLoaders = function (options) {
}
}
// generate loader string to be used with extract text plugin
function generateLoaders (loader, loaderOptions) {
//const loaders = options.usePostCSS ? [cssLoader, postcssLoader,px2remLoader] : [cssLoader]
......@@ -50,8 +49,6 @@ exports.cssLoaders = function (options) {
})
}
// Extract CSS when that option is specified
// (which is the case during production build)
if (options.extract) {
......
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
......@@ -21,8 +21,8 @@ const devWebpackConfig = merge(baseWebpackConfig, {
historyApiFallback: true,
hot: true,
compress: true,
host: process.env.HOST || config.dev.host,
port: process.env.PORT || config.dev.port,
host: process.env.HOST || config.dev.host,
port: process.env.PORT || config.dev.port,
open: config.dev.autoOpenBrowser,
overlay: config.dev.errorOverlay ? {
warnings: false,
......@@ -37,7 +37,8 @@ const devWebpackConfig = merge(baseWebpackConfig, {
},
plugins: [
new webpack.DefinePlugin({
'process.env': require('../config/dev.env')
'process.env': require('../config/dev.env'),
$config: require('../config/dev.env')
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
......
......@@ -10,14 +10,16 @@ const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
const env = require('../config/prod.env')
//console.log(config)
const env = require(`../config/${config.ENV}.env`)
const webpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({
sourceMap: config.build.productionSourceMap,
extract: true,
usePostCSS: true
usePostCSS: false
})
},
devtool: config.build.productionSourceMap ? config.build.devtool : false,
......@@ -29,14 +31,15 @@ const webpackConfig = merge(baseWebpackConfig, {
plugins: [
// http://vuejs.github.io/vue-loader/en/workflow/production.html
new webpack.DefinePlugin({
'process.env': env
'process.env': env,
$config: env,
}),
// UglifyJs do not support ES6+, you can also use babel-minify for better treeshaking: https://github.com/babel/minify
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
drop_debugger: true,
drop_console: true
drop_debugger: !env.debug,
drop_console: !env.debug
},
sourceMap: config.build.productionSourceMap,
parallel: true
......
......@@ -4,19 +4,14 @@ const prodEnv = require('./prod.env')
module.exports = merge(prodEnv, {
NODE_ENV: '"development"',
CONFIG_ENV: JSON.stringify(process.env.CONFIG_ENV),
debug: true,
isMobilePlatform: false,
appCode:'"HLS_APP"',
clearTable: true,
hmapUrl:'"http://hippius.hand-china.com/hmap220"',
loginPath: '"http://hlsapp.hand-china.com/core/oauth/token?client_id=hQGCtxTItRa34PUOgxaD0r7oSPeuEaIB&client_secret=7ee8338c-4a06-44a1-87cc-afa63f8e1bc3&grant_type=password&username=app&password=" ',
basePath: '"http://hlsapp.hand-china.com/core/r/api?sysName=HLS_APP&apiName="',
basePath: '"http://hlsapp.hand-china.com/core/r/api?sysName=XCMG_DEV&apiName="',
rootPath: '"http://hlsapp.hand-china.com/core/r/api"',
riskPath: '"http://hlsapp.hand-china.com/core/r/api/app/riskQuery?sysName=HLS_RISK&apiName="',
riskKey: '"pIGBbSRyThA4Xg"',
pushKey: '"45ace0e521f01edb2f1c753a"',
file_url: '"http://hlsapp.hand-china.com/file/"',
appId: '"com.hls.easy.car"',
currentVersion: '"1.0.0"',
dbName: '"Function.db"',
dbLocation: 0,
currentVersion: '"1.0.0"'
});
......@@ -4,14 +4,16 @@
const path = require('path')
const CONFIG_ENV = process.env.CONFIG_ENV
module.exports = {
ENV:CONFIG_ENV,
base: {
// Use Flexible?
useFlexible: true,
remUnit: 50, // 启用flexible时的根字体大小(px)
// Use PostCSS?
usePostCSS: true,
usePostCSS: false,
},
dev: {
......@@ -54,6 +56,7 @@ module.exports = {
// In our experience, they generally work as expected,
// just be aware of this issue when enabling this option.
cssSourceMap: false,
ENV:CONFIG_ENV
},
build: {
......@@ -77,6 +80,7 @@ module.exports = {
// 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
bundleAnalyzerReport: process.env.npm_config_report,
ENV:CONFIG_ENV
}
}
'use strict'
'use strict'
module.exports = {
NODE_ENV: '"production"',
debug: false,
isMobilePlatform: true,
appCode:'"HLS_APP"',
clearTable: true,
CONFIG_ENV: JSON.stringify(process.env.CONFIG_ENV),
debug: true,
isMobilePlatform: false,
hmapUrl:'"http://hippius.hand-china.com/hmap220"',
loginPath: '"http://hlsapp.hand-china.com/core/oauth/token?client_id=hQGCtxTItRa34PUOgxaD0r7oSPeuEaIB&client_secret=7ee8338c-4a06-44a1-87cc-afa63f8e1bc3&grant_type=password&username=app&password=" ',
basePath: '"http://hlsapp.hand-china.com/core/r/api?sysName=HLS_APP&apiName="',
rootPath: '"http://hlsapp.hand-china.com/core/r/api"',
riskPath: '"http://hlsapp.hand-china.com/core/r/api/app/riskQuery?sysName=HLS_RISK&apiName="',
riskKey: '"pIGBbSRyThA4Xg"',
pushKey: '"45ace0e521f01edb2f1c753a"',
file_url: '"http://hlsapp.hand-china.com/file/"',
appId: '"com.hls.easy.car"',
currentVersion: '"1.0.0"',
dbName: '"Function.db"',
dbLocation: 0,
currentVersion: '"1.0.0"'
}
'use strict'
module.exports = {
NODE_ENV: '"production"',
CONFIG_ENV: JSON.stringify(process.env.CONFIG_ENV),
debug: false,
isMobilePlatform: true,
hmapUrl:'"http://hippius.hand-china.com/hmap220"',
loginPath: '"http://hlsapp.hand-china.com/core/oauth/token?client_id=hQGCtxTItRa34PUOgxaD0r7oSPeuEaIB&client_secret=7ee8338c-4a06-44a1-87cc-afa63f8e1bc3&grant_type=password&username=app&password=" ',
basePath: '"http://hlsapp.hand-china.com/core/r/api?sysName=XCMG_DEV&apiName="',
rootPath: '"http://hlsapp.hand-china.com/core/r/api"',
file_url: '"http://hlsapp.hand-china.com/file/"',
appId: '"com.hls.easy.car"',
currentVersion: '"1.0.0"'
}
......@@ -10,6 +10,8 @@
<!-- safari私有meta标签 允许全屏模式浏览 指定safari顶部状态栏样式(黑色) -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<script type="text/javascript" src="./static/vuePlatform.js"></script>
<script type="text/javascript" src="./static/prototype.js"></script>
<script type="text/javascript" src="cordova.js"></script>
<title>车租易</title>
</head>
......
......@@ -5,9 +5,11 @@
"author": "JingChao <jingchao.wu@hand-china.com>",
"private": true,
"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"dev": "cross-env CONFIG_ENV=dev webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"start": "npm run dev",
"build": "node build/build.js"
"build:uat": "cross-env CONFIG_ENV=uat node build/build.js",
"build": "cross-env CONFIG_ENV=prod node build/build.js",
"clean": "rimraf www/*"
},
"dependencies": {
"autosize": "^3.0.20",
......@@ -18,7 +20,6 @@
"cordova-plugin-device": "^2.0.2",
"cordova-plugin-whitelist": "^1.3.3",
"crypto-js": "^3.1.9-1",
"fastclick": "https://hel.hand-china.com/easyUI/fastclick.git#v1.0.7",
"vue": "^2.5.2",
"vue-router": "^3.0.1",
"vuex": "^2.1.1",
......
......@@ -36,12 +36,8 @@ export default {
this.$router.isBack = true
this.pathList = []
}
let isBack = this.$router.isBack
if (isBack) {
// let isBack = this.$router.isBack
this.transitionName = 'router-slide-right'
} else {
this.transitionName = 'router-slide-left'
}
this.$router.isBack = false
},
},
......@@ -54,7 +50,8 @@ export default {
</script>
<style lang="less">
@import "styles/app.core.less";
@import "styles/variables";
@import "styles/public-style";
html, body, #app {
height: 100%;
......
底部弹出菜单 插件形式调用
```html
showActionSheet() {
hlsPopup.showActionSheet({
titleText: '请选择照片',
buttonArray: ['拍照', '从相册取'],
callback: (index) => {
alert(index);
}
})
}
showActionSheetButton() {
hlsPopup.showActionSheet({
titleText: '照片',
buttonArray: [{text: '拍照', type: 'warn'}, {text: '从相册取', type: 'primary'}],
callback: (index) => {
alert(index);
}
});
}
```
<template>
<div class="action-sheet-backdrop" :class="{'active': state == 1}" @click="hide(-1)">
<div class="action-sheet-wrapper" :class="{'action-sheet-up': state == 1}">
<div class="action-sheet">
<div class="action-sheet-group action-sheet-options">
<div class="action-sheet-title" style="" v-if="title" v-text="title">
</div>
<div class="action-sheet-option" :class="`action-sheet-option-${b.type || 'default'}`"
@click="hide(index)" v-for="(b, index) in buttons"
v-text="b.text">
</div>
</div>
<div class="action-sheet-group action-sheet-cancel">
<div class="ng-binding action-sheet-option" @click="hide(-1)" style="border:none">取消</div>
</div>
</div>
</div>
</div>
</template>
<style lang="less">
.platform-ios{
.action-sheet-backdrop{
.action-sheet{
margin-left: 8px;
margin-right: 8px;
width: auto;
z-index: 11;
overflow: hidden;
border-radius: 16px;
background-color: transparent;
.action-sheet-group{
margin-bottom: 8px;
border-radius: 16px;
background-color: #fff;
overflow: hidden;
}
.action-sheet-options{
background: #f1f2f3;
}
.action-sheet-option{
color: #007aff;
min-height: 94px;
font-size: 38px;
}
.action-sheet-option-primary {
color: @actionsheet-label-primary-color;
}
.action-sheet-option-warn {
color: @actionsheet-label-warn-color;
}
.action-sheet-option-default {
color: #007aff;
}
.action-sheet-option-disabled {
color: @actionsheet-label-disabled-color;
}
}
}
}
.action-sheet-backdrop {
-webkit-transition: background-color 150ms ease-in-out;
transition: background-color 150ms ease-in-out;
position: fixed;
top: 0;
left: 0;
z-index: 999;
width: 100%;
height: 100%;
background-color: transparent;
&.active {
background-color: rgba(0, 0, 0, 0.4);
}
.action-sheet-wrapper {
-webkit-transform: translate3d(0, 100%, 0);
transform: translate3d(0, 100%, 0);
-webkit-transition: all cubic-bezier(0.41, 0.57, 0.19, 0.79) 300ms;;
transition: all cubic-bezier(0.41, 0.57, 0.19, 0.79) 300ms;
position: absolute;
bottom: 0;
left: 0;
right: 0;
width: 100%;
//max-width: 500px;
margin: auto;
}
.action-sheet-up {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
.action-sheet {
width: auto;
z-index: 11;
overflow: hidden;
background-color: #efeff4;
}
.action-sheet-options {
background: white;
}
.action-sheet-group {
margin-bottom: 16px;
//border-radius: 4px;
background-color: #fff;
overflow: hidden;
&:last-child {
margin-bottom: 0;
}
}
.action-sheet-title {
padding: 32px;
color: #8f8f8f;
text-align: center;
font-size: @font-size-middle;
}
.action-sheet-group .action-sheet-option {
border-width: 1px 0 0 0;
&:last-child {
margin-top: 1px;
}
}
.action-sheet .action-sheet-option {
text-align: center;
display: flex;
display: -webkit-flex;
align-items: center;
-webkit-align-items: center;
justify-content: center;
-webkit-justify-content: center;
padding: 1px;
width: 100%;
border-radius: 0;
background-color: transparent;
//color: #444;
font-size: 32px;
min-width: 53px;
min-height: 90px;
border-top: 1px solid #d1d3d6
}
.action-sheet-option-primary {
color: @actionsheet-label-primary-color;
}
.action-sheet-option-warn {
color: @actionsheet-label-warn-color;
}
.action-sheet-option-default {
color: @actionsheet-label-default-color;
}
.action-sheet-option-disabled {
color: @actionsheet-label-disabled-color;
}
}
.modal-open [vum-action-sheet] {
pointer-events: auto;
}
// iPhoneX适配
@media (device-width: 375px) and (device-height: 812px) and (-webkit-min-device-pixel-ratio: 3) {
.platform-ios.platform-cordova:not(.fullscreen) {
.action-sheet-backdrop {
.action-sheet {
margin-bottom: @bottomSafeArea;
}
}
}
}
// iPhoneX适配
@media (device-width: 414px) and (device-height: 896px){
.platform-ios.platform-cordova:not(.fullscreen) {
.action-sheet-backdrop {
.action-sheet {
margin-bottom: @bottomSafeArea;
}
}
}
}
</style>
<script>
import assign from 'object-assign'
export default {
data() {
return {
defaultOptions: {
title: '',
buttons: [],
cancelText: 'Cancel'
},
title: '',
buttons: [],
cancelText: 'Cancel',
state: 0
}
},
mounted() {
this.$el.setAttribute('vum-action-sheet', '')
},
destroyed() {
document.body.removeChild(this.$el)
},
methods: {
_buttonList(buttons) {
let buttonList = []
for (let b in buttons) {
buttonList.push({
text: b.text,
callback: b.callback
})
}
return buttonList
},
show(options) {
let _options = assign({}, this.defaultOptions, options)
this.title = _options.title;
this.buttons = _options.buttons;
this.cancelText = _options.cancelText;
this.state = 1
},
hide(buttonIndex) {
this.state = 0
if (buttonIndex > -1) {
this.buttons[buttonIndex].callback(buttonIndex)
}
let wrapper = document.querySelector('[vum-action-sheet] > .action-sheet-wrapper')
wrapper.addEventListener('webkitTransitionEnd', () => {
this.$destroy()
}, false)
},
getState() {
return this.state
}
}
}
</script>
import Vue from 'vue'
import ActionSheet from './actionsheet.vue'
import elementUtil from '../../scripts/elementUtil.js'
class VueActionSheet {
constructor() {
this._vm = undefined
}
show(option) {
elementUtil.createElement('vum-action-sheet')
this._vm = new Vue(ActionSheet)
this._vm.$mount('[vum-action-sheet]')
setTimeout(() => {
this._vm.show(option)
})
}
hide(buttonIndex) {
this._vm.hide(buttonIndex)
}
getState() {
return this._vm ? this._vm.getState() : 0
}
}
export default new VueActionSheet()
<template>
<transition :name="transition">
<div v-show="show && !!content || showNotify" :class="[c(),cusClass,positionClass]" name="notify">
<div :class="[c('wrap'),wrapClass,c('wrap-'+type)]">
<div :class="c('content')">{{ content }}</div>
</div>
</div>
</transition>
</template>
<script>
import assign from 'object-assign'
import {base, prefix} from '../../common/mixins'
export default {
name: 'Notify',
/* eslint-disable vue/require-default-prop */
mixins: [base, prefix],
props: {
value: Boolean,
showNotify: {
type: Boolean,
default: false
},
content: {
type: String,
default: '',
},
position: {
type: String,
default: 'top',
},
time: {
type: Number,
default: 3000,
},
cusClass: {
type: String,
default: ''
},
type: {
type: String,
default: ''
}
},
/* eslint-enable */
data() {
return {
show: false,
plugin: false,
wrapClass: '',
wrapType: ''
}
},
computed: {
transition() {
return this.position === 'bottom' ? 'slide-in-up' : 'slide-in-down'
},
positionClass() {
return this.position === 'bottom' ? this.c('bottom') : this.c('top')
},
pluginClass() {
let vm = this;
if (vm.plugin === true) {
return vm.position === 'bottom' ? 'notify-plugin-bottom' : 'notify-plugin-top'
}
}
},
watch: {
value(val) {
this.show = val
},
show(val) {
// 标签用法时需要发射一个input事件,修改v-model绑定的属性值
this.$emit('input', val)
val &&
setTimeout(() => {
this.show = false
}, this.time)
}
},
methods: {
showPlugin(options) {
let vm = this;
let _options = assign({}, this.defaultOptions, options)
vm.content = _options.content;
vm.position = _options.position;
vm.time = _options.time;
vm.type = _options.type;
vm.showNotify = true;
vm.plugin = true;
vm.wrapClass = "hls-notify-wrap-plugin";
setTimeout(function () {
vm.showNotify = false
if (vm.plugin) {
document.body.removeChild(vm.$el)
}
}, vm.time)
},
},
}
</script>
<style lang="less">
.hls-notify {
width: 100%;
position: absolute;
left: 0;
text-align: center;
z-index: 1;
&-top {
top: 0;
}
&-bottom {
bottom: 0;
}
&-wrap {
padding: 16px 26px;
line-height: 30px;
font-size: 30px;
color: @notifyFontColor;
background-color: @dialogWrapBackgroundColor;
}
.hls-notify-wrap-plugin {
padding: 0;
height: 87px;
line-height: 0;
display: flex;
align-items: center;
justify-content: center;
}
&-wrap-warning {
background-color: @dialogWrapWarningBackgroundColor;
}
&-wrap-success {
background-color: @dialogWrapSuccessBackgroundColor;
}
&-content {
word-wrap: break-word;
}
}
// ios平台
.platform-ios .hls-notify .hls-notify-wrap-plugin {
padding-top: @iosPaddingTop;
height: @iosHasHeader;
}
// iPhoneX适配
@media (device-width: 375px) and (device-height: 812px) and (-webkit-min-device-pixel-ratio: 3) {
.platform-ios.platform-cordova:not(.fullscreen) {
.hls-notify .hls-notify-wrap-plugin {
padding-top: @iosxPaddingTop;
height: @iosxHasHeader;
}
}
}
// iPhoneX Max适配
@media (device-width: 414px) and (device-height: 896px) {
.platform-ios.platform-cordova:not(.fullscreen) {
.hls-notify .hls-notify-wrap-plugin {
padding-top: @iosxPaddingTop;
height: @iosxHasHeader;
}
}
}
</style>
Notify 通知提醒 插件和组件形式调用
```html
<h2 class="item-title">notify</h2>
<div class="local-region">
<notify v-model="show1" content="提示内容"/>
<notify v-model="show2" :time="3000" position="bottom" content="提示内容"/>
</div>
<h2 class="item-title">notify标签用法 (通常在局部显示时使用)</h2>
<h-button class="button-class" type="rimless" shadow @click.native="showNotifyAtTop">Notify (top)</h-button>
<h-button class="button-class" type="rimless" shadow @click.native="showNotifyAtBottom">Notify (bottom)</h-button>
// 标签用法
showNotifyAtTop() {
if (this.show1) return
this.show1 = true
},
showNotifyAtBottom() {
if (this.show2) return
this.show2 = true
},
// 插件用法
showNotify(ops = {}) {
hlsPopup.showNotify({
content: ops.content,
position: ops.position,
time: ops.time
})
},
handleNotify() {
this.showNotify({
content: '提示内容',
position: 'top',
time: 2000
})
},
```
import Vue from 'vue'
import Notify from '../Notify'
import elementUtil from '../../../scripts/elementUtil.js'
class VueNotify {
constructor() {
this._vm = undefined
}
show(option) {
elementUtil.createElement('vum-notify')
this._vm = new Vue(Notify)
this._vm.$mount('[vum-notify]')
setTimeout(() => {
this._vm.showPlugin(option)
})
}
}
export default new VueNotify()
<template>
<div class="function-item" @click="functionDo">
<img :src="functionIcon">
<div>{{ functionName }}</div>
</div>
</template>
<script>
export default {
name: 'FunctionItem',
props: {
functionIcon: {
type: String,
default: '',
},
functionName: {
type: String,
default: '',
},
data: {
type: Object,
default: null,
},
},
methods: {
functionDo () {
let vm = this
this.$emit('clickFunction', vm.data)
},
},
}
</script>
<style lang="less" scoped type="text/less">
.function-item{
text-align: center;
img{
width: 50%;
margin-bottom: 5px;
}
div{
font-size: 12px;
margin-bottom:10px;
}
}
</style>
<template>
<!--<transition :name="transition">-->
<div class="modal-backdrop" :class="active" v-show="showModal" @touchstart="hideModal">
<div class="modal-backdrop-bg"></div>
<div class="modal slide-in-up" :class="[modalClass,cusClass]"
@touchstart="start"
@mousedown="start">
<slot></slot>
</div>
</div>
<!--</transition>-->
</template>
<script>
export default {
name: "Modal",
props: {
value: Boolean,
position: {
type: String,
default: 'bottom',
},
cusClass: {
type: String,
default: ''
}
},
data() {
return {
showModal: false,
state: 0
}
},
computed: {
transition() {
return this.position === 'bottom' ? 'slide-in-up' : 'slide-in-down'
},
active() {
return this.showModal ? 'active' : 'hide'
},
modalClass() {
let mclass;
if (this.state == 1) {
mclass = "active"
} else if (this.state == 2) {
mclass = 'ng-enter ng-enter-active active'
} else if (this.state == 3) {
mclass = 'ng-leave ng-leave-active'
}
return mclass;
}
},
watch: {
value(val) {
this.showModal = val
this.state = 1
setTimeout(() => {
this.state = 2
setTimeout(() => {
}, 400)
}, 50)
},
showModal(val) {
// 标签用法时需要发射一个input事件,修改v-model绑定的属性值
this.$emit('input', val)
}
},
methods: {
preventDefault(e) {
//e.stopPropagation();
},
start(e) {
e.stopPropagation();
},
hideModal() {
this.state = 3
setTimeout(() => {
this.state = 0
this.showModal = false;
}, 250)
}
}
}
</script>
<style scoped lang="less">
</style>
<template>
<div class="modal-backdrop"
:class="{'active': state > 0, 'hide': state == 0}" @touchstart="hide(0)">
<div class="modal-backdrop-bg"></div>
<!--<div class="modal-wrapper">-->
<div class="modal slide-in-up" :class="[
modalClass,cusClass
]"
@touchstart="start"
@mousedown="start">
<div hls-modal-content></div>
</div>
</div>
<!--</div>-->
</template>
<script>
const show_modal_animate_dur = 400
const hide_modal_animate_dur = 250
export default {
props: {
cusClass: {
type: String,
default: ''
},
destroyOnHide: Boolean,
onShow: Function,
onHide: Function
},
data() {
return {
state: 0
}
},
computed: {
modalClass() {
let mclass;
if (this.state == 1) {
mclass = "active"
} else if (this.state == 2) {
mclass = 'ng-enter ng-enter-active active'
} else if (this.state == 3) {
mclass = 'ng-leave ng-leave-active'
}
return mclass;
}
},
destroyed() {
this.$el.parentNode.removeChild(this.$el)
},
methods: {
preventDefault(e) {
e.stopPropagation();
},
start(e) {
e.stopPropagation();
this.hide(1);
},
show() {
if (this.onShow) {
this.onShow()
}
this.state = 1
setTimeout(() => {
this.state = 2
setTimeout(() => {
}, show_modal_animate_dur)
}, 50)
},
hide(a) {
if (!a) {
if (this.onHide) {
this.onHide()
}
this.state = 3
setTimeout(() => {
this.state = 0
if (this.destroyOnHide) {
this.$destroy()
}
}, hide_modal_animate_dur)
}
}
}
}
</script>
import Vue from 'vue'
import Modal from './PluginModal.vue'
const createElement = (marker, root, tag) => {
let target = document.querySelector(root) || document.body
if (target.querySelectorAll(marker).length == 0) {
let el = document.createElement(tag || 'div')
el.setAttribute(marker, '')
target.appendChild(el)
}
}
class HlsModal {
constructor() {
this.modals = {}
}
fromComponent(comp, options) {
let destroyOnHide = options && options.destroyOnHide
let onHide = options && options.onHide
let onShow = options && options.onShow
let cusClass = options && options.cusClass
let modalId = 'modal_' + Math.random().toString(36).substr(3, 9)
createElement(modalId)
let ModalComponent = Vue.extend(Modal)
let modal = new ModalComponent({
propsData: {
destroyOnHide: !!destroyOnHide,
onShow:onShow,
onHide: onHide,
cusClass:cusClass
}
})
modal.$mount(`[${modalId}]`)
let ContentComponent = Vue.extend(comp)
let content = new ContentComponent()
content.$mount(modal.$el.querySelector('[hls-modal-content]'))
modal.id = modalId
modal.content = content
this.modals[modalId] = modal
return new Promise((resolve) => {
resolve(modal)
})
}
destroy(modal) {
if (modal) {
modal.content && modal.content.$destroy()
modal.$destroy()
}
}
}
export default new HlsModal()
数字键盘 插件和组件调用
```html
<list-item :item-height="90">
<item>
<div slot="name">数字键盘</div>
<input slot="right" type="number" placeholder="输入" readonly v-model="value" @click="keyboradShow">
</item>
</list-item>
<number-keyboard
:show="true"
title="数字键盘"
extra-key="."
@input="onInput"
@delete="onDelete"/>
keyboradShow() {
let vm = this;
hlsPopup.showNumberKeyborad({
title: '数字键盘',
keyDown: (text) => {
vm.onInput(text);
},
keyDelete: () => {
vm.onDelete()
},
})
},
```
import Vue from 'vue'
import numberKeyboard from './index.vue'
import elementUtil from '../../scripts/elementUtil.js'
class VueKeyboard {
constructor() {
this._vm = undefined
}
show(option) {
elementUtil.createElement('vum-show-keyborad')
this._vm = new Vue(numberKeyboard)
this._vm.$mount('[vum-show-keyborad]')
setTimeout(() => {
this._vm.showNumberKeyboard(option)
})
}
onClose() {
this._vm.onClose()
}
onPressKey() {
this._vm.onPressKey()
}
}
export default new VueKeyboard()
<template>
<transition :name="transition ? 'van-slide-bottom' : ''">
<div class="keyboard-backdrop" :class="cusClass" @click="closeKeyboard" v-show="show">
<div
v-show="show"
:style="style"
class="number-keyboard"
@touchstart.stop
@animationend="onAnimationEnd"
@webkitAnimationEnd="onAnimationEnd"
>
<div class="number-keyboard__title van-hairline--top" v-if="title || showTitleClose">
<span v-text="title"/>
<span
class="number-keyboard__close"
v-if="showTitleClose"
v-text="closeButtonText"
@click="onClose"
/>
</div>
<div class="number-keyboard__body">
<key
v-for="key in keys"
:key="key.text"
:text="key.text"
:type="key.type"
@press="onPressKey"
/>
</div>
</div>
</div>
</transition>
</template>
<style lang="less" scoped rel="stylesheet">
.keyboard-backdrop {
-webkit-transition: background-color 150ms ease-in-out;
transition: background-color 150ms ease-in-out;
position: fixed;
top: 0;
left: 0;
z-index: 999;
width: 100%;
height: 100%;
background-color: transparent;
&.active {
background-color: rgba(0, 0, 0, 0);
}
}
@van-number-keyboard-key-height: 108px;
.number-keyboard {
left: 0;
bottom: 0;
width: 100%;
position: fixed;
user-select: none;
background-color: @baseColor;
animation-timing-function: ease-out;
&__title {
height: 60px;
font-size: 27px;
line-height: 60px;
text-align: center;
position: relative;
color: #38f;
border-bottom: 1px solid #e5e5e5;
box-shadow: 0px -1px 6px rgba(0,0,0,0.1)
}
&__body {
box-sizing: border-box;
}
&__close {
right: 0;
color: #38f;
font-size: 28px;
padding: 0 30px;
position: absolute;
&:active {
background-color: #e8e8e8;
}
}
.key {
width: calc(100% / 3);
font-size: 48px;
font-style: normal;
text-align: center;
display: inline-block;
vertical-align: middle;
height: @van-number-keyboard-key-height;
line-height: @van-number-keyboard-key-height;
border-width: 1px 1px 0 0;
border-bottom: 1px solid #e5e5e5;
border-right: 1px solid #e5e5e5;
}
.delete {
font-size: 0;
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAeCAMAAABg6AyVAAAAbFBMVEUAAAAfHiIdHB4eHR8dHR4eHB4dHB4dHR8gICIdHB4dHB4dHB4dHB8eHh8hISEeHR8fHB8fHR8fHR8fHx8eHiArKyszMzMeHB8eHB8fHR8eHiAeHh4dHB4vLjDY2Nn////b29zKysq9vb28vLzkfBRpAAAAHHRSTlMAK/PW+I/llBv77N1kSCPwWlFAOTMGBb28hHlu08g5sgAAAMlJREFUOMuV1MsWgiAQgGHQyOx+s+sgYO//jnnMGIdDDfwbN99CYEDQFiVEKkolPUG7gl9VTWC31NKuDbVz+Fc1tRJtPDmxS2BS3p5ZC+XXnnbAVoz2WEBCH7uZAalzGoa06whGiznT6sG2xgX4QO2Aej1+KN7XBKL2FvGaMtTWBhbQhtoaYzVQrHKwuGf8hhAPSF5g3xPSt45sCHcouNWx436FGA+RHyQcD35EcUj54U8ff4WYvVi1zLjelUh/OG6XjOeLWv5hfAOI+HLwwOAqhAAAAABJRU5ErkJggg==") no-repeat center center;
background-size: auto 30px;
}
.gray {
background-color: #f3f3f6;
}
.active {
background-color: #e8e8e8;
}
}
@keyframes van-slide-bottom-enter {
from {
transform: translate3d(0, 100%, 0);
}
}
@keyframes van-slide-bottom-leave {
to {
transform: translate3d(0, 100%, 0);
}
}
@keyframes van-fade-in {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes van-fade-out {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
@keyframes van-rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.van-fade {
&-enter-active {
animation: .3s van-fade-in;
}
&-leave-active {
animation: .3s van-fade-out;
}
}
.van-slide-bottom {
&-enter-active {
animation: van-slide-bottom-enter .3s both ease;
}
&-leave-active {
animation: van-slide-bottom-leave .3s both ease;
}
}
// iPhoneX适配
@media (device-width: 375px) and (device-height: 812px) and (-webkit-min-device-pixel-ratio: 3) {
.platform-ios.platform-cordova:not(.fullscreen) {
.number-keyboard {
&__body {
margin-bottom: @bottomSafeArea;
}
}
}
}
// iPhoneX Max适配
@media (device-width: 414px) and (device-height: 896px) {
.platform-ios.platform-cordova:not(.fullscreen) {
.number-keyboard {
&__body {
margin-bottom: @bottomSafeArea;
}
}
}
}
</style>
<script>
import Key from './key';
export default {
name: 'number-keyboard',
components: {Key},
props: {
show: Boolean,
title: String,
closeButtonText: String,
theme: {
type: String,
default: 'default'
},
extraKey: {
type: String,
default: ''
},
zIndex: {
type: Number,
default: 100
},
transition: {
type: Boolean,
default: true
},
showDeleteKey: {
type: Boolean,
default: true
},
hideOnClickOutside: {
type: Boolean,
default: true
},
cusClass: {
type: String,
default: ''
}
},
data() {
return {
keyBoardPlugin: false
}
},
mounted() {
this.handler(true);
this.$el.setAttribute('vum-show-keyborad', '')
}
,
destroyed() {
this.handler(false);
if (this.keyBoardPlugin) {
document.body.removeChild(this.$el)
}
}
,
activated() {
this.handler(true);
}
,
deactivated() {
this.handler(false);
}
,
watch: {
show() {
if (!this.transition) {
this.$emit(this.show ? 'show' : 'hide');
}
}
}
,
computed: {
keys() {
const keys = [];
for (let i = 1; i <= 9; i++) {
keys.push({text: i});
}
keys.push(
{text: this.extraKey, type: 'gray'},
{text: 0},
{text: 'delete', type: "delete gray"}
);
return keys;
}
,
style() {
return {
zIndex: this.zIndex
};
}
,
showTitleClose() {
return this.closeButtonText && this.theme === 'default';
}
}
,
methods: {
closeKeyboard() {
let vm = this;
this.show = false;
let wrapper = document.querySelector('[vum-show-keyborad]')
if (wrapper && vm.keyBoardPlugin) {
document.body.removeChild(wrapper)
}
}
,
showNumberKeyboard(options) {
this.keyBoardPlugin = true;
this.title = options.title;
this.closeButtonText = options.closeButtonText;
this.extraKey = options.extraKey;
this.keyDown = options.keyDown;
this.keyDelete = options.keyDelete;
this.show = true
}
,
handler(action) {
if (action !== this.handlerStatus && this.hideOnClickOutside) {
this.handlerStatus = action;
document.body[(action ? 'add' : 'remove') + 'EventListener']('touchstart', this.onBlur);
}
}
,
onBlur() {
this.$emit('blur');
}
,
onClose() {
this.$emit('close');
this.show = false;
this.onBlur();
}
,
onAnimationEnd() {
this.$emit(this.show ? 'show' : 'hide');
}
,
onPressKey(text) {
let vm = this;
if (text === '') {
return;
}
if (text === 'delete') {
this.$emit('delete');
if (vm.keyDelete) {
vm.keyDelete();
}
} else if (text === this.closeButtonText) {
this.onClose();
} else {
this.$emit('input', text);
//debugger;
if (vm.keyDown) {
vm.keyDown(text);
}
}
}
}
}
</script>
<template>
<i
v-text="text"
@touchstart.stop.prevent="onFocus"
@touchmove="onBlur"
@touchend="onBlur"
@touchcancel="onBlur"
class="van-hairline key"
:class="type"
/>
</template>
<script>
export default {
name: 'key',
props: {
text: [String, Number],
type: {
type: String,
default: () => ''
}
},
data() {
return {
active: false
};
},
computed: {
},
methods: {
onFocus(e) {
e.target.className += ' ' + 'active';
this.$emit('press', this.text);
},
onBlur(e) {
e.target.classList.remove('active');
this.active = false;
}
}
};
</script>
select下拉框 插件形式调用
```html
<h-button class="button-class" type="primary" @click.native="selectListOne">selectList 普通下拉框</h-button>
<h-button class="button-class" type="primary" @click.native="selectListTwo">selectList 二级联动</h-button>
<h-button class="button-class" type="primary" @click.native="selectList">selectList 三级联动</h-button>
selectListOne() {
var bp_class_list = [
{
"code": "NP",
"code_name": "个人"
}, {
"code": "NP1",
"code_name": "个人1"
}, {
"code": "NP2",
"code_name": "个人2"
}
];
hlsPopup.selectList({
list: bp_class_list,
code: 'bp_type',
object: {},
returnItem: function (index, obj, child) {
console.log('index:' + index + ',object:' + vum.toJson(obj) + ',:child' + vum.toJson(child))
}
})
},
selectListTwo() {
var bp_class_list = [
{
"code": "NP",
"code_name": "个人"
}, {
"code": "NP1",
"code_name": "个人1"
}, {
"code": "NP2",
"code_name": "个人2"
}, {
"code": "NP3",
"code_name": "个人3",
"parent": 'NP',
}, {
"code": "NP4",
"code_name": "个人4",
"parent": 'NP1',
}, {
"code": "NP5",
"code_name": "个人5",
"parent": 'NP2',
}
];
hlsPopup.selectList({
list: bp_class_list,
code: 'bp_type',
object: {},
returnItem: function (index, obj, child) {
console.log('index:' + index + ',object:' + vum.toJson(obj) + ',:child' + vum.toJson(child))
}
})
},
selectList() {
var bp_class_list = [
{
"code": "NP",
"code_name": "个人"
}, {
"code": "NP1",
"code_name": "个人1"
}, {
"code": "NP2",
"code_name": "个人2"
}, {
"code": "NP3",
"code_name": "个人3",
"parent": 'NP',
}, {
"code": "NP4",
"code_name": "个人4",
"parent": 'NP',
}, {
"code": "NP5",
"code_name": "个人5",
"parent": 'NP2',
}, {
"code": "NP6",
"code_name": "个人6",
"parent": 'NP3'
}, {
"code": "NP7",
"code_name": "个人7",
"parent": 'NP4'
},
{
"code": "NP8",
"code_name": "个人8",
"parent": 'NP1'
}
];
hlsPopup.selectList({
list: bp_class_list,
code: 'bp_type',
object: {},
returnItem: function (index, obj, child) {
console.log('index:' + index + ',object:' + vum.toJson(obj) + ',:child' + vum.toJson(child))
}
})
},
```
import Vue from 'vue'
import Select from './select.vue'
import elementUtil from '../../scripts/elementUtil.js'
class VueSelect {
constructor() {
this._vm = undefined
}
show(option) {
elementUtil.createElement('vum-show-select')
this._vm = new Vue(Select)
this._vm.$mount('[vum-show-select]')
setTimeout(() => {
this._vm.show(option)
})
}
hide(index) {
this._vm.returnItem(index)
}
}
export default new VueSelect()
<template>
<div class="show-select-backdrop" :class="{'active': state == 1}" @click="returnItem(-1)">
<h-content class="show-select-wrapper"
:class="{'show-select-up': state == 1}">
<popup-header
:left-text="cancelText"
:right-text="confirmText"
@on-click-left="returnItem(-1)"
@on-click-right="returnItem(1)"
:title="popupTitle"></popup-header>
<picker
:data="list"
v-model="tempValue"
:columns="3"
@on-change="onPickerChange"
:key="index"
></picker>
</h-content>
</div>
</template>
<style lang="less" scoped>
.show-select-backdrop {
-webkit-transition: background-color 150ms ease-in-out;
transition: background-color 150ms ease-in-out;
position: fixed;
top: 0;
left: 0;
z-index: 999;
width: 100%;
height: 100%;
background-color: transparent;
&.active {
background-color: rgba(0, 0, 0, 0.2);
}
.show-select-wrapper {
-webkit-transform: translate3d(0, 100%, 0);
transform: translate3d(0, 100%, 0);
-webkit-transition: all cubic-bezier(0.36, 0.66, 0.04, 1) 500ms;
transition: all cubic-bezier(0.36, 0.66, 0.04, 1) 500ms;
bottom: 0 !important;
position: absolute !important;
max-height: 50% !important;
width: 100%;
border-radius: 6px;
left: 0;
top: auto;
padding-top: 0px;
background-color: #fff;
.vux-popup-header {
border-bottom: 1px solid rgba(0,0,0,.1) !important;
}
}
.show-select-up {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
.modal-open [vum-show-select] {
pointer-events: auto;
}
</style>
<script>
import assign from 'object-assign'
export default {
data() {
return {
defaultOptions: {
code: '',
list: [],
object: {},
index: 0
},
popupTitle: '',
cancelText: '取消',
confirmText: '确定',
code: '',
value: '',
name: '',
list: [],
object: {},
state: 0,
tempValue: [],
index: '',
callBack: null,
childs: {
index: '',
value: '',
name: '',
child: {
index: '',
value: '',
name: '',
}
}
}
},
mounted() {
this.$el.setAttribute('vum-show-select', '')
},
destroyed() {
document.body.removeChild(this.$el)
},
methods: {
show(options) {
let _options = assign({}, this.defaultOptions, options)
this.code = _options.code;
this.list = _options.list;
this.object = _options.object;
this.callBack = _options.callBack;
this.state = 1
},
returnItem(index) {
let vm = this;
if (index > -1) {
let code = vm.code;
let code_name = vm.code + '_n';
vm.object[code] = vm.value;
vm.object[code_name] = vm.name;
vm.callBack(vm.index, vm.object, vm.childs)
}
this.state = 0;
let wrapper = document.querySelector('[vum-show-select]')
wrapper.addEventListener('webkitTransitionEnd', () => {
this.$destroy()
}, false)
},
findIndex(list, value) {
let vm = this;
vum.forEach(list, function (date, index, array) {
if (date.value === value) {
vm.index = index;
vm.name = date.name;
return;
}
})
},
findChildIndex(list, value) {
let vm = this;
vum.forEach(list, function (date, index, array) {
if (date.value === value) {
vm.childs.index = index;
vm.childs.name = date.name;
return;
}
})
},
findChild2Index(list, value) {
let vm = this;
vum.forEach(list, function (date, index, array) {
if (date.value === value) {
vm.childs.child.index = index;
vm.childs.child.name = date.name;
return;
}
})
},
onPickerChange(val) {
let vm = this;
//联动时
//debugger;
if (val.length === 2) {
vm.childs.value = val[1];
this.findChildIndex(vm.list, val[1]);
vm.childs.child = {};
}
if (val.length === 3) {
vm.childs.value = val[1];
this.findChildIndex(vm.list, val[1]);
vm.childs.child.value = val[2];
this.findChild2Index(vm.list, val[2]);
}
if (val.length === 1) {
vm.childs = {}
}
vm.value = val[0];
this.findIndex(vm.list, vm.value);
}
}
}
</script>
<template>
<div class="show-select-backdrop" :class="{'active': state == 1}" @click="returnItem(-1)">
<h-content class="show-select-wrapper"
:class="{'show-select-up': state == 1}">
<div class="list">
<popup-header
:left-text="cancelText"
:right-text="confirmText"
@on-click-left="returnItem(-1)"
@on-click-right="returnItem(1)"
:title="popupTitle"></popup-header>
<picker
:data="list"
v-model="tempValue"
:columns="3"
@on-change="onPickerChange"
:key="index"
></picker>
</div>
</h-content>
</div>
</template>
<style lang="less" scoped>
.show-select-backdrop {
-webkit-transition: background-color 150ms ease-in-out;
transition: background-color 150ms ease-in-out;
position: fixed;
top: 0;
left: 0;
z-index: 999;
width: 100%;
height: 100%;
background-color: transparent;
.weui-tab {
width: 100%;
}
&.active {
background-color: rgba(0, 0, 0, 0.3);
}
.show-select-wrapper {
-webkit-transform: translate3d(0, 100%, 0);
transform: translate3d(0, 100%, 0);
-webkit-transition: all cubic-bezier(0.36, 0.66, 0.04, 1) 500ms;
transition: all cubic-bezier(0.36, 0.66, 0.04, 1) 500ms;
bottom: 0 !important;
position: absolute !important;
max-height: 50% !important;
width: 100%;
border-radius: 6px;
left: 0;
top: auto;
padding-top: 0px;
.list {
border: none;
//padding: 40px 0px 0px 0px;
width: 100%;
background-color: white;
.vux-popup-header {
border-bottom: 1px solid #ccc !important;
}
}
}
.show-select-up {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
.modal-open [vum-show-select] {
pointer-events: auto;
}
</style>
<script>
import assign from 'object-assign'
export default {
data() {
return {
defaultOptions: {
code: '',
list: [],
object: {},
index: 0
},
popupTitle: '',
cancelText: '取消',
confirmText: '确定',
code: '',
value: '',
name: '',
list: [],
object: {},
state: 0,
tempValue: [],
index: '',
callBack: null,
childs: {
index: '',
value: '',
name: '',
child: {
index: '',
value: '',
name: '',
}
}
}
},
mounted() {
this.$el.setAttribute('vum-show-select', '')
},
destroyed() {
document.body.removeChild(this.$el)
},
methods: {
show(options) {
let _options = assign({}, this.defaultOptions, options)
this.code = _options.code;
this.list = _options.list;
this.object = _options.object;
this.callBack = _options.callBack;
this.state = 1
},
returnItem(index) {
let vm = this;
if (index > -1) {
let code = vm.code;
let code_name = vm.code + '_n';
vm.object[code] = vm.value;
vm.object[code_name] = vm.name;
vm.callBack(vm.index, vm.object, vm.childs)
}
this.state = 0;
let wrapper = document.querySelector('[vum-show-select]')
wrapper.addEventListener('webkitTransitionEnd', () => {
this.$destroy()
}, false)
},
findIndex(list, value) {
let vm = this;
vum.forEach(list, function (date, index, array) {
if (date.value === value) {
vm.index = index;
vm.name = date.name;
return;
}
})
},
findChildIndex(list, value) {
let vm = this;
vum.forEach(list, function (date, index, array) {
if (date.value === value) {
vm.childs.index = index;
vm.childs.name = date.name;
return;
}
})
},
findChild2Index(list, value) {
let vm = this;
vum.forEach(list, function (date, index, array) {
if (date.value === value) {
vm.childs.child.index = index;
vm.childs.child.name = date.name;
return;
}
})
},
onPickerChange(val) {
let vm = this;
//联动时
//debugger;
if (val.length === 2) {
vm.childs.value = val[1];
this.findChildIndex(vm.list, val[1]);
vm.childs.child = {};
}
if (val.length === 3) {
vm.childs.value = val[1];
this.findChildIndex(vm.list, val[1]);
vm.childs.child.value = val[2];
this.findChild2Index(vm.list, val[2]);
}
if (val.length === 1) {
vm.childs = {}
}
vm.value = val[0];
this.findIndex(vm.list, vm.value);
}
}
}
</script>
showBigPicture查看大图 插件形式调用
```html
<h-button class="button-class" type="primary" @click.native="showBigPicture">showBigPicture</h-button>
showBigPicture() {
hlsPopup.showBigPicture({
imgUrl: 'http://hlsapp.hand-china.com/hls_file/2018/05/F1B6D85E409A4714A8540504B2D133AD'
})
},
```
import Vue from 'vue'
import ShowPicture from './showpicture.vue'
import elementUtil from '../../scripts/elementUtil.js'
class VueShowPicture {
constructor() {
this._vm = undefined
}
show(option) {
elementUtil.createElement('vum-show-picture')
this._vm = new Vue(ShowPicture)
this._vm.$mount('[vum-show-picture]')
setTimeout(() => {
this._vm.show(option)
})
}
hide() {
this._vm.hide()
}
getState() {
return this._vm ? this._vm.getState() : 0
}
}
export default new VueShowPicture()
<template>
<div class="show-picture show-picture-backdrop" :class="{'active': state == 1}">
<view-box>
<div class="content scroll-content ionic-scroll show-picture-wrapper"
:class="{'show-picture-up': state == 1}">
<div class="pad" ref="pad">
<img v-hls-img-zoom
:src="imgUrl"
:alt="imgTitle" v-tap="hide" v-longtap="sharePicture">
</div>
</div>
</view-box>
</div>
</template>
<style lang="less" scoped>
.show-picture-backdrop {
-webkit-transition: background-color 150ms ease-in-out;
transition: background-color 150ms ease-in-out;
position: fixed;
top: 0;
left: 0;
z-index: 999;
width: 100%;
height: 100%;
background-color: transparent;
.weui-tab {
width: 100%;
}
&.active {
background-color: rgba(0, 0, 0, 0.6);
}
.show-picture-wrapper {
-webkit-transform: translate3d(0, 100%, 0);
transform: translate3d(0, 100%, 0);
-webkit-transition: all cubic-bezier(0.36, 0.66, 0.04, 1) 500ms;
transition: all cubic-bezier(0.36, 0.66, 0.04, 1) 500ms;
position: absolute;
width: 100%;
//max-width: 500px;
height: 100%;
margin: auto;
display: flex;
display: -webkit-flex;
align-items: center;
-webkit-align-items: center;
justify-content: center;
-webkit-justify-content: center;
.pad {
//width: 100%;
//height: 100%;
display: -webkit-flex;
display: flex;
justify-content: center;
align-items: center;
-webkit-justify-content: center;
-webkit-align-items: center;
img {
width: 100%;
height: 100%;
display: -webkit-flex;
display: flex;
justify-content: center;
align-items: center;
-webkit-justify-content: center;
-webkit-align-items: center;
}
}
}
.show-picture-up {
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
.modal-open [vum-show-picture] {
pointer-events: auto;
}
</style>
<script>
import assign from 'object-assign'
export default {
data() {
return {
defaultOptions: {
imgUrl: '',
imgTitle: '',
index: '1',
width: '100'
},
imgUrl: '',
imgTitle: '',
index: '1',
state: 0,
width: '100'
}
},
mounted() {
this.$el.setAttribute('vum-show-picture', '')
},
destroyed() {
document.body.removeChild(this.$el)
},
methods: {
show(options) {
let vm = this;
let _options = assign({}, this.defaultOptions, options)
this.imgUrl = _options.imgUrl;
this.imgTitle = _options.imgTitle;
this.width = _options.width;
this.state = 1;
if (!this.width) {
this.width = 100;
}
vm.$refs.pad.style.width = this.width + '%'
},
hide() {
this.state = 0
let wrapper = document.querySelector('[vum-show-picture]')
wrapper.addEventListener('webkitTransitionEnd', () => {
this.$destroy()
}, false)
},
getState() {
return this.state
},
sharePicture() {
var reg = /(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?/;
window.plugins.socialsharing.share(null, null, this.imgUrl, null)
}
}
}
</script>
import FunctionItem from './FunctionItem/index'
export default (Vue) => {
Vue.component('function-item', FunctionItem)
}
......@@ -7,9 +7,8 @@ import App from './App'
import Vuex from 'vuex'
import vuexI18n from 'vuex-i18n'
/* import vconsole from 'vconsole';
let vConsole = new vconsole() */
import flexible from './common/ydui.flexible'
import components from './components/component'
import {componentInstall, appStyle} from 'hls-easy-ui'
/**
* 指令
......@@ -24,18 +23,10 @@ import filter from './scripts/filter'
// import component from './components/component.js'
import {
TransferDom,
ViewBox,
Tabbar,
TabbarItem,
XHeader,
Picker,
PopupHeader,
} from 'vux'
import './scripts/prototype'
import './scripts/vuePlatform'
/**
* 弹框组件
*/
......@@ -59,7 +50,13 @@ import Jpush from './scripts/jpushService'
import Jmessage from './scripts/jmessageService'
if (process.env.CONFIG_ENV === 'uat') {
const VConsole = require('vconsole')
new VConsole() // eslint-disable-line
}
Vue.use(componentInstall)
Vue.use(components)
Vue.use(appStyle)
Vue.use(flexible)
Vue.use(directives)
......@@ -69,13 +66,8 @@ Vue.use(filter)
// Vue.use(component)
Vue.use(Vuex)
Vue.directive('transfer-dom', TransferDom)
Vue.component('x-header', XHeader)
Vue.component('view-box', ViewBox)
Vue.component('tabbar', Tabbar)
Vue.component('tabbar-item', TabbarItem)
Vue.component('PopupHeader', PopupHeader)
Vue.component('picker', Picker)
/** i18n **/
let store = new Vuex.Store({
......@@ -159,7 +151,7 @@ vum.$vumPlatform.registerBackButtonAction(function (e) {
let time
let path = router.currentRoute.path
if (path == '/tab/home' || path == '/tab/allCar' || path == '/tab/message' || path == '/tab/my-info') {
if (path === '/tab/home' || path === '/tab/allCar' || path === '/tab/message' || path === '/tab/my-info') {
// 进入主界面清除缓存
if (backButtonPressedOnceToExit === true) {
vum.Platform.exitApp()
......@@ -171,7 +163,7 @@ vum.$vumPlatform.registerBackButtonAction(function (e) {
backButtonPressedOnceToExit = false
}, 1500)
}
} else if (path == '/login' || path == '/finger-login' || path == '/gesture') {
} else if (path === '/login' || path === '/finger-login' || path === '/gesture') {
vum.Platform.exitApp()
} else {
router.go(-1)
......
......@@ -8,7 +8,7 @@
<div class="userPicture">
<img :src="userPicture">
</div>
<div class="scan-img" @click="login"><img src="../assets/image/login/fingertip@2x.png"/></div>
<div class="scan-img" @click="login"><img src="../assets/image/login/fingertip@2x.png"></div>
</div>
<div class="finger-exist" @click="login">请验证已有指纹</div>
</div>
......@@ -19,60 +19,59 @@
</template>
<script>
export default {
data() {
export default {
data () {
return {
userPicture: window.localStorage.userImg
userPicture: window.localStorage.userImg,
}
},
created: function () {
let vm = this;
let vm = this
setTimeout(function () {
vm.login();
vm.login()
}, 2000)
},
methods: {
login: function () {
let vm = this;
let vm = this
vm.hlsUtil.fingerLogin().then(function () {
var username = window.localStorage.username;
var password = window.localStorage.password;
var netType = navigator.connection.type;
var username = window.localStorage.username
var password = window.localStorage.password
var netType = navigator.connection.type
if (netType == Connection.NONE) {
hlsPopup.showLongBottom('当前设备无网络连接请检查')
} else if (netType == Connection.CELL_2G || netType == Connection.CELL) {
hlsPopup.showLongBottom('当前设备网络连接较差请检查')
} else {
let url = process.env.loginPath + "appadmin";
let param = {};
vm.hlsPopup.showLoading('请稍等');
let url = process.env.loginPath + 'appadmin'
let param = {}
vm.hlsPopup.showLoading('请稍等')
vm.$post(url, param).then(function () {
vm.figinLogin(username, password);
});
vm.figinLogin(username, password)
})
}
})
},
figinLogin: function (username, password) {
let vm = this;
let vm = this
let param = {
'user_name': username,
'user_password': password
};
let url = process.env.basePath + 'login';
'user_password': password,
}
let url = process.env.basePath + 'login'
vm.$post(url, param)
.then(function (res) {
if (res.result === 'S') {
vm.hlsPopup.hideLoading();
window.localStorage.setItem('username', username.toUpperCase());
window.localStorage.setItem('password', password);
window.localStorage.setItem('user_id', res.user_id);
vm.$router.push('tab');
let tagOption={
"username":vm.userName.toUpperCase(),
"user_id":res.user_id,
"mobile":res.mobile
vm.hlsPopup.hideLoading()
window.localStorage.setItem('username', username.toUpperCase())
window.localStorage.setItem('password', password)
window.localStorage.setItem('user_id', res.user_id)
vm.$router.push('tab')
let tagOption = {
'username': vm.userName.toUpperCase(),
'user_id': res.user_id,
'mobile': res.mobile,
}
vm.Jpush._jpush_config(tagOption)
}
......@@ -84,14 +83,14 @@
buttonArray: ['用户名密码登录'],
callback: (index) => {
if (index === 0) {
this.$router.push({name: "Login"});
}
this.$router.push({name: 'Login'})
}
},
})
},
}
}
},
}
</script>
<style scoped lang="less" rel="stylesheet">
......
export default {
bannerList: [
{
pictureUrl: require('../assets/image/home/bannerWrap@2x.png'),
},
{
pictureUrl: require('../assets/image/home/bannerWrap2@2x.png'),
},
],
moduleSeparateList: [
{
'moduleId': 1,
'moduleCode': 'PARTNER',
'moduleName': '商业伙伴',
'moduleIcon': 'http://hlsapp.hand-china.com/file/hel_dev/function/partner@2x.png',
'roleId': 1,
'roleCode': 'ADMIN',
'roleName': '管理员',
'functions': [
{
'functionId': 1,
'functionCode': '110',
'functionName': '客户创建',
'functionIcon': 'http://hlsapp.hand-china.com/file/hel_dev/function/customerCreate@2x.png',
'functionState': 'PartnerCreate',
'prodFlag': 'Y',
'enableFlag': 'Y',
'functionType': 'local',
'target': null,
'applicationFlag': 'N',
'appCode': 'HLS_APP',
},
{
'functionId': 2,
'functionCode': '120',
'functionName': '客户维护',
'functionIcon': 'http://hlsapp.hand-china.com/file/hel_dev/function/customerMaintain@2x.png',
'functionState': 'PartnerList',
'prodFlag': 'Y',
'enableFlag': 'Y',
'functionType': 'local',
'target': null,
'applicationFlag': 'N',
'appCode': 'HLS_APP',
},
],
},
{
'moduleId': 2,
'moduleCode': 'PROJECT',
'moduleName': '项目申请',
'moduleIcon': 'http://hlsapp.hand-china.com/file/hel_dev/function/project@2x.png',
'roleId': 1,
'roleCode': 'ADMIN',
'roleName': '管理员',
'functions': [
{
'functionId': 3,
'functionCode': '210',
'functionName': '融资试算',
'functionIcon': 'http://hlsapp.hand-china.com/file/hel_dev/function/finaning-main@2x.png',
'functionState': 'CalculationEnter',
'prodFlag': 'Y',
'enableFlag': 'Y',
'functionType': 'local',
'target': null,
'applicationFlag': 'N',
'appCode': 'HLS_APP',
},
{
'functionId': 4,
'functionCode': '100',
'functionName': '租赁申请',
'functionIcon': 'http://hlsapp.hand-china.com/file/hel_dev/function/applyCreate@2x.png',
'functionState': 'PrjCreate',
'prodFlag': 'Y',
'enableFlag': 'Y',
'functionType': 'local',
'target': null,
'applicationFlag': 'N',
'appCode': 'HLS_APP',
},
{
'functionId': 5,
'functionCode': '130',
'functionName': '申请维护',
'functionIcon': 'http://hlsapp.hand-china.com/file/hel_dev/function/applyMaintain@2x.png',
'functionState': 'PrjMaintenList',
'prodFlag': 'Y',
'enableFlag': 'Y',
'functionType': 'local',
'target': null,
'applicationFlag': 'N',
'appCode': 'HLS_APP',
},
],
},
{
'moduleId': 3,
'moduleCode': 'CONTRACT',
'moduleName': '合同模块',
'moduleIcon': 'http://hlsapp.hand-china.com/file/hel_dev/function/contract@2x.png',
'roleId': 1,
'roleCode': 'ADMIN',
'roleName': '管理员',
'functions': [
{
'functionId': 6,
'functionCode': '400',
'functionName': '合同维护',
'functionIcon': 'http://hlsapp.hand-china.com/file/hel_dev/function/contractMaintain@2x.png',
'functionState': 'ContractMaintenList',
'prodFlag': 'Y',
'enableFlag': 'Y',
'functionType': 'local',
'target': null,
'applicationFlag': 'N',
'appCode': 'HLS_APP',
},
{
'functionId': 7,
'functionCode': '410',
'functionName': '合同签约',
'functionIcon': 'http://hlsapp.hand-china.com/file/hel_dev/function/contractSign@2x.png',
'functionState': 'ContractSignList',
'prodFlag': 'Y',
'enableFlag': 'Y',
'functionType': 'local',
'target': null,
'applicationFlag': 'N',
'appCode': 'HLS_APP',
},
],
},
{
'moduleId': 4,
'moduleCode': 'PERSONAL',
'moduleName': '个人办公',
'moduleIcon': 'http://hlsapp.hand-china.com/file/hel_dev/function/personWork@2x.png',
'roleId': 1,
'roleCode': 'ADMIN',
'roleName': '管理员',
'functions': [
{
'functionId': 8,
'functionCode': '160',
'functionName': '工作流',
'functionIcon': 'http://hlsapp.hand-china.com/file/hel_dev/function/workflow@2x.png',
'functionState': 'WorkflowList',
'prodFlag': 'Y',
'enableFlag': 'Y',
'functionType': 'local',
'target': null,
'applicationFlag': 'N',
'appCode': 'HLS_APP',
},
{
'functionId': 9,
'functionCode': '170',
'functionName': 'OCR',
'functionIcon': 'http://hlsapp.hand-china.com/file/hel_dev/function/ocr.png',
'functionState': 'OcrIdentify',
'prodFlag': 'Y',
'enableFlag': 'Y',
'functionType': 'local',
'target': null,
'applicationFlag': 'N',
'appCode': 'HLS_APP',
},
{
'functionId': 45,
'functionCode': '240',
'functionName': '报表',
'functionIcon': 'http://hlsapp.hand-china.com/file/hel_dev/function/chats@2x.png',
'functionState': 'Reports',
'prodFlag': 'Y',
'enableFlag': 'Y',
'functionType': 'local',
'target': null,
'applicationFlag': 'N',
'appCode': 'HLS_APP',
},
{
'functionId': 46,
'functionCode': '250',
'functionName': '启信宝',
'functionIcon': 'http://hlsapp.hand-china.com/file/hel_dev/function/qixinbao.png',
'functionState': 'QiXinBao',
'prodFlag': 'Y',
'enableFlag': 'Y',
'functionType': 'local',
'target': null,
'applicationFlag': 'N',
'appCode': 'HLS_APP',
},
],
},
],
}
<template>
<h-view id="home">
<h-content>
<section class="home-content">
这是首页
</section>
</h-content>>
<h-view id="home" class="public-style" title="车租易">
<h-content :cal-content="false" class="content scroll-content">
<div class="top-box">
<header class="header">
<input v-model="searchInput" placeholder="请输入功能名">
<img src="../assets/image/home/functionList@2x.png" @click="search">
</header>
<swipe :interval="5000" :showIndicators="false" class="swipe">
<swipe-item v-for="img in imgList" :key="img.pictureUrl">
<img :src="img.pictureUrl">
</swipe-item>
</swipe>
<div class="function">
<function-item
v-for="item in moduleSeparateList.slice(0,4)" :key="item.moduleId" :functionIcon="item.moduleIcon"
:functionName="item.moduleName"
:data="item" @clickFunction="goModuleFunction"/>
</div>
</div>
<div class="middle-box">
<header>常用应用</header>
<div class="function">
<function-item
v-for="item in functionList" :key="item.functionId" :functionIcon="item.functionIcon"
:functionName="item.functionName"
:data="item" class="function-item vue-1px" @clickFunction="goFunctionHome"/>
</div>
</div>
<div class="important-message">
<div class="important-message-title">重要消息</div>
<div class="important-message-title-icon">
<img src="../assets/image/home/messageIcon@2x.png">
</div>
<div id="scroll">
<ul id="p1">
<li v-for="item in messageList">{{ item.msg_body }}</li>
</ul>
<ul id="p2"/>
</div>
</div>
<div class="bank" style="height: 60px;width: 100%"></div>
</h-content>
</h-view>
</template>
<script>
import functionState from './functionState'
export default {
data () {
return {
imgList: [],
moduleSeparateList: [],
functionList: [], // 全部应用
messageList: [],
area: {},
box1: {},
box2: {},
searchInput: '',
}
},
beforeCreate: function () {
},
created: function () {
this.imgList = [...functionState.bannerList]
this.moduleSeparateList = [...functionState.moduleSeparateList]
this.moduleSeparateList.forEach(item => {
this.functionList = this.functionList.concat(item.functions)
})
},
updated: function () {
},
methods: {
search () {
let vm = this
let flag = 'N'
if (vm.searchInput) {
for (let i of vm.allFunctionList) {
if (vm.searchInput === i.functionName) {
vm.$router.push({
name: i.functionState,
})
flag = 'Y'
break
}
}
} else {
vm.hlsPopup.showLongCenter('请输入功能名称')
}
if (flag === 'N') {
vm.hlsPopup.showLongCenter('没有此功能')
}
},
goModuleFunction (data) {
this.$router.push({
name: 'ModuleFunction',
params: {
moduleFunctionList: data,
},
})
},
goFunctionHome (data) {
this.$router.push({
name: data.functionState,
})
},
},
}
</script>
<style lang="less" scoped type="text/less">
@import "../styles/mixin";
.home-content{
.wh(100%,100%);
.sc();
.fja()
}
@import "../styles/vue-1px";
#home {
.content{
margin-bottom: 40px;
}
.top-box {
height: 264px;
width: 100%;
overflow: hidden;
position: relative;
.header {
width: 100%;
height: 40px;
position: absolute;
top: 0;
z-index: 100;
input {
width: calc(~"100% - 53px");
height: 26px;
margin: 10px 0 0 10px;
background: white;
// border: 1px solid white;
border-radius: 15px;
text-align: center;
color: #B6B6B6;
font-size: 12px;
}
img {
width: 21px;
height: 21px;
position: absolute;
top: 12px;
right: 10px;
}
}
.hls-swipe {
height: 175px;
width: 100%;
overflow: hidden;
}
.function {
height: 117px;
width: 100%;
position: absolute;
bottom: 0;
background: url("../assets/image/home/moduleBg@2x.png");
Background-size: 100%;
padding-top: 43px;
display: flex;
justify-content: space-between;
&:before {
content: ''
}
&:after {
content: ''
}
.function-item {
text-align: center;
}
}
}
.middle-box {
margin-top: 8px;
background: white;
header {
height: 33px;
display: flex;
align-items: center;
line-height: 100%;
color: #5D98F6;
position: relative;
&:before {
content: '';
width: 4px;
height: 15px;
margin-right: 9px;
margin-left: 10px;
background-image: linear-gradient(-180deg, #5D98F6 0%, #76BCEE 100%);
border-radius: 2px;
}
&:after {
.setBottomLine()
}
span {
font-size: 12px;
color: #878A8D;
position: absolute;
right: 15px;
}
}
.function{
display: flex;
flex-wrap: wrap;
.function-item {
width: 25%;
height: 89px;
font-size: 12px;
// border: 1px solid rgba(169,169,169,0.1); /*no*/
/deep/ img {
height: 30px;
width: 30px;
margin: 23px 28px 9px 33px;
}
&:before {
.setBottomLine();
}
&:after {
.setRightLine();
}
}
}
}
.important-message {
width: 100%;
height: 42px;
margin-top: 8px;
background-color: #FFFFFF;
display: flex;
justify-content: flex-start;
align-items: center;
.important-message-title {
-webkit-flex: 0 0 20%;
flex: 0 0 20%;
max-width: 20%;
color: #E84A55;
font-size: 14px;
//margin-left: 3.2%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.important-message-title-icon {
height: 100%;
margin-left: 1%;
display: flex;
justify-content: flex-start;
align-items: center;
img {
width: 13px;
height: 12px;
}
}
#scroll {
height: 42px;
overflow: hidden;
margin-left: 5%;
}
#scroll li {
height: 42px;
color: #565656;
font-size: 13px;
line-height: 18px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
/*word-wrap: break-word;
word-break: break-all;
white-space: normal;*/
display: flex;
align-items: center;
margin-right: 10px;
}
}
}
.platform-ios{
#home{
.header{
top:20px
}
}
}
// iPhoneX适配
@media (device-width: 375px) and (device-height: 812px) and (-webkit-min-device-pixel-ratio: 3) {
.platform-ios{
#home{
.content{
margin-bottom: 74px;
}
.header{
top:40px
}
}
}
}
@media (device-width: 414px) and (device-height: 896px){
.platform-ios{
#home{
.content{
margin-bottom: 74px;
}
.header{
top:40px
}
}
}
}
</style>
<template>
<scroll ref="scroll" id="login" class="content">
<scroll id="login" ref="scroll" class="content">
<div>
<div class="bird-icon"><img src="../assets/image/login/bird-icon.png"/></div>
<div class="bird-icon"><img src="../assets/image/login/bird-icon.png"></div>
<div class="pwd">
<div class="pwd-icon"><img src="../assets/image/login/user.png"/></div>
<div class="pwd-input"><input type="text" placeholder="请输入用户名/手机号" v-model="username"/></div>
<div class="delete" v-if="username" @click="clearAccount"><img src="../assets/image/login/delete.png"/></div>
<div class="pwd-icon"><img src="../assets/image/login/user.png"></div>
<div class="pwd-input"><input v-model="username" type="text" placeholder="请输入用户名/手机号"></div>
<div v-if="username" class="delete" @click="clearAccount"><img src="../assets/image/login/delete.png"></div>
</div>
<div class="pwd">
<div class="pwd-icon"><img src="../assets/image/login/password.png"/></div>
<div class="pwd-input"><input type="password" placeholder="请输入密码" v-model="password"/></div>
<div class="delete" v-if="password" @click="clearPassword"><img src="../assets/image/login/delete.png"/></div>
<div class="pwd-icon"><img src="../assets/image/login/password.png"></div>
<div class="pwd-input"><input v-model="password" type="password" placeholder="请输入密码"></div>
<div v-if="password" class="delete" @click="clearPassword"><img src="../assets/image/login/delete.png"></div>
</div>
<div class="other-function">
<div class="register" @click="registerNew">用户注册</div>
......@@ -22,86 +22,82 @@
</template>
<script>
var CryptoJS = require("crypto-js");
export default {
data() {
var CryptoJS = require('crypto-js')
export default {
data () {
return {
username: window.localStorage.username ? window.localStorage.username : '',
password: '',
version: process.env.currentVersion,
routeName: this.$route.params.routeName || ''
routeName: this.$route.params.routeName || '',
}
},
methods: {
login: function () {
let vm = this;
//debugger;
//vm.password = CryptoJS.MD5(vm.password).toString().toUpperCase();
let md5passwprd = CryptoJS.MD5(vm.password).toString().toUpperCase();
let vm = this
// debugger;
// vm.password = CryptoJS.MD5(vm.password).toString().toUpperCase();
let md5passwprd = CryptoJS.MD5(vm.password).toString().toUpperCase()
let param = {
'user_name': vm.username,
'user_password': md5passwprd,
'platform': 'C'
};
'platform': 'C',
}
vm.$post(process.env.basePath + 'tc_app_login', param)
.then(function (res) {
if (res.result === 'S') {
vm.hlsPopup.hideLoading();
window.localStorage.setItem('username', vm.username.toUpperCase());
window.localStorage.setItem('password', md5passwprd);
window.localStorage.setItem('user_id', res.user_id);
vm.hlsPopup.hideLoading()
window.localStorage.setItem('username', vm.username.toUpperCase())
window.localStorage.setItem('password', md5passwprd)
window.localStorage.setItem('user_id', res.user_id)
if (res.bp_id && res.bp_id != 'undefined') {
window.localStorage.setItem('bp_id', res.bp_id);
window.localStorage.setItem('bp_id', res.bp_id)
}
//if (vm.routeName) {
// if (vm.routeName) {
// vm.$router.push({name: vm.routeName})
//} else {
vm.$router.push('tab');
//}
// } else {
vm.$router.push('tab')
// }
let tagOption = {
"username": vm.username.toUpperCase(),
"user_id": res.user_id
'username': vm.username.toUpperCase(),
'user_id': res.user_id,
}
vm.Jpush._jpush_config(tagOption)
}
//极光推送
// 极光推送
})
},
access: function () {
let vm = this;
let vm = this
if (!vm.username || vm.username === undefined) {
vm.hlsPopup.showLongCenter('请输入用户名');
}
else if (!vm.password || vm.password === undefined) {
vm.hlsPopup.showLongCenter('请输入密码');
}
else {
let url = process.env.loginPath + 'appadmin';
let param = {};
vm.hlsPopup.showLoading('请稍等');
vm.hlsPopup.showLongCenter('请输入用户名')
} else if (!vm.password || vm.password === undefined) {
vm.hlsPopup.showLongCenter('请输入密码')
} else {
let url = process.env.loginPath + 'appadmin'
let param = {}
vm.hlsPopup.showLoading('请稍等')
vm.$post(url, param).then(function (res) {
window.localStorage.setItem('access_token', res.access_token);
vm.login();
window.localStorage.setItem('access_token', res.access_token)
vm.login()
})
}
},
registerNew: function () {
this.$router.push('regiester');
this.$router.push('regiester')
},
pwdForgotten: function () {
this.$router.push('pwd-forgot');
this.$router.push('pwd-forgot')
},
clearAccount: function () {
this.username = '';
this.username = ''
},
clearPassword: function () {
this.password = '';
this.password = ''
},
}
}
},
}
</script>
<style lang="less" scoped type="text/less">
......@@ -251,4 +247,3 @@
}
}
</style>
......@@ -2,14 +2,13 @@
<div id="tab" style="height: 100%;width:100%;">
<transition>
<keep-alive>
<router-view v-if="$route.meta.keepAlive">
</router-view>
<router-view v-if="$route.meta.keepAlive"/>
</keep-alive>
</transition>
<transition>
<router-view v-if="!$route.meta.keepAlive"></router-view>
<router-view v-if="!$route.meta.keepAlive"/>
</transition>
<tabbar class="vux-tabbar" icon-class="vux-center" slot="bottom">
<tabbar slot="bottom" class="vux-tabbar" icon-class="vux-center">
<tabbar-item :link="{path:'/tab/home'}" :selected="$route.path === '/' || $route.path==='/tab/home'">
<img slot="icon-active" src="../assets/image/tab/home@2x.png">
<img slot="icon" src="../assets/image/tab/n_home@2x.png">
......@@ -31,49 +30,48 @@
</template>
<script>
export default {
export default {
components: {},
data() {
data () {
return {
pathList: [],
transitionName: ''
transitionName: '',
}
},
mounted() {
},
methods: {
tabClick() {
//console.log('click');
}
},
watch: { //监听路由变化
$route(to, from) {
watch: { // 监听路由变化
$route (to, from) {
if (this.pathList.includes(to.path)) {
const index = (this.pathList.findIndex(() => {
return from.path
}))
this.pathList.splice(index, 1)
this.$router.isBack = true;
}
else {
this.$router.isBack = true
} else {
this.pathList.push(to.path)
this.$router.isBack = false;
this.$router.isBack = false
}
if (to.path === '/tab/home') {
this.$router.isBack = true;
this.$router.isBack = true
this.pathList = []
}
let isBack = this.$router.isBack;
let isBack = this.$router.isBack
if (isBack) {
this.transitionName = 'router-slide-right'
} else {
this.transitionName = 'router-slide-left'
}
this.$router.isBack = false
}
}
}
},
},
mounted () {
},
methods: {
tabClick () {
// console.log('click');
},
},
}
</script>
<style lang="less" scoped>
......@@ -105,9 +103,16 @@
// iPhoneX适配
@media (device-width: 375px) and (device-height: 812px) and (-webkit-min-device-pixel-ratio: 3) {
.platform-ios.platform-cordova:not(.fullscreen) {
.platform-ios{
.weui-tabbar {
padding-bottom: 34px;
}
}
}
@media (device-width: 414px) and (device-height: 896px){
.platform-ios{
.weui-tabbar {
padding-bottom: 60px;
padding-bottom: 34px;
}
}
}
......
This diff is collapsed.
export default{
createElement :function(marker, tag) {
createElement: function (marker, tag) {
let el = document.createElement(tag || 'div')
el.setAttribute(marker, '')
document.body.appendChild(el)
},
removeElement:function (marker) {
removeElement: function (marker) {
let el = document.querySelector(marker) || document.querySelector(`[${marker}]`)
if (el)
document.body.removeChild(el)
if (el) { document.body.removeChild(el) }
},
timeout:function (duration = 0) {
timeout: function (duration = 0) {
return new Promise((resolve, reject) => {
setTimeout(resolve, duration);
setTimeout(resolve, duration)
})
}
},
}
export default (Vue) => {
Vue.filter('currency', function (val) {
if (!val) return '0.00';
if (!val) return '0.00'
var intPart = Number(val).toFixed(0); //获取整数部分
var intPartFormat = intPart.toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,'); //将整数部分逢三一断
var intPart = Number(val).toFixed(0) // 获取整数部分
var intPartFormat = intPart.toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,') // 将整数部分逢三一断
var floatPart = ".00"; //预定义小数部分
var value2Array = (val+'').split(".");
var floatPart = '.00' // 预定义小数部分
var value2Array = (val + '').split('.')
//=2表示数据有小数位
if (value2Array.length == 2) {
floatPart = value2Array[1].toString(); //拿到小数部分
// =2表示数据有小数位
if (value2Array.length === 2) {
floatPart = value2Array[1].toString() // 拿到小数部分
if (floatPart.length == 1) { //补0,实际上用不着
return intPartFormat + "." + floatPart + '0';
if (floatPart.length === 1) { // 补0,实际上用不着
return intPartFormat + '.' + floatPart + '0'
} else {
return intPartFormat + "." + floatPart;
return intPartFormat + '.' + floatPart
}
} else {
return intPartFormat + floatPart;
return intPartFormat + floatPart
}
})
Vue.filter('datetime', timestamp => {
function format (number) {
return number.toString().padStart(2, '0')
}
const date = new Date(Number.parseInt(timestamp, 10))
const YYYY = date.getFullYear()
const MM = date.getMonth() + 1
const DD = date.getDate()
const hh = date.getHours()
const mm = date.getMinutes()
const ss = date.getSeconds()
return `${YYYY}-${format(MM)}-${format(DD)} ${format(hh)}:${format(mm)}:${format(ss)}`
})
}
//引入axios
import axios from 'axios';
// 引入axios
import axios from 'axios'
import hlsPopup from './hlsPopup'
import router from '../router/index';
let cancel, promiseArr = {}
let vm = this;
const CancelToken = axios.CancelToken;
//请求拦截器
import router from '../router/index'
let promiseArr = {}
let cancel = {}
const CancelToken = axios.CancelToken
// 请求拦截器
axios.interceptors.request.use(config => {
//发起请求时,取消掉当前正在进行的相同请求
// 发起请求时,取消掉当前正在进行的相同请求
config.cancelToken = new CancelToken(c => {
cancel = c
})
if (promiseArr[config.url]) {
promiseArr[config.url]('操作取消')
promiseArr[config.url] = cancel
......@@ -19,98 +21,102 @@ axios.interceptors.request.use(config => {
}, error => {
return Promise.reject(error)
})
//响应拦截器即异常处理
// 响应拦截器即异常处理
axios.interceptors.response.use(response => {
if (process.env.debug) {
let postName = 'post';
console.log(postName + " success");
console.log(postName + " response " + JSON.stringify(response.data,'',2));
console.log(postName + " End!");
if ($config.debug) {
let postName = 'post'
console.log(postName + ' success')
console.log(postName + ' response ' + JSON.stringify(response.data, '', 2))
console.log(postName + ' End!')
}
if (response.data.result === 'E' || response.data.code === 'E') {
hlsPopup.hideLoading();
const err = {};
err.message = response.data.message;
hlsPopup.showError(err.message);
hlsPopup.hideLoading()
const err = {}
err.message = response.data.message
hlsPopup.showError(err.message)
return Promise.resolve(err)
} else {
return response.data;
return response.data
}
}, err => {
let vm = this;
if (err && err.response) {
switch (err.response.status) {
case 400:
err.message = '错误请求'
break;
break
case 401:
err.message = '登录已失效,请重新登录'
break;
break
case 403:
err.message = '拒绝访问'
break;
break
case 404:
err.message = '请求错误,未找到该资源'
break;
break
case 405:
err.message = '不支持的请求类型'
break;
break
case 408:
err.message = '请求超时'
break;
break
case 500:
err.message = '服务器端出错'
break;
break
case 501:
err.message = '网络未实现'
break;
break
case 502:
err.message = '网络错误'
break;
break
case 503:
err.message = '服务不可用'
break;
break
case 504:
err.message = '网络超时'
break;
break
case 505:
err.message = 'http版本不支持该请求'
break;
break
default:
err.message = `连接错误${err.response.status}`
}
} else {
err.message = "连接到服务器失败"
err.message = '连接到服务器失败'
}
if (err.response.status === 401) {
if (err.response && err.response.status === 401) {
hlsPopup.hideLoading()
hlsPopup.showPopup({
title: '登录失效,重新登录',
onConfirm: () => {
router.push({name: "Login"});
}
});
router.push({name: 'Login'})
},
})
} else {
hlsPopup.showError(err.message);
hlsPopup.hideLoading()
hlsPopup.showError(err.message)
}
return Promise.resolve(err)
})
axios.defaults.baseURL = '';
axios.defaults.timeout = 10000;
//get请求
axios.defaults.baseURL = ''
axios.defaults.timeout = 100000
// get请求
export function get (url) {
let param = {}
let headers = {};
let headers = {}
if (window.localStorage.access_token) {
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + window.localStorage.access_token
'Authorization': 'Bearer ' + window.localStorage.access_token,
}
}
else {
} else {
headers = {
'Content-Type': 'application/json'
'Content-Type': 'application/json',
}
}
if ($config.debug) {
let postName = 'GET'
console.log(postName + ' Start!')
console.log(postName + ' url ' + url)
}
return new Promise((resolve, reject) => {
axios({
......@@ -118,9 +124,6 @@ export function get (url) {
url,
headers: headers,
params: param,
cancelToken: new CancelToken(c => {
cancel = c
})
}).then(res => {
resolve(res)
}).catch(err => {
......@@ -128,27 +131,26 @@ export function get (url) {
})
})
}
//post请求
export function post(url, param) {
param.user_id = window.localStorage.user_id;
param.access_token = window.localStorage.access_token;
let headers = {};
// post请求
export function post (url, param) {
param.user_id = window.localStorage.user_id
param.access_token = window.localStorage.access_token
let headers = {}
if (window.localStorage.access_token) {
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + window.localStorage.access_token
'Authorization': 'Bearer ' + window.localStorage.access_token,
}
}
else {
} else {
headers = {
'Content-Type': 'application/json'
'Content-Type': 'application/json',
}
}
if (process.env.debug) {
if ($config.debug) {
let postName = 'POST'
console.log(postName + " Start!");
console.log(postName + " url " + url);
console.log(postName + " parameter " + JSON.stringify(param,'',2));
console.log(postName + ' Start!')
console.log(postName + ' url ' + url)
console.log(postName + ' parameter ' + JSON.stringify(param, '', 2))
}
return new Promise((resolve, reject) => {
axios({
......@@ -156,14 +158,10 @@ export function post(url, param) {
headers: headers,
url,
data: param,
cancelToken: new CancelToken(c => {
cancel = c
})
}).then(res => {
resolve(res)
}).catch(err => {
reject(err)
})
})
}
This diff is collapsed.
This diff is collapsed.
/**
* 一些帮助函数
* @author momoko
*/
/**
* 取URL上的参数
* @param {String} param 参数名
* @return {String}
*/
export function getUrlParam (param) {
const result = window.location.href.match(new RegExp('(\\?|&)' + param + '(\\[\\])?=([^&#]*)'))
return result ? result[3] : undefined
}
/**
* 动态插入 script to html
* @param url
* @param callback
*/
export function createScript (url, callback) {
const oScript = document.createElement('script')
oScript.type = 'text/javascript'
oScript.async = true
oScript.src = url
/**
* IE6/7/8 -- onreadystatechange
* IE9/10 -- onreadystatechange, onload
* Firefox/Chrome/Opera -- onload
*/
const isIE = !-[1,] // eslint-disable-line
if (isIE) {
// 判断IE8及以下浏览器
oScript.onreadystatechange = function () {
if (this.readyState === 'loaded' || this.readyState === 'complete') {
callback && callback()
}
}
} else {
// IE9及以上浏览器,Firefox,Chrome,Opera
oScript.onload = function () {
callback && callback()
}
}
document.body.appendChild(oScript)
}
/**
* 判断平台
* @return {String} 平台
*/
export function detectOS () {
const ua = navigator.userAgent.toLowerCase()
if (/MicroMessenger/i.test(ua)) {
return 'weixin'
} else if (/iPhone|iPad|iPod|iOS/i.test(ua)) {
return 'ios'
} else if (/Android/i.test(ua)) {
return 'android'
} else {
return 'other'
}
}
This diff is collapsed.
//@import '~vux/src/styles/reset.less';
//@import "animate";
//@import "variables";
//@import "../less/ionic";
//@import 'publicStyle';
//@import "ionic-public-style";
//@import "platform-iosx";
//@import "platform-ios";
.has-footer {
bottom: 44px;
.scrollContent{
padding-bottom: 45px;
}
}
.header-top {
margin-top: 34px;
}
.has-tabs {
.scrollContent{
padding-bottom: 50px;
}
bottom: 50px;
}
.spinner svg {
width: 28px;
height: 28px;
}
.public-style {
background-color: @background-color-gray;
width: 100%;
font-weight: inherit;
.bar.button.button-icon .icon:before, .bar .button.button-icon.icon-left:before, .bar .button.button-icon.icon-right:before, .bar .button.button-icon:before, .bar button.button-icon .icon:before, .bar button.button-icon.icon-left:before, .bar button.button-icon.icon-right:before, .bar button.button-icon:before {
padding-right: 4px;
padding-left: 4px;
font-size: 32px;
line-height: 32px;
}
.bar {
background-image: none;
padding: 5px 0;
height: 43px;
display: flex;
display: -webkit-flex;
align-items: center;
-webkit-align-items: center;
.title {
height: 43px;
min-width: 30px;
line-height: normal;
font-size: 17px;
display: flex;
display: -webkit-flex;
justify-content: center;
-webkit-justify-content: center;
align-items: center;
-webkit-align-items: center;
padding-top: 4px;
}
}
.header-bar {
background-color: #FFFFFF;
border-bottom: 1px solid rgba(0, 0, 0, 0.1); /*no*/
.buttons {
.button {
color: @headerColor;
font-size: 16px;
padding-left: 10px;
padding-right: 12.5px;
}
}
.title {
color: #4A4A4A;
font-size: 17px;
//font-weight: 600;
left: 0 !important;
right: 0 !important;
}
.iconLeft {
text-align: left;
i {
font-size: 12.5px;
padding-left: 5px;
}
}
}
.bar-custom {
background-color: @headerColor;
border-bottom: none;
.buttons {
.button {
color: #ffffff;
}
}
.title {
color: #ffffff;
}
}
// ion-list he ion-item公用样式 -
.content {
//padding-top: 2px;
width: 100%;
}
.list {
background-color: #ffffff;
//border-bottom: 1px solid rgba(0, 0, 0, 0.10);
margin-bottom: 10px;
.item:last-child {
.contents {
border-bottom: none;
}
}
.item.activated {
//background-color:not();
opacity: 0.8;
-webkit-transform: scale(1,1);
transform: scale(1,1)
}
.item {
height: 45px;
border: none;
padding: 0 0 0 15px;
.contents {
height: 100%;
width: 100%;
border-bottom: 1px solid rgba(0, 0, 0, 0.10);
float: right;
display: -webkit-flex;
display: flex;
justify-content: space-between;
align-items: center;
-webkit-justify-content: space-between;
-webkit-align-items: center;
padding: 0 15px 0 0;
&.activated {
opacity: 0.9;
-webkit-transform: scale(0.95);
transform: scale(0.95)
}
.add-name {
display: -webkit-flex;
display: flex;
justify-content: flex-start;
align-items: center;
-webkit-justify-content: flex-start;
-webkit-align-items: center;
letter-spacing: 0;
line-height: 16px;
font-size: @font-size-big;
color: #838E94;
letter-spacing: 0;
text-align: center;
.left-icon {
margin-right: 10px;
}
.required {
display: flex;
}
.required::after {
content: '*';
color: #D24E4E;
height: 8px;
padding-top: 4px;
margin-left: 2.5px;
}
}
.add-content {
display: -webkit-flex;
display: flex;
justify-content: flex-end;
align-items: center;
-webkit-justify-content: flex-end;
-webkit-align-items: center;
width: 100%;
font-size: @font-size-middle;
color: #666666;
height: 100%;
white-space: normal;
word-break: break-all;
word-wrap: break-word;
line-height: 20px;
//输入框
input {
font-size: @font-size-middle;
color: #666666;
line-height: normal;
width: 100%;
text-align: right;
border: none;
}
//右侧图标
.right-icon {
margin-left: 10px;
}
//toggle
.toggle-check {
display: -webkit-flex;
display: flex;
-webkit-justify-content: space-between;
justify-content: space-between;
-webkit-align-items: center;
align-items: center;
.track {
width: 40px;
height: 25px;
margin-right: 2.5px;
border-radius: 15px;
.handle {
width: 22.5px;
height: 22.5px;
top: 3.5px;
left: 2.5px;
}
}
}
.toggle.toggle-positive input:checked + .track {
border-color: @check-box-bg;
background-color: @check-box-bg;
.handle {
width: 22.5px;
height: 22.5px;
top: 3.5px;
left: 9px;
}
}
}
}
}
}
.bottom-tab {
height: 44px;
width: 100%;
background-color: #fff;
position: fixed;
bottom: 0;
display: -webkit-flex;
display: flex;
align-items: center;
justify-content: center;
-webkit-align-items: center;
-webkit-justify-content: center;
-webkit-box-shadow: 0 -1px 1px rgb(234, 235, 236); /*no*/
box-shadow: 0 -1px 1px rgb(226, 229, 231); /*no*/
.bottom-tab-button {
width: 100%;
height: 100%;
display: -webkit-flex;
display: flex;
align-items: center;
justify-content: center;
-webkit-align-items: center;
-webkit-justify-content: center;
font-size: @font-size-big;
&.activated {
opacity: 0.8;
-webkit-transform: scale(1,1);
transform: scale(1,1)
}
}
.bottom-tab-divider {
width: 2px; /*no*/
height: 30px;
background-color: rgb(214, 217, 218);
}
}
}
@media (min-width: 680px) {
.modal {
top: 0;
right: 0 !important;
left: 0 !important;
bottom: 0 !important;
//height: 100%;
position: absolute !important;
width: 100% !important;
}
}
@media (min-width: 680px) {
.active .modal-backdrop-bg {
opacity: .1;
}
}
.platform-ios {
.bar .title + .buttons {
top: auto;
bottom: 12px;
}
.has-header {
top: @iosHasHeader;
}
.header-top {
margin-top: 63px;
}
.img {
margin-top: 10px;
}
.bar {
background-image: none;
padding: 5px 0 5px 0;
height: 64px !important;
display: flex;
display: -webkit-flex;
align-items: center;
-webkit-align-items: center;
.title {
height: 48px;
min-width: 30px;
line-height: 48px;
font-size: 17px;
display: flex;
display: -webkit-flex;
justify-content: center;
-webkit-justify-content: center;
align-items: center;
-webkit-align-items: center;
margin-top: 4px;
}
}
.content {
.list {
.item {
.contents {
.add-name {
.required::after {
content: '*';
color: #D24E4E;
position: absolute;
top: 0;
right: -8px;
height: 8px;
padding-top: 2px;
}
}
}
}
}
}
}
// iPhoneX适配
@media (device-width: 375px) and (device-height: 812px) and (-webkit-min-device-pixel-ratio: 3) {
.platform-ios{
.has-header {
top: 79px
}
.has-tabs {
bottom: 84px;
}
.has-footer{
margin-bottom: @bottomSafeArea;
}
.public-style {
.bottom-tab{
height: 78px;
padding-bottom: @bottomSafeArea;
}
}
}
}
.public-style {
.h-header .h-header-left .h-header-btn:first-of-type{
padding-left: 20px;
}
.bar-custom {
background-color: @theme-color
}
}
// iPhoneX适配
@media (device-width: 375px) and (device-height: 812px) and (-webkit-min-device-pixel-ratio: 3) {
.platform-ios{
.has-header {
top: 79px
}
.has-tabs {
bottom: 84px;
}
.has-footer{
margin-bottom: @bottomSafeArea;
}
.public-style {
.bottom-tab{
height: 78px;
padding-bottom: @bottomSafeArea;
}
}
}
}
This diff is collapsed.
......@@ -64,21 +64,3 @@
transform: scale(0.5);
}
// 宽高
.wh(@width,@height){
width: @width;
height: @height;
}
// 字体大小,颜色
.sc(@size:12px, @color:#ccc){
font-size: @size;
color: @color;
}
//flex 布局和子元素水平垂直对齐方式
.fja(@jtype:center,@atype:center){
display: flex;
justify-content: @jtype;
align-items: @atype;
}
This diff is collapsed.
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 to comment