zoukankan      html  css  js  c++  java
  • 工单项目(前端)用于思考

    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;150px">
                        <LeftMenu></LeftMenu>
                        <!-- 以组件发昂视导入左侧菜单 -->
                    </a-layout-sider>
                    <a-layout>
    
                        <a-layout-header  style="height:80px;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{
      1530px;
      height: 722px;
      background:rgb(253,234,254)
    }
    .ant-layout{
      background:rgb(253,234,254);
      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=" 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);
         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="380px;float:right" 
                    placeholder="username" 
                    v-model="userList.username"
                    disabled="disabled"
                    ></a-input>                
                </p>
                <p v-else>UserName:
                    <a-input 
                    style="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="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="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="410px;float:right" placeholder="Email" v-model="userList.email"></a-input>
                </p>
                <br>
                <p>Mobile:
                    <a-input style="410px" placeholder="Mobile" v-model="userList.mobile"></a-input>
                </p>
                <br>
                <p>Weixin:
                    <a-input style="410px" placeholder="WeiXin" v-model="userList.weixin"></a-input>
                </p>
                <br>
                <p v-show="userList.id!=''">Is_superuser:
                    <a-input style="370px" placeholder="SuperUser" v-model="userList.is_superuser" disabled="disabled"></a-input>
                
                </p>
                <br>
                <p>Role:
                 <a-select
                    mode="multiple"               
                    style=" 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;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,
         50,
      },
      {
        title: 'UserName',
        dataIndex: 'username',
        key: 'username',
        scopedSlots: { customRender: 'username' },
         80,
      },
      {
        title: 'Email',
        dataIndex: 'email',
        key: 'email',
         100,
      },
      {
        title: 'Mobile',
        dataIndex: 'mobile',
        key: 'mobile',
        ellipsis: true,
         100,
      },
      {
        title: 'WeiXin',
        dataIndex: 'weixin',
        key: 'weixin',
        ellipsis: true,
         80,
      },
      {
        title: 'Is SuperUser',
        dataIndex: 'is_superuser',
        key: 'is_superuser',
        ellipsis: true,
         90,
      },
        {
        title: 'Roles',
        dataIndex: 'roles',
        key: 'roles',
        ellipsis: true,
         150,
        scopedSlots : { customRender: 'roles'}
        // 不写的话显示不了标签
      },
      {
        title:'操作',
        dataIndex: 'tags',
        key : 'tags',
         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="400px;float:right" 
                    placeholder="zh_rname"
                    v-model="roleList.zh_name"
                    disabled="disabled"
                    ></a-input>                
                </p>
                <p v-else>ZhName:
                    <a-input 
                    style="390px;float:right" 
                    placeholder="zh_name" 
                    v-model="roleList.zh_name"
                    ></a-input>
                </p>
                <br>
                <p>EnName:
                    <a-input style="380px;float:right" placeholder="Description" v-model="roleList.en_name"></a-input>
                </p>
                <br>
                <p>Description:
                    <a-input style="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;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,
         50,
      },
      {
        title: 'ZhName',
        dataIndex: 'zh_name',
        key: 'zh_name',
        scopedSlots: { customRender: 'zh_name' },
         80,
      },
      {
        title: 'EnName',
        dataIndex: 'en_name',
        key: 'en_name',
         100,
      },
        {
        title: 'Description',
        dataIndex: 'description',
        key: 'description',
         100,
      },
      {
        title:'操作',
        dataIndex: 'tags',
        key : 'tags',
         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="400px;float:right" 
                    placeholder="zh_rname"
                    v-model="flowTypeList.name"
                    disabled="disabled"
                    ></a-input>                
                </p>
                <p v-else>Name:
                    <a-input 
                    style="390px;float:right" 
                    placeholder="name" 
                    v-model="flowTypeList.name"
                    ></a-input>
                </p>
                <br>
                <p>Description:
                    <a-input style="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;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,
         50,
      },
      {
        title: 'Name',
        dataIndex: 'name',
        key: 'name',
        scopedSlots: { customRender: 'name' },
         80,
      },
    
        {
        title: 'Description',
        dataIndex: 'description',
        key: 'description',
         100,
      },
      {
        title:'操作',
        dataIndex: 'tags',
        key : 'tags',
         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="400px;float:right" 
                    placeholder="name"
                    v-model="flowConfList.name"
                    disabled="disabled"
                    ></a-input>                
                </p>
                <p v-else>Name:
                    <a-input 
                    style="420px;float:right" 
                    placeholder="name" 
                    v-model="flowConfList.name"
                    ></a-input>
                </p>
                <br>
                <p style="text-align:left">Customfield:<br>
                    <a-textarea style="470px;height:150px" placeholder="Write your customfields..." v-model="flowConfList.customfield"></a-textarea>
                </p>
                <br>FlowType:
                    <a-select        
                        style=" 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="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;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,
         50,
      },
      {
        title: 'Name',
        dataIndex: 'name',
        key: 'name',
        scopedSlots: { customRender: 'name' },
         80,
      },
      {
        title: 'Customfield',
        dataIndex: '',
        key: 'customfield',
        scopedSlots: { customRender: 'customfield' },
         60,    
      },
        {
        title: 'FlowType',
        dataIndex: 'flowtype_name',
        key: 'flowtype_name',
         50,
        scopedSlots: { customRender: 'flowtype_name' },
      },  
        {
        title: 'Description',
        dataIndex: 'description',
        key: 'description',
         150,
      },
      {
        title:'操作',
        dataIndex: 'tags',
        key : 'tags',
         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="400px;float:right" 
                    v-model="approveConfList.flowconf_name"
                    disabled="disabled"
                    ></a-input>                
                </p>         
                <br>
                <p>Sequence:
                    <a-input style="380px;float:right" placeholder="Sequence" v-model="approveConfList.sequence"></a-input>
                </p>
                <br>
                <p>
                    审批类型:
                    <a-select
                        style=" 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=" 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=" 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,
         50,
      },
      {
        title: 'FlowConfName',
        dataIndex: 'flowconf_name',
        key: 'flowconf_name',
        scopedSlots: { customRender: 'flowconf_name' },
         80,
      },
      {
        title: 'ApproveType',
        dataIndex: 'approvetype_name',
        key: 'approvetype_name',
        scopedSlots: { customRender: 'approvetype_name' },
         100,    
      },
        {
        title: 'ApprovePerson',
        dataIndex: 'approve_type_id_name',
        key: 'approve_type_id_name',
         100,
        scopedSlots: { customRender: 'approve_type_id_name' },
      },  
        {
        title: 'Sequence',
        dataIndex: 'sequence',
        key: 'sequence',
         100,
      },
      {
        title:'操作',
        dataIndex: 'tags',
        key : 'tags',
         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;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,
         50,
      },
      {
        title: '工单名称',
        dataIndex: 'flowconf_name',
        key: 'flowconf_name',
        scopedSlots: { customRender: 'flowconf_name' },
         80,
      },
      {
        title: '工单状态',
        dataIndex: 'order_status_name',
        key: 'order_status_name',
         100,
      },
        {
        title: '创建者',
        dataIndex: 'create_user_name',
        key: 'create_user_name',
         100,
      },
      {
        title: '创建日期',
        dataIndex: 'create_time',
        key: 'create_time',
         100,
      },
      {
        title:'操作',
        dataIndex: 'tags',
        key : 'tags',
         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="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="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="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;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,
         50,
      },
      {
        title: '工单名称',
        dataIndex: 'flowconf_name',
        key: 'flowconf_name',
        scopedSlots: { customRender: 'flowconf_name' },
         80,
      },
      {
        title: '工单状态',
        dataIndex: 'order_status_name',
        key: 'order_status_name',
         100,
      },
        {
        title: '创建者',
        dataIndex: 'create_user_name',
        key: 'create_user_name',
         100,
      },
      {
        title: '创建日期',
        dataIndex: 'create_time',
        key: 'create_time',
         100,
      },
      {
        title:'操作',
        dataIndex: 'tags',
        key : 'tags',
         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;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,
         50,
        scopedSlots: { customRender: 'id' },
      },
      {
        title: '工单名称',
        dataIndex: 'flowconf_name',
        key: 'flowconf_name',
        scopedSlots: { customRender: 'flowconf_name' },
         80,
      },
      {
        title: '工单状态',
        dataIndex: 'action_status_name',
        key: 'action_status_name',
         100,
      },
      {
        title: '审批人',
        dataIndex: 'approve_user_name',
        key: 'approve_user_name',
         100,
      },
      {
        title: '审批角色',
        dataIndex: 'approbe_user_role',
        key: 'approbe_user_role',
         100,
      },
      {
        title:'操作',
        dataIndex: 'tags',
        key : 'tags',
         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;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{
        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="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{
       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;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="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="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	mg.png" style="1000px;height:600px">
        </div>
    </template>
    
    <script>
    export default {
        data() {
            return {
    
            }
        },
        methods: {
    
        },
        created() {
    
        }
    }
    </script>
    
    <style scoped>
    
    </style>
    
  • 相关阅读:
    【转】PCA for opencv
    【转】PCA算法学习_1(OpenCV中PCA实现人脸降维)
    从输入URL到页面渲染完成(转)
    前端面试笔记(整理)
    这样“断舍离”,你会活得更高级
    angular5.x全局loading解决方法
    angular路由守卫
    优化回流和重绘
    回流 (Reflow)和重绘 (Repaint)
    Javascript获取数组中最大和最小值
  • 原文地址:https://www.cnblogs.com/mapel1594184/p/14145905.html
Copyright © 2011-2022 走看看