diff --git a/dvadmin-backend/apps/vadmin/logurus/test.py b/dvadmin-backend/apps/vadmin/logurus/test.py
new file mode 100644
index 0000000..d48c393
--- /dev/null
+++ b/dvadmin-backend/apps/vadmin/logurus/test.py
@@ -0,0 +1,31 @@
+from logging import StreamHandler, getLevelName
+from logging.handlers import RotatingFileHandler
+from typing import Optional, IO
+
+
+class MyStreamHandler(StreamHandler):
+
+    def __init__(self, stream: Optional[IO[str]] = ...) -> None:
+        print(222)
+        super().__init__(stream)
+
+    def __repr__(self):
+        level = getLevelName(self.level)
+        name = getattr(self.stream, 'name', '')
+        #  bpo-36015: name can be an int
+        name = str(name)
+        if name:
+            name += ' '
+        print(111)
+        return '<%s %s(%s)>' % (self.__class__.__name__, name, level)
+class MyRotatingFileHandler(RotatingFileHandler):
+
+    def __init__(self, filename: str, mode: str = ..., maxBytes: int = ..., backupCount: int = ...,
+                 encoding: Optional[str] = ..., delay: bool = ...) -> None:
+        print(4444)
+        super().__init__(filename, mode, maxBytes, backupCount, encoding, delay)
+
+    def __repr__(self):
+        level = getLevelName(self.level)
+        print(22)
+        return '<%s %s (%s)>' % (self.__class__.__name__, self.baseFilename, level)
diff --git a/dvadmin-backend/apps/vadmin/op_drf/mixins.py b/dvadmin-backend/apps/vadmin/op_drf/mixins.py
index cd9aba3..5bc65ef 100644
--- a/dvadmin-backend/apps/vadmin/op_drf/mixins.py
+++ b/dvadmin-backend/apps/vadmin/op_drf/mixins.py
@@ -1,3 +1,4 @@
+from django.db import transaction
 from rest_framework import mixins
 from rest_framework import serializers
 from rest_framework import status
@@ -5,6 +6,7 @@ from rest_framework.relations import ManyRelatedField, RelatedField, PrimaryKeyR
 from rest_framework.request import Request
 
 from .response import SuccessResponse
+from ..utils.export_excel import excel_to_data, export_excel_save_model
 
 
 class CreateModelMixin(mixins.CreateModelMixin):
@@ -271,3 +273,75 @@ class TableSerializerMixin:
                     info['type'] = 'select'
             column.append(info)
         return column
