from PDAPI import * from Utils.Models import GERPMessage, GERPUser, GERPRole, UserRole import TempLateAPI.GERP.API.FormAPI.FormData as FormData import uuid import datetime __metadata__ = { "route": "{DEFAULT_ROUTE}", "methods": ["GET", "POST", "PATCH", "DELETE"], "blueprint": "GERP", "permission": 1.0, "attributes": [], "limit": "10 per second" } def HandleRequest(_CleanedData): method = flask.request.method if method == "GET": return handle_get(_CleanedData) elif method == "POST": return handle_send(_CleanedData) elif method == "PATCH": return handle_mark_read(_CleanedData) elif method == "DELETE": return handle_delete(_CleanedData) return {"code": 405, "msg": "方法不允许"}, 405 def handle_get(_CleanedData): action = flask.request.args.get("action", "unread_count") if action == "unread_count": return get_unread_count(_CleanedData) elif action == "list": return get_message_list(_CleanedData) elif action == "detail": return get_message_detail(_CleanedData) elif action == "search_recipients": return search_recipients(_CleanedData) return {"code": 1, "msg": "未知操作"}, 400 def _get_current_user(): current_user = UGM.GetELTUser() if not current_user: return None return GERPUser.query.filter(GERPUser.UserUUID == current_user.UserUUID).first() def _format_msg(msg, user_tz=None): if user_tz is None: user_tz = FormData.get_user_timezone() sender_name = "系统" if msg.SenderUUID: sender = GERPUser.query.filter(GERPUser.UserUUID == msg.SenderUUID).first() if sender: sender_name = sender.UserName return { "MessageUUID": str(UUIDObj(msg.MessageUUID)), "Title": msg.Title, "Content": msg.Content[:100] if msg.Content else "", "MsgType": msg.MsgType, "IsRead": msg.IsRead, "SenderName": sender_name, "RelatedUUID": msg.RelatedUUID or "", "RelatedType": msg.RelatedType or "", "CreateTime": FormData.utc_to_user_tz(msg.CreateTime, user_tz).strftime("%Y-%m-%d %H:%M:%S") if msg.CreateTime else "", } def get_unread_count(_CleanedData): user = _get_current_user() if not user: return {"code": 0, "unreadCount": 0, "recentMessages": []}, 200 user_uuid_bytes = user.UserUUID count = GERPMessage.query.filter( GERPMessage.ReceiverUUID == user_uuid_bytes, GERPMessage.IsRead == 0 ).count() recent = GERPMessage.query.filter( GERPMessage.ReceiverUUID == user_uuid_bytes, GERPMessage.IsRead == 0 ).order_by(GERPMessage.CreateTime.desc()).limit(5).all() user_tz = FormData.get_user_timezone() messages = [_format_msg(msg, user_tz) for msg in recent] return { "code": 0, "unreadCount": count, "recentMessages": messages, }, 200 def get_message_list(_CleanedData): user = _get_current_user() if not user: return {"code": 0, "total": 0, "data": []}, 200 user_uuid_bytes = user.UserUUID page_index = max(flask.request.args.get("PageIndex", 1, type=int), 1) page_size = min(flask.request.args.get("PageSize", 20, type=int), 100) is_read = flask.request.args.get("IsRead", None) msg_type = flask.request.args.get("MsgType", None) query = GERPMessage.query.filter(GERPMessage.ReceiverUUID == user_uuid_bytes) if is_read is not None: try: query = query.filter(GERPMessage.IsRead == int(is_read)) except ValueError: pass if msg_type is not None: try: query = query.filter(GERPMessage.MsgType == int(msg_type)) except ValueError: pass query = query.order_by(GERPMessage.CreateTime.desc()) pagination = query.paginate(page=page_index, per_page=page_size, error_out=False) user_tz = FormData.get_user_timezone() messages = [] for msg in pagination.items: item = _format_msg(msg, user_tz) item["Content"] = msg.Content messages.append(item) return { "code": 0, "total": pagination.total, "data": messages, }, 200 def get_message_detail(_CleanedData): user = _get_current_user() if not user: return {"code": 401, "msg": "未登录"}, 401 msg_uuid_str = flask.request.args.get("MessageUUID", "") if not msg_uuid_str: return {"code": 1, "msg": "缺少MessageUUID"}, 400 try: msg_uuid_bytes = UUIDObj(msg_uuid_str).bytes except ValueError: return {"code": 1, "msg": "无效的MessageUUID"}, 400 msg = GERPMessage.query.filter(GERPMessage.MessageUUID == msg_uuid_bytes).first() if not msg: return {"code": 1, "msg": "消息不存在"}, 404 if msg.IsRead == 0: msg.IsRead = 1 db.session.commit() user_tz = FormData.get_user_timezone() item = _format_msg(msg, user_tz) item["Content"] = msg.Content return {"code": 0, "data": item}, 200 def handle_send(_CleanedData): user = _get_current_user() if not user: return {"code": 401, "msg": "未登录"}, 401 data = flask.request.form if flask.request.form else flask.request.get_json(silent=True) or {} receiver_uuid_str = data.get("ReceiverUUID", "") receiver_type = data.get("ReceiverType", "user") title = data.get("Title", "") content = data.get("Content", "") msg_type = data.get("MsgType", 3) related_uuid = data.get("RelatedUUID", "") related_type = data.get("RelatedType", "") if not receiver_uuid_str: return {"code": 1, "msg": "缺少接收人"}, 400 if not title: return {"code": 1, "msg": "缺少标题"}, 400 try: msg_type = int(msg_type) except (ValueError, TypeError): msg_type = 3 sender_uuid_bytes = user.UserUUID if receiver_type == "role": try: role_uuid_bytes = UUIDObj(receiver_uuid_str).bytes except ValueError: return {"code": 1, "msg": "无效的角色UUID"}, 400 role = GERPRole.query.filter(GERPRole.RoleUUID == role_uuid_bytes).first() if not role: return {"code": 1, "msg": "角色不存在"}, 400 members = UserRole.query.filter(UserRole.RoleUUID == role_uuid_bytes).all() if not members: return {"code": 1, "msg": "该角色下没有成员"}, 400 sent_count = 0 for member in members: msg = GERPMessage( MessageUUID=uuid.uuid4().bytes, SenderUUID=sender_uuid_bytes, ReceiverUUID=member.UserUUID, Title=title, Content=content, MsgType=msg_type, IsRead=0, RelatedUUID=related_uuid, RelatedType=related_type, CreateTime=datetime.datetime.utcnow(), ) db.session.add(msg) sent_count += 1 db.session.commit() return {"code": 0, "msg": f"已发送给{sent_count}人", "sentCount": sent_count}, 200 else: try: receiver_uuid_bytes = UUIDObj(receiver_uuid_str).bytes except ValueError: return {"code": 1, "msg": "无效的接收人UUID"}, 400 receiver = GERPUser.query.filter(GERPUser.UserUUID == receiver_uuid_bytes).first() if not receiver: return {"code": 1, "msg": "接收人不存在"}, 400 msg = GERPMessage( MessageUUID=uuid.uuid4().bytes, SenderUUID=sender_uuid_bytes, ReceiverUUID=receiver_uuid_bytes, Title=title, Content=content, MsgType=msg_type, IsRead=0, RelatedUUID=related_uuid, RelatedType=related_type, CreateTime=datetime.datetime.utcnow(), ) db.session.add(msg) db.session.commit() return {"code": 0, "msg": "发送成功", "MessageUUID": str(UUIDObj(msg.MessageUUID))}, 200 def handle_mark_read(_CleanedData): user = _get_current_user() if not user: return {"code": 401, "msg": "未登录"}, 401 data = flask.request.form if flask.request.form else flask.request.get_json(silent=True) or {} action = data.get("action", "") if action == "read_all": user_uuid_bytes = user.UserUUID GERPMessage.query.filter( GERPMessage.ReceiverUUID == user_uuid_bytes, GERPMessage.IsRead == 0 ).update({"IsRead": 1}) db.session.commit() return {"code": 0, "msg": "已全部标记为已读"}, 200 msg_uuid_str = data.get("MessageUUID", "") if msg_uuid_str: try: msg_uuid_bytes = UUIDObj(msg_uuid_str).bytes msg = GERPMessage.query.filter(GERPMessage.MessageUUID == msg_uuid_bytes).first() if msg: msg.IsRead = 1 db.session.commit() return {"code": 0, "msg": "已标记为已读"}, 200 except ValueError: pass return {"code": 1, "msg": "缺少MessageUUID或action"}, 400 def handle_delete(_CleanedData): current_user = UGM.GetELTUser() if not current_user: return {"code": 401, "msg": "未登录"}, 401 data = flask.request.get_json(silent=True) or {} msg_uuid_str = data.get("MessageUUID", "") if not msg_uuid_str: return {"code": 1, "msg": "缺少MessageUUID"}, 400 try: msg_uuid_bytes = UUIDObj(msg_uuid_str).bytes except ValueError: return {"code": 1, "msg": "无效的MessageUUID"}, 400 msg = GERPMessage.query.filter(GERPMessage.MessageUUID == msg_uuid_bytes).first() if not msg: return {"code": 1, "msg": "消息不存在"}, 404 if msg.ReceiverUUID != current_user.UserUUID: return {"code": 403, "msg": "无权删除此消息"}, 403 try: db.session.delete(msg) db.session.commit() except Exception as e: db.session.rollback() return {"code": 500, "msg": f"删除失败: {str(e)}"}, 500 return {"code": 0, "msg": "已删除"}, 200 def search_recipients(_CleanedData): user = _get_current_user() if not user: return {"code": 0, "data": []}, 200 keyword = flask.request.args.get("keyword", "").strip() if not keyword or len(keyword) < 1: return {"code": 0, "data": []}, 200 limit = min(max(int(flask.request.args.get("limit", 10)), 1), 30) pattern = f"%{keyword}%" results = [] users = GERPUser.query.filter( db.or_( GERPUser.UserName.like(pattern), GERPUser.UserEmail.like(pattern) ) ).limit(limit).all() for u in users: results.append({ "type": "user", "uuid": str(UUIDObj(u.UserUUID)), "name": u.UserName, "email": u.UserEmail or "", "label": u.UserName + (f" ({u.UserEmail})" if u.UserEmail else ""), }) roles = GERPRole.query.filter( GERPRole.RoleName.like(pattern) ).limit(limit).all() for r in roles: role_uuid_str = str(UUIDObj(r.RoleUUID)) member_count = UserRole.query.filter(UserRole.RoleUUID == r.RoleUUID).count() results.append({ "type": "role", "uuid": role_uuid_str, "name": r.RoleName, "memberCount": member_count, "label": f"[角色] {r.RoleName} ({member_count}人)", }) return {"code": 0, "data": results}, 200