工单项目(前端)用于思考

1 Vue端

1.1 http

1.1.1 aips.js
//将我们http.js中封装好的  get,post.put,delete,patch  导过来
import { axios_get, axios_post, axios_delete, axios_put, axios_patch } from './index.js'


//按照格式确定方法名
export const user_login = P => axios_post("/user/login/", P)  // 用户登录

// 用户模块
// 用户信息管理
export const get_userlist = P => axios_get('/user/user/?page='+P, P)            // 获取用户列表
export const get_userlist_new = P => axios_get('user/user_get/', P)             // 获取用户列表(不包含分页的接口)
export const add_user = P => axios_post('/user/register/', P)                   // 注册新用户
export const search_for = P => axios_get('user/user/', P)                       // 根据用户名查找指定用户信息并展示
export const delete_user = P => axios_delete('/user/user/' + P + '/')           // 根据获取到的用户id删除用户信息
export const update_user = P => axios_put('/user/user/'+ P.id +'/', P)          // 根据用户id和提交来的数据修改用户信息

// 角色管理
export const get_rolelist = P => axios_get('/user/role/?page='+P, P)            // 获取角色列表
export const get_rolelist_new = P => axios_get('/user/role_get/', P)            // 获取角色列表(不包含分页的接口)
export const add_role = P => axios_post('/user/role/', P)                       // 注册新角色
export const search_for_role = P => axios_get('user/role/', P)                  // 根据角色名查找指定角色信息并展示
export const delete_role = P => axios_delete('/user/role/' + P + '/')           // 根据获取到的角色id删除角色信息
export const update_role = P => axios_put('/user/role/'+ P.id +'/', P)          // 根据角色id和提交来的数据修改角色信息

// 工单模块---分类工单
export const get_flowtypelist = P => axios_get('/workflow/flowtype/?page='+P, P)            // 获取模板分类列表
export const get_flowtypelist_new = P => axios_get('/workflow/flowtype_get/', P)            // 获取模板分类列表(不含分页)
export const add_flowtype = P => axios_post('/workflow/flowtype/', P)                       // 创建新模板分类
export const search_for_flowtype = P => axios_get('/workflow/flowtype/', P)                  // 根据模板分类名查找指定模板分类信息并展示
export const delete_flowtype = P => axios_delete('/workflow/flowtype/' + P + '/')           // 根据获取到的模板分类id删除模板分类信息
export const update_flowtype = P => axios_put('/workflow/flowtype/'+ P.id +'/', P)          // 根据模板分类id和提交来的数据修改模板分类信息

// 工单模块---工单模板
export const get_flowconflist = P => axios_get('/workflow/flowconf/?page='+P, P)            // 获取工单模板列表
export const get_flowconflist_new = P => axios_get('/workflow/flowconf_get/', P)            // 获取工单模板列表(不含分页)
export const add_flowconf = P => axios_post('/workflow/flowconf/', P)                       // 创建新工单模板
export const search_for_flowconf = P => axios_get('/workflow/flowconf/', P)                 // 根据工单模板名查找指定工单模板信息并展示
export const delete_flowconf = P => axios_delete('/workflow/flowconf/' + P + '/')           // 根据获取到的工单模板id删除工单模板信息
export const update_flowconf = P => axios_put('/workflow/flowconf/'+ P.id +'/', P)          // 根据工单模板id和提交来的数据修改工单模板信息

// 工单模块---配置审批流
export const get_approveconflist = P => axios_get('/workflow/approveconf/?page='+P, P)            // 获取配置审批流列表
export const get_approveconflist_new = P =>axios_get('/workflow/approveconf/?flowconf='+P.flowconf, P)      // 获取指定模板的审批流
export const add_approveconf = P => axios_post('/workflow/approveconf/', P)                       // 配置新审批流
export const delete_approveconf = P => axios_delete('/workflow/approveconf/' + P + '/')           // 根据审批流id删除审批流信息
export const update_approveconf = P => axios_put('/workflow/approveconf/'+ P.id +'/', P)          // 根据审批流id和提交来的数据修改审批流信息

// 实例化工单
export const add_workorder = P => axios_post('/workerorder/workorder/', P)                   // 数据库添加实例化工单

// 工单管理---实例工单页面
export const get_workerorder = P => axios_get('/workerorder/workorder/', P)                      // 获取实例化工单列表
export const search_workerorder = P => axios_get('/workerorder/workorder_search/', P)            // 查找我的工单
// 工单管理---实例子工单页面(由实例工单页面带参跳转)
export const get_suborder = P => axios_get('/workerorder/suborder_get/', P)                      // 获取实例化工单列表
export const search_suborder = P => axios_get('/workerorder/suborder_search/', P)            // 查找能审批的工单
// 获取子工单审批状态
export const get_suborder_auth = P => axios_get('/workerorder/suborder/', P)
// 审批子工单
export const add_suborder = P => axios_post('/workerorder/suborder_get/', P)            // 获取实例化工单列表

// 判断是否是超级管理员

export const is_superuser = P => axios_get('/user/is_superuser/', P)
1.1.2 index.js
import axios from 'axios'

// 第一步:设置axios
axios.defaults.baseURL = "http://192.168.56.100:1594/"

//全局设置网络超时
axios.defaults.timeout = 10000;

//设置请求头信息
axios.defaults.headers.post['Content-Type'] = 'application/json';
axios.defaults.headers.put['Content-Type'] = 'application/json';


// 第二:设置拦截器
/**
 * 请求拦截器(当前端发送请求给后端前进行拦截)
 * 例1:请求拦截器获取token设置到axios请求头中,所有请求接口都具有这个功能
 * 例2:到用户访问某一个页面,但是用户没有登录,前端页面自动跳转 /login/ 页面
 */
axios.interceptors.request.use(
    config => {
        // 每次发送请求之前判断是否存在token,如果存在,则统一在http请求的header都加上token,不用每次请求都手动添加了
        const token = localStorage.getItem("token")
            // console.log(token)
        if (token) {
            config.headers.Authorization = 'JWT ' + token
        }
        return config;
    },
    error => {
        return Promise.error(error);
    })

axios.interceptors.response.use(
    // 请求成功,因为 API返回的状态码有多个,所以一定要在这里写上,不然会无法访问页面
    res => res.status === 200 || 201 || 204 ? Promise.resolve(res) : Promise.reject(res),
    // 请求失败
    error => {
        if (error.response) {
            // 判断一下返回结果的status == 401?  ==401跳转登录页面。  !=401passs
            // console.log(error.response)
            if (error.response.status === 401) {
                // 跳转不可以使用this.$router.push方法、
                // this.$router.push({path:'/login'})
                window.location.href = "http://127.0.0.1:8080/"
            } else {
                // errorHandle(response.status, response.data.message);
                return Promise.reject(error.response);
            }
            // 请求已发出,但是不在2xx的范围
        } else {
            // 处理断网的情况
            // eg:请求超时或断网时,更新state的network状态
            // network状态在app.vue中控制着一个全局的断网提示组件的显示隐藏
            // 关于断网组件中的刷新重新获取数据,会在断网组件中说明
            // store.commit('changeNetwork', false);
            return Promise.reject(error.response);
        }
    });


// 第三:封装axios请求
// 3.1 封装get请求
export function axios_get(url, params) {
    return new Promise(
        (resolve, reject) => {
            axios.get(url, {params:params})
                .then(res => {
                    // console.log("封装信息的的res", res)
                    resolve(res.data)
                }).catch(err => {
                    reject(err.data)
                })
        }
    )
}

// 3.2 封装post请求
export function axios_post(url, data) {
    return new Promise(
        (resolve, reject) => {
            // console.log(data)
            axios.post(url, JSON.stringify(data))
                .then(res => {
                    // console.log("封装信息的的res", res)
                    resolve(res.data)
                }).catch(err => {
                    reject(err.data)
                })
        }
    )
}

// 3.3 封装put请求
export function axios_put(url, data) {
    return new Promise(
        (resolve, reject) => {
            // console.log(data)
            axios.put(url, JSON.stringify(data))
                .then(res => {
                    // console.log("封装信息的的 res", res)
                    resolve(res.data)
                }).catch(err => {
                    reject(err.data)
                })
        }
    )
}

// 3.4 封装patch请求(可用于局部修改)

export function axios_patch(url, data) {
    return new Promise(
        (resolve, reject) => {
            // console.log(data)
            axios.patch(url, JSON.stringify(data))
                .then(res => {
                    // console.log("封装信息的的res", res)
                    resolve(res.data)
                }).catch(err => {
                    reject(err.data)
                })
        }
    )
}

// 3.5 封装delete请求
export function axios_delete(url, data) {
    return new Promise(
        (resolve, reject) => {
            // console.log(data)
            axios.delete(url, { params: data })
                .then(res => {
                    // console.log("封装信息的的res", res)
                    resolve(res.data)
                }).catch(err => {
                    // reject(err.data)
                })
        }
    )
}

1.2 router

1.2.1 index.js
  • 这里采用了子路由,在主页中直接<路由名></路由名>就可以引用组件
import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/components/layout/Home'
const page = name => () => import('@/views/' + name)
Vue.use(Router)

export default new Router({
  mode: 'history',
  routes: [
    { path: '/login',component: page('Login'),name: '登录'},
    { path: '/',component: Home,name: 'home',
      children: [
        { path: 'usermanage', component: page('user-manage/index'), name: '信息管理' },
        { path: 'rolemanage', component: page('role-manage/index'), name: '角色管理' },
        { path: 'flowtype', component: page('flowtype-manage/index'), name: '模板分类管理' },
        { path: 'flowconf', component: page('flowconf-manage/index'), name: '工单模板管理' },
        { path: 'approveconf', component: page('approveconf-manage/index'), name: '新建模板管理' },
        { path: 'workorder', component: page('workorder-manage/index'), name: '创建工单' },
        { path: 'flowconfform', component: page('flowconfform-manage/index'), name: '实例化工单form' },
        { path: 'childconfform', component: page('childconfform-manage/index'), name: '实例化子工单form' },
        { path: 'workerorder', component: page('workerorder-manage/index'), name: '查看工单' },
        { path: 'suborder', component: page('suborder-manage/index'), name: '查看子工单' },
        { path: 'start', component: page('StartPage'), name: '首页猫咪' },
        { path: 'baidu', component: page('BaiDu'), name: '跳转百度' },     
      ]
    },
  ]
})

1.3 components

  • 公用组件
1.3.1 Header.vue
<template>
        <div><a style="float:right" @click="outLogin">注销登录</a>
          <h3 style="margin-top:20px">           
          欢迎你
           <a-icon type="smile" theme="outlined" style="font-size:20px;color:pink"/>&ensp;
          {{username}}
            <a-icon type="fire" style="font-size:25px;color:pink"/>&ensp;
          </h3>         
        </div>
</template>
<script>
export default{
    data(){
        return{
          username:localStorage.getItem('username')
        }
    },
    methods:{
      outLogin(){
        localStorage.removeItem('token')
        localStorage.removeItem('username')
        localStorage.removeItem('uid')
        alert('注销登录成功,稍后为您跳转登录页面')
        this.$router.push('/login')
      }
    }
}
</script>
1.3.2 Home.vue
<template>
         <div id="components-layout-demo-basic" style="">
            <a-layout>
                <a-layout-sider style="height:250px;width:150px">
                    <LeftMenu></LeftMenu>
                    <!-- 以组件发昂视导入左侧菜单 -->
                </a-layout-sider>
                <a-layout>

                    <a-layout-header  style="height:80px;width:500px;background:rgb(253,234,254)">
                        <Header/>
                        <!-- 导入头部 -->
                    </a-layout-header>
                    
                        <div style="margin-left:100px">
                            <!-- 这里的 router-view 是绑定的路由 -->
                            <p><router-view></router-view></p>
                        </div>
                        
                </a-layout>

            </a-layout>
        </div>
</template>

<script>
// 导入组件
import LeftMenu from '@/components/layout/LeftMenu'
import Header from '@/components/layout/Header'
export default {
    // 注册组件
    components:{
        LeftMenu,
        Header
    },
    data() {
        
        return {

        }
    },
    methods: {

    },
    created() {

    }
}
</script>

<style scoped>
#components-layout-demo-basic {
  text-align: center;
}
#components-layout-demo-basic .ant-layout-header {
  background: white;
}
#components-layout-demo-basic .ant-layout-footer {
  background: rgb(253,234,254);
  color: rgb(253,234,254);
}
#components-layout-demo-basic .ant-layout-footer {
  line-height: 1.5;
}
#components-layout-demo-basic .ant-layout-sider {
  background: rgb(253,234,254);
  color: rgb(253,234,254);
  line-height: 120px;
}
#components-layout-demo-basic .ant-layout-content {
  background: white;
  color: white;
  min-height: 120px;
  line-height: 120px;
}
.ant-layout.ant-layout-has-sider{
  width:1530px;
  height: 722px;
  background:rgb(253,234,254)
}
.ant-layout{
  background:rgb(253,234,254);
  width:800px
}
</style>
1.3.3 LeftMenu.vue
<template>
  <div>
    <a-switch :default-checked="false" @change="changeMode" style="margin-top:70px"/>&emsp;
    <br>
    <a-menu
      style="width: 300px;background:rgb(253,234,254)"
      :default-selected-keys="['1']"
      :default-open-keys="['sub1']"
      :mode="mode"
      :theme="theme"
      @click="handleClick"
      
    >
    <!-- 必须定义click方法,handleClick是用来跳转路由的,内置毁掉参数e,包括传递上去的key路由地址 -->
      <a-sub-menu >
        <span slot="title">
          <a-icon type="user" />
          <span>用户模块</span>
        </span>
          
          <a-menu-item key="usermanage" title="用户信息管理" style="background:rgb(253,234,254)">
            信息管理
          </a-menu-item>
          <!-- key是路由地址 -->

          <a-menu-item key="rolemanage" title="工单模板" style="background:rgb(253,234,254)">
            角色管理
          </a-menu-item>


       </a-sub-menu>
      

      <a-menu-item key="baidu">
        <a-icon type="calendar" />
        百度翻译
      </a-menu-item>
      <a-sub-menu key="workflow" style="background:rgb(253,234,254)">
        <span slot="title">
          <a-icon type="appstore" />
          <span>模板管理</span>
        </span>
          
          <a-menu-item key="flowtype" title="工单分类" style="background:rgb(253,234,254);">
            模板分类
          </a-menu-item>

          <a-menu-item key="flowconf" title="工单模板" style="background:rgb(253,234,254)">
            新建模板
          </a-menu-item>

       </a-sub-menu>
    
      <a-sub-menu key="workorder">
        <span slot="title"><a-icon type="setting" /><span>工单管理</span></span>
              
          <a-menu-item key="workorder" style="background:rgb(253,234,254)">
          新建工单
          </a-menu-item>

          <a-menu-item key="workerorder"  style="background:rgb(253,234,254)">
          查看我的工单
          </a-menu-item>
          <a-menu-item key="suborder"  style="background:rgb(253,234,254)">
          查看我的子工单
          </a-menu-item>

      </a-sub-menu>
    </a-menu>
  </div>