+
+
+class ImportSerializerMixin:
+    """
+    自定义导出模板、导入功能
+    """
+    # 导入字段
+    import_field_data = {}
+    # 导入序列化器
+    import_serializer_class = None
+
+
+    @transaction.atomic # Django 事物
+    def importTemplate(self, request: Request, *args, **kwargs):
+        """
+        用户导人模板
+        :param request:
+        :param args:
+        :param kwargs:
+        :return:
+        """
+        assert self.import_field_data, (
+                "'%s' 请配置对应的导出模板字段。"
+                % self.__class__.__name__
+        )
+        # 导出模板
+        if request.method == 'GET':
+            # 示例数据
+            return SuccessResponse(
+                export_excel_save_model(request, self.import_field_data.values(), [], '导入用户数据模板.xls'))
+        updateSupport = request.data.get('updateSupport')
+        # 从excel中组织对应的数据结构,然后使用序列化器保存
+        data = excel_to_data(request.data.get('file_url'), self.import_field_data)
+        unique_list = [ele.attname for ele in self.get_queryset().model._meta.get_fields() if
+                       hasattr(ele, 'unique') and ele.unique == True]
+        for ele in data:
+            # 获取 unique 字段
+            filter_dic = {i: ele.get(i) for i in list(set(self.import_field_data.keys()) & set(unique_list))}
+            instance = self.get_queryset().filter(**filter_dic).first()
+            if instance and not updateSupport:
+                continue
+            if not filter_dic:
+                instance = None
+            serializer = self.import_serializer_class(instance, data=ele)
+            serializer.is_valid(raise_exception=True)
+            serializer.save()
+        return SuccessResponse(msg=f"导入成功!")
+
+
+class ExportSerializerMixin:
+    """
+    自定义导出功能
+    """
+    # 导出字段
+    export_field_data = []
+    # 导出序列化器
+    export_serializer_class = None
+
+    def export(self, request: Request, *args, **kwargs):
+        """
+        导出功能
+        :param request:
+        :param args:
+        :param kwargs:
+        :return:
+        """
+        assert self.export_field_data, (
+                "'%s' 请配置对应的导出模板字段。"
+                % self.__class__.__name__
+        )
+        data = self.export_serializer_class(self.get_queryset(), many=True).data
+        return SuccessResponse(export_excel_save_model(request, self.export_field_data, data, '导出用户数据.xls'))
diff --git a/dvadmin-backend/apps/vadmin/op_drf/viewsets.py b/dvadmin-backend/apps/vadmin/op_drf/viewsets.py
index edd9b81..d707526 100644
--- a/dvadmin-backend/apps/vadmin/op_drf/viewsets.py
+++ b/dvadmin-backend/apps/vadmin/op_drf/viewsets.py
@@ -201,7 +201,9 @@ class MongoModelViewSet(mixins.CreateModelMixin,
     pass
 
 
-class CustomModelViewSet(ModelViewSet, mixins.TableSerializerMixin):
+class CustomModelViewSet(ModelViewSet, mixins.TableSerializerMixin,
+                         mixins.ImportSerializerMixin,
+                         mixins.ExportSerializerMixin):
     """
     自定义的ModelViewSet:
     (1)默认分页器就为统一分页器op_drf.pagination.Pagination
diff --git a/dvadmin-backend/apps/vadmin/permission/serializers.py b/dvadmin-backend/apps/vadmin/permission/serializers.py
index ebfb510..4e67563 100644
--- a/dvadmin-backend/apps/vadmin/permission/serializers.py
+++ b/dvadmin-backend/apps/vadmin/permission/serializers.py
@@ -1,4 +1,5 @@
 from rest_framework import serializers
+from rest_framework.fields import empty
 from rest_framework.validators import UniqueValidator
 
 from ..op_drf.serializers import CustomModelSerializer
@@ -285,3 +286,25 @@ class UserProfileCreateUpdateSerializer(CustomModelSerializer):
         model = UserProfile
         exclude = ('password', 'secret', 'user_permissions', 'groups', 'is_superuser', 'date_joined')
         read_only_fields = ('dept',)
+
+class UserProfileImportSerializer(CustomModelSerializer):
+
+    def save(self, **kwargs):
+        data = super().save(**kwargs)
+        data.set_password(self.initial_data.get('password', None))
+        data.save()
+        return data
+
+    def run_validation(self, data={}):
+        # 把excel 数据进行格式转换
+        if type(data) is dict:
+            data['role'] = str(data['role']).split(',')
+            data['post'] = str(data['post']).split(',')
+            data['gender'] = {'男': '0', '女': '1', '未知': '2'}.get(data['gender'])
+            data['is_active'] = {'启用': True, '禁用': False}.get(data['is_active'])
+        return super().run_validation(data)
+
+
+    class Meta:
+        model = UserProfile
+        exclude = ('password', 'secret', 'user_permissions', 'groups', 'is_superuser', 'date_joined')
diff --git a/dvadmin-backend/apps/vadmin/permission/urls.py b/dvadmin-backend/apps/vadmin/permission/urls.py
index e3fd71a..cc746ac 100644
--- a/dvadmin-backend/apps/vadmin/permission/urls.py
+++ b/dvadmin-backend/apps/vadmin/permission/urls.py
@@ -29,13 +29,16 @@ urlpatterns = [
     # 用户自己重置密码
     re_path('user/profile/updatePwd/', UserProfileModelViewSet.as_view({'put': 'update_pwd'})),
     # 获取、更新用户个人信息
-    re_path('user/profile/', UserProfileModelViewSet.as_view({'get': 'profile','put': 'put_profile'})),
+    re_path('user/profile/', UserProfileModelViewSet.as_view({'get': 'profile', 'put': 'put_profile'})),
     # 导出用户
-    re_path('user/export/', UserProfileModelViewSet.as_view({'get': 'export',})),
+    re_path('user/export/', UserProfileModelViewSet.as_view({'get': 'export', })),
     # 导出角色
-    re_path('role/export/', RoleModelViewSet.as_view({'get': 'export',})),
+    re_path('role/export/', RoleModelViewSet.as_view({'get': 'export', })),
     # 导出岗位
-    re_path('post/export/', PostModelViewSet.as_view({'get': 'export',})),
+    re_path('post/export/', PostModelViewSet.as_view({'get': 'export', })),
+    # 用户导入模板下载及导入
+    re_path('user/importTemplate/',
+            UserProfileModelViewSet.as_view({'get': 'importTemplate', 'post': 'importTemplate'})),
 
 ]
 urlpatterns += router.urls
diff --git a/dvadmin-backend/apps/vadmin/permission/views.py b/dvadmin-backend/apps/vadmin/permission/views.py
index d1d09e3..d82b4c6 100644
--- a/dvadmin-backend/apps/vadmin/permission/views.py
+++ b/dvadmin-backend/apps/vadmin/permission/views.py
@@ -2,16 +2,17 @@ from django.contrib.auth import authenticate
 from rest_framework.request import Request
 from rest_framework.views import APIView
 
+from ..op_drf.filters import DataLevelPermissionsFilter
 from ..op_drf.viewsets import CustomModelViewSet
 from ..permission.filters import MenuFilter, DeptFilter, PostFilter, RoleFilter, UserProfileFilter
 from ..permission.models import Role, Menu, Dept, Post, UserProfile
 from ..permission.serializers import UserProfileSerializer, MenuSerializer, RoleSerializer, \
     MenuCreateUpdateSerializer, DeptSerializer, DeptCreateUpdateSerializer, PostSerializer, PostCreateUpdateSerializer, \
     RoleCreateUpdateSerializer, DeptTreeSerializer, MenuTreeSerializer, UserProfileCreateUpdateSerializer, \
-    PostSimpleSerializer, RoleSimpleSerializer, ExportUserProfileSerializer, ExportRoleSerializer, ExportPostSerializer
-from ..op_drf.filters import DataLevelPermissionsFilter
+    PostSimpleSerializer, RoleSimpleSerializer, ExportUserProfileSerializer, ExportRoleSerializer, ExportPostSerializer, \
+    UserProfileImportSerializer
 from ..system.models import DictDetails
-from ..utils.export_excel import export_excel_save_model
+from ..utils.export_excel import export_excel_save_model, excel_to_data
 from ..utils.response import SuccessResponse, ErrorResponse
 
 
@@ -22,7 +23,7 @@ class GetUserProfileView(APIView):
 
     def get(self, request, format=None):
         user_dict = UserProfileSerializer(request.user).data
-        permissions_list = ["*:*:*"] if user_dict.get('admin') else Menu.objects.filter(
+        permissions_list = ['*:*:*'] if user_dict.get('admin') else Menu.objects.filter(
             role__userprofile=request.user).values_list('perms', flat=True)
         return SuccessResponse({
             'permissions': [ele for ele in permissions_list if ele],
@@ -47,14 +48,14 @@ class GetRouters(APIView):
 
     def get(self, request, format=None):
         # data = GetUserInfoSerializer(request.user).data
-        menus = Menu.objects.filter(role__userprofile=request.user).exclude(menuType="2").values('id', 'name',
+        menus = Menu.objects.filter(role__userprofile=request.user).exclude(menuType='2').values('id', 'name',
                                                                                                  'web_path',
                                                                                                  'visible', 'status',
                                                                                                  'isFrame',
                                                                                                  'component_path',
                                                                                                  'icon', 'parentId',
                                                                                                  'isCache').distinct()
-        # data = '{"msg":"操作成功","code":200,"data":[{"name":"System","path":"/system","hidden":false,"redirect":"noRedirect","component":"Layout","alwaysShow":true,"meta":{"title":"系统管理","icon":"system","noCache":false},"children":[{"name":"User","path":"user","hidden":false,"component":"permission/user/index","meta":{"title":"用户管理","icon":"user","noCache":false}},{"name":"Role","path":"role","hidden":false,"component":"permission/role/index","meta":{"title":"角色管理","icon":"peoples","noCache":false}},{"name":"Menu","path":"menu","hidden":false,"component":"permission/menu/index","meta":{"title":"菜单管理","icon":"tree-table","noCache":false}},{"name":"Dept","path":"dept","hidden":false,"component":"permission/dept/index","meta":{"title":"部门管理","icon":"tree","noCache":false}},{"name":"Post","path":"post","hidden":false,"component":"permission/post/index","meta":{"title":"岗位管理","icon":"post","noCache":false}},{"name":"Dict","path":"dict","hidden":false,"component":"system/dict/index","meta":{"title":"字典管理","icon":"dict","noCache":false}},{"name":"Config","path":"config","hidden":false,"component":"system/config/index","meta":{"title":"参数设置","icon":"edit","noCache":false}},{"name":"Notice","path":"notice","hidden":false,"component":"system/notice/index","meta":{"title":"通知公告","icon":"message","noCache":false}},{"name":"Log","path":"log","hidden":false,"redirect":"noRedirect","component":"ParentView","alwaysShow":true,"meta":{"title":"日志管理","icon":"log","noCache":false},"children":[{"name":"Operlog","path":"operlog","hidden":false,"component":"monitor/operlog/index","meta":{"title":"操作日志","icon":"form","noCache":false}},{"name":"Logininfor","path":"logininfor","hidden":false,"component":"monitor/logininfor/index","meta":{"title":"登录日志","icon":"logininfor","noCache":false}}]}]},{"name":"Monitor","path":"/monitor","hidden":false,"redirect":"noRedirect","component":"Layout","alwaysShow":true,"meta":{"title":"系统监控","icon":"monitor","noCache":false},"children":[{"name":"Online","path":"online","hidden":false,"component":"monitor/online/index","meta":{"title":"在线用户","icon":"online","noCache":false}},{"name":"Job","path":"job","hidden":false,"component":"monitor/job/index","meta":{"title":"定时任务","icon":"job","noCache":false}},{"name":"Druid","path":"druid","hidden":false,"component":"monitor/druid/index","meta":{"title":"数据监控","icon":"druid","noCache":false}},{"name":"Server","path":"server","hidden":false,"component":"monitor/server/index","meta":{"title":"服务监控","icon":"server","noCache":false}},{"name":"Cache","path":"cache","hidden":false,"component":"monitor/cache/index","meta":{"title":"缓存监控","icon":"redis","noCache":false}}]},{"name":"Tool","path":"/tool","hidden":false,"redirect":"noRedirect","component":"Layout","alwaysShow":true,"meta":{"title":"系统工具","icon":"tool","noCache":false},"children":[{"name":"Build","path":"build","hidden":false,"component":"tool/build/index","meta":{"title":"表单构建","icon":"build","noCache":false}},{"name":"Gen","path":"gen","hidden":false,"component":"tool/gen/index","meta":{"title":"代码生成","icon":"code","noCache":false}},{"name":"Swagger","path":"swagger","hidden":false,"component":"tool/swagger/index","meta":{"title":"系统接口","icon":"swagger","noCache":false}}]},{"name":"Http://ruoyi.vip","path":"http://ruoyi.vip","hidden":false,"component":"Layout","meta":{"title":"若依官网","icon":"guide","noCache":false}}]}'
+        # data = '{'msg':'操作成功','code':200,'data':[{'name':'System','path':'/system','hidden':false,'redirect':'noRedirect','component':'Layout','alwaysShow':true,'meta':{'title':'系统管理','icon':'system','noCache':false},'children':[{'name':'User','path':'user','hidden':false,'component':'permission/user/index','meta':{'title':'用户管理','icon':'user','noCache':false}},{'name':'Role','path':'role','hidden':false,'component':'permission/role/index','meta':{'title':'角色管理','icon':'peoples','noCache':false}},{'name':'Menu','path':'menu','hidden':false,'component':'permission/menu/index','meta':{'title':'菜单管理','icon':'tree-table','noCache':false}},{'name':'Dept','path':'dept','hidden':false,'component':'permission/dept/index','meta':{'title':'部门管理','icon':'tree','noCache':false}},{'name':'Post','path':'post','hidden':false,'component':'permission/post/index','meta':{'title':'岗位管理','icon':'post','noCache':false}},{'name':'Dict','path':'dict','hidden':false,'component':'system/dict/index','meta':{'title':'字典管理','icon':'dict','noCache':false}},{'name':'Config','path':'config','hidden':false,'component':'system/config/index','meta':{'title':'参数设置','icon':'edit','noCache':false}},{'name':'Notice','path':'notice','hidden':false,'component':'system/notice/index','meta':{'title':'通知公告','icon':'message','noCache':false}},{'name':'Log','path':'log','hidden':false,'redirect':'noRedirect','component':'ParentView','alwaysShow':true,'meta':{'title':'日志管理','icon':'log','noCache':false},'children':[{'name':'Operlog','path':'operlog','hidden':false,'component':'monitor/operlog/index','meta':{'title':'操作日志','icon':'form','noCache':false}},{'name':'Logininfor','path':'logininfor','hidden':false,'component':'monitor/logininfor/index','meta':{'title':'登录日志','icon':'logininfor','noCache':false}}]}]},{'name':'Monitor','path':'/monitor','hidden':false,'redirect':'noRedirect','component':'Layout','alwaysShow':true,'meta':{'title':'系统监控','icon':'monitor','noCache':false},'children':[{'name':'Online','path':'online','hidden':false,'component':'monitor/online/index','meta':{'title':'在线用户','icon':'online','noCache':false}},{'name':'Job','path':'job','hidden':false,'component':'monitor/job/index','meta':{'title':'定时任务','icon':'job','noCache':false}},{'name':'Druid','path':'druid','hidden':false,'component':'monitor/druid/index','meta':{'title':'数据监控','icon':'druid','noCache':false}},{'name':'Server','path':'server','hidden':false,'component':'monitor/server/index','meta':{'title':'服务监控','icon':'server','noCache':false}},{'name':'Cache','path':'cache','hidden':false,'component':'monitor/cache/index','meta':{'title':'缓存监控','icon':'redis','noCache':false}}]},{'name':'Tool','path':'/tool','hidden':false,'redirect':'noRedirect','component':'Layout','alwaysShow':true,'meta':{'title':'系统工具','icon':'tool','noCache':false},'children':[{'name':'Build','path':'build','hidden':false,'component':'tool/build/index','meta':{'title':'表单构建','icon':'build','noCache':false}},{'name':'Gen','path':'gen','hidden':false,'component':'tool/gen/index','meta':{'title':'代码生成','icon':'code','noCache':false}},{'name':'Swagger','path':'swagger','hidden':false,'component':'tool/swagger/index','meta':{'title':'系统接口','icon':'swagger','noCache':false}}]},{'name':'Http://ruoyi.vip','path':'http://ruoyi.vip','hidden':false,'component':'Layout','meta':{'title':'若依官网','icon':'guide','noCache':false}}]}'
         # data = json.loads(data)
         data = []
         sys_show_hide = DictDetails.get_default_dictValue('sys_show_hide')
@@ -66,7 +67,8 @@ class GetRouters(APIView):
                 'hidden': True if ele.get('visible') != '1' else False,
                 'redirect': ele.get('web_path') if ele.get('isFrame') == '1' else 'noRedirect',
                 'component': ele.get('component_path') or 'Layout',
-                'meta': {"title": ele.get('name'), "icon": ele.get('icon'), "noCache": True if ele.get('isCache') == sys_show_hide else False},
+                'meta': {'title': ele.get('name'), 'icon': ele.get('icon'),
+                         'noCache': True if ele.get('isCache') == sys_show_hide else False},
                 'parentId': ele.get('parentId')
             })
         return SuccessResponse(data)
@@ -254,6 +256,15 @@ class UserProfileModelViewSet(CustomModelViewSet):
     update_serializer_class = UserProfileCreateUpdateSerializer
     filter_class = UserProfileFilter
     extra_filter_backends = [DataLevelPermissionsFilter]
+    # 导出
+    export_serializer_class = ExportUserProfileSerializer
+    export_field_data = ['用户序号', '登录名称', '用户名称', '用户邮箱', '手机号码', '用户性别', '帐号状态', '最后登录时间', '部门名称', '部门负责人']
+    # 导入
+    import_serializer_class = UserProfileImportSerializer
+    import_field_data = {'username': '登录账号', 'name': '用户名称', 'email': '用户邮箱', 'mobile': '手机号码',
+                         'gender': '用户性别(男/女/未知)',
+                         'is_active': '帐号状态(启用/禁用)', 'password': '登录密码', 'dept': '部门ID', 'role': '角色ID',
+                         'post': '岗位ID'}
     # update_extra_permission_classes = (IsManagerPermission,)
     # destroy_extra_permission_classes = (IsManagerPermission,)
     # create_extra_permission_classes = (IsManagerPermission,)
@@ -366,15 +377,3 @@ class UserProfileModelViewSet(CustomModelViewSet):
         if hasattr(self, 'handle_logging'):
             self.handle_logging(request, instance=instance, *args, **kwargs)
         return SuccessResponse(serializer.data)
-
-    def export(self, request: Request, *args, **kwargs):
-        """
-        导出用户
-        :param request:
-        :param args:
-        :param kwargs:
-        :return:
-        """
-        field_data = ['用户序号', '登录名称', '用户名称', '用户邮箱', '手机号码', '用户性别', '帐号状态', '最后登录时间', '部门名称', '部门负责人']
-        data = ExportUserProfileSerializer(UserProfile.objects.all(), many=True).data
-        return SuccessResponse(export_excel_save_model(request, field_data, data, '导出用户数据.xls'))
diff --git a/dvadmin-backend/apps/vadmin/utils/exceptions.py b/dvadmin-backend/apps/vadmin/utils/exceptions.py
index c6969b7..1f38afa 100644
--- a/dvadmin-backend/apps/vadmin/utils/exceptions.py
+++ b/dvadmin-backend/apps/vadmin/utils/exceptions.py
@@ -2,6 +2,7 @@ import logging
 import traceback
 
 from rest_framework import serializers, exceptions
+from rest_framework.views import set_rollback
 
 from .response import ErrorResponse
 
@@ -67,9 +68,10 @@ def op_exception_handler(ex, context):
         code = 401
         msg = ex.detail
     elif isinstance(ex, DRFAPIException):
-        # set_rollback()
+        set_rollback()
         msg = ex.detail
     elif isinstance(ex, exceptions.APIException):
+        set_rollback()
         msg = ex.detail
     elif isinstance(ex, Exception):
         logger.error(traceback.format_exc())
diff --git a/dvadmin-backend/apps/vadmin/utils/export_excel.py b/dvadmin-backend/apps/vadmin/utils/export_excel.py
index bd18c5c..c6484bd 100644
--- a/dvadmin-backend/apps/vadmin/utils/export_excel.py
+++ b/dvadmin-backend/apps/vadmin/utils/export_excel.py
@@ -3,6 +3,7 @@ import hashlib
 import os
 import time
 
+import xlrd
 import xlwt
 from django.conf import settings
 
@@ -68,8 +69,8 @@ def export_excel(field_data: list, data: list, FileName: str, file_path: str = s
 
     # 确定栏位宽度
     col_width = []
-    for index,ele in enumerate(data):
-        for inx,values in enumerate(ele.values()):
+    for index, ele in enumerate(data):
+        for inx, values in enumerate(ele.values()):
             if index == 0:
                 col_width.append(len_byte(str(values)))
             else:
@@ -83,7 +84,6 @@ def export_excel(field_data: list, data: list, FileName: str, file_path: str = s
         else:
             sheet.col(i).width = 256 * (default_width)
 
-
     row = 1
     # 内容背景颜色
     left_pattern = xlwt.Pattern()  # 创建一个模式
@@ -113,7 +113,8 @@ def export_excel(field_data: list, data: list, FileName: str, file_path: str = s
     wbk.save(path_name)
     return os.path.join('system', monthTime, FileName)
 
-def export_excel_save_model(request,field_data,data,FilName):
+
+def export_excel_save_model(request, field_data, data, FilName):
     """
     导出Excel并保存到 SaveFile 文件管理中
     :param request:
@@ -125,7 +126,7 @@ def export_excel_save_model(request,field_data,data,FilName):
     # 根据生成的字典MD5
     time_stamp = hashlib.md5(str(field_data).encode('utf8')).hexdigest()
     # 存入文件数据库中
-    FilName = str(time_stamp) + FilName
+    FilName = '.'.join(FilName.split('.')[:-1]) + str(time_stamp) + '.' + FilName.split('.')[-1]
     file_rul = export_excel(field_data=field_data, data=data, FileName=FilName)
     savefile, _ = SaveFile.objects.get_or_create(file=file_rul)
     if _ == True:
@@ -137,3 +138,33 @@ def export_excel_save_model(request,field_data,data,FilName):
     savefile.modifier = request.user.username
     savefile.save()
     return SaveFileSerializer(savefile).data
+
+
+def excel_to_data(file_url, field_data):
+    """
+    读取导入的excel文件
+    :param request:
+    :param field_data: 首行数据源
+    :param data: 数据源
+    :param FilName: 文件名
+    :return:
+    """
+    # 读取excel 文件
+    data = xlrd.open_workbook(os.path.join(settings.BASE_DIR, *file_url.split(os.sep)))
+    table = data.sheets()[0]
+    # 创建一个空列表,存储Excel的数据
+    tables = []
+    for i, rown in enumerate(range(table.nrows)):
+        if i == 0: continue
+        array = {}
+        for index, ele in enumerate(field_data.keys()):
+            cell_value = table.cell_value(rown, index)
+            # 由于excel导入数字类型后,会出现数字加 .0 的,进行处理
+            if type(cell_value) is float and str(cell_value).split('.')[1] == '0':
+                cell_value = int(str(cell_value).split('.')[0])
+            if type(cell_value) is str:
+                cell_value = cell_value.strip(' \t\n\r')
+            array[ele] = cell_value
+
+        tables.append(array)
+    return tables
diff --git a/dvadmin-backend/requirements.txt b/dvadmin-backend/requirements.txt
index 953c6e4..3c2399d 100644
--- a/dvadmin-backend/requirements.txt
+++ b/dvadmin-backend/requirements.txt
@@ -20,6 +20,7 @@ redis==3.5.3
 six==1.15.0
 sqlparse==0.4.1
 xlwt==1.3.0
+xlrd==2.0.1
 coreapi==2.3.3
 user-agents==2.2.0
 eventlet==0.30.2
diff --git a/dvadmin-ui/src/api/vadmin/permission/user.js b/dvadmin-ui/src/api/vadmin/permission/user.js
index 365b96d..7ab6326 100755
--- a/dvadmin-ui/src/api/vadmin/permission/user.js
+++ b/dvadmin-ui/src/api/vadmin/permission/user.js
@@ -13,7 +13,7 @@ export function listUser(query) {
 // 查询用户详细
 export function getUser(userId) {
   return request({
-    url: '/admin/permission/user/details/?userId=' + praseStrEmpty(userId) ,
+    url: '/admin/permission/user/details/?userId=' + praseStrEmpty(userId),
     method: 'get'
   })
 }
@@ -112,7 +112,7 @@ export function updateUserPwd(oldPassword, newPassword) {
 // 用户头像上传
 export function uploadAvatar(data) {
   return request({
-    url: '/admin/permission/user/profile/avatar',
+    url: '/admin/permission/user/profile/avatar/',
     method: 'post',
     data: data
   })
@@ -121,7 +121,16 @@ export function uploadAvatar(data) {
 // 下载用户导入模板
 export function importTemplate() {
   return request({
-    url: '/admin/permission/user/importTemplate',
+    url: '/admin/permission/user/importTemplate/',
     method: 'get'
   })
 }
+
+// 用户导入
+export function importsUser(data) {
+  return request({
+    url: '/admin/permission/user/importTemplate/',
+    method: 'post',
+    data: data
+  })
+}
diff --git a/dvadmin-ui/src/components/FileUpload/index.vue b/dvadmin-ui/src/components/FileUpload/index.vue
index 1fe014f..8447bca 100755
--- a/dvadmin-ui/src/components/FileUpload/index.vue
+++ b/dvadmin-ui/src/components/FileUpload/index.vue
@@ -64,7 +64,7 @@ export default {
   name:'FileUpload',
   data() {
     return {
-      uploadFileUrl: process.env.VUE_APP_BASE_API + "/system/savefile/", // 上传的图片服务器地址
+      uploadFileUrl: process.env.VUE_APP_BASE_API + "/admin/system/savefile/", // 上传的图片服务器地址
       headers: {
         Authorization: "Bearer " + getToken(),
       },
diff --git a/dvadmin-ui/src/views/vadmin/permission/user/index.vue b/dvadmin-ui/src/views/vadmin/permission/user/index.vue
index 13972c8..1991185 100755
--- a/dvadmin-ui/src/views/vadmin/permission/user/index.vue
+++ b/dvadmin-ui/src/views/vadmin/permission/user/index.vue
@@ -343,13 +343,24 @@
 </template>
 
 <script>
-import { listUser, getUser, delUser, addUser, updateUser, exportUser, resetUserPwd, changeUserStatus, importTemplate } from "@/api/vadmin/permission/user";
-import { getToken } from "@/utils/auth";
-import { treeselect } from "@/api/vadmin/permission/dept";
-import Treeselect from "@riophae/vue-treeselect";
-import "@riophae/vue-treeselect/dist/vue-treeselect.css";
+  import {
+    addUser,
+    changeUserStatus,
+    delUser,
+    exportUser,
+    getUser,
+    importsUser,
+    importTemplate,
+    listUser,
+    resetUserPwd,
+    updateUser
+  } from "@/api/vadmin/permission/user";
+  import {getToken} from "@/utils/auth";
+  import {treeselect} from "@/api/vadmin/permission/dept";
+  import Treeselect from "@riophae/vue-treeselect";
+  import "@riophae/vue-treeselect/dist/vue-treeselect.css";
 
-export default {
+  export default {
   name: "User",
   components: { Treeselect },
   data() {
@@ -407,7 +418,7 @@ export default {
         // 设置上传的请求头部
         headers: { Authorization: "Bearer " + getToken() },
         // 上传的地址
-        url: process.env.VUE_APP_BASE_API + "/system/savefile/"
+        url: process.env.VUE_APP_BASE_API + "/admin/system/savefile/"
       },
       // 查询参数
       queryParams: {
@@ -665,8 +676,11 @@ export default {
       this.upload.open = false;
       this.upload.isUploading = false;
       this.$refs.upload.clearFiles();
-      this.$alert(response.msg, "导入结果", { dangerouslyUseHTMLString: true });
-      this.getList();
+      // 是否更新已经存在的用户数据
+      importsUser({file_url: response.data.file_url,updateSupport:this.upload.updateSupport}).then(response => {
+        this.$alert('导入成功!', "导入结果", { dangerouslyUseHTMLString: true });
+        this.getList();
+      });
     },
     // 提交上传文件
     submitFileForm() {