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:
@@ -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>
|
||||||
|
@@ -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})
|
||||||
|
@@ -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):
|
||||||
"""
|
"""
|
||||||
|
@@ -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.
|
||||||
|
@@ -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()
|
||||||
|
Reference in New Issue
Block a user