一.工单系统需求分析

 

 

 

 

 

 

二.工单系统后端

(python36env) [vagrant@CentOS devops]$ django-admin startapp workorder
(python36env) [vagrant@CentOS devops]$ mv workorder apps/

settings.py:
INSTALLED_APPS = [
    .....
    \'workorder\',
    .......
]

(1)apps/workorder/models.py:

from django.db import models
from users.models import User

class WorkOrder(models.Model):
    TYPE = (
        (0, \'数据库\'),
        (1, \'WEB服务\'),
        (2, \'计划任务\'),
        (3, \'配置文件\'),
        (4, \'其它\'),
    )
    STATUS = (
        (0, \'申请\'),
        (1, \'处理中\'),
        (2, \'完成\'),
        (3, \'失败\'),
    )
    title = models.CharField(max_length=100, verbose_name=u\'工单标题\')
    type = models.IntegerField(choices=TYPE, default=0, verbose_name=u\'工单类型\')
    order_contents = models.TextField(verbose_name=\'工单内容\')
    applicant = models.ForeignKey(User, verbose_name=u\'申请人\', related_name=\'work_order_applicant\',on_delete=models.CASCADE)
    assign_to = models.ForeignKey(User, verbose_name=u\'指派给\',on_delete=models.CASCADE)
    final_processor = models.ForeignKey(User, null=True, blank=True, verbose_name=u\'最终处理人\', related_name=\'final_processor\',on_delete=models.CASCADE)
    status = models.IntegerField(choices=STATUS, default=0, verbose_name=u\'工单状态\')
    result_desc = models.TextField(verbose_name=u\'处理结果\', blank=True, null=True)
    apply_time = models.DateTimeField(auto_now_add=True, verbose_name=u\'申请时间\')
    complete_time = models.DateTimeField(auto_now=True, verbose_name=u\'处理完成时间\')

    def __str__(self):
        return self.title

    class Meta:
        verbose_name = \'工单\'
        verbose_name_plural = verbose_name
        ordering = [\'-complete_time\']

(python36env) [vagrant@CentOS devops]$ python manage.py makemigrations workorder

(python36env) [vagrant@CentOS devops]$ python manage.py migrate workorder

(2)workorder/serializers.py:

from rest_framework import serializers
from django.contrib.auth import get_user_model
from .models import WorkOrder
from datetime import  datetime

User = get_user_model()


class WorkOrderSerializer(serializers.ModelSerializer):
    """
    工单序列化类
    """
    # 获取当前登陆用户,并将其赋值给数据库中对应的字段
    applicant = serializers.HiddenField(
        default=serializers.CurrentUserDefault())
    # 后端格式时间
    # apply_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", read_only=True)
    # complete_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", read_only=True)

    class Meta:
        model = WorkOrder
        fields = "__all__"

    def to_representation(self, instance):
        applicant_obj = instance.applicant
        assign_to_obj = instance.assign_to
        final_processor_obj = instance.final_processor
        type_value = instance.get_type_display()
        # print("new:", type_value)
        # print("old:", instance.type)
        status_value = instance.get_status_display()
        ret = super(WorkOrderSerializer, self).to_representation(instance)
        ret[\'type\'] = {
             "id": instance.type,
             "name": type_value
        }
        ret[\'status\'] = {
            "id": instance.status,
            "name": status_value
        }
        ret["applicant"] = {
                               "id": applicant_obj.id,
                               "name": applicant_obj.name
                           },
        ret["assign_to"] = {
                               "id": assign_to_obj.id,
                               "name": assign_to_obj.name
                           },
        if final_processor_obj:
            ret["final_processor"] = {
                                "id": final_processor_obj.id,
                                "name": final_processor_obj.name
                            },
        # print(ret)
        return ret

    # def create(self, validated_data):
    #     applicant = self.context[\'request\'].user   #获取用户信息
    #     validated_data[\'applicant\'] = applicant
    #     print(validated_data)
    #     instance = self.Meta.model.objects.create(**validated_data)
    #     instance.save()
    #     return instance

    # def update(self, instance, validated_data):
    #     final_processor = self.context[\'request\'].user
    #     print(validated_data)
    #     validated_data[\'final_processor\'] = final_processor
    #     instance = self.Meta.model.objects.filter(id=instance.id).update(**validated_data)
    #     return instance

(3)workorder/views.py:

from django.contrib.auth import get_user_model
from rest_framework import viewsets, mixins,permissions, status
from rest_framework.response import Response
from rest_framework.pagination import PageNumberPagination
from rest_framework import filters
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.authentication import TokenAuthentication,BasicAuthentication,SessionAuthentication
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
import    time

from .serializers import WorkOrderSerializer
from .models import WorkOrder

User = get_user_model()


class Pagination(PageNumberPagination):
    page_size = 10
    page_size_query_param = \'page_size\'
    page_query_param = "page"
    max_page_size = 100


class WorkOrderViewset(viewsets.ModelViewSet):
    """
    create:
    创建工单
    list:
    获取工单列表
    retrieve:
    获取工单信息
    update:
    更新更新信息
    delete:
    删除用户
    """
    authentication_classes = (JSONWebTokenAuthentication, TokenAuthentication, SessionAuthentication, BasicAuthentication)
    permission_classes = (permissions.IsAuthenticated, permissions.DjangoModelPermissions)
    queryset = WorkOrder.objects.all()
    serializer_class = WorkOrderSerializer
    pagination_class = Pagination
    filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
    search_fields = (\'title\', \'order_contents\')
    ordering_fields = (\'id\',)

    def get_queryset(self):
        status = self.request.GET.get(\'status\', None)
        applicant = self.request.user
        # 获取当前登陆用户所有组的信息, RBAC   用户-->组-->权限
        role = applicant.groups.all().values(\'name\')
        # print(role)
        role_name = [r[\'name\'] for r in role]
        # print(role_name)
        queryset = super(WorkOrderViewset, self).get_queryset()

        # 判断传来的status值判断是申请列表还是历史列表
        if status and int(status) == 1:
            queryset = queryset.filter(status__lte=int(status))
        elif status and int(status) == 2:
            queryset = queryset.filter(status__gte=int(status))
        else:
            pass

        # 判断登陆用户是否是管理员,是则显示所有工单,否则只显示自己的
        if "sa" not in role_name:
            queryset = queryset.filter(applicant=applicant)
        return queryset

    def partial_update(self, request, *args, **kwargs):
        pk = int(kwargs.get("pk"))
        print(pk)
        final_processor = self.request.user
        data = request.data
        data[\'final_processor\'] = final_processor
        data[\'complete_time\'] = time.strftime(\'%Y-%m-%d    %H:%M:%S\', time.localtime(time.time()))
        print(data)
        WorkOrder.objects.filter(pk=pk).update(**data)
        return Response(status=status.HTTP_204_NO_CONTENT)

(4)workorder/filters.py

import django_filters

from django.contrib.auth import get_user_model
from.models import WorkOrder


User = get_user_model()


class WorkOrderFilter(django_filters.rest_framework.FilterSet):
    """
    工单过滤类
    """
    class Meta:
        model = WorkOrder
        fields = [\'title\']

(5)workorder/router.py:

from rest_framework.routers import DefaultRouter
from .views import WorkOrderViewset

workorder_router = DefaultRouter()
workorder_router.register(r\'workorder\', WorkOrderViewset, basename="workorder")

(6)devops/urls.py

from workorder.router import workorder_router
router.registry.extend(workorder_router.registry)

效果如图:

 

 

三.工单前端处理

安装插件:

F:\devops\data\web\vueAdmin-template>npm install moment  –save

1.工单基础页面实现

(1)src/api/workorder/workorder.js

import request from \'@/utils/request\'

// 获取工单列表
export function getWorkOrderList(params) {
  return request({
    url: \'/api/workorder/\',
    method: \'get\',
    params
  })
}

// 创建工单
export function createWorkOrder(data) {
  return request({
    url: \'/api/workorder/\',
    method: \'post\',
    data
  })
}

// 修改工单
export function updateWorkOrder(id, data) {
  return request({
    url: \'/api/workorder/\' + id + \'/\',
    method: \'patch\',
    data
  })
}

// 删除工单
export function deleteWorkOrder(id) {
  return request({
    url: \'/api/workorder/\' + id + \'/\',
    method: \'delete\'
  })
}

(2)src/router/index.js

  {
    path: \'/workorder\',
    component: Layout,
    name: \'workorder\',
    meta: { title: \'工单系统\', icon: \'form\' },
    children: [
      {
        path: \'apply\',
        name: \'工单申请\',
        meta: { title: \'工单申请\', icon: \'form\' }
      },
      {
        path: \'list\',
        name: \'申请列表\',
        component: () => import(\'@/views/workorder/list/index\'),
        meta: { title: \'申请列表\', icon: \'table\' }
      },
      {
        path: \'history\',
        name: \'工单历史\',
        meta: { title: \'工单历史\', icon: \'table\' }
      }
    ]
  },

(3)views/workorder/list/index.vue

<template>
  <div class="workorder">
    <div>
      <!--搜索-->
      <el-col :span="8">
        <el-input v-model="params.search" placeholder="搜索" @keyup.enter.native="searchClick">
          <el-button slot="append" icon="el-icon-search" @click="searchClick"/>
        </el-input>
      </el-col>
    </div>

    <!--表格-->
    <order-list :value="workorders" @rate="handleRate" @edit="handleEdit" @delete="handleDelete"/>

    <!--模态窗任务进度-->
    <el-dialog
      :title="currentValue.title"
      :visible.sync="dialogVisibleForRate"
      width="30%">
      <div style="height: 300px;">
        <el-steps :active="active" direction="vertical" finish-status="success" >
          <el-step
            v-for="(item,index) in rate"
            :title="item.title"
            :description="item.description"
            :key="index" />
        </el-steps>
      </div>
    </el-dialog>

    <!--模态窗工单处理-->
    <el-dialog
      :visible.sync="dialogVisibleForEdit"
      title="工单处理"
      width="50%">
      <order-form
        ref="workorderForm"
        :form="currentValue"
        @submit="handleSubmitEdit"
        @cancel="handleCancelEdit"/>
    </el-dialog>

    <!--分页-->
    <center>
      <el-pagination
        :page-size="pagesize"
        :total="totalNum"
        background
        layout="total, prev, pager, next, jumper"
        @current-change="handleCurrentChange"/>
    </center>
  </div>
</template>

<script>
  import { getWorkOrderList, updateWorkOrder } from \'@/api/workorder/workorder\'
  import OrderList from \'./table\'

  export default {
    name: \'Workorder\',
    components: {
      OrderList
    },

    data() {
      return {
        dialogVisibleForEdit: false,
        dialogVisibleForRate: false,
        currentValue: {},
        workorders: [],
        totalNum: 0,
        pagesize: 10,
        active: 1,
        apply: {},
        assign: {},
        final_processor: {},
        rate: [],
        params: {
          page: 1,
          search: \'\',
          status: 1
        }
      }
    },

    created() {
      this.fetchData()
    },

    methods: {
      fetchData() {
        getWorkOrderList(this.params).then(
          res => {
            this.workorders = res.results
            console.log(this.workorders)
            this.totalNum = res.count
          })
      },
      handleCurrentChange(val) {
        this.params.page = val
        this.fetchData()
      },
      searchClick() {
        this.fetchData()
      },
      /* 流程进度处理函数 */
      handleRate(value) {
        this.currentValue = { ...value }
        console.log(value)
        this.dialogVisibleForRate = true
        this.rate = []
        this.final_processor = {}
        this.apply[\'title\'] = \'任务申请: \' + value.applicant[0].name + \': \' + value.apply_time
        this.assign[\'title\'] = \'任务分配: \' + value.assign_to[0].name
        if (value.final_processor) {
          this.final_processor[\'title\'] = \'任务领取: \' + value.final_processor[0].name + \': \' + value.complete_time
          this.active = 3
        }
        this.rate.push(this.apply)
        this.rate.push(this.assign)
        this.rate.push(this.final_processor)
      },

      /*  处理工单,弹出模态窗、提交数据、取消 */
      handleEdit(value) {
        this.currentValue = { ...value }
        console.log(this.currentValue)
        const data = { \'status\': 1 }
        const id = this.currentValue.id
        updateWorkOrder(id, data).then(res => {
          this.$message({
            message: \'接受工单\',
            type: \'success\'
          })
          this.dialogVisibleForEdit = true
          this.fetchData()
        })
      },

      handleSubmitEdit(value) {
        const { id, ...params } = value // 很神奇,能把表单的值拆解成自己想要的样子
        console.log(params)
        const data = { \'status\': 2, \'result_desc\': params.result_desc }
        updateWorkOrder(id, data).then(res => {
          this.$message({
            message: \'更新成功\',
            type: \'success\'
          })
          this.handleCancelEdit()
          this.fetchData()
        })
      },
      handleCancelEdit() {
        this.dialogVisibleForEdit = false
        this.$refs.workorderForm.$refs.form.resetFields()
      },

      /* 取消 */
      handleDelete(id) {
        const data = { \'status\': 3 }
        updateWorkOrder(id, data).then(res => {
          this.$message({
            message: \'取消成功\',
            type: \'success\'
          })
          this.fetchData()
        },
        err => {
          console.log(err.message)
        })
      }
    }
  }
</script>

<style lang=\'scss\' scoped>
  .workorder {
    padding: 10px;
  }
</style>

(4)views/workorder/list/table.vue

<template>
  <div class="workorder-list">
    <el-table
      :data="value"
      border
      stripe
      style="width: 100%">

      <el-table-column type="expand">
        <template slot-scope="props">
          <span><pre>工单详情:{{ props.row.order_contents }}</pre></span>
        </template>
      </el-table-column>

      <el-table-column
        label="工单类型"
        prop="type.name"/>

      <el-table-column
        label="工单标题"
        prop="title"/>

      <el-table-column
        label="申请人"
        prop="applicant[0].name"/>

      <el-table-column
        label="工单状态"
        prop="status.name"/>

      <el-table-column
        label="任务进度"
        align="center">
        <template slot-scope="scope">
          <el-button type="text" size="small" @click="handleRate(scope.row)">
            {{ \'任务进度\' }}
          </el-button>
        </template>
      </el-table-column>

      <el-table-column
        :formatter="dateFormat"
        label="申请时间"
        prop="apply_time"
      />

      <el-table-column label="操作">
        <template slot-scope="scope">
          <el-button
            size="mini"
            type="primary"
            @click="handleEdit(scope.row)">处理</el-button>

          <el-button
            size="mini"
            type="danger"
            @click="handleDelete(scope.row)">取消</el-button>
        </template>
      </el-table-column>

    </el-table>
  </div>
</template>

<script>
import moment from \'moment\'

export default {
  name: \'OrderList\',
  props: {
    value: {
      type: Array,
      default: function() {
        return []
      }
    }
  },
  methods: {
    /* 点击编辑按钮,将子组件的事件传递给父组件 */
    handleEdit(value) {
      this.$emit(\'edit\', value)
    },

    /* 流程进度 */
    handleRate(value) {
      this.$emit(\'rate\', value)
    },

    /* 删除 */
    handleDelete(workorder) {
      const id = workorder.id
      const name = workorder.title
      this.$confirm(`此操作将删除: ${name}, 是否继续?`, \'提示\', {
        confirmButtonText: \'确定\',
        cancelButtonText: \'取消\',
        type: \'warning\'
      }).then(() => {
        this.$emit(\'delete\', id)
      }).catch(() => {
        this.$message({
          type: \'info\',
          message: \'已取消删除\'
        })
      })
    },
    dateFormat: function(row, column) {
      const date = row[column.property]
      if (date === undefined) {
        return \'\'
      }
      return moment(date).format(\'YYYY-MM-DD HH:mm:ss\')
    }

  }
}
</script>

<style lang=\'scss\'>
</style>

效果如图:

 

 2.历史工单

(1)src/router/index.js

    {
        path: \'history\',
        name: \'工单历史\',
        component: () => import(\'@/views/workorder/history/index\'),
        meta: { title: \'工单历史\', icon: \'table\' }
      }

(1)workorder/history/index.vue

<template>
  <div class="workorder">
    <div>
      <!--搜索-->
      <el-col :span="8">
        <el-input v-model="params.search" placeholder="搜索" @keyup.enter.native="searchClick">
          <el-button slot="append" icon="el-icon-search" @click="searchClick"/>
        </el-input>
      </el-col>
    </div>

    <!--表格-->
    <order-list :value="workorders"/>

    <!--分页-->
    <center>
      <el-pagination
        :page-size="pagesize"
        :total="totalNum"
        background
        layout="total, prev, pager, next, jumper"
        @current-change="handleCurrentChange"/>
    </center>
  </div>
</template>

<script>
import { getWorkOrderList } from \'@/api/workorder/workorder\'
import OrderList from \'./table\'

export default {
  name: \'Workorder\',
  components: {
    OrderList
  },

  data() {
    return {
      workorders: [],
      totalNum: 0,
      pagesize: 10,
      params: {
        page: 1,
        status: 2
      }
    }
  },

  created() {
    this.fetchData()
  },

  methods: {
    fetchData() {
      getWorkOrderList(this.params).then(
        res => {
          this.workorders = res.results
          console.log(this.workorders)
          this.totalNum = res.count
        })
    },
    handleCurrentChange(val) {
      this.params.page = val
      this.fetchData()
    },
    searchClick() {
      this.fetchData()
    }

  }

}
</script>

<style lang=\'scss\' scoped>
.workorder {
  padding: 10px;
}
</style>

(3)workorder/table.vue

<template>
  <div class="workorder-list">
    <el-table
      :data="value"
      border
      stripe
      style="width: 100%">

      <el-table-column type="expand">
        <template slot-scope="props">
          <span>工单详情:{{ props.row.order_contents }}</span>
          <br>
          <span>处理结果:{{ props.row.result_desc }}</span>
        </template>
      </el-table-column>

      <el-table-column
        label="工单类型"
        prop="type.name"/>

      <el-table-column
        label="工单标题"
        prop="title"/>

      <el-table-column
        label="申请人"
        prop="applicant[0].name"/>

      <el-table-column
        label="指派人"
        prop="assign_to[0].name"/>

      <el-table-column
        label="处理人"
        prop="final_processor[0].name"/>

      <el-table-column
        label="状态"
        prop="status.name"/>

      <el-table-column
        :formatter="dateFormat"
        label="申请时间"
        prop="apply_time"/>

      <el-table-column
        :formatter="dateFormat"
        label="完成时间"
        prop="complete_time"/>

    </el-table>
  </div>
</template>

<script>
import moment from \'moment\'
export default {
  name: \'OrderList\',
  props: {
    value: {
      type: Array,
      default: function() {
        return []
      }
    }
  },
  methods: {
    dateFormat: function(row, column) {
      var date = row[column.property]
      if (date === undefined) {
        return \'\'
      }
      return moment(date).format(\'YYYY-MM-DD HH:mm:ss\')
    }
  }
}
</script>

<style lang=\'scss\'>
.workorder-list {}
</style>

效果图:

 

 

 

点击工单处理时报如错:

 

jango.core.exceptions.ValidationError: [\'’2020-07-21\t22:55:55‘ 必须为合法的日期时间格式,请使用 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] 格式。\']

解决:

注掉workorder/views.py:
        # data[\'complete_time\'] = time.strftime(\'%Y-%m-%d    %H:%M:%S\', time.localtime(time.time()))
并打开workorder/serializers.py:
apply_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", read_only=True)
complete_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", read_only=True)

3.工单状态流转及步骤条实现

(1)workorder/list/form.vue

<template>
  <div class="workorder-form">
    <el-form ref="form" :model="form" :rules="rules" label-width="100px" class="demo-form">

      <el-form-item label="工单标题" prop="title">
        <el-input v-model="form.title" readonly/>
      </el-form-item>

      <el-form-item label="工单内容" prop="order_contents">
        <el-input v-model="form.order_contents" type="textarea" rows="8" readonly/>
      </el-form-item>

      <el-form-item label="处理结果" prop="result_desc">
        <el-input v-model="form.result_desc"/>
      </el-form-item>

      <el-form-item>
        <div class="btn-wrapper">
          <el-button size="small" @click="cancel">取消</el-button>
          <el-button size="small" type="primary" @click="submitForm">保存</el-button>
        </div>
      </el-form-item>

    </el-form>
  </div>
</template>

<script>

export default {
  name: \'OrderForm\',
  props: {
    form: { // 接受父组件传递过来的值渲染表单
      type: Object,
      default() {
        return {
          title: \'\',
          order_contents: \'\',
          result_desc: \'\'
        }
      }
    }
  },

  data() {
    return {
      rules: {
        result_desc: [
          { required: true, message: \'请输入处理结果\', trigger: \'blur\' }
        ]
      }
    }
  },

  methods: {
    submitForm() {
      this.$refs.form.validate(valid => {
        if (!valid) {
          return
        }
        this.$emit(\'submit\', this.form)
      })
    },
    cancel() {
      this.$emit(\'cancel\')
    }
  }
}
</script>

<style lang=\'scss\' scoped>
.workorder-form {
  position: relative;
  display: block;
  .btn-wrapper{
    text-align: right;
  }
}
</style>

(2)workorder/list/index.vue

...
import OrderForm from \'./form\'
....
  export default {
    name: \'Workorder\',
    components: {
      OrderList,
      OrderForm
    },

效果如图:

点击工单处理时如下报错:[Vue warn]: Invalid prop: type check failed for prop “rows”. Expected Number, got String.

 

 解决办法:

form.vue:中改成如下
        <el-input :rows="8" v-model="form.order_contents" type="textarea"  readonly/>

最终效果如下图:

 

 

 4.工单申请

(1)workorder/apply/index.vue

<template>
  <div class="apply">
    <el-form ref="form" :model="form" :rules="rules" label-width="180px">
      <el-form-item label="工单类型:" prop="type">
        <el-select v-model="form.type" placeholder="请选择工单类型" style="width: 60%;">
          <el-option
            v-for="item in type_list"
            :key="item.index"
            :label="item.name"
            :value="item.id"/>
        </el-select>
      </el-form-item>

      <el-form-item label="工单标题:" prop="title">
        <el-input v-model="form.title" style="width: 60%;"/>
      </el-form-item>

      <el-form-item label="工单内容:" prop="order_contents">
        <el-input :rows="8" v-model="form.order_contents" type="textarea"  style="width: 60%;"/>
      </el-form-item>

      <el-form-item label="指派给:" prop="assign_to">
        <el-select v-model="form.assign_to" filterable placeholder="请选择工单处理人" style="width: 60%;">
          <el-option
            v-for="item in sa_list"
            :key="item.index"
            :label="item.name"
            :value="item.id"/>
        </el-select>
      </el-form-item>

      <el-form-item>
        <el-button type="primary" @click="onSubmit">Create</el-button>
        <el-button @click="onCancel">Cancel</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>

import { getGroupMemberList } from \'@/api/group\'
import { createWorkOrder } from \'@/api/workorder/workorder\'
export default {
  data() {
    return {
      form: {
        type: \'\',
        title: \'\',
        order_contents: \'\',
        assign_to: \'\'
      },
      rules: {
        type: [
          { required: true, message: \'请输入工单类型\', trigger: \'blur\' }
        ],
        title: [
          { required: true, message: \'请输人工单标题\', trigger: \'blur\' }
        ],
        order_contents: [
          { required: true, message: \'请输人工单内容\', trigger: \'blur\' }
        ],
        assign_to: [
          { required: true, message: \'请输人工单指派人\', trigger: \'blur\' }
        ]

      },
      sa_list: [],
      type_list: [{ \'id\': 0, \'name\': \'数据库\' }, { \'id\': 1, \'name\': \'计划任务\' }, { \'id\': 2, \'name\': \'配置文件\' }, { \'id\': 3, \'name\': \'其他\' }],
      state: 0
    }
  },

  watch: {
    state() {
      getGroupMemberList(6).then(res => {
        this.sa_list = res.members
        console.log(this.sa_list)
      })
    }
  },

  created() {
    this.state = 1
  },

  methods: {
    onSubmit() {
      this.$message(\'submit!\')
      this.$refs.form.validate((valid) => {
        if (!valid) {
          return
        }
        const params = Object.assign({}, this.form)
        console.log(params)
        createWorkOrder(params).then(res => {
          this.$message({
            message: \'创建成功\',
            type: \'success\'
          })
          this.$router.push({ path: \'/workorder/list\' })
        })
      })
    },
    onCancel() {
      this.$message({
        message: \'cancel!\',
        type: \'warning\'
      })
    }
  }

}
</script>

<style scoped>
.apply{
    margin-top:2cm;
}
</style>

(2)src/router/index.js

import Vue from \'vue\'
import Router from \'vue-router\'

// in development-env not use lazy-loading, because lazy-loading too many pages will cause webpack hot update too slow. so only in production use lazy-loading;
// detail: https://panjiachen.github.io/vue-element-admin-site/#/lazy-loading

Vue.use(Router)

/* Layout */
import Layout from \'../views/layout/Layout\'

/**
 * hidden: true                   if `hidden:true` will not show in the sidebar(default is false)
 * alwaysShow: true               if set true, will always show the root menu, whatever its child routes length
 *                                if not set alwaysShow, only more than one route under the children
 *                                it will becomes nested mode, otherwise not show the root menu
 * redirect: noredirect           if `redirect:noredirect` will no redirect in the breadcrumb
 * name:\'router-name\'             the name is used by <keep-alive> (must set!!!)
 * meta : {
    title: \'title\'               the name show in submenu and breadcrumb (recommend set)
    icon: \'svg-name\'             the icon show in the sidebar,
  }
 **/
export const constantRouterMap = [
  { path: \'/login\', component: () => import(\'@/views/login/index\'), hidden: true },
  { path: \'/404\', component: () => import(\'@/views/404\'), hidden: true },
  {
    path: \'/\',
    component: Layout,
    redirect: \'/dashboard\',
    name: \'Dashboard\',
    children: [{
      path: \'dashboard\',
      component: () => import(\'@/views/dashboard/index\'),
      meta: { title: \'dashboard\', icon: \'example\' }
    }]
  },
  {
    path: \'/users\',
    component: Layout,
    name: \'users\',
    meta: { title: \'用户管理\', icon: \'example\' },
    children: [
      {
        path: \'user\',
        name: \'user\',
        component: () => import(\'@/views/users/user\'),
        meta: { title: \'用户\' }
      },
      {
        path: \'groups\',
        name: \'groups\',
        permission: \'resources.add_ip\',
        component: () => import(\'@/views/groups\'),
        meta: { title: \'用户组\' }
      }
    ]
  },
  {
    path: \'/workorder\',
    component: Layout,
    name: \'workorder\',
    meta: { title: \'工单系统\', icon: \'form\' },
    children: [
      {
        path: \'apply\',
        name: \'工单申请\',
        component: () => import(\'@/views/workorder/apply/index\'),
        meta: { title: \'工单申请\', icon: \'form\' }
      },
      {
        path: \'list\',
        name: \'申请列表\',
        component: () => import(\'@/views/workorder/list/index\'),
        meta: { title: \'申请列表\', icon: \'table\' }
      },
      {
        path: \'history\',
        name: \'工单历史\',
        component: () => import(\'@/views/workorder/history/index\'),
        meta: { title: \'工单历史\', icon: \'table\' }
      }
    ]
  },
  { path: \'*\', redirect: \'/404\', hidden: true }
]

export default new Router({
  mode: \'history\',
  scrollBehavior: () => ({ y: 0 }),
  routes: constantRouterMap
})

效果如下图:但是却获取不到用户列表—no data

 

 

 

 

 

 

 

 

1

 

版权声明:本文为dbslinux原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/dbslinux/archive/2004/01/13/13352932.html