blob: f3d6abaacda5037ae05d0d1cb3ab3d1a5e7a4ee0 [file] [log] [blame]
from flask import Flask, jsonify, request, current_app
from flask_cors import CORS
import traceback
import hashlib
import requests
from bs4 import BeautifulSoup, MarkupResemblesLocatorWarning
import warnings
import config
import pymysql.cursors # 确保导入了 pymysql 的 cursors
from pyngrok import ngrok
from flask import Flask, request, jsonify
from flask_cors import CORS
from smtplib import SMTP_SSL
from email.mime.text import MIMEText
import random, datetime
import bcrypt
import mysql.connector
app = Flask(__name__)
CORS(app, supports_credentials=True) # 支持 cookies(可选)
# 商户ID和密钥
merchant_id = 4058
merchant_key = '2c9e609b503698c6f1dba301725ec631'
base_url = 'https://api.ltrhcj.cn/api/paySubmit' # 请求网关
def generate_md5_signature(*args):
"""根据传入的参数生成MD5签名"""
sign_str = ''.join(args)
return hashlib.md5(sign_str.encode('utf-8')).hexdigest()
@app.route('/paySuccess', methods=['POST', 'GET'])
def pay_success():
data = request.form if request.method == 'POST' else request.args
orderid = data.get('orderid')
state = data.get('state')
amount = data.get('amount')
payment = data.get('payment')
rate = data.get('rate')
sign = data.get('sign')
if not orderid or not state or not amount or not payment or not sign:
return "Missing parameter", 400
try:
print("Received paySuccess notification:")
print(f"orderid: {orderid}")
print(f"state: {state}")
print(f"amount: {amount}")
print(f"payment: {payment}")
print(f"rate: {rate}")
print(f"sign: {sign}")
# 获取数据库连接
connection = config.get_db_connection()
cursor = connection.cursor(pymysql.cursors.DictCursor)
# 查询该订单对应的邮箱和密码
cursor.execute("SELECT user_name, password FROM `order` WHERE orderid = %s", (orderid,))
result = cursor.fetchone()
print("result内容:", result)
if result:
email = result["user_name"]
raw_password = result["password"]
# 查询 sys_user 是否已存在该 email
cursor.execute("SELECT user_id FROM sys_user WHERE email = %s", (email,))
user_exists = cursor.fetchone()
if not user_exists:
# 加密密码(如果已经加密过,可以略过这一步)
cursor.execute("""
INSERT INTO sys_user (
user_name, nick_name, password, email, create_time, del_flag, status, user_type
) VALUES (%s, %s, %s, %s, NOW(), '0', '0', '00')
""", (email, email, raw_password, email))
else:
cursor.execute("UPDATE sys_user SET status = '0' WHERE email = %s", (email,))
# 更新订单状态为已支付
cursor.execute("UPDATE `order` SET state = %s WHERE orderid = %s", ('已支付', orderid))
connection.commit()
cursor.close()
connection.close()
return "success", 200
except Exception as e:
import traceback
current_app.logger.error(f'发生异常: {e}')
traceback.print_exc()
return "Internal server error", 500
@app.route('/user/createOrder', methods=['POST'])
def create_order():
data = request.json
print(data)
orderid = data.get('orderid')
paytype = data.get('paytype')
money = data.get('money')
notifyUrl = data.get('notifyUrl', '')
returnUrl = data.get('returnUrl', '')
returnmsg = 2
user_name = data.get('user_name')
password = data.get('password') # 👈 获取前端传来的加密密码
print(data)
if not orderid or not paytype or not money or not user_name:
return jsonify({'success': False, 'message': '缺少必传参数'}), 400
try:
sign = generate_md5_signature(str(merchant_id), orderid, str(paytype), str(money), merchant_key)
payload = {
'appid': merchant_id,
'orderid': orderid,
'paytype': paytype,
'money': money,
'sign': sign,
'notifyUrl': notifyUrl,
'returnUrl': returnUrl,
'returnmsg': returnmsg
}
# 发送POST请求到外部 API
response = requests.post(base_url, data=payload)
current_app.logger.debug(f'请求URL: {base_url}')
current_app.logger.debug(f'请求数据: {payload}')
if response.status_code == 200:
# 将订单信息插入到数据库的 order 表中
connection = config.get_db_connection()
cursor = connection.cursor()
cursor.execute(
"INSERT INTO `order` (orderid, user_name, password, time, amount, state) VALUES (%s, %s, %s, NOW(), %s, %s)",
(orderid, user_name, password, money, 'pending')
)
connection.commit()
cursor.close()
connection.close()
return response.text, 200
else:
return jsonify({'success': False, 'message': f"外部 API 错误: {response.text}"}), response.status_code
except Exception as e:
current_app.logger.error(f'发生异常: {e}')
traceback.print_exc()
return jsonify({'success': False, 'message': f"Error: {e}"}), 530
# 邮箱配置
SMTP_SERVER = 'smtp.qq.com'
EMAIL_ADDRESS = '3534185780@qq.com'
EMAIL_AUTH_CODE = 'slcsbwtrwitbcjic'
# 数据库配置
DB_CONFIG = {
'host': '49.233.215.144',
'port': 3306,
'user': 'sy',
'password': 'sy_password',
'database': 'pt_station'
}
# === 发送验证码接口 ===
@app.route('/send-code', methods=['POST'])
def send_code():
data = request.get_json()
to_email = data.get('email')
if not to_email:
return jsonify({"success": False, "message": "缺少邮箱"}), 400
code = str(random.randint(100000, 999999))
msg = MIMEText(f"欢迎注册PTStation,您的验证码是:{code}(有效期5分钟)")
msg['Subject'] = '您的验证码'
msg['From'] = EMAIL_ADDRESS
msg['To'] = to_email
try:
# 发送邮件
with SMTP_SSL(SMTP_SERVER, 465) as smtp:
smtp.login(EMAIL_ADDRESS, EMAIL_AUTH_CODE)
smtp.send_message(msg)
smtp.quit()
# 存入数据库
conn = mysql.connector.connect(**DB_CONFIG)
cursor = conn.cursor()
sql = "INSERT INTO email_verification (email, code, created_at) VALUES (%s, %s, NOW())"
cursor.execute(sql, (to_email, code))
conn.commit()
cursor.close()
conn.close()
return jsonify({"success": True})
except Exception as e:
print("发送失败:", e)
return jsonify({"success": False, "message": f"邮件发送失败:{e}"}), 500
# === 注册接口 ===
@app.route('/register', methods=['POST'])
def register():
data = request.get_json()
email = data.get('email')
password = data.get('password') # 可以保留做哈希后传给支付回调存库
code = data.get('code')
if not all([email, password, code]):
return jsonify({"success": False, "message": "缺少参数"}), 400
try:
conn = mysql.connector.connect(**DB_CONFIG)
cursor = conn.cursor(dictionary=True)
# 1. 验证验证码是否有效(5分钟内)
cursor.execute("""
SELECT * FROM email_verification
WHERE email = %s AND code = %s AND created_at > NOW() - INTERVAL 5 MINUTE
ORDER BY created_at DESC LIMIT 1
""", (email, code))
result = cursor.fetchone()
if not result:
return jsonify({"success": False, "message": "验证码无效或已过期"}), 400
# 2. 检查邮箱是否已注册
cursor.execute("SELECT user_id FROM sys_user WHERE email = %s", (email,))
if cursor.fetchone():
return jsonify({"success": False, "message": "该邮箱已注册"}), 400
# ⚠️ 不再插入数据库,只返回验证通过
return jsonify({"success": True, "message": "验证通过"})
except Exception as e:
print("注册失败:", e)
return jsonify({"success": False, "message": f"注册失败:{e}"}), 500
finally:
cursor.close()
conn.close()
@app.route('/reset-password', methods=['POST'])
def reset_password():
data = request.get_json()
email = data.get('email')
code = data.get('code')
new_password = data.get('newPassword')
if not all([email, code, new_password]):
return jsonify({"success": False, "message": "参数缺失"}), 400
try:
conn = mysql.connector.connect(**DB_CONFIG)
cursor = conn.cursor()
# 验证验证码是否正确且在有效期内
cursor.execute("""
SELECT * FROM email_verification
WHERE email = %s AND code = %s
AND created_at > NOW() - INTERVAL 5 MINUTE
ORDER BY created_at DESC LIMIT 1
""", (email, code))
result = cursor.fetchone()
if not result:
return jsonify({"success": False, "message": "验证码错误或已过期"}), 400
# 加密密码
import bcrypt
hashed_pwd = bcrypt.hashpw(new_password.encode(), bcrypt.gensalt()).decode()
# 检查用户是否存在
cursor.execute("SELECT user_id FROM sys_user WHERE email = %s", (email,))
user = cursor.fetchone()
if not user:
return jsonify({"success": False, "message": "用户不存在"}), 404
# 更新密码
cursor.execute("""
UPDATE sys_user
SET password = %s
WHERE email = %s
""", (hashed_pwd, email))
conn.commit()
return jsonify({"success": True, "message": "密码已重置"})
except Exception as e:
print("重置失败:", e)
return jsonify({"success": False, "message": f"服务器异常:{e}"}), 500
finally:
if cursor:
cursor.close()
if conn:
conn.close()
from flask import send_file, jsonify
@app.route('/ngrok-url', methods=['GET'])
def ngrok_url():
try:
with open("ngrok_url.txt", "r", encoding="utf-8") as f:
url = f.read().strip()
print(url)
return jsonify({"backUrl": f"{url}"})
except FileNotFoundError:
# 回退到本地,避免前端报错
return jsonify({"backUrl": "http://localhost:6001"})
if __name__ == '__main__':
try:
conn = config.get_db_connection()
print("数据库连接成功!")
conn.close()
except Exception as e:
print(f"数据库连接失败: {e}")
app.run(host='0.0.0.0', port=6001,debug =True)