Files
property-resident-side/property-uniapp-project/pageSubPack/my/settingIndex.vue

433 lines
10 KiB
Vue
Raw 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 class="contentStyle">
<view class="status-bar"></view>
<uni-nav-bar title="设置" left-icon="left" @clickLeft="goBack" backgroundColor="transparent" :border="false">
</uni-nav-bar>
<scroll-view class="page" scroll-y>
<view class="setting-item" v-for="(item, index) in settingList" :key="index" @click="onItemClick(item)">
<text class="item-title">{{ item.title }}</text>
<view class="item-right" v-if="item.type === 'text'">
<text :class="item.valueClass || 'item-value'">{{ item.value }}</text>
<view class="item-arrow"></view>
</view>
<switch class="no-cross-switch" v-else-if="item.type === 'switch'" :checked="item.checked"
@change="onSwitchChange(item, $event)" />
<view class="item-arrow" v-else></view>
</view>
</scroll-view>
<view class="bottom-btn">
<button class="logout-btn" @click="logout">退出登录</button>
</view>
</view>
</template>
<script setup>
import {
ref,
onMounted,
reactive
} from 'vue'
import {
onReachBottom,
onLoad,
onUnload,
onPullDownRefresh
} from '@dcloudio/uni-app'
import {
authLogout, getUserProfile, getUserNotify, changeUserNotify, getAppVersion, checkAppUpdate, postUpdateLog
} from '/pageSubPack/api/apiSub.js'
//
const statusBarHeight = ref(20)
const cacheSize = ref(0)
const currentVersion = ref('1.0.0')
const currentVersionCode = ref(1)
const settingList = ref([{
title: '更改手机号码',
type: 'text',
value: ''
},
{
title: '修改密码',
type: 'arrow'
},
{
title: '消息通知',
type: 'switch',
checked: false
},
{
title: '清除缓存',
type: 'text',
value: '9.2M'
},
{
title: '升级版本',
type: 'text',
value: '当前版本 1.0.0',
valueClass: 'item-version'
}
])
// 格式化字节大小
const formatSize = (bytes) => {
if (!bytes || bytes === 0) return '0B'
const k = 1024
const sizes = ['B', 'KB', 'M', 'G']
const i = Math.floor(Math.log(bytes) / Math.log(k))
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + sizes[i]
}
// 获取真实缓存大小
const getCacheSizeData = () => {
return new Promise((resolve) => {
// #ifdef APP-PLUS
// App 端获取完整缓存(含图片、文件等)
plus.cache.calculate((size) => {
resolve(formatSize(size))
})
// #endif
// #ifndef APP-PLUS
// 小程序/H5 端只能获取 storage 缓存
const info = uni.getStorageInfoSync()
const size = (info.currentSize || 0) * 1024 // currentSize 单位 KB
resolve(formatSize(size))
// #endif
})
}
// 获取当前运行版本号
const initCurrentVersion = () => {
// #ifdef APP-PLUS
currentVersion.value = plus.runtime.version || '1.0.0'
currentVersionCode.value = plus.runtime.versionCode || 1
// #endif
// #ifndef APP-PLUS
const manifest = uni.getAppAuthorizeSetting ? uni.getAppAuthorizeSetting() : null
if (manifest && manifest.version) {
currentVersion.value = manifest.version
}
// #endif
settingList.value[4].value = '当前版本 ' + currentVersion.value
}
// 版本号比较v1 > v2 返回 1v1 = v2 返回 0v1 < v2 返回 -1
const compareVersion = (v1, v2) => {
const arr1 = v1.split('.').map(Number)
const arr2 = v2.split('.').map(Number)
const len = Math.max(arr1.length, arr2.length)
for (let i = 0; i < len; i++) {
const n1 = arr1[i] || 0
const n2 = arr2[i] || 0
if (n1 > n2) return 1
if (n1 < n2) return -1
}
return 0
}
// 检查版本更新
const checkVersionUpdate = async () => {
uni.showLoading({ title: '检查中...', mask: true })
try {
const systemInfo = uni.getSystemInfoSync()
const platform = systemInfo.platform === 'ios' ? 'ios' : 'android'
const channel = 'resident'
// 1. 查询最新版本
const versionRes = await getAppVersion(platform, channel)
if (versionRes.code === 200 && versionRes.data) {
const latestVersion = versionRes.data.versionName || ''
const latestVersionCode = versionRes.data.versionCode || 0
// 2. 调 checkAppUpdate 检查是否需要更新
const checkRes = await checkAppUpdate({
platform: platform,
channel: channel,
currentVersionCode: currentVersionCode.value
})
uni.hideLoading()
if (checkRes.code === 200 && checkRes.data) {
const needUpdate = checkRes.data.needUpdate !== false
if (needUpdate) {
const updateType = checkRes.data.updateType || versionRes.data.updateType || 'optional'
const isForce = updateType === 'force'
uni.showModal({
title: isForce ? '强制更新' : '发现新版本',
content: `当前版本:${currentVersion.value}\n最新版本${latestVersion}${versionRes.data.releaseNotes || versionRes.data.updateDesc ? '\n\n更新内容' + (versionRes.data.releaseNotes || versionRes.data.updateDesc) : ''}`,
showCancel: !isForce,
confirmText: '立即更新',
cancelText: '稍后',
success: (modalRes) => {
if (modalRes.confirm && versionRes.data.downloadUrl) {
// 记录更新日志
const userId = uni.getStorageSync('userId')
if (userId) {
postUpdateLog({
userId: userId,
platform: platform,
fromVersion: currentVersionCode.value,
toVersion: latestVersionCode
})
}
// #ifdef APP-PLUS
plus.runtime.openURL(versionRes.data.downloadUrl)
// #endif
// #ifndef APP-PLUS
uni.showToast({ title: '请在应用商店更新', icon: 'none' })
// #endif
} else if (isForce && !modalRes.confirm) {
// 强制更新时用户点取消,退出应用
// #ifdef APP-PLUS
plus.runtime.quit()
// #endif
}
}
})
} else {
uni.showToast({ title: '已是最新版本', icon: 'success' })
}
} else {
uni.showToast({ title: '检查失败', icon: 'none' })
}
} else {
uni.hideLoading()
uni.showToast({ title: '检查失败', icon: 'none' })
}
} catch (err) {
uni.hideLoading()
uni.showToast({ title: '检查失败', icon: 'none' })
}
}
//
const onItemClick = (item) => {
if (item.title == '更改手机号码') {
uni.redirectTo({
url: '/pageSubPack/my/changePhone'
});
} else if (item.title == '修改密码') {
uni.redirectTo({
url: '/pageSubPack/my/changePwd'
});
} else if (item.title == '清除缓存') {
uni.clearStorageSync();
// #ifdef APP-PLUS
plus.cache.clear(() => {})
// #endif
settingList.value[3].value = '0B'
uni.showLoading({
title: '清除中...',
mask: true
});
setTimeout(() => {
uni.showToast({
title: '清除成功',
icon: 'success'
});
}, 1000);
setTimeout(() => {
uni.hideLoading();
}, 2500);
} else if (item.title == '升级版本') {
checkVersionUpdate()
}
}
const logout = () => {
uni.showModal({
title: '提示',
content: '确定要退出当前账号吗?',
success: (res) => {
if (res.confirm) {
uni.showLoading({
title: '退出中...',
mask: true
});
authLogout().then(res => {
if (res.code === 200) {
uni.hideLoading();
uni.showToast({
title: '退出成功',
icon: 'success'
});
setTimeout(() => {
uni.hideLoading();
uni.redirectTo({
url: '/pageSubPack/loginSub/pwd-login'
});
}, 1500);
} else {
uni.showToast({
title: `${res.msg}`,
icon: 'error'
});
}
}).catch(err => {
console.log(err);
uni.showToast({
title: `${err}`,
icon: 'error'
});
})
}
}
})
}
const onSwitchChange = (item, e) => {
const checked = e.detail.value
const notifyEnabled = checked ? '1' : '0'
changeUserNotify({ notifyEnabled }).then(res => {
if (res.code === 200) {
item.checked = checked
} else {
uni.showToast({ title: res.msg || '更新失败', icon: 'none' })
item.checked = !checked
}
}).catch(() => {
uni.showToast({ title: '更新失败', icon: 'none' })
item.checked = !checked
})
}
const goBack = () => {
uni.switchTab({
url: '/pages/myIndex/myIndex'
});
}
onMounted(async () => {
initCurrentVersion()
settingList.value[3].value = await getCacheSizeData()
getUserProfile().then(res => {
if (res.code === 200 && res.data) {
const phone = res.data.phone || ''
settingList.value[0].value = phone
}
})
getUserNotify().then(res => {
if (res.code === 200 && res.data) {
settingList.value[2].checked = res.data.notifyEnabled === '1'
}
})
})
</script>
<style lang="scss">
page {
background: #f9f9f9;
}
</style>
<style lang="scss" scoped>
.contentStyle {
display: flex;
flex-direction: column;
height: 100vh;
background-color: #f9f9f9;
}
.page {
flex: 1;
overflow-y: auto;
padding: 0 40rpx;
box-sizing: border-box;
background-color: #fff;
}
.bottom-btn {
padding: 20rpx 30rpx 40rpx;
background-color: #fff;
}
</style>
<style scoped>
.setting-item {
display: flex;
align-items: center;
justify-content: space-between;
background-color: #fff;
padding: 30rpx;
border-bottom: 2rpx solid #f0f0f0;
}
.item-title {
font-size: 32rpx;
color: #333;
line-height: 1.4;
}
.item-right {
display: flex;
align-items: center;
gap: 10rpx;
}
.item-value {
font-size: 28rpx;
color: #333;
}
.item-version {
font-size: 28rpx;
color: #999;
}
.item-arrow {
width: 10rpx;
height: 10rpx;
border-top: 2rpx solid #999;
border-right: 2rpx solid #999;
transform: rotate(45deg);
margin-left: 10rpx;
}
.logout-btn {
width: 100%;
height: 96rpx;
line-height: 96rpx;
text-align: center;
font-size: 32rpx;
border-radius: 12rpx;
color: #666;
background-color: #F3F3F3;
/* box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.06); */
}
.logout-btn:active {
background-color: #f5f5f5;
opacity: 0.8;
}
.status-bar {
width: 100vw;
height: 46px;
}
</style>
<style>
::v-deep .uni-switch-input:before {
background-color: #cccccd !important;
}
.no-cross-switch::before {
display: none !important;
}
.no-cross-switch {
transform: scale(0.85);
border-radius: 50rpx !important;
}
.no-cross-switch>>>.uni-switch-input-checked {
background-color: #007aff !important;
}
</style>