新增三码适配
This commit is contained in:
@@ -11,9 +11,6 @@
|
|||||||
// 注意:语言初始化已移至 main.js,确保每次 reLaunch 都能正确加载新语言
|
// 注意:语言初始化已移至 main.js,确保每次 reLaunch 都能正确加载新语言
|
||||||
},
|
},
|
||||||
onShow: async function() {
|
onShow: async function() {
|
||||||
console.log('========================================')
|
|
||||||
console.log('=== App onShow 被调用 ===')
|
|
||||||
console.log('时间戳:', new Date().toLocaleTimeString())
|
|
||||||
|
|
||||||
// 检查启动路径,如果设置了启动路径则跳转
|
// 检查启动路径,如果设置了启动路径则跳转
|
||||||
try {
|
try {
|
||||||
@@ -81,8 +78,6 @@
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('App onShow - 语言检查失败:', e)
|
console.error('App onShow - 语言检查失败:', e)
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('========================================')
|
|
||||||
},
|
},
|
||||||
onHide: function() {
|
onHide: function() {
|
||||||
console.log('App Hide')
|
console.log('App Hide')
|
||||||
|
|||||||
+22
-8
@@ -36,8 +36,10 @@ const request = (option) => {
|
|||||||
method: option.method,
|
method: option.method,
|
||||||
data: option.data,
|
data: option.data,
|
||||||
header: {
|
header: {
|
||||||
"Content-Type": option.headers && option.headers["Content-Type"] ? option.headers["Content-Type"] : (option.method && option.method.toUpperCase() === 'POST' ? 'application/json' : 'application/x-www-form-urlencoded'),
|
"Content-Type": option.headers && option.headers["Content-Type"] ? option.headers[
|
||||||
...option.headers,
|
"Content-Type"] : (option.method && option.method.toUpperCase() === 'POST' ?
|
||||||
|
'application/json' : 'application/x-www-form-urlencoded'),
|
||||||
|
...option.headers,
|
||||||
'appid': platformAppid,
|
'appid': platformAppid,
|
||||||
'Authorization': "Bearer " + uni.getStorageSync('token'),
|
'Authorization': "Bearer " + uni.getStorageSync('token'),
|
||||||
'Clientid': uni.getStorageSync('client_id'),
|
'Clientid': uni.getStorageSync('client_id'),
|
||||||
@@ -56,7 +58,9 @@ const request = (option) => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
reject({msg: `请求失败,状态码:${res.statusCode}`})
|
reject({
|
||||||
|
msg: `请求失败,状态码:${res.statusCode}`
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,12 +72,22 @@ const request = (option) => {
|
|||||||
// 计算重定向地址
|
// 计算重定向地址
|
||||||
const pages = getCurrentPages()
|
const pages = getCurrentPages()
|
||||||
const current = pages && pages.length ? pages[pages.length - 1] : null
|
const current = pages && pages.length ? pages[pages.length - 1] : null
|
||||||
const route = current && current.route ? ('/' + current.route) : '/pages/index/index'
|
const route = current && current.route ? ('/' + current.route) :
|
||||||
const query = current && current.options ? Object.keys(current.options).map(k => `${k}=${encodeURIComponent(current.options[k])}`).join('&') : ''
|
'/pages/index/index'
|
||||||
|
const query = current && current.options ? Object.keys(current.options).map(
|
||||||
|
k => `${k}=${encodeURIComponent(current.options[k])}`).join('&') :
|
||||||
|
''
|
||||||
const redirect = encodeURIComponent(query ? `${route}?${query}` : route)
|
const redirect = encodeURIComponent(query ? `${route}?${query}` : route)
|
||||||
|
// console.log(redirect, "===========");
|
||||||
// 跳转到登录页
|
// 跳转到登录页
|
||||||
uni.reLaunch({ url: `/subPackages/user/login/index?redirect=${redirect}` })
|
uni.reLaunch({
|
||||||
} catch (e) {}
|
url: "/subPackages/user/login/index"
|
||||||
|
})
|
||||||
|
} catch (e) {
|
||||||
|
uni.reLaunch({
|
||||||
|
url: "/subPackages/user/login/index"
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查业务状态码
|
// 检查业务状态码
|
||||||
@@ -83,7 +97,7 @@ const request = (option) => {
|
|||||||
// 判断是否需要忽略数据为空的错误
|
// 判断是否需要忽略数据为空的错误
|
||||||
if (option.ignoreEmptyError &&
|
if (option.ignoreEmptyError &&
|
||||||
(res.data.code === 500 && res.data.msg &&
|
(res.data.code === 500 && res.data.msg &&
|
||||||
(res.data.msg.includes('未找到') || res.data.msg.includes('不存在')))) {
|
(res.data.msg.includes('未找到') || res.data.msg.includes('不存在')))) {
|
||||||
// 对于指定需要忽略的错误,返回一个标准的"成功但数据为空"的响应
|
// 对于指定需要忽略的错误,返回一个标准的"成功但数据为空"的响应
|
||||||
resolve({
|
resolve({
|
||||||
code: 200,
|
code: 200,
|
||||||
|
|||||||
@@ -71,10 +71,6 @@ function getI18nInstance() {
|
|||||||
// 每次都重新读取当前语言
|
// 每次都重新读取当前语言
|
||||||
const currentLang = getSavedLanguage()
|
const currentLang = getSavedLanguage()
|
||||||
|
|
||||||
console.log('=== getI18nInstance 被调用 ===')
|
|
||||||
console.log('缓存中的语言:', currentLang)
|
|
||||||
console.log('当前 i18n 实例存在?', !!i18nInstance)
|
|
||||||
console.log('当前 i18n.global.locale:', i18nInstance?.global?.locale)
|
|
||||||
|
|
||||||
// 检查是否需要更新语言
|
// 检查是否需要更新语言
|
||||||
if (i18nInstance && i18nInstance.global.locale !== currentLang) {
|
if (i18nInstance && i18nInstance.global.locale !== currentLang) {
|
||||||
@@ -85,18 +81,11 @@ function getI18nInstance() {
|
|||||||
// 直接更新 locale(这应该会触发所有组件重新渲染)
|
// 直接更新 locale(这应该会触发所有组件重新渲染)
|
||||||
i18nInstance.global.locale = currentLang
|
i18nInstance.global.locale = currentLang
|
||||||
|
|
||||||
console.log('i18n.global.locale 已更新为:', i18nInstance.global.locale)
|
|
||||||
console.log('测试翻译 (common.loading):', i18nInstance.global.t('common.loading'))
|
|
||||||
console.log('测试翻译 (home.title):', i18nInstance.global.t('home.title'))
|
|
||||||
console.log('===================================')
|
|
||||||
|
|
||||||
return i18nInstance
|
return i18nInstance
|
||||||
}
|
}
|
||||||
|
|
||||||
// 首次创建实例
|
// 首次创建实例
|
||||||
if (!i18nInstance) {
|
if (!i18nInstance) {
|
||||||
console.log('=== 首次创建 i18n 实例 ===')
|
|
||||||
|
|
||||||
i18nInstance = createI18n({
|
i18nInstance = createI18n({
|
||||||
legacy: true, // 使用 Legacy API 模式,支持全局 $t
|
legacy: true, // 使用 Legacy API 模式,支持全局 $t
|
||||||
locale: currentLang,
|
locale: currentLang,
|
||||||
@@ -110,20 +99,12 @@ function getI18nInstance() {
|
|||||||
silentFallbackWarn: true
|
silentFallbackWarn: true
|
||||||
})
|
})
|
||||||
|
|
||||||
console.log('i18n 实例已创建,语言:', currentLang)
|
|
||||||
console.log('测试翻译 (common.loading):', i18nInstance.global.t('common.loading'))
|
|
||||||
console.log('测试翻译 (home.title):', i18nInstance.global.t('home.title'))
|
|
||||||
console.log('============================')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return i18nInstance
|
return i18nInstance
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createApp() {
|
export function createApp() {
|
||||||
console.log('========================================')
|
|
||||||
console.log('=== createApp 被调用 ===')
|
|
||||||
console.log('时间戳:', new Date().toLocaleTimeString())
|
|
||||||
console.log('========================================')
|
|
||||||
|
|
||||||
const app = createSSRApp(App)
|
const app = createSSRApp(App)
|
||||||
|
|
||||||
@@ -153,13 +134,6 @@ export function createApp() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('=== Vue 3 应用创建完成 ===')
|
|
||||||
console.log('最终 locale:', i18n.global.locale)
|
|
||||||
console.log('app.config.globalProperties.$t 存在?', !!app.config.globalProperties.$t)
|
|
||||||
console.log('app.config.globalProperties.$i18n 存在?', !!app.config.globalProperties.$i18n)
|
|
||||||
console.log('测试 $t 调用:', i18n.global.t('common.loading'))
|
|
||||||
console.log('===========================')
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
app
|
app
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-3
@@ -93,9 +93,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"router" : {
|
"router" : {
|
||||||
"mode" : "hash",
|
"mode" : "history",
|
||||||
"base" : "./"
|
"base" : "/"
|
||||||
}
|
},
|
||||||
|
"title" : "FDZPower"
|
||||||
},
|
},
|
||||||
"uniStatistics" : {
|
"uniStatistics" : {
|
||||||
"enable" : false
|
"enable" : false
|
||||||
|
|||||||
@@ -61,6 +61,12 @@
|
|||||||
"navigationBarBackgroundColor": "#ffffff",
|
"navigationBarBackgroundColor": "#ffffff",
|
||||||
"navigationBarTextStyle": "black"
|
"navigationBarTextStyle": "black"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "toProgram",
|
||||||
|
"style": {
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"subPackages": [
|
"subPackages": [
|
||||||
|
|||||||
+5
-10
@@ -181,7 +181,6 @@
|
|||||||
|
|
||||||
// 生命周期 onLoad 钩子
|
// 生命周期 onLoad 钩子
|
||||||
onLoad(async (options) => {
|
onLoad(async (options) => {
|
||||||
console.log('options', options)
|
|
||||||
|
|
||||||
// 普通链接二维码进入时,参数通常在 options.q(且为编码后的完整 URL)
|
// 普通链接二维码进入时,参数通常在 options.q(且为编码后的完整 URL)
|
||||||
if (!options.deviceNo && options.q) {
|
if (!options.deviceNo && options.q) {
|
||||||
@@ -232,11 +231,6 @@
|
|||||||
isAlipayMiniProgram.value = false
|
isAlipayMiniProgram.value = false
|
||||||
isH5.value = true
|
isH5.value = true
|
||||||
// #endif
|
// #endif
|
||||||
console.log('当前运行环境:', {
|
|
||||||
isWechatMiniProgram: isWechatMiniProgram.value,
|
|
||||||
isAlipayMiniProgram: isAlipayMiniProgram.value,
|
|
||||||
isH5: isH5.value
|
|
||||||
})
|
|
||||||
await checkUserPhone()
|
await checkUserPhone()
|
||||||
await fetchDeviceInfo()
|
await fetchDeviceInfo()
|
||||||
})
|
})
|
||||||
@@ -366,7 +360,7 @@
|
|||||||
const fetchDeviceInfo = async () => {
|
const fetchDeviceInfo = async () => {
|
||||||
try {
|
try {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
console.log(deviceId.value);
|
// console.log(deviceId.value);
|
||||||
const res = await getDeviceInfo(deviceId.value)
|
const res = await getDeviceInfo(deviceId.value)
|
||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
deviceInfo.value = res.data.device || {}
|
deviceInfo.value = res.data.device || {}
|
||||||
@@ -404,9 +398,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
uni.reLaunch({
|
|
||||||
url:'/pages/index/index'
|
// uni.reLaunch({
|
||||||
})
|
// url:'/pages/index/index'
|
||||||
|
// })
|
||||||
}
|
}
|
||||||
}catch(error){
|
}catch(error){
|
||||||
console.error('获取设备信息失败:', error)
|
console.error('获取设备信息失败:', error)
|
||||||
|
|||||||
+46
-28
@@ -21,18 +21,18 @@
|
|||||||
<!-- 全屏地图组件 -->
|
<!-- 全屏地图组件 -->
|
||||||
<!-- 支付宝小程序使用专用组件 -->
|
<!-- 支付宝小程序使用专用组件 -->
|
||||||
<!-- #ifdef MP-ALIPAY -->
|
<!-- #ifdef MP-ALIPAY -->
|
||||||
<MapComponentAlipay v-if="!isLoading && userLocation && !locationPermissionDenied" ref="mapRef" :userLocation="userLocation"
|
<MapComponentAlipay v-if="!isLoading && userLocation && !locationPermissionDenied" ref="mapRef"
|
||||||
:positionList="positionList" :filteredPositions="filteredPositions" :searchKeyword="searchKeyword"
|
:userLocation="userLocation" :positionList="positionList" :filteredPositions="filteredPositions"
|
||||||
:enableMarkers="true" :bannerImages="bannerImages"
|
:searchKeyword="searchKeyword" :enableMarkers="true" :bannerImages="bannerImages"
|
||||||
:hideMapOverlays="showGuidePopup || showNoticePopup || showActivityPopup" @relocate="handleRelocate"
|
:hideMapOverlays="showGuidePopup || showNoticePopup || showActivityPopup" @relocate="handleRelocate"
|
||||||
@scan="handleScan" @showList="showLocationList" @markerTap="selectPosition"
|
@scan="handleScan" @showList="showLocationList" @markerTap="selectPosition"
|
||||||
@mapCenterChange="onMapCenterChange" @bannerClick="handleBannerClick" @guide="openGuidePopup" />
|
@mapCenterChange="onMapCenterChange" @bannerClick="handleBannerClick" @guide="openGuidePopup" />
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
<!-- 非支付宝小程序使用通用组件 -->
|
<!-- 非支付宝小程序使用通用组件 -->
|
||||||
<!-- #ifndef MP-ALIPAY -->
|
<!-- #ifndef MP-ALIPAY -->
|
||||||
<MapComponent v-if="!isLoading && userLocation && !locationPermissionDenied" ref="mapRef" :userLocation="userLocation"
|
<MapComponent v-if="!isLoading && userLocation && !locationPermissionDenied" ref="mapRef"
|
||||||
:positionList="positionList" :filteredPositions="filteredPositions" :searchKeyword="searchKeyword"
|
:userLocation="userLocation" :positionList="positionList" :filteredPositions="filteredPositions"
|
||||||
:enableMarkers="true" :bannerImages="bannerImages"
|
:searchKeyword="searchKeyword" :enableMarkers="true" :bannerImages="bannerImages"
|
||||||
:hideMapOverlays="showGuidePopup || showNoticePopup || showActivityPopup" @relocate="handleRelocate"
|
:hideMapOverlays="showGuidePopup || showNoticePopup || showActivityPopup" @relocate="handleRelocate"
|
||||||
@scan="handleScan" @showList="showLocationList" @markerTap="selectPosition"
|
@scan="handleScan" @showList="showLocationList" @markerTap="selectPosition"
|
||||||
@mapCenterChange="onMapCenterChange" @bannerClick="handleBannerClick" @guide="openGuidePopup" />
|
@mapCenterChange="onMapCenterChange" @bannerClick="handleBannerClick" @guide="openGuidePopup" />
|
||||||
@@ -125,13 +125,8 @@
|
|||||||
|
|
||||||
<!-- 支付宝:先授权 phoneNumber,再调用 my.getPhoneNumber,上报后端解密并校验一致性 -->
|
<!-- 支付宝:先授权 phoneNumber,再调用 my.getPhoneNumber,上报后端解密并校验一致性 -->
|
||||||
<!-- #ifdef MP-ALIPAY -->
|
<!-- #ifdef MP-ALIPAY -->
|
||||||
<button
|
<button class="auth-btn" open-type="getAuthorize" scope="phoneNumber"
|
||||||
class="auth-btn"
|
@getAuthorize="onAliAuthorizePhoneNumber" @error="onAliAuthorizePhoneNumberError">
|
||||||
open-type="getAuthorize"
|
|
||||||
scope="phoneNumber"
|
|
||||||
@getAuthorize="onAliAuthorizePhoneNumber"
|
|
||||||
@error="onAliAuthorizePhoneNumberError"
|
|
||||||
>
|
|
||||||
<text>{{ $t('auth.getPhoneNumber') }}</text>
|
<text>{{ $t('auth.getPhoneNumber') }}</text>
|
||||||
</button>
|
</button>
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
@@ -314,11 +309,15 @@
|
|||||||
const navbarStyle = computed(() => {
|
const navbarStyle = computed(() => {
|
||||||
// #ifdef MP-ALIPAY
|
// #ifdef MP-ALIPAY
|
||||||
// 支付宝小程序:不设置 paddingTop
|
// 支付宝小程序:不设置 paddingTop
|
||||||
return { paddingTop: '0px' }
|
return {
|
||||||
|
paddingTop: '0px'
|
||||||
|
}
|
||||||
// #endif
|
// #endif
|
||||||
// #ifndef MP-ALIPAY
|
// #ifndef MP-ALIPAY
|
||||||
// 非支付宝小程序:设置 statusBarHeight
|
// 非支付宝小程序:设置 statusBarHeight
|
||||||
return { paddingTop: statusBarHeight.value + 'px' }
|
return {
|
||||||
|
paddingTop: statusBarHeight.value + 'px'
|
||||||
|
}
|
||||||
// #endif
|
// #endif
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -326,21 +325,29 @@
|
|||||||
const topInfoSectionStyle = computed(() => {
|
const topInfoSectionStyle = computed(() => {
|
||||||
// #ifdef MP-ALIPAY
|
// #ifdef MP-ALIPAY
|
||||||
// 支付宝小程序:使用 paddingTop
|
// 支付宝小程序:使用 paddingTop
|
||||||
return { top: ( navBarHeight.value) + 'px' }
|
return {
|
||||||
|
top: (navBarHeight.value) + 'px'
|
||||||
|
}
|
||||||
// #endif
|
// #endif
|
||||||
// #ifndef MP-ALIPAY
|
// #ifndef MP-ALIPAY
|
||||||
// 非支付宝小程序:使用 top
|
// 非支付宝小程序:使用 top
|
||||||
return { top: (statusBarHeight.value + navBarHeight.value) + 'px' }
|
return {
|
||||||
|
top: (statusBarHeight.value + navBarHeight.value) + 'px'
|
||||||
|
}
|
||||||
// #endif
|
// #endif
|
||||||
})
|
})
|
||||||
|
|
||||||
// 主内容区域样式:不同端适配不同的 paddingTop
|
// 主内容区域样式:不同端适配不同的 paddingTop
|
||||||
const mainContentStyle = computed(() => {
|
const mainContentStyle = computed(() => {
|
||||||
// #ifdef MP-ALIPAY
|
// #ifdef MP-ALIPAY
|
||||||
return { paddingTop: (navBarHeight.value + noticeHeight.value) + 'px' }
|
return {
|
||||||
|
paddingTop: (navBarHeight.value + noticeHeight.value) + 'px'
|
||||||
|
}
|
||||||
// #endif
|
// #endif
|
||||||
// #ifndef MP-ALIPAY
|
// #ifndef MP-ALIPAY
|
||||||
return { paddingTop: (statusBarHeight.value + navBarHeight.value + noticeHeight.value) + 'px' }
|
return {
|
||||||
|
paddingTop: (statusBarHeight.value + navBarHeight.value + noticeHeight.value) + 'px'
|
||||||
|
}
|
||||||
// #endif
|
// #endif
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -372,7 +379,7 @@
|
|||||||
`${k}=${encodeURIComponent(current.options[k])}`).join('&') : ''
|
`${k}=${encodeURIComponent(current.options[k])}`).join('&') : ''
|
||||||
const redirect = encodeURIComponent(query ? `${route}?${query}` : route)
|
const redirect = encodeURIComponent(query ? `${route}?${query}` : route)
|
||||||
uni.reLaunch({
|
uni.reLaunch({
|
||||||
url: `/subPackages/user/login/index?redirect=${redirect}`
|
url: redirect
|
||||||
})
|
})
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
uni.reLaunch({
|
uni.reLaunch({
|
||||||
@@ -437,8 +444,8 @@
|
|||||||
// 调用接口获取广告内容
|
// 调用接口获取广告内容
|
||||||
const res = await getCurrentAdvertisement({
|
const res = await getCurrentAdvertisement({
|
||||||
appPlatform: appPlatform, // 微信平台
|
appPlatform: appPlatform, // 微信平台
|
||||||
appType: 'user' ,// 用户端
|
appType: 'user', // 用户端
|
||||||
pictureLocation:'home_banner'
|
pictureLocation: 'home_banner'
|
||||||
})
|
})
|
||||||
|
|
||||||
console.log('首页广告响应:', res)
|
console.log('首页广告响应:', res)
|
||||||
@@ -1336,19 +1343,25 @@
|
|||||||
uni.navigateBack({
|
uni.navigateBack({
|
||||||
success: () => {
|
success: () => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
uni.navigateTo({ url });
|
uni.navigateTo({
|
||||||
|
url
|
||||||
|
});
|
||||||
}, 100);
|
}, 100);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
uni.navigateTo({ url });
|
uni.navigateTo({
|
||||||
|
url
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (deviceInfo.feeConfig) {
|
if (deviceInfo.feeConfig) {
|
||||||
try {
|
try {
|
||||||
const feeConfig = JSON.parse(deviceInfo.feeConfig)
|
const feeConfig = JSON.parse(deviceInfo.feeConfig)
|
||||||
closeScanPageAndNavigate(`/pages/device/detail?deviceNo=${deviceNo}&feeConfig=${encodeURIComponent(deviceInfo.feeConfig)}`);
|
closeScanPageAndNavigate(
|
||||||
|
`/pages/device/detail?deviceNo=${deviceNo}&feeConfig=${encodeURIComponent(deviceInfo.feeConfig)}`
|
||||||
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
closeScanPageAndNavigate(`/pages/device/detail?deviceNo=${deviceNo}`);
|
closeScanPageAndNavigate(`/pages/device/detail?deviceNo=${deviceNo}`);
|
||||||
}
|
}
|
||||||
@@ -1435,7 +1448,9 @@
|
|||||||
// #ifdef MP-ALIPAY
|
// #ifdef MP-ALIPAY
|
||||||
try {
|
try {
|
||||||
console.log('[ALIPAY] getAuthorize(phoneNumber) event:', e)
|
console.log('[ALIPAY] getAuthorize(phoneNumber) event:', e)
|
||||||
uni.showLoading({ title: t('common.processing') })
|
uni.showLoading({
|
||||||
|
title: t('common.processing')
|
||||||
|
})
|
||||||
const res = await getAlipayUserPhoneNumber()
|
const res = await getAlipayUserPhoneNumber()
|
||||||
const aliPhone = res?.data?.phoneNumber || res?.data?.phone || res?.phoneNumber || ''
|
const aliPhone = res?.data?.phoneNumber || res?.data?.phone || res?.phoneNumber || ''
|
||||||
if (!aliPhone) {
|
if (!aliPhone) {
|
||||||
@@ -1453,7 +1468,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 缓存本次校验结果(避免每次扫码都弹)
|
// 缓存本次校验结果(避免每次扫码都弹)
|
||||||
uni.setStorageSync('alipay_phone_verified', { phone: aliPhone, ts: Date.now() })
|
uni.setStorageSync('alipay_phone_verified', {
|
||||||
|
phone: aliPhone,
|
||||||
|
ts: Date.now()
|
||||||
|
})
|
||||||
|
|
||||||
showPhoneAuthPopup.value = false
|
showPhoneAuthPopup.value = false
|
||||||
if (pendingScan.value) {
|
if (pendingScan.value) {
|
||||||
@@ -1477,7 +1495,7 @@
|
|||||||
// 使用指南弹窗控制
|
// 使用指南弹窗控制
|
||||||
const openPopup = () => {
|
const openPopup = () => {
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url:'/subPackages/business/device-goods'
|
url: '/subPackages/business/device-goods'
|
||||||
})
|
})
|
||||||
// try {
|
// try {
|
||||||
// showGuidePopup.value = true
|
// showGuidePopup.value = true
|
||||||
|
|||||||
@@ -182,7 +182,9 @@
|
|||||||
if (opts && opts.redirect) {
|
if (opts && opts.redirect) {
|
||||||
try {
|
try {
|
||||||
redirect.value = decodeURIComponent(opts.redirect)
|
redirect.value = decodeURIComponent(opts.redirect)
|
||||||
} catch (_) {}
|
} catch (err) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// #ifdef H5
|
// #ifdef H5
|
||||||
isHTML5.value = true
|
isHTML5.value = true
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
<view class="my-page">
|
<view class="my-page">
|
||||||
<view class="user-card" @click="navigateTo('/subPackages/user/userProfile/index')">
|
<view class="user-card" @click="navigateTo('/subPackages/user/userProfile/index')">
|
||||||
<view class="avatar-box">
|
<view class="avatar-box">
|
||||||
<image class="avatar" v-if="userInfo.avatar" :src="userInfo.avatar" mode="aspectFill" lazy-load="true"></image>
|
<image class="avatar" v-if="userInfo.avatar" :src="userInfo.avatar" mode="aspectFill" lazy-load="true">
|
||||||
|
</image>
|
||||||
<image v-else class="avatar" src="@/static/head.png" mode="aspectFill" lazy-load="true"></image>
|
<image v-else class="avatar" src="@/static/head.png" mode="aspectFill" lazy-load="true"></image>
|
||||||
</view>
|
</view>
|
||||||
<view class="user-text">
|
<view class="user-text">
|
||||||
@@ -29,7 +30,8 @@
|
|||||||
<swiper class="banner-swiper" :indicator-dots="bannerImages.length > 1"
|
<swiper class="banner-swiper" :indicator-dots="bannerImages.length > 1"
|
||||||
:autoplay="bannerImages.length > 1" :circular="true" :interval="3000">
|
:autoplay="bannerImages.length > 1" :circular="true" :interval="3000">
|
||||||
<swiper-item v-for="(image, index) in bannerImages" :key="index">
|
<swiper-item v-for="(image, index) in bannerImages" :key="index">
|
||||||
<image class="banner-image" :src="image" mode="aspectFill" @click="handleBannerClick(index)" lazy-load="true">
|
<image class="banner-image" :src="image" mode="aspectFill" @click="handleBannerClick(index)"
|
||||||
|
lazy-load="true">
|
||||||
</image>
|
</image>
|
||||||
</swiper-item>
|
</swiper-item>
|
||||||
</swiper>
|
</swiper>
|
||||||
@@ -78,7 +80,8 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="list-item" @click="navigateTo('/subPackages/service/help/index')">
|
<view class="list-item" @click="navigateTo('/subPackages/service/help/index')">
|
||||||
<view class="left">
|
<view class="left">
|
||||||
<image class="icon" src="/static/customer-service.png" mode="aspectFit" lazy-load="true"></image>
|
<image class="icon" src="/static/customer-service.png" mode="aspectFit" lazy-load="true">
|
||||||
|
</image>
|
||||||
<text class="title">{{ $t('user.customerService') }}</text>
|
<text class="title">{{ $t('user.customerService') }}</text>
|
||||||
</view>
|
</view>
|
||||||
<uv-icon name="arrow-right" size="16" color="#c8c8c8"></uv-icon>
|
<uv-icon name="arrow-right" size="16" color="#c8c8c8"></uv-icon>
|
||||||
@@ -118,9 +121,11 @@
|
|||||||
|
|
||||||
<view class="footer-agreements">
|
<view class="footer-agreements">
|
||||||
<view class="link-box">
|
<view class="link-box">
|
||||||
<text class="link" @click="navigateTo('/subPackages/other/legal/agreement')">{{ $t('user.userAgreement') }}</text>
|
<text class="link"
|
||||||
|
@click="navigateTo('/subPackages/other/legal/agreement')">{{ $t('user.userAgreement') }}</text>
|
||||||
<text class="sep">|</text>
|
<text class="sep">|</text>
|
||||||
<text class="link" @click="navigateTo('/subPackages/other/legal/privacy')">{{ $t('user.privacyPolicy') }}</text>
|
<text class="link"
|
||||||
|
@click="navigateTo('/subPackages/other/legal/privacy')">{{ $t('user.privacyPolicy') }}</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="version">{{ $t('user.version') }}{{ appVersion }}</view>
|
<view class="version">{{ $t('user.version') }}{{ appVersion }}</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -199,7 +204,7 @@
|
|||||||
const res = await getCurrentAdvertisement({
|
const res = await getCurrentAdvertisement({
|
||||||
appPlatform: appPlatform, // 微信平台
|
appPlatform: appPlatform, // 微信平台
|
||||||
appType: 'user', // 用户端
|
appType: 'user', // 用户端
|
||||||
pictureLocation:'userProfile_banner'
|
pictureLocation: 'userProfile_banner'
|
||||||
})
|
})
|
||||||
|
|
||||||
if (res && res.code === 200 && res.data) {
|
if (res && res.code === 200 && res.data) {
|
||||||
@@ -267,7 +272,7 @@
|
|||||||
uni.setNavigationBarTitle({
|
uni.setNavigationBarTitle({
|
||||||
title: t('user.personalCenter')
|
title: t('user.personalCenter')
|
||||||
})
|
})
|
||||||
getInfo();
|
// getInfo();
|
||||||
initVersion();
|
initVersion();
|
||||||
getBannerImages(); // 加载广告
|
getBannerImages(); // 加载广告
|
||||||
});
|
});
|
||||||
@@ -340,11 +345,12 @@
|
|||||||
const query = current && current.options ? Object.keys(current.options).map(k =>
|
const query = current && current.options ? Object.keys(current.options).map(k =>
|
||||||
`${k}=${encodeURIComponent(current.options[k])}`).join('&') : ''
|
`${k}=${encodeURIComponent(current.options[k])}`).join('&') : ''
|
||||||
const redirect = encodeURIComponent(query ? `${route}?${query}` : route)
|
const redirect = encodeURIComponent(query ? `${route}?${query}` : route)
|
||||||
uni.reLaunch({
|
console.log(redirect);
|
||||||
url: `/subPackages/user/login/index?redirect=${redirect}`
|
uni.redirectTo({
|
||||||
|
url: redirect
|
||||||
})
|
})
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
uni.reLaunch({
|
uni.redirectTo({
|
||||||
url: '/subPackages/user/login/index'
|
url: '/subPackages/user/login/index'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
+223
-211
@@ -1,240 +1,252 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="container">
|
<view class="container">
|
||||||
<!-- 用户信息卡片 -->
|
<!-- 用户信息卡片 -->
|
||||||
<view class="user-card">
|
<view class="user-card">
|
||||||
<view class="avatar">
|
<view class="avatar">
|
||||||
<image :src="userInfo.avatar || '/static/images/default-avatar.png'" mode="aspectFill"></image>
|
<image :src="userInfo.avatar || '/static/images/default-avatar.png'" mode="aspectFill"></image>
|
||||||
</view>
|
</view>
|
||||||
<view class="user-info">
|
<view class="user-info">
|
||||||
<text class="nickname">{{ userInfo.nickName || $t('user.notLoggedIn') }}</text>
|
<text class="nickname">{{ userInfo.nickName || $t('user.notLoggedIn') }}</text>
|
||||||
<text class="phone">{{ userInfo.phone || $t('user.phoneNotBound') }}</text>
|
<text class="phone">{{ userInfo.phone || $t('user.phoneNotBound') }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 余额卡片 -->
|
<!-- 余额卡片 -->
|
||||||
<view class="balance-card">
|
<view class="balance-card">
|
||||||
<view class="balance-title">{{ $t('userProfile.balance') }}</view>
|
<view class="balance-title">{{ $t('userProfile.balance') }}</view>
|
||||||
<view class="balance-amount">¥{{ userInfo.balanceAmount || '0.00' }}</view>
|
<view class="balance-amount">¥{{ userInfo.balanceAmount || '0.00' }}</view>
|
||||||
<view class="balance-desc">{{ $t('user.balanceDesc') }}</view>
|
<view class="balance-desc">{{ $t('user.balanceDesc') }}</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 功能菜单 -->
|
<!-- 功能菜单 -->
|
||||||
<view class="menu-list">
|
<view class="menu-list">
|
||||||
<view class="menu-item" @click="navigateTo('/pages/order/index')">
|
<view class="menu-item" @click="navigateTo('/pages/order/index')">
|
||||||
<text class="menu-icon">📋</text>
|
<text class="menu-icon">📋</text>
|
||||||
<text class="menu-text">{{ $t('user.myOrders') }}</text>
|
<text class="menu-text">{{ $t('user.myOrders') }}</text>
|
||||||
<text class="menu-arrow">></text>
|
<text class="menu-arrow">></text>
|
||||||
</view>
|
</view>
|
||||||
<view class="menu-item" @click="navigateTo('/pages/feedback/index')">
|
<view class="menu-item" @click="navigateTo('/pages/feedback/index')">
|
||||||
<text class="menu-icon">💬</text>
|
<text class="menu-icon">💬</text>
|
||||||
<text class="menu-text">{{ $t('user.feedback') }}</text>
|
<text class="menu-text">{{ $t('user.feedback') }}</text>
|
||||||
<text class="menu-arrow">></text>
|
<text class="menu-arrow">></text>
|
||||||
</view>
|
</view>
|
||||||
<view class="menu-item" @click="navigateTo('/pages/help/index')">
|
<view class="menu-item" @click="navigateTo('/pages/help/index')">
|
||||||
<text class="menu-icon">ℹ️</text>
|
<text class="menu-icon">ℹ️</text>
|
||||||
<text class="menu-text">{{ $t('help.title') }}</text>
|
<text class="menu-text">{{ $t('help.title') }}</text>
|
||||||
<text class="menu-arrow">></text>
|
<text class="menu-arrow">></text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 退出登录按钮 -->
|
<!-- 退出登录按钮 -->
|
||||||
<view class="logout-btn" @click="handleLogout" v-if="isLogin">
|
<view class="logout-btn" @click="handleLogout" v-if="isLogin">
|
||||||
<text>{{ $t('user.logout') }}</text>
|
<text>{{ $t('user.logout') }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { getUserInfo } from '@/util/index.js'
|
import {
|
||||||
import { URL } from '@/config/url'
|
getUserInfo
|
||||||
|
} from '@/util/index.js'
|
||||||
|
import {
|
||||||
|
URL
|
||||||
|
} from '@/config/url'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
userInfo: {},
|
userInfo: {},
|
||||||
isLogin: false
|
isLogin: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onLoad() {
|
onLoad() {
|
||||||
// 设置页面标题
|
// 设置页面标题
|
||||||
uni.setNavigationBarTitle({
|
uni.setNavigationBarTitle({
|
||||||
title: this.$t('user.personalCenter')
|
title: this.$t('user.personalCenter')
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
onShow() {
|
onShow() {
|
||||||
this.loadUserInfo()
|
this.loadUserInfo()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async loadUserInfo() {
|
async loadUserInfo() {
|
||||||
try {
|
try {
|
||||||
const res = await getUserInfo()
|
const res = await getUserInfo()
|
||||||
if (res.code === 401 || res.code === 40101) {
|
if (res.code === 401 || res.code === 40101) {
|
||||||
// 无提示跳转至登录
|
// 无提示跳转至登录
|
||||||
try {
|
try {
|
||||||
const pages = getCurrentPages()
|
const pages = getCurrentPages()
|
||||||
const current = pages && pages.length ? pages[pages.length - 1] : null
|
const current = pages && pages.length ? pages[pages.length - 1] : null
|
||||||
const route = current && current.route ? ('/' + current.route) : '/pages/index/index'
|
const route = current && current.route ? ('/' + current.route) : '/pages/index/index'
|
||||||
const query = current && current.options ? Object.keys(current.options).map(k => `${k}=${encodeURIComponent(current.options[k])}`).join('&') : ''
|
const query = current && current.options ? Object.keys(current.options).map(k =>
|
||||||
const redirect = encodeURIComponent(query ? `${route}?${query}` : route)
|
`${k}=${encodeURIComponent(current.options[k])}`).join('&') : ''
|
||||||
uni.reLaunch({ url: `/subPackages/user/login/index?redirect=${redirect}` })
|
const redirect = encodeURIComponent(query ? `${route}?${query}` : route)
|
||||||
} catch (e) {
|
console.log(redirect);
|
||||||
uni.reLaunch({ url: '/subPackages/user/login/index' })
|
uni.reLaunch({
|
||||||
}
|
url: redirect
|
||||||
} else if (res.code === 200) {
|
})
|
||||||
this.userInfo = res.data
|
} catch (e) {
|
||||||
this.isLogin = true
|
uni.reLaunch({
|
||||||
} else {
|
url: '/subPackages/user/login/index'
|
||||||
this.isLogin = false
|
})
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} else if (res.code === 200) {
|
||||||
console.error('加载用户信息失败:', error)
|
this.userInfo = res.data
|
||||||
this.isLogin = false
|
this.isLogin = true
|
||||||
}
|
} else {
|
||||||
},
|
this.isLogin = false
|
||||||
navigateTo(url) {
|
}
|
||||||
uni.navigateTo({ url })
|
} catch (error) {
|
||||||
},
|
console.error('加载用户信息失败:', error)
|
||||||
handleLogout() {
|
this.isLogin = false
|
||||||
uni.showModal({
|
}
|
||||||
title: this.$t('common.tips'),
|
},
|
||||||
content: this.$t('user.confirmLogout'),
|
navigateTo(url) {
|
||||||
success: (res) => {
|
uni.navigateTo({
|
||||||
if (res.confirm) {
|
url
|
||||||
uni.removeStorageSync('token')
|
})
|
||||||
uni.removeStorageSync('userInfo')
|
},
|
||||||
this.isLogin = false
|
handleLogout() {
|
||||||
uni.showToast({
|
uni.showModal({
|
||||||
title: this.$t('user.logoutSuccess'),
|
title: this.$t('common.tips'),
|
||||||
icon: 'success'
|
content: this.$t('user.confirmLogout'),
|
||||||
})
|
success: (res) => {
|
||||||
setTimeout(() => {
|
if (res.confirm) {
|
||||||
uni.redirectTo({
|
uni.removeStorageSync('token')
|
||||||
url: '/subPackages/user/login/index'
|
uni.removeStorageSync('userInfo')
|
||||||
})
|
this.isLogin = false
|
||||||
}, 500)
|
uni.showToast({
|
||||||
}
|
title: this.$t('user.logoutSuccess'),
|
||||||
}
|
icon: 'success'
|
||||||
})
|
})
|
||||||
}
|
setTimeout(() => {
|
||||||
}
|
uni.redirectTo({
|
||||||
}
|
url: '/subPackages/user/login/index'
|
||||||
|
})
|
||||||
|
}, 500)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.container {
|
.container {
|
||||||
padding: 20rpx;
|
padding: 20rpx;
|
||||||
background-color: #f5f5f5;
|
background-color: #f5f5f5;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-card {
|
.user-card {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border-radius: 16rpx;
|
border-radius: 16rpx;
|
||||||
padding: 30rpx;
|
padding: 30rpx;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-bottom: 20rpx;
|
margin-bottom: 20rpx;
|
||||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar {
|
.avatar {
|
||||||
width: 120rpx;
|
width: 120rpx;
|
||||||
height: 120rpx;
|
height: 120rpx;
|
||||||
border-radius: 60rpx;
|
border-radius: 60rpx;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
margin-right: 30rpx;
|
margin-right: 30rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar image {
|
.avatar image {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-info {
|
.user-info {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nickname {
|
.nickname {
|
||||||
font-size: 32rpx;
|
font-size: 32rpx;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #333;
|
color: #333;
|
||||||
margin-bottom: 10rpx;
|
margin-bottom: 10rpx;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.phone {
|
.phone {
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
color: #666;
|
color: #666;
|
||||||
}
|
}
|
||||||
|
|
||||||
.balance-card {
|
.balance-card {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border-radius: 16rpx;
|
border-radius: 16rpx;
|
||||||
padding: 30rpx;
|
padding: 30rpx;
|
||||||
margin-bottom: 20rpx;
|
margin-bottom: 20rpx;
|
||||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.balance-title {
|
.balance-title {
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
color: #666;
|
color: #666;
|
||||||
margin-bottom: 20rpx;
|
margin-bottom: 20rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.balance-amount {
|
.balance-amount {
|
||||||
font-size: 48rpx;
|
font-size: 48rpx;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #333;
|
color: #333;
|
||||||
margin-bottom: 10rpx;
|
margin-bottom: 10rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.balance-desc {
|
.balance-desc {
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
color: #999;
|
color: #999;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-list {
|
.menu-list {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border-radius: 16rpx;
|
border-radius: 16rpx;
|
||||||
margin-bottom: 20rpx;
|
margin-bottom: 20rpx;
|
||||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-item {
|
.menu-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 30rpx;
|
padding: 30rpx;
|
||||||
border-bottom: 1rpx solid #f5f5f5;
|
border-bottom: 1rpx solid #f5f5f5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-item:last-child {
|
.menu-item:last-child {
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-icon {
|
.menu-icon {
|
||||||
font-size: 36rpx;
|
font-size: 36rpx;
|
||||||
margin-right: 20rpx;
|
margin-right: 20rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-text {
|
.menu-text {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
color: #333;
|
color: #333;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-arrow {
|
.menu-arrow {
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
color: #999;
|
color: #999;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logout-btn {
|
.logout-btn {
|
||||||
margin-top: 40rpx;
|
margin-top: 40rpx;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border-radius: 16rpx;
|
border-radius: 16rpx;
|
||||||
padding: 30rpx;
|
padding: 30rpx;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #ff4d4f;
|
color: #ff4d4f;
|
||||||
font-size: 28rpx;
|
font-size: 28rpx;
|
||||||
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -2,7 +2,8 @@
|
|||||||
<view class="profile-page">
|
<view class="profile-page">
|
||||||
<view class="avatar-section">
|
<view class="avatar-section">
|
||||||
<view class="avatar-container">
|
<view class="avatar-container">
|
||||||
<image class="avatar" v-if="userInfo.avatar" :src="userInfo.avatar" mode="aspectFill" lazy-load="true"></image>
|
<image class="avatar" v-if="userInfo.avatar" :src="userInfo.avatar" mode="aspectFill" lazy-load="true">
|
||||||
|
</image>
|
||||||
<image v-else class="avatar" src="@/static/head.png" mode="aspectFill" lazy-load="true"></image>
|
<image v-else class="avatar" src="@/static/head.png" mode="aspectFill" lazy-load="true"></image>
|
||||||
<!-- 覆盖在头像上的微信选择头像授权按钮,仅小程序生效 -->
|
<!-- 覆盖在头像上的微信选择头像授权按钮,仅小程序生效 -->
|
||||||
<!-- #ifdef MP-WEIXIN -->
|
<!-- #ifdef MP-WEIXIN -->
|
||||||
@@ -12,407 +13,416 @@
|
|||||||
<!-- <button class="avatar-choose-btn" open-type="chooseAvatar" @chooseavatar="onChooseAvatar"></button> -->
|
<!-- <button class="avatar-choose-btn" open-type="chooseAvatar" @chooseavatar="onChooseAvatar"></button> -->
|
||||||
<!-- #endif -->
|
<!-- #endif -->
|
||||||
</view>
|
</view>
|
||||||
<view class="avatar-tip">{{ $t('userProfile.clickToChange') }}</view>
|
<view class="avatar-tip">{{ $t('userProfile.clickToChange') }}</view>
|
||||||
</view>
|
|
||||||
|
|
||||||
<view class="form-section">
|
|
||||||
<!-- 昵称编辑区域 -->
|
|
||||||
<view class="form-item nickname-item" :class="{ editing: isEditingNickname }">
|
|
||||||
<view class="label">{{ $t('userProfile.nickname') }}</view>
|
|
||||||
<view class="value" v-if="!isEditingNickname" @click="startEditNickname">
|
|
||||||
<text class="value-text">{{ userInfo.nickName || $t('userProfile.notSet') }}</text>
|
|
||||||
<uv-icon name="edit-pen" size="16" color="#999999"></uv-icon>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 昵称编辑输入框(展开状态) -->
|
<view class="form-section">
|
||||||
<view class="nickname-edit-area" v-if="isEditingNickname">
|
<!-- 昵称编辑区域 -->
|
||||||
<input
|
<view class="form-item nickname-item" :class="{ editing: isEditingNickname }">
|
||||||
class="nickname-input"
|
<view class="label">{{ $t('userProfile.nickname') }}</view>
|
||||||
v-model="newNickname"
|
<view class="value" v-if="!isEditingNickname" @click="startEditNickname">
|
||||||
:placeholder="$t('userProfile.enterNickname')"
|
<text class="value-text">{{ userInfo.nickName || $t('userProfile.notSet') }}</text>
|
||||||
maxlength="20"
|
<uv-icon name="edit-pen" size="16" color="#999999"></uv-icon>
|
||||||
:focus="true"
|
</view>
|
||||||
/>
|
|
||||||
<view class="edit-buttons">
|
|
||||||
<button class="cancel-btn" @click="cancelEditNickname">{{ $t('common.cancel') }}</button>
|
|
||||||
<button class="save-btn" @click="saveNickname">{{ $t('common.save') }}</button>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
|
||||||
|
|
||||||
<view class="form-item">
|
<!-- 昵称编辑输入框(展开状态) -->
|
||||||
<view class="label">{{ $t('userProfile.phone') }}</view>
|
<view class="nickname-edit-area" v-if="isEditingNickname">
|
||||||
<view class="value">
|
<input class="nickname-input" v-model="newNickname" :placeholder="$t('userProfile.enterNickname')"
|
||||||
<text class="value-text">{{ userInfo.phone ? maskPhone(userInfo.phone) : $t('userProfile.notBound') }}</text>
|
maxlength="20" :focus="true" />
|
||||||
|
<view class="edit-buttons">
|
||||||
|
<button class="cancel-btn" @click="cancelEditNickname">{{ $t('common.cancel') }}</button>
|
||||||
|
<button class="save-btn" @click="saveNickname">{{ $t('common.save') }}</button>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- <view class="form-item" v-if="userInfo.balanceAmount !== undefined">
|
<view class="form-item">
|
||||||
|
<view class="label">{{ $t('userProfile.phone') }}</view>
|
||||||
|
<view class="value">
|
||||||
|
<text
|
||||||
|
class="value-text">{{ userInfo.phone ? maskPhone(userInfo.phone) : $t('userProfile.notBound') }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- <view class="form-item" v-if="userInfo.balanceAmount !== undefined">
|
||||||
<view class="label">{{ $t('userProfile.balance') }}</view>
|
<view class="label">{{ $t('userProfile.balance') }}</view>
|
||||||
<view class="value">
|
<view class="value">
|
||||||
<text class="value-text amount">¥{{ userInfo.balanceAmount || '0.00' }}</text>
|
<text class="value-text amount">¥{{ userInfo.balanceAmount || '0.00' }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view> -->
|
</view> -->
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive, onMounted } from 'vue';
|
import {
|
||||||
import { getMyIndexInfo, uploadUserAvatar, updateUserInfo } from '@/config/api/user.js';
|
ref,
|
||||||
import { useI18n } from '@/utils/i18n.js'
|
reactive,
|
||||||
|
onMounted
|
||||||
|
} from 'vue';
|
||||||
|
import {
|
||||||
|
getMyIndexInfo,
|
||||||
|
uploadUserAvatar,
|
||||||
|
updateUserInfo
|
||||||
|
} from '@/config/api/user.js';
|
||||||
|
import {
|
||||||
|
useI18n
|
||||||
|
} from '@/utils/i18n.js'
|
||||||
|
|
||||||
const { t } = useI18n()
|
const {
|
||||||
|
t
|
||||||
|
} = useI18n()
|
||||||
|
|
||||||
// 响应式状态
|
// 响应式状态
|
||||||
const userInfo = ref({
|
const userInfo = ref({
|
||||||
nickName: '',
|
nickName: '',
|
||||||
phone: '',
|
phone: '',
|
||||||
avatar: '',
|
avatar: '',
|
||||||
balanceAmount: '0.00'
|
balanceAmount: '0.00'
|
||||||
});
|
});
|
||||||
|
|
||||||
const newNickname = ref('');
|
const newNickname = ref('');
|
||||||
const isEditingNickname = ref(false);
|
const isEditingNickname = ref(false);
|
||||||
|
|
||||||
// 页面加载时初始化
|
// 页面加载时初始化
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
uni.setNavigationBarTitle({
|
uni.setNavigationBarTitle({
|
||||||
title: t('userProfile.title')
|
title: t('userProfile.title')
|
||||||
})
|
})
|
||||||
loadUserInfo();
|
loadUserInfo();
|
||||||
});
|
});
|
||||||
|
|
||||||
// 获取用户信息
|
// 获取用户信息
|
||||||
const loadUserInfo = async () => {
|
const loadUserInfo = async () => {
|
||||||
try {
|
try {
|
||||||
const res = await getMyIndexInfo();
|
const res = await getMyIndexInfo();
|
||||||
console.log('User info response:', res);
|
console.log('User info response:', res);
|
||||||
|
|
||||||
if (res.code == 401 || res.code == 40101) {
|
if (res.code == 401 || res.code == 40101) {
|
||||||
redirectToLogin();
|
redirectToLogin();
|
||||||
return;
|
return;
|
||||||
} else if (res.code == 200) {
|
} else if (res.code == 200) {
|
||||||
userInfo.value = {
|
userInfo.value = {
|
||||||
nickName: res.data.nickname,
|
nickName: res.data.nickname,
|
||||||
phone: res.data.phone,
|
phone: res.data.phone,
|
||||||
avatar: res.data.iconUrl,
|
avatar: res.data.iconUrl,
|
||||||
balanceAmount: res.data.balanceAmount || '0.00',
|
balanceAmount: res.data.balanceAmount || '0.00',
|
||||||
isAdmin: res.data.isAdmin
|
isAdmin: res.data.isAdmin
|
||||||
};
|
};
|
||||||
uni.setStorageSync('userInfo', userInfo.value);
|
uni.setStorageSync('userInfo', userInfo.value);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取用户信息失败:', error);
|
console.error('获取用户信息失败:', error);
|
||||||
uni.showToast({
|
|
||||||
title: t('user.getUserInfoFailed'),
|
|
||||||
icon: 'none'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 跳转登录
|
|
||||||
const redirectToLogin = () => {
|
|
||||||
try {
|
|
||||||
const pages = getCurrentPages();
|
|
||||||
const current = pages && pages.length ? pages[pages.length - 1] : null;
|
|
||||||
const route = current && current.route ? ('/' + current.route) : '/pages/index/index';
|
|
||||||
const query = current && current.options ? Object.keys(current.options).map(k =>
|
|
||||||
`${k}=${encodeURIComponent(current.options[k])}`).join('&') : '';
|
|
||||||
const redirect = encodeURIComponent(query ? `${route}?${query}` : route);
|
|
||||||
uni.reLaunch({
|
|
||||||
url: `/subPackages/user/login/index?redirect=${redirect}`
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
uni.reLaunch({
|
|
||||||
url: '/subPackages/user/login/index'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 小程序原生选择头像回调
|
|
||||||
const onChooseAvatar = async (e) => {
|
|
||||||
console.log(e.detail.avatarUrl,'获取头像详情');
|
|
||||||
|
|
||||||
try {
|
|
||||||
const token = uni.getStorageSync('token');
|
|
||||||
if (!token) {
|
|
||||||
redirectToLogin();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const avatarLocalPath = e?.detail?.avatarUrl;
|
|
||||||
if (!avatarLocalPath) {
|
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: t('user.noAvatar'),
|
title: t('user.getUserInfoFailed'),
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 跳转登录
|
||||||
|
const redirectToLogin = () => {
|
||||||
|
try {
|
||||||
|
const pages = getCurrentPages();
|
||||||
|
const current = pages && pages.length ? pages[pages.length - 1] : null;
|
||||||
|
const route = current && current.route ? ('/' + current.route) : '/pages/index/index';
|
||||||
|
const query = current && current.options ? Object.keys(current.options).map(k =>
|
||||||
|
`${k}=${encodeURIComponent(current.options[k])}`).join('&') : '';
|
||||||
|
const redirect = encodeURIComponent(query ? `${route}?${query}` : route);
|
||||||
|
uni.reLaunch({
|
||||||
|
url: redirect
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
uni.reLaunch({
|
||||||
|
url: '/subPackages/user/login/index'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 小程序原生选择头像回调
|
||||||
|
const onChooseAvatar = async (e) => {
|
||||||
|
console.log(e.detail.avatarUrl, '获取头像详情');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const token = uni.getStorageSync('token');
|
||||||
|
if (!token) {
|
||||||
|
redirectToLogin();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const avatarLocalPath = e?.detail?.avatarUrl;
|
||||||
|
if (!avatarLocalPath) {
|
||||||
|
uni.showToast({
|
||||||
|
title: t('user.noAvatar'),
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uni.showLoading({
|
||||||
|
title: t('userProfile.uploading'),
|
||||||
|
mask: true
|
||||||
|
});
|
||||||
|
const uploadRes = await uploadUserAvatar(avatarLocalPath);
|
||||||
|
const serverAvatar = uploadRes?.data?.url || uploadRes?.url || uploadRes?.data || '';
|
||||||
|
if (serverAvatar) {
|
||||||
|
userInfo.value = {
|
||||||
|
...userInfo.value,
|
||||||
|
avatar: serverAvatar
|
||||||
|
};
|
||||||
|
uni.setStorageSync('userInfo', userInfo.value);
|
||||||
|
}
|
||||||
|
uni.showToast({
|
||||||
|
title: t('user.avatarUpdated'),
|
||||||
|
icon: 'success'
|
||||||
|
});
|
||||||
|
await loadUserInfo();
|
||||||
|
} catch (err) {
|
||||||
|
console.error('选择/上传头像失败:', err);
|
||||||
|
uni.showToast({
|
||||||
|
title: t('user.avatarUploadFailed'),
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
uni.hideLoading();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 开始编辑昵称
|
||||||
|
const startEditNickname = () => {
|
||||||
|
newNickname.value = userInfo.value.nickName || '';
|
||||||
|
isEditingNickname.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 取消编辑昵称
|
||||||
|
const cancelEditNickname = () => {
|
||||||
|
isEditingNickname.value = false;
|
||||||
|
newNickname.value = '';
|
||||||
|
};
|
||||||
|
|
||||||
|
// 保存昵称
|
||||||
|
const saveNickname = async () => {
|
||||||
|
if (!newNickname.value || !newNickname.value.trim()) {
|
||||||
|
uni.showToast({
|
||||||
|
title: t('userProfile.nicknameRequired'),
|
||||||
icon: 'none'
|
icon: 'none'
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uni.showLoading({
|
|
||||||
title: t('userProfile.uploading'),
|
try {
|
||||||
mask: true
|
uni.showLoading({
|
||||||
});
|
title: t('userProfile.saving'),
|
||||||
const uploadRes = await uploadUserAvatar(avatarLocalPath);
|
mask: true
|
||||||
const serverAvatar = uploadRes?.data?.url || uploadRes?.url || uploadRes?.data || '';
|
});
|
||||||
if (serverAvatar) {
|
|
||||||
userInfo.value = {
|
// 先获取最新的用户信息,确保数据是最新的
|
||||||
...userInfo.value,
|
const latestUserInfo = await getMyIndexInfo();
|
||||||
avatar: serverAvatar
|
|
||||||
|
if (latestUserInfo.code !== 200) {
|
||||||
|
throw new Error('获取用户信息失败');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用最新的服务器数据,只修改昵称字段
|
||||||
|
const updateData = {
|
||||||
|
nickname: newNickname.value.trim(),
|
||||||
|
phone: latestUserInfo.data.phone,
|
||||||
|
iconUrl: latestUserInfo.data.iconUrl,
|
||||||
|
// 保留其他可能的字段
|
||||||
|
...latestUserInfo.data
|
||||||
};
|
};
|
||||||
uni.setStorageSync('userInfo', userInfo.value);
|
|
||||||
}
|
|
||||||
uni.showToast({
|
|
||||||
title: t('user.avatarUpdated'),
|
|
||||||
icon: 'success'
|
|
||||||
});
|
|
||||||
await loadUserInfo();
|
|
||||||
} catch (err) {
|
|
||||||
console.error('选择/上传头像失败:', err);
|
|
||||||
uni.showToast({
|
|
||||||
title: t('user.avatarUploadFailed'),
|
|
||||||
icon: 'none'
|
|
||||||
});
|
|
||||||
} finally {
|
|
||||||
uni.hideLoading();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 开始编辑昵称
|
// 确保昵称使用新值
|
||||||
const startEditNickname = () => {
|
updateData.nickname = newNickname.value.trim();
|
||||||
newNickname.value = userInfo.value.nickName || '';
|
|
||||||
isEditingNickname.value = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 取消编辑昵称
|
// 调用后端接口更新用户信息
|
||||||
const cancelEditNickname = () => {
|
const res = await updateUserInfo(updateData);
|
||||||
isEditingNickname.value = false;
|
|
||||||
newNickname.value = '';
|
|
||||||
};
|
|
||||||
|
|
||||||
// 保存昵称
|
if (res.code === 200) {
|
||||||
const saveNickname = async () => {
|
// 更新成功后重新获取用户信息,确保数据同步
|
||||||
if (!newNickname.value || !newNickname.value.trim()) {
|
await loadUserInfo();
|
||||||
uni.showToast({
|
|
||||||
title: t('userProfile.nicknameRequired'),
|
|
||||||
icon: 'none'
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
uni.hideLoading();
|
||||||
uni.showLoading({
|
uni.showToast({
|
||||||
title: t('userProfile.saving'),
|
title: t('userProfile.nicknameUpdated'),
|
||||||
mask: true
|
icon: 'success'
|
||||||
});
|
});
|
||||||
|
isEditingNickname.value = false;
|
||||||
// 先获取最新的用户信息,确保数据是最新的
|
} else {
|
||||||
const latestUserInfo = await getMyIndexInfo();
|
throw new Error(res.message || t('userProfile.updateFailed'));
|
||||||
|
}
|
||||||
if (latestUserInfo.code !== 200) {
|
|
||||||
throw new Error('获取用户信息失败');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 使用最新的服务器数据,只修改昵称字段
|
|
||||||
const updateData = {
|
|
||||||
nickname: newNickname.value.trim(),
|
|
||||||
phone: latestUserInfo.data.phone,
|
|
||||||
iconUrl: latestUserInfo.data.iconUrl,
|
|
||||||
// 保留其他可能的字段
|
|
||||||
...latestUserInfo.data
|
|
||||||
};
|
|
||||||
|
|
||||||
// 确保昵称使用新值
|
|
||||||
updateData.nickname = newNickname.value.trim();
|
|
||||||
|
|
||||||
// 调用后端接口更新用户信息
|
|
||||||
const res = await updateUserInfo(updateData);
|
|
||||||
|
|
||||||
if (res.code === 200) {
|
|
||||||
// 更新成功后重新获取用户信息,确保数据同步
|
|
||||||
await loadUserInfo();
|
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('修改昵称失败:', error);
|
||||||
uni.hideLoading();
|
uni.hideLoading();
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: t('userProfile.nicknameUpdated'),
|
title: error.message || t('userProfile.updateFailed'),
|
||||||
icon: 'success'
|
icon: 'none'
|
||||||
});
|
});
|
||||||
isEditingNickname.value = false;
|
|
||||||
} else {
|
|
||||||
throw new Error(res.message || t('userProfile.updateFailed'));
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} catch (error) {
|
// 手机号掩码函数
|
||||||
console.error('修改昵称失败:', error);
|
function maskPhone(phone) {
|
||||||
uni.hideLoading();
|
if (!phone) return '';
|
||||||
uni.showToast({
|
return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
|
||||||
title: error.message || t('userProfile.updateFailed'),
|
|
||||||
icon: 'none'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
// 手机号掩码函数
|
|
||||||
function maskPhone(phone) {
|
|
||||||
if (!phone) return '';
|
|
||||||
return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.profile-page {
|
.profile-page {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
background-color: #f5f5f5;
|
background-color: #f5f5f5;
|
||||||
padding-bottom: env(safe-area-inset-bottom);
|
padding-bottom: env(safe-area-inset-bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar-section {
|
.avatar-section {
|
||||||
background: linear-gradient(180deg, #D1FFE1 0%, #ffffff 100%);
|
background: linear-gradient(180deg, #D1FFE1 0%, #ffffff 100%);
|
||||||
padding: 60rpx 0 40rpx;
|
padding: 60rpx 0 40rpx;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar-container {
|
.avatar-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
margin-bottom: 20rpx;
|
margin-bottom: 20rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar {
|
.avatar {
|
||||||
width: 160rpx;
|
width: 160rpx;
|
||||||
height: 160rpx;
|
height: 160rpx;
|
||||||
border-radius: 80rpx;
|
border-radius: 80rpx;
|
||||||
background-color: #f0f0f0;
|
background-color: #f0f0f0;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 仅小程序端存在,此按钮覆盖在头像上捕获点击以触发选择头像 */
|
/* 仅小程序端存在,此按钮覆盖在头像上捕获点击以触发选择头像 */
|
||||||
/* #ifdef MP-WEIXIN || MP-ALIPAY */
|
/* #ifdef MP-WEIXIN || MP-ALIPAY */
|
||||||
.avatar-choose-btn {
|
.avatar-choose-btn {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
width: 160rpx;
|
width: 160rpx;
|
||||||
height: 160rpx;
|
height: 160rpx;
|
||||||
border: none;
|
border: none;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
opacity: 0;
|
|
||||||
border-radius: 80rpx;
|
|
||||||
}
|
|
||||||
/* #endif */
|
|
||||||
|
|
||||||
.avatar-tip {
|
|
||||||
font-size: 24rpx;
|
|
||||||
color: #999999;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-section {
|
|
||||||
margin: 20rpx 30rpx;
|
|
||||||
background-color: #ffffff;
|
|
||||||
border-radius: 20rpx;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-item {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 32rpx 30rpx;
|
|
||||||
border-bottom: 1rpx solid #f5f5f5;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-item:last-child {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.form-item.nickname-item.editing {
|
|
||||||
border-bottom: none;
|
|
||||||
padding-bottom: 20rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.label {
|
|
||||||
font-size: 30rpx;
|
|
||||||
color: #333333;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.value {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.value-text {
|
|
||||||
font-size: 28rpx;
|
|
||||||
color: #666666;
|
|
||||||
margin-right: 10rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.value-text.amount {
|
|
||||||
color: #e2231a;
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 32rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 昵称编辑区域样式 */
|
|
||||||
.nickname-edit-area {
|
|
||||||
padding: 0 30rpx 30rpx 30rpx;
|
|
||||||
border-bottom: 1rpx solid #f5f5f5;
|
|
||||||
animation: slideDown 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes slideDown {
|
|
||||||
from {
|
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translateY(-20rpx);
|
border-radius: 80rpx;
|
||||||
}
|
}
|
||||||
to {
|
|
||||||
opacity: 1;
|
/* #endif */
|
||||||
transform: translateY(0);
|
|
||||||
|
.avatar-tip {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999999;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.nickname-input {
|
.form-section {
|
||||||
width: 100%;
|
margin: 20rpx 30rpx;
|
||||||
height: 80rpx;
|
background-color: #ffffff;
|
||||||
border: 1rpx solid #e0e0e0;
|
border-radius: 20rpx;
|
||||||
border-radius: 10rpx;
|
overflow: hidden;
|
||||||
padding: 0 20rpx;
|
}
|
||||||
font-size: 28rpx;
|
|
||||||
color: #333333;
|
|
||||||
box-sizing: border-box;
|
|
||||||
margin-bottom: 20rpx;
|
|
||||||
background-color: #fafafa;
|
|
||||||
}
|
|
||||||
|
|
||||||
.edit-buttons {
|
.form-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
align-items: center;
|
||||||
gap: 20rpx;
|
justify-content: space-between;
|
||||||
}
|
padding: 32rpx 30rpx;
|
||||||
|
border-bottom: 1rpx solid #f5f5f5;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
.cancel-btn,
|
.form-item:last-child {
|
||||||
.save-btn {
|
border-bottom: none;
|
||||||
padding: 0 40rpx;
|
}
|
||||||
height: 64rpx;
|
|
||||||
line-height: 64rpx;
|
|
||||||
text-align: center;
|
|
||||||
border-radius: 32rpx;
|
|
||||||
font-size: 28rpx;
|
|
||||||
border: none;
|
|
||||||
min-width: 120rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cancel-btn {
|
.form-item.nickname-item.editing {
|
||||||
background-color: #f5f5f5;
|
border-bottom: none;
|
||||||
color: #666666;
|
padding-bottom: 20rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.save-btn {
|
.label {
|
||||||
background: linear-gradient(135deg, #42d392 0%, #28c76f 100%);
|
font-size: 30rpx;
|
||||||
color: #ffffff;
|
color: #333333;
|
||||||
}
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666666;
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value-text.amount {
|
||||||
|
color: #e2231a;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 昵称编辑区域样式 */
|
||||||
|
.nickname-edit-area {
|
||||||
|
padding: 0 30rpx 30rpx 30rpx;
|
||||||
|
border-bottom: 1rpx solid #f5f5f5;
|
||||||
|
animation: slideDown 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideDown {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(-20rpx);
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nickname-input {
|
||||||
|
width: 100%;
|
||||||
|
height: 80rpx;
|
||||||
|
border: 1rpx solid #e0e0e0;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
padding: 0 20rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333333;
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
background-color: #fafafa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit-buttons {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cancel-btn,
|
||||||
|
.save-btn {
|
||||||
|
padding: 0 40rpx;
|
||||||
|
height: 64rpx;
|
||||||
|
line-height: 64rpx;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 32rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
border: none;
|
||||||
|
min-width: 120rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cancel-btn {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.save-btn {
|
||||||
|
background: linear-gradient(135deg, #42d392 0%, #28c76f 100%);
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
<template>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {
|
||||||
|
onLoad
|
||||||
|
} from '@dcloudio/uni-app'
|
||||||
|
import { onMounted } from 'vue';
|
||||||
|
|
||||||
|
onLoad((options) => {
|
||||||
|
let deviceNo;
|
||||||
|
if (options) {
|
||||||
|
deviceNo = options.deviceNo;
|
||||||
|
uni.reLaunch({
|
||||||
|
url: `/pages/device/detail?deviceNo=${deviceNo}`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// onMounted((options)=>{
|
||||||
|
// let deviceNo;
|
||||||
|
// if (options) {
|
||||||
|
// deviceNo = options.deviceNo;
|
||||||
|
// uni.reLaunch({
|
||||||
|
// url: `/pages/device/detail?deviceNo=${deviceNo}`
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user