</template>
<script>
import { is_superuser } from '@/http/apis'
export default {
  data() {
    return {
      mode: 'inline',
      theme: 'light',
      current: '1'
    };
  },
  methods: {
    changeMode(checked) {
      this.mode = checked ? 'vertical' : 'inline';
    },
    changeTheme(checked) {
      this.theme = checked ? 'dark' : 'light';
    },
     handleClick(e) {
      this.current = e.key;
      console.log(this.current)
      console.log(e.domEvent)
      is_superuser().then(res=>{
        if(res.type == 1 || this.current == 'workorder' || this.current == 'workerorder' || this.current == 'suborder'){
            this.$router.push({path:this.current});
            // click方法默认回调参数中的 key,所以 e.key就是传递来的路由
        }else{
          alert('您不是管理员,没有权限访问哦!')
        }
      })

    },
  },
};
</script>
<style>
.a-menu{
  background:rgb(253,234,254);
    width: 5500px;
}
.ul{
  background:rgb(253,234,254)
}
.ant-menu-submenu > .ant-menu{
  background-color: rgb(253,234,254);

}
</style>

1.4 views

1.4.1 user-manage

  • 用户组件
  • 只允许超级有用户访问
1 index.vue
<template>
<div>
  <div id="components-layout-demo-basic">
     <a-layout>
        <a-layout-header>
          <BreadCrumb style="float:left"></BreadCrumb>

        </a-layout-header>
        <a-layout>
            <a-layout-content>
            <div style="margin-bottom:80px">
                <a-button type="danger" ghost style="float:left;margin-left:20px;margin-top:16px;color:pink;border-color:pink;font-size:16px" @click="addNew">
                AddUser
                </a-button>
                <EditForm
                    :visible.sync="visible"
                    :userList='userList'
                    :roleList='roleList'
                    @add="add"
                >
                <!-- .sync控制组件是否显示 -->
                </EditForm>
                <Search 
                  style="margin-bottom:-20px;margin-top:10px" 
                  :searchList="searchList"
                  @find="find"
                  @getUser="getUser"
                >
                </Search>
                
            </div>
                <TableList
                  :userListGet="userListGet"
                  :userList="userList"
                  @getUser="getUser"
                  @add="add"
                >
                </TableList>
                <Pagination
                  @getPage="getPage" 
                  :count="count" 
                  style="margin-top:20px; "             
                ></Pagination>
                <p></p>
            </a-layout-content>
        </a-layout>
     </a-layout>
  </div>
</div>
</template>

<script>
import BreadCrumb from "./components/BreadCrumb";
import TableList from "./components/TableList";
import Search from "./components/Search";
import EditForm from "./components/EditForm";
import Pagination from "./components/Pagination"

import { add_user, search_for, get_userlist, update_user } from '@/http/apis';
import { delete_user } from '../../http/apis';
import { get_rolelist_new, add_role_user } from '../../http/apis';
export default {
    components:{
        BreadCrumb,
        TableList,
        Search,
        EditForm,
        Pagination
    },
    data() {
        return {
            visible:false,
            userList: {
              'id':'',
              // 'is_superuser':'',
              'username': '',
              'passowrd': '',
              'password_new': '',
              'email':'',
              'mobile':'',
              'weixin':'',
              'roles':[]
              // 没定义roles字段的话,没办法绑定
            },
            roleList: [],
            userListGet:[],
            searchList:{
                'username':'',
                'page':1,
                'page_size':4

            },
            updateUserList:[],
            // 当前页码
            current:1,
            // 总共的数据多少条
            count:0,
            addRoleList:[]

        }
    },
    methods: {
        addNew(){
          this.visible = true
          this.userList = {
              'id':'',
              'username': '',
              'passowrd': '',
              'password_new': '',
              'email':'',
              'mobile':'',
              'weixin':'',
              'roles':[],
            }
          // 用于控制组件显示
        },
        add(role_list){
          if(this.userList.id){            
            this.visible = true  
            update_user(this.userList).then(res=>{
              // alert('修改成功')
              this.getUser()
            })

          }else{
            
            // 添加用户,子组件中编辑的值实际上是写在父组件上面的
            add_user(this.userList).then(res=>{
              
              console.log(res)
              alert('添加新用户成功')
              this.getUser()
              
          })   
            this.visible=false       
          }
        },
        find(){
          // 根据用户名查找用户信息
          search_for(this.searchList).then(res=>{
            // 阔落的办法可以解决bug,但是不支持查询出多条数据,因为没办法分页
            // if(this.searchList.username){
            //   // 修复如果没有搜索数据,回车就只能显示一个页面的bug
            //   console.log(res)
            //   this.userListGet = res.results
            //   this.count = res.results.length
            // }else{
            //   this.getUser()
            // }
            this.getUser()

          })
        },
        getUser(){
          this.searchList.page = this.current
          // 获取用户信息列表,父组件传递给子组件
          get_userlist(this.searchList).then(res=>{
            this.userListGet = res.results
            this.count = res.count
            console.log(this.count)
            console.log(this.userListGet)

          })
        },
        // 获取页码
        getPage(currentChild){
          // 获取到的currentChild是子组件传递过来是第几页
          this.current = currentChild
          console.log(this.current)
          this.getUser()
        },
        getRole(){
            get_rolelist_new().then(res=>{
                this.roleList = res
                console.log(111111)
                console.log(this.roleList)
            })
        }
    },
    created() {
      this.getRole()
    }
}
</script>

<style scoped>
#components-layout-demo-basic {
  text-align: center;
}
#components-layout-demo-basic .ant-layout-header,
#components-layout-demo-basic .ant-layout-footer {
  background: white;
  color: #fff;
}
#components-layout-demo-basic .ant-layout-footer {
  line-height: 1.5;
}
#components-layout-demo-basic .ant-layout-content {
  background: white;
  color: #fff;
  min-height: 120px;
  line-height: 120px;
}
#components-layout-demo-basic > .ant-layout {
  margin-bottom: 48px;
}
#components-layout-demo-basic > .ant-layout:last-child {
  margin: 0;
}
</style>
2 components
2.1 BreadCrumb.vue
<template>
    <div>
        <a-breadcrumb>
            <br>
            <a-breadcrumb-item href="">
            <a-icon type="home" />
            </a-breadcrumb-item>

            <a-breadcrumb-item href="">
            <a-icon type="user" />
            <span>首页</span>

            </a-breadcrumb-item>
            <a-breadcrumb-item>
            用户模块
            </a-breadcrumb-item>
            <a-breadcrumb-item>
            信息管理页面
            </a-breadcrumb-item>
        </a-breadcrumb>
    </div>
</template>

<script>
export default {
    name:"BreadCrumb",
    data() {
        return {

        }
    },
    methods: {

    },
    created() {

    }
}
</script>

<style scoped>

</style>
2.2 EditForm.vue
<template>
    <div>
        <a-modal
        title="Please write now."
        :visible="visible"
        @ok="handleOk"
        @cancel="handleCancel"
        >
        <!-- @ok控制按钮ok -->
        <!-- @cancel控制按钮cancel -->
            <p v-if="userList.id">UserName:
                <a-input 
                style="width:380px;float:right" 
                placeholder="username" 
                v-model="userList.username"
                disabled="disabled"
                ></a-input>                
            </p>
            <p v-else>UserName:
                <a-input 
                style="width:380px;float:right" 
                placeholder="username" 
                v-model="userList.username"
                ></a-input>
            </p>
            <br>
            <div v-if="userList.id">

            </div>
            <div v-else>
            <p>PassWord:
                <a-input
                    v-decorator="[
                        'password',
                        { rules: [{ required: true, message: 'Please input your Password!' }] },
                    ]"
                    type="password"
                    placeholder="Password"
                    style="width:380px;float:right"
                    v-model="userList.password"
                    :disabled = 'false'
                >
                    <a-icon slot="prefix" type="lock" style="color:rgba(0,0,0,.25)" />
                </a-input>
            </p>
            <br>
            <p>PassWord Again:
                <a-input
                    v-decorator="[
                        'password',
                        { rules: [{ required: true, message: 'Please input your Password!' }] },
                    ]"
                    type="password"
                    placeholder="Password"
                    style="width:340px;float:right"
                    v-model="userList.password_new"
                >
                    <a-icon slot="prefix" type="lock" style="color:rgba(0,0,0,.25)" />
                </a-input>
            </p>
            </div>
            <br>
            <p>Email:
                <a-input style="width:410px;float:right" placeholder="Email" v-model="userList.email"></a-input>
            </p>
            <br>
            <p>Mobile:
                <a-input style="width:410px" placeholder="Mobile" v-model="userList.mobile"></a-input>
            </p>
            <br>
            <p>Weixin:
                <a-input style="width:410px" placeholder="WeiXin" v-model="userList.weixin"></a-input>
            </p>
            <br>
            <p v-show="userList.id!=''">Is_superuser:
                <a-input style="width:370px" placeholder="SuperUser" v-model="userList.is_superuser" disabled="disabled"></a-input>
            
            </p>
            <br>
            <p>Role:
             <a-select
                mode="multiple"               
                style="width: 410px; float:right"
                placeholder="Please select"
                @change="handleChange"
                v-model="userList.roles"
             >
                <a-select-option v-for="i in roleList" :key="i.id" >
                {{ i.zh_name }}
                </a-select-option>
            </a-select>
            </p>
        </a-modal>

    </div>
</template>

<script>
export default {
    props:['visible', 'userList', 'roleList'],
    data() {
        return {
        }
    },
    methods: {
        handleOk(e) {
            this.$emit('add', this.role)
            // add方法的调用一定要在关闭弹窗上面,否则方法不执行完毕没有办法关闭弹窗
            // 调用父组件中 add 方法            
            this.$emit('update:visible', false)
            // 把 visible 的值更新为 false,控制组件不显示

        },
        handleCancel(e) {
            this.$emit('update:visible', false)
            // 把 visible 的值更新为 false,控制组件不显示
        },
        handleChange(value) {
            // console.log(`selected ${value}`);
            console.log(value)
            this.userList.roles = value
        },
    },
    created() {

    }
}
</script>

<style scoped>

</style>
2.3 Pagination.vue
<template>
  <div>
    <a-pagination
      show-quick-jumper
      :default-current="2"
      :pageSize = '4'
      :total="count"
      show-less-items
      @change="onChange"
      v-model="current"

    />
  </div>
</template>

<script>
export default {
    props:[ 'count' ],
    data() {
        return {
            current:1
        }
    },
    methods: {
        
        onChange() {
            this.$emit('getPage', this.current)
    },
    },
    created() {

    }
}
</script>

<style scoped>

</style>
2.4 Search.vue
<template>
    <div>
        <a-input-search placeholder="Input the username that you want to search for..." enter-button @search="onSearch" style="float:right;width:400px;" v-model="searchList.username"/>
    </div>
</template>

<script>
export default {
    props:['searchList'],
    data() {
        return {

        } 
    },
    methods: {
        onSearch(){
            this.$emit('find')
            // 调用父组件中的find方法
        }
    },
    created() {

    }
}
</script>

<style scoped>

</style>
2.5 TableList.vue
<template>
  <a-table 
    :columns="columns" 
    :data-source="userListGet" 
    :rowKey="(record,index)=>{return index}"
    :pagination= 'false'
    style="height:430px"
  >
  <!-- 带:的都是属性绑定,不可以更换名字,带 : 就是 js 环境 -->
    <!-- 不写:rowKey="(record,index)=>{return index}"浏览器会发出警告 -->
    <p slot="roles" slot-scope="roles">
      <a-tag
        v-for="role in roles"
        :key="role.id"
        color="pink"
      >
        {{ role.role__zh_name }}
      </a-tag>
    </p>
    <p slot="tags" slot-scope="text,tags,i">
      <!-- 加入操作的按钮! -->
      <a-button @click="delUser(text,tags,i)">删除</a-button>
      <a-button @click="updateUser(text,tags,i)">修改</a-button>
    </p>
    
  </a-table>
</template>

