..
This commit is contained in:
@@ -22,16 +22,13 @@ layout("/layouts/platform.html"){
|
||||
</el-card>
|
||||
|
||||
<el-card shadow="never">
|
||||
<table-tool>
|
||||
</table-tool>
|
||||
<table-tool></table-tool>
|
||||
<el-table :data="tableData" @sort-change="pageOrder" style="width: 100%">
|
||||
<el-table-column type="index" width="50px" label="序号" :index="indexMethod"></el-table-column>
|
||||
<el-table-column prop="displayName" label="流程定义名称"></el-table-column>
|
||||
<el-table-column prop="name" label="流程定义编码"></el-table-column>
|
||||
<el-table-column prop="categoryName" label="流程分类">
|
||||
<template slot-scope="{row}">{{categoryOptions.find(item => item.id ===
|
||||
row.category)?.categoryName}}
|
||||
</template>
|
||||
<template slot-scope="{row}">{{categoryOptions.find(item => item.id === row.category)?.categoryName}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="version" label="版本号"></el-table-column>
|
||||
<el-table-column prop="state" label="状态">
|
||||
@@ -44,12 +41,9 @@ layout("/layouts/platform.html"){
|
||||
<el-table-column label="操作" fixed="right" width="350px">
|
||||
<template slot-scope="{row}">
|
||||
<el-button type="primary" size="mini" @click="onView(row)">查看</el-button>
|
||||
<el-button v-if="row.state===1" type="danger" size="mini" @click="onDisable(row)">停用
|
||||
</el-button>
|
||||
<el-button v-if="row.state===0" type="primary" size="mini" @click="onEnable(row)">启用
|
||||
</el-button>
|
||||
<el-button v-if="row.state===0" type="danger" size="mini" @click="onDelete(row)">删除
|
||||
</el-button>
|
||||
<el-button v-if="row.state===1" type="danger" size="mini" @click="onDisable(row)">停用</el-button>
|
||||
<el-button v-if="row.state===0" type="primary" size="mini" @click="onEnable(row)">启用</el-button>
|
||||
<el-button v-if="row.state===0" type="danger" size="mini" @click="onDelete(row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -59,11 +53,9 @@ layout("/layouts/platform.html"){
|
||||
|
||||
<el-dialog title="查看流程图" :visible.sync="designVisible" class="design-dialog" width="80%">
|
||||
<div style="height: calc(100vh - 150px); width: 100%">
|
||||
<iframe v-if="designVisible" :src="designUrl" frameborder="0" height="100%"
|
||||
style="height: 100%; width: inherit"></iframe>
|
||||
<iframe v-if="designVisible" :src="designUrl" frameborder="0" height="100%" style="height: 100%; width: inherit"></iframe>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
@@ -80,7 +72,7 @@ layout("/layouts/platform.html"){
|
||||
methods: {
|
||||
onView(row) {
|
||||
this.designVisible = true
|
||||
this.designUrl = "/flow/define/preview?id=" + row.id
|
||||
this.designUrl = "/flow/define/preview?defineId=" + row.id
|
||||
},
|
||||
|
||||
onDisable(row) {
|
||||
@@ -89,7 +81,7 @@ layout("/layouts/platform.html"){
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(() => {
|
||||
this.$axios.post("/flow/define/disable", { id: row.id }).then(res => {
|
||||
this.$axios.post("/flow/define/disable", { id: row.id }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$message.success("停用成功")
|
||||
this.pageData()
|
||||
@@ -103,7 +95,7 @@ layout("/layouts/platform.html"){
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(() => {
|
||||
this.$axios.post("/flow/define/enable", { id: row.id }).then(res => {
|
||||
this.$axios.post("/flow/define/enable", { id: row.id }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$message.success("启用成功")
|
||||
this.pageData()
|
||||
|
||||
@@ -1,66 +1,348 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
|
||||
<title>流程设计器</title>
|
||||
<script src="/assets/platform/plugins/vue/vue.js"></script>
|
||||
<script src="/assets/platform/plugins/jquery/jquery.js"></script>
|
||||
<script src="/assets/platform/plugins/element-ui/lib/index.js"></script>
|
||||
<link rel="stylesheet" href="https://cdn.staticfile.net/element-ui/2.15.14/theme-chalk/index.css" />
|
||||
<link rel="stylesheet" href="${base!}/assets/platform/plugins/element-ui/lib/theme-chalk/index.css" />
|
||||
<link rel="stylesheet" href="${base!}/assets/platform/plugins/element-ui/lib/theme-chalk/override.css" />
|
||||
<!-- 引入 core 包和对应 css-->
|
||||
<script src="https://cdn.jsdelivr.net/npm/@logicflow/core@1.2.12/dist/logic-flow.js"></script>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@logicflow/core@1.2.12/dist/style/index.css" />
|
||||
<script src="/assets/platform/plugins/snaker/SnakerflowDesigner.umd.js"></script>
|
||||
<style>
|
||||
#app {
|
||||
height: 100vh;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
<snaker-flow-designer ref="designer"
|
||||
v-model="flowData"
|
||||
:show-doc="false"
|
||||
:viewer="true"
|
||||
node-render-type="html"
|
||||
:wf-config="{
|
||||
showHelp: false,
|
||||
}"
|
||||
:config="{
|
||||
grid:{ size: 25,visible: true,type: 'dot',config:{color: '#ababab',thickness: 1}}
|
||||
}"
|
||||
></snaker-flow-designer>
|
||||
</div>
|
||||
</body>
|
||||
<script>
|
||||
Vue.use(SnakerflowDesigner.default)
|
||||
new Vue({
|
||||
el: "#app",
|
||||
data() {
|
||||
return {
|
||||
id: "${id!}",
|
||||
flowData: {}
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
|
||||
<title>流程设计器</title>
|
||||
<script src="/assets/platform/plugins/vue/vue.js"></script>
|
||||
<script src="/assets/platform/plugins/jquery/jquery.js"></script>
|
||||
<script src="/assets/platform/plugins/element-ui/lib/index.js"></script>
|
||||
<link rel="stylesheet" href="https://cdn.staticfile.net/element-ui/2.15.14/theme-chalk/index.css" />
|
||||
<link rel="stylesheet" href="${base!}/assets/platform/plugins/element-ui/lib/theme-chalk/index.css" />
|
||||
<link rel="stylesheet" href="${base!}/assets/platform/plugins/element-ui/lib/theme-chalk/override.css" />
|
||||
<!-- 引入 core 包和对应 css-->
|
||||
<script src="https://cdn.jsdelivr.net/npm/@logicflow/core@1.2.12/dist/logic-flow.js"></script>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@logicflow/core@1.2.12/dist/style/index.css" />
|
||||
<script src="/assets/platform/plugins/snaker/SnakerflowDesigner.umd.js"></script>
|
||||
<style>
|
||||
#snaker-flow-preview {
|
||||
height: 100vh;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getDetail() {
|
||||
$.get("/flow/define/detail", { id: this.id }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.flowData = res.data.content
|
||||
|
||||
.approval-card {
|
||||
position: absolute;
|
||||
width: 320px;
|
||||
background: #ffffff;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #d9e3f0;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
|
||||
z-index: 1000;
|
||||
font-family: "Microsoft YaHei", "PingFang SC", sans-serif;
|
||||
transform: translate(10px, 10px);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.tab-container {
|
||||
border-bottom: 1px solid #e8e8e8;
|
||||
}
|
||||
|
||||
.tab-header {
|
||||
display: flex;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.tab-item {
|
||||
padding: 8px 16px;
|
||||
cursor: pointer;
|
||||
border-right: 1px solid #e8e8e8;
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
background: #fafafa;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.tab-item:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.tab-item.active {
|
||||
background: #fff;
|
||||
color: #333;
|
||||
border-bottom: 2px solid #1890ff;
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
|
||||
.tab-item:hover {
|
||||
background: #f0f0f0;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
/* 卡片标题栏(OA风格顶部色条) */
|
||||
.approval-card .card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 12px 16px;
|
||||
background: #1a73e8;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.approval-card .card-header h3 {
|
||||
margin: 0;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.approval-card .card-header button {
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
border: none;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 50%;
|
||||
color: white;
|
||||
font-size: 16px;
|
||||
line-height: 1;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.approval-card .card-header button:hover {
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
/* 卡片内容区域 */
|
||||
.approval-card .card-body {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
/* 信息行样式 */
|
||||
.approval-card .info-row {
|
||||
display: flex;
|
||||
margin-bottom: 12px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.approval-card .info-label {
|
||||
width: 80px;
|
||||
color: #666;
|
||||
font-size: 13px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.approval-card .info-value {
|
||||
flex: 1;
|
||||
color: #333;
|
||||
font-size: 13px;
|
||||
line-height: 1.5;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
/*!* 分隔线 *!*/
|
||||
/*.approval-card .divider {*/
|
||||
/* height: 1px;*/
|
||||
/* background: #f0f0f0;*/
|
||||
/* margin: 12px 0;*/
|
||||
/*}*/
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="snaker-flow-preview">
|
||||
<snaker-flow-designer
|
||||
ref="designer"
|
||||
v-model="flowData"
|
||||
:show-doc="false"
|
||||
:viewer="true"
|
||||
node-render-type="html"
|
||||
:high-light="highLight"
|
||||
></snaker-flow-designer>
|
||||
|
||||
<div
|
||||
v-if="showApprovalCard"
|
||||
class="approval-card"
|
||||
:style="{
|
||||
left: cardPosition.x+'px',
|
||||
top: cardPosition.y+'px'
|
||||
}"
|
||||
>
|
||||
<div class="card-header">
|
||||
<h3>详情</h3>
|
||||
<button @click="closeCard">×</button>
|
||||
</div>
|
||||
<!-- Tab切换 -->
|
||||
<div class="tab-container" v-if="approvalInfos.length > 1">
|
||||
<div class="tab-header">
|
||||
<div
|
||||
v-for="(item, index) in approvalInfos"
|
||||
:key="index"
|
||||
class="tab-item"
|
||||
:class="{active: activeTabIndex === index}"
|
||||
@click="activeTabIndex = index"
|
||||
>
|
||||
记录{{index + 1}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<div v-for="(approvalInfo, index) in approvalInfos" :key="index" v-show="activeTabIndex === index">
|
||||
<div class="info-row">
|
||||
<span class="info-label">节点类型:</span>
|
||||
<span class="info-value">{{approvalInfo.displayName}}</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">审批人:</span>
|
||||
<span class="info-value" v-if="currentNode.id === 'startTask'">
|
||||
{{approvalInfo.ext?.initiatorName}}({{approvalInfo.ext?.initiatorAccount}})
|
||||
</span>
|
||||
<span class="info-value" v-else>{{approvalInfo.taskFormData.userName}}({{approvalInfo.taskFormData?.loginName}})</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">审核状态:</span>
|
||||
<span class="info-value">{{getTaskStateText(approvalInfo.taskState)}}</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">提交结果:</span>
|
||||
<span class="info-value">{{getSubmitTypeText(approvalInfo.ext.submitType)}}</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">提交意见:</span>
|
||||
<span class="info-value">{{approvalInfo.taskFormData.opinion}}</span>
|
||||
</div>
|
||||
<!-- <div class="divider"></div>-->
|
||||
<div class="info-row">
|
||||
<span class="info-label">提交时间:</span>
|
||||
<span class="info-value">{{approvalInfo.finishTime}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script>
|
||||
Vue.use(SnakerflowDesigner.default)
|
||||
new Vue({
|
||||
el: "#snaker-flow-preview",
|
||||
data() {
|
||||
return {
|
||||
// 流程定义ID
|
||||
defineId: "${defineId!}",
|
||||
// 流程实例ID
|
||||
instanceId: "${instanceId!}",
|
||||
// 流程定义数据
|
||||
flowData: {},
|
||||
// 高亮数据
|
||||
highLight: {},
|
||||
// 历史审批记录
|
||||
hisApproval: [],
|
||||
// 展示已审核信息
|
||||
showApprovalCard: false,
|
||||
// 审批信息卡片位置
|
||||
cardPosition: { x: 0, y: 0 },
|
||||
// 当前节点
|
||||
currentNode: [],
|
||||
// 审批信息数组
|
||||
approvalInfos: [],
|
||||
// 当前选中的tab索引
|
||||
activeTabIndex: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// approvalInfo() {
|
||||
// if (this.currentNode) {
|
||||
// return this.hisApproval.find((item) => item.taskName === this.currentNode.id)
|
||||
// }
|
||||
// }
|
||||
},
|
||||
methods: {
|
||||
getDetail() {
|
||||
$.get("/flow/define/detail", { id: this.defineId }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.flowData = res.data.content
|
||||
this.initNodeEvent()
|
||||
}
|
||||
})
|
||||
},
|
||||
getHighLight() {
|
||||
$.get("/flow/common/instanceHighLight", { instanceId: this.instanceId }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.highLight = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
getHisApproval() {
|
||||
$.get("/flow/common/approvalRecord", { instanceId: this.instanceId }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.hisApproval = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
initNodeEvent() {
|
||||
this.$nextTick(() => {
|
||||
console.log(this.$refs.designer.lf.graphModel.eventCenter)
|
||||
this.$refs.designer.lf.graphModel.eventCenter.on("node:click", ({ e, data }) => {
|
||||
console.log(data)
|
||||
console.log(e)
|
||||
|
||||
// 获取点击位置(考虑页面滚动情况)
|
||||
const scrollX = window.scrollX || window.pageXOffset
|
||||
const scrollY = window.scrollY || window.pageYOffset
|
||||
|
||||
this.cardPosition = {
|
||||
x: e.clientX + scrollX,
|
||||
y: e.clientY + scrollY
|
||||
}
|
||||
|
||||
if (data.type !== "snaker:task") return
|
||||
|
||||
const approvalInfos = this.hisApproval.filter((item) => item.taskName === data.id && item.taskState === 20)
|
||||
|
||||
if (approvalInfos && approvalInfos.length > 0) {
|
||||
this.approvalInfos = approvalInfos
|
||||
this.currentNode = data
|
||||
this.activeTabIndex = 0
|
||||
this.showApprovalCard = true
|
||||
}
|
||||
})
|
||||
|
||||
this.$refs.designer.lf.graphModel.eventCenter.on("blank:click", (args) => {
|
||||
this.closeCard()
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
closeCard() {
|
||||
this.showApprovalCard = false
|
||||
this.activeTabIndex = 0
|
||||
},
|
||||
|
||||
// 获取任务状态文本
|
||||
getTaskStateText(taskState) {
|
||||
const stateMap = {
|
||||
10: "进行中",
|
||||
20: "已完成",
|
||||
30: "已撤回"
|
||||
}
|
||||
})
|
||||
return stateMap[taskState] || taskState
|
||||
},
|
||||
|
||||
// 获取提交结果文本
|
||||
getSubmitTypeText(submitType) {
|
||||
const typeMap = {
|
||||
0: "发起申请",
|
||||
1: "同意申请",
|
||||
2: "拒绝申请",
|
||||
3: "退回上一步",
|
||||
4: "跳转",
|
||||
5: "重新提交",
|
||||
6: "退回发起人",
|
||||
20: "拒绝申请"
|
||||
}
|
||||
return typeMap[submitType] || submitType
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.defineId) {
|
||||
this.getDetail()
|
||||
}
|
||||
if (this.instanceId) {
|
||||
this.getHighLight()
|
||||
this.getHisApproval()
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.id) {
|
||||
this.getDetail()
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
})
|
||||
</script>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user