Commit c1a4c4f1 authored by Nature's avatar Nature

h-view title

parent bbbe5094
...@@ -20,12 +20,21 @@ export default { ...@@ -20,12 +20,21 @@ export default {
type: Boolean, type: Boolean,
default: true, default: true,
}, },
title: {
type: String,
default: '',
},
}, },
data () { data () {
return { return {
isIos: false, isIos: false,
} }
}, },
mounted () {
if (this.title) {
document.title = this.title
}
},
created () { created () {
this.fullScreen && detectOS() === 'ios' && (this.isIos = true) this.fullScreen && detectOS() === 'ios' && (this.isIos = true)
}, },
......
...@@ -9,8 +9,14 @@ import router from './router/index' ...@@ -9,8 +9,14 @@ import router from './router/index'
import flexible from './common/ydui.flexible' import flexible from './common/ydui.flexible'
import {componentInstall, appStyle, hlsUtil, get, post, hlsPopup, directives, filter} from '../packages/index' import {componentInstall, appStyle} from '../packages/index'
/**
* 指令
*/
import directives from './scripts/directives'
import filter from './scripts/filter'
/** /**
* 组件 * 组件
*/ */
...@@ -27,6 +33,20 @@ import { ...@@ -27,6 +33,20 @@ import {
import './scripts/prototype' import './scripts/prototype'
import './scripts/vuePlatform' import './scripts/vuePlatform'
/**
* 弹框组件
*/
import hlsPopup from './scripts/hlsPopup'
/**
* http
*/
import {post, get} from './scripts/hlsHttp'
/** 全局函数hlsUtil**/
import hlsUtil from './scripts/hlsUtil'
/** end**/ /** end**/
if (process.env.CONFIG_ENV === 'uat') { if (process.env.CONFIG_ENV === 'uat') {
......
<template> <template>
<h-view class="public-style hls-popup" style="height: 100%"> <h-view class="public-style hls-popup" style="height: 100%" title="封装测试">
<h-header class="bar-custom"> <h-header class="bar-custom">
<div slot="left" class="h-header-btn" @click="$routeGo()"> <div slot="left" class="h-header-btn" @click="$routeGo()">
<i class="ion-ios-arrow-back"/> <i class="ion-ios-arrow-back"/>
......
<template> <template>
<h-view id="home" class="public-style"> <h-view id="home" class="public-style" title="小易">
<h-header :has-border="false" class="bar-custom"> <h-header :has-border="false" class="bar-custom">
<div slot="left" class="h-header-btn" @click="$hlsExit()"> <div slot="left" class="h-header-btn" @click="$hlsExit()">
<i class="ion-ios-arrow-back"/> <i class="ion-ios-arrow-back"/>
......
import Autosize from 'autosize'
function vueTouch (el, binding, type) {
var _this = this
this.obj = el
this.binding = binding
this.touchType = type
this.vueTouches = {x: 0, y: 0}
this.vueMoves = true
this.vueLeave = true
this.longTouch = true
this.vueCallBack = typeof (binding.value) === 'object' ? binding.value.fn : binding.value
this.obj.addEventListener('touchstart', function (e) {
_this.start(e)
}, false)
this.obj.addEventListener('touchend', function (e) {
_this.end(e)
}, false)
this.obj.addEventListener('touchmove', function (e) {
_this.move(e)
}, false)
};
vueTouch.prototype = {
start: function (e) {
this.vueMoves = true
this.vueLeave = true
this.longTouch = true
this.vueTouches = {x: e.changedTouches[0].pageX, y: e.changedTouches[0].pageY}
this.time = setTimeout(function () {
if (this.vueLeave && this.vueMoves) {
this.touchType === 'longtap' && this.vueCallBack(this.binding.value, e)
this.longTouch = false
}
}.bind(this), 1000)
},
end: function (e) {
var disX = e.changedTouches[0].pageX - this.vueTouches.x
var disY = e.changedTouches[0].pageY - this.vueTouches.y
clearTimeout(this.time)
if (Math.abs(disX) > 100 || Math.abs(disY) > 100) {
this.touchType === 'swipe' && this.vueCallBack(this.binding.value, e)
if (Math.abs(disX) > Math.abs(disY)) {
if (disX > 100) {
this.touchType === 'swiperight' && this.vueCallBack(this.binding.value, e)
}
if (disX < -100) {
this.touchType === 'swipeleft' && this.vueCallBack(this.binding.value, e)
}
} else {
if (disY > 100) {
this.touchType === 'swipedown' && this.vueCallBack(this.binding.value, e)
}
if (disY < -100) {
this.touchType === 'swipeup' && this.vueCallBack(this.binding.value, e)
}
}
} else {
if (this.longTouch && this.vueMoves) {
this.touchType === 'tap' && this.vueCallBack(this.binding.value, e)
this.vueLeave = false
}
}
},
move: function (e) {
this.vueMoves = false
},
} // prop.autosize
export default (Vue) => {
Vue.directive('focus', {
// 自动获取鼠标焦点
inserted: function (el) {
el.focus()
},
})
Vue.directive('tap', {// 点击事件
bind: function (el, binding) {
new vueTouch(el, binding, 'tap') // eslint-disable-line
},
})
Vue.directive('swipe', {// 滑动事件
bind: function (el, binding) {
new vueTouch(el, binding, 'swipe') // eslint-disable-line
},
})
Vue.directive('swipeleft', {// 左滑事件
bind: function (el, binding) {
new vueTouch(el, binding, 'swipeleft') // eslint-disable-line
},
})
Vue.directive('swiperight', {// 右滑事件
bind: function (el, binding) {
new vueTouch(el, binding, 'swiperight') // eslint-disable-line
},
})
Vue.directive('swipedown', {// 下滑事件
bind: function (el, binding) {
new vueTouch(el, binding, 'swipedown') // eslint-disable-line
},
})
Vue.directive('swipeup', {// 上滑事件
bind: function (el, binding) {
new vueTouch(el, binding, 'swipeup') // eslint-disable-line
},
})
Vue.directive('longtap', {// 长按事件
bind: function (el, binding) {
new vueTouch(el, binding, 'longtap') // eslint-disable-line
},
})
Vue.directive('hlsImgZoom', {
componentUpdated: function (element) {
var elWidth, elHeight
// mode : 'pinch' or 'swipe'
var mode = ''
// distance between two touche points (mode : 'pinch')
var distance = 0
var initialDistance = 0
// image scaling
var scale = 1
var relativeScale = 1
var initialScale = 1
var maxScale = 5
if (isNaN(maxScale) || maxScale <= 1) {
maxScale = 3
}
// position of the upper left corner of the element
var positionX = 0
var positionY = 0
var initialPositionX = 0
var initialPositionY = 0
// central origin (mode : 'pinch')
var originX = 0
var originY = 0
// start coordinate and amount of movement (mode : 'swipe')
var startX = 0
var startY = 0
var moveX = 0
var moveY = 0
var image = new Image()
image.onload = function () {
elWidth = element.clientWidth
elHeight = element.clientHeight
element.style.webkitTransformOrigin = '0px 0px 0px'
element.style.transformOrigin = '0px 0px 0px'
element.addEventListener('touchstart', touchstartHandler)
element.addEventListener('touchmove', touchmoveHandler)
element.addEventListener('touchend', touchendHandler)
}
image.src = element.src
/**
* @param {object} evt
*/
function touchstartHandler (evt) {
var touches = evt.originalEvent ? evt.originalEvent.touches : evt.touches
startX = touches[0].clientX
startY = touches[0].clientY
initialPositionX = positionX
initialPositionY = positionY
moveX = 0
moveY = 0
}
/**
* @param {object} evt
*/
function touchmoveHandler (evt) {
var touches = evt.originalEvent ? evt.originalEvent.touches : evt.touches
if (mode === '') {
if (touches.length === 1 && scale > 1) {
mode = 'swipe'
} else if (touches.length === 2) {
mode = 'pinch'
initialScale = scale
initialDistance = getDistance(touches)
originX = touches[0].clientX -
parseInt((touches[0].clientX - touches[1].clientX) / 2, 10) -
element.offsetLeft - initialPositionX
originY = touches[0].clientY -
parseInt((touches[0].clientY - touches[1].clientY) / 2, 10) -
element.offsetTop - initialPositionY
}
}
if (mode === 'swipe') {
evt.preventDefault()
moveX = touches[0].clientX - startX
moveY = touches[0].clientY - startY
positionX = initialPositionX + moveX
positionY = initialPositionY + moveY
transformElement()
} else if (mode === 'pinch') {
evt.preventDefault()
distance = getDistance(touches)
relativeScale = distance / initialDistance
scale = relativeScale * initialScale
positionX = originX * (1 - relativeScale) + initialPositionX + moveX
positionY = originY * (1 - relativeScale) + initialPositionY + moveY
transformElement()
}
}
/**
* @param {object} evt
*/
function touchendHandler (evt) {
var touches = evt.originalEvent ? evt.originalEvent.touches : evt.touches
if (mode === '' || touches.length > 0) {
return
}
if (scale < 1) {
scale = 1
positionX = 0
positionY = 0
} else if (scale > maxScale) {
scale = maxScale
relativeScale = scale / initialScale
positionX = originX * (1 - relativeScale) + initialPositionX + moveX
positionY = originY * (1 - relativeScale) + initialPositionY + moveY
} else {
if (positionX > 0) {
positionX = 0
} else if (positionX < elWidth * (1 - scale)) {
positionX = elWidth * (1 - scale)
}
if (positionY > 0) {
positionY = 0
} else if (positionY < elHeight * (1 - scale)) {
positionY = elHeight * (1 - scale)
}
}
transformElement(0.1)
mode = ''
}
/**
* @param {Array} touches
* @return {number}
*/
function getDistance (touches) {
var d = Math.sqrt(Math.pow(touches[0].clientX - touches[1].clientX, 2) +
Math.pow(touches[0].clientY - touches[1].clientY, 2))
return parseInt(d, 10)
}
/**
* @param {number} [duration]
*/
function transformElement (duration) {
var transition = duration ? 'all cubic-bezier(0,0,.5,1) ' + duration + 's' : ''
var matrixArray = [scale, 0, 0, scale, positionX, positionY]
var matrix = 'matrix(' + matrixArray.join(',') + ')'
element.style.webkitTransition = transition
element.style.transition = transition
element.style.webkitTransform = matrix + ' translate3d(0,0,0)'
element.style.transform = matrix + ' translate3d(0,0,0)'
}
},
})
Vue.directive('keyboardAttach', {// 监听键盘
inserted: function (el, binding) {
let KEYBOARD_OPEN_CSS = 'foot-keyboard-open'
function keyboardHeight () {
let innerHeight = window.innerHeight
let innerWidth = window.innerWidth
if (vum.Platform.isIOS()) {
if (!vum.Platform.isWebView()) {
return 266
}
if (innerWidth >= 375 && innerHeight >= 812) {
return 330
}
return 300
} else {
return 275
}
}
let height = keyboardHeight()
function hasClass (element, csName) {
return element.className.match(RegExp('(\\s|^)' + csName + '(\\s|$)'))
}
function addClass (element, csName) {
if (!hasClass(element, csName)) {
element.className += ' ' + csName
}
element.style.marginBottom = height + 'px'
}
function removeClass (element, csName) {
if (hasClass(element, csName)) {
element.classList.remove(csName)
}
element.style.marginBottom = 0 + 'px'
}
window.addEventListener('native.keyboardshow', function (e) {
addClass(el, KEYBOARD_OPEN_CSS)
})
window.addEventListener('native.keyboardhide', function (e) {
removeClass(el, KEYBOARD_OPEN_CSS)
})
},
unbind: function (el, binding) {
let KEYBOARD_OPEN_CSS = 'foot-keyboard-open'
function hasClass (element, csName) {
return element.className.match(RegExp('(\\s|^)' + csName + '(\\s|$)'))
}
function removeClass (element, csName) {
if (hasClass(element, csName)) {
element.classList.remove(csName)
}
element.style.marginBottom = 0 + 'px'
}
removeClass(el, KEYBOARD_OPEN_CSS)
window.removeEventListener('native.keyboardshow', function (e) {
})
window.removeEventListener('native.keyboardhide', function (e) {
})
},
})
Vue.directive('autoSize', {
bind: function (el, binding) {
if (el.nodeName === 'TEXTAREA') {
Autosize(el)
}
el.addEventListener('oninput', function (e) {
Autosize.update(el)
})
},
unbind: function (el, binding) {
Autosize.update(el)
Autosize.destroy(el)
el.removeEventListener('oninput', function (e) {
})
},
})
}
export default (Vue) => {
Vue.filter('currency', function (val) {
if (!val) return '0.00'
var intPart = Number(val).toFixed(0) // 获取整数部分
var intPartFormat = intPart.toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,') // 将整数部分逢三一断
var floatPart = '.00' // 预定义小数部分
var value2Array = (val + '').split('.')
// =2表示数据有小数位
if (value2Array.length === 2) {
floatPart = value2Array[1].toString() // 拿到小数部分
if (floatPart.length === 1) { // 补0,实际上用不着
return intPartFormat + '.' + floatPart + '0'
} else {
return intPartFormat + '.' + floatPart
}
} else {
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'
import hlsPopup from './hlsPopup'
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
} else {
promiseArr[config.url] = cancel
}
return config
}, error => {
return Promise.reject(error)
})
// 响应拦截器即异常处理
axios.interceptors.response.use(response => {
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)
return Promise.resolve(err)
} else {
return response.data
}
}, err => {
if (err && err.response) {
switch (err.response.status) {
case 400:
err.message = '错误请求'
break
case 401:
err.message = '登录已失效,请重新登录'
break
case 403:
err.message = '拒绝访问'
break
case 404:
err.message = '请求错误,未找到该资源'
break
case 405:
err.message = '不支持的请求类型'
break
case 408:
err.message = '请求超时'
break
case 500:
err.message = '服务器端出错'
break
case 501:
err.message = '网络未实现'
break
case 502:
err.message = '网络错误'
break
case 503:
err.message = '服务不可用'
break
case 504:
err.message = '网络超时'
break
case 505:
err.message = 'http版本不支持该请求'
break
default:
err.message = `连接错误${err.response.status}`
}
} else {
err.message = '连接到服务器失败'
}
if (err.response && err.response.status === 401) {
hlsPopup.hideLoading()
hlsPopup.showPopup({
title: '登录失效,重新登录',
onConfirm: () => {
},
})
} else {
hlsPopup.hideLoading()
hlsPopup.showError(err.message)
}
return Promise.resolve(err)
})
axios.defaults.baseURL = ''
axios.defaults.timeout = 10000
// get请求
export function get (url) {
let param = {}
let headers = {}
if (window.localStorage.access_token) {
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + window.localStorage.access_token,
}
} else {
headers = {
'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({
method: 'get',
url,
headers: headers,
params: param,
}).then(res => {
resolve(res)
}).catch(err => {
reject(err)
})
})
}
// 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,
}
} else {
headers = {
'Content-Type': 'application/json',
}
}
if ($config.debug) {
let postName = 'POST'
console.log(postName + ' Start!')
console.log(postName + ' url ' + url)
console.log(postName + ' parameter ' + JSON.stringify(param, '', 2))
}
return new Promise((resolve, reject) => {
axios({
method: 'post',
headers: headers,
url,
data: param,
}).then(res => {
resolve(res)
}).catch(err => {
reject(err)
})
})
}
import Vue from 'vue'
import {ToastPlugin, AlertPlugin, ConfirmPlugin, LoadingPlugin, DatetimePlugin} from 'vux'
import {ActionSheetPlugin, ShowPicturePlugin, SelectPlugin, NotifyPlugin, HlsModalPlugin, NumberKeyboardPlugin} from '../../packages/index'
Vue.use(ToastPlugin)
Vue.use(AlertPlugin)
Vue.use(ConfirmPlugin)
Vue.use(LoadingPlugin)
Vue.use(DatetimePlugin)
Vue.use(ActionSheetPlugin)
Vue.use(ShowPicturePlugin)
Vue.use(SelectPlugin)
Vue.use(NumberKeyboardPlugin)
Vue.use(NotifyPlugin)
Vue.use(HlsModalPlugin)
export default {
isLoading: false,
SHOW_TIMES: 2000,
IS_SHOW_MASK: true,
/**
* 锁屏函数 超过10s后自动解屏用于防止屏幕锁死
* 自动截屏成弹出错误提示框
* @param content 锁屏内容
*/
showLoading: function (content) {
let vm = this
Vue.$vux.loading.show({
text: content || 'Loading',
})
this.isLoading = true
// 10s后自动解屏用于防止屏幕锁死
setTimeout(() => {
if (vm.isLoading) {
Vue.$vux.loading.hide()
vm.isLoading = false
// 弹出操作失败
/* Vue.$vux.toast.show({
text: '操作失败',
type: 'warn',
time: vm.SHOW_TIMES,
isShowMask: vm.IS_SHOW_MASK,
position: 'middle',
}) */
}
}, 10000)
},
/**
* 隐藏
*/
hideLoading: function () {
Vue.$vux.loading.hide()
this.isLoading = false
},
/**
* 长时间顶部提示toast
* @param content
*/
showLongTop: function (content) {
let vm = this
let text = content || '操作失败'
if (!process.env.isMobilePlatform) {
Vue.$vux.toast.show({
text: text,
type: 'text',
time: vm.SHOW_TIMES,
isShowMask: vm.IS_SHOW_MASK,
position: 'top',
})
} else {
window.plugins.toast.showLongTop(content, function (success) {
}, function (error) { // eslint-disable-line
})
}
},
/**
* 长时间中部提示toast
* @param content
*/
showLongCenter: function (content) {
let vm = this
let text = content || '操作失败'
if (!process.env.isMobilePlatform) {
Vue.$vux.toast.show({
text: text,
type: 'text',
time: vm.SHOW_TIMES,
isShowMask: vm.IS_SHOW_MASK,
position: 'middle',
})
} else {
window.plugins.toast.showLongCenter(content, function (success) {
}, function (error) { // eslint-disable-line
})
}
},
/**
* 长时间中部提示toast
* @param content
*/
showLongBottom: function (content) {
let vm = this
let text = content || '操作失败'
if (!process.env.isMobilePlatform) {
Vue.$vux.toast.show({
text: text,
time: vm.SHOW_TIMES,
type: 'text',
isShowMask: vm.IS_SHOW_MASK,
position: 'bottom',
})
} else {
window.plugins.toast.showLongBottom(content, function (success) {
}, function (error) { // eslint-disable-line
})
}
},
/**
* 成功提示框
* @param content
*/
showSuccess: function (content) {
let vm = this
Vue.$vux.toast.show({
text: content || '操作成功',
time: vm.SHOW_TIMES,
isShowMask: vm.IS_SHOW_MASK,
type: 'success',
position: 'middle',
})
},
/**
* 成功提示框
* @param content
*/
showError: function (content) {
let vm = this
Vue.$vux.toast.show({
text: content || '操作失败',
type: 'warn',
isShowMask: vm.IS_SHOW_MASK,
time: vm.SHOW_TIMES,
position: 'middle',
})
},
/**
* 弹出是否确认的窗口
* @param confirmObject.title 标题
* @param confirmObject.content 内容
* @param confirmObject.onConfirm 确定函数
*/
showConfirm: function (confirmObject) {
if (!process.env.isMobilePlatform) {
let def = {
title: confirmObject.title || '提示',
content: confirmObject.content || '',
confirmText: '确定',
cancelText: '取消',
onConfirm: () => {
confirmObject.onConfirm(1)
},
onCancel: () => {
confirmObject.onConfirm(0)
},
}
Vue.$vux.confirm.show(def)
} else {
let message = confirmObject.content || ''
let onConfirm = function (index) {
confirmObject.onConfirm(index)
}
let title = confirmObject.title
navigator.notification.confirm(
message, // message
function (index) {
onConfirm(index - 1)
},
title, // title
['取消', '确定'] // buttonLabels
)
}
},
/*
* 弹出确认的窗口
* @param confirmObject.title 标题
* @param confirmObject.content 内容
* @param confirmObject.onConfirm 确定函数
*
*/
showPopup: function (confirmObject) {
if (!process.env.isMobilePlatform) {
let def = {
title: confirmObject.title || '提示',
content: confirmObject.content || '',
confirmText: '确定',
showCancelButton: false,
onConfirm: () => {
confirmObject.onConfirm()
},
}
Vue.$vux.confirm.show(def)
} else {
var alertDismissed = function (index) {
confirmObject.onConfirm()
}
let title = confirmObject.title || '提示'
var message = confirmObject.content || ''
navigator.notification.alert(
message, // message
alertDismissed, // callback
title || '提示', // title
'确定' // buttonName
)
}
},
/**
* @param actionObject.titleText 弹出框的标题可空
* @param actionObject.callback 点击按钮的回调函数 回传buttonArray数组下标
* @param actionObject.buttonArray 按钮数组支持[string,string],[object,object],
* 当为后一种是 object为{text:'拍照',type:'primary'},type支持 primary,warn,disabled
*
* {
* titleText: '照片',
* buttonArray: [{text:'拍照',type:'warn'}, {text:'从相册取',type:'primary'}],
* callback: (index) => {
* alert(index);
* }
* }
*
* {
* buttonArray: ['拍照','从相册取'],
* callback: (index) => {
* alert(index);
* }
* }
*
*/
showActionSheet: function (actionObject) {
if (typeof actionObject === 'object') {
let buttons = []
for (let i = 0; i < actionObject.buttonArray.length; i++) {
if (typeof actionObject.buttonArray[i] === 'object') {
buttons.push({
text: actionObject.buttonArray[i].text,
type: actionObject.buttonArray[i].type,
callback: actionObject.callback,
})
} else {
buttons.push({
text: actionObject.buttonArray[i],
callback: actionObject.callback,
})
}
}
ActionSheetPlugin.show({
title: actionObject.titleText || '',
buttons: buttons,
})
}
},
/**
* 时间选择函数
* @param timeObject.nowDate 当前展示的时间 可不填
* @param timeObject.format 时间格式支持不支持秒
* @param timeObject.callback 点击确定的回调函数
*
*/
showTime: function (timeObject) {
let date = new Date().format('yyyy-MM-dd')
let format = 'YYYY-MM-DD'
if (timeObject.nowDate) {
date = timeObject.nowDate
}
if (timeObject.format) {
format = timeObject.format
}
Vue.$vux.datetime.show({
cancelText: '取消',
confirmText: '确定',
minYear: '1900',
maxYear: '2200',
format: format,
value: date,
onConfirm (val) {
timeObject.callback(val)
},
})
},
/**
* 图片放大预览
* @param imgObject.imgUrl
*/
showBigPicture: function (imgObject) {
if (typeof imgObject === 'object') {
ShowPicturePlugin.show({
imgUrl: imgObject.imgUrl,
width: imgObject.width,
})
}
},
/**
* 下拉框 支持级联操作 需指定 parent 属性
* @param selectOption.list Array [{"code": "NP","code_name": "个人"}]
* @param selectOption.code String "bp_type"
* @param selectOption.object Object 当前数据对象
* @param selectOption.returnItem function 回调函数返回index与object
* var bp_class_list = [
* {
* "code": "NP",
* "code_name": "个人"
* },{
* "code": "NP1",
* "code_name": "个人1"
* }];
* hlsPopup.selectList({
* list: bp_class_list,
* code: 'bp_type',
* object: {},
* returnItem: function (index, obj) {
* console.log(obj)
* }
* })
*
*/
selectList: function (selectOption) {
if (typeof selectOption === 'object') {
let list = []
let length = selectOption.list.length
vum.forEach(selectOption.list, function (date, index, array) {
list.push({
value: date.code,
name: date.code_name,
parent: date.parent,
})
if (index === (length - 1)) {
SelectPlugin.show({
list: list,
callBack: selectOption.returnItem,
code: selectOption.code,
object: selectOption.object,
})
}
})
}
},
/**
* 弹出数字键盘
* @param keyboardObject.title 键盘的title
* @param keyboardObject.closeButtonText 键盘的关闭按钮文字
* @param keyboardObject.keyDown 普通按键按下去事件
* @param keyboardObject.keyDelete 删除按键按下去事件
*/
showNumberKeyborad: function (keyboardObject) {
if (typeof keyboardObject === 'object') {
NumberKeyboardPlugin.show({
title: keyboardObject.title,
closeButtonText: keyboardObject.closeButtonText,
extraKey: keyboardObject.extraKey || '.',
keyDown: function (text) {
keyboardObject.keyDown(text)
},
keyDelete: function () {
keyboardObject.keyDelete()
// console.log('delete')
},
})
}
},
/**
* 弹出Notify
* @param notifyObject.content 内容
* @param notifyObject.position 位置
* @param notifyObject.time 显示时长
* @param notifyObject.type 类型 success warning default
*/
showNotify: function (notifyObject) {
if (typeof notifyObject === 'object') {
NotifyPlugin.show({
show: true,
content: notifyObject.content,
position: notifyObject.position || 'top',
time: notifyObject.time || 3000,
type: notifyObject.type || 'default',
})
}
},
}
export default {
city: {
11: '北京',
12: '天津',
13: '河北',
14: '山西',
15: '内蒙古',
21: '辽宁',
22: '吉林',
23: '黑龙江',
31: '上海',
32: '江苏',
33: '浙江',
34: '安徽',
35: '福建',
36: '江西',
37: '山东',
41: '河南',
42: '湖北',
43: '湖南',
44: '广东',
45: '广西',
46: '海南',
50: '重庆',
51: '四川',
52: '贵州',
53: '云南',
54: '西藏',
61: '陕西',
62: '甘肃',
63: '青海',
64: '宁夏',
65: '新疆',
71: '台湾',
81: '香港',
82: '澳门',
91: '国外',
},
// 检查号码是否符合规范,包括长度,类型
isCardNo (card) {
// 身份证号码为15位或者18位,15位时全为数字,18位前17位为数字,最后一位是校验位,可能为数字或字符X
card = card.toUpperCase()
let reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/
return reg.test(card)
},
// 取身份证前两位,校验省份
checkProvince: function (card) {
card = card.toUpperCase()
let province = card.substr(0, 2)
if (this.city[province] === undefined) {
return false
}
return true
},
// 检查生日是否正确
checkBirthday: function (card) {
card = card.toUpperCase()
let len = card.length
let arrData
let year
let month
let day
let birthday
// 身份证15位时,次序为省(3位)市(3位)年(2位)月(2位)日(2位)校验位(3位),皆为数字
if (len === 15) {
let reFifteen = /^(\d{6})(\d{2})(\d{2})(\d{2})(\d{3})$/
arrData = card.match(reFifteen)
year = arrData[2]
month = arrData[3]
day = arrData[4]
birthday = new Date('19' + year + '/' + month + '/' + day)
return this.verifyBirthday('19' + year, month, day, birthday)
}
// 身份证18位时,次序为省(3位)市(3位)年(4位)月(2位)日(2位)校验位(4位),校验位末尾可能为X
if (len === 18) {
let reEighteen = /^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9]|X)$/
arrData = card.match(reEighteen)
year = arrData[2]
month = arrData[3]
day = arrData[4]
birthday = new Date(year + '/' + month + '/' + day)
return this.verifyBirthday(year, month, day, birthday)
}
return false
},
// 校验日期
verifyBirthday: function (year, month, day, birthday) {
// 年月日是否合理
return (birthday.getFullYear().toString() === year && ((birthday.getMonth() + 1) < 10 ? '0' + (birthday.getMonth() + 1) : (birthday.getMonth() + 1)) === month &&
((birthday.getDate()) < 10 ? '0' + (birthday.getDate()).toString() : birthday.getDate().toString()) === day)
},
// 校验位的检测
checkParity (card) {
// 15位转18位
card = this.changeFivteenToEighteen(card)
var len = card.length
if (len === 18) {
let arrInt = new Array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2)
let arrCh = new Array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2')
let cardTemp = 0
for (let i = 0; i < 17; i++) {
cardTemp += card.substr(i, 1) * arrInt[i]
}
let valnum = arrCh[cardTemp % 11]
if (valnum === card.substr(17, 1)) {
return true
}
return false
}
return false
},
// 15位转18位身份证号
changeFivteenToEighteen (card) {
if (card.length === 15) {
let arrInt = new Array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2)
let arrCh = new Array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2')
let cardTemp = 0
card = card.substr(0, 6) + '19' + card.substr(6, card.length - 6)
for (let i = 0; i < 17; i++) {
cardTemp += card.substr(i, 1) * arrInt[i]
}
card += arrCh[cardTemp % 11]
return card
}
return card
},
/**
* 检验身份证号码
*/
isCardID (card) {
card = card.toUpperCase()
if (this.isCardNo(card) === false) {
return '你输入的身份证长度或格式错误'
}
// 检查省份
if (this.checkProvince(card) === false) {
return '你的身份证地区非法'
}
// 校验生日
if (this.checkBirthday(card) === false) {
return '身份证上的出生日期非法'
}
// 检验位的检测
if (this.checkParity(card) === false) {
return '你输入的身份证号非法'
}
return ''
},
// 银行卡号校验
isBankAccount: function (bankno) {
if (bankno.length < 16 || bankno.length > 19) {
/* 银行卡号长度必须在16到19之间 */
return '银行卡号长度必须在16到19之间'
}
let num = /^\d*$/// 全数字
if (!num.exec(bankno)) {
/* 银行卡号必须全为数字 */
return '银行卡号必须全为数字'
}
var strBin = '10,18,30,35,37,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,58,60,62,65,68,69,84,87,88,94,95,98,99'
if (strBin.indexOf(bankno.substring(0, 2)) === -1) {
/* 银行卡号开头6位不符合规范 */
return '银行卡号开头6位不符合规范'
}
// Luhn校验
if (!this.luhnCheck(bankno)) {
return '银行卡号有误,请从新输入'
}
// return true;
},
luhnCheck: function (bankno) {
let lastNum = bankno.substr(bankno.length - 1, 1)// 取出最后一位(与luhn进行比较)
let first15Num = bankno.substr(0, bankno.length - 1)// 前15或18位
let newArr = []
for (let i = first15Num.length - 1; i > -1; i--) { // 前15或18位倒序存进数组
newArr.push(first15Num.substr(i, 1))
}
let arrJiShu = [] // 奇数位*2的积 <9
let arrJiShu2 = [] // 奇数位*2的积 >9
let arrOuShu = [] // 偶数位数组
for (let j = 0; j < newArr.length; j++) {
if ((j + 1) % 2 === 1) { // 奇数位
if (parseInt(newArr[j]) * 2 < 9) { arrJiShu.push(parseInt(newArr[j]) * 2) } else { arrJiShu2.push(parseInt(newArr[j]) * 2) }
} else { arrOuShu.push(newArr[j]) }
}
let jishuChild1 = []// 奇数位*2 >9 的分割之后的数组个位数
let jishuChild2 = []// 奇数位*2 >9 的分割之后的数组十位数
for (let h = 0; h < arrJiShu2.length; h++) {
jishuChild1.push(parseInt(arrJiShu2[h]) % 10)
jishuChild2.push(parseInt(arrJiShu2[h]) / 10)
}
let sumJiShu = 0 // 奇数位*2 < 9 的数组之和
let sumOuShu = 0 // 偶数位数组之和
let sumJiShuChild1 = 0 // 奇数位*2 >9 的分割之后的数组个位数之和
let sumJiShuChild2 = 0 // 奇数位*2 >9 的分割之后的数组十位数之和
for (let m = 0; m < arrJiShu.length; m++) {
sumJiShu = sumJiShu + parseInt(arrJiShu[m])
}
for (let n = 0; n < arrOuShu.length; n++) {
sumOuShu = sumOuShu + parseInt(arrOuShu[n])
}
for (let p = 0; p < jishuChild1.length; p++) {
sumJiShuChild1 = sumJiShuChild1 + parseInt(jishuChild1[p])
sumJiShuChild2 = sumJiShuChild2 + parseInt(jishuChild2[p])
}
// 计算总和
let sumTotal = parseInt(sumJiShu) + parseInt(sumOuShu) + parseInt(sumJiShuChild1) + parseInt(sumJiShuChild2)
// 计算luhn值
let k = parseInt(sumTotal) % 10 === 0 ? 10 : parseInt(sumTotal) % 10
let luhn = 10 - k
if (lastNum === luhn) {
return true
} else {
/* 银行卡号必须符合luhn校验 */
return false
}
},
/**
* 判断输入是否为十一位电话号码
* @param str 字符串
* @returns {boolean}
*/
phoneNumber: function (str) {
// ^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\d{8}$
let reg = /^((13[0-9]{1})|(14[0-9]{1})|(15[0-9]{1})|(17[0-9]{1})|(18[0-9]{1})|166|198|199|(147))+\d{8}$/
return reg.test(str)
},
/**
* 判断+86后11位电话号码
* @param str 字符串
* @returns {boolean}
*/
phoneNumber86: function (str) {
let reg = /^(\+86|\+86+\s)+(((13[0-9]{1})|(14[0-9]{1})|(15[0-9]{1})|(17[0-9]{1})|(18[0-9]{1})|166|198|199|(147))+\d{8})$/
return reg.test(str)
},
/**
* 是否是邮件格式
* @param str
* @returns {boolean|*}
*/
isEmailAddress: function (str) {
let pattern = /^([a-zA-Z0-9_.-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/
return pattern.test(str)
},
/**
*
* @param cameraoption 对象{quality:质量默认50,allowEdit:true||false,width:宽度,height:高度}
* @param onSuccess 成功回调函数
* @param onFail 失败回调函数
*/
/* eslint-disable */
openCamera: function (cameraoption, onSuccess, onFail) {
if (typeof onSuccess === 'function' && typeof onFail === 'function') {
let options = {
quality: cameraoption.quality || 50,
destinationType: Camera.DestinationType.FILE_URI,
sourceType: Camera.PictureSourceType.CAMERA,
allowEdit: cameraoption.allowEdit || false,
targetWidth: cameraoption.width || 1024,
targetHeight: cameraoption.height || 768,
encodingType: Camera.EncodingType.JPEG,
popoverOptions: CameraPopoverOptions,
saveToPhotoAlbum: window.localStorage.savePhoto || false,
correctOrientation: true,
}
navigator.camera.getPicture(onSuccess, onFail, options)
} else {
window.hlsPopup.showLongCenter('参数有误!')
}
},
/**
* 最多选取10张,返回图片的存储地址数组形式
* @param obj {quality:质量默认50,width:宽度,height:高度}
* @param successFunction 成功回调函数
* @param errorFunction 失败函数
*/
takePicture: function (obj, successFunction, errorFunction) {
if (typeof successFunction === 'function' && typeof errorFunction === 'function') {
window.imagePicker.getPictures(
successFunction, errorFunction, {
maximumImagesCount: obj.maxCount || 10,
quality: obj.quality || 50,
width: obj.width || 1024,
height: obj.height || 768,
}
)
} else {
window.hlsPopup.showLongBottom('参数有误!')
}
},
/**
* 拨打电话仅仅限制于手机
* @param number
*/
callPhone: function (number) {
window.open('tel:' + number)
},
/**
* 发邮件
* @param email
*/
callEmail: function (email) {
window.open('mailto:' + email)
},
/**
* 非ftp的上传方式
* @param filePath
* @param success
*/
fileUploadHls: function (file, success) {
let path = file.filePath
let name = path.substr(path.lastIndexOf('/') + 1)
let url = encodeURI(process.env.rootPath + '/app/fileUploadHls?sysName=HLS_APP&apiName=attment_file_upload')
let options = new FileUploadOptions() // eslint-disable-line
options.fileKey = 'file'
options.headers = {
'Authorization': 'Bearer ' + window.localStorage.access_token,
}
options.params = {
'table_name': file.table_name,
'table_pk_value': file.table_pk_value,
'user_id': window.localStorage.user_id,
'access_token': window.localStorage.access_token,
'filePath': path,
}
options.fileName = name
options.mimeType = 'multipart/form-date'
let ft = new FileTransfer() // eslint-disable-line
ft.onprogress = function (progressEvent) {
if (progressEvent.lengthComputable) {
loadingStatus.setPercentage(progressEvent.loaded / progressEvent.total) // eslint-disable-line
} else {
loadingStatus.increment() // eslint-disable-line
}
}
function uploadSuccess (result) {
success(JSON.parse(result.response))
}
function fileError () {
window.hlsPopup.hideLoading()
console.log('upload error source ' + error.source)
console.log('upload error target ' + error.target)
}
ft.upload(path, url, uploadSuccess, fileError, options)
},
/**
* 调用系统svc进行上传
* @param filePath
* @param success
*/
fileUploadSvc: function (file, success) {
let path = file.filePath
let name = path.substr(path.lastIndexOf('/') + 1)
let url = encodeURI(process.env.rootPath + '/app/fileUploadSvc?sysName=HLS_APP&apiName=attachment_upload')
let options = new FileUploadOptions() // eslint-disable-line
options.fileKey = 'file'
options.headers = {
'Authorization': 'Bearer ' + window.localStorage.access_token,
}
options.params = {
'source_type': file.table_name,
'pkvalue': file.table_pk_value,
'user_id': window.localStorage.user_id,
'access_token': window.localStorage.access_token,
'filePath': path,
'timestamp': file.timestamp,
'sequence': file.sequence,
}
options.fileName = name
options.mimeType = 'multipart/form-date'
let ft = new FileTransfer() // eslint-disable-line
function uploadSuccess (result) {
success(JSON.parse(result.response))
}
function fileError () {
window.hlsPopup.hideLoading()
console.log('upload error source ' + error.source)
console.log('upload error target ' + error.target)
}
ft.upload(path, url, uploadSuccess, fileError, options)
},
/**
* 汉王识别
* @param file
* @param url
* @param success
*/
hangwan: function (fileUrl, postUrl, success) {
if (!fileUrl) {
return
}
let path = fileUrl
let name = fileUrl.substr(fileUrl.lastIndexOf('/') + 1)
let url = encodeURI(postUrl)
let options = new FileUploadOptions() // eslint-disable-line
options.headers = {
'Authorization': 'Bearer ' + window.localStorage.access_token,
}
options.fileKey = 'file'
options.fileName = name
options.mimeType = 'multipart/form-date'
let ft = new FileTransfer() // eslint-disable-line
function uploadSuccess (message) {
let res = JSON.parse(message.response)
success(res)
}
function error (e) {
this.hlsPopup.showLongCenter('汉王识别失败')
}
ft.upload(path, url, uploadSuccess, error, options)
},
/**
*
* @param x 输入的数字
* @returns {Number} 返回数字
*/
toDecimal: function (x) {
// hlsPopup.showLongCenter(baseConfig.debug);
let f = parseFloat(x)
if (isNaN(f)) {
return 0
}
f = Math.round(x * 100) / 100
return f
},
formatFloat: function (f, digit) {
let m = Math.pow(100000, digit)
return parseInt(f * m, 100000) / m
},
/**
*
* @param ir interest rate per month
* @param np number of periods (months)
* @param pv present value
* @param fv future value (residual value)
* @returns {number} 计算结果;
* @constructor
*/
PMT: function (ir, np, pv, fv, type) {
/*
ir - interest rate per month
np - number of periods (months)
pv - present value
fv - future value (residual value)
type - 0 or 1 need to implement that
*/
if (!type) {
type = 0
}
if (ir === 0) {
return -pv / np
}
let r1 = 1 + ir
// let pmt = -( ir * ( pv * Math.pow((ir + 1), np) + fv ) ) / ( ( ir + 1 ) * ( Math.pow((ir + 1), np) - 1 ) );
let pmt = -(pv * Math.pow(r1, np) + fv) * ir / ((1 + ir * type) * (Math.pow(r1, np) - 1))
return this.toDecimal(pmt)
},
/**
*
* @param rate
* @param per
* @param nper
* @param pv
* @param fv
* @param type
* @returns {*}
* @constructor
*/
IPMT: function (rate, per, nper, pv, fv, type) {
let ipmt = 0
let r = rate
let R1 = 1 + r
let t = per
let n = nper
let ct
if (rate === 0) {
return 0
}
if (fv) {
fv = -fv
} else {
fv = 0
}
if (type) {
ct = type
} else {
ct = 0
}
if (type === 1 && per === 1) {
return ipmt
} else {
ipmt = -(pv * Math.pow(R1, n) + fv) * r /
((1 + r * ct) * (Math.pow(R1, n) - 1)) -
(pv / (1 + r * ct) - (pv * Math.pow(R1, n) + fv) /
((1 + r * ct) * (Math.pow(R1, n) - 1))) *
(Math.pow(R1, t) - Math.pow(R1, (t - 1)))
return this.toDecimal(ipmt)
}
},
/**
*
* @param p_rate
* @param p_nper
* @param p_pmt
* @param p_fv
* @param p_type
* @returns {number|*}
* @constructor
*/
PV: function (pRate, pNper, pPmt, pFv, pType) {
let pv
let r
let R1
let n
let pmt
let fv
let ct
r = pRate
R1 = 1 + r
n = pNper
if (pPmt) {
pmt = pPmt
} else {
pmt = 0
}
if (pFv) {
fv = pFv
} else {
fv = 0
}
if (pType) {
ct = pType
} else {
ct = 0
}
pv = -(fv + pmt * (1 + r * ct) * (Math.pow(R1, n) - 1) / r) /
Math.pow(R1, n)
return this.toDecimal(pv)
},
/**
*
* @param p_rate
* @param p_nper
* @param p_pmt
* @param p_pv
* @param p_type
* @returns {number|*}
* @constructor
*/
FV: function (pRate, pNper, pPmt, pPv, pType) {
let fv
let r
let R1
let n
let pmt
let pv
let ct
r = pRate
R1 = 1 + r
n = pNper
if (pPmt) {
pmt = pPmt
} else {
pmt = 0
}
if (pPv) {
pv = pPv
} else {
pv = 0
}
if (pType) {
ct = pType
} else {
ct = 0
}
fv = -pv * Math.pow(R1, n) - pmt * (1 + r * ct) * (Math.pow(R1, n) - 1) / r
return this.toDecimal(fv)
},
/**
*
* @param args
* @param rate
* @returns {*}
* @constructor
*/
NPV: function (args, rate) {
let rrate = (1 + rate / 100)
let npv = args[0]
for (let i = 1; i < args.length; i++) {
npv += (args[i] / Math.pow(rrate, i))
}
return npv
},
/**
*
* @param fn
* @returns {number}
*/
seekZero: function (fn) {
let x = 1
while (fn(x) > 0) {
x += 1
}
while (fn(x) < 0) {
x -= 0.01
}
return x + 0.01
},
/**
*
* @param array
* @returns {number}
* @constructor
*/
IRR: function (array) {
let args = array
let numberOfTries = 1
// Cash flow values must contain at least one positive value and one negative value
let positive, negative
Array.prototype.slice.call(args).forEach(function (value) {
if (value > 0) positive = true
if (value < 0) negative = true
})
if (!positive || !negative) throw new Error('IRR requires at least one positive value and one negative value')
function npv (rate) {
numberOfTries++
if (numberOfTries > 1000) {
throw new Error('IRR can\'t find a result')
}
let rrate = (1 + rate / 100)
let npv = args[0]
for (let i = 1; i < args.length; i++) {
npv += (args[i] / Math.pow(rrate, i))
}
return npv
}
return this.seekZero(npv)
},
// Returns Sum of f(x)/f'(x)
sumEq: function (cfs, durs, guess) {
let sumFx = 0
let sumFdx = 0
for (let i = 0; i < cfs.length; i++) {
sumFx = sumFx + (cfs[i] / Math.pow(1 + guess, durs[i]))
}
for (let i = 0; i < cfs.length; i++) {
sumFdx = sumFdx + (-cfs[i] * durs[i] * Math.pow(1 + guess, -1 - durs[i]))
}
return sumFx / sumFdx
},
durYear: function (first, last) {
return (Math.abs(last.getTime() - first.getTime()) / (1000 * 3600 * 24 * 365))
},
/**
*
* @param cfs
* @param dts
* @param guess
* @returns {number}
* @constructor
*/
XIRR: function (cfs, dts, guess) {
if (cfs.length !== dts.length) throw new Error('Number of cash flows and dates should match')
let positive, negative
Array.prototype.slice.call(cfs).forEach(function (value) {
if (value > 0) positive = true
if (value < 0) negative = true
})
if (!positive || !negative) throw new Error('XIRR requires at least one positive value and one negative value')
guess = guess || 0
let limit = 100 // loop limit
let guessLast
let durs = []
durs.push(0)
// Create Array of durations from First date
for (let i = 1; i < dts.length; i++) {
durs.push(this.durYear(dts[0], dts[i]))
}
do {
guessLast = guess
guess = guessLast - this.sumEq(cfs, durs, guessLast)
limit--
} while (guessLast.toFixed(5) !== guess.toFixed(5) && limit > 0)
let xirr = guessLast.toFixed(5) !== guess.toFixed(5) ? null : guess * 100
return Math.round(xirr * 100) / 100
},
// 指纹
fingerLogin: function () {
if (vum.Platform.isIOS()) {
return this.fingerLoginIos()
} else {
return this.fingerLoginAndroid()
}
},
// android
fingerLoginAndroid: function () {
let isSupportFinger = 'true'
return new Promise(function (resolve, reject) {
Fingerprint.isAvailable(function (res) { // eslint-disable-line
if (window.localStorage.isSupportFinger) {
window.localStorage.removeItem('isSupportFinger')
}
window.localStorage.setItem('isSupportFinger', isSupportFinger)
if (window.localStorage.isOpenFingerLogin && window.localStorage.username && window.localStorage.password) {
var successCallback = function (msg) {
resolve(msg)
}
var errorCallback = function (err) {
reject(err)
}
Fingerprint.show({ // eslint-disable-line
clientId: 'com.car.rental.easy',
clientSecret: 'a_very_secret_encryption_key', // Only necessary for Android
}, successCallback, errorCallback)
} else {
reject() // eslint-disable-line
}
}, function (error) {
isSupportFinger = false
window.localStorage.isSupportFinger = isSupportFinger
reject(error)
})
})
},
// ios
fingerLoginIos: function () {
return new Promise(function (resolve, reject) {
let isSupportFinger = true
window.plugins.touchid.isAvailable(
// 支持指纹
function () {
isSupportFinger = true
if (window.localStorage.isSupportFinger) {
window.localStorage.removeItem('isSupportFinger')
}
window.localStorage.setItem('isSupportFinger', isSupportFinger)
// window.localStorage.isSupportFinger = true;
// 判断是否开启了指纹登录
if (window.localStorage.isOpenFingerLogin && window.localStorage.username && window.localStorage.password) {
window.plugins.touchid.verifyFingerprint(
'通过Home键验证已有的手机指纹!', // this will be shown in the native scanner popup
function (msg) {
resolve(msg)
},
function (msg) {
reject(msg)
})
} else {
reject() // eslint-disable-line
}
}
// 不支持指纹
, function (msg) {
isSupportFinger = false
window.localStorage.isSupportFinger = isSupportFinger
reject(msg)
}
)
})
},
// 判断是否为首次登录
isFirstTimeLogin: function (name) {
if (window.localStorage.username) {
if (window.localStorage.username !== name) {
return true
} else {
return false
}
} else {
return true
}
},
// 打开指纹登陆
openFingerLogin: function () {
return new Promise(function (resolve, reject) {
if (vum.Platform.isIOS()) {
window.plugins.touchid.isAvailable(function () {
window.plugins.touchid.verifyFingerprint(
'通过Home键验证已有的手机指纹!',
function () {
resolve()
}, function () {
reject() // eslint-disable-line
}
)
}, function () {
this.hlsPopup.showLongCenter('您的设配暂不支持指纹')
reject() // eslint-disable-line
})
} else {
Fingerprint.isAvailable(function (res) { // eslint-disable-line
Fingerprint.show({ // eslint-disable-line
clientId: 'com.car.rental.easy',
clientSecret: 'a_very_secret_encryption_key', // Only necessary for Android
}, successCallback, errorCallback)
function successCallback (msg) {
resolve(msg)
}
function errorCallback (err) {
reject(err)
}
}, function (error) {
this.hlsPopup.showLongCenter('您的设配暂不支持指纹')
reject(error)
})
}
})
},
/**
* 判断平台
* @return {String} 平台
*/
detectOS: function () {
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'
}
},
}
/**
* hmap子应用登录逻辑
* @author momoko 2018/05/08
*/
import axios from 'axios'
import { getUrlParam } from './utils'
// 模拟登录
export function analogLogin () {
return new Promise((resolve, reject) => {
const url = `${$config.hmapUrl}/oauth/token?client_id=18f58010-2831-11e8-b467-0ed5f89f718b&client_secret=2fe58f36-2831-11e8-b467-0ed5f89f718b&grant_type=password&username=%2B8618325379820&password=jingchaowu520&authType=TEL`
axios.post(url).then(res => {
window.localStorage.setItem('token', res.access_token)
resolve({
token: res.access_token,
tokenType: res.token_type,
expires: res.expires_in,
userId: res.userId,
organizationId: res.organizationId,
})
})
})
}
// 授权码登录
export async function authorizedLogin () {
return new Promise((resolve, reject) => {
const code = getUrlParam('code')
const url = `${$config.hmapUrl}/oauth/token?client_id=18f58010-2831-11e8-b467-0ed5f89f718b&client_secret=2fe58f36-2831-11e8-b467-0ed5f89f718b&grant_type=authorization_code&code=${encodeURIComponent(code)}`
axios.post(url).then(res => {
window.localStorage.setItem('token', res.access_token)
resolve({
token: res.access_token,
tokenType: res.token_type,
expires: res.expires_in,
userId: res.userId,
organizationId: res.organizationId,
account: res.account,
mobile: res.phoneNumber,
})
})
})
}
// 桥登录
export function bridgeLogin () {
return new Promise((resolve, reject) => {
// 登录成功回调
window.bridgeLoginSuccess = function (str) {
const res = JSON.parse(str)
window.localStorage.setItem('token', res.token)
const data = {
token: res.token,
tokenType: res.tokenType,
expires: res.expiresIn,
userId: res.userId,
organizationId: res.organizationId,
account: res.account,
mobile: res.phoneNumber,
}
resolve(data)
}
// 登录失败回调
window.bridgeLoginFailure = function (res) {
console.error(res)
reject(res)
}
const dict = {
'className': 'BaseBridge',
'function': 'getBaseInfo',
'successCallBack': 'bridgeLoginSuccess',
'failureCallBack': 'bridgeLoginFailure',
}
HandBridge.postMessage(JSON.stringify(dict))
})
}
// 获取用户详细信息
export function getUserInfo (userId) {
const url = `${$config.hmapUrl}/i/api/staff/customDetail`
const data = {
userId,
}
const options = {
headers: {
Authorization: `Bearer ${window.localStorage.token}`,
},
}
return new Promise((resolve, reject) => {
axios.post(url, data, options).then(res => {
resolve({
account: res.accountNumber,
mobile: res.mobile,
userId: res.userId,
organizationId: res.organizationId,
email: res.email,
})
})
})
}
/**
* 获取中台的token
* @returns {Promise<*>}
*/
export async function getSupportToken () {
const url = `${$config.loginPath}appadmin`
const res = await axios.post(url)
return res
}
/**
* 获取业务系统个人信息
* @returns {Promise<*>}
*/
export async function getLeasingUserInfo (account, mobile) {
window.localStorage.setItem('account', account)
const url = `${$config.basePath}hmap_app_login`
const data = {
'user_name': account,
'mobile': mobile,
}
const options = {
headers: {
Authorization: `Bearer ${window.localStorage.access_token}`,
},
}
return new Promise((resolve, reject) => {
axios.post(url, data, options).then(res => {
// console.log('leasingInfo:' + JSON.stringify(res))
if (res.result === 'S') {
resolve(res.user_info[0])
}
})
})
}
/**
* 登录总成
* @param {String} [type] 可选:'online''local'
* @param {Boolean} [needInfo] 是否需要获取用户详细信息
* @return {Object.Promise} 若登录成功PromiseValue为数据对象/登录失败PromiseValue 为 false
*/
export async function login (type = 'online', needInfo = true) { // 登录
const env = process.env.CONFIG_ENV // 环境
try {
let result = {}
let tokenInfo = {}
tokenInfo = await getSupportToken()
window.localStorage.setItem('access_token', tokenInfo.access_token)
if (env === 'prod' || env === 'uat') { // 真机
if (type === 'online') result = await authorizedLogin() // 在线子应用
if (type === 'local') result = await bridgeLogin() // 本地子应用
window.localStorage.setItem('mobile', result.mobile)
result.userInfo = await getLeasingUserInfo(result.account, result.mobile)
} else {
result = await analogLogin()
result.hmapUserInfo = await getUserInfo(result.userId)
window.localStorage.setItem('mobile', result.hmapUserInfo.mobile)
result.userInfo = await getLeasingUserInfo(result.hmapUserInfo.account, result.hmapUserInfo.mobile)
}
window.localStorage.setItem('user_id', result.userInfo.user_id)
return result
} catch (e) {
// console.error(e)
return false
}
}
/**
* 海马汇业务系统集成登录
* @param type
* @param needInfo
* @returns {Promise<any>}
*/
export default function hmapLogin (type = 'local', needInfo = true) {
const env = process.env.CONFIG_ENV // 环境
return new Promise((resolve, reject) => {
try {
let result = {}
if (env === 'prod' || env === 'uat') { // 真机
if (type === 'online') {
authorizedLogin().then(res => {
result = res
window.localStorage.setItem('mobile', res.mobile)
})
}// 在线子应用
if (type === 'local') {
result = bridgeLogin().then(res => {
result = res
window.localStorage.setItem('mobile', res.mobile)
})
}
getSupportToken().then(res => {
window.localStorage.setItem('access_token', res.access_token)
getLeasingUserInfo(result.account, result.mobile).then(res => {
result.userInfo = res
window.localStorage.setItem('user_id', res.user_id)
resolve(result)
})
})
} else {
analogLogin().then(res => {
result = res
getUserInfo(res.userId).then(info => {
result.hmapUserInfo = info
window.localStorage.setItem('mobile', info.mobile)
getSupportToken().then(support => {
window.localStorage.setItem('access_token', support.access_token)
getLeasingUserInfo(info.account, info.mobile).then(res => {
result.userInfo = res
window.localStorage.setItem('user_id', res.user_id)
resolve(result)
})
})
})
})
}
} catch (e) {
reject(e)
}
})
}
/**
* 一些帮助函数
* @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'
}
}
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