Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: 修正组织架构导入模版字段名 & 区分不同功能导出文件名 & 修复用户删除与恢复逻辑 & 调整创建时间显示 #161

Merged
merged 1 commit into from
Nov 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/api/bkuser_core/common/viewset.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ def check_object_permissions(self, request, obj):
if not permission.has_object_permission(request, self, obj):
self.permission_denied(request, message=getattr(permission, "message", None), obj=obj)

def permission_denied(self, request, message=None, obj=None):
def permission_denied(self, request, message=None, obj=None, **kwargs):
"""针对 IAM 注入相关信息"""
raise IAMPermissionDenied(
detail=message,
Expand Down
16 changes: 11 additions & 5 deletions src/api/bkuser_core/profiles/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
specific language governing permissions and limitations under the License.
"""
import datetime
from typing import Optional

import jsonfield
from bkuser_core.audit.constants import LogInFailReason
Expand Down Expand Up @@ -181,20 +182,25 @@ def latest_password_update_time(self) -> datetime.datetime:
"""最近一次更新密码时间"""
return self.password_update_time or self.create_time

@property
def last_login_time(self) -> Optional[datetime.datetime]:
"""获取用户最近一次登录时间"""
latest_logins = self.login_set.filter(is_success=True)
if latest_logins:
return latest_logins.latest().create_time

return None

def enable(self):
self.enabled = True
self.status = ProfileStatus.NORMAL.value
self.save(update_fields=["enabled", "status", "update_time"])

def delete(self, using=None, keep_parents=False):
"""软删除"""
# 为了保证用户恢复时拥有原来所有关系,这里只修改状态字段
self.enabled = False
self.status = ProfileStatus.DELETED.value

# 解除与其他模型的绑定关系
self.departments.clear()
self.leader.clear()

self.save(update_fields=["enabled", "status", "update_time"])
return

Expand Down
20 changes: 2 additions & 18 deletions src/api/bkuser_core/profiles/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,7 @@ class ProfileSerializer(CustomFieldsModelSerializer):
departments = SimpleDepartmentSerializer(many=True, required=False)
extras = serializers.SerializerMethodField(required=False)
leader = LeaderSerializer(many=True, required=False)
last_login_time = serializers.SerializerMethodField(required=False, read_only=True)

def get_last_login_time(self, obj: "Profile") -> Optional[str]:
"""获取用户最近一次登录时间"""
latest_logins = obj.login_set.filter(is_success=True)
if latest_logins:
return latest_logins.latest().create_time

return None
last_login_time = serializers.DateTimeField(required=False, read_only=True)

def get_extras(self, obj) -> dict:
"""尝试从 context 中获取默认字段值"""
Expand All @@ -106,7 +98,7 @@ class RapidProfileSerializer(CustomFieldsMixin, serializers.Serializer):

departments = SimpleDepartmentSerializer(many=True, required=False)
leader = LeaderSerializer(many=True, required=False)
last_login_time = serializers.SerializerMethodField(required=False, read_only=True)
last_login_time = serializers.DateTimeField(required=False, read_only=True)

create_time = serializers.DateTimeField(required=False, read_only=True)
update_time = serializers.DateTimeField(required=False, read_only=True)
Expand All @@ -130,14 +122,6 @@ class RapidProfileSerializer(CustomFieldsMixin, serializers.Serializer):
status = serializers.CharField(read_only=True)
logo = serializers.CharField(read_only=True, allow_blank=True)

def get_last_login_time(self, obj: "Profile") -> Optional[str]:
"""获取用户最近一次登录时间"""
latest_logins = obj.login_set.filter(is_success=True)
if latest_logins:
return latest_logins.latest().create_time

return None

def get_extras(self, obj: "Profile") -> dict:
"""尝试从 context 中获取默认字段值"""
return get_extras(obj.extras, self.context.get("extra_defaults", {}).copy())
Expand Down
16 changes: 14 additions & 2 deletions src/pages/src/views/organization/details/UserMaterial.vue
Original file line number Diff line number Diff line change
Expand Up @@ -129,14 +129,14 @@
<span class="name">{{$t('创建时间')}}</span>
<span class="gap">:</span>
<p class="desc">
<span class="text">{{currentProfile.create_time}}</span>
<span class="text">{{currentProfile.create_time | convertIsoTime}}</span>
</p>
</div>
<div class="specific-text">
<span class="name">{{$t('最近一次登录时间')}}</span>
<span class="gap">:</span>
<p class="desc">
<span class="text">{{currentProfile.last_login_time}}</span>
<span class="text">{{currentProfile.last_login_time | convertIsoTime}}</span>
</p>
</div>
</li>
Expand All @@ -147,6 +147,18 @@

<script>
export default {
filters: {
convertIsoTime(iso) {
if (iso === null) {
return '--';
}

const arr = iso.split('T');
const year = arr[0];
const time = arr[1].split('.')[0];
return `${year} ${time}`;
},
},
directives: {
focus: {
// 输入框自动获焦
Expand Down
7 changes: 0 additions & 7 deletions src/pages/src/views/organization/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,6 @@ import PullUser from './table/PullUser';
import DetailsBar from './details/DetailsBar';

import SetDepartment from '@/components/organization/SetDepartment';
import moment from 'moment';

export default {
components: {
Expand Down Expand Up @@ -884,12 +883,6 @@ export default {

// 查看当前用户的信息
viewDetails(item) {
item.create_time = moment(item.create_time).format('YYYY-MM-DD HH:mm:ss');
if (item.last_login_time) {
item.last_login_time = moment(item.last_login_time).format('YYYY-MM-DD HH:mm:ss');
} else {
item.last_login_time = '--';
}
this.currentProfile = item;
this.detailsBarInfo.type = 'view';
this.detailsBarInfo.title = this.currentProfile.display_name;
Expand Down
2 changes: 1 addition & 1 deletion src/saas/bkuser_shell/audit/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def export(self, request, validated_data: dict):
)

exporter = ProfileExcelExporter(
load_workbook(settings.EXPORT_LOGIN_TEMPLATE), settings.EXPORT_EXCEL_FILENAME, fields, 1
load_workbook(settings.EXPORT_LOGIN_TEMPLATE), settings.EXPORT_EXCEL_FILENAME + "_login_audit", fields, 1
)

# TODO: remove step when #88 is done
Expand Down
5 changes: 3 additions & 2 deletions src/saas/bkuser_shell/categories/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ class CategoriesExportViewSet(BkUserApiViewSet):

@inject_serializer(query_in=CategoryExportSerializer, out=EmptySerializer, tags=["categories"])
def export(self, request, category_id, validated_data):
"""导出组织架构"""
api_instance = bkuser_sdk.CategoriesApi(self.get_api_client_by_request(request))
category = api_instance.v2_categories_read(lookup_field="id", lookup_value=category_id)

Expand All @@ -207,7 +208,7 @@ def export(self, request, category_id, validated_data):

fields = self.get_paging_results(field_api_instance.v2_dynamic_fields_list)
exporter = ProfileExcelExporter(
load_workbook(settings.EXPORT_ORG_TEMPLATE), settings.EXPORT_EXCEL_FILENAME, fields
load_workbook(settings.EXPORT_ORG_TEMPLATE), settings.EXPORT_EXCEL_FILENAME + "_org", fields
)
exporter.update_profiles(all_profiles)

Expand All @@ -219,7 +220,7 @@ def export_template(self, request, category_id):
api_instance = bkuser_sdk.DynamicFieldsApi(self.get_api_client_by_request(request))
fields = self.get_paging_results(api_instance.v2_dynamic_fields_list)
exporter = ProfileExcelExporter(
load_workbook(settings.EXPORT_ORG_TEMPLATE), settings.EXPORT_EXCEL_FILENAME, fields
load_workbook(settings.EXPORT_ORG_TEMPLATE), settings.EXPORT_EXCEL_FILENAME + "_org_tmpl", fields
)

return exporter.to_response()
Binary file modified src/saas/media/excel/export_org_tmpl.xlsx
Binary file not shown.