from flask import request, jsonify, current_app from sqlalchemy.exc import IntegrityError import random import string from . import api_bp from ..models import get_session, Domain, Mailbox # 获取所有邮箱 @api_bp.route('/mailboxes', methods=['GET']) def get_mailboxes(): """获取所有邮箱列表""" try: page = int(request.args.get('page', 1)) limit = int(request.args.get('limit', 50)) offset = (page - 1) * limit db = get_session() try: # 查询总数 total = db.query(Mailbox).count() # 获取分页数据 mailboxes = db.query(Mailbox).order_by(Mailbox.created_at.desc()) \ .limit(limit) \ .offset(offset) \ .all() # 转换为字典列表 result = { 'total': total, 'page': page, 'limit': limit, 'mailboxes': [mailbox.to_dict() for mailbox in mailboxes] } return jsonify(result), 200 finally: db.close() except Exception as e: current_app.logger.error(f"获取邮箱列表出错: {str(e)}") return jsonify({'error': '获取邮箱列表失败', 'details': str(e)}), 500 # 创建邮箱 @api_bp.route('/mailboxes', methods=['POST']) def create_mailbox(): """创建新邮箱""" try: data = request.json # 验证必要参数 if not data or 'domain_id' not in data: return jsonify({'error': '缺少必要参数'}), 400 db = get_session() try: # 查询域名是否存在 domain = db.query(Domain).filter_by(id=data['domain_id'], active=True).first() if not domain: return jsonify({'error': '指定的域名不存在或未激活'}), 404 # 生成或使用给定地址 if 'address' not in data or not data['address']: # 生成随机地址 address = ''.join(random.choices(string.ascii_lowercase + string.digits, k=10)) else: address = data['address'] # 创建邮箱 mailbox = Mailbox( address=address, domain_id=domain.id, description=data.get('description', ''), active=True ) db.add(mailbox) db.commit() return jsonify({ 'message': '邮箱创建成功', 'mailbox': mailbox.to_dict() }), 201 except IntegrityError: db.rollback() return jsonify({'error': '邮箱地址已存在'}), 409 except Exception as e: db.rollback() raise finally: db.close() except Exception as e: current_app.logger.error(f"创建邮箱出错: {str(e)}") return jsonify({'error': '创建邮箱失败', 'details': str(e)}), 500 # 批量创建邮箱 @api_bp.route('/mailboxes/batch', methods=['POST']) def batch_create_mailboxes(): """批量创建邮箱""" try: data = request.json # 验证必要参数 if not data or 'domain_id' not in data or 'count' not in data: return jsonify({'error': '缺少必要参数'}), 400 domain_id = data['domain_id'] count = min(int(data['count']), 100) # 限制最大数量为100 prefix = data.get('prefix', '') db = get_session() try: # 查询域名是否存在 domain = db.query(Domain).filter_by(id=domain_id, active=True).first() if not domain: return jsonify({'error': '指定的域名不存在或未激活'}), 404 created_mailboxes = [] # 批量创建 for _ in range(count): # 生成随机地址 if prefix: address = f"{prefix}{random.randint(1000, 9999)}" else: address = ''.join(random.choices(string.ascii_lowercase + string.digits, k=10)) # 尝试创建,如果地址已存在则重试 retries = 0 while retries < 3: # 最多尝试3次 try: mailbox = Mailbox( address=address, domain_id=domain.id, active=True ) db.add(mailbox) db.flush() # 验证但不提交 created_mailboxes.append(mailbox) break except IntegrityError: db.rollback() # 地址已存在,重新生成 address = ''.join(random.choices(string.ascii_lowercase + string.digits, k=10)) retries += 1 # 提交所有更改 db.commit() return jsonify({ 'message': f'成功创建 {len(created_mailboxes)} 个邮箱', 'mailboxes': [mailbox.to_dict() for mailbox in created_mailboxes] }), 201 except Exception as e: db.rollback() raise finally: db.close() except Exception as e: current_app.logger.error(f"批量创建邮箱出错: {str(e)}") return jsonify({'error': '批量创建邮箱失败', 'details': str(e)}), 500 # 获取特定邮箱 @api_bp.route('/mailboxes/', methods=['GET']) def get_mailbox(mailbox_id): """获取指定ID的邮箱信息""" try: db = get_session() try: mailbox = db.query(Mailbox).filter_by(id=mailbox_id).first() if not mailbox: return jsonify({'error': '邮箱不存在'}), 404 return jsonify(mailbox.to_dict()), 200 finally: db.close() except Exception as e: current_app.logger.error(f"获取邮箱详情出错: {str(e)}") return jsonify({'error': '获取邮箱详情失败', 'details': str(e)}), 500 # 删除邮箱 @api_bp.route('/mailboxes/', methods=['DELETE']) def delete_mailbox(mailbox_id): """删除指定ID的邮箱""" try: db = get_session() try: mailbox = db.query(Mailbox).filter_by(id=mailbox_id).first() if not mailbox: return jsonify({'error': '邮箱不存在'}), 404 db.delete(mailbox) db.commit() return jsonify({'message': '邮箱已删除'}), 200 except Exception as e: db.rollback() raise finally: db.close() except Exception as e: current_app.logger.error(f"删除邮箱出错: {str(e)}") return jsonify({'error': '删除邮箱失败', 'details': str(e)}), 500