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
<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"/> 
{{username}}
<a-icon type="fire" style="font-size:25px;color:pink"/> 
</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>
<template>
<div>
<a-switch :default-checked="false" @change="changeMode" style="margin-top:70px"/> 
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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 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">审批流程 <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}} <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>
<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}}: 
<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}}: 
<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>
<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>
<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 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;" /> 审批详情
<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>
<template>
<div>
<div>
<p style="float:left"><a-icon type="smile" theme="twoTone" style="font-size:15px"/> 用户申请</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"/> 审批步骤</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;"/>  {{ 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">登 录</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>