ソースを参照

BPM:支持多表单,每个流程任务都可以绑定流程表单

YunaiV 1 年間 前
コミット
08dd4ed072

+ 1 - 6
src/components/bpmnProcessDesigner/package/penal/PropertiesPanel.vue

@@ -24,12 +24,7 @@
       </el-collapse-item>
       <el-collapse-item name="condition" v-if="formVisible" key="form">
         <template #title><Icon icon="ep:list" />表单</template>
-        <!-- <element-form :id="elementId" :type="elementType" /> -->
-        友情提示:使用
-        <router-link :to="{ path: '/bpm/manager/form' }"
-          ><el-link type="danger">流程表单</el-link>
-        </router-link>
-        替代,提供更好的表单设计功能
+        <element-form :id="elementId" :type="elementType" />
       </el-collapse-item>
       <el-collapse-item name="task" v-if="elementType.indexOf('Task') !== -1" key="task">
         <template #title><Icon icon="ep:checked" />任务(审批人)</template>

+ 219 - 206
src/components/bpmnProcessDesigner/package/penal/form/ElementForm.vue

@@ -1,228 +1,233 @@
 <template>
   <div class="panel-tab__content">
     <el-form label-width="80px">
-      <el-form-item label="表单标识">
-        <el-input v-model="formKey" clearable @change="updateElementFormKey" />
-      </el-form-item>
-      <el-form-item label="业务标识">
-        <el-select v-model="businessKey" @change="updateElementBusinessKey">
-          <el-option v-for="i in fieldList" :key="i.id" :value="i.id" :label="i.label" />
-          <el-option label="无" value="" />
+      <el-form-item label="流程表单">
+        <!--        <el-input v-model="formKey" clearable @change="updateElementFormKey" />-->
+        <el-select v-model="formKey" clearable @change="updateElementFormKey">
+          <el-option v-for="form in formList" :key="form.id" :label="form.name" :value="form.id" />
         </el-select>
       </el-form-item>
+      <!--      <el-form-item label="业务标识">-->
+      <!--        <el-select v-model="businessKey" @change="updateElementBusinessKey">-->
+      <!--          <el-option v-for="i in fieldList" :key="i.id" :value="i.id" :label="i.label" />-->
+      <!--          <el-option label="无" value="" />-->
+      <!--        </el-select>-->
+      <!--      </el-form-item>-->
     </el-form>
 
     <!--字段列表-->
-    <div class="element-property list-property">
-      <el-divider><Icon icon="ep:coin" /> 表单字段</el-divider>
-      <el-table :data="fieldList" max-height="240" fit border>
-        <el-table-column label="序号" type="index" width="50px" />
-        <el-table-column label="字段名称" prop="label" min-width="80px" show-overflow-tooltip />
-        <el-table-column
-          label="字段类型"
-          prop="type"
-          min-width="80px"
-          :formatter="(row) => fieldType[row.type] || row.type"
-          show-overflow-tooltip
-        />
-        <el-table-column
-          label="默认值"
-          prop="defaultValue"
-          min-width="80px"
-          show-overflow-tooltip
-        />
-        <el-table-column label="操作" width="90px">
-          <template #default="scope">
-            <el-button type="primary" link @click="openFieldForm(scope, scope.$index)"
-              >编辑</el-button
-            >
-            <el-divider direction="vertical" />
-            <el-button
-              type="primary"
-              link
-              style="color: #ff4d4f"
-              @click="removeField(scope, scope.$index)"
-              >移除</el-button
-            >
-          </template>
-        </el-table-column>
-      </el-table>
-    </div>
-    <div class="element-drawer__button">
-      <XButton type="primary" proIcon="ep:plus" title="添加字段" @click="openFieldForm(null, -1)" />
-    </div>
+    <!--    <div class="element-property list-property">-->
+    <!--      <el-divider><Icon icon="ep:coin" /> 表单字段</el-divider>-->
+    <!--      <el-table :data="fieldList" max-height="240" fit border>-->
+    <!--        <el-table-column label="序号" type="index" width="50px" />-->
+    <!--        <el-table-column label="字段名称" prop="label" min-width="80px" show-overflow-tooltip />-->
+    <!--        <el-table-column-->
+    <!--          label="字段类型"-->
+    <!--          prop="type"-->
+    <!--          min-width="80px"-->
+    <!--          :formatter="(row) => fieldType[row.type] || row.type"-->
+    <!--          show-overflow-tooltip-->
+    <!--        />-->
+    <!--        <el-table-column-->
+    <!--          label="默认值"-->
+    <!--          prop="defaultValue"-->
+    <!--          min-width="80px"-->
+    <!--          show-overflow-tooltip-->
+    <!--        />-->
+    <!--        <el-table-column label="操作" width="90px">-->
+    <!--          <template #default="scope">-->
+    <!--            <el-button type="primary" link @click="openFieldForm(scope, scope.$index)"-->
+    <!--              >编辑</el-button-->
+    <!--            >-->
+    <!--            <el-divider direction="vertical" />-->
+    <!--            <el-button-->
+    <!--              type="primary"-->
+    <!--              link-->
+    <!--              style="color: #ff4d4f"-->
+    <!--              @click="removeField(scope, scope.$index)"-->
+    <!--              >移除</el-button-->
+    <!--            >-->
+    <!--          </template>-->
+    <!--        </el-table-column>-->
+    <!--      </el-table>-->
+    <!--    </div>-->
+    <!--    <div class="element-drawer__button">-->
+    <!--      <XButton type="primary" proIcon="ep:plus" title="添加字段" @click="openFieldForm(null, -1)" />-->
+    <!--    </div>-->
 
     <!--字段配置侧边栏-->
