372 lines
11 KiB
Plaintext
372 lines
11 KiB
Plaintext
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
|