<script>
const columns = [
    {
    title: 'ID',
    dataIndex: 'id',
    key: 'id',
    // ellipsis: true,
    width: 50,
  },
  {
    title: 'UserName',
    dataIndex: 'username',
    key: 'username',
    scopedSlots: { customRender: 'username' },
    width: 80,
  },
  {
    title: 'Email',
    dataIndex: 'email',
    key: 'email',
    width: 100,
  },
  {
    title: 'Mobile',
    dataIndex: 'mobile',
    key: 'mobile',
    ellipsis: true,
    width: 100,
  },
  {
    title: 'WeiXin',
    dataIndex: 'weixin',
    key: 'weixin',
    ellipsis: true,
    width: 80,
  },
  {
    title: 'Is SuperUser',
    dataIndex: 'is_superuser',
    key: 'is_superuser',
    ellipsis: true,
    width: 90,
  },
    {
    title: 'Roles',
    dataIndex: 'roles',
    key: 'roles',
    ellipsis: true,
    width: 150,
    scopedSlots : { customRender: 'roles'}
    // 不写的话显示不了标签
  },
  {
    title:'操作',
    dataIndex: 'tags',
    key : 'tags',
    width: 100,
    scopedSlots : { customRender: 'tags'}
    // scopedSlots: { customRender: 'tags' },一定不能少不然渲染不了html标签

  }

]

import { delete_user } from '@/http/apis'
export default {
  props:[ 'userListGet', 'userList'],
  data() {
    return {
      columns,
    }
  },
  methods:{
    get(){
        this.$emit('getUser')
        // 调用父组件中的获取用户列表的方法
    },
    delUser(text,tags,i){
      // 定义变量 isDel来控制 confirm,isDel==true执行的就是对话框的 ok,isDel==false执行的就是对话框的 false
        const isDel = confirm('你确定要删除' + tags.id)
        if(isDel==true){
          delete_user(tags.id).then(
          res=>{
            // 删除回调地址是  http://192.168.56.100:1594/id/
            this.get()
            alert('删除成功啦~')
          })
        }else{
            alert('有需要再叫我哈~')
        }
             
    },
    updateUser(text,tags,i){
      const roleIds = []
      tags.roles.forEach(item => {
        roleIds.push(item.role__id)
      });

      this.userList.id = tags.id
      this.userList.username = tags.username
      this.userList.password = tags.password,
      this.userList.password_new = tags.password
      this.userList.email = tags.email
      this.userList.mobile = tags.mobile
      this.userList.weixin = tags.weixin
      this.userList.is_superuser = tags.is_superuser
      // 传一个角色id的列表给父组件
      this.userList.roles = roleIds     
      this.$emit('add')
    }
  },
  created(){
    this.get()
  }
};
</script>

1.4.2 role-manage

  • 角色组件
  • 只允许超级有用户访问
1 index.vue
<template>
<div>
  <div id="components-layout-demo-basic">
     <a-layout>
        <a-layout-header>
          <p></p>
          <BreadCrumb style="float:left"></BreadCrumb>
          <p></p>

        </a-layout-header>
        <a-layout>
            <a-layout-content>
            <div style="margin-bottom:80px">
                <a-button  type="danger" ghost style="float:left;margin-left:20px;margin-top:16px;color:pink;border-color:pink;font-size:16px" @click="addNew">
                AddRole
                </a-button>
                <p></p>
                <EditForm
                    :visible.sync="visible"
                    :roleList='roleList'
                    @add="add"
                >
                <!-- .sync控制组件是否显示 -->
                </EditForm>
                <Search 
                  style="margin-bottom:-20px;margin-top:10px" 
                  :searchList="searchList"
                  @find="find"
                  @getRole="getRole"
                >
                </Search>
                
            </div>
                <TableList
                  :roleListGet="roleListGet"
                  :roleList="roleList"
                  @getRole="getRole"
                  @add="add"
                >
                </TableList>

                <Pagination
                  @getPage="getPage" 
                  :count="count"
                  style="margin-top:20px;"              
                ></Pagination>
                <p></p>
                
            </a-layout-content>
        </a-layout>
     </a-layout>
  </div>
</div>
</template>

<script>
import BreadCrumb from "./components/BreadCrumb";
import TableList from "./components/TableList";
import Search from "./components/Search";
import EditForm from "./components/EditForm";
import Pagination from "./components/Pagination"

import { add_role, search_for_role, get_rolelist, update_role } from '@/http/apis';
import { delete_role } from '../../http/apis';
export default {
    components:{
        BreadCrumb,
        TableList,
        Search,
        EditForm,
        Pagination
    },
    data() {
        return {
            visible:false,
            roleList: {
              'id':'',
              'zh_name': '',
              'en_name': '',
              'description':''
            },
            roleListGet:[],
            searchList:{
                'zh_name':'',
                'page':1,
                'page_size':4,
                
            },
            updateRoleList:[],
            // 当前页码
            current:1,
            // 总共的数据多少条
            count:0

        }
    },
    methods: {
        addNew(){
          this.visible = true
          this.roleList = {
              'id':'',
              'zh_name': '',
              'en_name': '',
              'description':''
            }
          // 用于控制组件显示
        },
        add(){
          if(this.roleList.id){            
            this.visible = true  
            update_role(this.roleList).then(res=>{
              // alert('修改成功')
              this.getRole()
            })

          }else{
            // 添加用户,子组件中编辑的值实际上是写在父组件上面的
            add_role(this.roleList).then(res=>{
              console.log(res)
              alert('添加新用户成功')
              this.getRole()
              
          })   
            this.visible=false       
          }
        },
        find(){
          // 根据用户名查找用户信息
          search_for_role(this.searchList).then(res=>{
              this.getRole()
              // 数据解耦性!!!查询和查询某个其实可以调用同一个接口!
              // 查询所有:http://192.168.56.100:1594/?page=1&zh_name=
              // 查询某个:http://192.168.56.100:1594/?page=1&zh_name=
            
          })
        },
        getRole(){
          this.searchList.page = this.current
          // 获取用户信息列表,父组件传递给子组件
          get_rolelist(this.searchList).then(res=>{
            this.roleListGet = res.results
            this.count = res.count
            console.log(this.count)
            console.log(this.roleListGet)
          })
        },
        // 获取页码
        getPage(currentChild){
          // 获取到的currentChild是子组件传递过来是第几页
          this.current = currentChild
          console.log(this.current)
          this.getRole()
        }
    },
    created() {

    }
}
</script>

<style scoped>
#components-layout-demo-basic {
  text-align: center;
}
#components-layout-demo-basic .ant-layout-header,
#components-layout-demo-basic .ant-layout-footer {
  background: white;
  color: #fff;
}
#components-layout-demo-basic .ant-layout-footer {
  line-height: 1.5;
}
#components-layout-demo-basic .ant-layout-content {
  background: white;
  color: #fff;
  min-height: 120px;
  line-height: 120px;
}
#components-layout-demo-basic > .ant-layout {
  margin-bottom: 48px;
}
#components-layout-demo-basic > .ant-layout:last-child {
  margin: 0;
}
</style>
2 components
2.1 BreadCrumb.vue
<template>
    <div>
        <a-breadcrumb>
            <a-breadcrumb-item href="">
            <a-icon type="home" />
            </a-breadcrumb-item>

            <a-breadcrumb-item href="">
            <a-icon type="user" />
            <span>首页</span>

            </a-breadcrumb-item>
            <a-breadcrumb-item>
            用户模块
            </a-breadcrumb-item>
            <a-breadcrumb-item>
            角色管理页面
            </a-breadcrumb-item>
        </a-breadcrumb>
    </div>
</template>

<script>
export default {
    name:"BreadCrumb",
    data() {
        return {

        }
    },
    methods: {

    },
    created() {

    }
}
</script>

<style scoped>

</style>
2.2 EditForm.vue
<template>
    <div>
        <a-modal
        title="Please write now."
        :visible="visible"
        @ok="handleOk"
        @cancel="handleCancel"
        >
        <!-- @ok控制按钮ok -->
        <!-- @cancel控制按钮cancel -->
            <p v-if="roleList.id">ZhName:
                <a-input 
                style="width:400px;float:right" 
                placeholder="zh_rname"
                v-model="roleList.zh_name"
                disabled="disabled"
                ></a-input>                
            </p>
            <p v-else>ZhName:
                <a-input 
                style="width:390px;float:right" 
                placeholder="zh_name" 
                v-model="roleList.zh_name"
                ></a-input>
            </p>
            <br>
            <p>EnName:
                <a-input style="width:380px;float:right" placeholder="Description" v-model="roleList.en_name"></a-input>
            </p>
            <br>
            <p>Description:
                <a-input style="width:380px;float:right" placeholder="Description" v-model="roleList.description"></a-input>
            </p>
        </a-modal>

    </div>
</template>

<script>
export default {
    props:['visible', 'roleList'],
    data() {
        return {
        }
    },
    methods: {
        handleOk(e) {
            this.$emit('add')
            // add方法的调用一定要在关闭弹窗上面,否则方法不执行完毕没有办法关闭弹窗
            // 调用父组件中 add 方法            
            this.$emit('update:visible', false)
            // 把 visible 的值更新为 false,控制组件不显示

        },
        handleCancel(e) {
            this.$emit('update:visible', false)
            // 把 visible 的值更新为 false,控制组件不显示
        },
    },
    created() {

    }
}
</script>

<style scoped>

</style>
2.3 Pagination.vue
<template>
  <div>
    <a-pagination
      show-quick-jumper
      :default-current="2"
      :pageSize = '4'
      :total="count"
      show-less-items
      @change="onChange"
      v-model="current"

    />
  </div>
</template>

<script>
export default {
    props:[ 'count' ],
    data() {
        return {
            current:1
        }
    },
    methods: {
        
        onChange() {
            this.$emit('getPage', this.current)
            // this.$emit('getPage')
    },
    },
    created() {

    }
}
</script>

<style scoped>

</style>
2.4 Search.vue
<template>
    <div>
        <a-input-search placeholder="Input the rolename that you want to search for..." enter-button @search="onSearch" style="float:right;width:400px" v-model="searchList.zh_name"/>
    </div>
</template>

<script>
export default {
    props:['searchList'],
    data() {
        return {

        } 
    },
    methods: {
        onSearch(){
            this.$emit('find')
            // 调用父组件中的find方法
        }
    },
    created() {

    }
}
</script>

<style scoped>

</style>
2.5 TableList.vue
<template>
  <a-table 
    :columns="columns" 
    :data-source="roleListGet" 
    :rowKey="(record,index)=>{return index}"
    :pagination= 'false'
  >
  <!-- 带:的都是属性绑定,不可以更换名字,带 : 就是 js 环境 -->
    <!-- 不写:rowKey="(record,index)=>{return index}"浏览器会发出警告 -->
    <p slot="tags" slot-scope="text,tags,i">
      <!-- 加入操作的按钮! -->
      <a-button @click="delRole(text,tags,i)">删除</a-button>
      <a-button @click="updateRole(text,tags,i)">修改</a-button>
    </p>
  </a-table>
</template>

<script>
const columns = [
    {
    title: 'ID',
    dataIndex: 'id',
    key: 'id',
    // ellipsis: true,
    width: 50,
  },
  {
    title: 'ZhName',
    dataIndex: 'zh_name',
    key: 'zh_name',
    scopedSlots: { customRender: 'zh_name' },
    width: 80,
  },
  {
    title: 'EnName',
    dataIndex: 'en_name',
    key: 'en_name',
    width: 100,
  },
    {
    title: 'Description',
    dataIndex: 'description',
    key: 'description',
    width: 100,
  },
  {
    title:'操作',
    dataIndex: 'tags',
    key : 'tags',
    width: 100,
    scopedSlots : { customRender: 'tags'}
    // scopedSlots: { customRender: 'tags' },一定不能少不然渲染不了html标签

  }
]

import { delete_role } from '@/http/apis'
export default {
  props:[ 'roleListGet', 'roleList'],
  data() {
    return {
      columns,
    }
  },
  methods:{
    get(){
        this.$emit('getRole')
        // 调用父组件中的获取用户列表的方法
    },
    delRole(text,tags,i){
      // 定义变量 isDel来控制 confirm,isDel==true执行的就是对话框的 ok,isDel==false执行的就是对话框的 false
        const isDel = confirm('你确定要删除')
        if(isDel==true){
          delete_role(tags.id).then(
          res=>{
            // 删除回调地址是  http://192.168.56.100:1594/id/
            this.get()
            alert('删除成功啦~')
          })
        }else{
            alert('有需要再叫我哈~')
        }
             
    },
    updateRole(text,tags,i){
      this.roleList.id = tags.id
      this.roleList.zh_name = tags.zh_name
      this.roleList.en_name = tags.en_name,
      this.roleList.description = tags.description     
      this.$emit('add')
    }
  },
  created(){
    this.get()
  }
};
</script>

1.4.3 flowtype-manage

  • 工单分类组件
  • 只允许超级有用户访问
1 index.vue
<template>
<div>
  <div id="components-layout-demo-basic">
     <a-layout>
        <a-layout-header>
          <BreadCrumb style="float:left"></BreadCrumb>

        </a-layout-header>
        <a-layout>
            <a-layout-content>
            <div style="margin-bottom:80px">
                <a-button  type="danger" ghost style="float:left;margin-left:20px;margin-top:16px;color:pink;border-color:pink;font-size:16px" @click="addNew">
                AddFlowType
                </a-button>
                <p></p>
                <EditForm
                    :visible.sync="visible"
                    :flowTypeList='flowTypeList'
                    @add="add"
                >
                <!-- .sync控制组件是否显示 -->
                </EditForm>
                <Search 
                  style="margin-bottom:-20px;margin-top:10px" 
                  :searchList="searchList"
                  @find="find"
                  @getFlowType="getFlowType"
                >
                </Search>
                <p></p>
                
            </div>
                <TableList
                  :flowTypeListGet="flowTypeListGet"
                  :flowTypeList="flowTypeList"
                  @getFlowType="getFlowType"
                  @add="add"
                >
                </TableList>

                <Pagination
                  @getPage="getPage" 
                  :count="count"   
                  style="margin-top:20px"           
                ></Pagination>
                <p></p>
            </a-layout-content>
        </a-layout>
     </a-layout>
  </div>
