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
|
}), 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'])
|
@app.route('/api/auth/login/email', methods=['POST'])
|
||||||
def api_login_email():
|
def api_login_email():
|
||||||
"""邮箱登录接口"""
|
"""邮箱登录接口"""
|
||||||
|
|||||||
Reference in New Issue
Block a user