Merge branch 'develop' of https://e.coding.net/ctcdevteam/hberp/hberp into develop

This commit is contained in:
shilixia 2021-09-28 14:01:37 +08:00
commit b963b53140
16 changed files with 556 additions and 122 deletions

View File

@ -27,3 +27,13 @@ export default {
} }
} }
</script> </script>
<style>
.el-step__head.is-process>.is-text{
color: #ffffff;
background: #409EFF;
border-color: #409EFF;
}
.el-step__title.is-process{
color: #409EFF;
}
</style>

View File

@ -30,6 +30,14 @@ export function getUserList(query) {
}) })
} }
export function getOrganizationList(query) {
return request({
url: '/system/organization/',
method: 'get',
params: query
})
}
export function getUser(id) { export function getUser(id) {
return request({ return request({
url: `/system/user/${id}/`, url: `/system/user/${id}/`,

View File

@ -35,6 +35,14 @@ export function getWfStateList(id) {
method: 'get' method: 'get'
}) })
} }
//工单流转step
export function getWfFlowSteps(id) {
return request({
url: `/wf/ticket/${id}/flowsteps/`,
method: 'get'
})
}
//流转状态创建 //流转状态创建
export function createWfState(data) { export function createWfState(data) {
return request({ return request({
@ -43,6 +51,15 @@ export function createWfState(data) {
data data
}) })
} }
//处理工单
export function ticketHandle(id,data) {
return request({
url: `/wf/ticket/${id}/handle/`,
method: 'post',
data
})
}
//流转状态更新 //流转状态更新
export function updateWfState(id, data) { export function updateWfState(id, data) {
return request({ return request({
@ -121,7 +138,7 @@ export function deleteWfTransition(id, data) {
data data
}) })
} }
//工单详情 //工单列表
export function getTickets(query) { export function getTickets(query) {
return request({ return request({
url: `/wf/ticket/`, url: `/wf/ticket/`,
@ -129,3 +146,17 @@ export function getTickets(query) {
params:query params:query
}) })
} }
//工单详情
export function getTicketDetail(id) {
return request({
url: `/wf/ticket/${id}/`,
method: 'get'
})
}
//工单详情
export function getTicketTransitions(id) {
return request({
url: `/wf/ticket/${id}/transitions/`,
method: 'get'
})
}

View File

@ -271,42 +271,34 @@ export const asyncRoutes = [
} }
] ]
}, },
{ {
path: '/workflow', path: '/workflow',
component: Layout, component: Layout,
redirect: '/workflow/index', redirect: '/workflow/index',
name: 'workflow', name: 'workflow',
meta: { title: '工作流管理', icon: 'example', perms: ['workflow_set'] }, meta: { title: '工作流', icon: 'example', perms: ['workflow_set'] },
children: [ children: [
{
path: 'index',
name: 'index',
component: () => import('@/views/workflow/index'),
meta: { title: '工作流配置', icon: 'example', perms: ['workflow_manage'] }
},
{ {
path: 'configuration', path: 'index',
name: 'configuration', name: 'index',
component: () => import('@/views/workflow/configuration'), component: () => import('@/views/workflow/index'),
meta: { title: '人员信息详情', icon: 'example', perms: ['configuration_manage'] }, meta: { title: '工作流配置', icon: 'example', perms: ['workflow_manage'] }
hidden: true
}, },
{ {
path: 'ticket', path: 'ticket',
name: 'ticket', name: 'ticket',
component: () => import('@/views/workflow/ticket'), component: () => import('@/views/workflow/ticket'),
meta: { title: '工单列表', icon: 'example', perms: ['ticket_manage'] }, meta: { title: '工单管理', icon: 'example', perms: ['workflow_manage'] },
hidden: true },
},{ {
path: 'test', path: 'configuration',
name: 'test', name: 'configuration',
component: () => import('@/views/workflow/test'), component: () => import('@/views/workflow/configuration'),
meta: { title: '工单', icon: 'example', perms: ['test_manage'] }, meta: { title: '人员信息详情', icon: 'example', perms: ['workflow_manage'] },
hidden: true hidden: true
}, },
] ]
}, },
{ {
path: '/system', path: '/system',
component: Layout, component: Layout,

View File

@ -148,9 +148,10 @@ export default {
hasJsonFlag:true, // json是否验证通过 hasJsonFlag:true, // json是否验证通过
hasJsonFlag1:true, // json是否验证通过 hasJsonFlag1:true, // json是否验证通过
hasJsonFlag2:true, // json是否验证通过 hasJsonFlag2:true, // json是否验证通过
customfieldList: { // customfieldList: {
count:0 // count:0
}, // },
customfieldList:[],
options: [{ options: [{
value: 'string', value: 'string',
label: '文本' label: '文本'

View File

@ -76,7 +76,7 @@
<el-form <el-form
ref="Form" ref="Form"
:model="wfstate" :model="wfstate"
label-width="80px" label-width="100px"
label-position="right" label-position="right"
:rules="rule1" :rules="rule1"
> >
@ -113,8 +113,7 @@
<el-switch v-model="wfstate.enable_retreat"></el-switch> <el-switch v-model="wfstate.enable_retreat"></el-switch>
</el-form-item> </el-form-item>
<el-form-item label="参与者类型" prop="participant_type"> <el-form-item label="参与者类型" prop="participant_type">
<el-select style="width: 100%" v-model="wfstate.participant_type" placeholder="请选择" @change="typeChange">
<el-select style="width: 100%" v-model="wfstate.participant_type" placeholder="请选择">
<el-option <el-option
v-for="item in typeoptions" v-for="item in typeoptions"
:key="item.value" :key="item.value"
@ -123,6 +122,24 @@
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </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-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-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==3">
<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>
</el-form-item>
</el-form> </el-form>
<div style="text-align: right"> <div style="text-align: right">
<el-button type="danger" @click="dialogVisible = false">取消</el-button> <el-button type="danger" @click="dialogVisible = false">取消</el-button>
@ -133,6 +150,7 @@
</template> </template>
<script> <script>
import { getWfStateList, createWfState,updateWfState,deleteWfState } from "@/api/workflow"; import { getWfStateList, createWfState,updateWfState,deleteWfState } from "@/api/workflow";
import { getOrganizationList,getUserList } from "@/api/user";
import checkPermission from "@/utils/permission"; import checkPermission from "@/utils/permission";
const defaultwfstate = { const defaultwfstate = {
name: "", name: "",
@ -143,12 +161,25 @@ export default {
props: ["ID"], props: ["ID"],
data() { data() {
return { return {
wfstate: defaultwfstate, wfstate: {
name:'',
is_hidden:'',
sort:'',
type:'',
enable_retreat:'',
participant_type:'',
participant:'',
},
participant:'',
participants:[],
is_hidden:false, is_hidden:false,
enable_retreat:false, enable_retreat:false,
wfstateList: { staffs:[],
departments:[],
/*wfstateList: {
count:0 count:0
}, },*/
wfstateList:[],
options_:{ options_:{
"0":'无处理', "0":'无处理',
"1":'个人', "1":'个人',
@ -157,8 +188,8 @@ export default {
"4":'角色', "4":'角色',
"5":'变量', "5":'变量',
"6":'普通类型', "6":'普通类型',
"5":'工单字段', "7":'工单字段',
"6":'父工单字段', "8":'父工单字段',
}, },
options: [{ options: [{
value: 0, value: 0,
@ -170,7 +201,7 @@ export default {
value: 2, value: 2,
label: '结束状态' label: '结束状态'
}], }],
typeoptions: [{ typeoptions: [{
value: 0, value: 0,
label: '无处理' label: '无处理'
}, { }, {
@ -216,6 +247,8 @@ export default {
created() { created() {
this.getList(); this.getList();
this.getUser();
this.getDepartment();
}, },
methods: { methods: {
checkPermission, checkPermission,
@ -230,9 +263,26 @@ export default {
}); });
}, },
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() { handleCreate() {
this.wfstate = Object.assign({}, defaultwfstate); this.wfstate = Object.assign({}, defaultwfstate);
this.dialogType = "new"; this.dialogType = "new";
@ -241,28 +291,31 @@ export default {
this.$refs["Form"].clearValidate(); this.$refs["Form"].clearValidate();
}); });
}, },
//打开编辑
handleEdit(scope) { handleEdit(scope) {
this.wfstate = Object.assign({}, scope.row); // copy obj this.wfstate = Object.assign({}, scope.row); // copy obj
this.participants = this.wfstate.participant;
this.participant = this.wfstate.participant;
this.dialogType = "edit"; this.dialogType = "edit";
this.dialogVisible = true; this.dialogVisible = true;
this.$nextTick(() => { this.$nextTick(() => {
this.$refs["Form"].clearValidate(); this.$refs["Form"].clearValidate();
}); });
}, },
//编辑新建
async confirm(form) { async confirm(form) {
this.$refs[form].validate((valid) => { this.$refs[form].validate((valid) => {
if (valid) { if (valid) {
const isEdit = this.dialogType === "edit"; const isEdit = this.dialogType === "edit";
// this.wfstate.participant = 1;
this.wfstate.participant = this.participant!==''?this.participant:this.participants;
if (isEdit) { if (isEdit) {
updateWfState(this.wfstate.id, this.wfstate).then((res) => { updateWfState(this.wfstate.id, this.wfstate).then((res) => {
if (res.code >= 200) { if (res.code >= 200) {
this.getList(); this.getList();
this.dialogVisible = false; this.dialogVisible = false;
this.$message.success("成功"); this.$message.success("成功");
this.getList();
} }
}); });
} else { } else {
@ -271,6 +324,7 @@ export default {
if (res.code >= 200) { if (res.code >= 200) {
this.getList(); this.getList();
this.dialogVisible = false; this.dialogVisible = false;
this.getList();
this.$message.success("成功"); this.$message.success("成功");
} }
}); });

View File

@ -1,113 +1,329 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-card style="margin-top: 10px"> <el-card style="margin-bottom: 10px">
<el-table v-loading="listLoading" :data="tickets" border fit stripe highlight-current-row max-height="600"> <div>
<el-table-column type="index" width="50" /> <el-select v-model="pageForm.workflow" placeholder="工作流" clearable style="width: 200px" class="filter-item" @change="handleFilter">
<el-table-column label="工单标题"> <el-option
<template slot-scope="scope">{{ scope.row.title }}</template> v-for="item in workflows"
</el-table-column> :key="item.id"
<el-table-column label="当前状态"> :label="item.name"
<template slot-scope="scope">{{ scope.row.act_state }}</template> :value="item.id"
</el-table-column> />
<el-table-column width="180" label="创建时间"> </el-select>
<template slot-scope="scope">{{ scope.row.create_time }}</template> <el-button
</el-table-column> class="filter-item"
<el-table-column align="center" label="操作" width="220px"> type="primary"
<template slot-scope="scope"> icon="el-icon-refresh-left"
<el-link v-if="stateSteps==scope.row.act_state" type="danger" @click="handlePicture(scope)">查看流程图</el-link> @click="resetFilter"
</template> >重置</el-button>
</el-table-column> <el-button
</el-table> class="filter-item"
<pagination type="primary"
v-show="total > 0" icon="el-icon-search"
:total="total" @click="handleFilter"
:page.sync="pageForm.page" >搜索</el-button>
:limit.sync="pageForm.page_size" </div>
@pagination="getList"
/>
</el-card> </el-card>
<el-tabs v-model="activeName" type="border-card" @tab-click="handleClick">
<el-tab-pane label="待处理" name="first">
<el-table :data="tickets" border fit stripe style="width: 100%" >
<el-table-column label="工单标题" min-width="100" prop="title">
</el-table-column>
<el-table-column label="当前状态" min-width="100">
<template slot-scope="scope">
<span v-if="scope.row.act_state===1">已提交</span>
<span v-else-if="scope.row.act_state===4">已完成</span>
<span v-else>审批中</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 v-if="stateSteps==scope.row.act_state" type="danger" @click="handlePicture(scope)">查看流程图</el-link>
<el-link v-else type="danger" @click="handleDetail(scope)">处理</el-link>
<!--<el-link type="danger" @click="handleDetail(scope)">处理</el-link>-->
</template>
</el-table-column>
</el-table>
<pagination
:total="total"
:page.sync="pageForm.page"
:limit.sync="pageForm.page_size"
@pagination="getList"
/>
</el-tab-pane>
<el-tab-pane label="已处理" name="second">
<el-table :data="tickets" border fit stripe style="width: 100%" >
<el-table-column label="工单标题" min-width="100" prop="title">
</el-table-column>
<el-table-column label="当前状态" min-width="100">
<template slot-scope="scope">
<span v-if="scope.row.act_state===1">已提交</span>
<span v-else-if="scope.row.act_state===4">已完成</span>
<span v-else>审批中</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 v-if="stateSteps==scope.row.act_state" type="danger" @click="handlePicture(scope)">查看流程图</el-link>
<el-link v-else type="danger" @click="handleDetail(scope)">处理</el-link>
</template>
</el-table-column>
</el-table>
<pagination
:total="total"
:page.sync="pageForm.page"
:limit.sync="pageForm.page_size"
@pagination="getList"
/>
</el-tab-pane>
<el-tab-pane label="已发起" name="third">
<!--<el-button type="primary" icon="el-icon-plus" @click="handleusedstepCreate"-->
<!--&gt;新增</el-button>-->
<el-table :data="tickets" border fit stripe style="width: 100%" >
<el-table-column label="工单标题" min-width="100" prop="title">
</el-table-column>
<el-table-column label="当前状态" min-width="100">
<template slot-scope="scope">
<span v-if="scope.row.act_state===1">已提交</span>
<span v-else-if="scope.row.act_state===4">已完成</span>
<span v-else>审批中</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="danger" @click="handleDetail(scope)">处理</el-link>
</template>
</el-table-column>
</el-table>
<pagination
:total="total"
:page.sync="pageForm.page"
:limit.sync="pageForm.page_size"
@pagination="getList"
/>
</el-tab-pane>
<el-tab-pane label="抄送我" name="fourth">
<el-table :data="tickets" border fit stripe style="width: 100%" >
<el-table-column label="工单标题" min-width="100" prop="title">
</el-table-column>
<el-table-column label="当前状态" min-width="100">
<template slot-scope="scope">
<span v-if="scope.row.act_state===1">已提交</span>
<span v-else-if="scope.row.act_state===4">已完成</span>
<span v-else>审批中</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 v-if="stateSteps==scope.row.act_state" type="danger" @click="handlePicture(scope)">查看流程图</el-link>
<el-link v-else type="danger" @click="handleDetail(scope)">处理</el-link>
<!--<el-link type="danger" @click="handleDetail(scope)">处理</el-link>-->
</template>
</el-table-column>
</el-table>
<pagination
:total="total"
:page.sync="pageForm.page"
:limit.sync="pageForm.page_size"
@pagination="getList"
/>
</el-tab-pane>
</el-tabs>
<div class="svgMark" v-if="dialogVisible" @click="closeMark"> <div class="svgMark" v-if="dialogVisible" @click="closeMark">
<div class="svgWrapper"> <div class="svgWrapper">
<div class="svgItem">工单流程图<i class="el-dialog__close el-icon el-icon-close" @click="closeMark"></i></div> <div class="svgItem">工单流程图<i class="el-dialog__close el-icon el-icon-close" @click="closeMark"></i></div>
<el-steps :active="actives" spac="400px" align-center="" style="padding-top: 20px;">
<el-step :title="item.name" v-for="item in flowSteps " :key="item.id">
</el-step>
</el-steps>
<svg height=600 id="svg"> <svg height=600 id="svg">
<g id="svgG"/> <g id="svgG"/>
<rect/> <rect/>
</svg> </svg>
</div> </div>
</div> </div>
<el-dialog :visible.sync="limitedStep"
title="工单流程">
<el-steps :active="actives" spac="400px" align-center="" style="padding-top: 20px;">
<el-step :title="item.name" v-for="item in flowSteps "
:key="item.id" @click.native=stepclick(item.id)>
</el-step>
</el-steps>
<el-row>
<el-col :span="1" style="height: 1px;"></el-col>
<el-col :span="11">
<div class="listItem"><span>流水号</span>{{ticketDetail.sn}}</div>
<div class="listItem"><span>开始时间</span>{{}}</div>
<div class="listItem" v-if="ticketDetail.workflow_"><span>请假类型</span>{{ticketDetail.workflow_.name}}</div>
<div class="listItem"><span>创建人</span>{{}}</div>
<div class="listItem" v-if="ticketDetail.workflow_"><span>请假原因</span>{{ticketDetail.workflow_.name}}</div>
</el-col>
<el-col :span="11">
<div class="listItem"><span>标题</span>{{ticketDetail.title}}</div>
<div class="listItem"><span>结束时间</span>{{}}</div>
<div class="listItem"><span>创建时间</span>{{ticketDetail.create_time}}</div>
<div class="listItem" v-if="ticketDetail.ticket_data"><span>请假天数</span>{{ticketDetail.ticket_data.days}}</div>
</el-col>
</el-row>
<div style="text-align: center">
<el-button v-for="item in operationBtn" :key="item.id" class="filter-item" type="primary" @click="operationSubmit">{{item.name}}</el-button>
</div>
</el-dialog>
</div> </div>
</template> </template>
<script src="https://d3js.org/d3.v4.min.js"></script> <script src="https://d3js.org/d3.v4.min.js"></script>
<script> <script>
import {getWfStateList,getTickets } from "@/api/workflow"; import {getWorkflowList,getWfStateList,getTickets,ticketHandle,getWfFlowSteps,getTicketDetail,getTicketTransitions } from "@/api/workflow";
import Pagination from "@/components/Pagination"; import Pagination from "@/components/Pagination";
import dagreD3 from 'dagre-d3' import dagreD3 from 'dagre-d3'
import * as d3 from 'd3' import * as d3 from 'd3'
export default { export default {
name: "ticket", name: "ticket",
components: { Pagination }, components: { Pagination },
inject:['reload'],
data(){ data(){
return{ return{
step:4,
total:0, total:0,
actives:4,
ticketId:0,
pageForm:{ pageForm:{
page:1, page:1,
page_size:20, page_size:20,
workflow:0, workflow:'',
}, },
workflow:0,
stateSteps:0, stateSteps:0,
activeName:'first',
keyword:'', keyword:'',
workflow:'',
tickets:[], tickets:[],
workflows:[],
ticketDetail:{},
dialogVisible:false, dialogVisible:false,
listLoading:false, listLoading:false,
limitedStep:false,
nodes: [], nodes: [],
tooltip:null, tooltip:null,
edges: [] edges: [],
flowSteps:[],
operationBtn:[],
} }
}, },
created(){ mounted(){
this.workflow = this.$route.params.workflow;
let workflow = localStorage.getItem('workflow');
if(this.workflow){//有传参
this.pageForm.workflow = parseInt(this.workflow);
if(workflow){
localStorage.removeItem('workflow');
localStorage.setItem('workflow',this.pageForm.workflow)
}else{
localStorage.setItem('workflow',this.pageForm.workflow)
}
}else {//无传参
if (workflow) {
this.workflow = workflow;
this.pageForm.workflow = workflow;
} else {
}
}
this.getList();
this.getStates();
this.getWorkFlow();
},
activated(){
this.workflow = this.$route.params.workflow; this.workflow = this.$route.params.workflow;
let workflow = localStorage.getItem('workflow'); let workflow = localStorage.getItem('workflow');
if(this.workflow){ if(this.workflow){//有传参
this.pageForm.workflow = parseInt(this.workflow); this.pageForm.workflow = parseInt(this.workflow);
if(workflow){ if(workflow){
localStorage.removeItem('workflow'); localStorage.removeItem('workflow');
localStorage.setItem('workflow',this.$route.params.workflow) localStorage.setItem('workflow',this.pageForm.workflow)
}else{ }else{
localStorage.setItem('workflow',this.$route.params.workflow) localStorage.setItem('workflow',this.pageForm.workflow)
} }
}else{ }else{//无传参
this.workflow =workflow ; if(workflow){
this.pageForm.workflow =workflow ; this.workflow =workflow ;
this.pageForm.workflow =workflow ;
}else{}
} }
debugger;
this.getList(); this.getList();
this.getStates(); this.getStates();
}, },
methods:{ methods:{
getList(){ getList(){
this.listLoading = true;
getTickets( this.pageForm).then((res)=>{ getTickets( this.pageForm).then((res)=>{
if(res.data.results){ if(res.data.results){
this.total = res.data.count;
this.tickets = res.data.results; this.tickets = res.data.results;
this.listLoading = false;
} }
}) })
}, },
handleClick(tab, event) {
console.log(tab, event);
debugger;
//pagepageSizetotaltickets都要发生变化
let paneName = tab.paneName;
this.activeName = paneName;
if(paneName=='first'){
}else if(paneName=='second'){
}else if(paneName=='third'){
}else if(paneName=='fourth'){
}
},
getStates(){ getStates(){
getWfStateList(this.workflow).then((response) => { if(this.pageForm.workflow!==''){
if (response.data) { getWfStateList(this.pageForm.workflow).then((response) => {
let nodes = []; if (response.data) {
let res = response.data; let nodes = [];
this.stateSteps = res.length; let res = response.data;
for(let i=0;i<res.length;i++){ this.stateSteps = res.length;
let obj = new Object(); for(let i=0;i<res.length;i++){
obj.id = res[i].id; let obj = new Object();
obj.label = res[i].name; obj.id = res[i].id;
obj.shape = res[i].type===0? 'diamond':'rect'; obj.label = res[i].name;
nodes.push(obj) obj.shape = res[i].type===0? 'diamond':'rect';
nodes.push(obj)
}
this.nodes = nodes;
this.getEdges(nodes);
} }
this.nodes = nodes; });
console.log(nodes) }
this.getEdges(nodes); },
getWorkFlow(){
let listForm = {page:0};
getWorkflowList(listForm).then((response) => {
if (response.data) {
this.workflows = response.data;
} }
}); });
}, },
@ -121,10 +337,40 @@
edge.push(obj); edge.push(obj);
} }
this.edges = edge; this.edges = edge;
console.log(edge)
}, },
handleFilter(){}, handleFilter(){
handlePicture(){ this.getList();
this.getStates();
},
resetFilter(){
this.pageForm.workflow = '',
this.getList();
},
handlePicture(scope){
let that = this;
getWfFlowSteps( scope.row.id).then((res)=>{
if(res.data){
that.flowSteps = res.data;
getTicketDetail( ticketId).then((res)=>{
if(res.data){
that.ticketDetail = res.data;
let state = res.data.state;
debugger;
console.log(state)
console.log(that.flowSteps)
debugger;
let dat = that.flowSteps.filter((item)=>{
return item.id==state;
})
console.log(dat)
console.log(that.flowSteps.indexOf(dat[0]))
debugger;
this.actives = that.flowSteps.indexOf(dat[0]);
that.limitedStep = true;
}
});
}
});
// this.$router.push({name:"test"}) // this.$router.push({name:"test"})
this.dialogVisible = true; this.dialogVisible = true;
//获取D3 //获取D3
@ -137,7 +383,6 @@
marginx: 50, marginx: 50,
marginy: 50, marginy: 50,
}); });
console.log(g);
// 添加节点 // 添加节点
this.nodes.forEach((item) => { this.nodes.forEach((item) => {
g.setNode(item.id, { g.setNode(item.id, {
@ -181,13 +426,53 @@
}) })
}, },
handleDetail(scope){
// this.limitedStep = true;
let that = this;
that.ticketId = scope.row.id;
let ticketId = scope.row.id;
getWfFlowSteps( scope.row.id).then((res)=>{
if(res.data){
that.flowSteps = res.data;
getTicketDetail( ticketId).then((res)=>{
if(res.data){
that.ticketDetail = res.data;
let state = res.data.state;
debugger;
console.log(state)
console.log(that.flowSteps)
debugger;
let dat = that.flowSteps.filter((item)=>{
return item.id==state;
})
console.log(dat)
console.log(that.flowSteps.indexOf(dat[0]))
debugger;
this.actives = that.flowSteps.indexOf(dat[0]);
that.limitedStep = true;
}
});
}
});
getTicketTransitions(scope.row.id).then(res=>{
this.operationBtn = res.data;
})
},
operationSubmit(){
let transition = {transition:this.operationBtn[0].id,ticket_data:this.ticketDetail.ticket_data};
ticketHandle(this.ticketId,transition).then(res=>{
if (res.data){
this.limitedStep = false;
}
})
},
stepclick(){},
closeMark(){ closeMark(){
this.dialogVisible = false; this.dialogVisible = false;
},
},
mounted() {
} }
} }
}
</script> </script>
<style scoped> <style scoped>
@ -221,12 +506,10 @@
svg { svg {
font-size: 14px; font-size: 14px;
} }
.node rect { .node rect {
stroke: #606266; stroke: #606266;
fill: #fff; fill: #fff;
} }
.edgePath path { .edgePath path {
stroke: #606266; stroke: #606266;
fill: #333; fill: #333;
@ -235,4 +518,14 @@
.el-icon-close{ .el-icon-close{
cursor: pointer; cursor: pointer;
} }
.listItem{
margin-top: 15px;
font-size: 16px;
}
.listItem>span{
width: 100px;
text-align: right;
margin-right: 10px;
display: inline-block;
}
</style> </style>

View File

@ -23,7 +23,7 @@
</el-table-column> </el-table-column>
<el-table-column width="180" label="源状态"> <el-table-column width="180" label="源状态">
<template slot-scope="scope"> <template>
<span v-for="item in stateoptions" <span v-for="item in stateoptions"
:key="item.value" :key="item.value"
:label="item.label" :label="item.label"
@ -97,7 +97,7 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="条件表达式" prop="condition_expression"> <el-form-item label="条件表达式" prop="condition_expression">
<el-input v-model="wftransition.condition_expression" placeholder="[]" /> <el-input v-model="wftransition.condition_expression"/>
</el-form-item> </el-form-item>
<el-form-item label="属性类型" prop="attribute_type"> <el-form-item label="属性类型" prop="attribute_type">
@ -139,9 +139,11 @@ export default {
return { return {
wftransition: defaultwftransition, wftransition: defaultwftransition,
condition_expression:false, condition_expression:false,
wftransitionList: { /*wftransitionList: {
count:0 count:0
}, },*/
wftransitionList:[],
lable:'',
options_:[], options_:[],
options: [{ options: [{
value: 1, value: 1,

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<project ver="10" name="daq" libEmbed="true" icon="" ui="win" output="数据采集.exe" CompanyName="中存大数据" FileDescription="daq" LegalCopyright="Copyright (C) 作者 2021" ProductName="daq" InternalName="daq" FileVersion="0.0.0.08" ProductVersion="0.0.0.08" publishDir="/dist/" dstrip="false"> <project ver="10" name="daq" libEmbed="true" icon="" ui="win" output="数据采集.exe" CompanyName="中存大数据" FileDescription="daq" LegalCopyright="Copyright (C) 作者 2021" ProductName="daq" InternalName="daq" FileVersion="0.0.0.10" ProductVersion="0.0.0.10" publishDir="/dist/" dstrip="false">
<file name="main.aardio" path="main.aardio" comment="main.aardio"/> <file name="main.aardio" path="main.aardio" comment="main.aardio"/>
<folder name="资源文件" path="res" embed="true" local="false" ignored="false"/> <folder name="资源文件" path="res" embed="true" local="false" ignored="false"/>
<folder name="窗体文件" path="dlg" comment="目录" embed="true" local="false" ignored="false"> <folder name="窗体文件" path="dlg" comment="目录" embed="true" local="false" ignored="false">

View File

@ -76,6 +76,7 @@ if(!atom){
mainForm.onMinimize = function(lParam){ mainForm.onMinimize = function(lParam){
var tray = win.util.tray(mainForm) //创建托盘图标 var tray = win.util.tray(mainForm) //创建托盘图标
tray.tip = "数据采集"; tray.tip = "数据采集";
tray.pop("数据采集已最小化运行" )
mainForm.show(false); //隐藏窗口 mainForm.show(false); //隐藏窗口
return true;//阻击默认消息传递,取消最小化过程 return true;//阻击默认消息传递,取消最小化过程
} }
@ -159,7 +160,7 @@ http.beginRequest( mainForm.serverUrl.text + "/api/em/daq/", "POST" );
var res = web.json.parse(html) var res = web.json.parse(html)
if(res['code']==200){ if(res['code']==200){
import fsys import fsys
var theDir = fsys.createDir(mainForm.backupPath.text+"\"+number, false) var theDir = fsys.createDir(mainForm.backupPath.text+"\\"+number, false)
fsys.move(fullpath, theDir) //移动到备份文件库 fsys.move(fullpath, theDir) //移动到备份文件库
mainForm.listbox.add("采集成功!") mainForm.listbox.add("采集成功!")
}else{ }else{
@ -195,7 +196,7 @@ mainForm.listview.onnotify = function(id,code,ptr){
mainForm.add.oncommand = function(id,event){ mainForm.add.oncommand = function(id,event){
var frmChild = mainForm.loadForm("\dlg\add.aardio"); var frmChild = mainForm.loadForm("\\dlg\\add.aardio");
frmChild.doModal(); frmChild.doModal();
} }

View File

@ -0,0 +1,34 @@
# Generated by Django 3.2.6 on 2021-09-28 05:55
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('mtm', '0016_auto_20210917_0900'),
]
operations = [
migrations.AddField(
model_name='recordform',
name='material',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='mtm.material', verbose_name='关联物料'),
),
migrations.AlterField(
model_name='material',
name='processes',
field=models.JSONField(blank=True, default=list, null=True, verbose_name='工艺流程'),
),
migrations.AlterField(
model_name='recordform',
name='step',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='mtm.step', verbose_name='关联子工序'),
),
migrations.AlterField(
model_name='recordform',
name='type',
field=models.IntegerField(choices=[(1, '生产记录'), (2, '检验记录')], default=1, verbose_name='表格类型'),
),
]

View File

@ -29,7 +29,7 @@ class Material(CommonAModel):
specification = models.CharField('型号', max_length=100, null=True, blank=True) specification = models.CharField('型号', max_length=100, null=True, blank=True)
type = models.CharField('物料类型', choices= type_choices, max_length=20, default=1) type = models.CharField('物料类型', choices= type_choices, max_length=20, default=1)
sort_str = models.CharField('排序字符', max_length=100, null=True, blank=True) sort_str = models.CharField('排序字符', max_length=100, null=True, blank=True)
processes = models.JSONField('工艺流程', default=list, blank=True) processes = models.JSONField('工艺流程', default=list, blank=True, null=True)
unit = models.CharField('基准计量单位', choices=unit_choices, default='', max_length=10) unit = models.CharField('基准计量单位', choices=unit_choices, default='', max_length=10)
class Meta: class Meta:
@ -80,11 +80,12 @@ class RecordForm(CommonAModel):
""" """
type_choices=( type_choices=(
(1, '生产记录'), (1, '生产记录'),
(2, '检验记录')
) )
name = models.CharField('表格名称', max_length=100, unique=True) name = models.CharField('表格名称', max_length=100, unique=True)
type = models.IntegerField('表格类型', choices=type_choices, default=1) type = models.IntegerField('表格类型', choices=type_choices, default=1)
step = models.ForeignKey(Step, verbose_name='关联子工序', on_delete=models.CASCADE) step = models.ForeignKey(Step, verbose_name='关联子工序', on_delete=models.CASCADE, null=True, blank=True)
material = models.ForeignKey(Material, verbose_name='关联物料', on_delete=models.CASCADE, null=True, blank=True)
class Meta: class Meta:
verbose_name = '记录表格' verbose_name = '记录表格'
verbose_name_plural = verbose_name verbose_name_plural = verbose_name
@ -194,3 +195,4 @@ class TechDoc(CommonAModel):
class Meta: class Meta:
verbose_name = '技术文件' verbose_name = '技术文件'
verbose_name_plural = verbose_name verbose_name_plural = verbose_name

View File

@ -147,7 +147,7 @@ class RecordFormViewSet(OptimizationMixin, CreateUpdateModelAMixin, ModelViewSet
""" """
perms_map = {'*':'*'} perms_map = {'*':'*'}
queryset = RecordForm.objects.all() queryset = RecordForm.objects.all()
filterset_fields = ['step', 'type'] filterset_fields = ['step', 'type', 'material']
search_fields = ['name'] search_fields = ['name']
def get_serializer_class(self): def get_serializer_class(self):

View File

@ -78,4 +78,8 @@ class TicketFlowSerializer(serializers.ModelSerializer):
model = TicketFlow model = TicketFlow
fields = '__all__' fields = '__all__'
class TicketHandleSerializer(serializers.Serializer):
transition = serializers.IntegerField(label="流转id")
ticket_data = serializers.JSONField(label="表单数据json")
suggestion = serializers.CharField(label="处理意见", required = False)

View File

@ -167,7 +167,7 @@ class WfService(object):
elif participant_type in [State.PARTICIPANT_TYPE_MULTI, State.PARTICIPANT_TYPE_DEPT, State.PARTICIPANT_TYPE_ROLE]: elif participant_type in [State.PARTICIPANT_TYPE_MULTI, State.PARTICIPANT_TYPE_DEPT, State.PARTICIPANT_TYPE_ROLE]:
if user.id not in participant: if user.id not in participant:
return dict(permission=False, msg="非当前处理人") return dict(permission=False, msg="非当前处理人")
current_participant_count = len(participant.split(',')) current_participant_count = len(participant)
if current_participant_count >1 and state.distribute_type == State.STATE_DISTRIBUTE_TYPE_ACTIVE: if current_participant_count >1 and state.distribute_type == State.STATE_DISTRIBUTE_TYPE_ACTIVE:
return dict(permission=False, msg="需要先接单再处理") return dict(permission=False, msg="需要先接单再处理")
if ticket.in_add_node: if ticket.in_add_node:

View File

@ -2,7 +2,7 @@ from django.core.exceptions import AppRegistryNotReady
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework import serializers from rest_framework import serializers
from rest_framework.mixins import CreateModelMixin, DestroyModelMixin, ListModelMixin, RetrieveModelMixin, UpdateModelMixin from rest_framework.mixins import CreateModelMixin, DestroyModelMixin, ListModelMixin, RetrieveModelMixin, UpdateModelMixin
from apps.wf.serializers import CustomFieldSerializer, StateSerializer, TicketCreateSerializer, TicketFlowSerializer, TicketSerializer, TransitionSerializer, WorkflowSerializer from apps.wf.serializers import CustomFieldSerializer, StateSerializer, TicketCreateSerializer, TicketFlowSerializer, TicketHandleSerializer, TicketSerializer, TransitionSerializer, WorkflowSerializer
from django.shortcuts import get_object_or_404, render from django.shortcuts import get_object_or_404, render
from rest_framework.viewsets import GenericViewSet, ModelViewSet from rest_framework.viewsets import GenericViewSet, ModelViewSet
from rest_framework.decorators import action, api_view from rest_framework.decorators import action, api_view
@ -99,6 +99,8 @@ class TicketViewSet(OptimizationMixin, CreateUpdateCustomMixin, CreateModelMixin
def get_serializer_class(self): def get_serializer_class(self):
if self.action == 'create': if self.action == 'create':
return TicketCreateSerializer return TicketCreateSerializer
elif self.action == 'handle':
return TicketHandleSerializer
return super().get_serializer_class() return super().get_serializer_class()
def create(self, request, *args, **kwargs): def create(self, request, *args, **kwargs):