</div>
</template>

<script>
import BreadCrumb from "./components/BreadCrumb";
import TableList from "./components/TableList";
import Search from "./components/Search";
import EditForm from "./components/EditForm";
import Pagination from "./components/Pagination"

import { add_flowtype, search_for_flowtype, get_flowtypelist, update_flowtype } from '@/http/apis';
import { delete_flowtype } from '../../http/apis';
export default {
    components:{
        BreadCrumb,
        TableList,
        Search,
        EditForm,
        Pagination
    },
    data() {
        return {
            visible:false,
            flowTypeList: {
              'id':'',
              'name': '',
              'description':''
            },
            flowTypeListGet:[],
            searchList:{
                'name':'',
                'page':1,
                'page_size':4,
                
            },
            updateFlowTypeList:[],
            // 当前页码
            current:1,
            // 总共的数据多少条
            count:0

        }
    },
    methods: {
        addNew(){
          this.visible = true
          this.flowTypeList = {
              'id':'',
              'name': '',
              'description':''
            }
          // 用于控制组件显示
        },
        add(){
          if(this.flowTypeList.id){            
            this.visible = true  
            update_flowtype(this.flowTypeList).then(res=>{
              // alert('修改成功')
              this.getFlowType()
            })

          }else{
            // 添加用户,子组件中编辑的值实际上是写在父组件上面的
            add_flowtype(this.flowTypeList).then(res=>{
              console.log(res)
              alert('添加新用户成功')
              this.getFlowType()
              
          })   
            this.visible=false       
          }
        },
        find(){
          // 根据用户名查找用户信息
          search_for_flowtype(this.searchList).then(res=>{
              this.getFlowType()
              // 数据解耦性!!!查询和查询某个其实可以调用同一个接口!
              // 查询所有:http://192.168.56.100:1594/?page=1&zh_name=
              // 查询某个:http://192.168.56.100:1594/?page=1&zh_name=
            
          })
        },
        getFlowType(){
          this.searchList.page = this.current
          // 获取用户信息列表,父组件传递给子组件
          get_flowtypelist(this.searchList).then(res=>{
            this.flowTypeListGet = res.results
            this.count = res.count
            // console.log(this.count)
            // console.log(this.flowTypeListGet)
          })
        },
        // 获取页码
        getPage(currentChild){
          // 获取到的currentChild是子组件传递过来是第几页
          this.current = currentChild
          console.log(this.current)
          this.getFlowType()
        }
    },
    created() {

    }
}
</script>

<style scoped>
#components-layout-demo-basic {
  text-align: center;
}
#components-layout-demo-basic .ant-layout-header,
#components-layout-demo-basic .ant-layout-footer {
  background: white;
  color: #fff;
}
#components-layout-demo-basic .ant-layout-footer {
  line-height: 1.5;
}
#components-layout-demo-basic .ant-layout-content {
  background: white;
  color: #fff;
  min-height: 120px;
  line-height: 120px;
}
#components-layout-demo-basic > .ant-layout {
  margin-bottom: 48px;
}
#components-layout-demo-basic > .ant-layout:last-child {
  margin: 0;
}
</style>

2 components
2.1 BreadCrumb.vue
<template>
    <div>
        <a-breadcrumb>
            <a-breadcrumb-item href="">
            <a-icon type="home" />
            </a-breadcrumb-item>

            <a-breadcrumb-item href="">
            <a-icon type="user" />
            <span>首页</span>

            </a-breadcrumb-item>
            <a-breadcrumb-item>
            工单模块
            </a-breadcrumb-item>
            <a-breadcrumb-item>
            分类管理页面
            </a-breadcrumb-item>
        </a-breadcrumb>
    </div>
</template>

<script>
export default {
    name:"BreadCrumb",
    data() {
        return {

        }
    },
    methods: {

    },
    created() {

    }
}
</script>

<style scoped>

</style>
2.2 EditForm.vue
<template>
    <div>
        <a-modal
        title="Please write now."
        :visible="visible"
        @ok="handleOk"
        @cancel="handleCancel"
        >
        <!-- @ok控制按钮ok -->
        <!-- @cancel控制按钮cancel -->
            <p v-if="flowTypeList.id">Name:
                <a-input 
                style="width:400px;float:right" 
                placeholder="zh_rname"
                v-model="flowTypeList.name"
                disabled="disabled"
                ></a-input>                
            </p>
            <p v-else>Name:
                <a-input 
                style="width:390px;float:right" 
                placeholder="name" 
                v-model="flowTypeList.name"
                ></a-input>
            </p>
            <br>
            <p>Description:
                <a-input style="width:380px;float:right" placeholder="Description" v-model="flowTypeList.description"></a-input>
            </p>
        </a-modal>

    </div>
</template>

<script>
export default {
    props:['visible', 'flowTypeList'],
    data() {
        return {
        }
    },
    methods: {
        handleOk(e) {
            this.$emit('add')
            // add方法的调用一定要在关闭弹窗上面,否则方法不执行完毕没有办法关闭弹窗
            // 调用父组件中 add 方法            
            this.$emit('update:visible', false)
            // 把 visible 的值更新为 false,控制组件不显示

        },
        handleCancel(e) {
            this.$emit('update:visible', false)
            // 把 visible 的值更新为 false,控制组件不显示
        },
    },
    created() {

    }
}
</script>

<style scoped>

</style>
2.3 Pagination.vue
<template>
  <div>
    <a-pagination
      show-quick-jumper
      :default-current="2"
      :pageSize = '4'
      :total="count"
      show-less-items
      @change="onChange"
      v-model="current"

    />
  </div>
</template>

<script>
export default {
    props:[ 'count' ],
    data() {
        return {
            current:1
        }
    },
    methods: {
        
        onChange() {
            this.$emit('getPage', this.current)
            // this.$emit('getPage')
    },
    },
    created() {

    }
}
</script>

<style scoped>

</style>
2.4 Search.vue
<template>
    <div>
        <a-input-search placeholder="Input the flowtypename that you want to search for..." enter-button @search="onSearch" style="float:right;width:400px" v-model="searchList.name"/>
    </div>
</template>

<script>
export default {
    props:['searchList'],
    data() {
        return {

        } 
    },
    methods: {
        onSearch(){
            this.$emit('find')
            // 调用父组件中的find方法
        }
    },
    created() {

    }
}
</script>

<style scoped>

</style>
2.5 TableList.vue
<template>
  <a-table 
    :columns="columns" 
    :data-source="flowTypeListGet" 
    :rowKey="(record,index)=>{return index}"
    :pagination= 'false'
  >
  <!-- 带:的都是属性绑定,不可以更换名字,带 : 就是 js 环境 -->
    <!-- 不写:rowKey="(record,index)=>{return index}"浏览器会发出警告 -->
    <p slot="tags" slot-scope="text,tags,i">
      <!-- 加入操作的按钮! -->
      <a-button @click="delFlowType(text,tags,i)">删除</a-button>
      <a-button @click="updateFlowType(text,tags,i)">修改</a-button>
    </p>
  </a-table>
</template>

<script>
const columns = [
    {
    title: 'ID',
    dataIndex: 'id',
    key: 'id',
    // ellipsis: true,
    width: 50,
  },
  {
    title: 'Name',
    dataIndex: 'name',
    key: 'name',
    scopedSlots: { customRender: 'name' },
    width: 80,
  },

    {
    title: 'Description',
    dataIndex: 'description',
    key: 'description',
    width: 100,
  },
  {
    title:'操作',
    dataIndex: 'tags',
    key : 'tags',
    width: 100,
    scopedSlots : { customRender: 'tags'}
    // scopedSlots: { customRender: 'tags' },一定不能少不然渲染不了html标签

  }
]

import { delete_flowtype } from '@/http/apis'
export default {
  props:[ 'flowTypeListGet', 'flowTypeList'],
  data() {
    return {
      columns,
    }
  },
  methods:{
    get(){
        this.$emit('getFlowType')
        // 调用父组件中的获取用户列表的方法
    },
    delFlowType(text,tags,i){
      // 定义变量 isDel来控制 confirm,isDel==true执行的就是对话框的 ok,isDel==false执行的就是对话框的 false
        const isDel = confirm('你确定要删除')
        if(isDel==true){
          delete_flowtype(tags.id).then(
          res=>{
            // 删除回调地址是  http://192.168.56.100:1594/id/
            this.get()
            alert('删除成功啦~')
          })
        }else{
            alert('有需要再叫我哈~')
        }
             
    },
    updateFlowType(text,tags,i){
      this.flowTypeList.id = tags.id
      this.flowTypeList.name = tags.name
      this.flowTypeList.description = tags.description     
      this.$emit('add')
    }
  },
  created(){
    this.get()
  }
};
</script>

1.4.4 flowconf-manage

  • 工单模板组件
  • 只允许超级有用户访问
1 index.vue
<template>
<div>
  <div id="components-layout-demo-basic">
     <a-layout>
        <a-layout-header>
          <BreadCrumb style="float:left"></BreadCrumb>

        </a-layout-header>
        <a-layout>
            <a-layout-content>
            <div style="margin-bottom:80px">
                <a-button  type="danger" ghost style="float:left;margin-left:20px;margin-top:16px;color:pink;border-color:pink;font-size:16px" @click="addNew">
                AddFlowConf
                </a-button>
                <EditForm
                    :visible.sync="visible"
                    :flowConfList='flowConfList'
                    :flowTypeList='flowTypeList'
                    @add="add"
                >
                <!-- .sync控制组件是否显示 -->
                </EditForm>
                <Search 
                  style="margin-bottom:-20px;margin-top:10px" 
                  :searchList="searchList"
                  @find="find"
                  @getFlowConf="getFlowConf"
                >
                </Search>
                
            </div>
                <TableList
                  :flowConfListGet="flowConfListGet"
                  :flowConfList="flowConfList"
                  
                  @getFlowConf="getFlowConf"
                  @add="add"
                >
                </TableList>

                <Pagination
                  @getPage="getPage" 
                  :count="count"   
                  style="margin-top:20px"           
                ></Pagination>
                <p></p>
            </a-layout-content>
        </a-layout>
     </a-layout>
  </div>
</div>
</template>

<script>
import BreadCrumb from "./components/BreadCrumb";
import TableList from "./components/TableList";
import Search from "./components/Search";
import EditForm from "./components/EditForm";
import Pagination from "./components/Pagination"

import { add_flowconf, search_for_flowconf, get_flowconflist, update_flowconf } from '@/http/apis';
import { delete_flowconf, get_flowtypelist_new } from '../../http/apis';
export default {
    components:{
        BreadCrumb,
        TableList,
        Search,
        EditForm,
        Pagination
    },
    data() {
        return {
            visible:false,
            flowConfList: {
              'id':'',
              'name': '',
              'customfield':'',
              'flowtype':'',
              'description':''
            },
            flowTypeList:[],
            flowConfListGet:[],
            searchList:{
                'name':'',
                'page':1,
                'page_size':4,
                
            },
            updateFlowConfList:[],
            // 当前页码
            current:1,
            // 总共的数据多少条
            count:0,


        }
    },
    methods: {
        addNew(){
          this.visible = true
          this.flowConfList = {
              'id':'',
              'name': '',
              'customfield':'',
              'flowtype':1,
              'description':''
            }
          // 用于控制组件显示
        },
        add(){
          if(this.flowConfList.id){            
            this.visible = true  
            update_flowconf(this.flowConfList).then(res=>{
              // alert('修改成功')
              this.getFlowConf()
            })

          }else{
            // 添加用户,子组件中编辑的值实际上是写在父组件上面的
            add_flowconf(this.flowConfList).then(res=>{
              console.log(res)
              alert('添加新用户成功')
              this.getFlowConf()
              
          })   
            this.visible=false       
          }
        },
        find(){
          // 根据用户名查找用户信息
          search_for_flowconf(this.searchList).then(res=>{
              this.getFlowConf()
              // 数据解耦性!!!查询和查询某个其实可以调用同一个接口!
              // 查询所有:http://192.168.56.100:1594/?page=1&zh_name=
              // 查询某个:http://192.168.56.100:1594/?page=1&zh_name=
            
          })
        },
        getFlowConf(){
          this.searchList.page = this.current
          // 获取用户信息列表,父组件传递给子组件
          get_flowconflist(this.searchList).then(res=>{
            this.flowConfListGet = res.results
            this.count = res.count
            // console.log(this.count)
            // console.log(this.flowConfListGet)
          })
        },
        // 获取页码
        getPage(currentChild){
          // 获取到的currentChild是子组件传递过来是第几页
          this.current = currentChild
          console.log(this.current)
          this.getFlowConf()
        },
        // 获取分类
        getFlowType(){
          get_flowtypelist_new().then(
            res=>{
            this.flowTypeList = res
            console.log('11111',this.flowTypeList)              
            }

          )
        }
    },
    created() {
      this.getFlowType()
    }
}
</script>

<style scoped>
#components-layout-demo-basic {
  text-align: center;
}
#components-layout-demo-basic .ant-layout-header,
#components-layout-demo-basic .ant-layout-footer {
  background: white;
  color: #fff;
}
#components-layout-demo-basic .ant-layout-footer {
  line-height: 1.5;
}
#components-layout-demo-basic .ant-layout-content {
  background: white;
  color: #fff;
  min-height: 120px;
  line-height: 120px;
}
#components-layout-demo-basic > .ant-layout {
  margin-bottom: 48px;
}
#components-layout-demo-basic > .ant-layout:last-child {
  margin: 0;
}
</style>
2 components
2.1 BreadCrumb.vue
<template>
    <div>
        <a-breadcrumb>
            <a-breadcrumb-item href="">
            <a-icon type="home" />
            </a-breadcrumb-item>

            <a-breadcrumb-item href="">
            <a-icon type="user" />
            <span>首页</span>

            </a-breadcrumb-item>
            <a-breadcrumb-item>
            工单模块
            </a-breadcrumb-item>
            <a-breadcrumb-item>
            工单模板页面
            </a-breadcrumb-item>
        </a-breadcrumb>
    </div>