-    <el-drawer
-      v-model="fieldModelVisible"
-      title="字段配置"
-      :size="`${width}px`"
-      append-to-body
-      destroy-on-close
-    >
-      <el-form :model="formFieldForm" label-width="90px">
-        <el-form-item label="字段ID">
-          <el-input v-model="formFieldForm.id" clearable />
-        </el-form-item>
-        <el-form-item label="类型">
-          <el-select
-            v-model="formFieldForm.typeType"
-            placeholder="请选择字段类型"
-            clearable
-            @change="changeFieldTypeType"
-          >
-            <el-option v-for="(value, key) of fieldType" :label="value" :value="key" :key="key" />
-          </el-select>
-        </el-form-item>
-        <el-form-item label="类型名称" v-if="formFieldForm.typeType === 'custom'">
-          <el-input v-model="formFieldForm.type" clearable />
-        </el-form-item>
-        <el-form-item label="名称">
-          <el-input v-model="formFieldForm.label" clearable />
-        </el-form-item>
-        <el-form-item label="时间格式" v-if="formFieldForm.typeType === 'date'">
-          <el-input v-model="formFieldForm.datePattern" clearable />
-        </el-form-item>
-        <el-form-item label="默认值">
-          <el-input v-model="formFieldForm.defaultValue" clearable />
-        </el-form-item>
-      </el-form>
+    <!--    <el-drawer-->
+    <!--      v-model="fieldModelVisible"-->
+    <!--      title="字段配置"-->
+    <!--      :size="`${width}px`"-->
+    <!--      append-to-body-->
+    <!--      destroy-on-close-->
+    <!--    >-->
+    <!--      <el-form :model="formFieldForm" label-width="90px">-->
+    <!--        <el-form-item label="字段ID">-->
+    <!--          <el-input v-model="formFieldForm.id" clearable />-->
+    <!--        </el-form-item>-->
+    <!--        <el-form-item label="类型">-->
+    <!--          <el-select-->
+    <!--            v-model="formFieldForm.typeType"-->
+    <!--            placeholder="请选择字段类型"-->
+    <!--            clearable-->
+    <!--            @change="changeFieldTypeType"-->
+    <!--          >-->
+    <!--            <el-option v-for="(value, key) of fieldType" :label="value" :value="key" :key="key" />-->
+    <!--          </el-select>-->
+    <!--        </el-form-item>-->
+    <!--        <el-form-item label="类型名称" v-if="formFieldForm.typeType === 'custom'">-->
+    <!--          <el-input v-model="formFieldForm.type" clearable />-->
+    <!--        </el-form-item>-->
+    <!--        <el-form-item label="名称">-->
+    <!--          <el-input v-model="formFieldForm.label" clearable />-->
+    <!--        </el-form-item>-->
+    <!--        <el-form-item label="时间格式" v-if="formFieldForm.typeType === 'date'">-->
+    <!--          <el-input v-model="formFieldForm.datePattern" clearable />-->
+    <!--        </el-form-item>-->
+    <!--        <el-form-item label="默认值">-->
+    <!--          <el-input v-model="formFieldForm.defaultValue" clearable />-->
+    <!--        </el-form-item>-->
+    <!--      </el-form>-->
 
