2025-10-27 09:58:13 +08:00

543 lines
12 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view v-if="buttonInfo">
<view v-if="isLogin">
<view class="account-info" @click="toUsereInfo">
<image class="avatar" :src="userInfo.headUrl" mode="aspectFill"></image>
<view class="account-nickname">
<text class="nickname">{{ userInfo.nickname }}</text>
<text class="account">{{ userInfo.mobile }}</text>
</view>
</view>
<view class="follow-official-account">
<text>关注公众号接收更多消息提醒</text>
<!-- #ifdef MP-WEIXIN -->
<official-account><view class="follow-btn">关注公众号</view></official-account>
<!-- #endif -->
<view class="follow-btn" @click="jumpToWeChatfficialAccount">关注公众号</view>
</view>
<label for="contact">
<view class="option-item">
<view class="icon-label">
<image class="left-icon" src="https://cos-lock.skychip.top/mp/icon_customer_service.png">
</image>
<text>人工客服</text>
</view>
<image class="icon-arrow" src="https://cos-lock.skychip.top/mp/icon_arrow.png" mode="aspectFill">
</image>
</view>
</label>
<view class="view">
<!-- #ifdef APP-PLUS -->
<view @click="toContact">
<view class="view-button">
<view>客服</view>
<image class="icon-arrow" src="https://cos-lock.skychip.top/mp/icon_arrow.png"
mode="aspectFill">
</image>
</view>
</view>
<!-- #endif -->
<view class="view-button">
<view>邮箱 / 商务合作</view>
<text class="right-text">{{env.officialEmail}}</text>
</view>
<view class="view-line"></view>
<view class="view-button">
<view>官网</view>
<text class="right-text">{{env.officialWebsite}}</text>
</view>
<view class="view-line"></view>
<view class="view-button" @click="toWebview()">
<view>公司介绍</view>
<image class="icon-arrow" src="https://cos-lock.skychip.top/mp/icon_arrow.png" mode="aspectFill">
</image>
</view>
<view class="view-line"></view>
<view class="view-button" @click="toWebview('userAgreement')">
<view>用户协议</view>
<image class="icon-arrow" src="https://cos-lock.skychip.top/mp/icon_arrow.png" mode="aspectFill">
</image>
</view>
<view class="view-line"></view>
<view class="view-button" @click="toWebview('privacy')">
<view>隐私政策</view>
<image class="icon-arrow" src="https://cos-lock.skychip.top/mp/icon_arrow.png" mode="aspectFill">
</image>
</view>
</view>
<view class="env" v-if="env">
<view class="env-text">{{ env.name }} {{ env.version }}+{{ env.buildNumber }}</view>
<view>{{ env.baseUrl.split('/').slice(0, 3).join('/') }}</view>
<view v-if="!(envVersion === 'release' || nodeEnv === 'production') && env" class="env-button"
@click="show = true">切换环境</view>
</view>
<!-- #ifdef MP-WEIXIN -->
<label for="changePhone">
<view class="switch-account">切换账号</view>
</label>
<!-- #endif -->
<!-- #ifdef APP-PLUS -->
<view class="switch-account !bg-red-500" @click="logout">退出</view>
<view class="delete-account" @click="deleteAccount">删除账号</view>
<!-- #endif -->
</view>
<view v-else>
<view class="tips">因智能门锁与账号绑定登录为手机号登录</view>
<label for="phone">
<view class="button-login">登录</view>
</label>
<view class="env" v-if="env">
<view class="env-text">{{ env.name }} {{ env.version }}+{{ env.buildNumber }}</view>
<view>{{ env.baseUrl.split('/').slice(0, 3).join('/') }}</view>
<view v-if="!(envVersion === 'release' || nodeEnv === 'production') && env" class="env-button"
@click="show = true">
切换环境
</view>
</view>
</view>
</view>
<button open-type="contact" style="display: none" id="contact"></button>
<button open-type="getPhoneNumber" style="display: none" id="phone" @getphonenumber="getphonenumber"></button>
<button open-type="getPhoneNumber" style="display: none" id="changePhone" @getphonenumber="changePhone"></button>
<up-action-sheet :actions="envList" :closeOnClickOverlay="true" title="切换环境" cancelText="取消"
:closeOnClickAction="true" :show="show" :safeAreaInsetBottom="true" @close="show = false"
@select="selectEnv"></up-action-sheet>
</template>
<script>
import {
mapState,
mapActions
} from 'pinia'
import {
useBasicStore
} from '@/stores/basic'
import {
useUserStore
} from '@/stores/user'
import {
useLockStore
} from '@/stores/lock'
import {
phoneLoginRequest,
logoutRequest
} from '@/api/user'
import env from '@/config/env'
import {
setStorage,
getStorage,
removeStorage
} from '@/utils/storage'
import {
useNotificationStore
} from '@/stores/notification'
import {
getAppInfoRequest
} from '@/api/system'
import {
loginRequest
} from '@/api/user'
export default {
data() {
return {
buttonInfo: null,
env: null,
envVersion: '',
envList: [],
show: false,
nodeEnv: ''
}
},
computed: {
...mapState(useUserStore, ['isLogin', 'userInfo']),
...mapState(useLockStore, ['lockSearch']),
...mapState(useNotificationStore, ['notificationSearch'])
},
async onLoad() {
this.buttonInfo = await this.getButtonInfo()
this.env = await env[await getApp().globalData.getEnvConfig()]
this.envVersion = getApp().globalData.envVersion
this.nodeEnv = process.env.NODE_ENV
// eslint-disable-next-line guard-for-in,no-restricted-syntax
for (let key in env) {
this.envList.push({
...env[key],
key
})
}
},
methods: {
...mapActions(useBasicStore, ['getButtonInfo', 'routeJump']),
...mapActions(useLockStore, ['getLockList', 'updateLockSearch']),
...mapActions(useNotificationStore, ['getNotificationList', 'updateNotificationSearch']),
...mapActions(useUserStore, [
'updateLoginStatus',
'phoneLogin',
'updateUserInfo',
'getUserInfo',
'checkSession'
]),
deleteAccount() {
uni.showModal({
title: '提示',
content: '删除账号后,你的所有信息及相关记录都会从平台彻底删除,且不可恢复,是否删除?',
success: res => {
if (res.confirm) {
this.routeJump({
name: 'deleteAccount'
})
}
}
})
},
selectEnv(env) {
setStorage('envVersion', env.key)
removeStorage('token')
removeStorage('openid')
removeStorage('userInfo')
removeStorage('lockList')
uni.reLaunch({
url: '/pages/main/home'
})
},
toContact() {
getAppInfoRequest().then(res => {
if (res.code === 0) {
plus.runtime.openURL(res.data.wechat_service_url)
}
})
},
async changePhone(res) {
if (res.detail.errMsg === 'getPhoneNumber:fail user deny') {
return
}
const that = this
uni.showLoading({
title: '登录中'
})
uni.login({
provider: 'weixin',
async success(loginRes) {
const openid = getStorage('openid')
const {
code,
data,
message
} = await phoneLoginRequest({
encryptedData: res.detail.encryptedData,
iv: res.detail.iv,
rebind: true,
openid,
js_code: loginRes.code
})
uni.hideLoading()
if (code === 0) {
removeStorage('userInfo')
removeStorage('lockList')
setStorage('token', data.accessToken)
that.updateLockSearch({
...that.lockSearch,
pageNo: 1
})
that.getUserInfo()
that.getLockList(that.lockSearch)
that.updateNotificationSearch({
pageNo: 1
})
that.getNotificationList(that.notificationSearch)
uni.showToast({
title: '账号切换成功',
icon: 'none'
})
} else if (code === 438) {
/* empty */
} else {
uni.showToast({
title: message,
icon: 'none'
})
}
},
fail() {
uni.hideLoading()
uni.showToast({
title: '登录失败,请重试'
})
}
})
},
async getphonenumber(data) {
if (data.detail.errMsg === 'getPhoneNumber:fail user deny') {
return
}
const that = this
uni.showLoading({
title: '登录中'
})
uni.login({
provider: 'weixin',
async success(loginRes) {
const result = await that.phoneLogin({
encryptedData: data.detail.encryptedData,
iv: data.detail.iv,
code: loginRes.code
})
uni.hideLoading()
if (!result) {
uni.showToast({
title: result.message,
icon: 'none'
})
}
},
fail() {
uni.hideLoading()
uni.showToast({
title: '登录失败,请重试'
})
}
})
},
toUsereInfo() {
this.routeJump({
name: 'userInfo'
})
},
toWebview(type) {
this.routeJump({
name: 'webview',
params: {
type
}
})
},
jumpToWeChatfficialAccount(){
},
logout() {
uni.showModal({
title: '提示',
content: '确定退出登录吗?',
success: async res => {
if (res.confirm) {
await logoutRequest()
removeStorage('token')
removeStorage('openid')
removeStorage('userInfo')
removeStorage('lockList')
this.routeJump({
name: 'login',
type: 'reLaunch'
})
}
}
})
}
}
}
</script>
<style lang="scss">
page {
background-color: $uni-bg-color-grey;
}
</style>
<style scoped lang="scss">
.background-image {
width: 710rpx;
height: 156rpx;
margin-top: 32rpx;
margin-left: 20rpx;
border-radius: 32rpx;
}
.view {
background: #ffffff;
border-radius: 16rpx;
display: flex;
flex-direction: column;
align-items: center;
margin: 20rpx 20rpx;
padding: 20rpx 20rpx;
gap: 20rpx;
}
.follow-official-account {
margin: 20rpx 20rpx;
background-image: url('https://cos-lock.skychip.top/mp/follow_official_account_bg.png');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
height: 88rpx;
border-radius: 16rpx;
display: flex;
align-items: center;
justify-content: space-between;
color: white;
font-weight: 400;
font-size: 28rpx;
padding-left: 20rpx;
padding-right: 20rpx;
.follow-btn {
display: flex;
align-items: center;
padding: 12rpx 20rpx;
background-color: white;
border-radius: 16rpx;
color: #4777ee;
}
}
.account-info {
margin: 20rpx 20rpx;
padding-left: 20rpx;
padding-top: 20rpx;
padding-bottom: 20rpx;
padding-right: 20rpx;
display: flex;
gap: 18rpx;
align-items: center;
border-radius: 16rpx;
background-color: white;
.avatar {
width: 120rpx;
height: 120rpx;
}
.account-nickname {
display: flex;
flex-direction: column;
gap: 12rpx;
.nickname {
font-size: 32rpx;
font-weight: 600;
}
.account {
font-size: 24rpx;
color: gray;
font-weight: 500;
}
}
}
.view-button {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
border-radius: 16rpx;
font-size: 28rpx;
.right-text {
font-size: 28rpx;
color: gray;
}
}
.icon-arrow {
width: 40rpx;
height: 40rpx;
}
.view-line {
width: 100%;
height: 3rpx;
background: #ebebeb;
}
.switch-account {
position: absolute;
bottom: 120rpx;
width: 600rpx;
height: 80rpx;
margin-left: 75rpx;
font-size: 40rpx;
font-weight: bold;
line-height: 80rpx;
color: #ffffff;
text-align: center;
background: #4777ee;
border-radius: 46rpx;
}
.delete-account {
position: absolute;
right: 75rpx;
bottom: 60rpx;
font-size: 28rpx;
color: #666;
}
.env {
position: absolute;
bottom: 240rpx;
width: 600rpx;
margin-left: 75rpx;
line-height: 80rpx;
text-align: center;
.env-text {
font-size: 30rpx;
font-weight: bold;
color: #999999;
}
.env-button {
font-size: 0.8rem;
color: #022b7c;
text-align: right;
text-decoration: underline;
background: inherit;
}
}
.button-login {
width: 650rpx;
height: 120rpx;
margin-left: 50rpx;
font-size: 48rpx;
font-weight: bold;
line-height: 120rpx;
color: #ffffff;
text-align: center;
background: #4777ee;
border-radius: 46rpx;
}
.tips {
padding: 32rpx 0;
margin-top: 25vh;
font-size: 28rpx;
color: #999999;
text-align: center;
}
.option-item {
background-color: white;
display: flex;
padding: 20rpx 20rpx;
margin-left: 20rpx;
margin-right: 20rpx;
border-radius: 16rpx;
align-items: center;
justify-content: space-between;
.left-icon {
width: 52rpx;
height: 52rpx;
}
.icon-label {
display: flex;
align-items: center;
gap: 12rpx;
}
}
</style>