From 7f503e27b731af0524867281d6657c1b7a957ff5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8C=BF=E5=B0=8F=E5=A4=A9?= <1638245306@qq.com> Date: Tue, 20 Sep 2022 20:25:10 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=8F=98=E5=8C=96:=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=AF=BC=E5=87=BA=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/dvadmin/system/views/login.py | 10 +++ backend/dvadmin/system/views/user.py | 22 +++--- backend/dvadmin/utils/import_export_mixin.py | 67 ++++++++++++++----- backend/dvadmin/utils/viewset.py | 2 +- .../store/modules/d2admin/modules/account.js | 8 ++- 5 files changed, 79 insertions(+), 30 deletions(-) diff --git a/backend/dvadmin/system/views/login.py b/backend/dvadmin/system/views/login.py index 9df5669..faaa2ea 100644 --- a/backend/dvadmin/system/views/login.py +++ b/backend/dvadmin/system/views/login.py @@ -91,6 +91,16 @@ class LoginSerializer(TokenObtainPairSerializer): data["name"] = self.user.name data["userId"] = self.user.id data["avatar"] = self.user.avatar + dept = getattr(self.user, 'dept', None) + if dept: + data['dept_info'] = { + 'dept_id': dept.id, + 'dept_name': dept.name, + 'dept_key': dept.key + } + role = getattr(self.user, 'role', None) + if role: + data['role_info'] = role.values('id', 'name', 'key') request = self.context.get("request") request.user = self.user # 记录登录日志 diff --git a/backend/dvadmin/system/views/user.py b/backend/dvadmin/system/views/user.py index 5e2537c..c0aa72e 100644 --- a/backend/dvadmin/system/views/user.py +++ b/backend/dvadmin/system/views/user.py @@ -223,17 +223,17 @@ class UserViewSet(CustomModelViewSet): } search_fields = ["username", "name", "gender", "dept__name", "role__name"] # 导出 - export_field_label = [ - "用户账号", - "用户名称", - "用户邮箱", - "手机号码", - "用户性别", - "帐号状态", - "最后登录时间", - "部门名称", - "部门负责人", - ] + export_field_label = { + "username":"用户账号", + "name":"用户名称", + "email":"用户邮箱", + "mobile":"手机号码", + "gender":"用户性别", + "is_active":"帐号状态", + "last_login":"最后登录时间", + "dept_name":"部门名称", + "dept_owner":"部门负责人", + } export_serializer_class = ExportUserProfileSerializer # 导入 import_serializer_class = UserProfileImportSerializer diff --git a/backend/dvadmin/utils/import_export_mixin.py b/backend/dvadmin/utils/import_export_mixin.py index 1a35e34..ea64ba6 100644 --- a/backend/dvadmin/utils/import_export_mixin.py +++ b/backend/dvadmin/utils/import_export_mixin.py @@ -26,6 +26,21 @@ class ImportSerializerMixin: # 表格表头最大宽度,默认50个字符 export_column_width = 50 + def is_number(self,num): + try: + float(num) + return True + except ValueError: + pass + + try: + import unicodedata + unicodedata.numeric(num) + return True + except (TypeError, ValueError): + pass + return False + def get_string_len(self, string): """ 获取字符串最大长度 @@ -35,6 +50,8 @@ class ImportSerializerMixin: length = 4 if string is None: return length + if self.is_number(string): + return length for char in string: length += 2.1 if ord(char) > 256 else 1 return round(length, 1) if length <= self.export_column_width else self.export_column_width @@ -155,6 +172,21 @@ class ExportSerializerMixin: # 表格表头最大宽度,默认50个字符 export_column_width = 50 + def is_number(self,num): + try: + float(num) + return True + except ValueError: + pass + + try: + import unicodedata + unicodedata.numeric(num) + return True + except (TypeError, ValueError): + pass + return False + def get_string_len(self, string): """ 获取字符串最大长度 @@ -164,6 +196,8 @@ class ExportSerializerMixin: length = 4 if string is None: return length + if self.is_number(string): + return length for char in string: length += 2.1 if ord(char) > 256 else 1 return round(length, 1) if length <= self.export_column_width else self.export_column_width @@ -176,36 +210,35 @@ class ExportSerializerMixin: :param kwargs: :return: """ - assert self.export_field_label, "'%s' 请配置对应的导出模板字段。" % self.__class__.__name__ queryset = self.filter_queryset(self.get_queryset()) + assert self.export_field_label, "'%s' 请配置对应的导出模板字段。" % self.__class__.__name__ + assert self.export_serializer_class, "'%s' 请配置对应的导出序列化器。" % self.__class__.__name__ data = self.export_serializer_class(queryset, many=True).data # 导出excel 表 response = HttpResponse(content_type="application/msexcel") response["Access-Control-Expose-Headers"] = f"Content-Disposition" - response["Content-Disposition"] = f'attachment;filename={quote(str(f"导出{get_verbose_name(queryset)}.xlsx"))}' + response["content-disposition"] = f'attachment;filename={quote(str(f"导出{get_verbose_name(queryset)}.xlsx"))}' wb = Workbook() ws = wb.active - header_data = ["序号", *self.export_field_label] + header_data = ["序号", *self.export_field_label.values()] + hidden_header = ["#", *self.export_field_label.keys()] df_len_max = [self.get_string_len(ele) for ele in header_data] row = get_column_letter(len(self.export_field_label) + 1) column = 1 ws.append(header_data) for index, results in enumerate(data): results_list = [] - for inx, result in enumerate(results.values()): - # 布尔值进行更新 - if result is True: - result = "是" - elif result is False: - result = "否" - if isinstance(result, int): - result = str(result) - # 计算最大列宽度 - result_column_width = self.get_string_len(result) - if result_column_width > df_len_max[inx + 1]: - df_len_max[inx + 1] = result_column_width - - results_list.append(result) + for h_index, h_item in enumerate(hidden_header): + for key,val in results.items(): + if key == h_item: + if val is None or val=="": + results_list.append("") + else: + results_list.append(val) + # 计算最大列宽度 + result_column_width = self.get_string_len(val) + if h_index !=0 and result_column_width > df_len_max[h_index]: + df_len_max[h_index] = result_column_width ws.append([index + 1, *results_list]) column += 1 #  更新列宽 diff --git a/backend/dvadmin/utils/viewset.py b/backend/dvadmin/utils/viewset.py index 5e2008f..30ecc09 100644 --- a/backend/dvadmin/utils/viewset.py +++ b/backend/dvadmin/utils/viewset.py @@ -38,7 +38,7 @@ class CustomModelViewSet(ModelViewSet,ImportSerializerMixin,ExportSerializerMixi extra_filter_backends = [DataLevelPermissionsFilter] permission_classes = [CustomPermission] import_field_dict = {} - export_field_label = [] + export_field_label = {} def filter_queryset(self, queryset): for backend in set(set(self.filter_backends) | set(self.extra_filter_backends or [])): diff --git a/web/src/store/modules/d2admin/modules/account.js b/web/src/store/modules/d2admin/modules/account.js index e3f0d79..b934005 100644 --- a/web/src/store/modules/d2admin/modules/account.js +++ b/web/src/store/modules/d2admin/modules/account.js @@ -44,7 +44,13 @@ export default { util.cookies.set('token', res.access) util.cookies.set('refresh', res.refresh) // 设置 vuex 用户信息 - await dispatch('d2admin/user/set', { name: res.name, user_id: res.userId, avatar: res.avatar }, { root: true }) + await dispatch('d2admin/user/set', { + name: res.name, + user_id: res.userId, + avatar: res.avatar, + role_info: res.role_info, + dept_info: res.dept_info + }, { root: true }) // 用户登录后从持久化数据加载一系列的设置 await dispatch('load') },