-      <!-- 枚举值设置 -->
-      <template v-if="formFieldForm.type === 'enum'">
-        <el-divider key="enum-divider" />
-        <p class="listener-filed__title" key="enum-title">
-          <span><Icon icon="ep:menu" />枚举值列表:</span>
-          <el-button type="primary" @click="openFieldOptionForm(null, -1, 'enum')"
-            >添加枚举值</el-button
-          >
-        </p>
-        <el-table :data="fieldEnumList" key="enum-table" max-height="240" fit border>
-          <el-table-column label="序号" width="50px" type="index" />
-          <el-table-column label="枚举值编号" prop="id" min-width="100px" show-overflow-tooltip />
-          <el-table-column label="枚举值名称" prop="name" min-width="100px" show-overflow-tooltip />
-          <el-table-column label="操作" width="90px">
-            <template #default="scope">
-              <el-button
-                type="primary"
-                link
-                @click="openFieldOptionForm(scope, scope.$index, 'enum')"
-                >编辑</el-button
-              >
-              <el-divider direction="vertical" />
-              <el-button
-                type="primary"
-                link
-                style="color: #ff4d4f"
-                @click="removeFieldOptionItem(scope, scope.$index, 'enum')"
-                >移除</el-button
-              >
-            </template>
-          </el-table-column>
-        </el-table>
-      </template>
+    <!--      &lt;!&ndash; 枚举值设置 &ndash;&gt;-->
+    <!--      <template v-if="formFieldForm.type === 'enum'">-->
+    <!--        <el-divider key="enum-divider" />-->
+    <!--        <p class="listener-filed__title" key="enum-title">-->
+    <!--          <span><Icon icon="ep:menu" />枚举值列表:</span>-->
+    <!--          <el-button type="primary" @click="openFieldOptionForm(null, -1, 'enum')"-->
+    <!--            >添加枚举值</el-button-->
+    <!--          >-->
+    <!--        </p>-->
+    <!--        <el-table :data="fieldEnumList" key="enum-table" max-height="240" fit border>-->
+    <!--          <el-table-column label="序号" width="50px" type="index" />-->
+    <!--          <el-table-column label="枚举值编号" prop="id" min-width="100px" show-overflow-tooltip />-->
+    <!--          <el-table-column label="枚举值名称" prop="name" min-width="100px" show-overflow-tooltip />-->
+    <!--          <el-table-column label="操作" width="90px">-->
+    <!--            <template #default="scope">-->
+    <!--              <el-button-->
+    <!--                type="primary"-->
+    <!--                link-->
+    <!--                @click="openFieldOptionForm(scope, scope.$index, 'enum')"-->
+    <!--                >编辑</el-button-->
+    <!--              >-->
+    <!--              <el-divider direction="vertical" />-->
+    <!--              <el-button-->
+    <!--                type="primary"-->
+    <!--                link-->
+    <!--                style="color: #ff4d4f"-->
+    <!--                @click="removeFieldOptionItem(scope, scope.$index, 'enum')"-->
+    <!--                >移除</el-button-->
+    <!--              >-->
+    <!--            </template>-->
+    <!--          </el-table-column>-->
+    <!--        </el-table>-->
+    <!--      </template>-->
 
