三.运维平台之工单系统
一.工单系统需求分析
二.工单系统后端
- (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