This commit is contained in:
@@ -45,11 +45,13 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="function-name">资产套餐历史</view>
|
<view class="function-name">资产套餐历史</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="function-item interactive card-interactive" @tap="$emit('enter', 'bind')" role="button" tabindex="0">
|
<view class="function-item interactive card-interactive" @tap="handleBindPhone" role="button" tabindex="0">
|
||||||
<view class="function-icon">
|
<view class="function-icon">
|
||||||
<image src="/static/bind-phone.png" mode="aspectFit" alt="绑定手机号"></image>
|
<image src="/static/bind-phone.png" mode="aspectFit" alt="绑定手机号"></image>
|
||||||
</view>
|
</view>
|
||||||
<view class="function-name">绑定手机号</view>
|
<view :class="['function-name', alreadyBindPhone ? 'text-primary' : '']">
|
||||||
|
{{ alreadyBindPhone ? '已绑定' : '绑定手机号' }}
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="function-item interactive card-interactive" v-if="isDevice" @tap="$emit('enter', 'change-phone')" role="button" tabindex="0">
|
<view class="function-item interactive card-interactive" v-if="isDevice" @tap="$emit('enter', 'change-phone')" role="button" tabindex="0">
|
||||||
<view class="function-icon">
|
<view class="function-icon">
|
||||||
@@ -94,13 +96,22 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
defineProps({
|
const props = defineProps({
|
||||||
realNameStatus: { type: String, default: '' },
|
realNameStatus: { type: String, default: '' },
|
||||||
alreadyBindPhone: { type: Boolean, default: false },
|
alreadyBindPhone: { type: Boolean, default: false },
|
||||||
isDevice: { type: Boolean, default: true }
|
isDevice: { type: Boolean, default: true }
|
||||||
});
|
});
|
||||||
|
|
||||||
defineEmits(['enter', 'sync']);
|
const emit = defineEmits(['enter', 'sync']);
|
||||||
|
|
||||||
|
const handleBindPhone = () => {
|
||||||
|
if (props.alreadyBindPhone) {
|
||||||
|
// 已绑定,不可点击
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 未绑定,可以点击进入绑定页面
|
||||||
|
emit('enter', 'bind');
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@@ -135,18 +135,11 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 监听 identifier 变化
|
// 监听 identifier 变化
|
||||||
watch(() => props.identifier, (newVal) => {
|
watch(() => props.identifier || userStore.state.identifier, (newVal) => {
|
||||||
if (newVal) {
|
if (newVal) {
|
||||||
loadPackageData();
|
loadPackageData();
|
||||||
}
|
}
|
||||||
}, { immediate: true });
|
}, { immediate: true });
|
||||||
|
|
||||||
// 如果没有传入 identifier,则使用 store 中的
|
|
||||||
watch(() => userStore.state.identifier, (newVal) => {
|
|
||||||
if (newVal && !props.identifier) {
|
|
||||||
loadPackageData();
|
|
||||||
}
|
|
||||||
}, { immediate: true });
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="user-details flex-col-g8">
|
<view class="user-details flex-col-g8">
|
||||||
<view class="flex-row-g20">
|
<view class="flex-row-g20">
|
||||||
<view class="title">{{ currentCardNo }}</view>
|
<view class="title">{{ currentCardNo || '-' }}</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="caption">IMEI:{{ deviceInfo.imei || '-' }}</view>
|
<view class="caption">IMEI:{{ deviceInfo.imei || '-' }}</view>
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
@@ -47,7 +47,8 @@
|
|||||||
{
|
{
|
||||||
"path": "pages/bind/bind",
|
"path": "pages/bind/bind",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "绑定手机号"
|
"navigationBarTitleText": "绑定手机号",
|
||||||
|
"navigationStyle": "custom"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="container">
|
<view class="page">
|
||||||
|
<!-- 自定义导航栏 -->
|
||||||
|
<view v-if="!fromLogin" class="custom-navbar">
|
||||||
|
<view class="navbar-back" @tap="goBack">
|
||||||
|
<text class="back-icon">←</text>
|
||||||
|
<text class="back-text">返回</text>
|
||||||
|
</view>
|
||||||
|
<view class="navbar-title">绑定手机号</view>
|
||||||
|
<view class="navbar-placeholder"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="container" :style="{ paddingTop: fromLogin ? '0' : '0' }">
|
||||||
<view class="card flex-col-g20">
|
<view class="card flex-col-g20">
|
||||||
<view class="flex-row-g20">
|
<view class="flex-row-g20">
|
||||||
<label for="">手机号:</label>
|
<label for="">手机号:</label>
|
||||||
@@ -18,12 +29,18 @@
|
|||||||
<view class="btn">
|
<view class="btn">
|
||||||
<up-button type="primary" @tap="bindPhone">绑定手机号</up-button>
|
<up-button type="primary" @tap="bindPhone">绑定手机号</up-button>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<!-- 如果从登录页面跳转过来,显示退出按钮 -->
|
||||||
|
<view class="btn" v-if="fromLogin">
|
||||||
|
<up-button type="error" @tap="logout">退出</up-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive } from 'vue';
|
import { ref, reactive, onMounted } from 'vue';
|
||||||
import { authApi } from '@/api/index.js';
|
import { authApi } from '@/api/index.js';
|
||||||
|
|
||||||
let bind = reactive({
|
let bind = reactive({
|
||||||
@@ -34,6 +51,15 @@
|
|||||||
let cooldown = ref(0);
|
let cooldown = ref(0);
|
||||||
let codeText = ref('获取验证码');
|
let codeText = ref('获取验证码');
|
||||||
let timer = null;
|
let timer = null;
|
||||||
|
let fromLogin = ref(false);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 获取页面参数,判断是否从登录页面跳转过来
|
||||||
|
const pages = getCurrentPages();
|
||||||
|
const currentPage = pages[pages.length - 1];
|
||||||
|
const options = currentPage.options;
|
||||||
|
fromLogin.value = options.fromLogin === 'true';
|
||||||
|
});
|
||||||
|
|
||||||
const getCode = async () => {
|
const getCode = async () => {
|
||||||
if (!bind.phone) {
|
if (!bind.phone) {
|
||||||
@@ -77,13 +103,88 @@ let timer = null;
|
|||||||
await authApi.bindPhone(bind.phone, bind.code);
|
await authApi.bindPhone(bind.phone, bind.code);
|
||||||
uni.showToast({ title: '绑定成功', icon: 'success' });
|
uni.showToast({ title: '绑定成功', icon: 'success' });
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
if (fromLogin.value) {
|
||||||
|
// 从登录页面过来的,绑定成功后跳转到首页
|
||||||
|
uni.redirectTo({ url: '/pages/index/index' });
|
||||||
|
} else {
|
||||||
|
// 从其他页面过来的,返回上一页
|
||||||
uni.navigateBack();
|
uni.navigateBack();
|
||||||
|
}
|
||||||
}, 1500);
|
}, 1500);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('绑定手机号失败', e);
|
console.error('绑定手机号失败', e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const logout = () => {
|
||||||
|
uni.showModal({
|
||||||
|
title: '提示',
|
||||||
|
content: '确定要退出登录吗?',
|
||||||
|
success: (res) => {
|
||||||
|
if (res.confirm) {
|
||||||
|
uni.clearStorageSync();
|
||||||
|
uni.reLaunch({ url: '/pages/login/login' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const goBack = () => {
|
||||||
|
uni.navigateBack();
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style lang="scss" scoped>
|
||||||
|
.page {
|
||||||
|
min-height: 100vh;
|
||||||
|
background: var(--bg-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-navbar {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
height: 88rpx;
|
||||||
|
background: var(--bg-primary);
|
||||||
|
border-bottom: 1rpx solid var(--border-light);
|
||||||
|
padding: 0 24rpx;
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 100;
|
||||||
|
|
||||||
|
.navbar-back {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8rpx;
|
||||||
|
padding: 8rpx;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
.back-icon {
|
||||||
|
font-size: 36rpx;
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-title {
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--text-primary);
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-placeholder {
|
||||||
|
width: 100rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
padding: var(--space-md);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -125,6 +125,14 @@
|
|||||||
uni.showToast({ title: '请输入收件人电话', icon: 'none' });
|
uni.showToast({ title: '请输入收件人电话', icon: 'none' });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 手机号格式校验
|
||||||
|
const phoneReg = /^1[3-9]\d{9}$/;
|
||||||
|
if (!phoneReg.test(form.recipient_phone)) {
|
||||||
|
uni.showToast({ title: '请输入正确的手机号', icon: 'none' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!form.recipient_address) {
|
if (!form.recipient_address) {
|
||||||
uni.showToast({ title: '请输入收货地址', icon: 'none' });
|
uni.showToast({ title: '请输入收货地址', icon: 'none' });
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -320,15 +320,85 @@
|
|||||||
showModifyWifi.value = false;
|
showModifyWifi.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const connectKF = () => uni.showToast({
|
const connectKF = () => {
|
||||||
title: '正在跳转客服',
|
const kfUrl = 'https://work.weixin.qq.com/kfid/kfc0fd79f27686fb65e?enc_scene=ENCfR9AVui6UfvvxySGVuvaG&scene_param=commonlink';
|
||||||
icon: 'none'
|
|
||||||
});
|
|
||||||
|
|
||||||
const enterBack = () => uni.showToast({
|
// #ifdef H5
|
||||||
title: '正在跳转后台',
|
window.location.href = kfUrl;
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
// 微信小程序跳转到企业微信客服
|
||||||
|
wx.openCustomerServiceChat({
|
||||||
|
extInfo: { url: kfUrl },
|
||||||
|
corpId: 'ww4e3b7f9f7c8a9b0c',
|
||||||
|
success: () => {
|
||||||
|
console.log('打开客服会话成功');
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
console.error('打开客服会话失败', err);
|
||||||
|
// 失败时使用网页跳转
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `/pages/webview/webview?url=${encodeURIComponent(kfUrl)}`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifndef H5 || MP-WEIXIN
|
||||||
|
// 其他平台,复制链接
|
||||||
|
uni.showModal({
|
||||||
|
title: '联系客服',
|
||||||
|
content: '是否复制客服链接?',
|
||||||
|
confirmText: '复制',
|
||||||
|
success: (res) => {
|
||||||
|
if (res.confirm) {
|
||||||
|
uni.setClipboardData({
|
||||||
|
data: kfUrl,
|
||||||
|
success: () => {
|
||||||
|
uni.showToast({ title: '客服链接已复制', icon: 'success' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// #endif
|
||||||
|
};
|
||||||
|
|
||||||
|
const enterBack = () => {
|
||||||
|
if (!deviceInfo.lan_ip || deviceInfo.lan_ip === '-') {
|
||||||
|
uni.showToast({
|
||||||
|
title: '暂无后台地址',
|
||||||
icon: 'none'
|
icon: 'none'
|
||||||
});
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 跳转到设备后台管理地址
|
||||||
|
const url = deviceInfo.lan_ip.startsWith('http') ? deviceInfo.lan_ip : `http://${deviceInfo.lan_ip}`;
|
||||||
|
|
||||||
|
// #ifdef H5
|
||||||
|
window.location.href = url;
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifndef H5
|
||||||
|
uni.showModal({
|
||||||
|
title: '后台地址',
|
||||||
|
content: url,
|
||||||
|
confirmText: '复制',
|
||||||
|
success: (res) => {
|
||||||
|
if (res.confirm) {
|
||||||
|
uni.setClipboardData({
|
||||||
|
data: url,
|
||||||
|
success: () => {
|
||||||
|
uni.showToast({ title: '地址已复制', icon: 'success' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// #endif
|
||||||
|
};
|
||||||
|
|
||||||
const YesRestart = async () => {
|
const YesRestart = async () => {
|
||||||
try {
|
try {
|
||||||
@@ -496,11 +566,62 @@
|
|||||||
showSmsCode.value = false;
|
showSmsCode.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSync = () => {
|
const onSync = async () => {
|
||||||
|
const identifier = userStore.state.identifier;
|
||||||
|
if (!identifier) {
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '同步成功',
|
title: '请先登录',
|
||||||
icon: 'success'
|
icon: 'none'
|
||||||
});
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uni.showLoading({
|
||||||
|
title: '同步中...',
|
||||||
|
mask: true
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
const data = await assetApi.refresh(identifier);
|
||||||
|
|
||||||
|
uni.hideLoading();
|
||||||
|
|
||||||
|
if (data.accepted) {
|
||||||
|
const refreshTypeText = data.refresh_type === 'device' ? '设备' : '卡';
|
||||||
|
uni.showToast({
|
||||||
|
title: `${refreshTypeText}数据同步成功`,
|
||||||
|
icon: 'success',
|
||||||
|
duration: 2000
|
||||||
|
});
|
||||||
|
|
||||||
|
// 同步成功后,延迟重新加载资产信息
|
||||||
|
setTimeout(() => {
|
||||||
|
loadAssetInfo();
|
||||||
|
}, 2000);
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: '同步失败,请稍后重试',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
uni.hideLoading();
|
||||||
|
console.error('同步数据失败', e);
|
||||||
|
|
||||||
|
// 如果是冷却时间错误,显示提示
|
||||||
|
if (e.msg && e.msg.includes('冷却')) {
|
||||||
|
uni.showToast({
|
||||||
|
title: e.msg,
|
||||||
|
icon: 'none',
|
||||||
|
duration: 2000
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: '同步失败',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const enterDetail = (name) => {
|
const enterDetail = (name) => {
|
||||||
|
|||||||
@@ -98,7 +98,13 @@
|
|||||||
const loginData = await authApi.wechatLogin(verifyData.asset_token, 'mock_code');
|
const loginData = await authApi.wechatLogin(verifyData.asset_token, 'mock_code');
|
||||||
userStore.setToken(loginData.token);
|
userStore.setToken(loginData.token);
|
||||||
uni.setStorageSync('identifier', userStore.state.identifier);
|
uni.setStorageSync('identifier', userStore.state.identifier);
|
||||||
|
|
||||||
|
// 判断是否需要绑定手机号
|
||||||
|
if (loginData.need_bind_phone) {
|
||||||
|
uni.redirectTo({ url: '/pages/bind/bind?fromLogin=true' });
|
||||||
|
} else {
|
||||||
uni.redirectTo({ url: '/pages/index/index' });
|
uni.redirectTo({ url: '/pages/index/index' });
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,9 +129,16 @@
|
|||||||
try {
|
try {
|
||||||
const loginData = await authApi.wechatLogin(assetToken, code);
|
const loginData = await authApi.wechatLogin(assetToken, code);
|
||||||
userStore.setToken(loginData.token);
|
userStore.setToken(loginData.token);
|
||||||
|
|
||||||
uni.setStorageSync('identifier', userStore.state.identifier);
|
uni.setStorageSync('identifier', userStore.state.identifier);
|
||||||
|
|
||||||
|
// 判断是否需要绑定手机号
|
||||||
|
if (loginData.need_bind_phone) {
|
||||||
|
// 需要绑定手机号,跳转到绑定页面
|
||||||
|
uni.redirectTo({ url: '/pages/bind/bind?fromLogin=true' });
|
||||||
|
} else {
|
||||||
|
// 不需要绑定,直接进入首页
|
||||||
uni.redirectTo({ url: '/pages/index/index' });
|
uni.redirectTo({ url: '/pages/index/index' });
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('微信登录失败', e);
|
console.error('微信登录失败', e);
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user