parent
1ff66b868e
commit
f2d8e2ed27
@ -1,41 +1,42 @@
|
||||
// API配置
|
||||
export const BASE_URL = 'https://xukoushuniu.115.langye.net'
|
||||
|
||||
// 判断环境(你可以用 process.env.NODE_ENV 或自定义变量)
|
||||
const IS_PROD = process.env.NODE_ENV === 'production';
|
||||
|
||||
// API接口地址
|
||||
export const API = {
|
||||
WECHAT_JSSDK_CONFIG: `${BASE_URL}/api/customer/wechat/jssdk-config`,
|
||||
LOGIN: `${BASE_URL}/api/customer/login-by-code`,
|
||||
WX_LOGIN: `${BASE_URL}/api/customer/login-by-wechat-code`,
|
||||
STATISTICS: `${BASE_URL}/api/customer/reservation/statistics`,
|
||||
LOGIN_ACCOUNT: `${BASE_URL}/api/customer/login`,
|
||||
GET_USER_INFO: `${BASE_URL}/api/customer/me`,
|
||||
UPDATE_USER_INFO: `${BASE_URL}/api/customer/profile/update`,
|
||||
UPLOAD_FILE:`${BASE_URL}/api/customer/upload-file`,
|
||||
SHIP_CREATE: `${BASE_URL}/api/customer/ship/create`,
|
||||
SHIP_INDEX: `${BASE_URL}/api/customer/ship/index`,
|
||||
SHIP_DETAIL: `${BASE_URL}/api/customer/ship/get-one`,
|
||||
SHIP_PROPERTY_ENUM: `${BASE_URL}/api/customer/ship/get-property-enum`,
|
||||
SHIP_DELETE: `${BASE_URL}/api/customer/ship/delete`,
|
||||
RESERVATION_STATUS_ENUM: `${BASE_URL}/api/customer/reservation/get-status-enum`,
|
||||
RESERVATION_CREATE: `${BASE_URL}/api/customer/reservation/create`,
|
||||
RESERVATION_LIST: `${BASE_URL}/api/customer/reservation/index`,
|
||||
AVAILABLE_SHIP: `${BASE_URL}/api/customer/reservation/get-available-ship`,
|
||||
// GET_PAYMENT_QRCODE: IS_PROD
|
||||
// ? `${BASE_URL}/api/customer/reservation/get-payment-qrcode`
|
||||
// : `${BASE_URL}/api/customer/reservation/get-fake-payment-qrcode`,
|
||||
GET_PAYMENT_QRCODE: `${BASE_URL}/api/customer/reservation/fake-pay`,
|
||||
FAKE_PAY: `${BASE_URL}/api/customer/reservation/fake-pay`,
|
||||
NOTIFICATION_LIST: `${BASE_URL}/api/customer/notifications/index`,
|
||||
CANCEL_RESERVATION: `${BASE_URL}/api/customer/reservation/cancel`,
|
||||
GET_DIRECTION_ENUM: `${BASE_URL}/api/customer/reservation/get-direction-enum`,
|
||||
SHIP_UPDATE: `${BASE_URL}/api/customer/ship/update`,
|
||||
GET_INVOICE: `${BASE_URL}/api/customer/reservation/get-invoice`,
|
||||
GET_DAILY_RESERVATION_DEADLINE: `${BASE_URL}/api/customer/setting/get-daily-reservation-deadline`,
|
||||
GET_GEOFENCE_BY_DIRECTION: `${BASE_URL}/api/customer/geofence/get-by-direction`,
|
||||
GET_WATER_LEVEL: `${BASE_URL}/api/customer/setting/get-water-level`,
|
||||
GET_UNIT_PRICE: `${BASE_URL}/api/customer/setting/get-unit-price`,
|
||||
GET_SHIP_INSPECTION_EXAMPLES: `${BASE_URL}/api/customer/setting/get-ship-inspection-examples`,
|
||||
// API配置
|
||||
export const BASE_URL = 'https://xukoushuniu.115.langye.net'
|
||||
|
||||
// 判断环境(你可以用 process.env.NODE_ENV 或自定义变量)
|
||||
const IS_PROD = process.env.NODE_ENV === 'production';
|
||||
|
||||
// API接口地址
|
||||
export const API = {
|
||||
WECHAT_JSSDK_CONFIG: `${BASE_URL}/api/customer/wechat/jssdk-config`,
|
||||
LOGIN: `${BASE_URL}/api/customer/login-by-code`,
|
||||
WX_LOGIN: `${BASE_URL}/api/customer/login-by-wechat-code`,
|
||||
STATISTICS: `${BASE_URL}/api/customer/reservation/statistics`,
|
||||
LOGIN_ACCOUNT: `${BASE_URL}/api/customer/login`,
|
||||
GET_USER_INFO: `${BASE_URL}/api/customer/me`,
|
||||
UPDATE_USER_INFO: `${BASE_URL}/api/customer/profile/update`,
|
||||
UPLOAD_FILE:`${BASE_URL}/api/customer/upload-file`,
|
||||
SHIP_CREATE: `${BASE_URL}/api/customer/ship/create`,
|
||||
SHIP_INDEX: `${BASE_URL}/api/customer/ship/index`,
|
||||
SHIP_DETAIL: `${BASE_URL}/api/customer/ship/get-one`,
|
||||
SHIP_PROPERTY_ENUM: `${BASE_URL}/api/customer/ship/get-property-enum`,
|
||||
SHIP_DELETE: `${BASE_URL}/api/customer/ship/delete`,
|
||||
RESERVATION_STATUS_ENUM: `${BASE_URL}/api/customer/reservation/get-status-enum`,
|
||||
RESERVATION_CREATE: `${BASE_URL}/api/customer/reservation/create`,
|
||||
RESERVATION_LIST: `${BASE_URL}/api/customer/reservation/index`,
|
||||
AVAILABLE_SHIP: `${BASE_URL}/api/customer/reservation/get-available-ship`,
|
||||
// GET_PAYMENT_QRCODE: IS_PROD
|
||||
// ? `${BASE_URL}/api/customer/reservation/get-payment-qrcode`
|
||||
// : `${BASE_URL}/api/customer/reservation/get-fake-payment-qrcode`,
|
||||
GET_PAYMENT_QRCODE: `${BASE_URL}/api/customer/reservation/fake-pay`,
|
||||
FAKE_PAY: `${BASE_URL}/api/customer/reservation/fake-pay`,
|
||||
NOTIFICATION_LIST: `${BASE_URL}/api/customer/notifications/index`,
|
||||
CANCEL_RESERVATION: `${BASE_URL}/api/customer/reservation/cancel`,
|
||||
GET_DIRECTION_ENUM: `${BASE_URL}/api/customer/reservation/get-direction-enum`,
|
||||
SHIP_UPDATE: `${BASE_URL}/api/customer/ship/update`,
|
||||
GET_INVOICE: `${BASE_URL}/api/customer/reservation/get-invoice`,
|
||||
GET_DAILY_RESERVATION_DEADLINE: `${BASE_URL}/api/customer/setting/get-daily-reservation-deadline`,
|
||||
GET_GEOFENCE_BY_DIRECTION: `${BASE_URL}/api/customer/geofence/get-by-direction`,
|
||||
GET_WATER_LEVEL: `${BASE_URL}/api/customer/setting/get-water-level`,
|
||||
GET_UNIT_PRICE: `${BASE_URL}/api/customer/setting/get-unit-price`,
|
||||
GET_SHIP_INSPECTION_EXAMPLES: `${BASE_URL}/api/customer/setting/get-ship-inspection-examples`,
|
||||
PROFILE_SEND_PHONE_CODE: `${BASE_URL}/api/customer/profile/send-phone-code`,
|
||||
}
|
||||
@ -0,0 +1,305 @@
|
||||
<template>
|
||||
<view class="verify-page">
|
||||
<view class="fixed-nav" v-if="!isWeixinBrowser">
|
||||
<NavBar title="验证备用手机号" />
|
||||
</view>
|
||||
<view class="content-area">
|
||||
<view class="form-card">
|
||||
<view class="form-title">备用手机号验证</view>
|
||||
<view class="form-field">
|
||||
<text class="form-label">备用手机号</text>
|
||||
<input
|
||||
class="form-input"
|
||||
v-model="form.backup_phone"
|
||||
type="number"
|
||||
maxlength="11"
|
||||
placeholder="请输入备用手机号"
|
||||
/>
|
||||
</view>
|
||||
<view class="form-field">
|
||||
<text class="form-label">验证码</text>
|
||||
<view class="verify-code-row">
|
||||
<input
|
||||
class="form-input verify-code-input"
|
||||
v-model="form.backup_phone_code"
|
||||
type="number"
|
||||
maxlength="6"
|
||||
placeholder="请输入验证码"
|
||||
/>
|
||||
<button
|
||||
class="send-code-btn"
|
||||
:disabled="!canSendCode || countdown > 0"
|
||||
@click="sendSmsCode"
|
||||
>
|
||||
{{ countdown > 0 ? countdown + '秒后重发' : '获取验证码' }}
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="submit-btn-wrapper">
|
||||
<button class="submit-btn" @click="submitVerify">提交验证</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import NavBar from '@/components/NavBar.vue'
|
||||
import { API } from '@/config/index.js'
|
||||
|
||||
export default {
|
||||
name: 'VerifyBackupPhonePage',
|
||||
components: { NavBar },
|
||||
data() {
|
||||
return {
|
||||
isWeixinBrowser: false,
|
||||
form: {
|
||||
backup_phone: '',
|
||||
backup_phone_code: ''
|
||||
},
|
||||
canSendCode: true,
|
||||
countdown: 0,
|
||||
countdownTimer: null
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
// #ifdef H5
|
||||
this.isWeixinBrowser = /MicroMessenger/i.test(navigator.userAgent)
|
||||
// #endif
|
||||
},
|
||||
onUnload() {
|
||||
// 清理倒计时定时器
|
||||
if (this.countdownTimer) {
|
||||
clearInterval(this.countdownTimer)
|
||||
this.countdownTimer = null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 发送短信验证码
|
||||
async sendSmsCode() {
|
||||
// 验证手机号
|
||||
const phoneReg = /^1\d{10}$/
|
||||
if (!phoneReg.test(this.form.backup_phone)) {
|
||||
uni.showToast({ title: '请输入正确的手机号', icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (!this.canSendCode || this.countdown > 0) {
|
||||
return
|
||||
}
|
||||
const token = uni.getStorageSync('token')
|
||||
if (!token) {
|
||||
uni.showToast({ title: '请先登录', icon: 'none' })
|
||||
return
|
||||
}
|
||||
try {
|
||||
uni.showLoading({ title: '发送中...' })
|
||||
const res = await new Promise((resolve, reject) => {
|
||||
uni.request({
|
||||
url: `${API.PROFILE_SEND_PHONE_CODE}?token=${token}`,
|
||||
method: 'POST',
|
||||
data: {
|
||||
phone: this.form.backup_phone,
|
||||
type: 'backup_phone'
|
||||
},
|
||||
success: resolve,
|
||||
fail: reject
|
||||
})
|
||||
})
|
||||
uni.hideLoading()
|
||||
if (res.data && res.data.errcode === 0) {
|
||||
uni.showToast({ title: '验证码已发送', icon: 'success' })
|
||||
// 开始倒计时
|
||||
this.canSendCode = false
|
||||
this.countdown = 60
|
||||
this.countdownTimer = setInterval(() => {
|
||||
this.countdown--
|
||||
if (this.countdown <= 0) {
|
||||
clearInterval(this.countdownTimer)
|
||||
this.countdownTimer = null
|
||||
this.canSendCode = true
|
||||
}
|
||||
}, 1000)
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: (res.data && res.data.errmsg) || '发送失败',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
uni.hideLoading()
|
||||
uni.showToast({ title: '发送失败', icon: 'none' })
|
||||
}
|
||||
},
|
||||
// 提交验证
|
||||
async submitVerify() {
|
||||
// 验证表单
|
||||
const phoneReg = /^1\d{10}$/
|
||||
if (!phoneReg.test(this.form.backup_phone)) {
|
||||
uni.showToast({ title: '请输入正确的手机号', icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (!this.form.backup_phone_code || this.form.backup_phone_code.length !== 6) {
|
||||
uni.showToast({ title: '请输入6位验证码', icon: 'none' })
|
||||
return
|
||||
}
|
||||
const token = uni.getStorageSync('token')
|
||||
if (!token) {
|
||||
uni.showToast({ title: '请先登录', icon: 'none' })
|
||||
return
|
||||
}
|
||||
try {
|
||||
uni.showLoading({ title: '验证中...' })
|
||||
const res = await new Promise((resolve, reject) => {
|
||||
uni.request({
|
||||
url: `${API.UPDATE_USER_INFO}?token=${token}`,
|
||||
method: 'POST',
|
||||
data: {
|
||||
backup_phone: this.form.backup_phone,
|
||||
backup_phone_code: this.form.backup_phone_code
|
||||
},
|
||||
success: resolve,
|
||||
fail: reject
|
||||
})
|
||||
})
|
||||
uni.hideLoading()
|
||||
if (res.data && res.data.errcode === 0) {
|
||||
uni.showToast({ title: '验证成功', icon: 'success' })
|
||||
setTimeout(() => {
|
||||
uni.navigateBack()
|
||||
}, 1500)
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: (res.data && res.data.errmsg) || '验证失败',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
uni.hideLoading()
|
||||
uni.showToast({ title: '验证失败', icon: 'none' })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.verify-page {
|
||||
background: linear-gradient(180deg, #cbe6ff 0%, #f6faff 100%);
|
||||
min-height: 100vh;
|
||||
padding-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.wechat-browser {
|
||||
padding-top: 10rpx;
|
||||
}
|
||||
|
||||
.fixed-nav {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 100;
|
||||
background: linear-gradient(180deg, #cbe6ff 0%, #f6faff 100%);
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.04);
|
||||
}
|
||||
|
||||
.content-area {
|
||||
padding-top: 90px;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.form-card {
|
||||
background: #fff;
|
||||
border-radius: 24rpx;
|
||||
margin: 0 24rpx 32rpx 24rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(59,124,255,0.08);
|
||||
padding: 32rpx 24rpx;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.form-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #222;
|
||||
margin-bottom: 32rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.form-field {
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.form-field:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
display: block;
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.form-input {
|
||||
width: 100%;
|
||||
height: 80rpx;
|
||||
border-radius: 12rpx;
|
||||
border: 1rpx solid #e5e6eb;
|
||||
padding: 0 24rpx;
|
||||
font-size: 28rpx;
|
||||
box-sizing: border-box;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.verify-code-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.verify-code-input {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.send-code-btn {
|
||||
min-width: 180rpx;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
border-radius: 12rpx;
|
||||
background: #3b7cff;
|
||||
color: #fff;
|
||||
font-size: 24rpx;
|
||||
border: none;
|
||||
padding: 0 24rpx;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.send-code-btn::after {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.send-code-btn:disabled {
|
||||
background: #ccc;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.submit-btn-wrapper {
|
||||
padding: 0 24rpx;
|
||||
}
|
||||
|
||||
.submit-btn {
|
||||
width: 100%;
|
||||
height: 88rpx;
|
||||
line-height: 88rpx;
|
||||
border-radius: 44rpx;
|
||||
background: linear-gradient(90deg, #3b7cff 0%, #5bb6ff 100%);
|
||||
color: #fff;
|
||||
font-size: 32rpx;
|
||||
font-weight: 500;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.submit-btn::after {
|
||||
border: none;
|
||||
}
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue