From 98c529af09624ba80480321902aac6aab330f302 Mon Sep 17 00:00:00 2001 From: yunlongJia Date: Thu, 26 Dec 2024 18:36:06 +0800 Subject: [PATCH 1/8] =?UTF-8?q?feat:=E8=8E=B7=E5=8F=96=E6=88=90=E5=91=98?= =?UTF-8?q?=E5=8A=A0=E5=85=A5=E7=94=A8=E6=88=B7=E7=BB=84=E7=9A=84=E6=97=B6?= =?UTF-8?q?=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- saas/backend/api/management/v2/serializers.py | 1 + saas/backend/api/management/v2/views/group.py | 2 +- saas/backend/biz/group.py | 4 +++- saas/backend/util/time.py | 8 ++++++++ 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/saas/backend/api/management/v2/serializers.py b/saas/backend/api/management/v2/serializers.py index 19a222065..eaad5f30b 100644 --- a/saas/backend/api/management/v2/serializers.py +++ b/saas/backend/api/management/v2/serializers.py @@ -167,6 +167,7 @@ class ManagementGroupMemberSLZ(serializers.Serializer): id = serializers.CharField(label="成员id") name = serializers.CharField(label="名称") expired_at = serializers.IntegerField(label="过期时间戳(单位秒)") + created_at = serializers.IntegerField(label="创建时间戳(单位秒)") class ManagementGroupMemberDeleteSLZ(serializers.Serializer): diff --git a/saas/backend/api/management/v2/views/group.py b/saas/backend/api/management/v2/views/group.py index 2e0801901..3318c22c2 100644 --- a/saas/backend/api/management/v2/views/group.py +++ b/saas/backend/api/management/v2/views/group.py @@ -362,7 +362,7 @@ def list(self, request, *args, **kwargs): limit, offset = CompatiblePagination().get_limit_offset_pair(request) count, group_members = self.biz.list_paging_thin_group_member(group.id, limit, offset) - results = [one.dict(include={"type", "id", "name", "expired_at"}) for one in group_members] + results = [one.dict(include={"type", "id", "name", "expired_at", "created_at"}) for one in group_members] return Response({"count": count, "results": results}) @swagger_auto_schema( diff --git a/saas/backend/biz/group.py b/saas/backend/biz/group.py index 5a131bd45..a8bf331a9 100644 --- a/saas/backend/biz/group.py +++ b/saas/backend/biz/group.py @@ -46,7 +46,7 @@ from backend.service.subject_template import SubjectTemplateService from backend.service.system import SystemService from backend.service.template import TemplateService -from backend.util.time import utc_string_to_local +from backend.util.time import utc_string_to_local, utc_string_to_local_timestamp from backend.util.uuid import gen_uuid from .action import ActionCheckBiz, ActionResourceGroupForCheck @@ -93,6 +93,7 @@ class GroupMemberBean(BaseModel): expired_at: int expired_at_display: str created_time: datetime + created_at: int # 从部门继承的信息 department_id: int = 0 @@ -614,6 +615,7 @@ def _convert_to_thin_group_members(self, relations: List[SubjectGroup]) -> List[ expired_at=relation.expired_at, expired_at_display=expired_at_display(relation.expired_at), created_time=utc_string_to_local(relation.created_at), + created_at=utc_string_to_local_timestamp(relation.created_at), **subject_info.dict(), ) group_member_beans.append(group_member_bean) diff --git a/saas/backend/util/time.py b/saas/backend/util/time.py index ed53eeba1..e4267a1e1 100644 --- a/saas/backend/util/time.py +++ b/saas/backend/util/time.py @@ -56,3 +56,11 @@ def format_localtime(fmt="%Y%m%d%H%M%S"): """ t = time.strftime(fmt, time.localtime()) return t + + +def utc_string_to_local_timestamp(str_time: str) -> int: + """ + utc字符时间转换未本地时间戳 + """ + t = utc_string_to_local(str_time) + return int(t.timestamp()) From 7e191318da2ea9f10e3e73c3beb35f7a6db6003c Mon Sep 17 00:00:00 2001 From: yunlongJia Date: Fri, 27 Dec 2024 17:33:34 +0800 Subject: [PATCH 2/8] =?UTF-8?q?fix:=E9=A1=B5=E9=9D=A2=E5=B1=95=E7=A4=BA?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E5=8A=A0=E5=85=A5=E7=94=A8=E6=88=B7=E7=BB=84?= =?UTF-8?q?=E7=9A=84=E6=9C=89=E6=95=88=E6=9C=9F=E7=9B=B8=E5=B7=AE8?= =?UTF-8?q?=E5=B0=8F=E6=97=B6=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- saas/backend/api/management/v2/views/subject.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/saas/backend/api/management/v2/views/subject.py b/saas/backend/api/management/v2/views/subject.py index 12cadbb2c..3a863075f 100644 --- a/saas/backend/api/management/v2/views/subject.py +++ b/saas/backend/api/management/v2/views/subject.py @@ -31,7 +31,7 @@ from backend.component.iam import list_subject_groups_detail from backend.service.constants import GroupMemberType from backend.service.models import Subject -from backend.util.time import utc_string_to_timestamp +from backend.util.time import utc_string_to_local_timestamp class ManagementUserGroupBelongViewSet(GenericViewSet): @@ -139,7 +139,7 @@ def _get_subject_group_dict(subject: Subject, group_ids: List[int]) -> Dict[int, return { int(one["id"]): { "expired_at": one["expired_at"], - "created_at": utc_string_to_timestamp(one["created_at"]), + "created_at": utc_string_to_local_timestamp(one["created_at"]), } for one in groups } @@ -174,7 +174,7 @@ def list(self, request, *args, **kwargs): subject_group_map = { i.group_id: { "expired_at": i.expired_at, - "created_at": int(i.created_time.timestamp()), + "created_at": utc_string_to_local_timestamp(i.created_time), } for i in template_groups } From 33441f6ec87c7497f73458dbb47162c5f1afdee5 Mon Sep 17 00:00:00 2001 From: yunlongJia Date: Wed, 8 Jan 2025 15:17:04 +0800 Subject: [PATCH 3/8] =?UTF-8?q?feat:=E8=8E=B7=E5=8F=96=E6=88=90=E5=91=98?= =?UTF-8?q?=E5=8A=A0=E5=85=A5=E7=94=A8=E6=88=B7=E7=BB=84=E7=9A=84=E6=97=B6?= =?UTF-8?q?=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- saas/backend/api/management/v2/serializers.py | 2 +- saas/backend/api/management/v2/views/group.py | 4 +++- saas/backend/biz/group.py | 4 +--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/saas/backend/api/management/v2/serializers.py b/saas/backend/api/management/v2/serializers.py index eaad5f30b..5ea8fa0dd 100644 --- a/saas/backend/api/management/v2/serializers.py +++ b/saas/backend/api/management/v2/serializers.py @@ -167,7 +167,7 @@ class ManagementGroupMemberSLZ(serializers.Serializer): id = serializers.CharField(label="成员id") name = serializers.CharField(label="名称") expired_at = serializers.IntegerField(label="过期时间戳(单位秒)") - created_at = serializers.IntegerField(label="创建时间戳(单位秒)") + created_time = serializers.IntegerField(label="创建时间戳(单位秒)") class ManagementGroupMemberDeleteSLZ(serializers.Serializer): diff --git a/saas/backend/api/management/v2/views/group.py b/saas/backend/api/management/v2/views/group.py index 3318c22c2..d1dc38134 100644 --- a/saas/backend/api/management/v2/views/group.py +++ b/saas/backend/api/management/v2/views/group.py @@ -362,7 +362,9 @@ def list(self, request, *args, **kwargs): limit, offset = CompatiblePagination().get_limit_offset_pair(request) count, group_members = self.biz.list_paging_thin_group_member(group.id, limit, offset) - results = [one.dict(include={"type", "id", "name", "expired_at", "created_at"}) for one in group_members] + results = [one.dict(include={"type", "id", "name", "expired_at", "created_time"}) for one in group_members] + for result in results: + result['created_time'] = int(result['created_time'].timestamp()) return Response({"count": count, "results": results}) @swagger_auto_schema( diff --git a/saas/backend/biz/group.py b/saas/backend/biz/group.py index a8bf331a9..5a131bd45 100644 --- a/saas/backend/biz/group.py +++ b/saas/backend/biz/group.py @@ -46,7 +46,7 @@ from backend.service.subject_template import SubjectTemplateService from backend.service.system import SystemService from backend.service.template import TemplateService -from backend.util.time import utc_string_to_local, utc_string_to_local_timestamp +from backend.util.time import utc_string_to_local from backend.util.uuid import gen_uuid from .action import ActionCheckBiz, ActionResourceGroupForCheck @@ -93,7 +93,6 @@ class GroupMemberBean(BaseModel): expired_at: int expired_at_display: str created_time: datetime - created_at: int # 从部门继承的信息 department_id: int = 0 @@ -615,7 +614,6 @@ def _convert_to_thin_group_members(self, relations: List[SubjectGroup]) -> List[ expired_at=relation.expired_at, expired_at_display=expired_at_display(relation.expired_at), created_time=utc_string_to_local(relation.created_at), - created_at=utc_string_to_local_timestamp(relation.created_at), **subject_info.dict(), ) group_member_beans.append(group_member_bean) From 7440b93261b9d51351ae75437382d65b24caa22c Mon Sep 17 00:00:00 2001 From: yunlongJia Date: Wed, 8 Jan 2025 15:19:04 +0800 Subject: [PATCH 4/8] =?UTF-8?q?fix:=E7=94=A8=E6=88=B7=E5=8A=A0=E5=85=A5?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E7=BB=84=E7=9A=84=E6=9C=89=E6=95=88=E6=9C=9F?= =?UTF-8?q?=E7=9B=B8=E5=B7=AE8=E5=B0=8F=E6=97=B6=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- saas/backend/api/management/v2/views/subject.py | 6 +++--- saas/backend/util/time.py | 11 ++--------- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/saas/backend/api/management/v2/views/subject.py b/saas/backend/api/management/v2/views/subject.py index 3a863075f..12cadbb2c 100644 --- a/saas/backend/api/management/v2/views/subject.py +++ b/saas/backend/api/management/v2/views/subject.py @@ -31,7 +31,7 @@ from backend.component.iam import list_subject_groups_detail from backend.service.constants import GroupMemberType from backend.service.models import Subject -from backend.util.time import utc_string_to_local_timestamp +from backend.util.time import utc_string_to_timestamp class ManagementUserGroupBelongViewSet(GenericViewSet): @@ -139,7 +139,7 @@ def _get_subject_group_dict(subject: Subject, group_ids: List[int]) -> Dict[int, return { int(one["id"]): { "expired_at": one["expired_at"], - "created_at": utc_string_to_local_timestamp(one["created_at"]), + "created_at": utc_string_to_timestamp(one["created_at"]), } for one in groups } @@ -174,7 +174,7 @@ def list(self, request, *args, **kwargs): subject_group_map = { i.group_id: { "expired_at": i.expired_at, - "created_at": utc_string_to_local_timestamp(i.created_time), + "created_at": int(i.created_time.timestamp()), } for i in template_groups } diff --git a/saas/backend/util/time.py b/saas/backend/util/time.py index e4267a1e1..ed93a3a39 100644 --- a/saas/backend/util/time.py +++ b/saas/backend/util/time.py @@ -12,6 +12,7 @@ import time from django.utils import timezone +from dateutil import parser def string_to_datetime(str_time, fmt="%Y-%m-%d %H:%M:%S"): @@ -33,7 +34,7 @@ def utc_string_to_timestamp(str_time: str) -> int: """ 后端UTC时间转换为时间戳 """ - t = string_to_datetime(str_time, fmt="%Y-%m-%dT%H:%M:%SZ") + t = parser.isoparse(str_time) return int(t.timestamp()) @@ -56,11 +57,3 @@ def format_localtime(fmt="%Y%m%d%H%M%S"): """ t = time.strftime(fmt, time.localtime()) return t - - -def utc_string_to_local_timestamp(str_time: str) -> int: - """ - utc字符时间转换未本地时间戳 - """ - t = utc_string_to_local(str_time) - return int(t.timestamp()) From ffb7bcfdca494f40441bf3e14e6e8b98868d0653 Mon Sep 17 00:00:00 2001 From: yunlongJia Date: Wed, 8 Jan 2025 15:21:22 +0800 Subject: [PATCH 5/8] =?UTF-8?q?add:=E6=96=B0=E5=A2=9Eutc=5Fstring=5Fto=5Ft?= =?UTF-8?q?imestamp=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- saas/tests/util/time_tests.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 saas/tests/util/time_tests.py diff --git a/saas/tests/util/time_tests.py b/saas/tests/util/time_tests.py new file mode 100644 index 000000000..11cc8c463 --- /dev/null +++ b/saas/tests/util/time_tests.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +""" +TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-权限中心(BlueKing-IAM) available. +Copyright (C) 2017-2021 THL A29 Limited, a Tencent company. All rights reserved. +Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. +You may obtain a copy of the License at http://opensource.org/licenses/MIT +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on +an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. +""" +import pytest + +from backend.util.time import utc_string_to_timestamp + + +@pytest.mark.parametrize( + "utc_string, expected", + [ + ("2025-01-07T08:41:18Z", 1736239278), + ("2025-01-07T09:03:44Z", 1736240624), + ("2025-01-02T10:00:15Z", 1735812015), + ("2025-01-08T03:42:02Z", 1736307722), + ], +) +def test_utc_string_to_timestamp(utc_string: str, expected: int): + assert utc_string_to_timestamp(utc_string) == expected From 13c4e816ecc85a396107603678f238796f021b7c Mon Sep 17 00:00:00 2001 From: yunlongJia Date: Wed, 8 Jan 2025 16:17:20 +0800 Subject: [PATCH 6/8] =?UTF-8?q?fix:=E4=BF=AE=E5=A4=8Dflake8=E6=A0=A1?= =?UTF-8?q?=E9=AA=8C=E5=A4=B1=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- saas/backend/util/time.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/saas/backend/util/time.py b/saas/backend/util/time.py index ed93a3a39..a5ce1e893 100644 --- a/saas/backend/util/time.py +++ b/saas/backend/util/time.py @@ -12,7 +12,7 @@ import time from django.utils import timezone -from dateutil import parser +from dateutil import parser # type: ignore def string_to_datetime(str_time, fmt="%Y-%m-%d %H:%M:%S"): From f132ec59ed18a8a01edc9849ba87d2a473c5bdf9 Mon Sep 17 00:00:00 2001 From: yunlongJia Date: Thu, 9 Jan 2025 09:51:18 +0800 Subject: [PATCH 7/8] =?UTF-8?q?update:=E6=9B=B4=E6=96=B0=E6=97=B6=E9=97=B4?= =?UTF-8?q?=E5=A4=84=E7=90=86=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- saas/backend/api/management/v2/serializers.py | 2 +- saas/backend/api/management/v2/views/group.py | 2 +- saas/backend/util/time.py | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/saas/backend/api/management/v2/serializers.py b/saas/backend/api/management/v2/serializers.py index 5ea8fa0dd..eaad5f30b 100644 --- a/saas/backend/api/management/v2/serializers.py +++ b/saas/backend/api/management/v2/serializers.py @@ -167,7 +167,7 @@ class ManagementGroupMemberSLZ(serializers.Serializer): id = serializers.CharField(label="成员id") name = serializers.CharField(label="名称") expired_at = serializers.IntegerField(label="过期时间戳(单位秒)") - created_time = serializers.IntegerField(label="创建时间戳(单位秒)") + created_at = serializers.IntegerField(label="创建时间戳(单位秒)") class ManagementGroupMemberDeleteSLZ(serializers.Serializer): diff --git a/saas/backend/api/management/v2/views/group.py b/saas/backend/api/management/v2/views/group.py index d1dc38134..3f948eaa5 100644 --- a/saas/backend/api/management/v2/views/group.py +++ b/saas/backend/api/management/v2/views/group.py @@ -364,7 +364,7 @@ def list(self, request, *args, **kwargs): count, group_members = self.biz.list_paging_thin_group_member(group.id, limit, offset) results = [one.dict(include={"type", "id", "name", "expired_at", "created_time"}) for one in group_members] for result in results: - result['created_time'] = int(result['created_time'].timestamp()) + result['created_at'] = int(result.pop('created_time').timestamp()) return Response({"count": count, "results": results}) @swagger_auto_schema( diff --git a/saas/backend/util/time.py b/saas/backend/util/time.py index a5ce1e893..341e3c6f5 100644 --- a/saas/backend/util/time.py +++ b/saas/backend/util/time.py @@ -12,7 +12,6 @@ import time from django.utils import timezone -from dateutil import parser # type: ignore def string_to_datetime(str_time, fmt="%Y-%m-%d %H:%M:%S"): @@ -34,8 +33,9 @@ def utc_string_to_timestamp(str_time: str) -> int: """ 后端UTC时间转换为时间戳 """ - t = parser.isoparse(str_time) - return int(t.timestamp()) + naive_t = string_to_datetime(str_time, fmt="%Y-%m-%dT%H:%M:%SZ") + aware_t = naive_t.replace(tzinfo=datetime.timezone.utc) + return int(aware_t.timestamp()) def utc_to_local(utc_time): From c0a5d8cbe9206407dbfc9a09ed7495adaee7078a Mon Sep 17 00:00:00 2001 From: yunlongJia Date: Thu, 9 Jan 2025 11:09:48 +0800 Subject: [PATCH 8/8] =?UTF-8?q?add:=E6=B7=BB=E5=8A=A0=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- saas/backend/util/time.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/saas/backend/util/time.py b/saas/backend/util/time.py index 341e3c6f5..d61d854d9 100644 --- a/saas/backend/util/time.py +++ b/saas/backend/util/time.py @@ -33,7 +33,9 @@ def utc_string_to_timestamp(str_time: str) -> int: """ 后端UTC时间转换为时间戳 """ + # Note: 该转换后是 naive datetime,即不带时区 naive_t = string_to_datetime(str_time, fmt="%Y-%m-%dT%H:%M:%SZ") + # 由于 str_time 本身就是 utc 时间字符串,所以可以设置时区为 UTC,这样就得到 aware datetime aware_t = naive_t.replace(tzinfo=datetime.timezone.utc) return int(aware_t.timestamp())