提交 96778066 authored 作者: kxjia's avatar kxjia

问题工作流

上级 4c79503d
......@@ -162,6 +162,12 @@ export function assign(data) {
data: data
})
}
export function todoListAll() {
return defHttp.get({
url: '/flowable/task/todoListAll'
})
}
......
......@@ -139,15 +139,16 @@
},
})
} else {
// await rejectTask({
// instanceId: myTaskFlow.procInsId || '',
// deployId: myTaskFlow.deployId || '',
// taskId: myTaskFlow.taskId,
// comment: formDataTmp.comment,
// values: {
// rejectNode: props.beforeFlowNode,
// },
// })
await rejectTask({
instanceId: myTaskFlow.procInsId || '',
deployId: myTaskFlow.deployId || '',
taskId: myTaskFlow.taskId,
comment: formDataTmp.comment,
values: {
rejectNode: props.beforeFlowNode,
},
})
alert(3333)
emit('approval-fail', props.dataId)
}
}
......
<template>
<div>
<div style="margin-bottom: 16px; display: flex; justify-content: flex-end;">
<a-upload
:before-upload="handleBeforeUpload"
:show-upload-list="false"
accept=".xml"
>
<a-button type="primary">
<UploadOutlined />
上传XML文件
</a-button>
</a-upload>
</div>
<bpmn-model
:xml="xml"
:is-view="false"
......@@ -31,6 +43,8 @@
import { ref, onMounted, computed } from 'vue'
import { readXml, saveXml } from "/@/components/Process/api/definition"
import BpmnModel from '/@/components/Process/index.vue'
import { message, Modal } from 'ant-design-vue'
import { UploadOutlined } from '@ant-design/icons-vue'
import * as vkbeautify from 'vkbeautify'
import hljs from 'highlight.js'
......@@ -38,7 +52,6 @@ import { useRouter, useRoute } from 'vue-router'
import "highlight.js/styles/atom-one-dark.css"
const router = useRouter()
const route = useRoute()
......@@ -62,6 +75,7 @@ const xml = ref<string>('')
const xmlOpen = ref<boolean>(false)
const xmlTitle = ref<string>('')
const xmlData = ref<string>('')
const originalXml = ref<string>('') // 保存原始XML,用于判断是否需要提示保存
// 计算属性,用于高亮显示的XML
const highlightedXml = computed(() => {
......@@ -73,11 +87,75 @@ const highlightedXml = computed(() => {
const getXmlData = async (deployId: string) => {
try {
xml.value = await readXml(deployId)
originalXml.value = xml.value // 保存原始内容
} catch (error) {
console.error('Failed:', error)
}
}
// 上传前的处理
const handleBeforeUpload = (file: File) => {
// 检查文件类型
if (file.type !== 'text/xml' && !file.name.endsWith('.xml')) {
message.error('请上传 XML 格式的文件!')
return false
}
// 检查文件大小(限制为 10MB)
const isLt10M = file.size / 1024 / 1024 < 10
if (!isLt10M) {
message.error('文件大小不能超过 10MB!')
return false
}
// 读取文件内容
const reader = new FileReader()
reader.onload = (e) => {
const content = e.target?.result as string
// 检查当前是否有未保存的修改
if (xml.value && xml.value !== originalXml.value) {
Modal.confirm({
title: '提示',
content: '当前有未保存的修改,上传新文件将丢失这些修改,确定要继续吗?',
onOk: () => {
updateXmlContent(content)
},
})
} else {
updateXmlContent(content)
}
}
reader.onerror = () => {
message.error('文件读取失败!')
}
reader.readAsText(file, 'UTF-8')
return false // 阻止自动上传
}
// 更新XML内容
const updateXmlContent = (content: string) => {
try {
// 验证XML格式
const parser = new DOMParser()
const xmlDoc = parser.parseFromString(content, 'text/xml')
const parserError = xmlDoc.querySelector('parsererror')
if (parserError) {
message.error('XML 格式不正确,请检查文件内容!')
return
}
xml.value = content
originalXml.value = content
message.success('XML 文件上传成功!')
} catch (error) {
console.error('XML解析错误:', error)
message.error('XML 格式不正确,请检查文件内容!')
}
}
// 保存XML
const save = async (data: ProcessData) => {
const params: SaveParams = {
......@@ -88,9 +166,13 @@ const save = async (data: ProcessData) => {
try {
const res = await saveXml(params)
// 更新原始XML引用
originalXml.value = data.xml
message.success('保存成功!')
await handleSuccess()
} catch (error) {
console.error('Failed to save XML:', error)
message.error('保存失败:' + (error as Error).message)
}
}
......@@ -103,7 +185,6 @@ const showXML = (xmlContent: string) => {
xmlTitle.value = 'XML查看'
xmlOpen.value = true
// 修改2: 使用正确的大小写和调用方式
try {
// 第一种方式: 使用 default 导出(如果库是这种方式)
if (vkbeautify && typeof vkbeautify === 'object' && vkbeautify.xml) {
......@@ -164,7 +245,6 @@ onMounted(() => {
pre {
margin: 0;
padding: 16px;
// background-color: #282c34;
border-radius: 4px;
code {
......
......@@ -36,7 +36,7 @@
<StProblemCheckArchiveModal @register="registerModal" @success="handleSuccess"></StProblemCheckArchiveModal>
<!-- 审批记录 -->
<BpmPictureModal @register="registerBpmModal" />
<FlowHistoryDrawer @register="refFlowHistoryDrawer"/>
</div>
</template>
......@@ -48,20 +48,16 @@
import StProblemCheckArchiveModal from './components/StProblemCheckArchiveModal.vue'
import {columns, searchFormSchema, superQuerySchema} from './StProblemCheckArchive.data';
import {list, deleteOne, batchDelete, getImportUrl,getExportUrl} from './StProblemCheckArchive.api';
import FlowHistoryDrawer from '../../common/FlowHistoryDrawer.vue'
import { useDrawer } from '/@/components/Drawer';
import { getDateByPicker } from '/@/utils';
//日期个性化选择
const fieldPickers = reactive({
});
const fieldPickers = reactive({});
const [registerBpmModal, { openModal: bpmPicModal }] = useModal();
const queryParam = reactive<any>({});
const [refFlowHistoryDrawer, { openDrawer }] = useDrawer();
const refFlowHistory = ref();
const deployId = ref('');
const dataId = ref('');
// 审批记录抽屉
const drawerHistoryVisible = ref(false);
const queryParam = reactive<any>({});
const [registerModal, {openModal}] = useModal();
const { prefixCls,tableContext,onExportXls,onImportXls } = useListPage({
......@@ -149,11 +145,14 @@
}
function handleShowHistory(record) {
drawerHistoryVisible.value = true;
deployId.value = record.deployId;
dataId.value = record.id;
refFlowHistory.value.iniData(record);
openDrawer(true,{
procInsId: record.procInsId,
dataId: record.id,
deployId: record.deployId,
});
}
function getTableAction(record){
return [
{
......
......@@ -11,6 +11,7 @@
:currentFlowNode="node"
:nextFlowNode="workflowNodes[index+1]"
@open-multi-form="handleOpenMultiForm"
:todo-list="todoList"
/>
</div>
<div v-else class="no-form">
......@@ -50,10 +51,12 @@
import { ref, nextTick, onMounted, defineAsyncComponent, h } from 'vue';
import { getNodesByTableName } from '/@/components/Process/api/definition';
import { definitionStart, definitionStartByDeployId,addMyTaskFlow } from "/@/components/Process/api/definition";
import { todoListAll } from "/@/components/Process/api/todo";
import WorkFlowFormDrawer from '/@/views/common/WorkFlowFormDrawer.vue';
import TaskAssigneeDrawer from '/@/views/common/TaskAssigneeDrawer.vue'
import { useDrawer } from '/@/components/Drawer';
const [ registerAssigneeDrawer, { openDrawer: openAssigneeDrawer }] = useDrawer();
const formTableName = "st_problem_check";
......@@ -74,6 +77,8 @@
const formData = ref<any>({});
const customNextApi = ref<any>(null);
const todoList = ref<any[]>([]);
// 抽屉相关状态
const drawerVisible = ref(false);
const drawerTitle = ref('表单处理');
......@@ -154,7 +159,6 @@
if (startResRaw?.instanceId) {
procInsId.value = startResRaw.instanceId;
alert(procInsId.value)
myTaskFlow["taskId"] = startResRaw.taskId;
myTaskFlow["deployId"] = startResRaw.deployId;
myTaskFlow["procInsId"] = startResRaw.instanceId;
......@@ -265,6 +269,7 @@
const currentFormComponent = getCurrentFormComponent();
if (currentFormComponent && typeof currentFormComponent.handleUpdate === 'function') {
const beforeNode = workflowNodes.value[currentMultiFormIndex.value-1];
alert(currentMultiFormIndex.value)
alert(JSON.stringify(beforeNode))
await currentFormComponent.handleUpdate(dataId,beforeNode);
} else {
......@@ -272,7 +277,6 @@
}
}
async function handleOpenMultiForm(data: any) {
deployId.value = currentNode.value.deployId || '';
......@@ -281,7 +285,8 @@
dataId.value = data.id || '';
currentNode.value = workflowNodes.value[currentMultiFormIndex.value];
currentProcDefId.value = currentNode.value.procDefId || '';
const isApprovalNode = JSON.parse(currentNode.value["isApprove"] || 'false');
const isApprovalNode = JSON.parse(currentNode.value["isApprove"]);
if(isApprovalNode) {
isShowApprovalPanel.value = true;
} else {
......@@ -295,6 +300,7 @@
await nextTick();
try {
const nodes = await getNodesByTableName(formTableName);
todoList.value = await todoListAll();
workflowNodes.value = nodes;
if (workflowNodes.value && workflowNodes.value.length > 0) {
workflowNodes.value.forEach(node => {
......
......@@ -54,6 +54,12 @@ public class FlowTaskController {
return flowTaskService.todoList(pageNum, pageSize);
}
@GetMapping(value = "/todoListAll")
public Result todoListAll() {
return flowTaskService.todoListAll();
}
@GetMapping(value = "/finishedList")
public Result finishedList(
@RequestParam Integer pageNum,
......
......@@ -177,6 +177,7 @@ public interface IFlowTaskService {
public Result getMyTaskFlow(FlowTaskVo flowTaskVo);
public Result<List<String>> todoListAll();
}
......@@ -1263,6 +1263,30 @@ public class FlowTaskServiceImpl extends FlowServiceFactory implements IFlowTask
return Result.OK();
}
@Override
public Result<List<String>> todoListAll() {
String userId = iFlowThirdService.getLoginUser().getId();
String userName = iFlowThirdService.getLoginUser().getUsername();
List<String> userRoleIds = iFlowThirdService.getUserRoleIdsByUserId(userName);
List<String> retList = new ArrayList<>();
TaskQuery taskQuery = taskService.createTaskQuery()
.active()
.includeProcessVariables()
.or()
.taskAssignee(userId)
.taskCandidateUser(userId)
.taskCandidateGroupIn(userRoleIds)
.endOr()
.orderByTaskCreateTime().desc();
List<Task> taskList = taskQuery.list();
for(Task task: taskList) {
retList.add(task.getProcessInstanceId());
}
return Result.OK(retList);
}
/**
* 代办任务列表
*
......
......@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import dev.langchain4j.internal.Utils;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
......@@ -25,6 +26,7 @@ import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
......@@ -62,13 +64,17 @@ public class StProblemCheckController extends JeecgController<StProblemCheck, IS
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<StProblemCheck> queryWrapper = QueryGenerator.initQueryWrapper(stProblemCheck, req.getParameterMap());
List<String> todoList = stProblemCheck.getTodolist();
if(Utils.isNullOrEmpty(todoList)) {
//return Result.OK(null);
} else {
queryWrapper.in("procInsId", todoList);
}
Page<StProblemCheck> page = new Page<StProblemCheck>(pageNo, pageSize);
IPage<StProblemCheck> pageList = stProblemCheckService.page(page, queryWrapper);
return Result.OK(pageList);
}
......
package org.jeecg.modules.stm.problem.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
......@@ -12,6 +13,7 @@ import org.jeecgframework.poi.excel.annotation.Excel;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.List;
/**
* @Description: 问题整改
......@@ -166,4 +168,8 @@ public class StProblemCheck implements Serializable {
/**流程节点ID*/
private java.lang.String bmpNodeId;
// 当前用户需要处理的工作流 实例ID
@TableField(exist = false)
private java.util.List todolist;
}
......@@ -150,6 +150,12 @@ public class StProblemCheckArchive implements Serializable {
@Excel(name = "流程状态", width = 15)
@Schema(description = "流程状态")
private java.lang.String bpmStatus;
/**流程实例ID*/
@Excel(name = "流程实例ID", width = 15)
@Schema(description = "流程实例ID")
private java.lang.String procInsId;
/**部署ID*/
@Excel(name = "部署ID", width = 15)
@Schema(description = "部署ID")
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论