update pay ui
This commit is contained in:
178
app_vx.py
178
app_vx.py
@@ -4044,6 +4044,184 @@ def api_login_wechat():
|
||||
}), 500
|
||||
|
||||
|
||||
# ============================================
|
||||
# 微信获取手机号接口
|
||||
# ============================================
|
||||
# 缓存微信 access_token
|
||||
_wechat_access_token_cache = {
|
||||
'token': None,
|
||||
'expires_at': 0
|
||||
}
|
||||
|
||||
|
||||
def get_wechat_access_token():
|
||||
"""
|
||||
获取微信小程序 access_token(带缓存)
|
||||
access_token 有效期为 7200 秒,提前 5 分钟刷新
|
||||
"""
|
||||
import time
|
||||
global _wechat_access_token_cache
|
||||
|
||||
current_time = time.time()
|
||||
|
||||
# 如果缓存有效(提前5分钟刷新)
|
||||
if (_wechat_access_token_cache['token'] and
|
||||
_wechat_access_token_cache['expires_at'] > current_time + 300):
|
||||
return _wechat_access_token_cache['token']
|
||||
|
||||
# 请求新的 access_token
|
||||
url = 'https://api.weixin.qq.com/cgi-bin/token'
|
||||
params = {
|
||||
'grant_type': 'client_credential',
|
||||
'appid': WECHAT_APP_ID,
|
||||
'secret': WECHAT_APP_SECRET
|
||||
}
|
||||
|
||||
try:
|
||||
response = requests.get(url, params=params, timeout=10)
|
||||
result = response.json()
|
||||
|
||||
if 'access_token' in result:
|
||||
_wechat_access_token_cache['token'] = result['access_token']
|
||||
_wechat_access_token_cache['expires_at'] = current_time + result.get('expires_in', 7200)
|
||||
logger.info(f"获取微信 access_token 成功,有效期: {result.get('expires_in', 7200)}秒")
|
||||
return result['access_token']
|
||||
else:
|
||||
logger.error(f"获取微信 access_token 失败: {result}")
|
||||
return None
|
||||
except Exception as e:
|
||||
logger.error(f"获取微信 access_token 异常: {e}")
|
||||
return None
|
||||
|
||||
|
||||
@app.route('/api/auth/bindphone/wechat', methods=['POST'])
|
||||
@token_required
|
||||
def api_bindphone_wechat():
|
||||
"""
|
||||
微信小程序绑定手机号接口
|
||||
|
||||
前端调用 wx.getPhoneNumber 获取 code,传给后端
|
||||
后端用 code 调用微信接口获取手机号,绑定到当前用户
|
||||
|
||||
请求参数:
|
||||
{
|
||||
"code": "微信返回的动态令牌code"
|
||||
}
|
||||
|
||||
返回:
|
||||
{
|
||||
"code": 200,
|
||||
"message": "success",
|
||||
"data": {
|
||||
"phone": "138xxxx1234",
|
||||
"bindcd": true
|
||||
}
|
||||
}
|
||||
"""
|
||||
try:
|
||||
user = request.user
|
||||
data = request.get_json()
|
||||
code = data.get('code') if data else None
|
||||
|
||||
if not code:
|
||||
return jsonify({
|
||||
'code': 400,
|
||||
'message': '缺少必要的参数 code',
|
||||
'data': None
|
||||
}), 400
|
||||
|
||||
# 1. 获取 access_token
|
||||
access_token = get_wechat_access_token()
|
||||
if not access_token:
|
||||
return jsonify({
|
||||
'code': 500,
|
||||
'message': '获取微信凭证失败,请稍后重试',
|
||||
'data': None
|
||||
}), 500
|
||||
|
||||
# 2. 调用微信接口获取手机号
|
||||
wx_phone_url = f'https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token={access_token}'
|
||||
payload = {'code': code}
|
||||
|
||||
try:
|
||||
response = requests.post(wx_phone_url, json=payload, timeout=10)
|
||||
result = response.json()
|
||||
logger.info(f"微信获取手机号响应: {result}")
|
||||
except Exception as e:
|
||||
logger.error(f"调用微信获取手机号接口异常: {e}")
|
||||
return jsonify({
|
||||
'code': 500,
|
||||
'message': '调用微信接口失败,请稍后重试',
|
||||
'data': None
|
||||
}), 500
|
||||
|
||||
# 3. 解析微信返回结果
|
||||
if result.get('errcode') != 0:
|
||||
error_msg = result.get('errmsg', '未知错误')
|
||||
logger.error(f"微信获取手机号失败: errcode={result.get('errcode')}, errmsg={error_msg}")
|
||||
|
||||
# 常见错误码处理
|
||||
errcode = result.get('errcode')
|
||||
if errcode == 40029:
|
||||
return jsonify({'code': 400, 'message': 'code无效或已过期,请重新获取', 'data': None}), 400
|
||||
elif errcode == 40013:
|
||||
return jsonify({'code': 400, 'message': 'AppID无效', 'data': None}), 400
|
||||
elif errcode == -1:
|
||||
return jsonify({'code': 500, 'message': '微信服务繁忙,请稍后重试', 'data': None}), 500
|
||||
else:
|
||||
return jsonify({'code': 400, 'message': f'获取手机号失败: {error_msg}', 'data': None}), 400
|
||||
|
||||
phone_info = result.get('phone_info', {})
|
||||
phone_number = phone_info.get('phoneNumber') or phone_info.get('purePhoneNumber')
|
||||
|
||||
if not phone_number:
|
||||
return jsonify({
|
||||
'code': 400,
|
||||
'message': '未获取到手机号',
|
||||
'data': None
|
||||
}), 400
|
||||
|
||||
# 4. 检查手机号是否已被其他用户绑定
|
||||
existing_user = User.query.filter(
|
||||
User.phone == phone_number,
|
||||
User.phone_confirmed == True,
|
||||
User.id != user.id
|
||||
).first()
|
||||
|
||||
if existing_user:
|
||||
return jsonify({
|
||||
'code': 400,
|
||||
'message': '该手机号已被其他账号绑定',
|
||||
'data': None
|
||||
}), 400
|
||||
|
||||
# 5. 更新用户手机号
|
||||
user.phone = phone_number
|
||||
user.phone_confirmed = True
|
||||
user.phone_confirm_time = beijing_now()
|
||||
db.session.commit()
|
||||
|
||||
logger.info(f"用户 {user.id} 成功绑定手机号: {phone_number[:3]}****{phone_number[-4:]}")
|
||||
|
||||
return jsonify({
|
||||
'code': 200,
|
||||
'message': '绑定成功',
|
||||
'data': {
|
||||
'phone': phone_number,
|
||||
'bindcd': True
|
||||
}
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"绑定手机号异常: {e}", exc_info=True)
|
||||
db.session.rollback()
|
||||
return jsonify({
|
||||
'code': 500,
|
||||
'message': '服务器内部错误',
|
||||
'data': None
|
||||
}), 500
|
||||
|
||||
|
||||
@app.route('/api/auth/login/email', methods=['POST'])
|
||||
def api_login_email():
|
||||
"""邮箱登录接口"""
|
||||
|
||||
Reference in New Issue
Block a user