blob: f3d6abaacda5037ae05d0d1cb3ab3d1a5e7a4ee0 [file] [log] [blame]
22301110e361be52025-06-08 15:24:14 +08001from flask import Flask, jsonify, request, current_app
2from flask_cors import CORS
3import traceback
4import hashlib
5import requests
6from bs4 import BeautifulSoup, MarkupResemblesLocatorWarning
7import warnings
8import config
9import pymysql.cursors # 确保导入了 pymysql 的 cursors
10from pyngrok import ngrok
11from flask import Flask, request, jsonify
12from flask_cors import CORS
13from smtplib import SMTP_SSL
14from email.mime.text import MIMEText
15import random, datetime
16import bcrypt
17import mysql.connector
18
19
20app = Flask(__name__)
21CORS(app, supports_credentials=True) # 支持 cookies(可选)
22
23# 商户ID和密钥
24merchant_id = 4058
25merchant_key = '2c9e609b503698c6f1dba301725ec631'
26base_url = 'https://api.ltrhcj.cn/api/paySubmit' # 请求网关
27
28def generate_md5_signature(*args):
29 """根据传入的参数生成MD5签名"""
30 sign_str = ''.join(args)
31 return hashlib.md5(sign_str.encode('utf-8')).hexdigest()
32
33@app.route('/paySuccess', methods=['POST', 'GET'])
34def pay_success():
35 data = request.form if request.method == 'POST' else request.args
36 orderid = data.get('orderid')
37 state = data.get('state')
38 amount = data.get('amount')
39 payment = data.get('payment')
40 rate = data.get('rate')
41 sign = data.get('sign')
42
43 if not orderid or not state or not amount or not payment or not sign:
44 return "Missing parameter", 400
45
46 try:
47 print("Received paySuccess notification:")
48 print(f"orderid: {orderid}")
49 print(f"state: {state}")
50 print(f"amount: {amount}")
51 print(f"payment: {payment}")
52 print(f"rate: {rate}")
53 print(f"sign: {sign}")
54
55 # 获取数据库连接
56 connection = config.get_db_connection()
57 cursor = connection.cursor(pymysql.cursors.DictCursor)
58
59 # 查询该订单对应的邮箱和密码
60 cursor.execute("SELECT user_name, password FROM `order` WHERE orderid = %s", (orderid,))
61 result = cursor.fetchone()
62 print("result内容:", result)
63
64 if result:
65 email = result["user_name"]
66 raw_password = result["password"]
67
68 # 查询 sys_user 是否已存在该 email
69 cursor.execute("SELECT user_id FROM sys_user WHERE email = %s", (email,))
70 user_exists = cursor.fetchone()
71
72 if not user_exists:
73 # 加密密码(如果已经加密过,可以略过这一步)
74
75 cursor.execute("""
76 INSERT INTO sys_user (
77 user_name, nick_name, password, email, create_time, del_flag, status, user_type
78 ) VALUES (%s, %s, %s, %s, NOW(), '0', '0', '00')
79 """, (email, email, raw_password, email))
80 else:
81 cursor.execute("UPDATE sys_user SET status = '0' WHERE email = %s", (email,))
82
83 # 更新订单状态为已支付
84 cursor.execute("UPDATE `order` SET state = %s WHERE orderid = %s", ('已支付', orderid))
85
86 connection.commit()
87
88 cursor.close()
89 connection.close()
90
91 return "success", 200
92
93 except Exception as e:
94 import traceback
95 current_app.logger.error(f'发生异常: {e}')
96 traceback.print_exc()
97 return "Internal server error", 500
98
99
100
101
102@app.route('/user/createOrder', methods=['POST'])
103def create_order():
104 data = request.json
105 print(data)
106 orderid = data.get('orderid')
107 paytype = data.get('paytype')
108 money = data.get('money')
109 notifyUrl = data.get('notifyUrl', '')
110 returnUrl = data.get('returnUrl', '')
111 returnmsg = 2
112 user_name = data.get('user_name')
113 password = data.get('password') # 👈 获取前端传来的加密密码
114
115 print(data)
116 if not orderid or not paytype or not money or not user_name:
117 return jsonify({'success': False, 'message': '缺少必传参数'}), 400
118
119 try:
120 sign = generate_md5_signature(str(merchant_id), orderid, str(paytype), str(money), merchant_key)
121 payload = {
122 'appid': merchant_id,
123 'orderid': orderid,
124 'paytype': paytype,
125 'money': money,
126 'sign': sign,
127 'notifyUrl': notifyUrl,
128 'returnUrl': returnUrl,
129 'returnmsg': returnmsg
130 }
131
132 # 发送POST请求到外部 API
133 response = requests.post(base_url, data=payload)
134 current_app.logger.debug(f'请求URL: {base_url}')
135 current_app.logger.debug(f'请求数据: {payload}')
136
137 if response.status_code == 200:
138 # 将订单信息插入到数据库的 order 表中
139 connection = config.get_db_connection()
140 cursor = connection.cursor()
141 cursor.execute(
142 "INSERT INTO `order` (orderid, user_name, password, time, amount, state) VALUES (%s, %s, %s, NOW(), %s, %s)",
143 (orderid, user_name, password, money, 'pending')
144 )
145
146 connection.commit()
147 cursor.close()
148 connection.close()
149
150 return response.text, 200
151 else:
152 return jsonify({'success': False, 'message': f"外部 API 错误: {response.text}"}), response.status_code
153 except Exception as e:
154 current_app.logger.error(f'发生异常: {e}')
155 traceback.print_exc()
156 return jsonify({'success': False, 'message': f"Error: {e}"}), 530
157
158
159
160
161
162
163
164# 邮箱配置
165SMTP_SERVER = 'smtp.qq.com'
166EMAIL_ADDRESS = '3534185780@qq.com'
167EMAIL_AUTH_CODE = 'slcsbwtrwitbcjic'
168
169# 数据库配置
170DB_CONFIG = {
171 'host': '49.233.215.144',
172 'port': 3306,
173 'user': 'sy',
174 'password': 'sy_password',
175 'database': 'pt_station'
176}
177
178
179# === 发送验证码接口 ===
180@app.route('/send-code', methods=['POST'])
181def send_code():
182 data = request.get_json()
183 to_email = data.get('email')
184
185 if not to_email:
186 return jsonify({"success": False, "message": "缺少邮箱"}), 400
187
188 code = str(random.randint(100000, 999999))
189 msg = MIMEText(f"欢迎注册PTStation,您的验证码是:{code}(有效期5分钟)")
190 msg['Subject'] = '您的验证码'
191 msg['From'] = EMAIL_ADDRESS
192 msg['To'] = to_email
193
194 try:
195 # 发送邮件
196 with SMTP_SSL(SMTP_SERVER, 465) as smtp:
197 smtp.login(EMAIL_ADDRESS, EMAIL_AUTH_CODE)
198 smtp.send_message(msg)
199 smtp.quit()
200 # 存入数据库
201 conn = mysql.connector.connect(**DB_CONFIG)
202 cursor = conn.cursor()
203 sql = "INSERT INTO email_verification (email, code, created_at) VALUES (%s, %s, NOW())"
204 cursor.execute(sql, (to_email, code))
205 conn.commit()
206 cursor.close()
207 conn.close()
208
209 return jsonify({"success": True})
210 except Exception as e:
211 print("发送失败:", e)
212 return jsonify({"success": False, "message": f"邮件发送失败:{e}"}), 500
213
214
215# === 注册接口 ===
216@app.route('/register', methods=['POST'])
217def register():
218 data = request.get_json()
219 email = data.get('email')
220 password = data.get('password') # 可以保留做哈希后传给支付回调存库
221 code = data.get('code')
222
223 if not all([email, password, code]):
224 return jsonify({"success": False, "message": "缺少参数"}), 400
225
226 try:
227 conn = mysql.connector.connect(**DB_CONFIG)
228 cursor = conn.cursor(dictionary=True)
229
230 # 1. 验证验证码是否有效(5分钟内)
231 cursor.execute("""
232 SELECT * FROM email_verification
233 WHERE email = %s AND code = %s AND created_at > NOW() - INTERVAL 5 MINUTE
234 ORDER BY created_at DESC LIMIT 1
235 """, (email, code))
236 result = cursor.fetchone()
237
238 if not result:
239 return jsonify({"success": False, "message": "验证码无效或已过期"}), 400
240
241 # 2. 检查邮箱是否已注册
242 cursor.execute("SELECT user_id FROM sys_user WHERE email = %s", (email,))
243 if cursor.fetchone():
244 return jsonify({"success": False, "message": "该邮箱已注册"}), 400
245
246 # ⚠️ 不再插入数据库,只返回验证通过
247 return jsonify({"success": True, "message": "验证通过"})
248
249 except Exception as e:
250 print("注册失败:", e)
251 return jsonify({"success": False, "message": f"注册失败:{e}"}), 500
252 finally:
253 cursor.close()
254 conn.close()
255
256
257
258@app.route('/reset-password', methods=['POST'])
259def reset_password():
260 data = request.get_json()
261 email = data.get('email')
262 code = data.get('code')
263 new_password = data.get('newPassword')
264
265 if not all([email, code, new_password]):
266 return jsonify({"success": False, "message": "参数缺失"}), 400
267
268 try:
269 conn = mysql.connector.connect(**DB_CONFIG)
270 cursor = conn.cursor()
271
272 # 验证验证码是否正确且在有效期内
273 cursor.execute("""
274 SELECT * FROM email_verification
275 WHERE email = %s AND code = %s
276 AND created_at > NOW() - INTERVAL 5 MINUTE
277 ORDER BY created_at DESC LIMIT 1
278 """, (email, code))
279 result = cursor.fetchone()
280
281 if not result:
282 return jsonify({"success": False, "message": "验证码错误或已过期"}), 400
283
284 # 加密密码
285 import bcrypt
286 hashed_pwd = bcrypt.hashpw(new_password.encode(), bcrypt.gensalt()).decode()
287
288 # 检查用户是否存在
289 cursor.execute("SELECT user_id FROM sys_user WHERE email = %s", (email,))
290 user = cursor.fetchone()
291 if not user:
292 return jsonify({"success": False, "message": "用户不存在"}), 404
293
294 # 更新密码
295 cursor.execute("""
296 UPDATE sys_user
297 SET password = %s
298 WHERE email = %s
299 """, (hashed_pwd, email))
300
301 conn.commit()
302 return jsonify({"success": True, "message": "密码已重置"})
303
304 except Exception as e:
305 print("重置失败:", e)
306 return jsonify({"success": False, "message": f"服务器异常:{e}"}), 500
307
308 finally:
309 if cursor:
310 cursor.close()
311 if conn:
312 conn.close()
313
314from flask import send_file, jsonify
315
316@app.route('/ngrok-url', methods=['GET'])
317def ngrok_url():
318 try:
319 with open("ngrok_url.txt", "r", encoding="utf-8") as f:
320 url = f.read().strip()
321 print(url)
322 return jsonify({"backUrl": f"{url}"})
323 except FileNotFoundError:
324 # 回退到本地,避免前端报错
325 return jsonify({"backUrl": "http://localhost:6001"})
326
327if __name__ == '__main__':
328 try:
329 conn = config.get_db_connection()
330 print("数据库连接成功!")
331 conn.close()
332 except Exception as e:
333 print(f"数据库连接失败: {e}")
334 app.run(host='0.0.0.0', port=6001,debug =True)