| 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) |