</template>

<script>
export default {
    name:"BreadCrumb",
    data() {
        return {

        }
    },
    methods: {

    },
    created() {

    }
}
</script>

<style scoped>

</style>
2.2 EditForm.vue
<template>
    <div>
        <a-modal
        title="Please write now."
        :visible="visible"
        @ok="handleOk"
        @cancel="handleCancel"
        >
        <!-- @ok控制按钮ok -->
        <!-- @cancel控制按钮cancel -->
            <p v-if="flowConfList.id">Name:
                <a-input 
                style="width:400px;float:right" 
                placeholder="name"
                v-model="flowConfList.name"
                disabled="disabled"
                ></a-input>                
            </p>
            <p v-else>Name:
                <a-input 
                style="width:420px;float:right" 
                placeholder="name" 
                v-model="flowConfList.name"
                ></a-input>
            </p>
            <br>
            <p style="text-align:left">Customfield:<br>
                <a-textarea style="width:470px;height:150px" placeholder="Write your customfields..." v-model="flowConfList.customfield"></a-textarea>
            </p>
            <br>FlowType:
                <a-select        
                    style="width: 400px; float:right"
                    @change="handleChange"
                    v-model="flowConfList.flowtype"
                >
                    <a-select-option v-for="i in flowTypeList" :key="i.id" :value='i.id'>
                    {{ i.name }}
                    </a-select-option>
                </a-select>
            </p>            
            <br>
            <p>Description:
                <a-input style="width:380px;float:right" placeholder="Description" v-model="flowConfList.description"></a-input>
            </p>
        </a-modal>

    </div>
</template>

<script>
export default {
    props:['visible', 'flowConfList', 'flowTypeList'],
    data() {
        return {
        }
    },
    methods: {
        handleOk(e) {
            this.$emit('add')
            // add方法的调用一定要在关闭弹窗上面,否则方法不执行完毕没有办法关闭弹窗
            // 调用父组件中 add 方法            
            this.$emit('update:visible', false)
            // 把 visible 的值更新为 false,控制组件不显示

        },
        handleCancel(e) {
            this.$emit('update:visible', false)
            // 把 visible 的值更新为 false,控制组件不显示
        },
        handleChange(value) {
            // console.log(`selected ${value.key}`);
            this.flowConfList.flowtype = value
            console.log('111111',this.flowConfList.flowtype)
            // 输出类型为 { key: 2,label: '财务工单' }
        },
    },
    created() {

    }
}
</script>

<style scoped>

</style>
2.3 Pagination.vue
<template>
  <div>
    <a-pagination
      show-quick-jumper
      :default-current="2"
      :pageSize = '4'
      :total="count"
      show-less-items
      @change="onChange"
      v-model="current"

    />
  </div>
</template>

<script>
export default {
    props:[ 'count' ],
    data() {
        return {
            current:1
        }
    },
    methods: {
        
        onChange() {
            this.$emit('getPage', this.current)
            // this.$emit('getPage')
    },
    },
    created() {

    }
}
</script>

<style scoped>

</style>
2.4 Search.vue
<template>
    <div>
        <a-input-search placeholder="Input the flowconfname that you want to search for..." enter-button @search="onSearch" style="float:right;width:400px" v-model="searchList.name"/>
    </div>
</template>

<script>
export default {
    props:['searchList'],
    data() {
        return {

        } 
    },
    methods: {
        onSearch(){
            this.$emit('find')
            // 调用父组件中的find方法
        }
    },
    created() {

    }
}
</script>

<style scoped>

</style>
2.5 TableList.vue
<template>
  <a-table 
    :columns="columns" 
    :data-source="flowConfListGet" 
    :rowKey="(record,index)=>{return index}"
    :pagination= 'false'
  >
  <!-- 带:的都是属性绑定,不可以更换名字,带 : 就是 js 环境 -->
    <!-- 不写:rowKey="(record,index)=>{return index}"浏览器会发出警告 -->
    <p slot="flowtype_name" slot-scope="flowtype_name">
      <a-tag
        color="pink"
      >
        {{ flowtype_name }}
      </a-tag>
    </p>
    <p slot="tags" slot-scope="text,tags,i">
      <!-- 加入操作的按钮! -->
      <a-button @click="delFlowConf(text,tags,i)">删除</a-button>
      <a-button @click="updateFlowConf(text,tags,i)">修改</a-button>
      <a-button @click="jump(text,tags,i)">配置审批流</a-button>
    </p>
  </a-table>
</template>

<script>
const columns = [
    {
    title: 'ID',
    dataIndex: 'id',
    key: 'id',
    // ellipsis: true,
    width: 50,
  },
  {
    title: 'Name',
    dataIndex: 'name',
    key: 'name',
    scopedSlots: { customRender: 'name' },
    width: 80,
  },
  {
    title: 'Customfield',
    dataIndex: '',
    key: 'customfield',
    scopedSlots: { customRender: 'customfield' },
    width: 60,    
  },
    {
    title: 'FlowType',
    dataIndex: 'flowtype_name',
    key: 'flowtype_name',
    width: 50,
    scopedSlots: { customRender: 'flowtype_name' },
  },  
    {
    title: 'Description',
    dataIndex: 'description',
    key: 'description',
    width: 150,
  },
  {
    title:'操作',
    dataIndex: 'tags',
    key : 'tags',
    width: 100,
    scopedSlots : { customRender: 'tags'}
    // scopedSlots: { customRender: 'tags' },一定不能少不然渲染不了html标签

  }
]

import { delete_flowconf } from '@/http/apis'
export default {
  props:[ 'flowConfListGet', 'flowConfList'],
  data() {
    return {
      columns,
    }
  },
  methods:{
    get(){
        this.$emit('getFlowConf')
        // 调用父组件中的获取用户列表的方法
    },
    delFlowConf(text,tags,i){
      // 定义变量 isDel来控制 confirm,isDel==true执行的就是对话框的 ok,isDel==false执行的就是对话框的 false
        const isDel = confirm('你确定要删除')
        if(isDel==true){
          delete_flowconf(tags.id).then(
          res=>{
            // 删除回调地址是  http://192.168.56.100:1594/id/
            this.get()
            alert('删除成功啦~')
          })
        }else{
            alert('有需要再叫我哈~')
        }
             
    },
    updateFlowConf(text,tags,i){
      this.flowConfList.id = tags.id
      this.flowConfList.name = tags.name
      this.flowConfList.flowtype = tags.flowtype
      this.flowConfList.customfield = tags.customfield
      this.flowConfList.description = tags.description     
      this.$emit('add')
      console.log('tags',tags)
    },
    // 跳转配置审批流
    jump(text,tags,i){
      this.$router.push({
        'path':'approveconf',
        // 不写query,写params会报错啊
        'query':{
          'id': tags.id,
          'name': tags.name
        }
      })
    }
  },
  created(){
    this.get()
  }
};
</script>

1.4.5 approveconf-manage

  • 配置审批流组件
1 index.vue
<template>
<div>
  <div id="components-layout-demo-basic">
     <a-layout>
        <a-layout-header>
          <BreadCrumb style="float:left"></BreadCrumb>

        </a-layout-header>
        <a-layout>
            <a-layout-content>
            <div style="margin-bottom:80px">
                <a-button  type="danger" ghost style="float:left;margin-left:20px;margin-top:16px;color:pink;border-color:pink;font-size:16px" @click="addNew">
                AddApproveConf
                </a-button>
                <EditForm
                    :visible.sync="visible"
                    :approveConfList='approveConfList'
                    @add="add"
                >
                <!-- .sync控制组件是否显示 -->
                </EditForm>
                
            </div>
                <TableList
                  :approveConfListGet="approveConfListGet"
                  :approveConfList="approveConfList"
                  
                  @getApproveConf="getApproveConf"
                  @add="add"
                >
                </TableList>

                <Pagination
                  @getPage="getPage" 
                  :count="count"   
                  style="margin-top:20px"           
                ></Pagination>
            </a-layout-content>
        </a-layout>
     </a-layout>
  </div>
</div>
</template>

<script>
import BreadCrumb from "./components/BreadCrumb";
import TableList from "./components/TableList";
import EditForm from "./components/EditForm";
import Pagination from "./components/Pagination"

import { add_approveconf, search_for_approveconf, get_approveconflist, update_approveconf } from '@/http/apis';
import { delete_approveconf } from '../../http/apis';
export default {
    components:{
        BreadCrumb,
        TableList,
        EditForm,
        Pagination
    },
    data() {
        return {
            visible:false,
            approveConfList: {
              'id':'',
              'approvetype':'',
              'approve_type_id':'',
              'sequence':'',
              'flowconf':'',
              'flowconf_name':''
            },
            approveConfListGet:[],
            searchList:{
                'flowconf':'',
                'page':1,
                'page_size':4,
                
            },
            updateApproveConfList:[],
            // 当前页码
            current:1,
            // 总共的数据多少条
            count:0,
            // 获取跳转id
            id:this.$route.query.id,
            flowconf_name: this.$route.query.name


        }
    },
    methods: {
        addNew(){
          this.visible = true
          this.approveConfList = {
              'id':'',
              'approvetype':'',
              'approve_type_id':'',
              'sequence':'',
              'flowconf':this.id,
              'flowconf_name':this.flowconf_name
            }
          // 用于控制组件显示
        },
        add(){
          if(this.approveConfList.id){            
            this.visible = true  
            update_approveconf(this.approveConfList).then(res=>{
              // alert('修改成功')
              this.getApproveConf()
            })

          }else{
            // 添加用户,子组件中编辑的值实际上是写在父组件上面的
            add_approveconf(this.approveConfList).then(res=>{
              console.log(res)
              alert('添加新用户成功')
              this.getApproveConf()
              
          })   
            this.visible=false       
          }
        },
        getApproveConf(){
          this.searchList.page = this.current
          this.searchList.flowconf = this.id
          // 获取用户信息列表,父组件传递给子组件
          get_approveconflist(this.searchList).then(res=>{
            this.approveConfListGet = res.results
            this.count = res.count
            // console.log(this.count)
            // console.log(this.flowConfListGet)
          })
        },
        // 获取页码
        getPage(currentChild){
          // 获取到的currentChild是子组件传递过来是第几页
          this.current = currentChild
          console.log(this.current)
          this.getApproveConf()
        },
    },
    created() {
    }
}
</script>

<style scoped>
#components-layout-demo-basic {
  text-align: center;
}
#components-layout-demo-basic .ant-layout-header,
#components-layout-demo-basic .ant-layout-footer {
  background: white;
  color: #fff;
}
#components-layout-demo-basic .ant-layout-footer {
  line-height: 1.5;
}
#components-layout-demo-basic .ant-layout-content {
  background: white;
  color: #fff;
  min-height: 120px;
  line-height: 120px;
}
#components-layout-demo-basic > .ant-layout {
  margin-bottom: 48px;
}
#components-layout-demo-basic > .ant-layout:last-child {
  margin: 0;
}
</style>
2 components
2.1 BreadCrumb.vue
<template>
    <div>
        <a-breadcrumb>
            <a-breadcrumb-item href="">
            <a-icon type="home" />
            </a-breadcrumb-item>

            <a-breadcrumb-item href="">
            <a-icon type="user" />
            <span>首页</span>

            </a-breadcrumb-item>
            <a-breadcrumb-item>
            工单模块
            </a-breadcrumb-item>
            <a-breadcrumb-item>
            配置审批流页面
            </a-breadcrumb-item>
        </a-breadcrumb>
    </div>
</template>

<script>
export default {
    name:"BreadCrumb",
    data() {
        return {

        }
    },
    methods: {

    },
    created() {

    }
}
</script>

<style scoped>

</style>
2.2 EditForm.vue
<template>
    <div>
        <a-modal
        title="Please write now."
        :visible="visible"
        @ok="handleOk"
        @cancel="handleCancel"
        >
        <!-- @ok控制按钮ok -->
        <!-- @cancel控制按钮cancel -->
            <p>FlowConf:
                <a-input 
                style="width:400px;float:right" 
                v-model="approveConfList.flowconf_name"
                disabled="disabled"
                ></a-input>                
            </p>         
            <br>
            <p>Sequence:
                <a-input style="width:380px;float:right" placeholder="Sequence" v-model="approveConfList.sequence"></a-input>
            </p>
            <br>
            <p>
                审批类型:
                <a-select
                    style="width: 180px"
                    @change="handleChangeRole"
                    v-model="approveConfList.approvetype"
                >
                    <a-select-option v-for="select in selectList" :key="select.id" :value="select.id">
                    {{ select.name }}
                    </a-select-option>
                </a-select>
            </p>
            <br>
            <p v-if="approveConfList.approvetype=='2'">审批人员:
                <a-select
                    style="width: 120px"
                    @change="handleChangeUser"
                    v-model="approveConfList.approve_type_id"
                >
                    <a-select-option v-for="user in userList" :key="user.id" :value="user.id" >
                        {{user.username}}
                    </a-select-option>
                </a-select>
            </p>
            <p v-else>审批人员:
                <a-select
                    style="width: 120px"
                    @change="handleChangeRole"
                    v-model="approveConfList.approve_type_id"
                >
                    <a-select-option :value="role.id" v-for="role in roleList" :key="role.id">
                    {{ role.zh_name }}
                    </a-select-option>
                </a-select>
            </p>
        </a-modal>

    </div>
</template>

