From 8ba1eedb470fc7eea23a631a549fc5b0df2ed8a5 Mon Sep 17 00:00:00 2001 From: awu0403 <76416779+awu0403@users.noreply.github.com> Date: Tue, 11 Mar 2025 11:01:40 +0800 Subject: [PATCH] Add org last activity time (#7575) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * update * optimize code * update ui --------- Co-authored-by: 孙永强 <11704063+s-yongqiang@user.noreply.gitee.com> --- frontend/src/pages/sys-admin/orgs/orgs-content.js | 9 +++++++-- seahub/api2/endpoints/admin/organizations.py | 11 ++++++++++- seahub/auth/__init__.py | 6 ++++++ seahub/base/models.py | 12 ++++++++++++ seahub/organizations/signals.py | 1 + 5 files changed, 36 insertions(+), 3 deletions(-) diff --git a/frontend/src/pages/sys-admin/orgs/orgs-content.js b/frontend/src/pages/sys-admin/orgs/orgs-content.js index e53a407299..82965bd73b 100644 --- a/frontend/src/pages/sys-admin/orgs/orgs-content.js +++ b/frontend/src/pages/sys-admin/orgs/orgs-content.js @@ -38,6 +38,7 @@ class Content extends Component { render() { const { loading, errorMsg, items } = this.props; + const colCreatedText = `${gettext('Created At')} / ${gettext('Last Access')}`; if (loading) { return ; } else if (errorMsg) { @@ -57,7 +58,7 @@ class Content extends Component { {gettext('Status')} {gettext('Role')} {gettext('Space Used')} - {gettext('Created At')} + {colCreatedText} {/* Operations */} @@ -255,7 +256,11 @@ class Item extends Component { /> {`${Utils.bytesToSize(item.quota_usage)} / ${item.quota > 0 ? Utils.bytesToSize(item.quota) : '--'}`} - {dayjs(item.ctime).format('YYYY-MM-DD HH:mm:ss')} + + {`${dayjs(item.ctime).format('YYYY-MM-DD HH:mm:ss')} /`} +
+ {`${item.last_activity_time ? dayjs(item.last_activity_time).fromNow() : '--'} `} + diff --git a/seahub/api2/endpoints/admin/organizations.py b/seahub/api2/endpoints/admin/organizations.py index 85b86af096..f254682c2f 100644 --- a/seahub/api2/endpoints/admin/organizations.py +++ b/seahub/api2/endpoints/admin/organizations.py @@ -15,10 +15,11 @@ from seahub.auth.utils import get_virtual_id_by_email from seahub.organizations.settings import ORG_MEMBER_QUOTA_DEFAULT from seahub.utils import is_valid_email from seahub.utils.file_size import get_file_size_unit -from seahub.utils.timeutils import timestamp_to_isoformat_timestr +from seahub.utils.timeutils import timestamp_to_isoformat_timestr, datetime_to_isoformat_timestr from seahub.base.templatetags.seahub_tags import email2nickname, \ email2contact_email from seahub.base.accounts import User +from seahub.base.models import OrgLastActivityTime from seahub.api2.authentication import TokenAuthentication from seahub.api2.throttling import UserRateThrottle from seahub.api2.utils import api_error @@ -177,8 +178,16 @@ class AdminOrganizations(APIView): return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) result = [] + org_ids = [org.org_id for org in orgs] + orgs_last_activity = OrgLastActivityTime.objects.filter(org_id__in=org_ids) + orgs_last_activity_dict = {org.org_id:org.timestamp for org in orgs_last_activity} for org in orgs: org_info = get_org_info(org) + org_id = org_info['org_id'] + if org_id in orgs_last_activity_dict: + org_info['last_activity_time'] = datetime_to_isoformat_timestr(orgs_last_activity_dict[org_id]) + else: + org_info['last_activity_time'] = None result.append(org_info) return Response({'organizations': result, 'total_count': total_count}) diff --git a/seahub/auth/__init__.py b/seahub/auth/__init__.py index b69abacf6a..da3fcc025d 100644 --- a/seahub/auth/__init__.py +++ b/seahub/auth/__init__.py @@ -7,8 +7,10 @@ from django.conf import settings from django.core.exceptions import ImproperlyConfigured from seahub.auth.signals import user_logged_in +from seahub.organizations.signals import org_last_activity from constance import config +from seaserv import ccnet_api SESSION_KEY = '_auth_user_name' BACKEND_SESSION_KEY = '_auth_user_backend_2' @@ -106,6 +108,10 @@ def login(request, user, mobile_login=False): if hasattr(request, 'user'): request.user = user user_logged_in.send(sender=user.__class__, request=request, user=user) + orgs = ccnet_api.get_orgs_by_user(user.username) + if orgs: + org_id = orgs[0].org_id + org_last_activity.send(sender=user.__class__, org_id=org_id) def logout(request): """ diff --git a/seahub/base/models.py b/seahub/base/models.py index 052c5e8819..97c5f9f676 100644 --- a/seahub/base/models.py +++ b/seahub/base/models.py @@ -9,6 +9,7 @@ from pysearpc import SearpcError from seaserv import seafile_api from seahub.auth.signals import user_logged_in +from seahub.organizations.signals import org_last_activity from seahub.utils import within_time_range, gen_token, \ normalize_file_path, normalize_dir_path from seahub.utils.timeutils import datetime_to_isoformat_timestr @@ -305,6 +306,17 @@ def update_last_login(sender, user, **kwargs): user_logged_in.connect(update_last_login) +class OrgLastActivityTime(models.Model): + org_id = models.IntegerField(unique=True, db_index=True) + timestamp = models.DateTimeField(default=timezone.now) + + class Meta: + db_table = 'org_last_active_time' + +def update_org_last_activity_time(sender, org_id, **kwargs): + OrgLastActivityTime.objects.update_or_create(org_id=org_id, defaults={'timestamp': timezone.now}) + +org_last_activity.connect(update_org_last_activity_time) class CommandsLastCheck(models.Model): """Record last check time for Django/custom commands. diff --git a/seahub/organizations/signals.py b/seahub/organizations/signals.py index e07618bbfa..2bb6788311 100644 --- a/seahub/organizations/signals.py +++ b/seahub/organizations/signals.py @@ -3,3 +3,4 @@ from django.dispatch import Signal # A new org is created org_created = Signal() +org_last_activity = Signal()