@@ -46,3 +46,9 @@ npm run lint | |||
- 增加 封装 toast ,notify 和 dialog | |||
- 增加 亲情号码,增加/修改亲情号码页面 | |||
- 修改 tabBar 文件 | |||
`2023年12月20日` FETURE | |||
- 增加 路由拦截 | |||
- 增加 登陆和绑定页面 | |||
- 修改 tabbar 图标 |
@@ -1,4 +0,0 @@ | |||
// import qs from 'qs' | |||
// axios | |||
// import request from '@/utils/request' | |||
// home api |
@@ -1,7 +0,0 @@ | |||
const api = { | |||
Login: '/user/login', | |||
UserInfo: '/user/userinfo', | |||
UserName: '/user/name' | |||
}; | |||
export default api; |
@@ -9,7 +9,9 @@ export const APIUser = { | |||
modifyPassword, | |||
alarmList, | |||
getAdminList, //管理员列表 | |||
wxAutoLogin //微信自动登录 | |||
wxAutoLogin, //微信自动登录 | |||
getVerificationCode, //获取手机验证码 | |||
wxLogin //微信登陆 | |||
}; | |||
export default APIUser; | |||
// 获取用户信息 | |||
@@ -85,3 +87,19 @@ function wxAutoLogin(params) { | |||
data: params | |||
}); | |||
} | |||
function getVerificationCode(params) { | |||
return request({ | |||
url: `/api/User/VerificationCode`, | |||
method: 'post', | |||
headers: { AuthKey: 'key1' }, | |||
data: params | |||
}); | |||
} | |||
function wxLogin(params) { | |||
return request({ | |||
url: `/api/User/WxLogin`, | |||
method: 'post', | |||
headers: { AuthKey: 'key1' }, | |||
data: params | |||
}); | |||
} |
@@ -1,8 +1,11 @@ | |||
<template> | |||
<div> | |||
<van-tabbar fixed route v-model="active" @change="handleChange"> | |||
<van-tabbar-item v-for="(item, index) in tabbars" :to="item.to" :icon="item.icon" :key="index"> | |||
<van-tabbar-item v-for="(item, index) in tabbars" :to="item.to" :key="index"> | |||
{{ item.title }} | |||
<template #icon="props"> | |||
<img :src="props.active ? item.icon.active : item.icon.inactive" /> | |||
</template> | |||
</van-tabbar-item> | |||
</van-tabbar> | |||
</div> | |||
@@ -25,35 +28,50 @@ export default { | |||
to: { | |||
name: 'Development' | |||
}, | |||
icon: 'guide-o' | |||
icon: { | |||
active: require('../assets/com-imges/55_41.png'), | |||
inactive: require('../assets/com-imges/55_17.png') | |||
} | |||
}, | |||
{ | |||
title: '今日', | |||
to: { | |||
name: 'Today' | |||
}, | |||
icon: 'notes-o' | |||
icon: { | |||
active: require('../assets/com-imges/55_36.png'), | |||
inactive: require('../assets/com-imges/55_20.png') | |||
} | |||
}, | |||
{ | |||
title: '洞悉', | |||
to: { | |||
name: 'Insight' | |||
}, | |||
icon: 'apps-o' | |||
icon: { | |||
active: require('../assets/com-imges/55_38.png'), | |||
inactive: require('../assets/com-imges/55_22.png') | |||
} | |||
}, | |||
{ | |||
title: '优化', | |||
to: { | |||
name: 'Optimize' | |||
}, | |||
icon: 'diamond-o' | |||
icon: { | |||
active: require('../assets/com-imges/55_44.png'), | |||
inactive: require('../assets/com-imges/55_25.png') | |||
} | |||
}, | |||
{ | |||
title: '我的', | |||
to: { | |||
name: 'Myself' | |||
}, | |||
icon: 'user-circle-o' | |||
icon: { | |||
active: require('../assets/com-imges/55_33.png'), | |||
inactive: require('../assets/com-imges/55_14.png') | |||
} | |||
} | |||
] | |||
}; | |||
@@ -1,5 +1,7 @@ | |||
import Vue from 'vue'; | |||
import Router from 'vue-router'; | |||
import store from '@/store/index'; | |||
import prefix from '@/store/prefix'; | |||
import { constantRouterMap } from './router.config.js'; | |||
// hack router push callback | |||
@@ -27,4 +29,17 @@ export function resetRouter() { | |||
router.matcher = newRouter.matcher; // reset router | |||
} | |||
// TODO 增加路由拦截 | |||
router.beforeEach((to, from, next) => { | |||
store.commit('fromRuoter', from.name); | |||
if (to.path == '/login') { | |||
next(); | |||
} else { | |||
let token = localStorage.getItem(prefix + 'authToken'); | |||
if (token == null || token == '') { | |||
next({ name: 'login' }); | |||
} else { | |||
next(); | |||
} | |||
} | |||
}); | |||
export default router; |
@@ -247,6 +247,18 @@ export const constantRouterMap = [ | |||
name: 'news', | |||
component: () => import('@/views/myself/news/news'), | |||
meta: { title: '消息', keepAlive: false } | |||
}, | |||
{ | |||
path: '/login', | |||
name: 'login', | |||
component: () => import('@/views/login/login'), | |||
meta: { title: '登录', keepAlive: false } | |||
}, | |||
{ | |||
path: '/bind', | |||
name: 'bind', | |||
component: () => import('@/views/login/bindDevices'), | |||
meta: { title: '绑定设备', keepAlive: false } | |||
} | |||
] | |||
} | |||
@@ -1,2 +1,2 @@ | |||
const prefix = 'card_parent_'; | |||
const prefix = 'health_student_'; | |||
export default prefix; |
@@ -0,0 +1,134 @@ | |||
<!-- --> | |||
<template> | |||
<div class="bind"> | |||
<NavBar title="绑定设备" @on-click-left="onNavBack"></NavBar> | |||
<div class="main"> | |||
<div class="top"> | |||
<van-button size="small" round type="default" class="btn-def">暂不绑定</van-button> | |||
</div> | |||
<div class="bind-con"> | |||
<div class="scan"> | |||
<p>申请获取并验证你的手机号</p> | |||
<img :src="scanImg" alt="" /> | |||
</div> | |||
<div class="cut-line"> | |||
<span>----------或手动填写绑定----------</span> | |||
</div> | |||
<div class="input"> | |||
<van-field v-model="imei" placeholder="请填写设备码" input-align="right"> | |||
<template #label> | |||
<p class="input-label">设备码</p> | |||
</template> | |||
</van-field> | |||
</div> | |||
</div> | |||
</div> | |||
<div class="bottom"> | |||
<div class="btn"> | |||
<van-button size="large" round @click="onNext" :color="$green" class="next-text">下一步</van-button> | |||
</div> | |||
</div> | |||
</div> | |||
</template> | |||
<script> | |||
import NavBar from '@/components/NavBar.vue'; | |||
export default { | |||
components: { NavBar }, | |||
data() { | |||
return { | |||
scanImg: require('../../assets/com-imges/55_10.png'), | |||
imei: '' | |||
}; | |||
}, | |||
created() {}, | |||
mounted() {}, | |||
methods: { | |||
onNavBack() { | |||
this.$router.back(); | |||
}, | |||
onNext() { | |||
this.$router.push({ | |||
name: 'Index' | |||
}); | |||
} | |||
} | |||
}; | |||
</script> | |||
<style scoped lang="scss"> | |||
.bind { | |||
height: 100vh; | |||
overflow: hidden; | |||
.main { | |||
position: relative; | |||
overflow: scroll; | |||
padding: 100px 40px; | |||
.top { | |||
height: 60px; | |||
padding: 20px 0; | |||
display: flex; | |||
justify-content: flex-end; | |||
align-items: center; | |||
.btn-def { | |||
height: 40px; | |||
padding: 10px; | |||
border: 1px solid $green; | |||
} | |||
} | |||
.bind-con { | |||
position: relative; | |||
.scan { | |||
display: flex; | |||
justify-content: space-between; | |||
align-items: center; | |||
font-size: 34px; | |||
padding: 20px 0; | |||
p { | |||
font-size: 36px; | |||
font-weight: bold; | |||
} | |||
img { | |||
height: 60px; | |||
width: 60px; | |||
object-fit: contain; | |||
} | |||
} | |||
.cut-line { | |||
padding: 20px; | |||
font-size: 28px; | |||
color: $border_color; | |||
@include center(); | |||
} | |||
.input { | |||
padding: 20px 0; | |||
.van-cell { | |||
display: flex; | |||
justify-content: space-between; | |||
align-items: center; | |||
padding: 0 !important; | |||
.input-label { | |||
@include colorAndFont(#333, 18); | |||
font-weight: bold; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
.bottom { | |||
height: 120px; | |||
width: 100%; | |||
position: absolute; | |||
bottom: 10px; | |||
left: 0; | |||
@include center(); | |||
.btn { | |||
width: 100%; | |||
padding: 40px; | |||
.next-text { | |||
font-size: 48px; | |||
} | |||
} | |||
} | |||
} | |||
/* @import url(); 引入css类 */ | |||
</style> |
@@ -0,0 +1,43 @@ | |||
.login { | |||
position: relative; | |||
height: 100vh; | |||
width: 100%; | |||
overflow: hidden; | |||
@include center(); | |||
.login-con { | |||
flex: 1; | |||
padding: 90px 90px 0 90px; | |||
display: flex; | |||
justify-content: space-around; | |||
align-items: center; | |||
flex-direction: column; | |||
.login-bg-img { | |||
padding: 5%; | |||
@include center(); | |||
img { | |||
height: 100%; | |||
width: 100%; | |||
object-fit: contain; | |||
} | |||
} | |||
.login-btn { | |||
height: 120px; | |||
width: 520px; | |||
padding-top: 60px; | |||
.login-text { | |||
font-size: 48px; | |||
} | |||
} | |||
} | |||
.popup { | |||
padding: 60px; | |||
.login-text { | |||
margin-top: 30px; | |||
font-size: 48px; | |||
} | |||
} | |||
} |
@@ -0,0 +1,177 @@ | |||
import Vue from 'vue/types/umd'; | |||
<!-- --> | |||
<template> | |||
<div class="login"> | |||
<div class="login-con"> | |||
<div class="login-bg-img"> | |||
<img :src="bgImgPath" alt="" /> | |||
</div> | |||
<div class="login-btn"> | |||
<van-button type="primary" size="large" round @click="onLogin" :color="$green" class="login-text" | |||
>用户一键登录</van-button | |||
> | |||
</div> | |||
</div> | |||
<van-popup v-model="show" round position="bottom" :style="{ height: '50%' }"> | |||
<div class="popup"> | |||
<van-cell-group> | |||
<van-field | |||
v-model="phone" | |||
type="tel" | |||
maxlength="12" | |||
placeholder="请输入监护人手机号码" | |||
:error-message="errPhoneMsg" | |||
> | |||
<template #left-icon> </template> | |||
</van-field> | |||
<van-field | |||
v-model="verificacode" | |||
type="digit" | |||
maxlength="6" | |||
placeholder="请输入短信验证码" | |||
:error-message="errCodeMsg" | |||
> | |||
<template #button> | |||
<van-button size="small" round :color="$green" @click="sendCode" :disabled="sendMsgDisabled">{{ | |||
sendMsgDisabled ? '已发送(' + codeTime + ')' : '发送验证码' | |||
}}</van-button> | |||
</template> | |||
</van-field> | |||
</van-cell-group> | |||
<van-button size="large" round @click="onLogin('new')" :color="$green" class="login-text">注册/登录</van-button> | |||
</div> | |||
</van-popup> | |||
</div> | |||
</template> | |||
<script> | |||
import APIUser from '@/api/user'; | |||
import NotifyService from '@/services/notify-service'; | |||
import AppId from '@/config/appId'; | |||
export default { | |||
data() { | |||
const time = 120; | |||
return { | |||
bgImgPath: require('../../assets/com-imges/55_06.png'), | |||
show: false, | |||
verificacode: '', | |||
phone: '', | |||
errPhoneMsg: '', | |||
errCodeMsg: '', | |||
codeTime: time, //倒计时间 | |||
codeInterval: time, //倒计时间 | |||
sendMsgDisabled: false, | |||
verificationCode: ' ' | |||
}; | |||
}, | |||
created() {}, | |||
mounted() {}, | |||
methods: { | |||
sendCode() { | |||
// 验证是否输正确的手机号码, | |||
let reg = /^1[3456789]\d{9}$/; | |||
if (this.$own.isNull(this.phone)) { | |||
console.log('手机号码为空'); | |||
this.errPhoneMsg = '手机号码不能为空'; | |||
} else if (!reg.test(this.phone)) { | |||
console.log('手机号码为空222'); | |||
this.errPhoneMsg = '请输入正确的手机号码'; | |||
} else { | |||
this.errPhoneMsg = ''; | |||
// 调取发送/获取验证码接口 | |||
this.getVerificationCode(); | |||
} | |||
}, | |||
getVerificationCode() { | |||
let reqBody = { | |||
mobile: this.phone, | |||
validateType: 2 // 登录页面 后端约定为 2 | |||
}; | |||
APIUser.getVerificationCode(reqBody) | |||
.then(res => { | |||
let item = res.data; | |||
if (item.stateCode === 1 && item.code !== null) { | |||
NotifyService.notify({ message: '已发送验证码到该手机', type: 'success' }); | |||
this.verificationCode = item.code; | |||
this.sendMsgDisabled = true; | |||
this.countDown(); | |||
} | |||
if (item.stateCode === 0 && item.code === null) { | |||
// this.notify('请勿频繁获取,验证码5分钟内有效'); | |||
NotifyService.notify({ message: item.message }); | |||
} | |||
}) | |||
.catch(() => { | |||
NotifyService.notify({ message: '获取验证码过于频繁.请稍后再试', type: 'warning' }); | |||
}) | |||
.finally(() => (this.canSendVerificationCode = true)); | |||
}, | |||
countDown() { | |||
let codeInterval = window.setInterval(() => { | |||
if (--this.codeTime <= 0) { | |||
this.codeTime = this.codeInterval; | |||
this.sendMsgDisabled = false; | |||
window.clearInterval(codeInterval); | |||
} | |||
}, 1000); | |||
}, | |||
onLogin(type) { | |||
// 一键登录之前调取登录接口查询是否是旧用户,如果是旧用户直接登录无需再输入手机号码和验证码登录,否则需要 | |||
// 现在模拟是新用户,待接口完成 | |||
this.show = true; | |||
let reg = /^1[3456789]\d{9}$/; | |||
if (type === 'new') { | |||
if (this.phone === '' || !reg.test(this.phone)) { | |||
this.errPhoneMsg = '请输入正确的手机号码'; | |||
} else if (this.verificacode === '') { | |||
this.errCodeMsg = '请输入正确的验证码'; | |||
} else { | |||
// 格式正确 | |||
this.errPhoneMsg = ''; | |||
this.loginRequest(); | |||
} | |||
} | |||
}, | |||
loginRequest() { | |||
let reqBody = { | |||
loginName: /* this.phone */ '18664272743', | |||
password: '123456', | |||
loginCode: /* this.$store.getters.openId */ 'odcaWxCyeDHFpa3xpnQukqIcWvg0', | |||
appId: AppId | |||
}; | |||
APIUser.wxLogin(reqBody) | |||
.then(res => { | |||
let item = res.data; | |||
if (item.stateCode === 0) { | |||
NotifyService.notify({ message: item.message }); | |||
} else if (item.stateCode === 1) { | |||
this.$store.commit('authToken', item.authToken); | |||
this.$store.commit('userId', item.userId); | |||
this.$store.commit('code', ''); | |||
NotifyService.notify({ message: '登录成功!正在为您跳转...', type: 'success' }); | |||
this.$store.commit('isLogin', 'true'); | |||
setTimeout(() => { | |||
this.$router.push({ | |||
name: 'personInfos', | |||
query: { | |||
from: 'login', | |||
fromRouter: 'Index' | |||
} | |||
}); | |||
}, 1000); | |||
} else { | |||
NotifyService.notify({ message: '获取openId失败,请您重新进入公众号' }); | |||
} | |||
}) | |||
.catch(e => { | |||
console.log(e); | |||
NotifyService.notify({ message: '请求失败,请联系系统管理员' }); | |||
}); | |||
} | |||
} | |||
}; | |||
</script> | |||
<style scoped> | |||
/* @import url(); 引入css类 */ | |||
@import './login.scss'; | |||
</style> |
@@ -11,7 +11,9 @@ | |||
<div class="list"> | |||
<div class="avatar" v-show="$route.query.from === 'login'"> | |||
<div class="avatar-con"> | |||
<div class="avatar-img"></div> | |||
<div class="avatar-img"> | |||
<img :src="imgPath" alt="" /> | |||
</div> | |||
<div class="avatar-text"> | |||
<span>设置头像</span> | |||
</div> | |||
@@ -204,6 +206,7 @@ export default { | |||
height: '', | |||
weight: '', | |||
rightIcon: require('../../../assets/myself/health/right_more.png'), | |||
imgPath: require('../../../assets/com-imges/55_03.png'), | |||
isDateShow: false, | |||
currentDate: '', | |||
minDate: '', | |||
@@ -361,7 +364,7 @@ export default { | |||
}); */ | |||
APIDevice.getPersonInfo({ | |||
userId: this.$store.getters.userId, | |||
deviceId: this.$store.getters.deviceId | |||
deviceId: this.$store.getters.deviceId || '398b4b34-221b-4fc9-a9fb-e7bec8876248' | |||
}).then(res => { | |||
console.log('用户信息', res); | |||
let data = res.data; | |||
@@ -384,7 +387,7 @@ export default { | |||
let fromRouter = this.$route.query.from; | |||
this.$store.commit('notJump', 1); | |||
this.$router.push({ | |||
name: fromRouter ? fromRouter : 'psychologicalIndex', | |||
name: fromRouter ? fromRouter : 'psychologicalSetting', | |||
notJump: true | |||
}); | |||
}, | |||
@@ -458,7 +461,6 @@ export default { | |||
ToastService.success({ | |||
message: '保存成功' | |||
}); | |||
this.getPersonData(); | |||
if (this.$route.query.from === 'watchSetting') { | |||
setTimeout(() => { | |||
this.$router.push({ | |||
@@ -473,7 +475,11 @@ export default { | |||
}); | |||
}, 1500); | |||
} else if (this.$route.query.from === 'login') { | |||
console.log('注册过来,下一步绑定设备'); | |||
setTimeout(() => { | |||
this.$router.push({ | |||
name: 'bind' | |||
}); | |||
}, 1500); | |||
} else { | |||
setTimeout(() => { | |||
this.$router.push({ | |||
@@ -545,22 +551,18 @@ export default { | |||
.registe-user-infos-container { | |||
height: 100vh; | |||
overflow: hidden; | |||
.nav-bar { | |||
height: 100px; | |||
padding: 0 20px; | |||
} | |||
.main { | |||
position: relative; | |||
height: calc(100vh - 80px); | |||
background-color: $background; | |||
height: calc(100vh - 170px); | |||
background-color: #fff; | |||
.list { | |||
position: relative; | |||
height: 78%; | |||
height: 75vh; | |||
background-color: #fff; | |||
border-radius: 8px; | |||
padding: 20px 0; | |||
overflow: scroll; | |||
z-index: 99; | |||
//@at-rootpadding: 0 20px; | |||
.avatar { | |||
position: relative; | |||
height: 240px; | |||
@@ -574,6 +576,10 @@ export default { | |||
border: 2px solid #333; | |||
border-radius: 50%; | |||
margin-bottom: 10px; | |||
img { | |||
height: inherit; | |||
width: inherit; | |||
} | |||
} | |||
.avatar-text { | |||
font-size: 36px; | |||
@@ -583,7 +589,7 @@ export default { | |||
} | |||
.item { | |||
position: relative; | |||
height: 60px; | |||
height: 50px; | |||
padding: 20px 40px; | |||
display: flex; | |||
justify-content: space-between; | |||
@@ -665,8 +671,9 @@ export default { | |||
} | |||
} | |||
.bottom-btn { | |||
position: relative; | |||
margin-top: 80px; | |||
position: absolute; | |||
bottom: -40px; | |||
left: 0; | |||
height: 120px; | |||
width: 100%; | |||
@include center(); | |||
@@ -674,11 +681,11 @@ export default { | |||
clear: both; | |||
.btn { | |||
position: relative; | |||
height: 100px; | |||
height: 90px; | |||
width: 560px; | |||
background-color: $green; | |||
color: #fff; | |||
font-size: 32px; | |||
font-size: 48px; | |||
border-radius: 50px; | |||
@include center(); | |||
} | |||