<script>
import { get_userlist_new, get_rolelist_new } from '@/http/apis'
import { get_rolelist } from '../../../http/apis'
export default {
    props:['visible', 'approveConfList'],
    data() {
        return {
            userList:[],
            roleList:[],
            selectList:[
                { 'id':1, 'name':'角色组审批'},
                { 'id':2, 'name':'指定人员审批'}
            ]
        }
    },
    methods: {
        handleOk(e) {
            this.$emit('add')
            // add方法的调用一定要在关闭弹窗上面,否则方法不执行完毕没有办法关闭弹窗
            // 调用父组件中 add 方法            
            this.$emit('update:visible', false)
            // 把 visible 的值更新为 false,控制组件不显示

        },
        handleCancel(e) {
            this.$emit('update:visible', false)
            // 把 visible 的值更新为 false,控制组件不显示
        },
         handleChangeUser(value) {
            console.log(value);
        },
         handleChangeRole(value) {
            console.log(value); // { key: "lucy", label: "Lucy (101)" }
        },
        // 获取用户信息列表
        get_user(){
            get_userlist_new().then(res=>{
                this.userList=res
                console.log(this.userList)
            })
        },
        // 获取角色信息列表
        get_role(){
            get_rolelist_new().then(res=>{
                this.roleList=res
                console.log(this.roleList)
            })
        }
    },
    created() {
        this.get_user()
        this.get_role()
    }
}
</script>

<style scoped>

</style>
2.3 Pagination.vue
<template>
  <div>
    <a-pagination
      show-quick-jumper
      :default-current="2"
      :pageSize = '4'
      :total="count"
      show-less-items
      @change="onChange"
      v-model="current"

    />
  </div>
</template>

<script>
export default {
    props:[ 'count' ],
    data() {
        return {
            current:1
        }
    },
    methods: {
        
        onChange() {
            this.$emit('getPage', this.current)
            // this.$emit('getPage')
    },
    },
    created() {

    }
}
</script>

<style scoped>

</style>
2.4 TableList.vue
<template>
  <a-table 
    :columns="columns" 
    :data-source="approveConfListGet" 
    :rowKey="(record,index)=>{return index}"
    :pagination= 'false'
  >
  <!-- 带:的都是属性绑定,不可以更换名字,带 : 就是 js 环境 -->
    <!-- 不写:rowKey="(record,index)=>{return index}"浏览器会发出警告 -->
    <p slot="flowtype_name" slot-scope="flowtype_name">
      <a-tag
        color="pink"
      >
        {{ flowtype_name }}
      </a-tag>
    </p>
    <p slot="tags" slot-scope="text,tags,i">
      <!-- 加入操作的按钮! -->
      <a-button @click="delApproveConf(text,tags,i)">删除</a-button>
      <a-button @click="updateApproveConf(text,tags,i)">修改</a-button>
     
    </p>
  </a-table>
</template>

<script>
const columns = [
    {
    title: 'ID',
    dataIndex: 'id',
    key: 'id',
    // ellipsis: true,
    width: 50,
  },
  {
    title: 'FlowConfName',
    dataIndex: 'flowconf_name',
    key: 'flowconf_name',
    scopedSlots: { customRender: 'flowconf_name' },
    width: 80,
  },
  {
    title: 'ApproveType',
    dataIndex: 'approvetype_name',
    key: 'approvetype_name',
    scopedSlots: { customRender: 'approvetype_name' },
    width: 100,    
  },
    {
    title: 'ApprovePerson',
    dataIndex: 'approve_type_id_name',
    key: 'approve_type_id_name',
    width: 100,
    scopedSlots: { customRender: 'approve_type_id_name' },
  },  
    {
    title: 'Sequence',
    dataIndex: 'sequence',
    key: 'sequence',
    width: 100,
  },
  {
    title:'操作',
    dataIndex: 'tags',
    key : 'tags',
    width: 100,
    scopedSlots : { customRender: 'tags'}
    // scopedSlots: { customRender: 'tags' },一定不能少不然渲染不了html标签

  }
]

import { delete_approveconf } from '@/http/apis'
export default {
  props:[ 'approveConfListGet', 'approveConfList'],
  data() {
    return {
      columns,

    }
  },
  methods:{
    get(){
        this.$emit('getApproveConf')
        // 调用父组件中的获取用户列表的方法
    },
    delApproveConf(text,tags,i){
      // 定义变量 isDel来控制 confirm,isDel==true执行的就是对话框的 ok,isDel==false执行的就是对话框的 false
        const isDel = confirm('你确定要删除')
        if(isDel==true){
          delete_approveconf(tags.id).then(
          res=>{
            // 删除回调地址是  http://192.168.56.100:1594/id/
            this.get()
            alert('删除成功啦~')
          })
        }else{
            alert('有需要再叫我哈~')
        }
             
    },
    updateApproveConf(text,tags,i){
      this.approveConfList.id = tags.id
      this.approveConfList.approvetype_name = tags.approvetype_name
      this.approveConfList.approvetype = tags.approvetype
      this.approveConfList.approve_type_id = tags.approve_type_id
      this.approveConfList.approve_type_id_name = tags.approve_type_id_name
      this.approveConfList.sequence = tags.sequence
      this.approveConfList.flowconf = tags.flowconf 
      this.approveConfList.flowconf_name = tags.flowconf_name      
      this.$emit('add')
      console.log('tags',tags)
    }
  },
  created(){
    this.get()
  }
};
</script>

1.4.6 workorder-manage

  • 新建工单,提供模板选择工单组件(让用户选择需要的工单模板)
1 index.vue
<template>
<div>
  <div id="components-layout-demo-basic">
     <a-layout>
        <a-layout-header>
          <p></p>
          <BreadCrumb style="float:left"></BreadCrumb>
          <p></p>

        </a-layout-header>
        <a-layout>
            <a-layout-content>
            <div style="margin-bottom:80px">
                <Search 
                  style="margin-bottom:-20px;margin-top:10px" 
                  :searchES="searchES"
                  @search="search"
                >
                </Search>
                
            </div>
                <TableList
                  :workerOrderListGet="workerOrderListGet"
                  @getWorkerOrder="getWorkerOrder"
                >
                </TableList>

                <Pagination
                  @getPage="getPage" 
                  :count="count"
                  style="margin-top:20px;"              
                ></Pagination>
                <p></p>
                
            </a-layout-content>
        </a-layout>
     </a-layout>
  </div>
</div>
</template>

<script>
import BreadCrumb from "./components/BreadCrumb";
import TableList from "./components/TableList";
import Search from "./components/Search";
import Pagination from "./components/Pagination"

import { get_workerorder, search_workerorder } from '@/http/apis';

export default {
    components:{
        BreadCrumb,
        TableList,
        Search,
        Pagination
    },
    data() {
        return {
            visible:false,
            workerOrderListGet:[],
            searchList:{
                'create_user':'',
                'page':1,
                'page_size':4,
                
            },
            // 当前页码
            current:1,
            // 总共的数据多少条
            count:0,
                        // ES查询
            searchES:{
                'page':1,
                'page_size':4, 
                'q':''    
            }

        }
    },
    methods: {
        find(){
          // 根据用户名查找用户信息
          get_workerorder(this.searchList).then(res=>{
              this.getWorkerOrder()
              // 数据解耦性!!!查询和查询某个其实可以调用同一个接口!
              // 查询所有:http://192.168.56.100:1594/?page=1&zh_name=
              // 查询某个:http://192.168.56.100:1594/?page=1&zh_name=
            
          })
        },
        getWorkerOrder(){
          this.searchList.page = this.current
          // 获取用户信息列表,父组件传递给子组件
          get_workerorder(this.searchList).then(res=>{
            this.workerOrderListGet = res.results
            this.count = res.count
          })
        },
        // 获取页码
        getPage(currentChild){
          // 获取到的currentChild是子组件传递过来是第几页
          this.current = currentChild
          console.log(this.current)
          this.getWorkerOrder()
        },
        search(){
          search_workerorder(this.searchES).then(
            res =>{
              this.workerOrderListGet = res.results
              this.count = res.count
            }
          )
        }
    },
    created() {

    }
}
</script>

<style scoped>
#components-layout-demo-basic {
  text-align: center;
}
#components-layout-demo-basic .ant-layout-header,
#components-layout-demo-basic .ant-layout-footer {
  background: white;
  color: #fff;
}
#components-layout-demo-basic .ant-layout-footer {
  line-height: 1.5;
}
#components-layout-demo-basic .ant-layout-content {
  background: white;
  color: #fff;
  min-height: 120px;
  line-height: 120px;
}
#components-layout-demo-basic > .ant-layout {
  margin-bottom: 48px;
}
#components-layout-demo-basic > .ant-layout:last-child {
  margin: 0;
}
</style>
2 components
2.1 BreadCrumb.vue
<template>
    <div>
        <a-breadcrumb>
            <a-breadcrumb-item href="">
            <a-icon type="home" />
            </a-breadcrumb-item>

            <a-breadcrumb-item href="">
            <a-icon type="user" />
            <span>首页</span>

            </a-breadcrumb-item>
            <a-breadcrumb-item>
            工单管理
            </a-breadcrumb-item>
            <a-breadcrumb-item>
            实例工单页面
            </a-breadcrumb-item>
        </a-breadcrumb>
    </div>
</template>

<script>
export default {
    name:"BreadCrumb",
    data() {
        return {

        }
    },
    methods: {

    },
    created() {

    }
}
</script>

<style scoped>

</style>
2.2 Pagination.vue
<template>
  <div>
    <a-pagination
      show-quick-jumper
      :default-current="2"
      :pageSize = '4'
      :total="count"
      show-less-items
      @change="onChange"
      v-model="current"

    />
  </div>
</template>

<script>
export default {
    props:[ 'count' ],
    data() {
        return {
            current:1
        }
    },
    methods: {
        
        onChange() {
            this.$emit('getPage', this.current)
            // this.$emit('getPage')
    },
    },
    created() {

    }
}
</script>

<style scoped>

</style>
2.3 Search.vue
<template>
    <div>
        <!-- 日期格式请按照:2020 - 12 - 3 -->
        <a-input-search placeholder="Input the rolename that you want to search for..." enter-button @search="onSearch" style="float:right;width:400px" v-model="searchES.q"/>
    </div>
</template>

<script>
export default {
    props:['searchES'],
    data() {
        return {

        } 
    },
    methods: {
        onSearch(){
            this.$emit('search')
            // 调用父组件中的find方法
        }
    },
    created() {

    }
}
</script>

<style scoped>

</style>
2.4 TableList.vue
<template>
  <a-table 
    :columns="columns" 
    :data-source="workerOrderListGet" 
    :rowKey="(record,index)=>{return index}"
    :pagination= 'false'
  >
  <!-- 带:的都是属性绑定,不可以更换名字,带 : 就是 js 环境 -->
    <!-- 不写:rowKey="(record,index)=>{return index}"浏览器会发出警告 -->
    <p slot="tags" slot-scope="text,tags,i">
      <!-- 加入操作的按钮! -->
      <a-button @click="jumpChild(text,tags,i)">查看详情</a-button>
      
    </p>
  </a-table>
</template>

<script>
const columns = [
    {
    title: 'ID',
    dataIndex: 'id',
    key: 'id',
    // ellipsis: true,
    width: 50,
  },
  {
    title: '工单名称',
    dataIndex: 'flowconf_name',
    key: 'flowconf_name',
    scopedSlots: { customRender: 'flowconf_name' },
    width: 80,
  },
  {
    title: '工单状态',
    dataIndex: 'order_status_name',
    key: 'order_status_name',
    width: 100,
  },
    {
    title: '创建者',
    dataIndex: 'create_user_name',
    key: 'create_user_name',
    width: 100,
  },
  {
    title: '创建日期',
    dataIndex: 'create_time',
    key: 'create_time',
    width: 100,
  },
  {
    title:'操作',
    dataIndex: 'tags',
    key : 'tags',
    width: 100,
    scopedSlots : { customRender: 'tags'}
    // scopedSlots: { customRender: 'tags' },一定不能少不然渲染不了html标签

  }
]


export default {
  props:[ 'workerOrderListGet'],
  data() {
    return {
      columns,
    }
  },
  methods:{
    get(){
        this.$emit('getWorkerOrder')
        // 调用父组件中的获取用户列表的方法
    },
    jumpChild(text,tags,i){
      console.log('tags',tags)
      // 查看详情
      this.$router.push({
        path:'childconfform',
        query:{
          'flowconf':tags.flowconf,
          'id':tags.id
        }
      })
    }
  },
  created(){
    this.get()
  }
};
</script>

1.4.7 flowconfform-manage

  • 动态生成工单组件
1 index.vue
<template>
    <div>
        <div>
             <a-row>
            <a-col :span="16" style="height:500px">
                <CreateForm
                   :msg="flowConf"
                   @addWorkOrder="addWorkOrder" 
                   
                ></CreateForm>
            </a-col>
            <a-col :span="8" style="height:500px;text-align:left;font-size:20px;color:pink">
                <br><br><br><br><br><br><br><p>{{flowConf.description}}</p>
            </a-col>
            </a-row>
            <a-row>
            <a-col :span="24" style="height:160px">
                <Check
                    :flowConf="flowConf"
                    
                ></Check>
            </a-col>
            </a-row>
        </div>
    </div>
</template>

<script>
import Check from '@/views/flowconfform-manage/components/Check'
import CreateForm from '@/views/flowconfform-manage/components/CreateForm'
import { add_workorder } from '@/http/apis'
export default {
    components:{
        Check,
        CreateForm
    },
    data() {
        return {
            flowConf:this.$route.query.flowconf,
            // token:localStorage.getItem('token')
        }
    },
    methods: {
        // json转换
        changeJson(){
            const textJson = this.flowConf.customfield
            console.log('自定义字段', textJson)
            const textJsonChange = JSON.parse(textJson)
            console.log('转换后自定义字段', textJsonChange)
            this.flowConf.customfield = textJsonChange
            console.log(this.flowConf)
        },
        // 添加
        addWorkOrder(){
            let data = {
                // 'token':this.token,
                'name':this.flowConf.name,
                'form':this.flowConf.customfield.field_list,                
            }
            console.log('data',data)
            add_workorder(data).then(res=>{
                console.log(res.msg)
                if(res.code==200){
                    alert('实例化工单完成')
                }
            })
        }
    },
    created() {
    this.changeJson()
    }
}
</script>

