1. tabbar
2. 我的页面 3. 用户信息页面 4. 更新头像、更新昵称、更新邮箱、重置密码
21
App.vue
@ -1,5 +1,6 @@
|
|||||||
<script>
|
<script>
|
||||||
import { useBluetoothStore } from '@/stores/bluetooth'
|
import { useBluetoothStore } from '@/stores/bluetooth'
|
||||||
|
import { useBasicStore } from '@/stores/basic'
|
||||||
import { mapState, mapActions } from 'pinia'
|
import { mapState, mapActions } from 'pinia'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -9,14 +10,17 @@
|
|||||||
onLaunch: function() {
|
onLaunch: function() {
|
||||||
// 检查强制升级
|
// 检查强制升级
|
||||||
this.updateMiniProgram()
|
this.updateMiniProgram()
|
||||||
// 初始化蓝牙
|
// // 初始化蓝牙
|
||||||
this.initBluetooth()
|
// this.initBluetooth()
|
||||||
// 监听蓝牙开关状态
|
// // 监听蓝牙开关状态
|
||||||
this.onBluetoothState()
|
// this.onBluetoothState()
|
||||||
// 监听蓝牙连接状态
|
// // 监听蓝牙连接状态
|
||||||
this.onBluetoothConnectStatus()
|
// this.onBluetoothConnectStatus()
|
||||||
// 监听设备特征值变化
|
// // 监听设备特征值变化
|
||||||
this.onBluetoothCharacteristicValueChange()
|
// this.onBluetoothCharacteristicValueChange()
|
||||||
|
|
||||||
|
this.getDeviceInfo()
|
||||||
|
this.getButtonInfo()
|
||||||
},
|
},
|
||||||
onShow: function() {
|
onShow: function() {
|
||||||
this.checkSetting()
|
this.checkSetting()
|
||||||
@ -24,6 +28,7 @@
|
|||||||
methods: {
|
methods: {
|
||||||
...mapActions(useBluetoothStore, ['initBluetooth', 'onBluetoothState', 'updateBluetoothStatus', 'checkSetting',
|
...mapActions(useBluetoothStore, ['initBluetooth', 'onBluetoothState', 'updateBluetoothStatus', 'checkSetting',
|
||||||
'onBluetoothConnectStatus', 'onBluetoothCharacteristicValueChange']),
|
'onBluetoothConnectStatus', 'onBluetoothCharacteristicValueChange']),
|
||||||
|
...mapActions(useBasicStore, ['getDeviceInfo', 'getButtonInfo']),
|
||||||
// 强制升级
|
// 强制升级
|
||||||
updateMiniProgram() {
|
updateMiniProgram() {
|
||||||
const updateManager = uni.getUpdateManager()
|
const updateManager = uni.getUpdateManager()
|
||||||
|
|||||||
12
api/file.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import request from '../utils/request'
|
||||||
|
|
||||||
|
// file 用户模块
|
||||||
|
|
||||||
|
// 获取文件上传参数
|
||||||
|
export function getUploadParamsRequest(data) {
|
||||||
|
return request({
|
||||||
|
url: '/file/getUploadParams',
|
||||||
|
method: 'POST',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
30
api/safeAnswer.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import request from '../utils/request'
|
||||||
|
|
||||||
|
// safeAnswer 安全问题模块
|
||||||
|
|
||||||
|
// 获取安全问题列表
|
||||||
|
export function getQuestionListRequest(data) {
|
||||||
|
return request({
|
||||||
|
url: '/safeAnswer/getQuestionList',
|
||||||
|
method: 'POST',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取安全问题答案
|
||||||
|
export function getQuestionAnswerRequest(data) {
|
||||||
|
return request({
|
||||||
|
url: '/safeAnswer/getOwnQuestionList',
|
||||||
|
method: 'POST',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新安全问题答案
|
||||||
|
export function updateQuestionAnswerRequest(data) {
|
||||||
|
return request({
|
||||||
|
url: '/safeAnswer/set',
|
||||||
|
method: 'POST',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
51
api/user.js
@ -2,10 +2,55 @@ import request from '../utils/request'
|
|||||||
|
|
||||||
// user 用户模块
|
// user 用户模块
|
||||||
|
|
||||||
// 登录
|
// 获取用户信息
|
||||||
export function login(data) {
|
export function getUserInfoRequest(data) {
|
||||||
return request({
|
return request({
|
||||||
url: '/user/login',
|
url: '/user/getUserInfo',
|
||||||
|
method: 'POST',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新用户信息
|
||||||
|
export function updateUserInfoRequest(data) {
|
||||||
|
return request({
|
||||||
|
url: '/user/updateUserInfo',
|
||||||
|
method: 'POST',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改密码
|
||||||
|
export function updatePasswordRequest(data) {
|
||||||
|
return request({
|
||||||
|
url: '/user/changePassword',
|
||||||
|
method: 'POST',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取解绑邮箱token
|
||||||
|
export function unbindEmailTokenRequest(data) {
|
||||||
|
return request({
|
||||||
|
url: '/user/unbindEmailToken',
|
||||||
|
method: 'POST',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改绑定邮箱
|
||||||
|
export function updateEmailRequest(data) {
|
||||||
|
return request({
|
||||||
|
url: '/user/bindEmail',
|
||||||
|
method: 'POST',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取邮箱验证码
|
||||||
|
export function getEmailCodeRequest(data) {
|
||||||
|
return request({
|
||||||
|
url: '/user/sendValidationCodeAuth',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
|
|||||||
@ -4,12 +4,14 @@ const version = '1.0.0.0'
|
|||||||
|
|
||||||
const DEV = {
|
const DEV = {
|
||||||
name: '开发',
|
name: '开发',
|
||||||
baseUrl: 'https://www.baidu.com',
|
baseUrl: 'https://dev.lock.star-lock.cn/api',
|
||||||
|
webviewBaseUrl: 'https://dev.lock.star-lock.cn',
|
||||||
version: version
|
version: version
|
||||||
}
|
}
|
||||||
const PRE = {
|
const PRE = {
|
||||||
name: '预发',
|
name: '预发',
|
||||||
baseUrl: '',
|
baseUrl: 'https://pre.lock.star-lock.cn/api',
|
||||||
|
webviewBaseUrl: 'https://pre.lock.star-lock.cn',
|
||||||
version: version
|
version: version
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -20,4 +22,4 @@ const PROD = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 更换环境的时候 切换导出就行
|
// 更换环境的时候 切换导出就行
|
||||||
export default DEV
|
export default PRE
|
||||||
|
|||||||
@ -55,7 +55,8 @@
|
|||||||
"urlCheck" : true,
|
"urlCheck" : true,
|
||||||
"minified" : true
|
"minified" : true
|
||||||
},
|
},
|
||||||
"usingComponents" : true
|
"usingComponents" : true,
|
||||||
|
"lazyCodeLoading" : "requiredComponents"
|
||||||
},
|
},
|
||||||
"mp-alipay" : {
|
"mp-alipay" : {
|
||||||
"usingComponents" : true
|
"usingComponents" : true
|
||||||
|
|||||||
95
pages.json
@ -8,16 +8,105 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"pages": [
|
"pages": [
|
||||||
|
{
|
||||||
|
"path": "pages/home/home"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/mine/mine"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/index/index"
|
"path": "pages/index/index"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/userInfo/userInfo",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "个人信息",
|
||||||
|
"navigationBarTextStyle": "white",
|
||||||
|
"navigationBarBackgroundColor": "#63b8af",
|
||||||
|
"navigationStyle": "default"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/updateName/updateName",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "修改昵称",
|
||||||
|
"navigationBarTextStyle": "white",
|
||||||
|
"navigationBarBackgroundColor": "#63b8af",
|
||||||
|
"navigationStyle": "default"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/updatePassword/updatePassword",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "重置密码",
|
||||||
|
"navigationBarTextStyle": "white",
|
||||||
|
"navigationBarBackgroundColor": "#63b8af",
|
||||||
|
"navigationStyle": "default"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/updateEmail/updateEmail",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "修改邮箱",
|
||||||
|
"navigationBarTextStyle": "white",
|
||||||
|
"navigationBarBackgroundColor": "#63b8af",
|
||||||
|
"navigationStyle": "default"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/verifyEmail/verifyEmail",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "验证邮箱",
|
||||||
|
"navigationBarTextStyle": "white",
|
||||||
|
"navigationBarBackgroundColor": "#63b8af",
|
||||||
|
"navigationStyle": "default"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/safeQuestion/safeQuestion",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "安全问题",
|
||||||
|
"navigationBarTextStyle": "white",
|
||||||
|
"navigationBarBackgroundColor": "#63b8af",
|
||||||
|
"navigationStyle": "default"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/webview/webview",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "介绍",
|
||||||
|
"navigationBarTextStyle": "white",
|
||||||
|
"navigationBarBackgroundColor": "#63b8af",
|
||||||
|
"navigationStyle": "default"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"globalStyle": {
|
"globalStyle": {
|
||||||
"navigationBarTextStyle": "black",
|
"navigationBarTextStyle": "black",
|
||||||
"navigationBarTitleText": "星星锁",
|
"navigationBarTitleText": "星星锁",
|
||||||
"navigationBarBackgroundColor": "#F8F8F8",
|
"navigationBarBackgroundColor": "#F3F3F3",
|
||||||
"backgroundColor": "#F8F8F8",
|
"backgroundColor": "#F3F3F3",
|
||||||
"navigationStyle": "custom"
|
"navigationStyle": "custom"
|
||||||
},
|
},
|
||||||
"uniIdRouter": {}
|
"tabBar": {
|
||||||
|
"color": "#a3a3a3",
|
||||||
|
"selectedColor": "#63b8af",
|
||||||
|
"borderStyle": "white",
|
||||||
|
"backgroundColor": "#FFFFFF",
|
||||||
|
"position": "bottom",
|
||||||
|
"list": [
|
||||||
|
{
|
||||||
|
"pagePath": "pages/home/home",
|
||||||
|
"iconPath": "static/images/tabbar_key_no_select.png",
|
||||||
|
"selectedIconPath": "static/images/tabbar_key_select.png",
|
||||||
|
"text": "设备"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pagePath": "pages/mine/mine",
|
||||||
|
"iconPath": "static/images/tabbar_mine_no_select.png",
|
||||||
|
"selectedIconPath": "static/images/tabbar_mine_select.png",
|
||||||
|
"text": "我的"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
47
pages/home/home.vue
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
home
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getUserInfoRequest } from '@/api/user'
|
||||||
|
import { useUserStore } from '@/stores/user'
|
||||||
|
import { mapState, mapActions } from 'pinia'
|
||||||
|
import { getCompanyRequest } from '@/api/app'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState(useUserStore, ['userInfo'])
|
||||||
|
},
|
||||||
|
async onLoad() {
|
||||||
|
uni.setStorageSync('token', '3016|NQth8ud3JRGLDKO3Gsmg7gEgv9yBjowrZNijlBCp975d2a97')
|
||||||
|
this.getUserInfo()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapActions(useUserStore, ['updateUserInfo']),
|
||||||
|
async getUserInfo() {
|
||||||
|
const { code, data } = await getUserInfoRequest()
|
||||||
|
if(code === 0) {
|
||||||
|
this.updateUserInfo(data)
|
||||||
|
console.log(this.userInfo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
page {
|
||||||
|
background-color: $uni-bg-color-grey;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
|
||||||
|
</style>
|
||||||
123
pages/mine/mine.vue
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
<template>
|
||||||
|
<view v-if="buttonInfo">
|
||||||
|
<image :style="{marginTop: buttonInfo.bottom + 10 + 'px'}" src="/static/images/background_mine.png"
|
||||||
|
class="background-image"></image>
|
||||||
|
<view class="view">
|
||||||
|
<view class="view-button" @click="toUsereInfo">
|
||||||
|
<view>个人信息</view>
|
||||||
|
<image class="icon-arrow" src="/static/images/icon_arrow.png" mode="aspectFill"></image>
|
||||||
|
</view>
|
||||||
|
<view class="view-line"></view>
|
||||||
|
<label for="contact">
|
||||||
|
<view class="view-button">
|
||||||
|
<view>客服</view>
|
||||||
|
<image class="icon-arrow" src="/static/images/icon_arrow.png" mode="aspectFill"></image>
|
||||||
|
</view>
|
||||||
|
</label>
|
||||||
|
<view class="view-line"></view>
|
||||||
|
<view class="view-button" @click="toWebview">
|
||||||
|
<view>关于</view>
|
||||||
|
<image class="icon-arrow" src="/static/images/icon_arrow.png" mode="aspectFill"></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="button-logout">退出</view>
|
||||||
|
</view>
|
||||||
|
<button open-type="contact" id="contact"></button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { useBasicStore } from '@/stores/basic'
|
||||||
|
import { mapState, mapActions } from 'pinia'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
buttonInfo: null,
|
||||||
|
deviceInfo: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async onLoad() {
|
||||||
|
this.deviceInfo = await this.getDeviceInfo()
|
||||||
|
this.buttonInfo = await this.getButtonInfo()
|
||||||
|
console.log(this.deviceInfo)
|
||||||
|
console.log(this.buttonInfo.top)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapActions(useBasicStore, ['getDeviceInfo', 'getButtonInfo', 'routeJump']),
|
||||||
|
toUsereInfo() {
|
||||||
|
this.routeJump({
|
||||||
|
name: 'userInfo'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
toWebview() {
|
||||||
|
this.routeJump({
|
||||||
|
name: 'webview',
|
||||||
|
params: {
|
||||||
|
type: 'default'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
page {
|
||||||
|
background-color: $uni-bg-color-grey;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.background-image {
|
||||||
|
margin-left: 20rpx;
|
||||||
|
width: 710rpx;
|
||||||
|
height: 156rpx;
|
||||||
|
border-radius: 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.view {
|
||||||
|
margin-top: 32rpx;
|
||||||
|
border-radius: 32rpx;
|
||||||
|
width: 710rpx;
|
||||||
|
margin-left: 20rpx;
|
||||||
|
background: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.view-button {
|
||||||
|
padding: 0 20rpx 0 40rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
color: #292826;
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 80rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-arrow {
|
||||||
|
width: 40rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.view-line {
|
||||||
|
width: 100%;
|
||||||
|
height: 3rpx;
|
||||||
|
background: #EBEBEB;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-logout {
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 46rpx;
|
||||||
|
bottom: 40rpx;
|
||||||
|
width: 710rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
line-height: 80rpx;
|
||||||
|
text-align: center;
|
||||||
|
margin-left: 20rpx;
|
||||||
|
background: #ec433c;
|
||||||
|
color: #ffffff;
|
||||||
|
font-size: 40rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
46
pages/safeQuestion/safeQuestion.vue
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getQuestionAnswerRequest, getQuestionListRequest } from '@/api/safeAnswer'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
onLoad() {
|
||||||
|
this.getQuestionList()
|
||||||
|
this.getQuestionAnswer()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async getQuestionList() {
|
||||||
|
const { code, data, message } = await getQuestionListRequest()
|
||||||
|
if(code === 0) {
|
||||||
|
console.log(1, data)
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: message,
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async getQuestionAnswer() {
|
||||||
|
const { code, data, message } = await getQuestionAnswerRequest()
|
||||||
|
if(code === 0) {
|
||||||
|
console.log(2, data)
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: message,
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
|
||||||
|
</style>
|
||||||
195
pages/updateEmail/updateEmail.vue
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<input class="input-email" :value="email" placeholder="请输入邮箱"
|
||||||
|
placeholder-class="input-placeholder" :focus="true" @input="updateInputEmail"></input>
|
||||||
|
<view class="view-top">
|
||||||
|
<input type="number" class="input-verify" :value="verificationCode" maxlength="6" placeholder="请输入验证码"
|
||||||
|
placeholder-class="input-placeholder" @input="updateInputCode"></input>
|
||||||
|
<view class="button-verify" @click="getEmailCode">{{text}}</view>
|
||||||
|
</view>
|
||||||
|
<view class="button" @click="toUpdateEmail">确定</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapActions, mapState } from 'pinia'
|
||||||
|
import { useUserStore } from '@/stores/user'
|
||||||
|
import { getEmailCodeRequest, unbindEmailTokenRequest, updateEmailRequest, updateUserInfoRequest } from '@/api/user'
|
||||||
|
import { useBasicStore } from '@/stores/basic'
|
||||||
|
import { test } from 'uview-plus'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
text: '获取验证码',
|
||||||
|
verificationCode: '',
|
||||||
|
token: '',
|
||||||
|
email: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState(useUserStore, ['userInfo'])
|
||||||
|
},
|
||||||
|
onLoad(option) {
|
||||||
|
if(option.token){
|
||||||
|
this.token = option.token
|
||||||
|
} else {
|
||||||
|
uni.setNavigationBarTitle({
|
||||||
|
title: '绑定邮箱'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapActions(useUserStore, ['updateUserInfo']),
|
||||||
|
...mapActions(useBasicStore, ['routeJump']),
|
||||||
|
updateInputEmail(data) {
|
||||||
|
this.email = data.detail.value
|
||||||
|
},
|
||||||
|
updateInputCode (data) {
|
||||||
|
this.verificationCode = data.detail.value
|
||||||
|
},
|
||||||
|
async getEmailCode () {
|
||||||
|
if (this.text !== '获取验证码') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if(!test.email(this.email)){
|
||||||
|
uni.showToast({
|
||||||
|
title: '请输入正确的邮箱',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const { code } = await getEmailCodeRequest({
|
||||||
|
account: this.email,
|
||||||
|
channel: '2',
|
||||||
|
codeType: 6
|
||||||
|
})
|
||||||
|
if (code === 0) {
|
||||||
|
this.updateTime()
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: '验证码获取失败',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async toUpdateEmail () {
|
||||||
|
if (this.verificationCode.length === 6 && test.digits(this.verificationCode)) {
|
||||||
|
const params = {
|
||||||
|
verificationCode: this.verificationCode,
|
||||||
|
email: this.email
|
||||||
|
}
|
||||||
|
if(this.token !== ''){
|
||||||
|
params.unbindToken = this.token
|
||||||
|
}
|
||||||
|
const { code, data, message } = await updateEmailRequest(params)
|
||||||
|
if (code === 0) {
|
||||||
|
this.updateUserInfo({
|
||||||
|
...this.userInfo,
|
||||||
|
email: this.email
|
||||||
|
})
|
||||||
|
uni.navigateBack({
|
||||||
|
complete () {
|
||||||
|
uni.showToast({
|
||||||
|
title: '邮箱更新成功',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: message,
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: '验证码为6位纯数字',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
updateTime () {
|
||||||
|
let time = 120
|
||||||
|
this.text = `${time} s`
|
||||||
|
const timer = setInterval(() => {
|
||||||
|
time--
|
||||||
|
this.text = `${time} s`
|
||||||
|
if (time === 0) {
|
||||||
|
clearInterval(timer)
|
||||||
|
this.text = '获取验证码'
|
||||||
|
}
|
||||||
|
}, 1000)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
page {
|
||||||
|
background-color: $uni-bg-color-grey;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.input-email {
|
||||||
|
border-radius: 16rpx;
|
||||||
|
background: #FFFFFF;
|
||||||
|
margin-left: 35rpx;
|
||||||
|
margin-top: 48rpx;
|
||||||
|
height: 108rpx;
|
||||||
|
width: 616rpx;
|
||||||
|
padding-left: 32rpx;
|
||||||
|
padding-right: 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-verify {
|
||||||
|
margin-top: 48rpx;
|
||||||
|
height: 108rpx;
|
||||||
|
width: 265rpx;
|
||||||
|
line-height: 108rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 32rpx;
|
||||||
|
margin-left: 35rpx;
|
||||||
|
|
||||||
|
background: #63b8af;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.view-top {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-verify {
|
||||||
|
border-radius: 16rpx;
|
||||||
|
background: #FFFFFF;
|
||||||
|
margin-left: 35rpx;
|
||||||
|
margin-top: 48rpx;
|
||||||
|
height: 108rpx;
|
||||||
|
width: 316rpx;
|
||||||
|
padding-left: 32rpx;
|
||||||
|
padding-right: 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-placeholder {
|
||||||
|
height: 108rpx;
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 108rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
margin-top: 32rpx;
|
||||||
|
margin-left: 35rpx;
|
||||||
|
width: 680rpx;
|
||||||
|
height: 96rpx;
|
||||||
|
background: #63b8af;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
line-height: 96rpx;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
104
pages/updateName/updateName.vue
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<input class="input" :value="nickname" maxlength="20" placeholder="请输入昵称"
|
||||||
|
placeholder-class="input-placeholder" :focus="true" @input="updateInput"></input>
|
||||||
|
<view class="button" @click="updateName">保存</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapActions, mapState } from 'pinia'
|
||||||
|
import { useUserStore } from '@/stores/user'
|
||||||
|
import { updateUserInfoRequest } from '@/api/user'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
nickname: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState(useUserStore, ['userInfo'])
|
||||||
|
},
|
||||||
|
onLoad() {
|
||||||
|
this.nickname = this.userInfo.nickname
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapActions(useUserStore, ['updateUserInfo']),
|
||||||
|
updateInput(data) {
|
||||||
|
this.nickname = data.detail.value
|
||||||
|
console.log(data)
|
||||||
|
},
|
||||||
|
async updateName() {
|
||||||
|
if(this.nickname === '') {
|
||||||
|
uni.showToast({
|
||||||
|
title: '昵称不能为空',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const { code } = await updateUserInfoRequest({
|
||||||
|
nickname: this.nickname
|
||||||
|
})
|
||||||
|
if(code === 0) {
|
||||||
|
this.updateUserInfo({
|
||||||
|
...this.userInfo,
|
||||||
|
nickname: this.nickname
|
||||||
|
})
|
||||||
|
uni.navigateBack({
|
||||||
|
complete() {
|
||||||
|
uni.showToast({
|
||||||
|
title: '昵称更新成功',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: '昵称更新失败',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
page {
|
||||||
|
background-color: $uni-bg-color-grey;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.input {
|
||||||
|
border-radius: 16rpx;
|
||||||
|
background: #FFFFFF;
|
||||||
|
margin-left: 35rpx;
|
||||||
|
margin-top: 48rpx;
|
||||||
|
height: 108rpx;
|
||||||
|
width: 616rpx;
|
||||||
|
padding-left: 32rpx;
|
||||||
|
padding-right: 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-placeholder {
|
||||||
|
height: 108rpx;
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 108rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
margin-top: 32rpx;
|
||||||
|
margin-left: 35rpx;
|
||||||
|
width: 680rpx;
|
||||||
|
height: 96rpx;
|
||||||
|
background: #63b8af;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
line-height: 96rpx;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
137
pages/updatePassword/updatePassword.vue
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<input class="input" :password="true" style="margin-top: 48rpx;" :value="oldPassword" maxlength="20"
|
||||||
|
placeholder="请输入原密码" placeholder-class="input-placeholder" :focus="true" @input="updateOldPassword"></input>
|
||||||
|
<input class="input" :password="true" :value="newPassword" maxlength="20" placeholder="请输入新密码"
|
||||||
|
placeholder-class="input-placeholder" @input="updateNewPassword"></input>
|
||||||
|
<input class="input" :password="true" :value="confirmPassword" maxlength="20" placeholder="请确认密码"
|
||||||
|
placeholder-class="input-placeholder" @input="updateConfirmPassword"></input>
|
||||||
|
<view class="text-tips">密码必须是8-20位,至少包括数字/字母/符号中的2种</view>
|
||||||
|
<view class="button" @click="updatePassword">保存</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapActions, mapState } from 'pinia'
|
||||||
|
import { useUserStore } from '@/stores/user'
|
||||||
|
import { updatePasswordRequest } from '@/api/user'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
oldPassword: '',
|
||||||
|
newPassword: '',
|
||||||
|
confirmPassword: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState(useUserStore, ['userInfo'])
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapActions(useUserStore, ['updateUserInfo']),
|
||||||
|
updateOldPassword (data) {
|
||||||
|
this.oldPassword = data.detail.value
|
||||||
|
},
|
||||||
|
updateNewPassword (data) {
|
||||||
|
this.newPassword = data.detail.value
|
||||||
|
},
|
||||||
|
updateConfirmPassword (data) {
|
||||||
|
this.confirmPassword = data.detail.value
|
||||||
|
},
|
||||||
|
async updatePassword () {
|
||||||
|
if (this.oldPassword === '' || this.newPassword === '' || this.confirmPassword === '') {
|
||||||
|
uni.showToast({
|
||||||
|
title: '密码不能为空',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.newPassword.length < 8 || this.newPassword.length > 20 || this.confirmPassword.length < 8 ||
|
||||||
|
this.confirmPassword.length > 20 || this.oldPassword.length < 8 || this.oldPassword.length > 20) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '密码长度必须是8-20位',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.newPassword !== this.confirmPassword) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '两次密码输入不一致',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const { code, message } = await updatePasswordRequest({
|
||||||
|
oldPassword: this.oldPassword,
|
||||||
|
newPassword: this.newPassword,
|
||||||
|
date: new Date().getTime()
|
||||||
|
})
|
||||||
|
if (code === 0) {
|
||||||
|
this.updateUserInfo({
|
||||||
|
...this.userInfo,
|
||||||
|
nickname: this.nickname
|
||||||
|
})
|
||||||
|
uni.navigateBack({
|
||||||
|
complete () {
|
||||||
|
uni.showToast({
|
||||||
|
title: '密码重置成功',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: message,
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
page {
|
||||||
|
background-color: $uni-bg-color-grey;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.input {
|
||||||
|
border-radius: 16rpx;
|
||||||
|
background: #FFFFFF;
|
||||||
|
margin-left: 35rpx;
|
||||||
|
margin-top: 24rpx;
|
||||||
|
height: 108rpx;
|
||||||
|
width: 616rpx;
|
||||||
|
padding-left: 32rpx;
|
||||||
|
padding-right: 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-placeholder {
|
||||||
|
height: 108rpx;
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 108rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
margin-top: 32rpx;
|
||||||
|
margin-left: 35rpx;
|
||||||
|
width: 680rpx;
|
||||||
|
height: 96rpx;
|
||||||
|
background: #63b8af;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
line-height: 96rpx;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-tips {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 32rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #9B9B9B;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
229
pages/userInfo/userInfo.vue
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<view class="view">
|
||||||
|
<label for="avatar">
|
||||||
|
<view class="view-button">
|
||||||
|
<view>头像</view>
|
||||||
|
<view class="view-button" style="padding: 0">
|
||||||
|
<image class="avatar" :src="userInfo.headUrl" mode="aspectFill"></image>
|
||||||
|
<image class="icon-arrow" src="/static/images/icon_arrow.png" mode="aspectFill"></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</label>
|
||||||
|
<view class="view-line"></view>
|
||||||
|
<view class="view-button" @click="toUpdateName">
|
||||||
|
<view>昵称</view>
|
||||||
|
<view class="view-button" style="padding: 0">
|
||||||
|
<view class="info">{{userInfo.nickname}}</view>
|
||||||
|
<image class="icon-arrow" src="/static/images/icon_arrow.png" mode="aspectFill"></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="view-line"></view>
|
||||||
|
<view class="view-button">
|
||||||
|
<view>手机号</view>
|
||||||
|
<view class="view-button" style="padding: 0">
|
||||||
|
<view v-if="userInfo.mobile !== ''" class="info">{{userInfo.mobile}}</view>
|
||||||
|
<view v-else class="red-dot"></view>
|
||||||
|
<image class="icon-arrow" src="/static/images/icon_arrow.png" mode="aspectFill"></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="view-line"></view>
|
||||||
|
<view class="view-button" @click="toUpdateEmail">
|
||||||
|
<view>邮箱</view>
|
||||||
|
<view class="view-button" style="padding: 0">
|
||||||
|
<view v-if="userInfo.email !== ''" class="info">{{userInfo.email}}</view>
|
||||||
|
<view v-else class="red-dot"></view>
|
||||||
|
<image class="icon-arrow" src="/static/images/icon_arrow.png" mode="aspectFill"></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="view-line"></view>
|
||||||
|
<view class="view-button" @click="toUpdatePassword">
|
||||||
|
<view>重置密码</view>
|
||||||
|
<image class="icon-arrow" src="/static/images/icon_arrow.png" mode="aspectFill"></image>
|
||||||
|
</view>
|
||||||
|
<view class="view-line"></view>
|
||||||
|
<view class="view-button" @click="toSafeQuestion">
|
||||||
|
<view>安全问题</view>
|
||||||
|
<view class="view-button" style="padding: 0">
|
||||||
|
<view v-if="!userInfo.haveSafeAnswer" class="red-dot"></view>
|
||||||
|
<image class="icon-arrow" src="/static/images/icon_arrow.png" mode="aspectFill"></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="view-line"></view>
|
||||||
|
<view class="view-button">
|
||||||
|
<view>国家/地区</view>
|
||||||
|
<view class="view-button" style="padding: 0">
|
||||||
|
<view class="info">{{userInfo.countryName}}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<button open-type="chooseAvatar" style="display: none" id="avatar" @chooseavatar="chooseAvatar"></button>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapActions, mapState } from 'pinia'
|
||||||
|
import { useUserStore } from '@/stores/user'
|
||||||
|
import { useBasicStore } from '@/stores/basic'
|
||||||
|
import { getUploadParamsRequest } from '@/api/file'
|
||||||
|
import { updateUserInfoRequest } from '@/api/user'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
computed: {
|
||||||
|
...mapState(useUserStore, ['userInfo'])
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapActions(useBasicStore, ['routeJump']),
|
||||||
|
...mapActions(useUserStore, ['updateUserInfo']),
|
||||||
|
chooseAvatar(e) {
|
||||||
|
const that = this
|
||||||
|
const path = e.detail.avatarUrl
|
||||||
|
const list = path.split('/')
|
||||||
|
const filename = list[list.length - 1]
|
||||||
|
wx.getFileSystemManager().getFileInfo({
|
||||||
|
filePath: path,
|
||||||
|
async success (res) {
|
||||||
|
const size = res.size
|
||||||
|
const { code, data } = await getUploadParamsRequest({
|
||||||
|
size,
|
||||||
|
module: 'avatar',
|
||||||
|
userId: that.userInfo.userId,
|
||||||
|
filename
|
||||||
|
})
|
||||||
|
if(code === 0) {
|
||||||
|
uni.uploadFile({
|
||||||
|
url: data.uploadUrl,
|
||||||
|
filePath: path,
|
||||||
|
name: 'file',
|
||||||
|
formData: data.formData,
|
||||||
|
async success (res) {
|
||||||
|
const { code: updateCode } = await updateUserInfoRequest({
|
||||||
|
headUrl: data.fileUrl
|
||||||
|
})
|
||||||
|
if(updateCode === 0) {
|
||||||
|
that.updateUserInfo({
|
||||||
|
...that.userInfo,
|
||||||
|
headUrl: data.fileUrl
|
||||||
|
})
|
||||||
|
uni.showToast({
|
||||||
|
title: '头像更新成功',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: '头像更新失败',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fail(res) {
|
||||||
|
console.log(res)
|
||||||
|
uni.showToast({
|
||||||
|
title: '头像更新失败',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: '头像更新失败',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
toUpdateName() {
|
||||||
|
this.routeJump({
|
||||||
|
name: 'updateName'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
toUpdateEmail() {
|
||||||
|
if(this.userInfo.email === '') {
|
||||||
|
this.routeJump({
|
||||||
|
name: 'updateEmail'
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.routeJump({
|
||||||
|
name: 'verifyEmail'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toUpdatePassword() {
|
||||||
|
this.routeJump({
|
||||||
|
name: 'updatePassword'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
toSafeQuestion() {
|
||||||
|
this.routeJump({
|
||||||
|
name: 'safeQuestion'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
page {
|
||||||
|
background-color: $uni-bg-color-grey;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.view {
|
||||||
|
margin-top: 32rpx;
|
||||||
|
border-radius: 32rpx;
|
||||||
|
width: 710rpx;
|
||||||
|
margin-left: 20rpx;
|
||||||
|
background: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.view-button {
|
||||||
|
padding: 0 20rpx 0 40rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
color: #292826;
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 80rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info {
|
||||||
|
text-align: right;
|
||||||
|
width: 400rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red-dot {
|
||||||
|
margin-right: 20rpx;
|
||||||
|
background: #ec433c;
|
||||||
|
width: 20rpx;
|
||||||
|
height: 20rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-arrow {
|
||||||
|
width: 40rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.view-line {
|
||||||
|
width: 100%;
|
||||||
|
height: 3rpx;
|
||||||
|
background: #EBEBEB;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
width: 80rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
margin-top: 20rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
181
pages/verifyEmail/verifyEmail.vue
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<view class="view-top">
|
||||||
|
<input type="number" class="input" :value="verificationCode" maxlength="20" placeholder="请输入验证码"
|
||||||
|
placeholder-class="input-placeholder" @input="updateInput"></input>
|
||||||
|
<view class="button-verify" @click="getEmailCode">{{text}}</view>
|
||||||
|
</view>
|
||||||
|
<view class="button" @click="toUpdateEmail">下一步</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapActions, mapState } from 'pinia'
|
||||||
|
import { useUserStore } from '@/stores/user'
|
||||||
|
import { getEmailCodeRequest, unbindEmailTokenRequest, updateUserInfoRequest } from '@/api/user'
|
||||||
|
import { useBasicStore } from '@/stores/basic'
|
||||||
|
import { test } from 'uview-plus'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
text: '获取验证码',
|
||||||
|
verificationCode: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState(useUserStore, ['userInfo'])
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapActions(useUserStore, ['updateUserInfo']),
|
||||||
|
...mapActions(useBasicStore, ['routeJump']),
|
||||||
|
async getEmailCode() {
|
||||||
|
if(this.text !== '获取验证码') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const { code } = await getEmailCodeRequest({
|
||||||
|
channel: '2',
|
||||||
|
codeType: 7
|
||||||
|
})
|
||||||
|
if(code === 0) {
|
||||||
|
this.updateTime()
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: '验证码获取失败',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async toUpdateEmail() {
|
||||||
|
if(this.verificationCode.length === 6 && test.digits(this.verificationCode)) {
|
||||||
|
const { code, data, message } = await unbindEmailTokenRequest({
|
||||||
|
verificationCode: this.verificationCode
|
||||||
|
})
|
||||||
|
if(code === 0) {
|
||||||
|
this.routeJump({
|
||||||
|
type: 'redirectTo',
|
||||||
|
name: 'updateEmail',
|
||||||
|
params: {
|
||||||
|
token: data.token
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: message,
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: '验证码为6位纯数字',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
updateTime() {
|
||||||
|
let time = 120
|
||||||
|
this.text = `${time} s`
|
||||||
|
const timer = setInterval(() => {
|
||||||
|
time--
|
||||||
|
this.text = `${time} s`
|
||||||
|
if(time === 0) {
|
||||||
|
clearInterval(timer)
|
||||||
|
this.text = '获取验证码'
|
||||||
|
}
|
||||||
|
}, 1000)
|
||||||
|
},
|
||||||
|
updateInput(data) {
|
||||||
|
this.verificationCode = data.detail.value
|
||||||
|
},
|
||||||
|
async updateName() {
|
||||||
|
if(this.nickname === '') {
|
||||||
|
uni.showToast({
|
||||||
|
title: '昵称不能为空',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const { code } = await updateUserInfoRequest({
|
||||||
|
nickname: this.nickname
|
||||||
|
})
|
||||||
|
if(code === 0) {
|
||||||
|
this.updateUserInfo({
|
||||||
|
...this.userInfo,
|
||||||
|
nickname: this.nickname
|
||||||
|
})
|
||||||
|
uni.navigateBack({
|
||||||
|
complete() {
|
||||||
|
uni.showToast({
|
||||||
|
title: '昵称更新成功',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: '昵称更新失败',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
page {
|
||||||
|
background-color: $uni-bg-color-grey;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.button-verify {
|
||||||
|
margin-top: 48rpx;
|
||||||
|
height: 108rpx;
|
||||||
|
width: 265rpx;
|
||||||
|
line-height: 108rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 32rpx;
|
||||||
|
margin-left: 35rpx;
|
||||||
|
|
||||||
|
background: #63b8af;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.view-top {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input {
|
||||||
|
border-radius: 16rpx;
|
||||||
|
background: #FFFFFF;
|
||||||
|
margin-left: 35rpx;
|
||||||
|
margin-top: 48rpx;
|
||||||
|
height: 108rpx;
|
||||||
|
width: 316rpx;
|
||||||
|
padding-left: 32rpx;
|
||||||
|
padding-right: 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-placeholder {
|
||||||
|
height: 108rpx;
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 108rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
margin-top: 32rpx;
|
||||||
|
margin-left: 35rpx;
|
||||||
|
width: 680rpx;
|
||||||
|
height: 96rpx;
|
||||||
|
background: #63b8af;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
line-height: 96rpx;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
36
pages/webview/webview.vue
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<web-view :src="url"></web-view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import baseConfig from '@/config/env'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
url: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onLoad: function (options) {
|
||||||
|
console.log(baseConfig.webviewBaseUrl)
|
||||||
|
const officialAccounts = {
|
||||||
|
default: {
|
||||||
|
url: '/app/introduce',
|
||||||
|
name: '介绍'
|
||||||
|
},
|
||||||
|
userAgreement: {
|
||||||
|
url: '/app/userAgreement',
|
||||||
|
name: '用户协议'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const item = officialAccounts[options?.type] || officialAccounts['default']
|
||||||
|
this.url = baseConfig.webviewBaseUrl + item['url']
|
||||||
|
console.log(this.url)
|
||||||
|
uni.setNavigationBarTitle({
|
||||||
|
title: item['name']
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
BIN
static/images/background_mine.png
Normal file
|
After Width: | Height: | Size: 91 KiB |
BIN
static/images/icon_arrow.png
Normal file
|
After Width: | Height: | Size: 941 B |
BIN
static/images/tabbar_key_no_select.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
static/images/tabbar_key_select.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
static/images/tabbar_mine_no_select.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
static/images/tabbar_mine_select.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
static/logo.png
|
Before Width: | Height: | Size: 3.9 KiB |
110
stores/basic.js
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
|
// 页面配置
|
||||||
|
const pages = [
|
||||||
|
{
|
||||||
|
name: 'home',
|
||||||
|
path: '/pages/home/home',
|
||||||
|
tabBar: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'mine',
|
||||||
|
path: '/pages/mine/mine',
|
||||||
|
tabBar: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'userInfo',
|
||||||
|
path: '/pages/userInfo/userInfo',
|
||||||
|
tabBar: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updateName',
|
||||||
|
path: '/pages/updateName/updateName',
|
||||||
|
tabBar: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updatePassword',
|
||||||
|
path: '/pages/updatePassword/updatePassword',
|
||||||
|
tabBar: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updateEmail',
|
||||||
|
path: '/pages/updateEmail/updateEmail',
|
||||||
|
tabBar: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'verifyEmail',
|
||||||
|
path: '/pages/verifyEmail/verifyEmail',
|
||||||
|
tabBar: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'safeQuestion',
|
||||||
|
path: '/pages/safeQuestion/safeQuestion',
|
||||||
|
tabBar: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'webview',
|
||||||
|
path: '/pages/webview/webview',
|
||||||
|
tabBar: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
export const useBasicStore = defineStore('basic', {
|
||||||
|
state() {
|
||||||
|
return {
|
||||||
|
// 设备信息
|
||||||
|
deviceInfo: null,
|
||||||
|
// 胶囊按钮的位置信息
|
||||||
|
buttonInfo: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
// 路由跳转
|
||||||
|
/* data 入参 name string页面名称 type string跳转方式 params object传递参数 delta number返回页面数
|
||||||
|
* 具体入参查看文档 https://www.uviewui.com/js/route.html */
|
||||||
|
routeJump(data) {
|
||||||
|
console.log(data)
|
||||||
|
const page = pages.find((page) => {
|
||||||
|
return page.name === data.name
|
||||||
|
})
|
||||||
|
if (page) {
|
||||||
|
uni.$u.route({
|
||||||
|
url: page.path,
|
||||||
|
...data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 获取设备信息
|
||||||
|
getDeviceInfo() {
|
||||||
|
const that = this
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
if (that.deviceInfo?.model) {
|
||||||
|
resolve(that.deviceInfo)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
uni.getSystemInfo({
|
||||||
|
success: function (res) {
|
||||||
|
that.deviceInfo = res
|
||||||
|
resolve(that.deviceInfo)
|
||||||
|
},
|
||||||
|
fail: function () {
|
||||||
|
resolve({})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 获取胶囊信息
|
||||||
|
getButtonInfo() {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if (this.buttonInfo?.top) {
|
||||||
|
resolve(this.buttonInfo)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.buttonInfo = uni.getMenuButtonBoundingClientRect()
|
||||||
|
resolve(this.buttonInfo)
|
||||||
|
return
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
2
uni.scss
@ -32,7 +32,7 @@ $uni-text-color-disable:#c0c0c0;
|
|||||||
|
|
||||||
/* 背景颜色 */
|
/* 背景颜色 */
|
||||||
$uni-bg-color:#ffffff;
|
$uni-bg-color:#ffffff;
|
||||||
$uni-bg-color-grey:#f8f8f8;
|
$uni-bg-color-grey:#f3f3f3;
|
||||||
$uni-bg-color-hover:#f1f1f1;//点击状态颜色
|
$uni-bg-color-hover:#f1f1f1;//点击状态颜色
|
||||||
$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
|
$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
|
||||||
|
|
||||||
|
|||||||
@ -12,9 +12,10 @@ import baseConfig from '@/config/env'
|
|||||||
|
|
||||||
const request = (config) => {
|
const request = (config) => {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
|
const token = config?.token ? config.token : uni.getStorageSync('token')
|
||||||
const headerDefault = {
|
const headerDefault = {
|
||||||
version: baseConfig.version,
|
version: baseConfig.version,
|
||||||
token: config?.token ? config.token : uni.getStorageSync('token')
|
authorization: `Bearer ${token}`
|
||||||
}
|
}
|
||||||
const URL = config.baseUrl ? config.baseUrl + config.url : baseConfig.baseUrl + config.url
|
const URL = config.baseUrl ? config.baseUrl + config.url : baseConfig.baseUrl + config.url
|
||||||
const method = config.method || 'POST'
|
const method = config.method || 'POST'
|
||||||
@ -31,7 +32,11 @@ const request = (config) => {
|
|||||||
const { statusCode, data } = res
|
const { statusCode, data } = res
|
||||||
if (statusCode === 200) {
|
if (statusCode === 200) {
|
||||||
// 根据情况添加处理代码
|
// 根据情况添加处理代码
|
||||||
resolve(data)
|
resolve({
|
||||||
|
code: data.errorCode,
|
||||||
|
data: data.data,
|
||||||
|
message: data.errorMsg
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
resolve({ code: -1, data, message: '网络不太好哦,请稍后再试' })
|
resolve({ code: -1, data, message: '网络不太好哦,请稍后再试' })
|
||||||
}
|
}
|
||||||
@ -49,10 +54,9 @@ const request = (config) => {
|
|||||||
console.log(URL.substring(baseConfig.baseUrl.length + 1), {
|
console.log(URL.substring(baseConfig.baseUrl.length + 1), {
|
||||||
url: URL.substring(baseConfig.baseUrl.length + 1),
|
url: URL.substring(baseConfig.baseUrl.length + 1),
|
||||||
req: config?.data || {},
|
req: config?.data || {},
|
||||||
code: res?.data?.code,
|
code: res?.data?.errorCode,
|
||||||
res: res?.data?.data,
|
res: res?.data?.data,
|
||||||
requestId: res?.header ? res?.header['X-Ca-Request-Id'] : '',
|
token: header?.authorization || '',
|
||||||
token: header?.token || '',
|
|
||||||
duration: new Date().getTime() - timestamp
|
duration: new Date().getTime() - timestamp
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||