-      <!-- 校验规则 -->
-      <el-divider key="validation-divider" />
-      <p class="listener-filed__title" key="validation-title">
-        <span><Icon icon="ep:menu" />约束条件列表:</span>
-        <el-button type="primary" @click="openFieldOptionForm(null, -1, 'constraint')"
-          >添加约束</el-button
-        >
-      </p>
-      <el-table :data="fieldConstraintsList" key="validation-table" max-height="240" fit border>
-        <el-table-column label="序号" width="50px" type="index" />
-        <el-table-column label="约束名称" prop="name" min-width="100px" show-overflow-tooltip />
-        <el-table-column label="约束配置" prop="config" min-width="100px" show-overflow-tooltip />
-        <el-table-column label="操作" width="90px">
-          <template #default="scope">
-            <el-button
-              type="primary"
-              link
-              @click="openFieldOptionForm(scope, scope.$index, 'constraint')"
-              >编辑</el-button
-            >
-            <el-divider direction="vertical" />
-            <el-button
-              type="primary"
-              link
-              style="color: #ff4d4f"
-              @click="removeFieldOptionItem(scope, scope.$index, 'constraint')"
-              >移除</el-button
-            >
-          </template>
-        </el-table-column>
-      </el-table>
+    <!--      &lt;!&ndash; 校验规则 &ndash;&gt;-->
+    <!--      <el-divider key="validation-divider" />-->
+    <!--      <p class="listener-filed__title" key="validation-title">-->
+    <!--        <span><Icon icon="ep:menu" />约束条件列表:</span>-->
+    <!--        <el-button type="primary" @click="openFieldOptionForm(null, -1, 'constraint')"-->
+    <!--          >添加约束</el-button-->
+    <!--        >-->
+    <!--      </p>-->
+    <!--      <el-table :data="fieldConstraintsList" key="validation-table" max-height="240" fit border>-->
+    <!--        <el-table-column label="序号" width="50px" type="index" />-->
+    <!--        <el-table-column label="约束名称" prop="name" min-width="100px" show-overflow-tooltip />-->
+    <!--        <el-table-column label="约束配置" prop="config" min-width="100px" show-overflow-tooltip />-->
+    <!--        <el-table-column label="操作" width="90px">-->
+    <!--          <template #default="scope">-->
+    <!--            <el-button-->
+    <!--              type="primary"-->
+    <!--              link-->
+    <!--              @click="openFieldOptionForm(scope, scope.$index, 'constraint')"-->
+    <!--              >编辑</el-button-->
+    <!--            >-->
+    <!--            <el-divider direction="vertical" />-->
+    <!--            <el-button-->
+    <!--              type="primary"-->
+    <!--              link-->
+    <!--              style="color: #ff4d4f"-->
+    <!--              @click="removeFieldOptionItem(scope, scope.$index, 'constraint')"-->
+    <!--              >移除</el-button-->
+    <!--            >-->
+    <!--          </template>-->
+    <!--        </el-table-column>-->
+    <!--      </el-table>-->
 
