15 changed files with 1374 additions and 148 deletions
Unified View
Diff Options
-
32App.vue
-
42apis/loginApi.js
-
29enums/index.js
-
6pages.json
-
35pages/agreement/index.vue
-
271pages/login/index.vue
-
126store/index.js
-
31uni_modules/uni-easyinput/changelog.md
-
56uni_modules/uni-easyinput/components/uni-easyinput/common.js
-
461uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue
-
90uni_modules/uni-easyinput/package.json
-
11uni_modules/uni-easyinput/readme.md
-
84utils/hook.js
-
215utils/http/http.js
-
33utils/http/index.js
@ -1,18 +1,24 @@ |
|||||
<script> |
<script> |
||||
export default { |
|
||||
onLaunch: function() { |
|
||||
console.log('App Launch') |
|
||||
}, |
|
||||
onShow: function() { |
|
||||
console.log('App Show') |
|
||||
}, |
|
||||
onHide: function() { |
|
||||
console.log('App Hide') |
|
||||
} |
|
||||
} |
|
||||
|
import { go2 } from '@/utils/hook.js' |
||||
|
import store from '@/store/index.js' |
||||
|
export default { |
||||
|
onLaunch: function () { |
||||
|
const token = store.state.qnToken |
||||
|
if (!token) { |
||||
|
go2('login') |
||||
|
} |
||||
|
console.log('App launched') |
||||
|
}, |
||||
|
onShow: function () { |
||||
|
console.log('App Show') |
||||
|
}, |
||||
|
onHide: function () { |
||||
|
console.log('App Hide') |
||||
|
} |
||||
|
} |
||||
</script> |
</script> |
||||
|
|
||||
<style> |
<style> |
||||
/*每个页面公共css */ |
|
||||
@import url("./common/css/reset.scss"); |
|
||||
|
/*每个页面公共css */ |
||||
|
@import url('./common/css/reset.scss'); |
||||
</style> |
</style> |
||||
@ -0,0 +1,42 @@ |
|||||
|
import http from '../utils/http/index.js' |
||||
|
|
||||
|
/** |
||||
|
* 手机登录获取验证码接口 |
||||
|
* @param {object} data 获取验证码参数 |
||||
|
* @returns 获取验证码结果 |
||||
|
* swagger:http://api-ops-uec-test.qniao.cn/uec/swagger-ui/index.html?urls.primaryName=CustomerApi#/%E7%99%BB%E5%BD%95%E8%AE%A4%E8%AF%81/authorizeByCaptchaUsingPOST
|
||||
|
*/ |
||||
|
export const getAuthCaptcha = (data) => { |
||||
|
return http.post({ |
||||
|
url: '/uec/get/auth-captcha', |
||||
|
data |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 手机验证码登录,返回临时token |
||||
|
* @param {object} data 登录参数 |
||||
|
* @returns {object} 返回参数 {token: '', userId: ''} |
||||
|
* |
||||
|
* swagger:http://api-ops-uec-test.qniao.cn/uec/swagger-ui/index.html?urls.primaryName=CustomerApi#/%E7%99%BB%E5%BD%95%E8%AE%A4%E8%AF%81/authorizeByCaptchaUsingPOST
|
||||
|
*/ |
||||
|
export const loginByPhone = (data) => { |
||||
|
return http.post({ |
||||
|
url: '/uec/authorize/by-captcha', |
||||
|
data |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 手机验证码登录,返回临时token |
||||
|
* @param {object} data 登录参数 |
||||
|
* @returns {string} 返回参数 token:string |
||||
|
* |
||||
|
* swagger:http://api-ops-yyt-test.qniao.cn/yyt-uec/swagger-ui/index.html?urls.primaryName=CustomerApi#/%E7%99%BB%E5%BD%95%E8%AE%A4%E8%AF%81/getProductLineTokenByLoginTokenUsingPOST
|
||||
|
*/ |
||||
|
export const getQnToken = (data) => { |
||||
|
return http.post({ |
||||
|
url: '/yyt-uec/authorize/get/product-line-token/by/login-token', |
||||
|
data |
||||
|
}) |
||||
|
} |
||||
@ -0,0 +1,29 @@ |
|||||
|
/** |
||||
|
* 账号类型 |
||||
|
*/ |
||||
|
export const accountType = { |
||||
|
WX: 1, |
||||
|
PHONE: 2, |
||||
|
EMAIL: 3, |
||||
|
APPLEID: 4, |
||||
|
CUSTOM: 5 |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 验证码用途 |
||||
|
*/ |
||||
|
export const codePurpose = { |
||||
|
CERTIFICATION: 1, |
||||
|
RESET_LOGIN_PASSWORD: 2, |
||||
|
RESET_PHONE: 3, |
||||
|
BIND_BANK_CARD: 4, |
||||
|
RESET_CREDIT_PASSWORD: 5 |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 可验证账号类型 |
||||
|
*/ |
||||
|
export const verificationType = { |
||||
|
PHONE: 1, |
||||
|
EMAIL: 2 |
||||
|
} |
||||
@ -0,0 +1,35 @@ |
|||||
|
<template> |
||||
|
<view class="content">agreement</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default {} |
||||
|
</script> |
||||
|
|
||||
|
<style> |
||||
|
.content { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
} |
||||
|
|
||||
|
.logo { |
||||
|
height: 200rpx; |
||||
|
width: 200rpx; |
||||
|
margin-top: 200rpx; |
||||
|
margin-left: auto; |
||||
|
margin-right: auto; |
||||
|
margin-bottom: 50rpx; |
||||
|
} |
||||
|
|
||||
|
.text-area { |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
} |
||||
|
|
||||
|
.title { |
||||
|
font-size: 36rpx; |
||||
|
color: #8f8f94; |
||||
|
} |
||||
|
</style> |
||||
@ -1,15 +1,270 @@ |
|||||
<template> |
<template> |
||||
<view> |
|
||||
login |
|
||||
</view> |
|
||||
|
<view> |
||||
|
<uni-nav-bar |
||||
|
:fixed="true" |
||||
|
color="#ffffff" |
||||
|
background-color="#ffffff" |
||||
|
:status-bar="true" |
||||
|
:border="false" |
||||
|
left-icon="closeempty" |
||||
|
@clickLeft="close" |
||||
|
/> |
||||
|
<view class="logo_area"> |
||||
|
<image class="logo" src="/static/logo.png"></image> |
||||
|
<text class="title">纸掌柜</text> |
||||
|
</view> |
||||
|
<view class="form"> |
||||
|
<view class="phone"> |
||||
|
<uni-easyinput |
||||
|
v-model="phoneNumber" |
||||
|
:inputBorder="false" |
||||
|
:placeholderStyle="'font-size:32rpx;'" |
||||
|
placeholder="请输入手机号码" |
||||
|
:maxlength="11" |
||||
|
/> |
||||
|
</view> |
||||
|
<view class="captcha"> |
||||
|
<uni-easyinput |
||||
|
v-model="captcha" |
||||
|
:inputBorder="false" |
||||
|
:placeholderStyle="'font-size:32rpx;'" |
||||
|
placeholder="请输入验证码" |
||||
|
:maxlength="6" |
||||
|
/> |
||||
|
<view v-show="timer > 0" class="timer_area"> |
||||
|
<text class="timer">{{ `(${timer}S后) ` }}</text> |
||||
|
<text class="timer_text">重新获取</text> |
||||
|
</view> |
||||
|
<text v-show="timer <= 0" class="code" @click="getCode"> |
||||
|
获取验证码 |
||||
|
</text> |
||||
|
</view> |
||||
|
<view |
||||
|
class="login-button" |
||||
|
@click="login" |
||||
|
:style="{ opacity: disabled ? '0.5' : '' }" |
||||
|
> |
||||
|
登录 |
||||
|
</view> |
||||
|
</view> |
||||
|
<view class="agreement_area"> |
||||
|
<checkbox-group @change="onCheck"> |
||||
|
<checkbox |
||||
|
value="cb" |
||||
|
:checked="checked" |
||||
|
color="#000000" |
||||
|
style="transform: scale(0.7)" |
||||
|
/> |
||||
|
</checkbox-group> |
||||
|
<view class="agreement"> |
||||
|
已阅读并同意纸掌柜 |
||||
|
<text class="agreement_text" @click="jumpAgreement"> |
||||
|
《用户与隐私协议》 |
||||
|
</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
<!-- |
||||
|
<uni-easyinput v-model="captcha" placeholder="验证码" /> |
||||
|
<button @click="getCode">获取验证码</button> |
||||
|
<button @click="login">登录</button> --> |
||||
|
</view> |
||||
</template> |
</template> |
||||
|
|
||||
<script> |
<script> |
||||
export default { |
|
||||
|
|
||||
} |
|
||||
|
import { getAuthCaptcha, loginByPhone, getQnToken } from '@/apis/loginApi' |
||||
|
import { accountType, verificationType, codePurpose } from '@/enums/index.js' |
||||
|
import store from '@/store/index.js' |
||||
|
import { go2, back } from '@/utils/hook.js' |
||||
|
export default { |
||||
|
data() { |
||||
|
return { |
||||
|
phoneNumber: '', |
||||
|
captcha: '', |
||||
|
timer: 0, |
||||
|
checked: false |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
// 退出登录 |
||||
|
close() { |
||||
|
back() |
||||
|
}, |
||||
|
onCheck(e) { |
||||
|
if (e.detail.value.length > 0) { |
||||
|
this.checked = true |
||||
|
} else { |
||||
|
this.checked = false |
||||
|
} |
||||
|
}, |
||||
|
jumpAgreement() { |
||||
|
go2('agreement') |
||||
|
}, |
||||
|
// 获取验证码 |
||||
|
getCode() { |
||||
|
if (this.phoneNumber.trim() === '') { |
||||
|
uni.showToast({ |
||||
|
title: '请输入手机号码', |
||||
|
icon: 'none' |
||||
|
}) |
||||
|
return |
||||
|
} |
||||
|
if (this.phoneNumber.trim().length !== 11) { |
||||
|
uni.showToast({ |
||||
|
title: '请输入正确的手机号码', |
||||
|
icon: 'none' |
||||
|
}) |
||||
|
return |
||||
|
} |
||||
|
this.countdown() |
||||
|
getAuthCaptcha({ |
||||
|
purpose: codePurpose.CERTIFICATION, |
||||
|
verifiableAccount: this.phoneNumber, |
||||
|
verifiableAccountType: verificationType.PHONE |
||||
|
}).then((res) => { |
||||
|
console.log(res) |
||||
|
}) |
||||
|
}, |
||||
|
// 倒计时 |
||||
|
countdown() { |
||||
|
this.timer = 60 |
||||
|
let timer = setInterval(() => { |
||||
|
this.timer-- |
||||
|
if (this.timer <= 0) { |
||||
|
clearInterval(timer) |
||||
|
} |
||||
|
}, 1000) |
||||
|
}, |
||||
|
// 登录 |
||||
|
login() { |
||||
|
if (this.disabled) { |
||||
|
return |
||||
|
} |
||||
|
if (!this.checked) { |
||||
|
uni.showToast({ |
||||
|
title: '请同意用户与隐私协议', |
||||
|
icon: 'none' |
||||
|
}) |
||||
|
return |
||||
|
} |
||||
|
loginByPhone({ |
||||
|
accountType: accountType.PHONE, |
||||
|
account: this.phoneNumber, |
||||
|
captcha: this.captcha |
||||
|
}).then((res) => { |
||||
|
if (res) { |
||||
|
store.commit('setUecToken', res.token) |
||||
|
getQnToken({ loginToken: res.token }).then((token) => { |
||||
|
if (token) { |
||||
|
store.commit('setToken', token) |
||||
|
// 登录成功先查看是否有下一个页面 |
||||
|
const nextPage = store.state.nextPage |
||||
|
if (nextPage.name) { |
||||
|
go2(nextPage.name, nextPage.data) |
||||
|
} else { |
||||
|
go2('mine') |
||||
|
} |
||||
|
store.commit('removeNextPage') |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
}, |
||||
|
computed: { |
||||
|
disabled() { |
||||
|
return ( |
||||
|
this.phoneNumber.trim() === '' || |
||||
|
this.phoneNumber.trim().length != 11 || |
||||
|
this.captcha.trim() === '' |
||||
|
) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
</script> |
</script> |
||||
|
|
||||
<style> |
|
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.logo_area { |
||||
|
margin-top: 187rpx; |
||||
|
width: 750rpx; |
||||
|
height: 100rpx; |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
.logo { |
||||
|
width: 100rpx; |
||||
|
height: 100rpx; |
||||
|
margin-right: 20rpx; |
||||
|
} |
||||
|
.title { |
||||
|
opacity: 0.8; |
||||
|
font-size: 60rpx; |
||||
|
color: #000000; |
||||
|
letter-spacing: 9rpx; |
||||
|
text-align: center; |
||||
|
font-weight: 400; |
||||
|
} |
||||
|
} |
||||
|
.form { |
||||
|
width: 750rpx; |
||||
|
margin-top: 280rpx; |
||||
|
padding: 0 64rpx; |
||||
|
.phone { |
||||
|
width: 622rpx; |
||||
|
border-bottom: 2rpx solid #e0e0e0; |
||||
|
} |
||||
|
.captcha { |
||||
|
margin-top: 44rpx; |
||||
|
width: 622rpx; |
||||
|
border-bottom: 2rpx solid #e0e0e0; |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
align-items: center; |
||||
|
.timer_area { |
||||
|
width: auto; |
||||
|
flex: 0 0 auto; |
||||
|
.timer { |
||||
|
font-size: 32rpx; |
||||
|
color: #007aff; |
||||
|
} |
||||
|
.timer_area { |
||||
|
font-size: 32rpx; |
||||
|
color: #999999; |
||||
|
} |
||||
|
} |
||||
|
.code { |
||||
|
width: 160rpx; |
||||
|
font-size: 32rpx; |
||||
|
color: #007aff; |
||||
|
flex: 0 0 auto; |
||||
|
} |
||||
|
} |
||||
|
.login-button { |
||||
|
font-size: 32rpx; |
||||
|
margin-top: 92rpx; |
||||
|
width: 622rpx; |
||||
|
height: 86rpx; |
||||
|
border-radius: 42px; |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
background-color: #007aff; |
||||
|
color: #ffffff; |
||||
|
} |
||||
|
} |
||||
|
.agreement_area { |
||||
|
position: fixed; |
||||
|
bottom: 108rpx; |
||||
|
width: 750rpx; |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
.agreement { |
||||
|
font-size: 24rpx; |
||||
|
color: #555555; |
||||
|
.agreement_text { |
||||
|
font-size: 24rpx; |
||||
|
color: #007aff; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
</style> |
</style> |
||||
@ -1,7 +1,131 @@ |
|||||
import Vue from 'vue' |
import Vue from 'vue' |
||||
import Vuex from 'vuex' |
import Vuex from 'vuex' |
||||
|
import { isObject } from '@/utils/is' |
||||
|
|
||||
|
let qnToken = null, |
||||
|
userInfo = null, |
||||
|
supplierInfo = null, |
||||
|
uecToken = null |
||||
|
try { |
||||
|
uecToken = uni.getStorageSync('uecToken') |
||||
|
qnToken = uni.getStorageSync('qnToken') |
||||
|
userInfo = uni.getStorageSync('userInfo') |
||||
|
if (userInfo) { |
||||
|
userInfo = JSON.parse(userInfo) |
||||
|
} |
||||
|
supplierInfo = uni.getStorageSync('supplierInfo') |
||||
|
if (supplierInfo) { |
||||
|
supplierInfo = JSON.parse(supplierInfo) |
||||
|
} |
||||
|
} catch (e) { |
||||
|
console.error('初始化错误:', e) |
||||
|
} |
||||
|
|
||||
Vue.use(Vuex) |
Vue.use(Vuex) |
||||
const store = new Vuex.Store({ |
const store = new Vuex.Store({ |
||||
state: {} |
|
||||
|
state: { |
||||
|
uecToken: uecToken || '', |
||||
|
qnToken: qnToken || '', // token
|
||||
|
userInfo: userInfo || {}, // 用户信息
|
||||
|
supplierInfo: supplierInfo || {}, // 纸盘商信息
|
||||
|
nextPage: { |
||||
|
name: '', |
||||
|
data: {} |
||||
|
} |
||||
|
}, |
||||
|
mutations: { |
||||
|
setUecToken(state, token) { |
||||
|
try { |
||||
|
uni.setStorageSync('uecToken', token) |
||||
|
state.uecToken = token |
||||
|
} catch (e) { |
||||
|
console.error('更改uecToken失败:', e) |
||||
|
} |
||||
|
}, |
||||
|
removeUecToken(state) { |
||||
|
try { |
||||
|
uni.removeStorageSync('uecToken') |
||||
|
state.uecToken = '' |
||||
|
} catch (e) { |
||||
|
console.error('删除uecToken失败:', e) |
||||
|
} |
||||
|
}, |
||||
|
setToken(state, token) { |
||||
|
try { |
||||
|
uni.setStorageSync('qnToken', token) |
||||
|
state.qnToken = token |
||||
|
} catch (e) { |
||||
|
console.error('更改token失败:', e) |
||||
|
} |
||||
|
}, |
||||
|
removeToken(state) { |
||||
|
try { |
||||
|
uni.removeStorageSync('qnToken') |
||||
|
state.qnToken = '' |
||||
|
} catch (e) { |
||||
|
console.error('删除token失败:', e) |
||||
|
} |
||||
|
}, |
||||
|
setUserInfo(state, userInfo) { |
||||
|
if (!isObject(userInfo)) { |
||||
|
console.error('userInfo必须是对象') |
||||
|
return |
||||
|
} |
||||
|
try { |
||||
|
uni.setStorageSync('userInfo', JSON.stringify(userInfo)) |
||||
|
state.userInfo = userInfo |
||||
|
} catch (e) { |
||||
|
console.error('更改userInfo失败:', e) |
||||
|
} |
||||
|
}, |
||||
|
removeUserInfo(state) { |
||||
|
try { |
||||
|
uni.removeStorageSync('userInfo') |
||||
|
state.userInfo = {} |
||||
|
} catch (e) { |
||||
|
console.error('删除userInfo失败:', e) |
||||
|
} |
||||
|
}, |
||||
|
setSupplierInfo(state, supplierInfo) { |
||||
|
if (!isObject(supplierInfo)) { |
||||
|
console.error('supplierInfo必须是对象') |
||||
|
return |
||||
|
} |
||||
|
try { |
||||
|
uni.setStorageSync('supplierInfo', JSON.stringify(supplierInfo)) |
||||
|
state.supplierInfo = supplierInfo |
||||
|
} catch (e) { |
||||
|
console.error('更改supplierInfo失败:', e) |
||||
|
} |
||||
|
}, |
||||
|
removeSupplierInfo(state) { |
||||
|
try { |
||||
|
uni.removeStorageSync('supplierInfo') |
||||
|
state.supplierInfo = {} |
||||
|
} catch (e) { |
||||
|
console.error('删除supplierInfo失败:', e) |
||||
|
} |
||||
|
}, |
||||
|
setNextPage(state, nextPage) { |
||||
|
if (!isObject(nextPage)) { |
||||
|
console.error('nextPage必须是对象') |
||||
|
return |
||||
|
} |
||||
|
state.nextPage.name = nextPage.name || '' |
||||
|
state.nextPage.data = nextPage.data || {} |
||||
|
}, |
||||
|
removeNextPage(state) { |
||||
|
state.nextPage.name = '' |
||||
|
state.nextPage.data = {} |
||||
|
} |
||||
|
}, |
||||
|
actions: { |
||||
|
logout({ commit }) { |
||||
|
commit('removeUecToken') |
||||
|
commit('removeToken') |
||||
|
commit('removeUserInfo') |
||||
|
commit('removeSupplierInfo') |
||||
|
} |
||||
|
} |
||||
}) |
}) |
||||
export default store |
export default store |
||||
@ -0,0 +1,31 @@ |
|||||
|
## 1.0.0(2021-11-19) |
||||
|
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource) |
||||
|
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-easyinput](https://uniapp.dcloud.io/component/uniui/uni-easyinput) |
||||
|
## 0.1.4(2021-08-20) |
||||
|
- 修复 在 uni-forms 的动态表单中默认值校验不通过的 bug |
||||
|
## 0.1.3(2021-08-11) |
||||
|
- 修复 在 uni-forms 中重置表单,错误信息无法清除的问题 |
||||
|
## 0.1.2(2021-07-30) |
||||
|
- 优化 vue3下事件警告的问题 |
||||
|
## 0.1.1 |
||||
|
- 优化 errorMessage 属性支持 Boolean 类型 |
||||
|
## 0.1.0(2021-07-13) |
||||
|
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834) |
||||
|
## 0.0.16(2021-06-29) |
||||
|
- 修复 confirmType 属性(仅 type="text" 生效)导致多行文本框无法换行的 bug |
||||
|
## 0.0.15(2021-06-21) |
||||
|
- 修复 passwordIcon 属性拼写错误的 bug |
||||
|
## 0.0.14(2021-06-18) |
||||
|
- 新增 passwordIcon 属性,当type=password时是否显示小眼睛图标 |
||||
|
- 修复 confirmType 属性不生效的问题 |
||||
|
## 0.0.13(2021-06-04) |
||||
|
- 修复 disabled 状态可清出内容的 bug |
||||
|
## 0.0.12(2021-05-12) |
||||
|
- 新增 组件示例地址 |
||||
|
## 0.0.11(2021-05-07) |
||||
|
- 修复 input-border 属性不生效的问题 |
||||
|
## 0.0.10(2021-04-30) |
||||
|
- 修复 ios 遮挡文字、显示一半的问题 |
||||
|
## 0.0.9(2021-02-05) |
||||
|
- 调整为uni_modules目录规范 |
||||
|
- 优化 兼容 nvue 页面 |
||||
@ -0,0 +1,56 @@ |
|||||
|
/** |
||||
|
* @desc 函数防抖 |
||||
|
* @param func 目标函数 |
||||
|
* @param wait 延迟执行毫秒数 |
||||
|
* @param immediate true - 立即执行, false - 延迟执行 |
||||
|
*/ |
||||
|
export const debounce = function(func, wait = 1000, immediate = true) { |
||||
|
let timer; |
||||
|
console.log(1); |
||||
|
return function() { |
||||
|
console.log(123); |
||||
|
let context = this, |
||||
|
args = arguments; |
||||
|
if (timer) clearTimeout(timer); |
||||
|
if (immediate) { |
||||
|
let callNow = !timer; |
||||
|
timer = setTimeout(() => { |
||||
|
timer = null; |
||||
|
}, wait); |
||||
|
if (callNow) func.apply(context, args); |
||||
|
} else { |
||||
|
timer = setTimeout(() => { |
||||
|
func.apply(context, args); |
||||
|
}, wait) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
/** |
||||
|
* @desc 函数节流 |
||||
|
* @param func 函数 |
||||
|
* @param wait 延迟执行毫秒数 |
||||
|
* @param type 1 使用表时间戳,在时间段开始的时候触发 2 使用表定时器,在时间段结束的时候触发 |
||||
|
*/ |
||||
|
export const throttle = (func, wait = 1000, type = 1) => { |
||||
|
let previous = 0; |
||||
|
let timeout; |
||||
|
return function() { |
||||
|
let context = this; |
||||
|
let args = arguments; |
||||
|
if (type === 1) { |
||||
|
let now = Date.now(); |
||||
|
|
||||
|
if (now - previous > wait) { |
||||
|
func.apply(context, args); |
||||
|
previous = now; |
||||
|
} |
||||
|
} else if (type === 2) { |
||||
|
if (!timeout) { |
||||
|
timeout = setTimeout(() => { |
||||
|
timeout = null; |
||||
|
func.apply(context, args) |
||||
|
}, wait) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,461 @@ |
|||||
|
<template> |
||||
|
<view class="uni-easyinput" :class="{'uni-easyinput-error':msg}" :style="{color:inputBorder && msg?'#e43d33':styles.color}"> |
||||
|
<view class="uni-easyinput__content" :class="{'is-input-border':inputBorder ,'is-input-error-border':inputBorder && msg,'is-textarea':type==='textarea','is-disabled':disabled}" |
||||
|
:style="{'border-color':inputBorder && msg?'#dd524d':styles.borderColor,'background-color':disabled?styles.disableColor:''}"> |
||||
|
<uni-icons v-if="prefixIcon" class="content-clear-icon" :type="prefixIcon" color="#c0c4cc" @click="onClickIcon('prefix')"></uni-icons> |
||||
|
<textarea v-if="type === 'textarea'" class="uni-easyinput__content-textarea" :class="{'input-padding':inputBorder}" |
||||
|
:name="name" :value="val" :placeholder="placeholder" :placeholderStyle="placeholderStyle" :disabled="disabled" placeholder-class="uni-easyinput__placeholder-class" |
||||
|
:maxlength="inputMaxlength" :focus="focused" :autoHeight="autoHeight" @input="onInput" @blur="onBlur" @focus="onFocus" |
||||
|
@confirm="onConfirm"></textarea> |
||||
|
<input v-else :type="type === 'password'?'text':type" class="uni-easyinput__content-input" :style="{ |
||||
|
'padding-right':type === 'password' ||clearable || prefixIcon?'':'10px', |
||||
|
'padding-left':prefixIcon?'':'10px' |
||||
|
}" |
||||
|
:name="name" :value="val" :password="!showPassword && type === 'password'" :placeholder="placeholder" |
||||
|
:placeholderStyle="placeholderStyle" placeholder-class="uni-easyinput__placeholder-class" :disabled="disabled" :maxlength="inputMaxlength" :focus="focused" :confirmType="confirmType" @focus="onFocus" |
||||
|
@blur="onBlur" @input="onInput" @confirm="onConfirm" /> |
||||
|
<template v-if="type === 'password' && passwordIcon" > |
||||
|
<uni-icons v-if="val != '' " class="content-clear-icon" :class="{'is-textarea-icon':type==='textarea'}" :type="showPassword?'eye-slash-filled':'eye-filled'" |
||||
|
:size="18" color="#c0c4cc" @click="onEyes"></uni-icons> |
||||
|
</template> |
||||
|
<template v-else-if="suffixIcon"> |
||||
|
<uni-icons v-if="suffixIcon" class="content-clear-icon" :type="suffixIcon" color="#c0c4cc" @click="onClickIcon('suffix')"></uni-icons> |
||||
|
</template> |
||||
|
<template v-else> |
||||
|
<uni-icons class="content-clear-icon" :class="{'is-textarea-icon':type==='textarea'}" type="clear" :size="clearSize" |
||||
|
v-if="clearable && val && !disabled" color="#c0c4cc" @click="onClear"></uni-icons> |
||||
|
</template> |
||||
|
<slot name="right"></slot> |
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
// import { |
||||
|
// debounce, |
||||
|
// throttle |
||||
|
// } from './common.js' |
||||
|
/** |
||||
|
* Easyinput 输入框 |
||||
|
* @description 此组件可以实现表单的输入与校验,包括 "text" 和 "textarea" 类型。 |
||||
|
* @tutorial https://ext.dcloud.net.cn/plugin?id=3455 |
||||
|
* @property {String} value 输入内容 |
||||
|
* @property {String } type 输入框的类型(默认text) password/text/textarea/.. |
||||
|
* @value text 文本输入键盘 |
||||
|
* @value textarea 多行文本输入键盘 |
||||
|
* @value password 密码输入键盘 |
||||
|
* @value number 数字输入键盘,注意iOS上app-vue弹出的数字键盘并非9宫格方式 |
||||
|
* @value idcard 身份证输入键盘,信、支付宝、百度、QQ小程序 |
||||
|
* @value digit 带小数点的数字键盘 ,App的nvue页面、微信、支付宝、百度、头条、QQ小程序支持 |
||||
|
* @property {Boolean} clearable 是否显示右侧清空内容的图标控件,点击可清空输入框内容(默认true) |
||||
|
* @property {Boolean} autoHeight 是否自动增高输入区域,type为textarea时有效(默认true) |
||||
|
* @property {String } placeholder 输入框的提示文字 |
||||
|
* @property {String } placeholderStyle placeholder的样式(内联样式,字符串),如"color: #ddd" |
||||
|
* @property {Boolean} focus 是否自动获得焦点(默认false) |
||||
|
* @property {Boolean} disabled 是否禁用(默认false) |
||||
|
* @property {Number } maxlength 最大输入长度,设置为 -1 的时候不限制最大长度(默认140) |
||||
|
* @property {String } confirmType 设置键盘右下角按钮的文字,仅在type="text"时生效(默认done) |
||||
|
* @property {Number } clearSize 清除图标的大小,单位px(默认15) |
||||
|
* @property {String} prefixIcon 输入框头部图标 |
||||
|
* @property {String} suffixIcon 输入框尾部图标 |
||||
|
* @property {Boolean} trim 是否自动去除两端的空格 |
||||
|
* @value both 去除两端空格 |
||||
|
* @value left 去除左侧空格 |
||||
|
* @value right 去除右侧空格 |
||||
|
* @value start 去除左侧空格 |
||||
|
* @value end 去除右侧空格 |
||||
|
* @value all 去除全部空格 |
||||
|
* @value none 不去除空格 |
||||
|
* @property {Boolean} inputBorder 是否显示input输入框的边框(默认true) |
||||
|
* @property {Boolean} passwordIcon type=password时是否显示小眼睛图标 |
||||
|
* @property {Object} styles 自定义颜色 |
||||
|
* @event {Function} input 输入框内容发生变化时触发 |
||||
|
* @event {Function} focus 输入框获得焦点时触发 |
||||
|
* @event {Function} blur 输入框失去焦点时触发 |
||||
|
* @event {Function} confirm 点击完成按钮时触发 |
||||
|
* @event {Function} iconClick 点击图标时触发 |
||||
|
* @example <uni-easyinput v-model="mobile"></uni-easyinput> |
||||
|
*/ |
||||
|
|
||||
|
export default { |
||||
|
name: 'uni-easyinput', |
||||
|
emits:['click','iconClick','update:modelValue','input','focus','blur','confirm'], |
||||
|
model:{ |
||||
|
prop:'modelValue', |
||||
|
event:'update:modelValue' |
||||
|
}, |
||||
|
props: { |
||||
|
name: String, |
||||
|
value: [Number, String], |
||||
|
modelValue: [Number, String], |
||||
|
type: { |
||||
|
type: String, |
||||
|
default: 'text' |
||||
|
}, |
||||
|
clearable: { |
||||
|
type: Boolean, |
||||
|
default: true |
||||
|
}, |
||||
|
autoHeight: { |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
placeholder: String, |
||||
|
placeholderStyle: String, |
||||
|
focus: { |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
disabled: { |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
maxlength: { |
||||
|
type: [Number, String], |
||||
|
default: 140 |
||||
|
}, |
||||
|
confirmType: { |
||||
|
type: String, |
||||
|
default: 'done' |
||||
|
}, |
||||
|
clearSize: { |
||||
|
type: [Number, String], |
||||
|
default: 15 |
||||
|
}, |
||||
|
inputBorder: { |
||||
|
type: Boolean, |
||||
|
default: true |
||||
|
}, |
||||
|
prefixIcon: { |
||||
|
type: String, |
||||
|
default: '' |
||||
|
}, |
||||
|
suffixIcon: { |
||||
|
type: String, |
||||
|
default: '' |
||||
|
}, |
||||
|
trim: { |
||||
|
type: [Boolean, String], |
||||
|
default: true |
||||
|
}, |
||||
|
passwordIcon:{ |
||||
|
type: Boolean, |
||||
|
default: true |
||||
|
}, |
||||
|
styles: { |
||||
|
type: Object, |
||||
|
default () { |
||||
|
return { |
||||
|
color: '#333', |
||||
|
disableColor: '#F7F6F6', |
||||
|
borderColor: '#e5e5e5' |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
errorMessage:{ |
||||
|
type:[String,Boolean], |
||||
|
default:'' |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
focused: false, |
||||
|
errMsg: '', |
||||
|
val: '', |
||||
|
showMsg: '', |
||||
|
border: false, |
||||
|
isFirstBorder: false, |
||||
|
showClearIcon: false, |
||||
|
showPassword: false |
||||
|
}; |
||||
|
}, |
||||
|
computed: { |
||||
|
msg() { |
||||
|
return this.errorMessage || this.errMsg; |
||||
|
}, |
||||
|
// 因为uniapp的input组件的maxlength组件必须要数值,这里转为数值,用户可以传入字符串数值 |
||||
|
inputMaxlength() { |
||||
|
return Number(this.maxlength); |
||||
|
}, |
||||
|
}, |
||||
|
watch: { |
||||
|
value(newVal) { |
||||
|
if (this.errMsg) this.errMsg = '' |
||||
|
this.val = newVal |
||||
|
// fix by mehaotian is_reset 在 uni-forms 中定义 |
||||
|
if (this.form && this.formItem &&!this.is_reset) { |
||||
|
this.is_reset = false |
||||
|
this.formItem.setValue(newVal) |
||||
|
} |
||||
|
}, |
||||
|
modelValue(newVal) { |
||||
|
if (this.errMsg) this.errMsg = '' |
||||
|
this.val = newVal |
||||
|
if (this.form && this.formItem &&!this.is_reset) { |
||||
|
this.is_reset = false |
||||
|
this.formItem.setValue(newVal) |
||||
|
} |
||||
|
}, |
||||
|
focus(newVal) { |
||||
|
this.$nextTick(() => { |
||||
|
this.focused = this.focus |
||||
|
}) |
||||
|
} |
||||
|
}, |
||||
|
created() { |
||||
|
if(!this.value){ |
||||
|
this.val = this.modelValue |
||||
|
} |
||||
|
if(!this.modelValue){ |
||||
|
this.val = this.value |
||||
|
} |
||||
|
this.form = this.getForm('uniForms') |
||||
|
this.formItem = this.getForm('uniFormsItem') |
||||
|
if (this.form && this.formItem) { |
||||
|
if (this.formItem.name) { |
||||
|
if(!this.is_reset){ |
||||
|
this.is_reset = false |
||||
|
this.formItem.setValue(this.val) |
||||
|
} |
||||
|
this.rename = this.formItem.name |
||||
|
this.form.inputChildrens.push(this) |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
mounted() { |
||||
|
this.$nextTick(() => { |
||||
|
this.focused = this.focus |
||||
|
}) |
||||
|
}, |
||||
|
methods: { |
||||
|
/** |
||||
|
* 初始化变量值 |
||||
|
*/ |
||||
|
init() { |
||||
|
|
||||
|
}, |
||||
|
onClickIcon(type) { |
||||
|
this.$emit('iconClick', type) |
||||
|
}, |
||||
|
/** |
||||
|
* 获取父元素实例 |
||||
|
*/ |
||||
|
getForm(name = 'uniForms') { |
||||
|
let parent = this.$parent; |
||||
|
let parentName = parent.$options.name; |
||||
|
while (parentName !== name) { |
||||
|
parent = parent.$parent; |
||||
|
if (!parent) return false; |
||||
|
parentName = parent.$options.name; |
||||
|
} |
||||
|
return parent; |
||||
|
}, |
||||
|
|
||||
|
onEyes() { |
||||
|
this.showPassword = !this.showPassword |
||||
|
}, |
||||
|
onInput(event) { |
||||
|
let value = event.detail.value; |
||||
|
// 判断是否去除空格 |
||||
|
if (this.trim) { |
||||
|
if (typeof(this.trim) === 'boolean' && this.trim) { |
||||
|
value = this.trimStr(value) |
||||
|
} |
||||
|
if (typeof(this.trim) === 'string') { |
||||
|
value = this.trimStr(value, this.trim) |
||||
|
} |
||||
|
}; |
||||
|
if (this.errMsg) this.errMsg = '' |
||||
|
this.val = value |
||||
|
// TODO 兼容 vue2 |
||||
|
this.$emit('input', value); |
||||
|
// TODO 兼容 vue3 |
||||
|
this.$emit('update:modelValue',value) |
||||
|
}, |
||||
|
|
||||
|
onFocus(event) { |
||||
|
this.$emit('focus', event); |
||||
|
}, |
||||
|
onBlur(event) { |
||||
|
let value = event.detail.value; |
||||
|
this.$emit('blur', event); |
||||
|
}, |
||||
|
onConfirm(e) { |
||||
|
this.$emit('confirm', e.detail.value); |
||||
|
}, |
||||
|
onClear(event) { |
||||
|
this.val = ''; |
||||
|
// TODO 兼容 vue2 |
||||
|
this.$emit('input', ''); |
||||
|
// TODO 兼容 vue2 |
||||
|
// TODO 兼容 vue3 |
||||
|
this.$emit('update:modelValue','') |
||||
|
}, |
||||
|
fieldClick() { |
||||
|
this.$emit('click'); |
||||
|
}, |
||||
|
trimStr(str, pos = 'both') { |
||||
|
if (pos === 'both') { |
||||
|
return str.trim(); |
||||
|
} else if (pos === 'left') { |
||||
|
return str.trimLeft(); |
||||
|
} else if (pos === 'right') { |
||||
|
return str.trimRight(); |
||||
|
} else if (pos === 'start') { |
||||
|
return str.trimStart() |
||||
|
} else if (pos === 'end') { |
||||
|
return str.trimEnd() |
||||
|
} else if (pos === 'all') { |
||||
|
return str.replace(/\s+/g, ''); |
||||
|
} else if (pos === 'none') { |
||||
|
return str; |
||||
|
} |
||||
|
return str; |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
$uni-error: #e43d33; |
||||
|
$uni-border-1: #DCDFE6 !default; |
||||
|
.uni-easyinput { |
||||
|
/* #ifndef APP-NVUE */ |
||||
|
width: 100%; |
||||
|
/* #endif */ |
||||
|
flex: 1; |
||||
|
position: relative; |
||||
|
text-align: left; |
||||
|
color: #333; |
||||
|
font-size: 14px; |
||||
|
} |
||||
|
|
||||
|
.uni-easyinput__content { |
||||
|
flex: 1; |
||||
|
/* #ifndef APP-NVUE */ |
||||
|
width: 100%; |
||||
|
display: flex; |
||||
|
box-sizing: border-box; |
||||
|
min-height: 36px; |
||||
|
/* #endif */ |
||||
|
flex-direction: row; |
||||
|
align-items: center; |
||||
|
} |
||||
|
|
||||
|
.uni-easyinput__content-input { |
||||
|
/* #ifndef APP-NVUE */ |
||||
|
width: auto; |
||||
|
/* #endif */ |
||||
|
position: relative; |
||||
|
overflow: hidden; |
||||
|
flex: 1; |
||||
|
line-height: 1; |
||||
|
font-size: 14px; |
||||
|
} |
||||
|
.uni-easyinput__placeholder-class { |
||||
|
color: #999; |
||||
|
font-size: 12px; |
||||
|
font-weight: 200; |
||||
|
} |
||||
|
.is-textarea { |
||||
|
align-items: flex-start; |
||||
|
} |
||||
|
|
||||
|
.is-textarea-icon { |
||||
|
margin-top: 5px; |
||||
|
} |
||||
|
|
||||
|
.uni-easyinput__content-textarea { |
||||
|
position: relative; |
||||
|
overflow: hidden; |
||||
|
flex: 1; |
||||
|
line-height: 1.5; |
||||
|
font-size: 14px; |
||||
|
padding-top: 6px; |
||||
|
padding-bottom: 10px; |
||||
|
height: 80px; |
||||
|
/* #ifndef APP-NVUE */ |
||||
|
min-height: 80px; |
||||
|
width: auto; |
||||
|
/* #endif */ |
||||
|
} |
||||
|
|
||||
|
.input-padding { |
||||
|
padding-left: 10px; |
||||
|
} |
||||
|
|
||||
|
.content-clear-icon { |
||||
|
padding: 0 5px; |
||||
|
} |
||||
|
|
||||
|
.label-icon { |
||||
|
margin-right: 5px; |
||||
|
margin-top: -1px; |
||||
|
} |
||||
|
|
||||
|
// 显示边框 |
||||
|
.is-input-border { |
||||
|
/* #ifndef APP-NVUE */ |
||||
|
display: flex; |
||||
|
box-sizing: border-box; |
||||
|
/* #endif */ |
||||
|
flex-direction: row; |
||||
|
align-items: center; |
||||
|
border: 1px solid $uni-border-1; |
||||
|
border-radius: 4px; |
||||
|
} |
||||
|
|
||||
|
.uni-error-message { |
||||
|
position: absolute; |
||||
|
bottom: -17px; |
||||
|
left: 0; |
||||
|
line-height: 12px; |
||||
|
color: $uni-error; |
||||
|
font-size: 12px; |
||||
|
text-align: left; |
||||
|
} |
||||
|
|
||||
|
.uni-error-msg--boeder { |
||||
|
position: relative; |
||||
|
bottom: 0; |
||||
|
line-height: 22px; |
||||
|
} |
||||
|
|
||||
|
.is-input-error-border { |
||||
|
border-color: $uni-error; |
||||
|
.uni-easyinput__placeholder-class { |
||||
|
color: mix(#fff, $uni-error, 50%);; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
.uni-easyinput--border { |
||||
|
margin-bottom: 0; |
||||
|
padding: 10px 15px; |
||||
|
// padding-bottom: 0; |
||||
|
border-top: 1px #eee solid; |
||||
|
} |
||||
|
|
||||
|
.uni-easyinput-error { |
||||
|
padding-bottom: 0; |
||||
|
} |
||||
|
|
||||
|
.is-first-border { |
||||
|
/* #ifndef APP-NVUE */ |
||||
|
border: none; |
||||
|
/* #endif */ |
||||
|
/* #ifdef APP-NVUE */ |
||||
|
border-width: 0; |
||||
|
/* #endif */ |
||||
|
} |
||||
|
|
||||
|
.is-disabled { |
||||
|
border-color: red; |
||||
|
background-color: #F7F6F6; |
||||
|
color: #D5D5D5; |
||||
|
.uni-easyinput__placeholder-class { |
||||
|
color: #D5D5D5; |
||||
|
font-size: 12px; |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,90 @@ |
|||||
|
{ |
||||
|
"id": "uni-easyinput", |
||||
|
"displayName": "uni-easyinput 增强输入框", |
||||
|
"version": "1.0.0", |
||||
|
"description": "Easyinput 组件是对原生input组件的增强", |
||||
|
"keywords": [ |
||||
|
"uni-ui", |
||||
|
"uniui", |
||||
|
"input", |
||||
|
"uni-easyinput", |
||||
|
"输入框" |
||||
|
], |
||||
|
"repository": "https://github.com/dcloudio/uni-ui", |
||||
|
"engines": { |
||||
|
"HBuilderX": "" |
||||
|
}, |
||||
|
"directories": { |
||||
|
"example": "../../temps/example_temps" |
||||
|
}, |
||||
|
"dcloudext": { |
||||
|
"category": [ |
||||
|
"前端组件", |
||||
|
"通用组件" |
||||
|
], |
||||
|
"sale": { |
||||
|
"regular": { |
||||
|
"price": "0.00" |
||||
|
}, |
||||
|
"sourcecode": { |
||||
|
"price": "0.00" |
||||
|
} |
||||
|
}, |
||||
|
"contact": { |
||||
|
"qq": "" |
||||
|
}, |
||||
|
"declaration": { |
||||
|
"ads": "无", |
||||
|
"data": "无", |
||||
|
"permissions": "无" |
||||
|
}, |
||||
|
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui" |
||||
|
}, |
||||
|
"uni_modules": { |
||||
|
"dependencies": [ |
||||
|
"uni-scss", |
||||
|
"uni-icons" |
||||
|
], |
||||
|
"encrypt": [], |
||||
|
"platforms": { |
||||
|
"cloud": { |
||||
|
"tcb": "y", |
||||
|
"aliyun": "y" |
||||
|
}, |
||||
|
"client": { |
||||
|
"App": { |
||||
|
"app-vue": "y", |
||||
|
"app-nvue": "y" |
||||
|
}, |
||||
|
"H5-mobile": { |
||||
|
"Safari": "y", |
||||
|
"Android Browser": "y", |
||||
|
"微信浏览器(Android)": "y", |
||||
|
"QQ浏览器(Android)": "y" |
||||
|
}, |
||||
|
"H5-pc": { |
||||
|
"Chrome": "y", |
||||
|
"IE": "y", |
||||
|
"Edge": "y", |
||||
|
"Firefox": "y", |
||||
|
"Safari": "y" |
||||
|
}, |
||||
|
"小程序": { |
||||
|
"微信": "y", |
||||
|
"阿里": "y", |
||||
|
"百度": "y", |
||||
|
"字节跳动": "y", |
||||
|
"QQ": "y" |
||||
|
}, |
||||
|
"快应用": { |
||||
|
"华为": "u", |
||||
|
"联盟": "u" |
||||
|
}, |
||||
|
"Vue": { |
||||
|
"vue2": "y", |
||||
|
"vue3": "y" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
|
||||
|
|
||||
|
### Easyinput 增强输入框 |
||||
|
> **组件名:uni-easyinput** |
||||
|
> 代码块: `uEasyinput` |
||||
|
|
||||
|
|
||||
|
easyinput 组件是对原生input组件的增强 ,是专门为配合表单组件[uni-forms](https://ext.dcloud.net.cn/plugin?id=2773)而设计的,easyinput 内置了边框,图标等,同时包含 input 所有功能 |
||||
|
|
||||
|
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-easyinput) |
||||
|
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 |
||||
@ -1,14 +1,82 @@ |
|||||
|
import store from '@/store/index' |
||||
// 框架方法封装
|
// 框架方法封装
|
||||
const tabList = ['client','trade','mall','mine'] |
|
||||
|
const tabList = ['store', 'cart', 'mine'] |
||||
|
|
||||
/** |
/** |
||||
* @param {string} 跳转的tabBar页面 |
|
||||
|
* @param {string} 跳转的tabBar页面 |
||||
* @return {null} |
* @return {null} |
||||
*/ |
*/ |
||||
export function tab2(tabPage) { |
export function tab2(tabPage) { |
||||
if(tabList.includes(tabPage)) { |
|
||||
uni.switchTab({ |
|
||||
url:`/pages/${tabPage}/index` |
|
||||
}) |
|
||||
} |
|
||||
} |
|
||||
|
if (tabList.includes(tabPage)) { |
||||
|
uni.switchTab({ |
||||
|
url: `/pages/${tabPage}/index` |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
/** |
||||
|
* @param {string} 返回上一级 |
||||
|
* @return {null} |
||||
|
*/ |
||||
|
export function back() { |
||||
|
if (getCurrentPages().length > 1) { |
||||
|
uni.navigateBack({ |
||||
|
delta: 1 |
||||
|
}) |
||||
|
} else { |
||||
|
go2('client') |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 跳转到指定页面,包括tabBar页面 |
||||
|
* @param {string} url 页面名称 |
||||
|
* @param {object} data 页面参数 |
||||
|
* @param {string} isRedirect 是否重定向 默认false |
||||
|
* @return {null} |
||||
|
*/ |
||||
|
export function go2(url, data = {}, isRedirect = false) { |
||||
|
if (!url) { |
||||
|
console.error('请选择页面') |
||||
|
return |
||||
|
} |
||||
|
let param = '' |
||||
|
Object.keys(data).forEach((key) => { |
||||
|
if (param === '') { |
||||
|
param = `${key}=${data[key]}` |
||||
|
} else { |
||||
|
param += `&${key}=${data[key]}` |
||||
|
} |
||||
|
}) |
||||
|
if (tabList.includes(url)) { |
||||
|
uni.switchTab({ |
||||
|
url: `/pages/${url}/index${param ? '?' + param : ''}` |
||||
|
}) |
||||
|
} else { |
||||
|
if (isRedirect) { |
||||
|
uni.redirectTo({ |
||||
|
url: `/pages/${url}/index${param ? '?' + param : ''}` |
||||
|
}) |
||||
|
} else { |
||||
|
uni.navigateTo({ |
||||
|
url: `/pages/${url}/index${param ? '?' + param : ''}` |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 跳转到指定页面,包括tabBar页面,校验是否已登录,未登录则跳转到登录页面 |
||||
|
* @param {string} url 页面名称 |
||||
|
* @param {object} data 页面参数 |
||||
|
* @param {string} isRedirect 是否重定向 默认false |
||||
|
* @return {null} |
||||
|
*/ |
||||
|
export function loginGo2(url, data = {}, isRedirect) { |
||||
|
const token = store.state.qnToken |
||||
|
if (token) { |
||||
|
go2(url, data, isRedirect) |
||||
|
} else { |
||||
|
store.commit('setNextPage', { name: url, data }) |
||||
|
go2('login') |
||||
|
} |
||||
|
} |
||||
@ -1,112 +1,109 @@ |
|||||
import { |
|
||||
isFunction |
|
||||
} from '../is.js' |
|
||||
const urlEnv = process.env.NODE_ENV === 'production' ? '-test' : '' |
|
||||
|
import { isFunction } from '../is.js' |
||||
|
const urlEnv = process.env.NODE_ENV === 'production' ? '' : '-test' |
||||
const uplaodUrl = `https://api-ops-yyt${urlEnv}.qniao.cn/cloud-print-user-center/utils/uploadImage` |
const uplaodUrl = `https://api-ops-yyt${urlEnv}.qniao.cn/cloud-print-user-center/utils/uploadImage` |
||||
export default class Http { |
export default class Http { |
||||
constructor(config = {}, { |
|
||||
reqInterceptor, |
|
||||
resInterceptor, |
|
||||
tranformConfig |
|
||||
} = {}) { |
|
||||
this.baseUrl = config.baseUrl |
|
||||
this.header = config.header || { |
|
||||
'content-type': 'application/json;charset=UTF-8' |
|
||||
} |
|
||||
this.requestOption = config.requestOption || {} |
|
||||
this.reqInterceptor = reqInterceptor |
|
||||
this.resInterceptor = resInterceptor |
|
||||
this.tranformConfig = tranformConfig |
|
||||
} |
|
||||
post(config, options) { |
|
||||
return this.request({ |
|
||||
method: 'POST', |
|
||||
...config |
|
||||
}, options) |
|
||||
} |
|
||||
get(config, options) { |
|
||||
return this.request({ |
|
||||
method: 'GET', |
|
||||
...config |
|
||||
}, options) |
|
||||
} |
|
||||
/** |
|
||||
* @param {Object} config 和请求相关的参数 |
|
||||
* @param {Object} options 对请求数据进行额外处理的参数 |
|
||||
*/ |
|
||||
request(config, options) { |
|
||||
let conf = Object.assign({}, config) |
|
||||
const { |
|
||||
tranformConfig, |
|
||||
reqInterceptor, |
|
||||
resInterceptor |
|
||||
} = this |
|
||||
if (tranformConfig && isFunction(tranformConfig)) { |
|
||||
conf = tranformConfig(this, config) |
|
||||
} |
|
||||
let opt = Object.assign({}, this.requestOption, options) |
|
||||
if (reqInterceptor && isFunction(reqInterceptor)) { |
|
||||
conf = reqInterceptor(conf, opt) |
|
||||
} |
|
||||
return new Promise((resolve, reject) => { |
|
||||
uni.request({ |
|
||||
url: conf.url, |
|
||||
data: conf.data, |
|
||||
header: conf.header, |
|
||||
success: (res) => { |
|
||||
console.log('native response', res) |
|
||||
let data = resInterceptor(res, opt) |
|
||||
// 服务器错误也会用then抛出,需要自己判断data==null
|
|
||||
resolve(data) |
|
||||
}, |
|
||||
fail: (err) => { |
|
||||
uni.showToast({ |
|
||||
title: '发生未知错误,请联系客服' |
|
||||
}) |
|
||||
reject(err) |
|
||||
} |
|
||||
}) |
|
||||
}).catch(err => { |
|
||||
// 吃掉请求产生的异常
|
|
||||
// 后期可以记录
|
|
||||
console.log('native response error', err) |
|
||||
}) |
|
||||
} |
|
||||
// config:{}
|
|
||||
uploadFile(config, options) { |
|
||||
return new Promise((resolve, rejetc) => { |
|
||||
let conf = Object.assign({}, config) |
|
||||
conf.url = uplaodUrl |
|
||||
const { |
|
||||
reqInterceptor |
|
||||
} = this |
|
||||
let opt = Object.assign({}, this.requestOption, options) |
|
||||
if (reqInterceptor && isFunction(reqInterceptor)) { |
|
||||
conf = reqInterceptor(conf, opt) |
|
||||
} |
|
||||
delete conf.header['Content-Type'] |
|
||||
uni.uploadFile({ |
|
||||
url: conf.url, |
|
||||
header: { |
|
||||
...conf.header, |
|
||||
image: config.data.filePath, |
|
||||
// 'Content-Type': 'image/png'
|
|
||||
}, |
|
||||
filePath: config.data.filePath, |
|
||||
name: config.data.fileName || 'image', |
|
||||
formData: { |
|
||||
image: config.data.filePath |
|
||||
}, |
|
||||
success: (res) => { |
|
||||
uni.hideLoading() |
|
||||
resolve(res.data) |
|
||||
}, |
|
||||
fail: (err) => { |
|
||||
reject(err) |
|
||||
} |
|
||||
}) |
|
||||
}).catch(err => { |
|
||||
console.log('upload native err', err) |
|
||||
}) |
|
||||
} |
|
||||
|
constructor( |
||||
|
config = {}, |
||||
|
{ reqInterceptor, resInterceptor, tranformConfig } = {} |
||||
|
) { |
||||
|
this.baseUrl = config.baseUrl |
||||
|
this.header = config.header || { |
||||
|
'content-type': 'application/json;charset=UTF-8' |
||||
|
} |
||||
|
this.requestOption = config.requestOption || {} |
||||
|
this.reqInterceptor = reqInterceptor |
||||
|
this.resInterceptor = resInterceptor |
||||
|
this.tranformConfig = tranformConfig |
||||
|
} |
||||
|
post(config, options) { |
||||
|
return this.request( |
||||
|
{ |
||||
|
method: 'POST', |
||||
|
...config |
||||
|
}, |
||||
|
options |
||||
|
) |
||||
|
} |
||||
|
get(config, options) { |
||||
|
return this.request( |
||||
|
{ |
||||
|
method: 'GET', |
||||
|
...config |
||||
|
}, |
||||
|
options |
||||
|
) |
||||
|
} |
||||
|
/** |
||||
|
* @param {Object} config 和请求相关的参数 |
||||
|
* @param {Object} options 对请求数据进行额外处理的参数 |
||||
|
*/ |
||||
|
request(config, options) { |
||||
|
let conf = Object.assign({}, config) |
||||
|
const { tranformConfig, reqInterceptor, resInterceptor } = this |
||||
|
if (tranformConfig && isFunction(tranformConfig)) { |
||||
|
conf = tranformConfig(this, config) |
||||
|
} |
||||
|
let opt = Object.assign({}, this.requestOption, options) |
||||
|
if (reqInterceptor && isFunction(reqInterceptor)) { |
||||
|
conf = reqInterceptor(conf, opt) |
||||
|
} |
||||
|
return new Promise((resolve, reject) => { |
||||
|
uni.request({ |
||||
|
url: conf.url, |
||||
|
data: conf.data, |
||||
|
header: conf.header, |
||||
|
method: conf.method, |
||||
|
success: (res) => { |
||||
|
let data = resInterceptor(res, opt) |
||||
|
// 服务器错误也会用then抛出,需要自己判断data==null
|
||||
|
resolve(data) |
||||
|
}, |
||||
|
fail: (err) => { |
||||
|
uni.showToast({ |
||||
|
title: '发生未知错误,请联系客服' |
||||
|
}) |
||||
|
reject(err) |
||||
|
} |
||||
|
}) |
||||
|
}).catch((err) => { |
||||
|
// 吃掉请求产生的异常
|
||||
|
// 后期可以记录
|
||||
|
console.log('native response error', err) |
||||
|
}) |
||||
|
} |
||||
|
// config:{}
|
||||
|
uploadFile(config, options) { |
||||
|
return new Promise((resolve, rejetc) => { |
||||
|
let conf = Object.assign({}, config) |
||||
|
conf.url = uplaodUrl |
||||
|
const { reqInterceptor } = this |
||||
|
let opt = Object.assign({}, this.requestOption, options) |
||||
|
if (reqInterceptor && isFunction(reqInterceptor)) { |
||||
|
conf = reqInterceptor(conf, opt) |
||||
|
} |
||||
|
delete conf.header['Content-Type'] |
||||
|
uni.uploadFile({ |
||||
|
url: conf.url, |
||||
|
header: { |
||||
|
...conf.header, |
||||
|
image: config.data.filePath |
||||
|
// 'Content-Type': 'image/png'
|
||||
|
}, |
||||
|
filePath: config.data.filePath, |
||||
|
name: config.data.fileName || 'image', |
||||
|
formData: { |
||||
|
image: config.data.filePath |
||||
|
}, |
||||
|
success: (res) => { |
||||
|
uni.hideLoading() |
||||
|
resolve(res.data) |
||||
|
}, |
||||
|
fail: (err) => { |
||||
|
reject(err) |
||||
|
} |
||||
|
}) |
||||
|
}).catch((err) => { |
||||
|
console.log('upload native err', err) |
||||
|
}) |
||||
|
} |
||||
} |
} |
||||
Write
Preview
Loading…
Cancel
Save