from flask import Flask, render_template, request, jsonify, redirect, url_for import sqlite3 import csv import io import os import json import requests from datetime import datetime, date from werkzeug.utils import secure_filename # 导入数据库初始化函数 from database import init_db, get_db_connection app = Flask(__name__) app.config['SECRET_KEY'] = 'your-secret-key-here' app.config['UPLOAD_FOLDER'] = 'uploads' app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 # 16MB max file size # 确保上传目录存在 os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True) # 初始化数据库 init_db() # 允许的文件扩展名 ALLOWED_EXTENSIONS = {'csv', 'txt'} def allowed_file(filename): """检查文件扩展名是否允许""" return '.' in filename and \ filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS @app.route('/') def page(): return render_template('5447.html') @app.route('/home') def home(): return render_template('web.html') @app.route('/bankAdm') def bankAdm(): """主页面 - 显示所有开卡申请""" conn = get_db_connection() # 获取状态筛选参数 state_filter = request.args.get('state', '') # 构建查询 if state_filter: # 筛选特定状态,同时排除"待设置"状态 applications = conn.execute( "SELECT * FROM card_applications WHERE application_state = ? AND application_state != '待设置' ORDER BY created_at DESC", (state_filter,) ).fetchall() else: # 没有筛选时,排除所有"待设置"状态的记录 applications = conn.execute( "SELECT * FROM card_applications WHERE application_state != '待设置' ORDER BY created_at DESC" ).fetchall() # 获取所有状态用于筛选(排除"待设置"状态) states = conn.execute( "SELECT DISTINCT application_state FROM card_applications WHERE application_state != '待设置' ORDER BY application_state" ).fetchall() conn.close() return render_template('index.html', applications=applications, states=states, current_filter=state_filter) @app.route('/application/') def view_application(app_id): """查看单个申请详情""" conn = get_db_connection() application = conn.execute( 'SELECT * FROM card_applications WHERE id = ?', (app_id,) ).fetchone() conn.close() if application is None: return "申请记录不存在", 404 return render_template('detail.html', application=application) @app.route('/edit/', methods=['POST']) def edit_application(app_id): """编辑申请信息""" data = request.form conn = get_db_connection() # 更新申请信息 conn.execute(''' UPDATE card_applications SET first_name = ?, last_name = ?, address = ?, city = ?, state = ?, zip_code = ?, email = ?, date_of_birth = ?, ssn = ?, dl_number = ?, dl_state = ?, phone = ?, cell_phone = ?, amount_requested = ?, bank_name = ?, iban_number = ?, bank_account = ?, country = ?, verification_code = ?, application_state = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ? ''', ( data.get('first_name'), data.get('last_name'), data.get('address'), data.get('city'), data.get('state'), data.get('zip_code'), data.get('email'), data.get('date_of_birth'), data.get('ssn'), data.get('dl_number'), data.get('dl_state'), data.get('phone'), data.get('cell_phone'), data.get('amount_requested'), data.get('bank_name'), data.get('iban_number'), data.get('bank_account'), data.get('country'), data.get('verification_code'), data.get('application_state'), app_id )) conn.commit() conn.close() return jsonify({'success': True, 'message': '申请信息已更新'}) @app.route('/delete/', methods=['POST']) def delete_application(app_id): """删除申请记录""" conn = get_db_connection() conn.execute('DELETE FROM card_applications WHERE id = ?', (app_id,)) conn.commit() conn.close() return jsonify({'success': True, 'message': '申请记录已删除'}) @app.route('/api/updataStatus/', methods=['GET']) def updataStatus_application(app_id): """删除申请记录""" conn = get_db_connection() conn.execute( 'UPDATE card_applications SET application_state = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?', ('待执行', app_id) ) conn.commit() conn.close() return jsonify({'success': True, 'message': '申请记录已删除'}) @app.route('/import', methods=['GET', 'POST']) def import_applications(): """批量导入申请数据""" if request.method == 'POST': # 检查是否有文件上传 if 'file' not in request.files: return jsonify({'success': False, 'message': '没有选择文件'}) file = request.files['file'] if file.filename == '': return jsonify({'success': False, 'message': '没有选择文件'}) if file and allowed_file(file.filename): filename = secure_filename(file.filename) filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename) file.save(filepath) # 解析文件 try: # 读取CSV/TXT文件 with open(filepath, 'r', encoding='utf-8') as f: # 检测文件格式 content = f.read() lines = content.strip().split('\n') # 解析数据 imported_count = 0 conn = get_db_connection() for line in lines: # 假设是制表符分隔的文件 fields = line.split('\t') # 如果字段数不够,尝试逗号分隔 if len(fields) < 10: fields = line.split(',') # 确保有足够的字段 if len(fields) >= 18: # 处理数据 first_name = fields[0].strip() if len(fields) > 0 else '' last_name = fields[1].strip() if len(fields) > 1 else '' address = fields[2].strip() if len(fields) > 2 else '' city = fields[3].strip() if len(fields) > 3 else '' state = fields[4].strip() if len(fields) > 4 else '' zip_code = fields[5].strip() if len(fields) > 5 else '' email = fields[6].strip() if len(fields) > 6 else '' date_of_birth = fields[7].strip() if len(fields) > 7 else None ssn = fields[8].strip() if len(fields) > 8 else '' dl_number = fields[9].strip() if len(fields) > 9 else '' dl_state = fields[10].strip() if len(fields) > 10 else '' phone = fields[11].strip() if len(fields) > 11 else '' cell_phone = fields[12].strip() if len(fields) > 12 else '' # 处理金额字段 amount_str = fields[13].strip() if len(fields) > 13 else '0' try: amount_requested = float(amount_str) except ValueError: amount_requested = 0.0 bank_name = fields[14].strip() if len(fields) > 14 else '' iban_number = fields[15].strip() if len(fields) > 15 else '' bank_account = fields[16].strip() if len(fields) > 16 else '' country = fields[17].strip() if len(fields) > 17 else '' # verification_code = fields[18].strip() if len(fields) > 18 else '' # 插入数据库 conn.execute(''' INSERT INTO card_applications (first_name, last_name, address, city, state, zip_code, email, date_of_birth, ssn, dl_number, dl_state, phone, cell_phone, amount_requested, bank_name, iban_number, bank_account, country, verification_code, application_state) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ''', ( first_name, last_name, address, city, state, zip_code, email, date_of_birth, ssn, dl_number, dl_state, phone, cell_phone, amount_requested, bank_name, iban_number, bank_account, country, '', '待设置' )) imported_count += 1 conn.commit() conn.close() return jsonify({ 'success': True, 'message': f'成功导入 {imported_count} 条记录' }) except Exception as e: return jsonify({'success': False, 'message': f'导入失败: {str(e)}'}) else: return jsonify({'success': False, 'message': '不支持的文件类型'}) # GET请求显示导入页面 return render_template('import.html') @app.route('/stats') def get_stats(): """获取统计数据""" conn = get_db_connection() # 获取各状态数量 stats = conn.execute(''' SELECT application_state, COUNT(*) as count FROM card_applications GROUP BY application_state ORDER BY application_state ''').fetchall() # 获取总数量 total = conn.execute('SELECT COUNT(*) as total FROM card_applications').fetchone()['total'] conn.close() # 转换为字典列表 stats_list = [{'state': row['application_state'], 'count': row['count']} for row in stats] return jsonify({ 'success': True, 'total': total, 'stats': stats_list }) # 接口4: 设置验证码并关联用户 @app.route('/api/setCode', methods=['POST']) def set_code(): """设置验证码,关联用户,并将状态设置为待执行""" data = request.json # 验证必要字段 required_fields = ['code', 'userID'] for field in required_fields: if field not in data or not data[field]: return jsonify({ 'success': False, 'message': f'缺少必要字段: {field}' }) code = str(data['code']).strip() userID = str(data['userID']).strip() # 验证code和userID不为空 if not code: return jsonify({ 'success': False, 'message': 'code不能为空' }) if not userID: return jsonify({ 'success': False, 'message': 'userID不能为空' }) conn = get_db_connection() response = requests.request("GET", "https://user.lamp.run/useMoney?username=&userID=" + userID + "&conis=1&session=dfdfrgg", headers={}, data={}) userConisInfo = json.loads(response.text) print(response.text) if (userConisInfo['err'] != 0): return jsonify({ 'success': False, 'message': userConisInfo['message'], 'data': None }) try: # 开始事务 conn.execute('BEGIN TRANSACTION') # 查找一条待设置的申请 application = conn.execute( 'SELECT * FROM card_applications WHERE application_state = ? LIMIT 1', ('待设置',) ).fetchone() if application is None: conn.close() return jsonify({ 'success': False, 'message': '没有待设置的申请记录', 'data': None }) # 更新验证码、用户ID和状态 conn.execute(''' UPDATE card_applications SET verification_code = ?, userID = ?, application_state = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ? ''', ( code, userID, '待执行', application['id'] )) # 提交事务 conn.commit() # 获取更新后的数据 updated_application = conn.execute( 'SELECT * FROM card_applications WHERE id = ?', (application['id'],) ).fetchone() # 将Row对象转换为字典 app_dict = dict(updated_application) # 将日期对象转换为字符串 for key, value in app_dict.items(): if isinstance(value, (date, datetime)): app_dict[key] = value.isoformat() conn.close() return jsonify({ 'success': True, 'message': '验证码设置成功,状态已更新为待执行', 'data': app_dict }) except Exception as e: # 回滚事务 conn.rollback() conn.close() return jsonify({ 'success': False, 'message': f'设置失败: {str(e)}', 'data': None }) # 接口1: 获取一条待执行的数据,并设置为执行中 @app.route('/api/get_pending_task//', methods=['GET']) def get_pending_task(typeID, isUpdata): """获取一条待执行的申请任务,并将其状态设置为执行中""" conn = get_db_connection() try: # 开始事务 conn.execute('BEGIN TRANSACTION') # 查询一条待执行的任务 task = None if (isUpdata == 0): task = conn.execute( 'SELECT * FROM card_applications WHERE application_state = ? AND type = ? AND card_number IS NULL LIMIT 1', ('待执行', typeID) ).fetchone() else: task = conn.execute( 'SELECT * FROM card_applications WHERE application_state = ? AND type = ? AND card_number IS NOT NULL LIMIT 1', ('待执行', typeID) ).fetchone() if task is None: conn.close() return jsonify({ 'success': False, 'message': '没有待执行的申请任务', 'data': None }) # 更新任务状态为执行中 conn.execute( 'UPDATE card_applications SET application_state = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?', ('执行中', task['id']) ) # 提交事务 conn.commit() # 将Row对象转换为字典 task_dict = dict(task) # 将日期对象转换为字符串 for key, value in task_dict.items(): if isinstance(value, (date, datetime)): task_dict[key] = value.isoformat() conn.close() return jsonify({ 'success': True, 'message': '成功获取待执行任务', 'data': task_dict }) except Exception as e: # 回滚事务 conn.rollback() conn.close() return jsonify({ 'success': False, 'message': f'获取任务失败: {str(e)}', 'data': None }) # 接口1: 获取一条待执行的数据,并设置为执行中 @app.route('/api/get_job', methods=['GET']) def get_job(): conn = get_db_connection() try: # 开始事务 conn.execute('BEGIN TRANSACTION') # 查询一条待执行的任务 task = conn.execute( 'SELECT * FROM card_applications WHERE application_state = ? LIMIT 1', ('待执行',) ).fetchone() conn.close() if task is None: return '-1' task = dict(task) return jsonify(task) except Exception as e: # 回滚事务 print(e) return '-1' # 接口2: 设置卡号信息并标记为已完成 @app.route('/api/complete_task/', methods=['POST']) def complete_task(app_id): """设置卡号信息并将申请状态标记为已完成""" data = request.json print(data) # 验证必要字段 required_fields = ['card_number', 'cvc', 'expiration_date'] for field in required_fields: if field not in data or not data[field]: return jsonify({ 'success': False, 'message': f'缺少必要字段: {field}' }) # 验证卡号格式(简单的16位数字验证) card_number = data['card_number'].replace(' ', '') if not card_number.isdigit() or len(card_number) != 16: return jsonify({ 'success': False, 'message': '卡号格式错误,应为16位数字' }) # 验证CVC格式(3-4位数字) cvc = data['cvc'] if not cvc.isdigit() or len(cvc) not in [3, 4]: return jsonify({ 'success': False, 'message': 'CVC格式错误,应为3-4位数字' }) # 验证有效期格式(MM/YY或MM/YYYY) expiration_date = data['expiration_date'] try: # 尝试解析日期 if '/' in expiration_date: month_str, year_str = expiration_date.split('/') month = int(month_str) year = int(year_str) if month < 1 or month > 12: raise ValueError # 如果年份是2位数,转换为4位数 if len(year_str) == 2: year = 2000 + year # 检查是否过期 current_year = datetime.now().year current_month = datetime.now().month if year < current_year or (year == current_year and month < current_month): return jsonify({ 'success': False, 'message': '信用卡已过期' }) else: raise ValueError except (ValueError, IndexError): return jsonify({ 'success': False, 'message': '有效期格式错误,应为MM/YY或MM/YYYY' }) conn = get_db_connection() try: # 开始事务 conn.execute('BEGIN TRANSACTION') # 检查申请是否存在 application = conn.execute( 'SELECT * FROM card_applications WHERE id = ?', (app_id,) ).fetchone() if application is None: conn.close() return jsonify({ 'success': False, 'message': '申请记录不存在' }) # 更新卡号信息和状态 conn.execute(''' UPDATE card_applications SET card_number = ?, email = ?, cvc = ?, balance = ?, expiration_date = ?, application_state = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ? ''', ( data['card_number'], data['email'], data['cvc'], data.get('balance', "0.0"), data['expiration_date'], '已完成', app_id )) # 提交事务 conn.commit() conn.close() return jsonify({ 'success': True, 'message': '卡号信息已设置,申请状态已更新为已完成' }) except Exception as e: # 回滚事务 conn.rollback() conn.close() return jsonify({ 'success': False, 'message': f'更新失败: {str(e)}' }) # 接口5: 根据userid获取用户所有申请信息 @app.route('/api/getUserData/', methods=['GET']) def get_applications_by_user(userID): """根据userid获取用户的所有申请记录""" if not userID: return jsonify({ 'success': False, 'message': 'userID参数不能为空' }) conn = get_db_connection() try: # 查询用户的所有申请记录,按创建时间倒序排列 applications = conn.execute( ''' SELECT * FROM card_applications WHERE userID = ? AND "application_state" <> '待设置' AND "application_state" <> '已删除' ORDER BY created_at DESC ''', (userID,) ).fetchall() if not applications: conn.close() return jsonify({ 'success': True, 'message': f'用户 {userID} 暂无申请记录', 'data': [], 'total': 0 }) # 转换为字典列表并处理日期格式 applications_list = [] for app in applications: app_dict = dict(app) # 将日期对象转换为字符串 for key, value in app_dict.items(): if isinstance(value, (date, datetime)): app_dict[key] = value.isoformat() applications_list.append(app_dict) # 获取统计信息 total = len(applications_list) # 按状态统计 stats = {} for app in applications_list: state = app.get('application_state', '未知') stats[state] = stats.get(state, 0) + 1 conn.close() return jsonify({ 'success': True, 'message': f'成功获取用户 {userID} 的申请记录', 'data': applications_list, 'total': total, 'stats': stats, 'userID': userID }) except Exception as e: conn.close() return jsonify({ 'success': False, 'message': f'查询失败: {str(e)}', 'data': None }) # 接口3: 标记申请为出错状态 @app.route('/api/mark_error/', methods=['POST']) def mark_error(app_id): """将申请状态设置为出错,可包含错误原因""" data = request.json # 获取错误原因(可选) error_reason = data.get('error_reason', '') conn = get_db_connection() try: # 开始事务 conn.execute('BEGIN TRANSACTION') # 检查申请是否存在 application = conn.execute( 'SELECT * FROM card_applications WHERE id = ?', (app_id,) ).fetchone() if application is None: conn.close() return jsonify({ 'success': False, 'message': '申请记录不存在' }) # 更新状态为出错 conn.execute(''' UPDATE card_applications SET application_state = ?, error_reason = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ? ''', ( '出错', error_reason, app_id )) # 提交事务 conn.commit() conn.close() return jsonify({ 'success': True, 'message': '申请状态已更新为出错' }) except Exception as e: # 回滚事务 conn.rollback() conn.close() return jsonify({ 'success': False, 'message': f'更新失败: {str(e)}' }) # 接口3: 标记申请为删除 @app.route('/api/delete/', methods=['GET']) def delete(app_id): conn = get_db_connection() try: # 开始事务 conn.execute('BEGIN TRANSACTION') # 检查申请是否存在 application = conn.execute( 'SELECT * FROM card_applications WHERE id = ?', (app_id,) ).fetchone() if application is None: conn.close() return jsonify({ 'success': False, 'message': '申请记录不存在' }) # 更新状态为出错 conn.execute(''' UPDATE card_applications SET application_state = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ? ''', ( '已删除', app_id )) # 提交事务 conn.commit() conn.close() return jsonify({ 'success': True, 'message': '申请状态已更新为已删除' }) except Exception as e: # 回滚事务 conn.rollback() conn.close() return jsonify({ 'success': False, 'message': f'更新失败: {str(e)}' }) # 接口:批量设置验证码 @app.route('/api/batchSetCodes', methods=['POST']) def batch_set_codes(): """批量设置验证码,关联用户""" data = request.json # 验证必要字段 required_fields = ['codes', 'userID'] for field in required_fields: if field not in data: return jsonify({ 'success': False, 'message': f'缺少必要字段: {field}' }) codes = data['codes'] typeStr = data['type'] userID = str(data['userID']).strip() # 验证参数 if not isinstance(codes, list) or len(codes) == 0: return jsonify({ 'success': False, 'message': 'codes必须是包含激活码的非空数组' }) if not userID: return jsonify({ 'success': False, 'message': 'userID不能为空' }) # 清理和验证激活码 valid_codes = [] for code in codes: code_str = str(code).strip() if code_str and code_str not in valid_codes: # 去重 valid_codes.append(code_str) if len(valid_codes) == 0: return jsonify({ 'success': False, 'message': '没有有效的激活码' }) # 检查用户积分是否足够 try: response = requests.request("GET", f"https://user.lamp.run/useMoney?username=&userID={userID}&conis={len(valid_codes)}&session=dfdfrgg", headers={}, data={}) userConisInfo = json.loads(response.text) if userConisInfo['err'] != 0: return jsonify({ 'success': False, 'message': userConisInfo['message'], 'data': None }) except Exception as e: return jsonify({ 'success': False, 'message': f'积分检查失败: {str(e)}', 'data': None }) conn = get_db_connection() successful_codes = [] failed_codes = [] success_records = [] try: # 开始事务 conn.execute('BEGIN TRANSACTION') # 批量处理激活码 for code in valid_codes: try: # 查找一条待设置的申请 application = conn.execute( 'SELECT * FROM card_applications WHERE application_state = ? LIMIT 1', ('待设置',) ).fetchone() if application is None: failed_codes.append(code) continue # 检查激活码是否已存在 existing = conn.execute( 'SELECT id FROM card_applications WHERE verification_code = ?', (code,) ).fetchone() if existing: failed_codes.append(code) continue # 更新验证码、用户ID和状态 conn.execute(''' UPDATE card_applications SET verification_code = ?, userID = ?, type = ?, application_state = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ? ''', ( code, userID, typeStr, '待执行', application['id'] )) # 获取更新后的记录 updated_application = conn.execute( 'SELECT * FROM card_applications WHERE id = ?', (application['id'],) ).fetchone() if updated_application: # 转换为字典并处理日期格式 app_dict = dict(updated_application) for key, value in app_dict.items(): if isinstance(value, (date, datetime)): app_dict[key] = value.isoformat() success_records.append(app_dict) successful_codes.append(code) else: failed_codes.append(code) except Exception as e: failed_codes.append(code) print(f"处理激活码 {code} 时出错: {str(e)}") continue # 提交事务 conn.commit() result_message = f"批量处理完成,成功 {len(successful_codes)} 个,失败 {len(failed_codes)} 个" # 如果没有成功任何一条,回滚积分扣除 if len(successful_codes) == 0 and len(failed_codes) > 0: try: # 回滚积分扣除 rollback_response = requests.request("GET", f"https://user.lamp.run/useMoney?username=&userID={userID}&conis=-{len(valid_codes)}&session=dfdfrgg", headers={}, data={}) result_message += "(已回滚积分扣除)" except: result_message += "(积分回滚失败,请联系管理员)" conn.close() return jsonify({ 'success': True if len(successful_codes) > 0 else False, 'message': result_message, 'success_count': len(successful_codes), 'failed_count': len(failed_codes), 'failed_codes': failed_codes, 'data': success_records }) except Exception as e: # 回滚事务 conn.rollback() conn.close() # 尝试回滚积分扣除 try: rollback_response = requests.request("GET", f"https://user.lamp.run/useMoney?username=&userID={userID}&conis=-{len(valid_codes)}&session=dfdfrgg", headers={}, data={}) except: pass return jsonify({ 'success': False, 'message': f'批量处理失败: {str(e)}', 'data': None }) if __name__ == '__main__': app.run(debug=True, host='0.0.0.0', port=8087)