ticketdelete

This commit is contained in:
shijing 2021-10-15 16:03:50 +08:00
parent 7cbbdfaf48
commit 22b52686bc
9 changed files with 933 additions and 414 deletions

View File

@ -163,13 +163,45 @@ export function ticketAccpet(id,data) {
})
}
//撤回工单,允许创建人在指定状态撤回工单至初始状态
export function getTicketRetreat(id,data) {
export function ticketRetreat(id,data) {
return request({
url: `/wf/ticket/${id}/retreat/`,
method: 'post',
data
})
}
//关闭工单,仅允许创建人在初始状态关闭工单
export function ticketAddNode(id,data) {
return request({
url: `/wf/ticket/${id}/add_node/`,
method: 'post',
data
})
}
//加签
export function ticketClose(id,data) {
return request({
url: `/wf/ticket/${id}/close/`,
method: 'post',
data
})
}
//加签
export function ticketAddNodeEnd(id,data) {
return request({
url: `/wf/ticket/${id}/add_node_end/`,
method: 'post',
data
})
}
//工单删除
export function ticketDestory(data) {
return request({
url: `/wf/ticket/destory/`,
method: 'post',
data
})
}
//工单详情
export function getTicketDetail(id) {
return request({

View File

@ -86,13 +86,13 @@ export const asyncRoutes = [
component: Layout,
redirect: '/mtm/material/',
name: 'mtm',
meta: { title: '制造管理', icon: 'example', perms: ['procurement_set'] },
meta: { title: '制造管理', icon: 'example', perms: ['mtm_manage'] },
children: [
{
path: 'material',
name: 'material',
component: () => import('@/views/mtm/material'),
meta: { title: '物料清单', icon: 'example', perms: ['vendor_manage'] }
meta: { title: '物料清单', icon: 'example', perms: ['mtm_material'] }
}
,
{
@ -106,7 +106,7 @@ export const asyncRoutes = [
path: 'process',
name: 'process',
component: () => import('@/views/mtm/process'),
meta: { title: '工序管理', icon: 'example', perms: ['vendor_manage'] }
meta: { title: '工序管理', icon: 'example', perms: ['mtm_process'] }
},
{
path: 'step/:id',
@ -127,7 +127,7 @@ export const asyncRoutes = [
path: '/mtm/productprocess/',
name: 'productprocess',
component: () => import('@/views/mtm/productprocess'),
meta: { title: '产品管理', icon: 'example', perms: ['vendor_manage'] }
meta: { title: '产品管理', icon: 'example', perms: ['mtm_productprocess'] }
},
]
}
@ -137,25 +137,25 @@ export const asyncRoutes = [
component: Layout,
redirect: '/pm/plan',
name: 'pm',
meta: { title: '生产管理', icon: 'example', perms: ['equipment_set'] },
meta: { title: '生产管理', icon: 'example', perms: ['pm_manage'] },
children: [
{
path: 'plan',
name: 'plan',
component: () => import('@/views/pm/plan'),
meta: { title: '生产计划管理', icon: 'example', perms: ['index_manage'] }
meta: { title: '生产计划管理', icon: 'example', perms: ['pm_plan'] }
},
{
path: 'resources',
name: 'resources',
component: () => import('@/views/pm/resources'),
meta: { title: '生产资源配置', icon: 'example', perms: ['index_manage'] }
meta: { title: '生产资源配置', icon: 'example', perms: ['pm_resources'] }
},
{
path: 'testitem',
name: 'testitem',
component: () => import('@/views/pm/plan'),
meta: { title: '生产作业管理', icon: 'example', perms: ['index_manage'] }
meta: { title: '生产作业管理', icon: 'example', perms: ['pm_testitem'] }
}
]
},
@ -164,31 +164,31 @@ export const asyncRoutes = [
component: Layout,
redirect: '/em/equipment',
name: 'em',
meta: { title: '设备管理', icon: 'example', perms: ['equipment_set'] },
meta: { title: '设备管理', icon: 'example', perms: ['em_manage'] },
children: [
{
path: 'equipment',
name: 'equipment',
component: () => import('@/views/em/equipment'),
meta: { title: '生产设备', icon: 'example', perms: ['index_manage'] }
meta: { title: '生产设备', icon: 'example', perms: ['em_equipment'] }
},
{
path: 'detection ',
name: 'detection ',
component: () => import('@/views/em/detection'),
meta: { title: '监视和测量设备', icon: 'example', perms: ['index_manage'] }
meta: { title: '监视和测量设备', icon: 'example', perms: ['em_detection'] }
},
{
path: 'record',
name: 'record',
component: () => import('@/views/em/record'),
meta: { title: '校准检定记录', icon: 'example', perms: ['index_manage'] }
meta: { title: '校准检定记录', icon: 'example', perms: ['em_record'] }
},
{
path: 'detection ',
name: 'detection ',
component: () => import('@/views/em/detection'),
meta: { title: '运维记录', icon: 'example', perms: ['index_manage'] }
meta: { title: '运维记录', icon: 'example', perms: ['em_detection'] }
}
]
},
@ -319,32 +319,39 @@ export const asyncRoutes = [
component: Layout,
redirect: '/workflow/index',
name: 'workflow',
meta: { title: '工作流', icon: 'example', perms: ['workflow_set'] },
meta: { title: '工作流', icon: 'example', perms: ['workflow_manage'] },
children: [
{
path: 'index',
name: 'index',
component: () => import('@/views/workflow/index'),
meta: { title: '工作流配置', icon: 'example', perms: ['workflow_manage'] }
meta: { title: '工作流配置', icon: 'example', perms: ['workflow_index'] }
},
{
path: 'ticket',
name: 'ticket',
component: () => import('@/views/workflow/ticket'),
meta: { title: '工单管理', icon: 'example', perms: ['workflow_manage'] },
meta: { title: '工单管理', icon: 'example' ,noCache: true, perms: ['workflow_ticket'] },
},
{
path: 'workFlowTickets',
name: 'workFlowTickets',
component: () => import('@/views/workflow/workFlowTickets'),
meta: { title: '工单管理', icon: 'example' ,noCache: true,},
hidden: true
},
{
path: 'configuration',
name: 'configuration',
component: () => import('@/views/workflow/configuration'),
meta: { title: '人员信息详情', icon: 'example', perms: ['workflow_manage'] },
meta: { title: '人员信息详情', icon: 'example' },
hidden: true
},
{
path: 'ticketHandle',
name: 'ticketHandle',
component: () => import('@/views/workflow/ticketHandle'),
meta: { title: '工单处理', icon: 'example', perms: ['workflow_manage'] },
meta: { title: '工单处理', icon: 'example',noCache: true,},
hidden: true
},
]

View File

@ -86,21 +86,21 @@ div:focus {
.el-dialog__header {
padding: 10px 10px 6px;
}
// .el-dialog{
// display: flex;
// flex-direction: column;
// margin:0 !important;
// position:absolute;
// top:50%;
// left:50%;
// transform:translate(-50%,-50%);
// /*height:600px;*/
// max-height:calc(100% - 30px);
// max-width:calc(100% - 30px);
// }
.el-dialog{
display: flex;
flex-direction: column;
margin:0 !important;
position:absolute;
top:50%;
left:50%;
transform:translate(-50%,-50%);
/*height:600px;*/
max-height:calc(100% - 30px);
max-width:calc(100% - 30px);
}
.el-dialog .el-dialog__body{
// flex:1;
// overflow: auto;
flex:1;
overflow: auto;
padding: 8px 12px;
}

View File

@ -37,6 +37,7 @@
name="password"
tabindex="2"
auto-complete="on"
id="passwordInput"
@keyup.enter.native="handleLogin"
><svg-icon
slot="prefix"
@ -200,7 +201,9 @@
margin-left: 2px;
}
}
#passwordInput{
padding-right: 35px;
}
.show-pwd {
height: 39px;
margin-right: 2px;

View File

@ -102,7 +102,7 @@
<p>创建时间 {{watchedCreateTime}}</p>
</el-col>
</el-row>
<svg height=800 id="mySvg" style="width: max-content!important">
<svg height=800 id="mySvg" style="width: 100%;">
</svg>
</div>
</div>
@ -278,7 +278,7 @@ export default {
});
},
handleTicket(scope){
this.$router.push({name:"ticket",params:{workflow:scope.row.id}})
this.$router.push({name:"workFlowTickets",params:{workflow:scope.row.id}})
},
async confirm(form) {
debugger;
@ -321,12 +321,12 @@ export default {
that.limitedWatch = true;
that.$nextTick(()=>{
var g = new dagreD3.graphlib.Graph().setGraph({
align: 'DL',
rankdir: 'DL',
nodesep: 100,
edgesep: 100,
ranksep: 50,
marginx: 0,
marginy: 50,
edgesep: 10,//两条线之间的距离
ranksep: 50,//节点之间的距离
marginx: 160,
marginy: 20,
});
//获取state得到节点
getWfStateList(workFlow).then((response) => {
@ -343,8 +343,6 @@ export default {
//节点样式
style: "fill:#fff;stroke:#000",
labelStyle: "fill:#000;",
// width: 83,
// height: 40,
rx :5,//矩形节点圆角度
ry :5
});
@ -356,9 +354,8 @@ export default {
getWfTransitionList(workFlow).then((res)=>{
if(res.data){
let transitionList = res.data;
transitionList.forEach((transitions)=>{
let transition0 = transitions;
if (transition0.condition_expression.length>3){
transitionList.forEach((transition0)=>{
if (transition0.condition_expression.length>0){
debugger;
g.setNode(transition0.source_state_.id+100000, {label: "条件表达式",style: "stroke: #000;fill: #afa", shape: "diamond"});
g.setEdge(transition0.source_state_.id, transition0.source_state_.id+100000, {
@ -366,7 +363,7 @@ export default {
label: transition0.name,
style: "fill:#ffffff;stroke:#c0c1c3;stroke-width:1.5px"
});
let condition_expression = JSON.parse(transition0.condition_expression);
let condition_expression = transition0.condition_expression;
condition_expression.forEach(condition_expression0=>{
g.setEdge(transition0.source_state_.id+100000, condition_expression0.target_state, {
label: condition_expression0.label,
@ -386,7 +383,6 @@ export default {
g.nodes().forEach(function (v) {
console.log("Node " + v + ": " + JSON.stringify(g.node(v)));
});
// 创建渲染器
let render = new dagreD3.render();
// 选择 svg 并添加一个g元素作为绘图容器.
@ -399,6 +395,7 @@ export default {
}
});
})
},
closeMark(){
@ -415,33 +412,25 @@ export default {
this.hasJsonFlag = true
},
onError(value) {
// console.log("json错误了value:", value);
this.hasJsonFlag = false
},
onJsonChange1 (value) {
// console.log('更改value:', value);
// 实时保存
this.onJsonSave1(value)
},
onJsonSave1 (value) {
// console.log('保存value:', value);
this.display_form_str = value
this.hasJsonFlag1 = true
},
onError1(value) {
// console.log("json错误了value:", value);
this.hasJsonFlag1 = false
},
// 检查json
checkJson(){
if (this.hasJsonFlag == false){
// console.log("json验证失败")
// this.$message.error("json验证失败")
alert("限制表达式json验证失败")
return false
} else {
// console.log("json验证成功")
// this.$message.success("json验证成功")
alert("限制表达式json验证成功")
return true
}
@ -449,13 +438,9 @@ export default {
// 检查json
checkJson2(){
if (this.hasJsonFlag1 == false){
// console.log("json验证失败")
// this.$message.error("json验证失败")
alert("展现表单字段json验证失败")
return false
} else {
// console.log("json验证成功")
// this.$message.success("json验证成功")
alert("展现表单字段json1验证成功")
return true
}
@ -464,6 +449,19 @@ export default {
};
</script>
<style scoped>
::-webkit-scrollbar {
width: 15px;
}
::-webkit-scrollbar-track{
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.2);
background-color: #fefefe;
border-radius: 7px;
}
::-webkit-scrollbar-thumb{
border-radius: 7px;
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.5);
background-color: #f5f5f5;
}
.svgMark{
width: 100%;
height: 100%;
@ -483,6 +481,8 @@ export default {
margin: 10vh auto 0;
text-align: center;
border-radius: 2px;
max-height: 75vh;
overflow-y: scroll;
}
.svgItem{
padding: 20px 40px 0 ;

View File

@ -1,51 +1,49 @@
<template>
<div class="app-container">
<el-card>
<div style="margin-top: 10px">
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
>新增</el-button
>
</div>
<div style="margin-top: 10px">
<el-button type="primary" icon="el-icon-plus" @click="handleCreate">新增
</el-button>
</div>
</el-card>
<el-card style="margin-top: 10px">
<el-table
:data="wfstateList"
style="width: 100%"
>
<el-table-column type="index" width="50" />
<el-table-column width="180" label="名称">
<el-table-column type="index" width="50"/>
<el-table-column width="180" label="名称">
<template slot-scope="scope">{{ scope.row.name }}</template>
</el-table-column>
<el-table-column width="180" label="是否隐藏">
<template slot-scope="scope">
<el-table-column width="180" label="是否隐藏">
<template slot-scope="scope">
{{ !!(scope.row.is_hidde)?'':'' }}
</template>
</el-table-column>
<el-table-column width="180" label="顺序ID">
<el-table-column width="180" label="顺序ID">
<template slot-scope="scope">{{ scope.row.sort }}</template>
</el-table-column>
<el-table-column width="180" label="类型">
<el-table-column width="180" label="类型">
<template slot-scope="scope">
<el-tag effect="plain" v-if="scope.row.type==0">
普通类型
<el-tag effect="plain" v-if="scope.row.type==0">
普通类型
</el-tag>
<el-tag effect="plain" v-if="scope.row.type==1">
初始状态
<el-tag effect="plain" v-if="scope.row.type==1">
初始状态
</el-tag>
<el-tag effect="plain" v-if="scope.row.type==2">
结束状态
结束状态
</el-tag>
</template>
</el-table-column>
<el-table-column width="180" label="参与人类型">
<el-table-column width="180" label="参与人类型">
<template slot-scope="scope">{{ options_[scope.row.participant_type] }}</template>
</el-table-column>
<el-table-column width="180" label="创建时间">
<el-table-column width="180" label="创建时间">
<template slot-scope="scope">{{ scope.row.create_time }}</template>
</el-table-column>
<el-table-column
align="center"
@ -53,21 +51,19 @@
width="220px"
>
<template slot-scope="scope">
<!-- v-if="checkPermission(['workflow_update'])" -->
<el-link
v-if="checkPermission(['wfstate_update'])"
@click="handleEdit(scope)"
>编辑</el-link
>
>编辑
</el-link>
<el-link
v-if="checkPermission(['wfstate_delete'])"
type="danger"
@click="handleDelete(scope)"
>删除</el-link
>
>删除
</el-link>
</template>
</el-table-column>
</el-table>
</el-card>
<el-dialog
:visible.sync="dialogVisible"
@ -81,7 +77,7 @@
:rules="rule1"
>
<el-form-item label="名称" prop="name">
<el-input v-model="wfstate.name" placeholder="名称" />
<el-input v-model="wfstate.name" placeholder="名称"/>
</el-form-item>
<el-form-item
label="是否隐藏"
@ -90,52 +86,52 @@
>
<el-switch v-model="wfstate.is_hidden"></el-switch>
</el-form-item>
<el-form-item label="状态顺序" prop="sort">
<el-input v-model="wfstate.sort" type="number" placeholder="状态顺序" />
<el-form-item label="状态顺序" prop="sort">
<el-input v-model="wfstate.sort" type="number" placeholder="状态顺序"/>
</el-form-item>
<el-form-item label="状态类型" prop="type">
<el-select style="width: 100%" v-model="wfstate.type" placeholder="请选择">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
<el-form-item label="状态类型" prop="type">
<el-select style="width: 100%" v-model="wfstate.type" placeholder="请选择">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item
<el-form-item
label="允许撤回"
prop="enable_retreat"
label-width="120px"
>
<el-switch v-model="wfstate.enable_retreat"></el-switch>
</el-form-item>
<el-form-item label="参与者类型" prop="participant_type">
<el-select style="width: 100%" v-model="wfstate.participant_type" placeholder="请选择" @change="typeChange">
<el-option
v-for="item in typeoptions"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
<el-form-item label="参与者类型" prop="participant_type">
<el-select style="width: 100%" v-model="wfstate.participant_type" placeholder="请选择" @change="typeChange">
<el-option
v-for="item in typeoptions"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="参与者" prop="participant" v-if="wfstate.participant_type==1">
<el-select style="width: 100%" v-model="participant" placeholder="请选择参与者">
<el-select style="width: 100%" v-model="participant" placeholder="请选择参与者">
<el-option v-for="item in staffs" :key="item.id" :label="item.name" :value="item.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="参与者" prop="participant" v-if="wfstate.participant_type==2">
<el-select style="width: 100%" v-model="participants" multiple placeholder="请选择参与者">
<el-select style="width: 100%" v-model="participants" multiple placeholder="请选择参与者">
<el-option v-for="item in staffs" :key="item.id" :label="item.name" :value="item.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="分配方式" prop="participant" v-if="wfstate.participant_type==2">
<el-select style="width: 100%" v-model="wfstate.distribute_type" placeholder="请选择分配方式">
<el-select style="width: 100%" v-model="wfstate.distribute_type" placeholder="请选择分配方式">
<el-option label="主动接单" value="1"></el-option>
<el-option label="直接处理" value="2"></el-option>
<el-option label="随机分配" value="3"></el-option>
@ -143,7 +139,7 @@
</el-select>
</el-form-item>
<el-form-item label="部门" prop="participant" v-if="wfstate.participant_type==3">
<el-select style="width: 100%" v-model="participant" placeholder="请选择部门">
<el-select style="width: 100%" v-model="participant" placeholder="请选择部门">
<el-option v-for="item in departments" :key="item.id" :label="item.name" :value="item.id">
</el-option>
</el-select>
@ -152,21 +148,23 @@
<el-button @click="addWordStatusChange">添加修改</el-button>
<el-row v-for="(item,$index) in statusChange" :key="item+$index" style="margin-top: 10px">
<el-col :span="11">
<el-select style="width: 100%" v-model="item.name" placeholder="请选择字段">
<el-option v-for="item in customfieldList" :key="item.id" :label="item.field_name" :value="item.field_key">
<el-select style="width: 100%" v-model="item.name" placeholder="请选择字段">
<el-option v-for="item in customfieldList" :key="item.id" :label="item.field_name"
:value="item.field_key">
</el-option>
</el-select>
</el-col>
<el-col :span="1" style="height: 1px;"></el-col>
<el-col :span="8">
<el-select style="width: 100%" v-model="item.value" placeholder="请选择状态">
<el-select style="width: 100%" v-model="item.value" placeholder="请选择状态">
<el-option label="只读" value="1"></el-option>
<el-option label="必填" value="2"></el-option>
<el-option label="可选" value="3"></el-option>
</el-select>
</el-col>
<el-col :span="2" style="text-align: center" v-if="$index!==0">
<i class="el-icon-remove-outline" @click.prevent="removeStatusChange($index)" style="color: red;font-size: 16px;"></i>
<i class="el-icon-remove-outline" @click.prevent="removeStatusChange($index)"
style="color: red;font-size: 16px;"></i>
</el-col>
</el-row>
</el-form-item>
@ -179,53 +177,53 @@
</div>
</template>
<script>
import { getWfStateList, createWfState,updateWfState,deleteWfState,getWfCustomfieldList } from "@/api/workflow";
import { getOrganizationList,getUserList } from "@/api/user";
import checkPermission from "@/utils/permission";
const defaultwfstate = {
name: "",
};
export default {
components: { },
name: "State",
props: ["ID"],
data() {
return {
wfstate: {
name:'',
is_hidden:'',
sort:'',
type:'',
enable_retreat:'',
participant_type:'',
participant:'',
distribute_type:'',//分发类型
state_fields:{}//字段状态是否可写
},
statusChange:[],
participant:'',
participants:[],
is_hidden:false,
enable_retreat:false,
staffs:[],
departments:[],
customfieldList:[],
/*wfstateList: {
count:0
},*/
wfstateList:[],
options_:{
"0":'无处理',
"1":'个人',
"2":'多人',
"3":'部门',
"4":'角色',
"5":'变量',
"6":'普通类型',
"7":'工单字段',
"8":'父工单字段',
},
options: [{
import {getWfStateList, createWfState, updateWfState, deleteWfState, getWfCustomfieldList} from "@/api/workflow";
import {getOrganizationList, getUserList} from "@/api/user";
import checkPermission from "@/utils/permission";
const defaultwfstate = {
name: "",
};
export default {
components: {},
name: "State",
props: ["ID"],
data() {
return {
wfstate: {
name: '',
is_hidden: '',
sort: '',
type: '',
enable_retreat: '',
participant_type: '',
participant: '',
distribute_type: '',//分发类型
state_fields: {}//字段状态是否可写
},
statusChange: [],
participant: '',
participants: [],
is_hidden: false,
enable_retreat: false,
staffs: [],
departments: [],
customfieldList: [],
/*wfstateList: {
count:0
},*/
wfstateList: [],
options_: {
"0": '无处理',
"1": '个人',
"2": '多人',
"3": '部门',
"4": '角色',
"5": '变量',
"6": '普通类型',
"7": '工单字段',
"8": '父工单字段',
},
options: [{
value: 0,
label: '普通类型'
}, {
@ -235,7 +233,7 @@ export default {
value: 2,
label: '结束状态'
}],
typeoptions: [{
typeoptions: [{
value: 0,
label: '无处理'
}, {
@ -245,182 +243,186 @@ export default {
value: 2,
label: '多人'
}
, {
value: 3,
label: '部门'
}
, {
value: 4,
label: '角色'
}
, {
value: 5,
label: '变量'
}
, {
value: 7,
label: '工单字段'
}
, {
value: 8,
label: '父工单字段'
}],
display_form_str:[],
limit_expression:[],
dialogVisible: false,
dialogType: "new",
rule1: {
name: [{ required: true, message: "请输入", trigger: "blur" }],
sort: [{ required: true, message: "请输入", trigger: "blur" }],
type:[{ required: true, message: "选择", trigger: "blur" }],
, {
value: 3,
label: '部门'
}
, {
value: 4,
label: '角色'
}
, {
value: 5,
label: '变量'
}
, {
value: 7,
label: '工单字段'
}
, {
value: 8,
label: '父工单字段'
}],
display_form_str: [],
limit_expression: [],
dialogVisible: false,
dialogType: "new",
rule1: {
name: [{required: true, message: "请输入", trigger: "blur"}],
sort: [{required: true, message: "请输入", trigger: "blur"}],
type: [{required: true, message: "选择", trigger: "blur"}],
},
};
},
created() {
this.getList();
this.getUser();
this.getDepartment();
},
methods: {
checkPermission(value){
debugger;
console.log(checkPermission(value))
checkPermission(value);
},
};
},
created() {
this.getList();
this.getUser();
this.getDepartment();
},
methods: {
checkPermission,
getList() {
getWfStateList(this.ID).then((response) => {
if (response.data) {
this.wfstateList = response.data;
}
});
getWfCustomfieldList(this.ID).then((response) => {
if (response.data) {
this.customfieldList = response.data;
}
getList() {
});
},
getUser(){
getUserList({}).then(res=>{
if(res.data){
this.staffs = res.data.results;
}
})
},
getDepartment(){
getOrganizationList().then(res=>{
if(res.data){
this.departments = res.data;
}
})
},
//参与者类型变化
typeChange(){
this.participant = '';
this.participants = [];
},
//打开新建
handleCreate() {
this.wfstate = Object.assign({}, defaultwfstate);
this.dialogType = "new";
this.dialogVisible = true;
this.$nextTick(() => {
this.$refs["Form"].clearValidate();
});
},
//打开编辑
handleEdit(scope) {
this.wfstate = Object.assign({}, scope.row); // copy obj
this.participants = this.wfstate.participant;
this.participant = this.wfstate.participant;
/////
debugger;
console.log(this.wfstate.state_fields);
let arr = [];
for (let pro in this.wfstate.state_fields) {
let obj = new Object();
obj.name = pro;
obj.value = this.wfstate.state_fields[pro];
arr.push(obj)
}
this.statusChange = arr;
this.wfstate.distribute_type = this.wfstate.distribute_type.toString();
this.dialogType = "edit";
this.dialogVisible = true;
this.$nextTick(() => {
this.$refs["Form"].clearValidate();
});
},
addWordStatusChange(){
this.statusChange.push({name:'',value:''})
},
removeStatusChange(index){
this.statusChange.splice(index, 1)
},
//编辑新建
async confirm(form) {
this.$refs[form].validate((valid) => {
if (valid) {
const isEdit = this.dialogType === "edit";
// this.wfstate.participant = 1;
let state_fields = {};
if(this.statusChange.length>0){
for(let i=0;i<this.statusChange.length;i++){
state_fields[this.statusChange[i].name] = this.statusChange[i].value;
}
getWfStateList(this.ID).then((response) => {
if (response.data) {
this.wfstateList = response.data;
}
debugger;
console.log(state_fields);
this.wfstate.state_fields = state_fields;
this.wfstate.participant = this.participant!==''?this.participant:this.participants;
if (isEdit) {
updateWfState(this.wfstate.id, this.wfstate).then((res) => {
if (res.code >= 200) {
this.getList();
this.dialogVisible = false;
this.$message.success("成功");
this.getList();
}
});
} else {
this.wfstate.workflow=this.ID;
createWfState(this.wfstate).then((res) => {
if (res.code >= 200) {
this.getList();
this.dialogVisible = false;
this.getList();
this.$message.success("成功");
}
});
}
} else {
return false;
}
});
},
handleDelete(scope) {
this.$confirm("确认删除?", "警告", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
await deleteWfState(scope.row.id);
this.getList();
this.$message.success("成功");
})
.catch((err) => {
console.error(err);
});
getWfCustomfieldList(this.ID).then((response) => {
if (response.data) {
this.customfieldList = response.data;
}
});
},
getUser() {
getUserList({}).then(res => {
if (res.data) {
this.staffs = res.data.results;
}
})
},
getDepartment() {
getOrganizationList().then(res => {
if (res.data) {
this.departments = res.data;
}
})
},
//参与者类型变化
typeChange() {
this.participant = '';
this.participants = [];
},
//打开新建
handleCreate() {
this.wfstate = Object.assign({}, defaultwfstate);
this.dialogType = "new";
this.dialogVisible = true;
this.$nextTick(() => {
this.$refs["Form"].clearValidate();
});
},
//打开编辑
handleEdit(scope) {
this.wfstate = Object.assign({}, scope.row); // copy obj
this.participants = this.wfstate.participant;
this.participant = this.wfstate.participant;
/////
debugger;
console.log(this.wfstate.state_fields);
let arr = [];
for (let pro in this.wfstate.state_fields) {
let obj = new Object();
obj.name = pro;
obj.value = this.wfstate.state_fields[pro];
arr.push(obj)
}
this.statusChange = arr;
this.wfstate.distribute_type = this.wfstate.distribute_type.toString();
this.dialogType = "edit";
this.dialogVisible = true;
this.$nextTick(() => {
this.$refs["Form"].clearValidate();
});
},
addWordStatusChange() {
this.statusChange.push({name: '', value: ''})
},
removeStatusChange(index) {
this.statusChange.splice(index, 1)
},
//编辑新建
async confirm(form) {
this.$refs[form].validate((valid) => {
if (valid) {
const isEdit = this.dialogType === "edit";
// this.wfstate.participant = 1;
let state_fields = {};
if (this.statusChange.length > 0) {
for (let i = 0; i < this.statusChange.length; i++) {
state_fields[this.statusChange[i].name] = this.statusChange[i].value;
}
}
debugger;
console.log(state_fields);
this.wfstate.state_fields = state_fields;
this.wfstate.participant = this.wfstate.participant_type === 1 ? this.participant : this.participants;
if (isEdit) {
updateWfState(this.wfstate.id, this.wfstate).then((res) => {
if (res.code >= 200) {
this.getList();
this.dialogVisible = false;
this.$message.success("成功");
this.getList();
}
});
} else {
this.wfstate.workflow = this.ID;
createWfState(this.wfstate).then((res) => {
if (res.code >= 200) {
this.getList();
this.dialogVisible = false;
this.getList();
this.$message.success("成功");
}
});
}
} else {
return false;
}
});
},
handleDelete(scope) {
this.$confirm("确认删除?", "警告", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
await deleteWfState(scope.row.id);
this.getList();
this.$message.success("成功");
})
.catch((err) => {
console.error(err);
});
},
},
},
};
};
</script>

View File

@ -61,10 +61,13 @@
<el-table-column align="center" label="操作">
<template slot-scope="scope">
<el-link v-if="scope.row.state_.distribute_type==1&&scope.row.participant_type==2" type="danger" @click="handleGetTicket(scope)">接单</el-link>
<el-link v-else-if="(scope.row.act_state==1||scope.row.act_state==3)&&scope.row.participant_type!==2" type="primary" @click="handleDetail(scope)">处理</el-link>
<!--如果state_.retreat为可退回则显示撤回按钮-->
<el-link v-if="scope.row.state_.enable_retreat&&userId==scope.row.create_by" type="danger" @click="handleRetreat(scope)">撤回</el-link>
<el-link v-else-if="(scope.row.act_state==1||scope.row.act_state==3)&&scope.row.participant_type!==2&&scope.row.state_.type===0" type="primary" @click="handleDetail(scope)">处理</el-link>
<el-link v-if="scope.row.state_.type==1&&userId==1" type="danger" @click="handleClose(scope,'2')">关闭</el-link>
<!--如果state_.retreat为可退回则显示撤回按钮 state_.type==1处于草稿状态 -->
<el-link v-if="scope.row.state_.enable_retreat&&userId==scope.row.create_by&&scope.row.state_.type!==1" type="danger" @click="handleClose(scope,'1')">撤回</el-link>
<el-link type="success" @click="handleDelete(scope)">删除</el-link>
<el-link type="success" @click="handlePicture(scope)">查看流程图</el-link>
<el-link type="success" @click="handleLogs(scope)">工单日志</el-link>
</template>
</el-table-column>
</el-table>
@ -107,7 +110,12 @@
</el-table-column>
<el-table-column align="center" label="操作">
<template slot-scope="scope">
<el-link type="primary" v-if="scope.row.act_state==4" @click="handlePicture(scope)">查看流程图</el-link>
<!-- <el-link v-if="scope.row.state_.distribute_type==1&&scope.row.participant_type==2" type="danger" @click="handleGetTicket(scope)">接单</el-link>
<el-link v-else-if="(scope.row.act_state==1||scope.row.act_state==3)&&scope.row.participant_type!==2&&scope.row.state_.type===0" type="primary" @click="handleDetail(scope)">处理</el-link>
-->
<el-link v-if="scope.row.state_.type==1&&userId==1" type="danger" @click="handleClose(scope,'2')">关闭</el-link>
<el-link type="success" @click="handlePicture(scope)">查看流程图</el-link>
<el-link type="success" @click="handleLogs(scope)">工单日志</el-link>
</template>
</el-table-column>
</el-table>
@ -150,10 +158,11 @@
</el-table-column>
<el-table-column align="center" label="操作">
<template slot-scope="scope" v-if="scope.row.state_">
<el-link v-if="scope.row.state_.distribute_type==1&&scope.row.participant_type==2" type="danger" @click="handleGetTicket(scope)">接单</el-link>
<el-link v-else-if="(scope.row.act_state==1||scope.row.act_state==3)&&scope.row.participant_type!==2" type="primary" @click="handleDetail(scope)">处理</el-link>
<el-link v-if="scope.row.state_.enable_retreat" type="danger" @click="handleRetreat(scope)">撤回</el-link>
<el-link v-if="scope.row.state_.enable_retreat&&scope.row.state_.type!==1" type="danger" @click="handleClose(scope,'1')">撤回</el-link>
<el-link v-if="scope.row.state_.type==1" type="danger" @click="handleClose(scope,'2')">关闭</el-link>
<el-link type="success" @click="handleDelete(scope)">删除</el-link>
<el-link type="success" @click="handlePicture(scope)">查看流程图</el-link>
<el-link type="success" @click="handleLogs(scope)">工单日志</el-link>
</template>
</el-table-column>
</el-table>
@ -197,7 +206,7 @@
<el-table-column align="center" label="操作">
<template slot-scope="scope">
<el-link type="danger" @click="handlePicture(scope)">查看流程图</el-link>
<el-link v-if="scope.row.act_state==1" type="danger" @click="handleDetail(scope)">处理</el-link>
<el-link type="success" @click="handleLogs(scope)">工单日志</el-link>
</template>
</el-table-column>
</el-table>
@ -224,25 +233,27 @@
<el-step :title="item.name" v-for="item in flowSteps " :key="item.id">
</el-step>
</el-steps>
<svg height=800 id="mySvg" style="width:100%!important;">
</svg>
<div style="width: 90%;margin: auto;">
<svg height=800 id="mySvg" style="width:100%!important;">
</svg>
</div>
</div>
</div>
<el-dialog :visible.sync="limitedRetreat" title="工单撤回">
<el-dialog :visible.sync="limitedRetreat" :title="handleTitle">
<el-row>
<el-form ref="Form" :model="handleForm" label-width="100px" label-position="right" :rules="handleRule">
<el-col :span="2" style="height: 1px;"></el-col>
<el-col :span="20" style="margin:6vh 0">
<el-form-item label="撤回原因">
<el-form ref="Form" :model="handleForm" label-width="100px" label-position="right">
<el-col :span="1" style="height: 1px;"></el-col>
<el-col :span="22" style="margin:3vh 0">
<el-form-item :label="handleLabel">
<el-input type="textarea" :rows="3" v-model="handleForm.suggestion" placeholder="撤回原因"/>
</el-form-item>
</el-col>
</el-form>
</el-row>
<div style="text-align: center">
<el-button class="filter-item" type="" @click="retreatCancel">取消</el-button>
<el-button class="filter-item" type="primary" @click="retreatSubmit">确定</el-button>
<el-button class="filter-item" type="" @click="handleCancel">取消</el-button>
<el-button class="filter-item" type="primary" @click="handleSubmit">确定</el-button>
</div>
</el-dialog>
<el-dialog :visible.sync="limitedAdd" title="新增工单">
@ -337,13 +348,49 @@
<el-button type="primary" @click="confirm('Form')">确认</el-button>
</div>
</el-dialog>
<el-dialog :visible.sync="limitedFlowLogs" title="工单日志">
<el-table :data="floeLogs" fit stripe
style="width: 100%;border-top:1px solid #EBEEF5;"
height="100"
highlight-current-row
v-el-height-adaptive-table="{bottomOffset: 60}">
<el-table-column label="工单标题" min-width="100">
<template slot-scope="scope" v-if="scope.row.ticket_data">
<span>{{scope.row.ticket_data.title}}</span>
</template>
</el-table-column>
<!-- <el-table-column label="当前状态" min-width="100">
<template slot-scope="scope">
<el-tag v-if="scope.row.act_state==0" label="草稿中" value="scope.row.act_state">草稿中</el-tag>
<el-tag v-else-if="scope.row.act_state==1" label="进行中" value="scope.row.act_state">进行中</el-tag>
<el-tag v-else-if="scope.row.act_state==2" label="被退回" value="scope.row.act_state">被退回</el-tag>
<el-tag v-else-if="scope.row.act_state==3" label="被撤回" value="scope.row.act_state">被撤回</el-tag>
<el-tag v-else-if="scope.row.act_state==4" label="已完成" value="scope.row.act_state">已完成</el-tag>
<el-tag v-else-if="scope.row.act_state==5" label="已关闭" value="scope.row.act_state">已关闭</el-tag>
</template>
</el-table-column>-->
<el-table-column label="进行状态" min-width="100">
<template slot-scope="scope" v-if="scope.row.state_">
<span v-if="scope.row.state_.type==0">{{scope.row.state_.name}}</span>
<span v-else>{{scope.row.state_.name}}</span>
</template>
</el-table-column>
<el-table-column label="操作人" min-width="100">
<template slot-scope="scope" v-if="scope.row.participant_">{{ scope.row.participant_.name }}</template>
</el-table-column>
<el-table-column label="操作意见" min-width="100" prop="suggestion">
</el-table-column>
<el-table-column label="更新时间" min-width="100" prop="update_time">
</el-table-column>
</el-table>
</el-dialog>
</div>
</template>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
import { upUrl, upHeaders } from "@/api/file";
import {getWorkflowList,getWfCustomfieldList,createTicket,getWfStateList,getTickets,ticketAccpet,getWfTransitionList,
ticketHandle,getWfFlowSteps,getTicketDetail,getTicketTransitions,getTicketFlowlog,getTicketRetreat} from "@/api/workflow";
ticketHandle,getWfFlowSteps,getTicketDetail,getTicketTransitions,getTicketFlowlog,ticketRetreat,ticketClose,ticketDestory} from "@/api/workflow";
import Pagination from "@/components/Pagination";
import dagreD3 from 'dagre-d3'
import * as d3 from 'd3'
@ -389,6 +436,8 @@
limitedStep:false,
limitedAdd:false,
limitedRetreat:false,
limitedFlowLogs:false,
floeLogs:[],
nodes: [],
tooltip:null,
edges: [],
@ -397,11 +446,12 @@
operationBtn:[],
customfields:[],
transitions:[],
handleLabel:'撤回原因',
handleTitle:'工单撤回',
rule1:{
title: [{ required: true, message: "请输入", trigger: "blur" }],
workflow: [{ required: true, message: "选择", trigger: "blur" }]
}
,
}
},
@ -416,15 +466,6 @@
this.getStates();
this.getWorkFlow();
},
activated(){
this.workflow = this.$route.params.workflow;
if(this.workflow){//有传参
this.pageForm.workflow = parseInt(this.workflow);
}
this.getList();
this.getStates();
this.getWorkFlow();
},
methods:{
getList(){
this.listLoading = true;
@ -439,16 +480,12 @@
getTicketFlowlogs(id){
getTicketFlowlog(id).then(res=>{
if(res.data){
debugger;
console.log(res)
this.logs = res.data;
}
})
},
handleClick(tab, event) {
console.log(tab, event);
console.log(this.pageForm.category);
debugger;
this.getList();
},
//获取工作流所有状态
@ -563,30 +600,58 @@
}
});
},
retreatCancel(){
handleCancel(){
this.limitedRetreat = false;
},
retreatSubmit(){
this.$confirm("确认撤回吗?", "温馨提示", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "warning",
})
.then(async () => {
getTicketRetreat(this.retreatId,this.handleForm).then(res=>{
this.limitedRetreat = false;
this.getList();
this.$message.success("成功");
})
handleSubmit(){
debugger;
if(this.handleTitle === '撤回工单'){
this.$confirm("确认撤回工单吗?", "温馨提示", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "warning",
})
.catch((err) => {
console.error(err);
});
.then(async () => {
ticketRetreat(this.retreatId,this.handleForm).then(res=>{
this.limitedRetreat = false;
this.getList();
this.$message.success("成功");
})
})
.catch((err) => {
console.error(err);
});
}else{
this.$confirm("确认关闭工单吗?", "温馨提示", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "warning",
})
.then(async () => {
ticketClose(this.retreatId,this.handleForm).then(res=>{
this.limitedRetreat = false;
this.getList();
this.$message.success("成功");
})
})
.catch((err) => {
console.error(err);
});
}
},
handleRetreat(scope){
handleClose(scope,index){
if(index==='1'){
this.handleTitle = '撤回工单';
this.handleLabel='撤回原因';
}else{
this.handleTitle = '关闭工单';
this.handleLabel='关闭原因';
}
this.limitedRetreat = true;
this.retreatId = scope.row.id;
},
handleLogs(){},
handlePicture(scope){
let that = this;
that.dialogVisible = true;
@ -594,8 +659,6 @@
that.watchedCreateTime = scope.row.create_time;
that.pageForm.workflow = scope.row.workflow;
let ticketId = scope.row.id;
// that.getStates();
// that.getTicketFlowlogs(ticketId);
getWfFlowSteps( ticketId).then((res)=>{
if(res.data){
debugger;
@ -616,12 +679,12 @@
that.actives =that.flowSteps.length;
}
var g = new dagreD3.graphlib.Graph().setGraph({
align: 'DL',
rankdir: 'DL',
nodesep: 100,
edgesep: 100,
ranksep: 50,
marginx: 300,
marginy: 50,
edgesep: 10,//两条线之间的距离
ranksep: 50,//节点之间的距离
marginx: 60,
marginy: 20,
});
//获取state得到节点
getWfStateList(that.pageForm.workflow).then((response) => {
@ -629,9 +692,6 @@
let nodes = response.data;
// 添加节点
nodes.forEach((item) => {
/*debugger;
console.log(item.sort)
console.log(that.state)*/
if(item.sort==that.sort){
g.setNode(item.id, {
// 节点标签
@ -645,7 +705,6 @@
rx :5,//矩形节点圆角度
ry :5
});
}else{
g.setNode(item.id, {
// 节点标签
@ -677,12 +736,14 @@
g.setEdge(transition0.source_state_.id, transition0.source_state_.id+100000, {
// 边标签
label: transition0.name,
// curve: d3.curveBasis,
style: "fill:#ffffff;stroke:#c0c1c3;stroke-width:1.5px"
});
let condition_expression = transition0.condition_expression;
condition_expression.forEach(condition_expression0=>{
g.setEdge(transition0.source_state_.id+100000, condition_expression0.target_state, {
label: condition_expression0.label,
// curve: d3.curveBasis,
style: "fill:#ffffff;stroke:#c0c1c3;stroke-width:1.5px"
})
})
@ -690,6 +751,7 @@
g.setEdge(transition0.source_state_.id, transition0.destination_state_.id, {
// 边标签
label: transition0.name,
// curve: d3.curveBasis,
// 边样式
style: "fill:#ffffff;stroke:#c0c1c3;stroke-width:1.5px" // 根据后台数据来改变连线的颜色
});
@ -699,6 +761,10 @@
g.nodes().forEach(function (v) {
console.log("Node " + v + ": " + JSON.stringify(g.node(v)));
});
console.log("1111111111111");
g.edges().forEach(function (e) {
console.log("Edge " + e.v + " -> " + e.w + ": " + JSON.stringify(g.edge(e)));
});
// 创建渲染器
let render = new dagreD3.render();
// 选择 svg 并添加一个g元素作为绘图容器.
@ -800,6 +866,31 @@
}
})
},
handleLogs(scope){
let id = scope.row.id;
this.limitedFlowLogs = true;
getTicketFlowlog(id).then(res=>{
if(res.data){
this.floeLogs = res.data;
}
})
},
handleDelete(scope){
let data = new Object(),ids=[];
ids.push(scope.row.id);
data.ids = ids;
this.$confirm("确认删除该工单吗?", "温馨提示", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "warning",
}).then(async () => {
ticketDestory(data).then(res=>{
if(res.code==200){
this.getList();
}
})
})
},
stepclick(){},
closeMark(){
this.dialogVisible = false;
@ -809,6 +900,19 @@
</script>
<style scoped>
::-webkit-scrollbar {
width: 15px;
}
::-webkit-scrollbar-track{
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.2);
background-color: #fefefe;
border-radius: 7px;
}
::-webkit-scrollbar-thumb{
border-radius: 7px;
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.5);
background-color: #f5f5f5;
}
.svgMark{
width: 100%;
height: 100%;
@ -828,6 +932,8 @@
margin: 10vh auto 0;
text-align: center;
border-radius: 2px;
max-height: 80vh;
overflow-y: scroll;
}
.svgItem{
padding: 20px 40px 0 ;

View File

@ -13,7 +13,7 @@
</el-col>
<el-col :span="16">
<el-card style="margin-left: 10px">
<el-form ref="Form" :model="handleForm" label-width="100px" label-position="right" :rules="handleRule">
<el-form ref="Form" :model="ticketForm" label-width="100px" label-position="right" :rules="ticketFormRule">
<el-col :span="12">
<el-form-item label="标题" style="margin-bottom: 0">
<span>{{ticketDetail.title}}</span>
@ -114,24 +114,102 @@
<el-row>
<el-col :span="12">
<el-form-item label="审批意见">
<el-input type="textarea" :rows="3" v-model="handleForm.suggestion" placeholder="审批意见"/>
<el-input type="textarea" :rows="3" v-model="ticketForm.suggestion" placeholder="审批意见"/>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div style="text-align: center">
<el-button v-for="item in operationBtn" :key="item.id" class="filter-item" type="primary" @click="operationSubmit(item.id)">{{item.name}}</el-button>
<div style="text-align: center;display: flex;justify-content: space-between;">
<div>
<template v-if="ticketDetail.state_">
<!--state_.type===0普通状态&&act_state==1进行中participant_type!==2处理人不是多人!ticketDetail.in_add_node非加签状态-->
<el-button v-if="ticketDetail.act_state==1&&ticketDetail.state_.type===0&&!ticketDetail.in_add_node" type="primary" @click="handleAdd">加签</el-button>
<el-button v-if="ticketDetail.state_.type===1" type="primary" @click="handleClick('2')">关闭</el-button>
<el-button v-if="ticketDetail.state_.enable_retreat&&(userId==ticketDetail.create_by)&&ticketDetail.state_.type!==1" type="danger" @click="handleClick('1')">撤回</el-button>
</template>
</div>
<div>
<el-button v-if="ticketDetail.in_add_node" class="filter-item" type="primary" @click="handleClick('3')">加签处理</el-button>
<el-button v-for="item in operationBtn" :key="item.id" class="filter-item" type="primary" @click="operationSubmit(item.id)">{{item.name}}</el-button>
</div>
</div>
</el-card>
<el-card style="margin-left: 10px">
<el-table :data="logs" fit stripe
style="width: 100%;border-top:1px solid #EBEEF5;"
height="100"
highlight-current-row
v-el-height-adaptive-table="{bottomOffset: 60}">
<el-table-column label="工单标题" min-width="100">
<template slot-scope="scope" v-if="scope.row.ticket_data">
<span>{{scope.row.ticket_data.title}}</span>
</template>
</el-table-column>
<el-table-column label="进行状态" min-width="100">
<template slot-scope="scope" v-if="scope.row.state_">
<span v-if="scope.row.state_.type==0">{{scope.row.state_.name}}</span>
<span v-else>{{scope.row.state_.name}}</span>
</template>
</el-table-column>
<el-table-column label="操作人" min-width="100">
<template slot-scope="scope" v-if="scope.row.participant_">{{ scope.row.participant_.name }}</template>
</el-table-column>
<el-table-column label="操作意见" min-width="100" prop="suggestion">
</el-table-column>
<el-table-column label="更新时间" min-width="100" prop="update_time">
</el-table-column>
</el-table>
</el-card>
</el-col>
</el-row>
<!--撤回1关闭2加签结束3-->
<el-dialog :visible.sync="limitedHandle" :title="handleTitle">
<el-row>
<el-form ref="Form" :model="handleForm" label-width="100px" label-position="right">
<el-col :span="1" style="height: 1px;"></el-col>
<el-col :span="22" style="margin:3vh 0">
<el-form-item :label="handleLabel">
<el-input type="textarea" :rows="3" v-model="handleForm.suggestion" placeholder="撤回原因"/>
</el-form-item>
</el-col>
</el-form>
</el-row>
<div style="text-align: center">
<el-button class="filter-item" type="" @click="retreatCancel">取消</el-button>
<el-button class="filter-item" type="primary" @click="handleSubmit">确定</el-button>
</div>
</el-dialog>
<el-dialog :visible.sync="limitedAdd" title="加签">
<el-row>
<el-form ref="Form" :model="addForm" label-width="100px" label-position="right">
<el-col :span="22">
<el-form-item label="加签操作人">
<el-select style="width: 100%" v-model="addForm.toadd_user" placeholder="加签操作人">
<el-option v-for="item in staffs" :key="item.id" :label="item.name" :value="item.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="加签原因">
<el-input type="textarea" :rows="3" v-model="addForm.suggestion" placeholder="加签原因"/>
</el-form-item>
</el-col>
</el-form>
</el-row>
<div style="text-align: center">
<el-button class="filter-item" type="" @click="addCancel">取消</el-button>
<el-button class="filter-item" type="primary" @click="addSubmit">确定</el-button>
</div>
</el-dialog>
</div>
</template>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
import { upUrl, upHeaders } from "@/api/file";
import {getWorkflowList,getWfCustomfieldList,getWfStateList,getWfTransitionList,
ticketHandle,getWfFlowSteps,getTicketDetail,getTicketTransitions,getTicketFlowlog } from "@/api/workflow";
import { getUserList } from "@/api/user";
import {getWorkflowList,getWfCustomfieldList,getWfStateList,getWfTransitionList,ticketHandle
,getWfFlowSteps,getTicketDetail,getTicketTransitions,getTicketFlowlog,ticketRetreat,
ticketAddNode,ticketAddNodeEnd,ticketClose } from "@/api/workflow";
import Pagination from "@/components/Pagination";
import dagreD3 from 'dagre-d3'
import * as d3 from 'd3'
@ -145,19 +223,31 @@
actives:4,
ticketId:0,
stateSteps:0,
handleForm:{
ticketForm:{
transition:'',
ticket_data:{},
suggestion:'',
},
handleType:'1',
handleLabel:'撤回原因',
handleTitle:'工单撤回',
handleForm:{
suggestion:'',
},
addForm:{
toadd_user:'',
suggestion:'',
},
tooltip:null,
handleRule:{},
upUrl: upUrl(),
upHeaders: upHeaders(),
userId:'',
workflow:'',
watchedName:'',
watchedCreateTime:'',
logs:[],
staffs:[],
edges: [],
nodes: [],
tooltip: [],
@ -167,11 +257,15 @@
ticketDetail:{},
operationBtn:[],
customfields:[],
transitions:[]
transitions:[],
limitedAdd:false,
limitedHandle:false,
ticketFormRule:{},
}
},
mounted(){
let that = this;
that.userId = sessionStorage.getItem('userId')
let ticketId = that.ticketId = this.$route.params.ticketId;
let workflow = that.workflow = this.$route.params.workflow;
let handleTicketId = sessionStorage.getItem('handleTicketId');
@ -190,6 +284,7 @@
ticketId = that.ticketId = handleTicketId;
workflow = that.workflow = handleTicketWorkflow;
}
this.getTicketFlowlogs(ticketId);
getTicketTransitions(ticketId).then(res=>{
this.operationBtn = res.data;
})
@ -201,6 +296,9 @@
if(res.data){
that.tooltip = that.createTooltip();
that.ticketDetail = res.data;
console.log(that.ticketDetail.state_.enable_retreat);
debugger;
let state = res.data.state;
let dat = that.flowSteps.filter((item)=>{
return item.id==state;
@ -211,12 +309,12 @@
that.actives =that.flowSteps.length;
}
var g = new dagreD3.graphlib.Graph().setGraph({
align: 'DL',
rankdir: 'DL',
nodesep: 100,
edgesep: 100,
ranksep: 50,
marginx: 50,
marginy: 50,
edgesep: 10,//两条线之间的距离
ranksep: 50,//节点之间的距离
marginx: 60,
marginy: 20,
});
//获取state得到节点
getWfStateList(workflow).then((response) => {
@ -345,6 +443,13 @@
activated(){
},
methods:{
getUser(){
getUserList({}).then(res=>{
if(res.data){
this.staffs = res.data.results;
}
})
},
//工单流转记录
getTicketFlowlogs(id){
getTicketFlowlog(id).then(res=>{
@ -403,19 +508,86 @@
.style('display', 'none')
},
operationSubmit(id){
this.handleForm.transition = id;
this.handleForm.ticket_data = this.ticketDetail.ticket_data;
this.ticketForm.transition = id;
this.ticketForm.ticket_data = this.ticketDetail.ticket_data;
let obj = new Object();
obj.transition = id;
obj.ticket_data = this.ticketDetail.ticket_data;
obj.suggestion = this.handleForm.suggestion;
console.log(this.handleForm);
obj.suggestion = this.ticketForm.suggestion;
console.log(this.ticketForm);
ticketHandle(this.ticketId,obj).then(res=>{
if (res.data){
this.$router.replace({name:"ticket"})
}
})
},
retreatCancel(){
this.limitedHandle = false;
},
handleSubmit(){
let text = '',url='';
if(this.handleType==='1'){
text = "确认撤回工单吗?";
url = ticketRetreat;
}else if(this.handleType==='2'){
text = "确认关闭工单吗?";
url = ticketClose;
}if(this.handleType==='3'){
text = "确认处理工单吗?";
url = ticketAddNodeEnd;
}
this.$confirm(text, "温馨提示", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "warning",
})
.then(async () => {
url(this.ticketId,this.handleForm).then(res=>{
this.limitedHandle = false;
this.$router.replace({name:"ticket"})
this.$message.success("成功");
})
})
.catch((err) => {
console.error(err);
});
},
handleClick(index){
this.limitedHandle = true;
this.handleType = index;
if(index==='1'){
this.handleTitle = '工单撤回';
this.handleLabel = '撤回原因';
}else if(index==='2'){
this.handleTitle = '工单关闭';
this.handleLabel = '关闭原因';
}else if(index==='3'){
this.handleTitle = '加签处理';
this.handleLabel = '加签意见';
}
},
handleAdd(){
this.getUser();
this.limitedAdd = true;
},
addCancel(){
this.limitedAdd = false;
},
addSubmit(){
ticketAddNode(this.ticketId,this.addForm).then(res=>{
if(res.data){
this.limitedAdd = false;
this.$nextTick(function () {
this.limitedAdd = true;
this.$router.replace({name:"ticket"})
})
}
})
},
addNode(){
},
}
}
</script>

View File

@ -0,0 +1,197 @@
<template>
<div class="app-container">
<el-card style="margin-bottom: 10px">
<div>
<el-select v-model="filter.workflow" placeholder="工作流" clearable style="width: 200px" class="filter-item" @change="handleFilter">
<el-option
v-for="item in workFlows"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
<el-select v-model="filter.act_state" placeholder="工单进行状态" clearable style="width: 200px" class="filter-item" @change="handleFilter">
<el-option label="草稿中" value="0" />
<el-option label="进行中" value="1" />
<el-option label="被退回" value="2" />
<el-option label="被撤回" value="3" />
<el-option label="已完成" value="4" />
<el-option label="已关闭" value="5" />
</el-select>
<el-button
class="filter-item"
type="primary"
icon="el-icon-refresh-left"
@click="resetFilter"
>重置</el-button>
<el-button
class="filter-item"
type="primary"
icon="el-icon-search"
@click="handleFilter"
>搜索</el-button>
</div>
</el-card>
<el-card>
<el-table :data="tickets"
border fit stripe
style="width: 100%"
height="100"
highlight-current-row
v-el-height-adaptive-table="{bottomOffset: 60}">
<el-table-column label="工单标题" min-width="100" prop="title">
</el-table-column>
<el-table-column label="当前状态" min-width="100">
<template slot-scope="scope">
<el-tag v-if="scope.row.act_state==0" label="草稿中" value="scope.row.act_state">草稿中</el-tag>
<el-tag v-else-if="scope.row.act_state==1" label="进行中" value="scope.row.act_state">进行中</el-tag>
<el-tag v-else-if="scope.row.act_state==2" label="被退回" value="scope.row.act_state">被退回</el-tag>
<el-tag v-else-if="scope.row.act_state==3" label="被撤回" value="scope.row.act_state">被撤回</el-tag>
<el-tag v-else-if="scope.row.act_state==4" label="已完成" value="scope.row.act_state">已完成</el-tag>
<el-tag v-else-if="scope.row.act_state==5" label="已关闭" value="scope.row.act_state">已关闭</el-tag>
</template>
</el-table-column>
<el-table-column label="进行状态" min-width="100">
<template slot-scope="scope">
<span v-if="scope.row.state_.type==0">{{scope.row.state_.name}}</span>
<span v-else>{{scope.row.state_.name}}</span>
</template>
</el-table-column>
<el-table-column label="类型" min-width="100">
<template slot-scope="scope">{{ scope.row.workflow_.name }}</template>
</el-table-column>
<el-table-column label="创建时间" min-width="100" prop="create_time">
</el-table-column>
<el-table-column align="center" label="操作">
<template slot-scope="scope">
<el-link type="success" @click="handleLogs(scope)">工单日志</el-link>
</template>
</el-table-column>
</el-table>
<pagination
:total="total"
:page.sync="filter.page"
:limit.sync="filter.page_size"
@pagination="getList"
/>
</el-card>
<el-dialog :visible.sync="limitedFlowLogs" title="工单日志">
<el-table :data="floeLogs" fit stripe
style="width: 100%;border-top:1px solid #EBEEF5;"
height="100"
highlight-current-row
v-el-height-adaptive-table="{bottomOffset: 60}">
<el-table-column label="工单标题" min-width="100">
<template slot-scope="scope" v-if="scope.row.ticket_data">
<span>{{scope.row.ticket_data.title}}</span>
</template>
</el-table-column>
<!-- <el-table-column label="当前状态" min-width="100">
<template slot-scope="scope">
<el-tag v-if="scope.row.act_state==0" label="草稿中" value="scope.row.act_state">草稿中</el-tag>
<el-tag v-else-if="scope.row.act_state==1" label="进行中" value="scope.row.act_state">进行中</el-tag>
<el-tag v-else-if="scope.row.act_state==2" label="被退回" value="scope.row.act_state">被退回</el-tag>
<el-tag v-else-if="scope.row.act_state==3" label="被撤回" value="scope.row.act_state">被撤回</el-tag>
<el-tag v-else-if="scope.row.act_state==4" label="已完成" value="scope.row.act_state">已完成</el-tag>
<el-tag v-else-if="scope.row.act_state==5" label="已关闭" value="scope.row.act_state">已关闭</el-tag>
</template>
</el-table-column>-->
<el-table-column label="进行状态" min-width="100">
<template slot-scope="scope" v-if="scope.row.state_">
<span v-if="scope.row.state_.type==0">{{scope.row.state_.name}}</span>
<span v-else>{{scope.row.state_.name}}</span>
</template>
</el-table-column>
<el-table-column label="操作人" min-width="100">
<template slot-scope="scope" v-if="scope.row.participant_">{{ scope.row.participant_.name }}</template>
</el-table-column>
<el-table-column label="操作意见" min-width="100" prop="suggestion">
</el-table-column>
<el-table-column label="更新时间" min-width="100" prop="update_time">
</el-table-column>
</el-table>
</el-dialog>
</div>
</template>
<script>
import {getWorkflowList,getTickets,getTicketFlowlog} from "@/api/workflow";
import Pagination from "@/components/Pagination";
export default {
name: "workFlowTickets",
components: { Pagination },
inject:['reload'],
data(){
return{
sort:0,
total:0,
filter:{
page:1,
page_size:20,
state:'',
act_state:'',
workflow:'',
category:'all',
search:'',
},
listLoading:false,
limitedFlowLogs:false,
floeLogs:[],
tickets:[],
workFlows:[],
}
},
mounted(){
this.workflow = this.$route.params.workflow;
if(this.workflow){//有传参
this.filter.workflow = parseInt(this.workflow);
}
this.getList();
this.getWorkFlow();
},
methods:{
getList(){
this.listLoading = true;
getTickets( this.filter).then((res)=>{
if(res.data.results){
this.total = res.data.count;
this.tickets = res.data.results;
this.listLoading = false;
}
})
},
//获取工作流
getWorkFlow(){
let listForm = {page:0};
getWorkflowList(listForm).then((response) => {
if (response.data) {
this.workFlows = response.data;
}
});
},
//查询搜索
handleFilter(){
this.filter.page=1;
this.getList();
},
//筛选重置
resetFilter(){
this.filter.workflow = '';
this.filter.act_state = '';
this.getList();
},
handleLogs(scope){
let id = scope.row.id;
this.limitedFlowLogs = true;
getTicketFlowlog(id).then(res=>{
if(res.data){
this.floeLogs = res.data;
}
})
},
}
}
</script>
<style scoped>
</style>