提交 4996e66f authored 作者: kxjia's avatar kxjia

问题管理

上级 4fa74ba6
......@@ -14,6 +14,7 @@ export const listDefinition = async (params) => {
// 部署流程实例
export function definitionStart(procDefId, data) {
alert(JSON.stringify(procDefId))
return defHttp.post({
url: '/flowable/definition/startByProcDefId',
data: {
......
......@@ -10,7 +10,6 @@ export function myProcessList(query) {
}
export function flowFormData(query) {
alert(JSON.stringify(query))
return defHttp.get({
url: '/flowable/task/flowFormData',
params: query
......
<template>
<div class="multi-form-preview">
<!-- 只读表单列表:前 N-1 个 -->
<div v-for="(node, idx) in previousNodes" :key="`readonly-${idx}`" class="form-readonly-item">
<div class="form-header">
<span class="form-name">{{ node.name }}</span>
<a-tag color="blue" class="readonly-tag">只读</a-tag>
</div>
<div class="form-content readonly">
<component
:is="loadComponent(node.formUrl)"
:disabled="true"
:readonly="true"
:form-data="formDataMap[node.id]"
:current-flow-node="node"
/>
</div>
</div>
<!-- 可编辑表单:第 N 个(当前节点) -->
<div v-if="currentNode" class="form-editable-item">
<div class="form-header">
<span class="form-name">{{ currentNode.name }}</span>
<a-tag color="green">可编辑</a-tag>
</div>
<div class="form-content editable">
<component
:is="loadComponent(currentNode.formUrl)"
:disabled="false"
:readonly="false"
:form-data="currentFormData"
:current-flow-node="currentNode"
@update:form-data="handleFormDataUpdate"
@submit="handleSubmit"
/>
</div>
</div>
<!-- 加载错误提示 -->
<a-empty v-if="!currentNode && previousNodes.length === 0" description="未找到有效表单节点" />
</div>
</template>
<script lang="ts" setup>
import { ref, computed, onMounted, defineAsyncComponent, h, watch } from 'vue';
import { message } from 'ant-design-vue';
// 定义组件属性
const props = defineProps({
// 当前节点在 workflowNodes 中的索引(从 0 开始)
currentNodeIndex: {
type: Number,
required: true,
default: 2 // 默认第三个(索引2)
},
// 工作流节点列表(从父组件传入)
workflowNodes: {
type: Array as () => Array<any>,
required: true,
default: () => []
},
// 外部传入的表单数据(用于回显)
externalFormData: {
type: Object,
default: () => ({})
}
});
// 定义事件
const emit = defineEmits(['form-data-update', 'submit']);
// 组件缓存
const componentCache = new Map();
// 使用 import.meta.glob 预加载所有可能的组件
const modules = import.meta.glob('@/views/**/*.vue');
// 当前节点的表单数据(可编辑)
const currentFormData = ref<any>({});
// 只读节点的表单数据映射(按节点id存储)
const formDataMap = ref<Record<string, any>>({});
// 获取前 N 个节点(只读部分)
const previousNodes = computed(() => {
if (!props.workflowNodes || props.workflowNodes.length === 0) return [];
const idx = props.currentNodeIndex;
// 取索引小于 idx 的节点(即当前节点之前的所有节点)
return props.workflowNodes.slice(0, idx);
});
// 获取当前节点(第 N 个,可编辑)
const currentNode = computed(() => {
if (!props.workflowNodes || props.workflowNodes.length === 0) return null;
const idx = props.currentNodeIndex;
if (idx < 0 || idx >= props.workflowNodes.length) return null;
return props.workflowNodes[idx];
});
// 将 URL 转换为正确的导入路径并动态加载组件
function loadComponent(url: string) {
if (!url) {
console.warn('formUrl 为空');
return createEmptyComponent();
}
if (componentCache.has(url)) {
return componentCache.get(url);
}
// 构建组件路径(使用 /@/ 格式)
let componentPath = '';
if (url.includes('/views')) {
componentPath = `/src${url}`;
} else {
componentPath = `/src/views${url}`;
}
// 确保有文件后缀
if (!componentPath.match(/\.(vue|js|ts|jsx|tsx)$/)) {
componentPath += '.vue';
}
console.log('加载组件路径:', componentPath);
// 从预加载的 modules 中获取加载器
let loader = modules[componentPath];
if (!loader) {
console.error('未找到组件:', componentPath);
console.log('可用路径示例:', Object.keys(modules).slice(0, 5));
const ErrorComponent = createErrorComponent(`组件未找到: ${componentPath}`);
componentCache.set(url, ErrorComponent);
return ErrorComponent;
}
// 创建异步组件,并注入额外的 props(disabled/readonly 等)
const AsyncComponent = defineAsyncComponent({
loader: () => loader() as Promise<{ default: any }>,
loadingComponent: {
render: () => h('div', { style: 'text-align: center; padding: 20px;' }, '加载中...')
},
errorComponent: {
render: () => h('div', { style: 'color: red; padding: 20px;' }, '组件加载失败,请刷新页面重试')
},
delay: 200,
timeout: 3000,
onError(error) {
console.error('异步组件加载错误:', error);
}
});
componentCache.set(url, AsyncComponent);
return AsyncComponent;
}
// 创建空组件(当 formUrl 为空时使用)
function createEmptyComponent() {
return {
render: () => h('div', { style: 'color: #999; padding: 20px; text-align: center;' }, '该节点未配置表单')
};
}
// 创建错误组件
function createErrorComponent(msg: string) {
return {
render: () => h('div', { style: 'color: red; padding: 20px;' }, msg)
};
}
// 处理表单数据更新(来自可编辑组件)
function handleFormDataUpdate(data: any) {
currentFormData.value = { ...currentFormData.value, ...data };
emit('form-data-update', currentFormData.value);
}
// 处理提交事件
function handleSubmit(data: any) {
emit('submit', {
nodeId: currentNode.value?.id,
nodeName: currentNode.value?.name,
formData: data || currentFormData.value
});
}
// 初始化只读节点的表单数据(从外部传入或模拟)
function initReadonlyFormData() {
// 如果外部传入了表单数据,则按节点id映射
if (props.externalFormData && Object.keys(props.externalFormData).length > 0) {
// 假设 externalFormData 的结构为 { nodeId: formData, ... }
previousNodes.value.forEach(node => {
if (props.externalFormData[node.id]) {
formDataMap.value[node.id] = props.externalFormData[node.id];
} else {
// 如果没有传入,设置空对象
formDataMap.value[node.id] = {};
}
});
} else {
// 初始化空数据
previousNodes.value.forEach(node => {
formDataMap.value[node.id] = {};
});
}
}
// 监听外部表单数据变化
watch(() => props.externalFormData, (newData) => {
if (newData && Object.keys(newData).length > 0) {
previousNodes.value.forEach(node => {
if (newData[node.id]) {
formDataMap.value[node.id] = newData[node.id];
}
});
// 如果当前节点有数据,也更新
if (currentNode.value && newData[currentNode.value.id]) {
currentFormData.value = newData[currentNode.value.id];
}
}
}, { deep: true, immediate: true });
// 组件挂载时初始化
onMounted(() => {
initReadonlyFormData();
console.log('MultiFormPreview 组件已挂载');
console.log('当前节点索引:', props.currentNodeIndex);
console.log('只读节点数量:', previousNodes.value.length);
console.log('当前节点:', currentNode.value?.name);
});
</script>
<style scoped lang="scss">
.multi-form-preview {
width: 100%;
padding: 16px;
background-color: #f5f7fa;
border-radius: 8px;
.form-readonly-item,
.form-editable-item {
margin-bottom: 24px;
background-color: #fff;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
transition: box-shadow 0.2s;
&:hover {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.form-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 16px;
background-color: #fafbfc;
border-bottom: 1px solid #e8eef2;
.form-name {
font-size: 15px;
font-weight: 500;
color: #1f2f3d;
}
.readonly-tag,
.ant-tag {
font-size: 12px;
}
}
.form-content {
padding: 20px;
&.readonly {
background-color: #fefefe;
// 只读模式下添加半透明遮罩效果,但仍保留交互(如果子组件支持disabled)
opacity: 0.95;
}
&.editable {
background-color: #fff;
}
}
}
.form-editable-item {
border: 1px solid #d9ecff;
box-shadow: 0 2px 8px rgba(24, 144, 255, 0.08);
.form-header {
background-color: #e6f7ff;
border-bottom-color: #bae7ff;
.form-name {
color: #096dd9;
}
}
}
}
</style>
\ No newline at end of file
<template>
<a-drawer
:title="drawerTitle"
:visible="visible"
:width="drawerWidth"
:closable="true"
:mask-closable="maskClosable"
@close="handleClose"
>
<!-- 选项卡模式 -->
<a-tabs v-model:activeKey="activeTabKey" type="card" class="form-tabs">
<!-- 只读选项卡:索引小于 currentNodeIndex 的节点 -->
<a-tab-pane
v-for="node in readonlyNodes"
:key="node.id"
:tab="node.name"
>
<template #tab>
<span>
{{ node.name }}
<a-tag color="blue" size="small" class="tab-tag">只读</a-tag>
</span>
</template>
<div class="tab-content readonly-content">
<component
:is="getComponent(node.formUrl || node.formListUrl)"
:disabled="true"
:readonly="true"
:form-data="getFormData(node.id)"
:current-flow-node="node"
/>
</div>
</a-tab-pane>
<!-- 可编辑选项卡:索引等于 currentNodeIndex 的节点 -->
<a-tab-pane
v-if="editableNode"
:key="editableNode.id"
:tab="editableNode.name"
>
<template #tab>
<span>
{{ editableNode.name }}
<a-tag color="green" size="small" class="tab-tag">可编辑</a-tag>
</span>
</template>
<div class="tab-content editable-content">
<component
:is="getComponent(editableNode.formUrl || editableNode.formListUrl)"
ref="editableFormRef"
:disabled="false"
:readonly="false"
:form-data="currentFormData"
:current-flow-node="editableNode"
@update:form-data="handleFormDataUpdate"
/>
</div>
</a-tab-pane>
</a-tabs>
<!-- 空状态 -->
<div v-if="!editableNode && readonlyNodes.length === 0" class="empty-state">
<a-empty description="未找到有效表单节点" />
</div>
<template #footer>
<div class="drawer-footer">
<a-button @click="handleClose">取消</a-button>
<a-button type="primary" :loading="submitLoading" @click="handleSubmit">
提交
</a-button>
</div>
</template>
</a-drawer>
</template>
<script lang="ts" setup>
import { ref, computed, onMounted, defineAsyncComponent, h, watch } from 'vue'
import { message } from 'ant-design-vue'
interface WorkflowNode {
id: string
name: string
formUrl?: string
formListUrl?: string
procDefId?: string
[key: string]: any
}
const props = defineProps({
visible: {
type: Boolean,
default: false
},
title: {
type: String,
default: '表单处理'
},
width: {
type: [Number, String],
default: 720
},
maskClosable: {
type: Boolean,
default: false
},
// 当前节点索引(从0开始),这个索引对应的节点是可编辑的
currentNodeIndex: {
type: Number,
required: true,
default: 2
},
workflowNodes: {
type: Array as () => WorkflowNode[],
required: true,
default: () => []
},
externalFormData: {
type: Object as () => Record<string, any>,
default: () => ({})
},
procDefId: {
type: String,
default: ''
}
})
const emit = defineEmits(['update:visible', 'submit', 'close', 'form-data-update'])
// 组件缓存
const componentCache = new Map()
const modules = import.meta.glob('@/views/**/*.vue')
// 状态
const loading = ref(false)
const submitLoading = ref(false)
const editableFormRef = ref()
const currentFormData = ref<any>({})
const formDataMap = ref<Record<string, any>>({})
const activeTabKey = ref<string>('')
// 计算属性
const drawerTitle = computed(() => props.title)
const drawerWidth = computed(() => props.width)
// 只读节点:索引小于 currentNodeIndex 的节点
const readonlyNodes = computed(() => {
if (!props.workflowNodes || props.workflowNodes.length === 0) {
return []
}
const idx = props.currentNodeIndex
console.log('只读节点 - 当前索引:', idx)
console.log('只读节点 - 所有节点:', props.workflowNodes.map((n, i) => `${i}:${n.name}`))
if (idx <= 0) return []
// 返回索引小于 idx 的节点
const nodes = props.workflowNodes.slice(0, idx)
console.log('只读节点:', nodes.map(n => n.name))
return nodes
})
// 可编辑节点:索引等于 currentNodeIndex 的节点
const editableNode = computed(() => {
if (!props.workflowNodes || props.workflowNodes.length === 0) {
return null
}
const idx = props.currentNodeIndex
if (idx < 0 || idx >= props.workflowNodes.length) {
console.warn('可编辑节点索引无效:', idx)
return null
}
const node = props.workflowNodes[idx]
console.log('可编辑节点:', node?.name, '索引:', idx)
return node
})
// 获取表单数据
function getFormData(nodeId: string): any {
const data = formDataMap.value[nodeId] || {}
console.log('获取表单数据 - 节点:', nodeId, '数据:', data)
return data
}
// 获取或加载组件
function getComponent(url: string) {
if (!url) {
console.warn('URL为空,返回空组件')
return createEmptyComponent()
}
if (componentCache.has(url)) {
return componentCache.get(url)
}
let componentPath = ''
if (url.includes('/views')) {
componentPath = `/src${url}`
} else {
componentPath = `/src/views${url}`
}
if (!componentPath.match(/\.(vue|js|ts|jsx|tsx)$/)) {
componentPath += '.vue'
}
console.log('加载组件路径:', componentPath)
const loader = modules[componentPath]
if (!loader) {
console.error('未找到组件:', componentPath)
const ErrorComponent = createErrorComponent(`组件未找到: ${componentPath}`)
componentCache.set(url, ErrorComponent)
return ErrorComponent
}
const AsyncComponent = defineAsyncComponent({
loader: () => loader() as Promise<{ default: any }>,
loadingComponent: {
render: () => h('div', { style: 'text-align: center; padding: 20px;' }, '加载中...')
},
errorComponent: {
render: () => h('div', { style: 'color: red; padding: 20px;' }, '组件加载失败')
},
delay: 200,
timeout: 3000
})
componentCache.set(url, AsyncComponent)
return AsyncComponent
}
function createEmptyComponent() {
return {
render: () => h('div', { style: 'color: #999; padding: 20px; text-align: center;' }, '该节点未配置表单')
}
}
function createErrorComponent(msg: string) {
return {
render: () => h('div', { style: 'color: red; padding: 20px;' }, msg)
}
}
// 处理表单数据更新
function handleFormDataUpdate(data: any) {
currentFormData.value = { ...currentFormData.value, ...data }
emit('form-data-update', currentFormData.value)
}
// 提交处理
async function handleSubmit() {
if (!editableNode.value) {
message.warning('没有可编辑的表单')
return
}
if (editableFormRef.value && editableFormRef.value.validate) {
try {
await editableFormRef.value.validate()
} catch (error) {
message.error('请完善表单信息')
return
}
}
let submitData = currentFormData.value
if (editableFormRef.value && editableFormRef.value.getFormData) {
submitData = editableFormRef.value.getFormData()
} else if (editableFormRef.value && editableFormRef.value.formData) {
submitData = editableFormRef.value.formData
}
console.log('提交数据:', {
nodeId: editableNode.value.id,
nodeName: editableNode.value.name,
formData: submitData,
procDefId: props.procDefId
})
emit('submit', {
nodeId: editableNode.value.id,
nodeName: editableNode.value.name,
formData: submitData,
procDefId: props.procDefId
})
}
// 关闭抽屉
function handleClose() {
emit('update:visible', false)
emit('close')
}
// 重置数据
function resetFormData() {
currentFormData.value = {}
const newFormDataMap: Record<string, any> = {}
readonlyNodes.value.forEach(node => {
newFormDataMap[node.id] = props.externalFormData[node.id] || {}
})
formDataMap.value = newFormDataMap
if (editableNode.value && props.externalFormData[editableNode.value.id]) {
currentFormData.value = { ...props.externalFormData[editableNode.value.id] }
}
// 设置默认激活的选项卡为可编辑的选项卡
if (editableNode.value) {
activeTabKey.value = editableNode.value.id
console.log('设置激活选项卡为可编辑节点:', editableNode.value.name)
} else if (readonlyNodes.value.length > 0) {
activeTabKey.value = readonlyNodes.value[0].id
console.log('设置激活选项卡为第一个只读节点:', readonlyNodes.value[0].name)
}
}
// 预加载组件
function preloadComponents() {
props.workflowNodes.forEach(node => {
const url = node.formUrl || node.formListUrl
if (url) {
getComponent(url)
}
})
}
// 监听抽屉打开
watch(() => props.visible, (newVal) => {
if (newVal) {
console.log('抽屉打开,currentNodeIndex:', props.currentNodeIndex)
console.log('所有节点:', props.workflowNodes)
resetFormData()
preloadComponents()
}
}, { immediate: true })
// 监听外部数据变化
watch(() => props.externalFormData, (newData) => {
if (newData && Object.keys(newData).length > 0) {
console.log('外部数据变化:', newData)
const newFormDataMap = { ...formDataMap.value }
readonlyNodes.value.forEach(node => {
if (newData[node.id]) {
newFormDataMap[node.id] = newData[node.id]
}
})
formDataMap.value = newFormDataMap
if (editableNode.value && newData[editableNode.value.id]) {
currentFormData.value = newData[editableNode.value.id]
}
}
}, { deep: true })
onMounted(() => {
console.log('组件挂载,workflowNodes:', props.workflowNodes)
console.log('currentNodeIndex:', props.currentNodeIndex)
resetFormData()
preloadComponents()
})
defineExpose({
resetFormData,
getFormData: () => currentFormData.value,
validate: async () => {
if (editableFormRef.value && editableFormRef.value.validate) {
return await editableFormRef.value.validate()
}
return true
}
})
</script>
<style scoped lang="scss">
.workflow-form-drawer {
width: 100%;
height: 100%;
overflow-y: auto;
.form-card {
border-radius: 8px;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
:deep(.ant-card-body) {
padding: 0;
}
}
.form-tabs {
:deep(.ant-tabs-nav) {
margin-bottom: 0;
background-color: #fafbfc;
padding: 0 16px;
border-bottom: 1px solid #e8eef2;
}
:deep(.ant-tabs-tab) {
padding: 12px 20px;
font-weight: 500;
transition: all 0.3s;
&:hover {
color: #1890ff;
}
}
:deep(.ant-tabs-tab-active) {
.ant-tabs-tab-btn {
color: #1890ff;
}
}
:deep(.ant-tabs-ink-bar) {
background: #1890ff;
}
}
.tab-content {
padding: 24px;
min-height: 400px;
background-color: #fff;
&.readonly-content {
background-color: #f5f5f5;
// 让只读内容区域内的所有表单输入框都显示为只读样式
:deep(input),
:deep(textarea),
:deep(.ant-input),
:deep(.ant-select-selector),
:deep(.ant-picker) {
background-color: #f5f5f5 !important;
cursor: not-allowed !important;
color: #666 !important;
}
:deep(.ant-input-affix-wrapper) {
background-color: #f5f5f5 !important;
}
}
&.editable-content {
background-color: #fff;
}
}
.tab-tag {
margin-left: 8px;
font-size: 12px;
transform: scale(0.9);
display: inline-block;
}
.empty-state {
padding: 60px 0;
text-align: center;
}
&::-webkit-scrollbar {
width: 6px;
}
&::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 3px;
}
&::-webkit-scrollbar-thumb {
background: #c1c1c1;
border-radius: 3px;
&:hover {
background: #a8a8a8;
}
}
}
.drawer-footer {
text-align: right;
:deep(.ant-btn) {
margin-left: 8px;
&:first-child {
margin-left: 0;
}
}
}
:deep(.ant-drawer-body) {
padding: 16px;
background-color: #f5f7fa;
}
:deep(.ant-drawer-footer) {
padding: 12px 16px;
border-top: 1px solid #e8eef2;
}
</style>
\ No newline at end of file
......@@ -183,12 +183,13 @@ export const formSchema: FormSchema[] = [
{
label: '问题描述',
field: 'problemDes',
component: 'InputTextArea',
component: 'JEditor',
required: true,
componentProps: {
rows: 4,
showCount: true,
maxlength: 3000,
maxlength: 30000,
height: 300,
},
},
{
......
......@@ -2,10 +2,8 @@
<div>
<BasicTable @register="registerTable" :rowSelection="rowSelection">
<template #tableTitle>
<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="primary" @click="handleAdd" preIcon="ant-design:plus-outlined">添加问题</a-button>
<a-button type="primary" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="onImportXls">导入</j-upload-button>
<a-dropdown v-if="selectedRowKeys.length > 0">
<template #overlay>
<a-menu>
......@@ -55,6 +53,8 @@
}
})
const emit = defineEmits(['callback'])
//注册model
const [registerModal, { openModal }] = useModal();
const [registerPlanModal, { openModal: openPlanModal }] = useModal();
......@@ -95,7 +95,7 @@
/**
* 新增事件
*/
function handleAdd() {
function handleAdd333333() {
openModal(true, {
isUpdate: false,
showFooter: true,
......@@ -106,6 +106,10 @@
}
});
}
function handleAdd() {
emit("callback",null)
}
/**
* 编辑事件
*/
......@@ -162,7 +166,7 @@
onClick: handleEdit.bind(null, record),
},
{
label: '启动流程',
label: '发送任务',
onClick: handleFlow.bind(null, record),
},
......
......@@ -4,34 +4,60 @@
<a-tab-pane v-for="(node, index) in workflowNodes" :key="index + 1" :tab="node.name">
<div v-if="node.formListUrl" class="tab-content">
<component :is="loadComponent(node.formListUrl)"
:beforeFlowNode="workflowNodes[index-1]" :currentFlowNode="node" :nextFlowNode="workflowNodes[index+1]" />
@startWorkFlow="handleDefinitionStart"
:beforeFlowNode="workflowNodes[index-1]"
:currentFlowNode="node"
:nextFlowNode="workflowNodes[index+1]"
@open-multi-form="handleOpenMultiForm"
@callback="handleCallback"
/>
</div>
<div v-else class="no-form">
该节点未配置表单
</div>
</a-tab-pane>
</a-tabs>
<!-- 多表单抽屉组件 -->
<WorkFlowFormDrawer
v-model:visible="drawerVisible"
:title="drawerTitle"
:current-node-index="currentMultiFormIndex"
:workflow-nodes="workflowNodes"
:external-form-data="externalFormData"
:proc-def-id="currentProcDefId"
@submit="handleMultiFormSubmit"
@close="handleDrawerClose"
@form-data-update="handleMultiFormDataUpdate"
width="50%"
/>
</div>
</template>
<script lang="ts" name="problem-stProblemCheck" setup>
import { ref, nextTick, onMounted, defineAsyncComponent, h } from 'vue';
import { getNodesByTableName } from '/@/components/Process/api/definition';
import { definitionStart, flowXmlAndNode } from "/@/components/Process/api/definition";
import WorkFlowFormDrawer from '/@/views/common/WorkFlowFormDrawer.vue';
const workflowNodes = ref<any[]>([]);
const activeTab = ref(1);
// 组件缓存,避免重复加载
const componentCache = new Map();
// 抽屉相关状态
const drawerVisible = ref(false);
const drawerTitle = ref('表单处理');
const currentMultiFormIndex = ref(0);
const currentProcDefId = ref('');
const externalFormData = ref<Record<string, any>>({});
// 使用 import.meta.glob 预加载所有可能的组件,使用 /@/ 格式
const componentCache = new Map();
const modules = import.meta.glob('@/views/**/*.vue');
function handleTabChange(key) {
activeTab.value = key;
currentMultiFormIndex.value = key - 1;
}
// 将URL转换为正确的导入路径并动态加载组件
function loadComponent(url: string) {
console.log('开始加载组件,URL:', url);
......@@ -39,44 +65,29 @@
console.log('从缓存加载组件:', url);
return componentCache.get(url);
}
// 构建使用 /@/ 格式的组件路径
let componentPath = '';
// 检查url是否已包含/views
if (url.includes('/views')) {
// 如果已包含/views,直接使用 /@/ 前缀
componentPath = `/src${url}`;
} else {
// 否则添加 /@/views 前缀
componentPath = `/src/views${url}`;
}
// 检查是否已有文件后缀
if (!componentPath.match(/\.(vue|js|ts|jsx|tsx)$/)) {
// 如果没有文件后缀,添加.vue
componentPath += '.vue';
}
console.log('生成的组件路径:', componentPath);
console.log('所有可用的组件路径示例:', Object.keys(modules).slice(0, 10));
// 从预加载的 modules 中获取加载器
let loader = modules[componentPath];
if (!loader) {
console.error('未找到组件:', componentPath);
console.log('包含 problemCheck 的路径:', Object.keys(modules).filter(key => key.includes('problemCheck')));
// 返回错误组件
const ErrorComponent = {
render: () => h('div', { style: 'color: red; padding: 20px;' }, `组件未找到: ${componentPath}`)
};
componentCache.set(url, ErrorComponent);
return ErrorComponent;
}
// 创建异步组件
const AsyncComponent = defineAsyncComponent({
loader: () => loader() as Promise<{ default: any }>,
loadingComponent: {
......@@ -91,11 +102,89 @@
console.error('异步组件加载错误:', error);
}
});
componentCache.set(url, AsyncComponent);
return AsyncComponent;
}
const handleDefinitionStart = (procDefId: string, submitData: any) => {
return definitionStart({
procDefId,
variables: submitData
})
}
const handleOpenMultiForm = (params: {
nodeIndex?: number;
title?: string;
procDefId?: string;
formData?: Record<string, any>;
}) => {
console.log('打开多表单抽屉:', params);
if (params.nodeIndex !== undefined) {
currentMultiFormIndex.value = params.nodeIndex;
} else {
currentMultiFormIndex.value = activeTab.value - 1;
}
if (params.title) {
drawerTitle.value = params.title;
} else {
const currentNode = workflowNodes.value[currentMultiFormIndex.value];
drawerTitle.value = currentNode ? `${currentNode.name} - 历史表单查看` : '表单处理';
}
if (params.procDefId) {
currentProcDefId.value = params.procDefId;
} else if (workflowNodes.value[currentMultiFormIndex.value]) {
currentProcDefId.value = workflowNodes.value[currentMultiFormIndex.value].procDefId || '';
}
if (params.formData) {
externalFormData.value = params.formData;
} else {
externalFormData.value = {};
}
drawerVisible.value = true;
};
const handleMultiFormSubmit = async (submitData: {
nodeId: string;
nodeName: string;
formData: any;
procDefId: string;
}) => {
console.log('多表单提交数据:', submitData);
try {
await definitionStart({
procDefId: submitData.procDefId,
variables: submitData.formData
});
drawerVisible.value = false;
const currentTabKey = activeTab.value;
const currentComponent = loadComponent(workflowNodes.value[currentTabKey - 1]?.formListUrl);
} catch (error) {
console.error('提交失败:', error);
throw error;
}
};
const handleDrawerClose = () => {
drawerVisible.value = false;
console.log('抽屉关闭');
};
const handleMultiFormDataUpdate = (data: any) => {
console.log('多表单数据更新:', data);
// 可以在这里实时保存数据到本地
};
const openHistoryForms = (nodeIndex: number, formData?: Record<string, any>) => {
handleOpenMultiForm({
nodeIndex,
title: `查看历史表单 - ${workflowNodes.value[nodeIndex]?.name || ''}`,
formData
});
};
defineExpose({
openHistoryForms,
openMultiForm: handleOpenMultiForm
});
onMounted(async () => {
await nextTick();
try {
......@@ -104,12 +193,10 @@
workflowNodes.value = nodes;
console.log('获取到的工作流节点:', workflowNodes.value);
// 打印每个节点的 formListUrl
workflowNodes.value.forEach((node, index) => {
console.log(`节点${index + 1}:`, node.name, 'formListUrl:', node.formListUrl);
});
// 预加载所有节点的组件
if (workflowNodes.value && workflowNodes.value.length > 0) {
console.log('开始预加载组件...');
workflowNodes.value.forEach(node => {
......@@ -123,6 +210,22 @@
console.error('获取工作流节点失败:', error);
}
});
function handleCallback(data: any) {
drawerVisible.value = true;
const currentNode = workflowNodes.value[currentMultiFormIndex.value];
currentProcDefId.value = currentNode.procDefId || '';
const userid = currentNode.assignee || '';
const nodeId = currentNode.id
const deployId = currentNode.deployId || '';
const procDefId = currentNode.procDefId || '';
const attributes = currentNode.attributes || {};
const userType = attributes.userType || [];
if (userType.length > 0) {
data['userType'] = userType[0].value || '';
}
}
</script>
<style scoped>
......
......@@ -25,6 +25,7 @@
import { list} from './StProblemCheck.api';
import StProblemCheckExecuteModal from './components/StProblemCheckExecuteModal.vue';
const emit = defineEmits(['callback'])
const props = defineProps({
beforeFlowNode: {
......@@ -41,9 +42,7 @@
}
})
const [registerExecuteModal, { openModal: openExecuteModal }] = useModal();
const { prefixCls, tableContext } = useListPage({
tableProps: {
title: '问题整改计划',
......@@ -71,12 +70,7 @@
const [registerTable, { reload }, { rowSelection, selectedRowKeys }] = tableContext;
function handlePlan(record: Recordable) {
openExecuteModal(true, {
record,
isUpdate: true,
showFooter: true,
nextFlowNode: props.nextFlowNode,
});
emit("callback",record)
}
function handleSuccess() {
......
......@@ -41,7 +41,6 @@
let formData = {};
const queryByIdUrl = '/problem/stProblemCheck/queryById/';
alert(props.formData.dataId)
async function initFormData() {
let params = { id: props.formData.dataId };
const data = await defHttp.get({ url: queryByIdUrl, params });
......@@ -53,6 +52,7 @@
}
async function submitForm() {
alert(888)
let data = getFieldsValue();
let params = Object.assign({}, formData, data);
console.log('表单数据', params);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论