1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-25 14:50:29 +00:00

Add org last activity time (#7575)

* update

* optimize code

* update ui

---------

Co-authored-by: 孙永强 <11704063+s-yongqiang@user.noreply.gitee.com>
This commit is contained in:
awu0403
2025-03-11 11:01:40 +08:00
committed by GitHub
parent 0e7cc9f3c5
commit 8ba1eedb47
5 changed files with 36 additions and 3 deletions

View File

@@ -38,6 +38,7 @@ class Content extends Component {
render() { render() {
const { loading, errorMsg, items } = this.props; const { loading, errorMsg, items } = this.props;
const colCreatedText = `${gettext('Created At')} / ${gettext('Last Access')}`;
if (loading) { if (loading) {
return <Loading />; return <Loading />;
} else if (errorMsg) { } else if (errorMsg) {
@@ -57,7 +58,7 @@ class Content extends Component {
<th width="10%">{gettext('Status')}</th> <th width="10%">{gettext('Status')}</th>
<th width="20%">{gettext('Role')}</th> <th width="20%">{gettext('Role')}</th>
<th width="15%">{gettext('Space Used')}</th> <th width="15%">{gettext('Space Used')}</th>
<th width="20%">{gettext('Created At')}</th> <th width="20%">{colCreatedText}</th>
<th width="5%">{/* Operations */}</th> <th width="5%">{/* Operations */}</th>
</tr> </tr>
</thead> </thead>
@@ -255,7 +256,11 @@ class Item extends Component {
/> />
</td> </td>
<td>{`${Utils.bytesToSize(item.quota_usage)} / ${item.quota > 0 ? Utils.bytesToSize(item.quota) : '--'}`}</td> <td>{`${Utils.bytesToSize(item.quota_usage)} / ${item.quota > 0 ? Utils.bytesToSize(item.quota) : '--'}`}</td>
<td>{dayjs(item.ctime).format('YYYY-MM-DD HH:mm:ss')}</td> <td>
{`${dayjs(item.ctime).format('YYYY-MM-DD HH:mm:ss')} /`}
<br />
{`${item.last_activity_time ? dayjs(item.last_activity_time).fromNow() : '--'} `}
</td>
<td> <td>
<a href="#" className={`action-icon sf3-font-delete1 sf3-font ${highlighted ? '' : 'invisible'}`} title={gettext('Delete')} onClick={this.toggleDeleteDialog}></a> <a href="#" className={`action-icon sf3-font-delete1 sf3-font ${highlighted ? '' : 'invisible'}`} title={gettext('Delete')} onClick={this.toggleDeleteDialog}></a>
</td> </td>

View File

@@ -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.organizations.settings import ORG_MEMBER_QUOTA_DEFAULT
from seahub.utils import is_valid_email from seahub.utils import is_valid_email
from seahub.utils.file_size import get_file_size_unit 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, \ from seahub.base.templatetags.seahub_tags import email2nickname, \
email2contact_email email2contact_email
from seahub.base.accounts import User from seahub.base.accounts import User
from seahub.base.models import OrgLastActivityTime
from seahub.api2.authentication import TokenAuthentication from seahub.api2.authentication import TokenAuthentication
from seahub.api2.throttling import UserRateThrottle from seahub.api2.throttling import UserRateThrottle
from seahub.api2.utils import api_error 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) return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
result = [] 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: for org in orgs:
org_info = get_org_info(org) 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) result.append(org_info)
return Response({'organizations': result, 'total_count': total_count}) return Response({'organizations': result, 'total_count': total_count})

View File

@@ -7,8 +7,10 @@ from django.conf import settings
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from seahub.auth.signals import user_logged_in from seahub.auth.signals import user_logged_in
from seahub.organizations.signals import org_last_activity
from constance import config from constance import config
from seaserv import ccnet_api
SESSION_KEY = '_auth_user_name' SESSION_KEY = '_auth_user_name'
BACKEND_SESSION_KEY = '_auth_user_backend_2' BACKEND_SESSION_KEY = '_auth_user_backend_2'
@@ -106,6 +108,10 @@ def login(request, user, mobile_login=False):
if hasattr(request, 'user'): if hasattr(request, 'user'):
request.user = user request.user = user
user_logged_in.send(sender=user.__class__, request=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): def logout(request):
""" """

View File

@@ -9,6 +9,7 @@ from pysearpc import SearpcError
from seaserv import seafile_api from seaserv import seafile_api
from seahub.auth.signals import user_logged_in 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, \ from seahub.utils import within_time_range, gen_token, \
normalize_file_path, normalize_dir_path normalize_file_path, normalize_dir_path
from seahub.utils.timeutils import datetime_to_isoformat_timestr 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) 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): class CommandsLastCheck(models.Model):
"""Record last check time for Django/custom commands. """Record last check time for Django/custom commands.

View File

@@ -3,3 +3,4 @@ from django.dispatch import Signal
# A new org is created # A new org is created
org_created = Signal() org_created = Signal()
org_last_activity = Signal()