<style scoped>

</style>
2 components
2.1 Check.vue
<template>
    <div>
        <p style="float:left;margin-top:20px;font-size:20px">审批流程&ensp;<a-icon type="heart" theme="twoTone" two-tone-color="#eb2f96" /></p>
        <div v-for="check in checkList" :key="check.id" style="float:left;margin-left:200px;margin-top:50px">
            <p>
                <a-icon type="user" style="font-size:40px;color:pink"/>
            </p>
            <p>
            {{check.approvetype_name}}:{{check.approve_type_id_name}}&ensp;<a-icon type="forward" theme="filled" style="font-size:20px;color:pink"/>
            </p>
        </div>

    </div>
</template>

<script>
import { get_approveconflist_new } from '@/http/apis'
export default {
    props:[ "flowConf" ],
    data() {
        return {
            checkList:[]
        }
    },
    methods: {
        getApproveConf(){
            get_approveconflist_new({'flowconf':this.flowConf.id}).then(res=>{
                // console.log(res.results)
                this.checkList = res.results
            })
        }

    },
    created() {
        // console.log('AAA', this.flowConf)
        this.getApproveConf()
    }
}
</script>

<style scoped>

</style>
2.2 CreateForm.vue
<template>
    <div>
         <a-form-model :label-col="labelCol" :wrapper-col="wrapperCol">
            <a-form-model-item v-for="(select,item) in msg.customfield.field_list" :key="item">
            
            <p v-if="select.field_type==='input'" style="text-align:left">{{select.verbos_name}}:&emsp;
                <a-input v-model="select.value" style="width:200px" @change="giveValue"/>
            </p>
            
            <p v-show="select.field_type==='select'" style="text-align:left">
                {{select.verbos_name}}:&emsp;
                <a-select v-model="select.value" placeholder="please select your option" style="width:200px" @change="giveValue">
                    <a-select-option v-for="s in select.field_datasource" :key="s.value" :value="s.value">
                    {{ s.label }}
                    </a-select-option>
                </a-select>
            </p>

            <p v-show="select.field_type=='textarea'" style="text-align:left">
                {{select.verbos_name}}:
                <a-input v-model="select.value" type="textarea" style="width:700px;height:150px" @change="giveValue"/>
            </p>
            </a-form-model-item>
            <a-form-model-item :wrapper-col="{ span: 14, offset: 4 }">
                <a-button type="primary" @click="onSubmit">
                提交
                </a-button>
                <a-button style="margin-left: 10px;">
                取消
                </a-button>
            </a-form-model-item>
        </a-form-model>
    </div>
</template>
<script>
export default {
  props:[ 'msg' ],
  data() {
    return {  
      labelCol: { span: 4 },
      wrapperCol: { span: 14 },
    };
  },
  methods: {
    // 实例化工单
    onSubmit() {
      console.log('submit!', this.msg);
      this.$emit('addWorkOrder')
    },  
    // giveValue(){
    //     for(var i in this.msg.customfield.form){
    //     const val = this.getInputValue(i);
    //     this.msg.customfield.form[i] = val;
    //   }       
    // },
    // getInputValue(key){
    //     for(var i=0;i<this.msg.customfield.field_list.length;i=i+1){
    //         const fileld_dic = this.msg.customfield.field_list[i];
    //         const k1 = fileld_dic['name'];
    //         if(key == k1){
    //         return fileld_dic['value']
    //     }
    //   }
    //   return ''
    // }
    giveValue(){
        const form_list = Object.keys(this.msg.customfield.form) 
        // 可以获取到所有的key
        for(var i=0;i<this.msg.customfield.field_list.length;i++){
            form_list.forEach(item => {
                if(this.msg.customfield.field_list[i].name==item){
                    this.msg.customfield.form[item]=this.msg.customfield.field_list[i].value
                }
            });
        }
        return this.msg
    }
  },

};
</script>

<style scoped>
</style>

1.4.8 workerorder-manage

  • 主工单组件
  • 超级管理员身份可以查看全部工单,其他普通用户只能看到自己创建的工单
  • 采用了ES,只能根据状态进行查询(因为主工单和子工单时外键关联的关系,这种索引名一样的,建立索引会出现先后查找混乱的现象)
1 index.vue
<template>
<div>
  <div id="components-layout-demo-basic">
     <a-layout>
        <a-layout-header>
          <p></p>
          <BreadCrumb style="float:left"></BreadCrumb>
          <p></p>

        </a-layout-header>
        <a-layout>
            <a-layout-content>
            <div style="margin-bottom:80px">
                <Search 
                  style="margin-bottom:-20px;margin-top:10px" 
                  :searchES="searchES"
                  @search="search"
                >
                </Search>
                
            </div>
                <TableList
                  :workerOrderListGet="workerOrderListGet"
                  @getWorkerOrder="getWorkerOrder"
                >
                </TableList>

                <Pagination
                  @getPage="getPage" 
                  :count="count"
                  style="margin-top:20px;"              
                ></Pagination>
                <p></p>
                
            </a-layout-content>
        </a-layout>
     </a-layout>
  </div>
</div>
</template>

<script>
import BreadCrumb from "./components/BreadCrumb";
import TableList from "./components/TableList";
import Search from "./components/Search";
import Pagination from "./components/Pagination"

import { get_workerorder, search_workerorder } from '@/http/apis';

export default {
    components:{
        BreadCrumb,
        TableList,
        Search,
        Pagination
    },
    data() {
        return {
            visible:false,
            workerOrderListGet:[],
            searchList:{
                'create_user':'',
                'page':1,
                'page_size':4,
                
            },
            // 当前页码
            current:1,
            // 总共的数据多少条
            count:0,
                        // ES查询
            searchES:{
                'page':1,
                'page_size':4, 
                'q':''    
            }

        }
    },
    methods: {
        find(){
          // 根据用户名查找用户信息
          get_workerorder(this.searchList).then(res=>{
              this.getWorkerOrder()
              // 数据解耦性!!!查询和查询某个其实可以调用同一个接口!
              // 查询所有:http://192.168.56.100:1594/?page=1&zh_name=
              // 查询某个:http://192.168.56.100:1594/?page=1&zh_name=
            
          })
        },
        getWorkerOrder(){
          this.searchList.page = this.current
          // 获取用户信息列表,父组件传递给子组件
          get_workerorder(this.searchList).then(res=>{
            this.workerOrderListGet = res.results
            this.count = res.count
          })
        },
        // 获取页码
        getPage(currentChild){
          // 获取到的currentChild是子组件传递过来是第几页
          this.current = currentChild
          console.log(this.current)
          this.getWorkerOrder()
        },
        search(){
          search_workerorder(this.searchES).then(
            res =>{
              this.workerOrderListGet = res.results
              this.count = res.count
            }
          )
        }
    },
    created() {

    }
}
</script>

<style scoped>
#components-layout-demo-basic {
  text-align: center;
}
#components-layout-demo-basic .ant-layout-header,
#components-layout-demo-basic .ant-layout-footer {
  background: white;
  color: #fff;
}
#components-layout-demo-basic .ant-layout-footer {
  line-height: 1.5;
}
#components-layout-demo-basic .ant-layout-content {
  background: white;
  color: #fff;
  min-height: 120px;
  line-height: 120px;
}
#components-layout-demo-basic > .ant-layout {
  margin-bottom: 48px;
}
#components-layout-demo-basic > .ant-layout:last-child {
  margin: 0;
}
</style>
2 components
2.1 BreadCrumb.vue
<template>
    <div>
        <a-breadcrumb>
            <a-breadcrumb-item href="">
            <a-icon type="home" />
            </a-breadcrumb-item>

            <a-breadcrumb-item href="">
            <a-icon type="user" />
            <span>首页</span>

            </a-breadcrumb-item>
            <a-breadcrumb-item>
            工单管理
            </a-breadcrumb-item>
            <a-breadcrumb-item>
            实例工单页面
            </a-breadcrumb-item>
        </a-breadcrumb>
    </div>
</template>

<script>
export default {
    name:"BreadCrumb",
    data() {
        return {

        }
    },
    methods: {

    },
    created() {

    }
}
</script>

<style scoped>

</style>
2.2 Pagination.vue
<template>
  <div>
    <a-pagination
      show-quick-jumper
      :default-current="2"
      :pageSize = '4'
      :total="count"
      show-less-items
      @change="onChange"
      v-model="current"

    />
  </div>
</template>

<script>
export default {
    props:[ 'count' ],
    data() {
        return {
            current:1
        }
    },
    methods: {
        
        onChange() {
            this.$emit('getPage', this.current)
            // this.$emit('getPage')
    },
    },
    created() {

    }
}
</script>

<style scoped>

</style>
2.3 Search.vue
<template>
    <div>
        <!-- 日期格式请按照:2020 - 12 - 3 -->
        <a-input-search placeholder="Input the rolename that you want to search for..." enter-button @search="onSearch" style="float:right;width:400px" v-model="searchES.q"/>
    </div>
</template>

<script>
export default {
    props:['searchES'],
    data() {
        return {

        } 
    },
    methods: {
        onSearch(){
            this.$emit('search')
            // 调用父组件中的find方法
        }
    },
    created() {

    }
}
</script>

<style scoped>

</style>
2.4 TableList.vue
<template>
  <a-table 
    :columns="columns" 
    :data-source="workerOrderListGet" 
    :rowKey="(record,index)=>{return index}"
    :pagination= 'false'
  >
  <!-- 带:的都是属性绑定,不可以更换名字,带 : 就是 js 环境 -->
    <!-- 不写:rowKey="(record,index)=>{return index}"浏览器会发出警告 -->
    <p slot="tags" slot-scope="text,tags,i">
      <!-- 加入操作的按钮! -->
      <a-button @click="jumpChild(text,tags,i)">查看详情</a-button>
      
    </p>
  </a-table>
</template>

<script>
const columns = [
    {
    title: 'ID',
    dataIndex: 'id',
    key: 'id',
    // ellipsis: true,
    width: 50,
  },
  {
    title: '工单名称',
    dataIndex: 'flowconf_name',
    key: 'flowconf_name',
    scopedSlots: { customRender: 'flowconf_name' },
    width: 80,
  },
  {
    title: '工单状态',
    dataIndex: 'order_status_name',
    key: 'order_status_name',
    width: 100,
  },
    {
    title: '创建者',
    dataIndex: 'create_user_name',
    key: 'create_user_name',
    width: 100,
  },
  {
    title: '创建日期',
    dataIndex: 'create_time',
    key: 'create_time',
    width: 100,
  },
  {
    title:'操作',
    dataIndex: 'tags',
    key : 'tags',
    width: 100,
    scopedSlots : { customRender: 'tags'}
    // scopedSlots: { customRender: 'tags' },一定不能少不然渲染不了html标签

  }
]


export default {
  props:[ 'workerOrderListGet'],
  data() {
    return {
      columns,
    }
  },
  methods:{
    get(){
        this.$emit('getWorkerOrder')
        // 调用父组件中的获取用户列表的方法
    },
    jumpChild(text,tags,i){
      console.log('tags',tags)
      // 查看详情
      this.$router.push({
        path:'childconfform',
        query:{
          'flowconf':tags.flowconf,
          'id':tags.id
        }
      })
    }
  },
  created(){
    this.get()
  }
};
</script>

1.4.9 suborder-manage

  • 子工单组件
  • 超级管理员身份可以看到全部工单,其他普通用户只能看到自己能审批的工单(包括不在当前节点的也能看见)
  • 采用了ES,可以根据显示在 table 中的全部字段进行查询
1 index.vue
<template>
<div>
  <div id="components-layout-demo-basic">
     <a-layout>
        <a-layout-header>
          <p></p>
          <BreadCrumb style="float:left"></BreadCrumb>
          <p></p>

        </a-layout-header>
        <a-layout>
            <a-layout-content>

              <div style="margin-bottom:80px">
                <Search 
                  style="margin-bottom:-20px;margin-top:10px" 
                  :searchES="searchES"
                  @search="search"
                >
                </Search>    
            </div>

                <TableList
                  :subOrderListGet="subOrderListGet"
                  @getSubOrder="getSubOrder"
                  :mainorder="mainorder"
                >
                </TableList>

                <Pagination
                  @getPage="getPage" 
                  :count="count"
                  style="margin-top:20px;"              
                ></Pagination>
                <p></p>
                
            </a-layout-content>
        </a-layout>
     </a-layout>
  </div>
</div>
</template>

<script>
import BreadCrumb from "./components/BreadCrumb";
import Pagination from "./components/Pagination";
import Search from "./components/Search";
import TableList from "./components/TableList";
import { get_suborder, search_suborder } from '@/http/apis';

export default {
    components:{
        BreadCrumb,
        TableList,
        Pagination,
        Search,
    },
    data() {
        return {
            mainorder:this.$route.query.id,
            subOrderListGet:[],
            searchList:{
                'page':1,
                'page_size':4,               
            },
            // 当前页码
            current:1,
            // 总共的数据多少条
            count:0,
            // ES查询
            searchES:{
                'page':1,
                'page_size':4, 
                'q':''    
            }

        }
    },
    methods: {
        getSubOrder(){
          
          this.searchList.page = this.current
          // 获取用户信息列表,父组件传递给子组件
          get_suborder(this.searchList).then(res=>{
            console.log(res)
            this.subOrderListGet = res.results
            this.count = res.count
            
          })
        },
        // 获取页码
        getPage(currentChild){
          // 获取到的currentChild是子组件传递过来是第几页
          this.current = currentChild
          console.log(this.current)
          if(this.subOrderListGet[0].type){
            this.search()
          }else{
            this.getSubOrder()
          }
          
        },
        search(){
          this.searchES['page'] = this.current
          search_suborder(this.searchES).then(
            res =>{
              console.log('res',res)
              this.subOrderListGet = res.results
              this.count = res.count
              console.log('this.subOrderListGet',this.subOrderListGet)
            }
          )
        }
    },
    created() {
      this.getSubOrder()
    }
}
</script>

