zoukankan      html  css  js  c++  java
  • 一.运维平台之用户资源功能完整版

     参考https://github.com/rfjer/autoAdmin/

    https://github.com/rfjer/autoAdmin/blob/master/apps/users/serializers.py

    用户功能:
        创建用户        <<=post
        获取用户列表    <<= get
            分页        
            搜索
        修改用户        <=patch/put
        删除用户         <=delete
    我把分成用户注册登录是一个功能,用户列表修改是一个功能

    新建运维平台项目:

    
    

    1.创建数据库:

    [vagrant@CentOS ~]$ sudo su - root
    [root@CentOS ~]# mysql -uroot
    CREATE DATABASE `devops_test` /*!40100 DEFAULT CHARACTER SET utf8 */;

    创建虚拟环境:

    sudo su - vagrant
    sudo /usr/local/python36/bin/pip3 install virtualenv
    /usr/local/python36/bin/virtualenv ./python36env
    source ./python36env/bin/activate
    cd /vagrant/

    2.关闭防火墙:

    sudo systemctl stop firewalld

    sudo systemctl disable firewalld.service

    3.安装工具: pip list

     Django 2.2.1
     pip install coreapi-cli
     pip install djangorestframework
     pip install django-apscheduler pip install tencentcloud-sdk-python
     pip install django-filter
     pip install requests -i https://pypi.douban.com/simple/ 
     pip install pymysql
     pip install django-rest-swagger
     pip install django-cors-headers
     pip install djangorestframework-jwt
    4.创建项目:
    django-admin startproject devops (python36env) [vagrant@CentOS devops]$ python manage.py runserver 0.0.0.0:8000
    pycharm设置远程连接此虚拟环境中的django项目!!
    5.创建用户app: (python36env) [vagrant@CentOS devops]$ pwd
    /vagrant/devops (python36env) [vagrant@CentOS devops]$ django-admin startapp users (python36env) [vagrant@CentOS devops]$ mkdir apps (python36env) [vagrant@CentOS devops]$ mv users apps/ settings.py配置:
    import os
    import sys
    
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    sys.path.insert(0,os.path.join(BASE_DIR, "apps"))
    
    SECRET_KEY = '9vg^(z0ay7ii873g1!7--##r(r#=iisz3wn@mzkxbmx_5iw7))'
    
    DEBUG = True
    
    ALLOWED_HOSTS = []
    
    AUTH_USER_MODEL = 'users.User'
    
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'rest_framework',
        'rest_framework.authtoken',
        'users',
        'corsheaders',
        'django_apscheduler',
        'django_filters'
    ]
    CORS_ALLOW_CREDENTIALS = True
    CORS_ORIGIN_ALLOW_ALL = True
    CORS_ORIGIN_WHITELIST = (
        'http://127.0.0.1:8000',
    )
    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'corsheaders.middleware.CorsMiddleware',
        'django.middleware.common.CommonMiddleware',
        #'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
    ]
    
    ROOT_URLCONF = 'devops.urls'
    
    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [],
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                ],
            },
        },
    ]
    
    WSGI_APPLICATION = 'devops.wsgi.application'
    
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'devops_test',
            'USER': 'root',
            'PASSWORD': '123456',
            'HOST': '127.0.0.1',
            'PORT': 3306,
            'OPTIONS':{
                'init_command':"SET sql_mode='STRICT_TRANS_TABLES'",
                'charset':'utf8mb4',
            },
        }
    }
    
    
    AUTH_PASSWORD_VALIDATORS = [
        {
            'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
        },
    ]
    
    
    LANGUAGE_CODE = 'zh-hans'
    
    TIME_ZONE = 'Asia/Shanghai'
    
    USE_I18N = True
    
    USE_L10N = True
    
    USE_TZ = False
    
    
    STATIC_URL = '/static/'
    
    from rest_framework.settings import api_settings
    
    REST_FRAMEWORK = {
        'DEFAULT_PAGINATION_CLASS': 'devops.paginations.Pagination',
        'PAGE_SIZE': 10,
        'DEFAULT_FILTER_BACKENDS': (
            'django_filters.rest_framework.DjangoFilterBackend',
        ),
        # 'DEFAULT_PERMISSION_CLASSES': (
        #     'rest_framework.permissions.IsAuthenticated',
        #     'rest_framework.permissions.DjangoModelPermissions',
        # ),
        # 'DEFAULT_AUTHENTICATION_CLASSES': (
        #     'rest_framework.authentication.SessionAuthentication',
        #     'rest_framework.authentication.BasicAuthentication',
        #     'rest_framework.authentication.TokenAuthentication',
        # ),
        'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
    }
    
    ## qcloud
    QCLOUD_SECRETID = "AKIDFaq5EbGxiQx22qzUL2XtCJJ7j9NQuyTq"
    QCLOUD_SECRETKEY = "LTP8fz72lOr8D8reFerunUyGQN7f4LTP"
    
    # LOGGING = {
    #     'version': 1,
    #     'disable_existing_loggers': False,
    #     'loggers': {
    #         'reboot': {
    #             'handlers': ["reboot"],
    #             'level': 'DEBUG',
    #             'propagate': True
    #         },
    #         "django": {
    #             'handlers': ["django"],
    #             'level': 'DEBUG',
    #             'propagate': True
    #         },
    #         "django.server": {
    #             'handlers': ["django_server"],
    #             'level': 'DEBUG',
    #             "propagate": True
    #         },
    #         "django.db.backends": {
    #             "propagate": False,
    #             'level': 'DEBUG',
    #             'handlers': ["db_backends"]
    #         }
    #     },
    #     'handlers': {
    #         "db_backends": {
    #             'level': 'DEBUG',
    #             'class': 'logging.FileHandler',
    #             'filename': '/tmp/db_backends.log',
    #             'formatter': 'default'
    #         },
    #         'reboot': {
    #             'level': 'DEBUG',
    #             'class': 'logging.StreamHandler',
    #             'formatter': 'simple',
    #         },
    #         'file': {
    #             'level': 'DEBUG',
    #             'class': 'logging.FileHandler',
    #             'filename': '/tmp/django.log',
    #             'formatter': 'json',
    #         },
    #         'django': {
    #             'level': 'DEBUG',
    #             'class': 'logging.FileHandler',
    #             'filename': '/tmp/default.log',
    #             'formatter': 'simple',
    #         },
    #         'django_server': {
    #             'level': 'DEBUG',
    #             'class': 'logging.FileHandler',
    #             'filename': '/tmp/django_server.log',
    #             'formatter': 'simple',
    #         },
    #     },
    #     'formatters': {
    #         'json': {
    #             'format': '{"levelname":"%(levelname)s","asctime":"%(asctime)s","module":"%(name)s","fullpath":"%(pathname)s","funcName":"%(funcName)s","lineno":"%(lineno)s","message":"%(message)s"}'
    #         },
    #         'reboot': {
    #             'format': '%(asctime)s - %(pathname)s:%(lineno)d[%(levelname)s] - %(message)s'
    #         },
    #         'simple': {
    #             'format': '%(name)s %(asctime)s %(levelname)s %(message)s'
    #         },
    #         'verbose': {
    #             'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
    #         },
    #         "default": {
    #             "format": '%(asctime)s %(name)s %(lineno)s %(levelname)s  %(message)s',
    #             "datefmt": "%Y-%m-%d %H:%M:%S"
    #         }
    #     },
    #     "root": {
    #         'handlers': ["file"],
    #         'level': 'DEBUG',
    #     }
    # }
    
    DOMAIN = "@51reboot.com"
    
    
    后端实现:
    6.users/models.py:

    from django.db import models
    # Create your models here.
    from django.contrib.auth.models import AbstractUser, Group
    
    class User(AbstractUser):
        name = models.CharField("姓名", max_length=32, null=True, help_text="姓名")
        phone = models.CharField("电话", max_length=11, null=True, help_text="手机号")
    
        class Meta:
            verbose_name = "用户"
            ordering = ["id"]
            db_table = 'auth_user'
    
        def __str__(self):
            return self.username
    
    

    7.users/views.py:

    from rest_framework import viewsets, permissions, mixins
    from .serializers import UserSerializer, UserRegSerializer
    from .filters import UserFilter
    from django_filters.rest_framework import DjangoFilterBackend
    from django.contrib.auth import get_user_model
    User = get_user_model()
    
    
    class UserViewset(mixins.RetrieveModelMixin,
                       mixins.UpdateModelMixin,
                       mixins.DestroyModelMixin,
                       mixins.ListModelMixin,
                       viewsets.GenericViewSet):
        """
        retrieve:
            获取指定user记录
        list:
            获取user列表
        update:
            更新user记录
        partial_update:
            更新user的部门字段
        destroy:
            删除user记录
        """
        queryset = User.objects.filter(is_superuser=False)
        serializer_class = UserSerializer
        filter_class=UserFilter
        filter_fields = ("username",)
    #有两个地方可控制你提交哪些方法:一个是此处的视图层,一个是序列化中(序列化中控制的是具体要怎么个做法动作)
    #UserRegViewset类想支持什么方法在此引入就好了
    class UserRegViewset(viewsets.GenericViewSet,
                         mixins.CreateModelMixin,
                         mixins.UpdateModelMixin):
        """
        create:
            用户注册
        partial_update:
            修改密码
        update:
            修改密码
        """
        queryset = User.objects.all()
        serializer_class = UserRegSerializer

    8.users/serializers.py:

    from rest_framework import serializers
    from django.contrib.auth.models import Group
    from django.contrib.auth import get_user_model
    from django.conf import settings
    User = get_user_model()
    
    #控制具体动作有哪些
    class UserSerializer(serializers.ModelSerializer):
        """
        用户序列化类
        """
        #控制的你是返回的格式:
        last_login  = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S",
                                                label="上次登录时间",
                                                help_text="上次登录时间")
    
        # 控制往前端返回哪些字段:
        class Meta:
            model = User
            fields = ("id", "username", "name", "phone", "email", "is_active", "last_login")
        #想修改哪些字段可在此方法中控制:
        def update(self, instance, validated_data):
            instance.phone = validated_data.get("phone", instance.phone)
            instance.is_active = validated_data.get("is_active", instance.is_active)
            instance.save()
            return instance
    
    
    class UserRegSerializer(serializers.ModelSerializer):
        """
        用户注册序列化类
        """
        #把密码处理成密文
        password = serializers.CharField(style={"input_type": "password"},
                                         label="密码",
                                         write_only=True,
                                         help_text="密码")
       #验证
        def validate(self, attrs):
            attrs["is_active"] = False #默认创建完的用户不可直接登录
            #给用户自动加email地址
            attrs["email"] = "{}{}".format(attrs['username'], settings.DOMAIN)
            return attrs
        #此create可不要,但不要的结果是密码直接存进去了
        def create(self, validated_data):
            instance = super(UserRegSerializer, self).create(validated_data=validated_data)
            instance.set_password(validated_data["password"])
            instance.save()
            return instance
    
        def update(self, instance, validated_data):
            password =  validated_data.get("password", None)
            if password:
                instance.set_password(password)
                instance.save()
            return instance
        class Meta:
            model = User
            #序列化时返回的数据
            fields = ("username", "password", "name", "id", "phone")

    9.users/router.py:

    from rest_framework.routers import DefaultRouter
    from .views import UserViewset, UserRegViewset
    router = DefaultRouter()
    router.register("users", UserViewset, basename="users")
    router.register("userReg", UserRegViewset, basename="userReg")

    10.users/urls.py:

    from django.conf.urls import url, include
    from rest_framework.routers import DefaultRouter
    from rest_framework.documentation import include_docs_urls
    from users.router import router as user_router
    # from resources.router import router as resources_router
    router = DefaultRouter()
    router.registry.extend(user_router.registry)
    # router.registry.extend(resources_router.registry)
    
    
    from rest_framework.authtoken.views import obtain_auth_token
    urlpatterns = [
        url(r'^api/', include(router.urls)),
        url(r'^api-auth/', include('rest_framework.urls')),
        url(r'^docs/', include_docs_urls("51reboot接口文档")),
        url(r'^api-token-auth/', obtain_auth_token)
    ]

    11.users/filters.py:

    import django_filters
    from django.contrib.auth import get_user_model
    
    User = get_user_model()
    
    
    class UserFilter(django_filters.FilterSet):
        username = django_filters.CharFilter(lookup_expr="icontains")
    
        class Meta:
            model = User
            fields=["username"]

    12.devops/urls.py:

    import django_filters
    from django.contrib.auth import get_user_model
    
    User = get_user_model()
    
    
    class UserFilter(django_filters.FilterSet):
        username = django_filters.CharFilter(lookup_expr="icontains")
    
        class Meta:
            model = User
            fields=["username"]

    13.devops/paginations.py:

    from rest_framework.pagination import PageNumberPagination
    
    
    class Pagination(PageNumberPagination):
        def get_page_size(self, request):
            try:
                page_size = int(request.query_params.get("page_size", -1))
                if page_size >= 0:
                    return page_size
            except:
                pass
            return self.page_size
    数据迁移报错:
    migration执行没有报错,但是执行migrate就报错:
    Migration admin.0001_initial is applied before its dependency users.0001_initial on database 'default'.
    解决:删除数据库,新建一个跟原来一样名字的数据库,就解决了

    启动项目:

    (python36env) [vagrant@CentOS devops]$ python manage.py createsuperuser
    用户名: admin
    电子邮件地址: admin@51reboot.com
    Password:  123456

    (python36env) [vagrant@CentOS devops]$ python manage.py runserver 0.0.0.0:8000

    效果如下:

    一. 用户注册登陆与列表 

    1.后端实现:后端需要:写序列化/视图/路由

    创建测试用户的数据:

    (python36env) [vagrant@CentOS devops]$ python manage.py shell                                          
    In [2]: from django.contrib.auth import get_user_model                                               
    In [3]: User = get_user_model()                                                                      
    In [4]: def create_user(name): 
       ...:     for i in range(1,20): 
       ...:         username = "{}-{}".format(name,i) 
       ...:         User.objects.create_user(username, "{}@51reboot.com".format(username),"12345678") 
       ...:                                                                                              
    
    In [5]: create_user("rock")
    In [6]: create_user("panda")                                                                         
    
    In [7]: create_user("wd") 
    In [8]: User.objects.all().delete()  ---不想要时可用此命令清空数据

    (1).users/serializers.py:

    使用模型序列化,那create方法就可不用写(因为它默认把create做好了),但前提是我需要把数据给准备好,而这里有些数据是没有的,如email地址,而注册时我要求是填入用户名,密码,联系电话这些是必须要的,但是没有填邮件地址。那这个是可以改的---根据用户再来一个DOMAIN域名

     (1)settings.py中加入DOMAIN---让自动生成邮件域名

    DOMAIN = "@51reboot.com"
    from rest_framework import serializers
    from django.contrib.auth.models import Group
    from django.contrib.auth import get_user_model
    from django.conf import settings
    User = get_user_model()
    
    #控制具体动作有哪些
    class UserSerializer(serializers.ModelSerializer):
        """
        用户序列化类
        """
        #控制的你是返回的格式:
        last_login  = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S",
                                                label="上次登录时间",
                                                help_text="上次登录时间")
    
        # 控制往前端返回哪些字段:
        class Meta:
            model = User
            fields = ("id", "username", "name", "phone", "email", "is_active", "last_login")
        #想修改哪些字段可在此方法中控制:
        def update(self, instance, validated_data):
            instance.phone = validated_data.get("phone", instance.phone)
            instance.is_active = validated_data.get("is_active", instance.is_active)
            instance.save()
            return instance
    
    
    class UserRegSerializer(serializers.ModelSerializer):
        """
        用户注册序列化类
        """
        #把密码处理成密文
        password = serializers.CharField(style={"input_type": "password"},
                                         label="密码",
                                         write_only=True,
                                         help_text="密码")
       #验证
        def validate(self, attrs):
            attrs["is_active"] = False #默认创建完的用户不可直接登录
            #给用户自动加email地址
            attrs["email"] = "{}{}".format(attrs['username'], settings.DOMAIN)
            return attrs
        #此create可不要,但不要的结果是密码直接存进去了
        def create(self, validated_data):
            instance = super(UserRegSerializer, self).create(validated_data=validated_data)
            instance.set_password(validated_data["password"])
            instance.save()
            return instance
    
        def update(self, instance, validated_data):
            password =  validated_data.get("password", None)
            if password:
                instance.set_password(password)
                instance.save()
            return instance
        class Meta:
            model = User
            #序列化时返回的数据
            fields = ("username", "password", "name", "id", "phone")

    ( 2).users/views.py:

    from rest_framework import viewsets, permissions, mixins
    from .serializers import UserSerializer, UserRegSerializer
    from .filters import UserFilter
    from django_filters.rest_framework import DjangoFilterBackend
    from django.contrib.auth import get_user_model
    User = get_user_model()
    
    
    class UserViewset(mixins.RetrieveModelMixin,
                       mixins.UpdateModelMixin,
                       mixins.DestroyModelMixin,
                       mixins.ListModelMixin,
                       viewsets.GenericViewSet):
        """
        retrieve:
            获取指定user记录
        list:
            获取user列表
        update:
            更新user记录
        partial_update:
            更新user的部门字段
        destroy:
            删除user记录
        """
        queryset = User.objects.filter(is_superuser=False)
        serializer_class = UserSerializer
        filter_class=UserFilter
        filter_fields = ("username",)
    #有两个地方可控制你提交哪些方法:一个是此处的视图层,一个是序列化中(序列化中控制的是具体要怎么个做法动作)
    #UserRegViewset类想支持什么方法在此引入就好了
    class UserRegViewset(viewsets.GenericViewSet,
                         mixins.CreateModelMixin,
                         mixins.UpdateModelMixin):
        """
        create:
            用户注册
        partial_update:
            修改密码
        update:
            修改密码
        """
        queryset = User.objects.all()
        serializer_class = UserRegSerializer

    (3).users/router.py:

    from rest_framework.routers import DefaultRouter
    from .views import UserViewset, UserRegViewset
    router = DefaultRouter()
    router.register("users", UserViewset, basename="users")
    router.register("userReg", UserRegViewset, basename="userReg")

    (4)devops/urls.py:

    from django.conf.urls import url, include
    from rest_framework.routers import DefaultRouter
    from rest_framework.documentation import include_docs_urls
    from groupUsers .views import GroupUsersViewset
    from users.router import router as user_router
    router = DefaultRouter()
    router.registry.extend(user_router.registry)
    #
    
    from rest_framework.authtoken.views import obtain_auth_token
    urlpatterns = [
        url(r'^api/', include(router.urls)),  
        url(r'^', include('resources.urls')),
        url(r'^api-auth/', include('rest_framework.urls')),
        url(r'^docs/', include_docs_urls("51reboot接口文档")),
        url(r'^api-token-auth/', obtain_auth_token)
    ]

      上述中是以api开头的全部交给router.urls去处理,,因为到时我前端和后端可能放在一台服务器上,然后调动的时候只要不是api开头的全部交给nginx去处理,以api开头则交给django去处理。

    效果如下:

     

     

     二.展示用户列表--打通前后端

    1.vue环境搭建:

    参考https://www.cnblogs.com/dbslinux/p/13180500.html

    下载vue模版: 

     F:devopsdataweb>git clone https://github.com/gxhsh/vueAdmin-template.git

    安装nodejs:  F:devopsdatawebvue-admin-template>npm install --registry=https://registry.npm.taobao.org

     F:devopsdatawebvue-admin-template>npm run dev 

    2.配置:

     (2)src/permission.js ---取消权限

    import router from './router'
    // import store from './store'
    import NProgress from 'nprogress' // Progress 进度条
    import 'nprogress/nprogress.css'// Progress 进度条样式
    // import { Message } from 'element-ui'
    // import { getToken } from '@/utils/auth' // 验权
    
    // const whiteList = ['/login'] // 不重定向白名单
    router.beforeEach((to, from, next) => {
      NProgress.start()
      next()
      // if (getToken()) {
      //   if (to.path === '/login') {
      //     next({ path: '/' })
      //   } else {
      //     if (store.getters.roles.length === 0) {
      //       store.dispatch('GetInfo').then(res => { // 拉取用户信息
      //         next()
      //       }).catch(() => {
      //         store.dispatch('FedLogOut').then(() => {
      //           Message.error('验证失败,请重新登录')
      //           next({ path: '/login' })
      //         })
      //       })
      //     } else {
      //       next()
      //     }
      //   }
      // } else {
      //   if (whiteList.indexOf(to.path) !== -1) {
      //     next()
      //   } else {
      //     next('/login')
      //     NProgress.done()
      //   }
      // }
    })
    
    router.afterEach(() => {
      NProgress.done() // 结束Progress
    })

    效果如图

     (3)重新指向路由config/index.js

    (4)开发环境配置成本机config/dev.env.js

      BASE_API: '"http://127.0.0.1:8000"',

    (5)线上环境配置config/rpod.env.js

     BASE_API: '"http://127.0.0.1:8000"',

    (6)去掉不需要的路由router/index.js

     最终效果如下--这就是我的前端页面:

     注意上述图中url有#开头的路由,我可把它改成history模式---即/目录名/目录名。但如果以#开头的路由那我的nginx不用作任何处理,如果是history模式则需nginx支持--https://router.vuejs.org/zh/guide/essentials/history-mode.html

    打开 router/index.jx中的

    mode: 'history',
    效果如下:

    3.用户展示

    (1)router/index.js添加前端路由

      {
        path: '/users',
        component: Layout,
        name: 'users',
        meta: { title: '用户管理', icon: 'example' },
        children: [
          {
            path: 'user',
            name: 'user',
            component: () => import('@/views/users/user'),   <<<--引用下面定义的路由
            meta: { title: '用户', icon: 'table' }
          }
        ]
      },

    (2)前端视图views/users/user.vue

    <template>
      <div class="app-container">
        用户列表: {{ msg }}
      </div>
    </template>
    
    <script>
      export default {
        name: 'UserList',
        data() {
          return {
            msg: 'rock'
          }
        }
      }
    </script>
    
    <style scoped>
    
    </style>

    效果如图:

    浏览器装vue插件https://www.gugeapps.com/

     4.获取后端数据---在api中

     (1)api/user.js

    import request from '@/utils/request'
    
    export function getUserList(params) {
      return request({
        url: '/api/users/',
        method: 'get',
        params
      })
    }

    (2)users/user.vue中引入

    ................
    <script> import { getUserList } from '@/api/user' export default { name: 'UserList', data() { return { msg: 'rock' } }, created() { this.fetchUserList() }, methods: { fetchUserList() { getUserList() } } } </script>

    报如下错:

    (3)解决跨域参考github

    还不能解决跨域则如下配置:

    CORS_ALLOW_CREDENTIALS = True
    CORS_ORIGIN_ALLOW_ALL = True
    CORS_ORIGIN_WHITELIST = (
    'http://127.0.0.1:8000',
    ))

    (4) 解决前端request拦截器utils/request.js

    import axios from 'axios'
    import { Message } from 'element-ui'
    // import store from '../store'
    // import { getToken } from '@/utils/auth'
    
    // 创建axios实例
    const service = axios.create({
      baseURL: process.env.BASE_API, // api的base_url
      timeout: 15000 // 请求超时时间
    })
    
    // request拦截器
    // service.interceptors.request.use(config => {
    //   if (store.getters.token) {
    //     config.headers['X-Token'] = getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
    //   }
    //   return config
    // }, error => {
    //   // Do something with request error
    //   console.log(error) // for debug
    //   Promise.reject(error)
    // })
    
    // respone拦截器
    service.interceptors.response.use(
      response => {
      /**
      * code为非20000是抛错 可结合自己业务进行修改
      */
        return response.data
        // const res = response.data
        // if (res.code !== 20000) {
        //   Message({
        //     message: res.message,
        //     type: 'error',
        //     duration: 5 * 1000
        //   })
        //
        //   // 50008:非法的token; 50012:其他客户端登录了;  50014:Token 过期了;
        //   if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
        //     MessageBox.confirm('你已被登出,可以取消继续留在该页面,或者重新登录', '确定登出', {
        //       confirmButtonText: '重新登录',
        //       cancelButtonText: '取消',
        //       type: 'warning'
        //     }).then(() => {
        //       store.dispatch('FedLogOut').then(() => {
        //         location.reload()// 为了重新实例化vue-router对象 避免bug
        //       })
        //     })
        //   }
        //   return Promise.reject('error')
        // } else {
        //   return response.data
        // }
      },
      error => {
        console.log('err' + error)// for debug
        Message({
          message: error.message,
          type: 'error',
          duration: 5 * 1000
        })
        return Promise.reject(error)
      }
    )
    
    export default service

    (5)users/user.vue

    <template>
      <div class="app-container">
        用户列表:
      </div>
    </template>
    
    <script>
    import { getUserList } from '@/api/user'
    
    export default {
      name: 'UserList',
      data() {
        return {
          userList: []
        }
      },
      created() {
        this.fetchUserList()
      },
      methods: {
        fetchUserList() {
          getUserList().then(res => {
            this.userList = res.results
          })
        }
      }
    }
    </script>

    效果如图:已拿到数据

     5.将数据展示到页面----去element ui拿组件即可--https://element.eleme.io/#/

     users/user.vue:

    <template>
      <div class="app-container">
        <el-table
          :data="userList"
          stripe
          style=" 100%">
          <el-table-column
            prop="username"
            label="username"/>
          <el-table-column
            prop="name"
            label="姓名"/>
          <el-table-column
            prop="phone"
            label="电话"/>
          <el-table-column
            prop="email"
            label="email"/>
          <el-table-column
            prop="is_active"
            label="状态">
            <template slot-scope="scope">
              <el-switch v-model="scope.row.is_active" @change="handleUserStatusChange(scope.row)"/>
            </template>
          </el-table-column>
          <el-table-column
            prop="last_login"
            label="last_login"/>
          <el-table-column
            fixed="right"
            label="操作"
            width="100">
            <template slot-scope="scope">
              <el-button type="text" size="small" @click="handleModify(scope.row)">修改</el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>
    </template>
    。。。。。。。

    效果出来了:

     三.修改用户状态:

    (1)api/user.jss

    ......
    export function modifyUser(id, data) {
      return request({
        url: `/api/users/${id}/`,
        method: 'patch',
        data
      })
    }

    (2)users/user.vue

    <template>
      <div class="app-container">
        <el-table
          :data="userList"
          stripe
          style=" 100%">
          <el-table-column
            prop="username"
            label="username"/>
          <el-table-column
            prop="name"
            label="姓名"/>
          <el-table-column
            prop="phone"
            label="电话"/>
          <el-table-column
            prop="email"
            label="email"/>
          <el-table-column
            prop="is_active"
            label="状态">
            <template slot-scope="scope">
              <el-switch v-model="scope.row.is_active" @change="handleUserStatusChange(scope.row)"/>
            </template>
          </el-table-column>
          <el-table-column
            prop="last_login"
            label="last_login"/>
          <el-table-column
            fixed="right"
            label="操作"
            width="100">
            <template slot-scope="scope">
              <el-button type="text" size="small" @click="handleModify(scope.row)">修改</el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>
    </template>
    
    <script>
    import { getUserList, modifyUser } from '@/api/user'
    
    export default {
      name: 'UserList',
      data() {
        return {
          userList: []
        }
      },
      created() {
        this.fetchUserList()
      },
      methods: {
        fetchUserList() {
          getUserList().then(res => {
            this.userList = res.results
          })
        },
        handleUserStatusChange(obj) {
          modifyUser(obj.id, { is_active: obj.is_active }).then(() => {
            this.$message({
              message: `修改 ${obj.name} 的状态成功`,
              type: 'success'
            })
          })
        }
      }
    }
    </script>

    效果如下:

     四.添加用户/修改用户--此功能把它定义成组件

    https://element.eleme.io/#/zh-CN/component/installation

    我要的是弹框效果

     1.users/components/addUserForm.vue

    <template>
      <div class="add-user-form">
        <el-dialog :visible.sync="visible" title="用户信息" @close="handleClose">
          <el-form ref="addUserForm" :model="form" :rules="rules" label-width="100px">
            <el-form-item label="登陆名:" prop="username">
              <el-input v-model="form.username" placeholder="请输入登陆名"/>
            </el-form-item>
            <el-form-item label="姓名:" prop="name">
              <el-input v-model="form.name" placeholder="请输入姓名"/>
            </el-form-item>
            <el-form-item label="密码:" prop="password">
              <el-input v-model="form.password" type="password" placeholder="请输入密码"/>
            </el-form-item>
            <el-form-item label="手机号:" prop="phone">
              <el-input v-model="form.phone" placeholder="请输入手机号"/>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="submitForm">立即创建</el-button>
              <el-button @click="resetForm">重置</el-button>
            </el-form-item>
          </el-form>
          <div slot="footer" class="dialog-footer">
            <el-button @click="handleClose">取 消</el-button>
            <el-button type="primary" @click="handleClose">确 定</el-button>
          </div>
        </el-dialog>
      </div>
    </template>
    <script>
      import { addUser } from '@/api/user'
      export default {
        name: 'AddUserForm',
        props: {
          value: {
            type: Boolean,
            default: false
          }
        },
        data() {
          return {
            visible: false,
            form: {
              username: '',
              name: '',
              password: '',
              phone: ''
            },
            rules: {
              username: [
                { required: true, message: '请输入用户名', trigger: 'blur' }
              ],
              name: [
                { required: true, message: '请输入用户姓名', trigger: 'blur' }
              ],
              password: [
                { required: true, message: '请输入密码', trigger: 'blur' }
              ],
              phone: [
                { required: true, message: '请输入联系电话', trigger: 'blur' }
              ]
            }
          }
        },
        watch: {
          value(val) {
            this.visible = val
          }
        },
        methods: {
          handleClose() {
            this.visible = false
            this.$emit('input', false)
            this.resetForm()
          },
          resetForm() {
            this.$refs.addUserForm.resetFields()
          },
          submitForm() {
            this.$refs.addUserForm.validate((valid) => {
              if (valid) {
                addUser(this.form).then(() => {
                  this.$message({
                    message: `创建用户 ${this.form.name} 成功`,
                    type: 'success'
                  })
                  this.handleClose()
                  this.$emit('fetch')
                })
              } else {
                console.log('error submit!!')
                return false
              }
            })
          }
        }
      }
    </script>

    2.api/user.js

    import request from '@/utils/request'
    
    export function getUserList(params) {
      return request({
        url: '/api/users/',
        method: 'get',
        params
      })
    }
    
    export function getUser(userId) {
      return request({
        url: `/api/users/${userId}/`,
        method: 'get'
      })
    }
    
    export function modifyUser(id, data) {
      return request({
        url: `/api/users/${id}/`,
        method: 'patch',
        data
      })
    }
    
    export function addUser(data) {
      return request({
        url: `/api/userReg/`,
        method: 'post',
        data
      })
    }

    3.users/user.vue

    <template>
      <div class="app-container">
        <el-row>
          <el-col :span="12">
            <el-input v-model="params.username" placeholder="搜索用户名" @keyup.enter.native="handleSearch">
              <el-button slot="append" icon="el-icon-search" @click="handleSearch"/>
            </el-input>
          </el-col>
          <el-col :span="12" align="right" style="padding-right:20px;">
            <el-button type="primary" @click="addUserVisible=true">添加用户</el-button>
          </el-col>
        </el-row>
        <el-table
          :data="userList"
          stripe
          style=" 100%">
          <el-table-column
            prop="username"
            label="username"/>
          <el-table-column
            prop="name"
            label="姓名"/>
          <el-table-column
            prop="phone"
            label="电话"/>
          <el-table-column
            prop="email"
            label="email"/>
          <el-table-column
            prop="is_active"
            label="状态">
            <template slot-scope="scope">
              <el-switch v-model="scope.row.is_active" @change="handleUserStatusChange(scope.row)"/>
            </template>
          </el-table-column>
          <el-table-column
            prop="last_login"
            label="last_login"/>
          <el-table-column
            fixed="right"
            label="操作"
            width="100">
            <template slot-scope="scope">
              <el-button type="text" size="small" @click="handleModify(scope.row)">修改</el-button>
            </template>
          </el-table-column>
        </el-table>
        <el-row v-show="total>10" type="flex" justify="center" style="padding-top:20px;">
          <el-pagination
            :total="total"
            layout="prev, pager, next"
            background
            @current-change="handleChange" />
        </el-row>
        <AddUserForm v-model="addUserVisible" @fetch="handleFetch" />
        <ModifyUserForm v-model="modifyUserVisible" :user-id="userId" @fetch="handleFetch" />
      </div>
    </template>
    <script>
      import { getUserList, modifyUser } from '@/api/user'
      import AddUserForm from './components/addUserForm'
      import ModifyUserForm from './components/modifyUser'
      export default {
        name: 'UserList',
        components: {
          AddUserForm,
          ModifyUserForm
        },
        data() {
          return {
            userList: [],
            addUserVisible: false,
            modifyUserVisible: false,
            userId: 0,
            total: 0,
            params: {
              page: 1,
              username: ''
            }
          }
        },
        created() {
          this.fetchUserList()
        },
        methods: {
          fetchUserList() {
            getUserList(this.params).then(res => {
              this.userList = res.results
              this.total = res.count
            })
          },
          handleUserStatusChange(obj) {
            modifyUser(obj.id, { is_active: obj.is_active }).then(() => {
              this.$message({
                message: `修改 ${obj.name} 的状态成功`,
                type: 'success'
              })
            })
          },
          handleFetch() {
            this.fetchUserList()
          },
          handleModify(obj) {
            this.userId = obj.id
            this.modifyUserVisible = true
          },
          handleChange(val) {
            this.params.page = val
            this.fetchUserList()
          },
          handleSearch() {
            this.params.page = 1
            this.fetchUserList()
          }
        }
      }
    </script>

    效果如下:可创建用户了

    4.users/components/modifyUser.vue   ---用户修改功能

    <template>
      <div class="modify-user-form">
        <el-dialog :visible.sync="visible" :title="title" @close="handleClose">
          <el-form ref="modifyUserForm" :model="form" :rules="rules" label-width="100px">
            <el-form-item label="手机号:" prop="phone">
              <el-input v-model="form.phone" placeholder="请输入手机号"/>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="submitForm">修改</el-button>
              <el-button @click="resetForm">重置</el-button>
            </el-form-item>
          </el-form>
        </el-dialog>
      </div>
    </template>
    <script>
    import { getUser, modifyUser } from '@/api/user'
    export default {
      name: 'ModifyUser',
      props: {
        value: {
          type: Boolean,
          default: false
        },
        userId: {
          type: Number,
          default: 0
        }
      },
      data() {
        return {
          visible: false,
          userObj: null,
          form: {
            phone: ''
          },
          rules: {
            phone: [
              { required: true, message: '请输入联系电话', trigger: 'blur' }
            ]
          },
          uid: 0,
          title: ''
        }
      },
      watch: {
        value(val) {
          this.visible = val
        },
        userId(val) {
          if (val === 0) return
          this.uid = val
          this.fetchUser()
        }
      },
      methods: {
        handleClose() {
          this.visible = false
          this.$emit('input', false)
          this.userId = 0
          this.userObj = null
          this.resetForm()
          this.title = ''
        },
        resetForm() {
          this.$refs.modifyUserForm.resetFields()
          if (this.userId === 0) return
          if (this.userObj === null) return
          this.form.phone = this.userObj.phone
        },
        submitForm() {
          this.$refs.modifyUserForm.validate((valid) => {
            if (valid) {
              modifyUser(this.userId, this.form).then(() => {
                this.$message({
                  message: `创建用户 ${this.userObj.name} 手机号成功`,
                  type: 'success'
                })
                this.handleClose()
                this.$emit('fetch')
              })
            } else {
              console.log('error submit!!')
              return false
            }
          })
        },
        fetchUser() {
          getUser(this.uid).then(res => {
            this.title = `修改 ${res.name} 的信息`
            this.userObj = res
            this.form.phone = res.phone
          })
        }
      }
    }
    </script>

    1

    2

    3

  • 相关阅读:
    Eclipse(MyEclipse)使用技巧——改动凝视字体大小
    C++标准库之 Lower_Bound, upper_Bound
    Mongodb地理空间索引
    AfxMessageBox和MessageBox差别
    具体解释VB中连接access数据库的几种方法
    C++中this指针的使用方法.
    秒杀多线程第四篇 一个经典的多线程同步问题
    设计模式学习03—抽象工厂模式
    Neutron中的Service类
    Opencv学习笔记(六)SURF学习笔记
  • 原文地址:https://www.cnblogs.com/dbslinux/p/13308294.html
Copyright © 2011-2022 走看看