-      <!-- 表单属性 -->
-      <el-divider key="property-divider" />
-      <p class="listener-filed__title" key="property-title">
-        <span><Icon icon="ep:menu" />字段属性列表:</span>
-        <el-button type="primary" @click="openFieldOptionForm(null, -1, 'property')"
-          >添加属性</el-button
-        >
-      </p>
-      <el-table :data="fieldPropertiesList" key="property-table" max-height="240" fit border>
-        <el-table-column label="序号" width="50px" type="index" />
-        <el-table-column label="属性编号" prop="id" min-width="100px" show-overflow-tooltip />
-        <el-table-column label="属性值" prop="value" min-width="100px" show-overflow-tooltip />
-        <el-table-column label="操作" width="90px">
-          <template #default="scope">
-            <el-button
-              type="primary"
-              link
-              @click="openFieldOptionForm(scope, scope.$index, 'property')"
-              >编辑</el-button
-            >
-            <el-divider direction="vertical" />
-            <el-button
-              type="primary"
-              link
-              style="color: #ff4d4f"
-              @click="removeFieldOptionItem(scope, scope.$index, 'property')"
-              >移除</el-button
-            >
-          </template>
-        </el-table-column>
-      </el-table>
+    <!--      &lt;!&ndash; 表单属性 &ndash;&gt;-->
+    <!--      <el-divider key="property-divider" />-->
+    <!--      <p class="listener-filed__title" key="property-title">-->
+    <!--        <span><Icon icon="ep:menu" />字段属性列表:</span>-->
+    <!--        <el-button type="primary" @click="openFieldOptionForm(null, -1, 'property')"-->
+    <!--          >添加属性</el-button-->
+    <!--        >-->
+    <!--      </p>-->
+    <!--      <el-table :data="fieldPropertiesList" key="property-table" max-height="240" fit border>-->
+    <!--        <el-table-column label="序号" width="50px" type="index" />-->
+    <!--        <el-table-column label="属性编号" prop="id" min-width="100px" show-overflow-tooltip />-->
+    <!--        <el-table-column label="属性值" prop="value" min-width="100px" show-overflow-tooltip />-->
+    <!--        <el-table-column label="操作" width="90px">-->
+    <!--          <template #default="scope">-->
+    <!--            <el-button-->
+    <!--              type="primary"-->
+    <!--              link-->
+    <!--              @click="openFieldOptionForm(scope, scope.$index, 'property')"-->
+    <!--              >编辑</el-button-->
+    <!--            >-->
+    <!--            <el-divider direction="vertical" />-->
+    <!--            <el-button-->
+    <!--              type="primary"-->
+    <!--              link-->
+    <!--              style="color: #ff4d4f"-->
+    <!--              @click="removeFieldOptionItem(scope, scope.$index, 'property')"-->
+    <!--              >移除</el-button-->
+    <!--            >-->
+    <!--          </template>-->
+    <!--        </el-table-column>-->
+    <!--      </el-table>-->
 
-      <!-- 底部按钮 -->
-      <div class="element-drawer__button">
-        <el-button>取 消</el-button>
-        <el-button type="primary" @click="saveField">保 存</el-button>
-      </div>
-    </el-drawer>
+    <!--      &lt;!&ndash; 底部按钮 &ndash;&gt;-->
+    <!--      <div class="element-drawer__button">-->
+    <!--        <el-button>取 消</el-button>-->
+    <!--        <el-button type="primary" @click="saveField">保 存</el-button>-->
+    <!--      </div>-->
+    <!--    </el-drawer>-->
 
-    <el-dialog
-      v-model="fieldOptionModelVisible"
-      :title="optionModelTitle"
-      width="600px"
-      append-to-body
-      destroy-on-close
-    >
-      <el-form :model="fieldOptionForm" label-width="96px">
-        <el-form-item label="编号/ID" v-if="fieldOptionType !== 'constraint'" key="option-id">
-          <el-input v-model="fieldOptionForm.id" clearable />
-        </el-form-item>
-        <el-form-item label="名称" v-if="fieldOptionType !== 'property'" key="option-name">
-          <el-input v-model="fieldOptionForm.name" clearable />
-        </el-form-item>
-        <el-form-item label="配置" v-if="fieldOptionType === 'constraint'" key="option-config">
-          <el-input v-model="fieldOptionForm.config" clearable />
-        </el-form-item>
-        <el-form-item label="值" v-if="fieldOptionType === 'property'" key="option-value">
-          <el-input v-model="fieldOptionForm.value" clearable />
-        </el-form-item>
-      </el-form>
-      <template #footer>
-        <el-button @click="fieldOptionModelVisible = false">取 消</el-button>
-        <el-button type="primary" @click="saveFieldOption">确 定</el-button>
-      </template>
-    </el-dialog>
+    <!--    <el-dialog-->
+    <!--      v-model="fieldOptionModelVisible"-->
+    <!--      :title="optionModelTitle"-->
+    <!--      width="600px"-->
+    <!--      append-to-body-->
+    <!--      destroy-on-close-->
+    <!--    >-->
+    <!--      <el-form :model="fieldOptionForm" label-width="96px">-->
+    <!--        <el-form-item label="编号/ID" v-if="fieldOptionType !== 'constraint'" key="option-id">-->
+    <!--          <el-input v-model="fieldOptionForm.id" clearable />-->
+    <!--        </el-form-item>-->
+    <!--        <el-form-item label="名称" v-if="fieldOptionType !== 'property'" key="option-name">-->
+    <!--          <el-input v-model="fieldOptionForm.name" clearable />-->
+    <!--        </el-form-item>-->
+    <!--        <el-form-item label="配置" v-if="fieldOptionType === 'constraint'" key="option-config">-->
+    <!--          <el-input v-model="fieldOptionForm.config" clearable />-->
+    <!--        </el-form-item>-->
+    <!--        <el-form-item label="值" v-if="fieldOptionType === 'property'" key="option-value">-->
+    <!--          <el-input v-model="fieldOptionForm.value" clearable />-->
+    <!--        </el-form-item>-->
+    <!--      </el-form>-->
+    <!--      <template #footer>-->
+    <!--        <el-button @click="fieldOptionModelVisible = false">取 消</el-button>-->
+    <!--        <el-button type="primary" @click="saveFieldOption">确 定</el-button>-->
+    <!--      </template>-->
+    <!--    </el-dialog>-->
   </div>
 </template>
 
 <script lang="ts" setup>