<style scoped>
#components-layout-demo-basic {
  text-align: center;
}
#components-layout-demo-basic .ant-layout-header,
#components-layout-demo-basic .ant-layout-footer {
  background: white;
  color: #fff;
}
#components-layout-demo-basic .ant-layout-footer {
  line-height: 1.5;
}
#components-layout-demo-basic .ant-layout-content {
  background: white;
  color: #fff;
  min-height: 120px;
  line-height: 120px;
}
#components-layout-demo-basic > .ant-layout {
  margin-bottom: 48px;
}
#components-layout-demo-basic > .ant-layout:last-child {
  margin: 0;
}
</style>
2 components
2.1 BreadCrumb.vue
<template>
    <div>
        <a-breadcrumb>
            <a-breadcrumb-item href="">
            <a-icon type="home" />
            </a-breadcrumb-item>

            <a-breadcrumb-item href="">
            <a-icon type="user" />
            <span>首页</span>

            </a-breadcrumb-item>
            <a-breadcrumb-item>
            工单管理
            </a-breadcrumb-item>
            <a-breadcrumb-item>
            子工单页面
            </a-breadcrumb-item>
        </a-breadcrumb>
    </div>
</template>

<script>
export default {
    name:"BreadCrumb",
    data() {
        return {

        }
    },
    methods: {

    },
    created() {

    }
}
</script>

<style scoped>

</style>
2.2 Search.vue
<template>
    <div>
        <a-input-search placeholder="Input the rolename that you want to search for..." enter-button @search="onSearch" style="float:right;width:400px" v-model="searchES.q"/>
    </div>
</template>

<script>
export default {
    props:['searchES'],
    data() {
        return {

        } 
    },
    methods: {
        onSearch(){

            this.$emit('search')
            // 调用父组件中的find方法
        }
    },
    created() {

    }
}
</script>

<style scoped>

</style>
2.3 Pagination.vue
<template>
  <div>
    <a-pagination
      show-quick-jumper
      :default-current="2"
      :pageSize = '4'
      :total="count"
      show-less-items
      @change="onChange"
      v-model="current"

    />
  </div>
</template>

<script>
export default {
    props:[ 'count' ],
    data() {
        return {
            current:1
        }
    },
    methods: {
        
        onChange() {
            this.$emit('getPage', this.current)
            // this.$emit('getPage')
    },
    },
    created() {

    }
}
</script>

<style scoped>

</style>
2.4 TableList.vue
<template>
  <div>
    <a-table 
      :columns="columns" 
      :data-source="subOrderListGet" 
      :rowKey="(record,index)=>{return index}"
      :pagination='false'
    >
    <!-- 带:的都是属性绑定,不可以更换名字,带 : 就是 js 环境 -->
      <!-- 不写:rowKey="(record,index)=>{return index}"浏览器会发出警告 -->
      <p slot="tags" slot-scope="text,tags,i">
        <a-button @click="jump(text,tags,i)">查看工单审批详情</a-button>
      </p>
    </a-table>
  </div>
</template>

<script>
const columns = [
    {
    title: 'ID',
    dataIndex: 'id',
    key: 'id',
    // ellipsis: true,
    width: 50,
    scopedSlots: { customRender: 'id' },
  },
  {
    title: '工单名称',
    dataIndex: 'flowconf_name',
    key: 'flowconf_name',
    scopedSlots: { customRender: 'flowconf_name' },
    width: 80,
  },
  {
    title: '工单状态',
    dataIndex: 'action_status_name',
    key: 'action_status_name',
    width: 100,
  },
  {
    title: '审批人',
    dataIndex: 'approve_user_name',
    key: 'approve_user_name',
    width: 100,
  },
  {
    title: '审批角色',
    dataIndex: 'approbe_user_role',
    key: 'approbe_user_role',
    width: 100,
  },
  {
    title:'操作',
    dataIndex: 'tags',
    key : 'tags',
    width: 100,
    scopedSlots : { customRender: 'tags'}
    // scopedSlots: { customRender: 'tags' },一定不能少不然渲染不了html标签
  }
]


export default {
  props:[ 'subOrderListGet', 'mainorder'],
  data() {
    return {
      columns,
    }
  },
  methods:{
    get(){
        this.$emit('getSubOrder')
        // 调用父组件中的获取用户列表的方法
    },
    jump(text,tags,i){
      this.$router.push({
        path:'childconfform',
        query:{
          'id':tags.mainorder,
          'flowconf':tags.flowconf
        }
      })
    }
  },
  created(){
    this.get()
  }
};
</script>

1.4.10 childconfform-manage

  • 子工单审批
1 index.vue
<template>
    <div>
      <a-row>
      <a-col :span="10" style="background:rgb(253,234,254);height:700px">
          <br>
        <CreateChildForm
            :form="form"
        >
        </CreateChildForm>
        <br><br><br><br>
        <div style="float:left">
            <PersonRole
                :approveConfList="approveConfList"
            ></PersonRole>
        </div>
      </a-col>
      <a-col :span="14" style="height:700px">
        <Approval
            :approveConf="approveConfList"
            :mainorder="mainorder"
        ></Approval>
      </a-col>
    </a-row>
    </div>
</template>

<script>
import CreateChildForm from './components/CreateChildForm'
import PersonRole from './components/PersonRole'
import Approval from './components/Approval'
import { get_workerorder,get_suborder } from '@/http/apis'
import { get_approveconflist_new } from '@/http/apis'

export default {
    
    components:{
        CreateChildForm,
        PersonRole,
        Approval
    },
    data() {
        return {
            mainorder:this.$route.query.id,
            form:{},
            flowconf:this.$route.query.flowconf,
            approveConfList:[]

        }
    },
    methods: {
        getForm(){
            get_workerorder({'id': this.mainorder}).then(res=>{
                const data = res[0].parameter         
                var dic = data.replace(/'/g, '"')
                this.form = JSON.parse(dic)

                })
            get_approveconflist_new({'flowconf': this.flowconf}).then(res=>{
                    this.approveConfList = res.results
                    console.log('approveConfList', res.results)
                    })

        },
        

    },
    created() {
        this.getForm()
    }
}
</script>

<style scoped>
</style>
2 components
2.1 Approval.vue
<template>
    <div>
        <div style="float:left">
            <a-icon type="smile" theme="twoTone" style="font-size:15px;" />&ensp;审批详情
            <div v-for=" (approve, item) in approveConf" :key="item" style="margin-top:30px">

                <span style="float:left;font-size:16px;">
                    <a-button style="border-radius: 50%;margin-right:8px;background:lightblue;color:white;border:white">Step{{ approve.sequence }}</a-button>
                    Role:{{ approve.approve_type_id_name }}
                    <br>
                    Status:{{ suborderList[item].suborder_status_name }}
                    <br>
                    Advice:
            
                </span>
                    <span>
                        
                        <a-textarea
                            v-model="value[item]"
                            placeholder="Write your advice..."
                            :auto-size="{ minRows: 3, maxRows: 8 }"
                            style="height:80px;width:500px;margin-top:30px"
                            v-if="suborderList[item].type=='1'"
                        />
                        <br>
                        <br>
                        <a-button type="link" style="color:palevioletred;font-size:20px" ghost v-if="suborderList[item].type=='1'" @click="choose(value[item],yes,suborderList[item].id)">
                            √通过
                        </a-button>
                        <a-button type="primary" style="margin-left:30px" ghost v-if="suborderList[item].type=='1'" @click="choose(value[item],returnMsg,suborderList[item].id)">
                            退回
                        </a-button>
                        <a-button type="danger" style="margin-left:30px" ghost v-if="suborderList[item].type=='1'" @click="choose(value[item],no,suborderList[item].id)">拒绝</a-button>
                    </span>

            </div>
        </div>
    </div>
</template>

<script>
import { get_suborder_auth, add_suborder } from '@/http/apis'
export default {
    props:[ 'approveConf', 'mainorder' ],
    data() {
        return {
            current:1,
            value:[],
            suborderList:[],
            yes:'2',
            no:'3',
            returnMsg:'4'
        }
    },
    methods: {
        onChange(current) {
            console.log('onChange:', current);
            this.current = current;
            },
        getSuborder(){
            get_suborder_auth({'mainorder':this.mainorder}).then(res=>{
                this.suborderList = res
                console.log('suborderList', this.suborderList)

            })
        },
        choose(decision, action_status, suborder_id){
            let data={
                'suborder_id':suborder_id,
                'decision':decision,
                'action_status':action_status
            }
            console.log('i am data',data)
            add_suborder(data).then(res=>{
                if(res.code==200){
                    alert('审批成功')
                    this.getSuborder()
                }else{
                    alert('审批失败')
                }
            })
        }
    },
    created() {
        this.getSuborder()
    }
}
</script>

<style scoped>
.a-textarea{
    width:100;
    min-height:50px;
    max-height: 300px;
}
</style>
2.2 CreateChildForm.vue
<template>
    <div>
        <div>
          <p style="float:left"><a-icon type="smile" theme="twoTone" style="font-size:15px"/>&ensp;用户申请</p><br><br><br>
            <table style="width:500px;height:150px">
              <tr>
                <th>标题</th>
                <th>数据</th>
              </tr>
              <tr v-for="(f,item) in form" :key="item">
                <td>{{ f.verbos_name }}</td>
                <td>{{ f.value }}</td>
              </tr>
            </table>
        </div>

    </div>
</template>

<script>
export default {
    props:['form'],
    data() {
        return {
            
        }
    },
    methods: {

        // get_form(){
        //   this.$emit('getForm')
        // }
    },
    created() {
      // this.get_form()
    }
}
</script>

<style scoped>
.table,th,tr,td{
  border: white 3px solid;
}
.table{
  width: 300px;
  height: 300px
}
</style>
2.3 PersonRole.vue
<template>
    <div>
        <p style="float:left"><a-icon type="smile" theme="twoTone" style="font-size:15px"/>&ensp;审批步骤</p><br>
        <br>
        <br>
        <div v-for="person in approveConfList" :key="person.id">          
          <span style="margin-top:40px">
              <h2 style="color:palevioletred"><a-icon type="user"  style="color:lightblue;"/>&ensp;&ensp;{{ person.approve_type_id_name }}</h2>
              <h3>.</h3>
          </span>
        </div>

    </div>
</template>

<script>
export default {
    props:[ 'approveConfList' ],
    data() {
        return {
            
        }
    },
    methods: {

    },
    created() {

    }
}
</script>

<style scoped>

</style>

1.5 BaiDu.vue

  • 自动跳转到百度翻译页面
<template>
    <div>

    </div>
</template>

<script>
export default {
    data() {
        return {

        }
    },
    methods: {
        goBaiDu(){
            window.location.href = 'https://fanyi.baidu.com/?aldtype=16047#auto/zh'
        }
    },
    created() {
        this.goBaiDu()
    }
}
</script>

<style scoped>

</style>

1.6 Login.vue

  • 登录页面
<template>
  <div>
    <div class="d1">
      <div style="margin-top:150px;height:400px;width:800px;margin-left:400px;background:pink">
        <br>
        <center><h1 style="margin-top:50px;color:white">登&emsp;录</h1></center>
        <br>

        <a-form-item label="用户名" v-bind="formlayout" style="color:pink">

          <a-input v-model="username" style="width:400px"/>
    
        </a-form-item>   
        <a-form-item label="密码" v-bind="formlayout" style="color:pink">
          <a-input-password v-model="password" placeholder="input password" @keyup.enter.native.enter="submit"  style="width:400px"/>
        </a-form-item>

        <a-form-item v-bind="buttonlayout">

          <a-button type="primary"  @click="submit" style="color:blue;background:white;border:pink;color:pink">登录</a-button>

        </a-form-item>

      </div>
    </div>
  </div>
</template>

<script type="text/javascript">
import { user_login } from '../http/apis';

export default{

  data(){
    return{
      username:"",
      password:'',
      //表单样式
      formlayout:{
        //标签
        labelCol:{
          xs:{span:24},
          sm:{span:8}
        },
        //文本框
        wrapperCol:{
          xs:{span:14},
          sm:{span:6}
        }
      },
      //按钮样式
      buttonlayout:{
        //按钮
        wrapperCol:{
          xs:{
            span:24,
            offset:0
          },
          sm:{span:16,offset:8}
        }
      }
    }

  },
  //自定义方法
  methods:{
    submit:function(){
      var data={'username':this.username,'password':this.password}
      user_login(data).then(resp => {
        console.log(resp)
        if(resp.token){
          // 如果返还token值,就储存 token username uid
          localStorage.setItem('token',resp.token)
          localStorage.setItem('username',resp.username)
          localStorage.setItem('uid',resp.id)
          this.$router.push('/start')
        }
      }).catch(err=>{
        console.log(err)
        alert('登录失败')
      })

    }
  }
};


</script>

<style type="text/css">
</style>

1.7 StartPage.vue

  • 初始界面
<template>
    <div>
        <img src="static\tmg.png" style="width:1000px;height:600px">
    </div>
</template>

<script>
export default {
    data() {
        return {

        }
    },
    methods: {

    },
    created() {

    }
}
</script>

<style scoped>

</style>
posted @ 2020-12-16 20:10  狐狸大大爱吃糖  阅读(333)  评论(0编辑  收藏  举报