+import * as FormApi from '@/api/bpm/form'
+
 defineOptions({ name: 'ElementForm' })
 
 const props = defineProps({
@@ -263,6 +268,9 @@ const bpmnInstances = () => (window as any)?.bpmnInstances
 const resetFormList = () => {
   bpmnELement.value = bpmnInstances().bpmnElement
   formKey.value = bpmnELement.value.businessObject.formKey
+  if (formKey.value?.length > 0) {
+    formKey.value = parseInt(formKey.value)
+  }
   // 获取元素扩展属性 或者 创建扩展属性
   elExtensionElements.value =
     bpmnELement.value.businessObject.get('extensionElements') ||
@@ -451,6 +459,11 @@ const updateElementExtensions = () => {
   })
 }
 
+const formList = ref([]) // 流程表单的下拉框的数据
+onMounted(async () => {
+  formList.value = await FormApi.getSimpleFormList()
+})
+
 watch(
   () => props.id,
   (val) => {

+ 8 - 5
src/utils/formCreate.ts

@@ -28,7 +28,7 @@ export const decodeFields = (fields: string[]) => {
   return rule
 }
 
-// 设置表单的 Conf 和 Fields
+// 设置表单的 Conf 和 Fields,适用 FcDesigner 场景
 export const setConfAndFields = (designerRef: object, conf: string, fields: string) => {
   // @ts-ignore
   designerRef.value.setOption(JSON.parse(conf))
@@ -36,19 +36,22 @@ export const setConfAndFields = (designerRef: object, conf: string, fields: stri
   designerRef.value.setRule(decodeFields(fields))
 }
 
-// 设置表单的 Conf 和 Fields
+// 设置表单的 Conf 和 Fields,适用 form-create 场景
 export const setConfAndFields2 = (
   detailPreview: object,
   conf: string,
   fields: string,
   value?: object
 ) => {
+  if (isRef(detailPreview)) {
+    detailPreview = detailPreview.value
+  }
   // @ts-ignore
-  detailPreview.value.option = JSON.parse(conf)
+  detailPreview.option = JSON.parse(conf)
   // @ts-ignore
-  detailPreview.value.rule = decodeFields(fields)
+  detailPreview.rule = decodeFields(fields)
   if (value) {
     // @ts-ignore
-    detailPreview.value.value = value
+    detailPreview.value = value
   }
 }

+ 2 - 3
src/views/bpm/model/ModelForm.vue

@@ -194,11 +194,10 @@ const submitForm = async () => {
       await ModelApi.createModel(data)
       // 提示,引导用户做后续的操作
       await ElMessageBox.alert(
-        '<strong>新建模型成功!</strong>后续需要执行如下 4 个步骤:' +
+        '<strong>新建模型成功!</strong>后续需要执行如下 3 个步骤:' +
           '<div>1. 点击【修改流程】按钮,配置流程的分类、表单信息</div>' +
           '<div>2. 点击【设计流程】按钮,绘制流程图</div>' +
-          '<div>3. 点击【分配规则】按钮,设置每个用户任务的审批人</div>' +
-          '<div>4. 点击【发布流程】按钮,完成流程的最终发布</div>' +
+          '<div>3. 点击【发布流程】按钮,完成流程的最终发布</div>' +
           '另外,每次流程修改后,都需要点击【发布流程】按钮,才能正式生效!!!',
         '重要提示',
         {

+ 51 - 4
src/views/bpm/processInstance/detail/index.vue

@@ -21,9 +21,22 @@
             {{ processInstance.name }}
           </el-form-item>
           <el-form-item v-if="processInstance && processInstance.startUser" label="流程发起人">
-            {{ processInstance.startUser.nickname }}
-            <el-tag size="small" type="info">{{ processInstance.startUser.deptName }}</el-tag>
+            {{ processInstance?.startUser.nickname }}
+            <el-tag size="small" type="info">{{ processInstance?.startUser.deptName }}</el-tag>
           </el-form-item>
+          <el-card class="mb-15px !-mt-10px" v-if="runningTasks[index].formId > 0">
+            <template #header>
+              <span class="el-icon-picture-outline">
+                填写表单【{{ runningTasks[index]?.formName }}】
+              </span>
+            </template>
+            <form-create
+              v-model:api="approveFormFApis[index]"
+              v-model="approveForms[index].value"
+              :option="approveForms[index].option"
+              :rule="approveForms[index].rule"
+            />
+          </el-card>
           <el-form-item label="审批建议" prop="reason">
             <el-input
               v-model="auditForms[index].reason"
@@ -149,6 +162,9 @@ const auditForms = ref<any[]>([]) // 审批任务的表单
 const auditRule = reactive({
   reason: [{ required: true, message: '审批建议不能为空', trigger: 'blur' }]
 })
+const approveForms = ref<any[]>([]) // 审批通过时,额外的补充信息
+const approveFormFApis = ref<ApiAttrs[]>([]) // approveForms 的 fAPi
+
 // ========== 申请信息 ==========
 const fApi = ref<ApiAttrs>() //
 const detailForm = ref({
@@ -158,6 +174,20 @@ const detailForm = ref({
   value: {}
 })
 
+/** 监听 approveFormFApis,实现它对应的 form-create 初始化后,隐藏掉对应的表单提交按钮 */
+watch(
+  () => approveFormFApis.value,
+  (value) => {
+    value?.forEach((api) => {
+      api.btn.show(false)
+      api.resetBtn.show(false)
+    })
+  },
+  {
+    deep: true
+  }
+)
+
 /** 处理审批通过和不通过的操作 */
 const handleAudit = async (task, pass) => {
   // 1.1 获得对应表单
@@ -176,6 +206,12 @@ const handleAudit = async (task, pass) => {
     copyUserIds: auditForms.value[index].copyUserIds
   }
   if (pass) {
+    // 审批通过,并且有额外的 approveForm 表单,需要校验 + 拼接到 data 表单里提交
+    const formCreateApi = approveFormFApis.value[index]
+    if (formCreateApi) {
+      await formCreateApi.validate()
+      data.variables = approveForms.value[index].value
+    }
     await TaskApi.approveTask(data)
     message.success('审批通过成功')
   } else {
@@ -258,6 +294,10 @@ const getProcessInstance = async () => {
 
 /** 加载任务列表 */
 const getTaskList = async () => {
+  runningTasks.value = []
+  auditForms.value = []
+  approveForms.value = []
+  approveFormFApis.value = []
   try {
     // 获得未取消的任务
     tasksLoad.value = true
@@ -285,8 +325,6 @@ const getTaskList = async () => {
     })
 
     // 获得需要自己审批的任务
-    runningTasks.value = []
-    auditForms.value = []
     loadRunningTask(tasks.value)
   } finally {
     tasksLoad.value = false
@@ -315,6 +353,15 @@ const loadRunningTask = (tasks) => {
       reason: '',
       copyUserIds: []
     })
+
+    // 2.4 处理 approve 表单
+    if (task.formId && task.formConf) {
+      const approveForm = {}
+      setConfAndFields2(approveForm, task.formConf, task.formFields, task.formVariable)
+      approveForms.value.push(approveForm)
+    } else {
+      approveForms.value.push({}) // 占位,避免为空
+    }
   })
 }