| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999 |
- <template>
- <page-meta root-font-size="system" />
- <view class="process_detail_container">
- <!-- 动态表单组件区域(包含表单、重复表、签名等所有表单相关内容) -->
- <view class="dynamic-form-section">
- <!-- 采购流程表单 -->
- <purchase-form
- v-if="formComponentName === 'purchase-form'"
- ref="dynamicFormRef"
- :formData="{...formData, ...purchaseData}"
- :formElements="formElements"
- :repeatingForm="repeatingForm"
- :is-initiate="flowInfo.seModel == '1'"
- :editable-fields="editableFields"
- :current-tache-opinion="currentTacheOpinion"
- @update="handleFormUpdate"
- @signature-change="handleSignatureChange" />
-
- <!-- 合同流程表单 -->
- <contract-form
- v-else-if="formComponentName === 'contract-form'"
- ref="dynamicFormRef"
- :formData="{...formData, ...contractData}"
- :formElements="formElements"
- :repeatingForm="repeatingForm"
- :is-initiate="flowInfo.seModel == '1'"
- :editable-fields="editableFields"
- :current-tache-opinion="currentTacheOpinion"
- @update="handleFormUpdate"
- @signature-change="handleSignatureChange" />
-
- <!-- 付款流程表单 -->
- <payment-form
- v-else-if="formComponentName === 'payment-form'"
- ref="dynamicFormRef"
- :formData="{...formData, ...paymentData}"
- :formElements="formElements"
- :repeatingForm="repeatingForm"
- :is-initiate="flowInfo.seModel == '1'"
- :editable-fields="editableFields"
- :current-tache-opinion="currentTacheOpinion"
- @update="handleFormUpdate"
- @signature-change="handleSignatureChange" />
-
- <!-- 默认表单 -->
- <default-form
- v-else
- ref="dynamicFormRef"
- :formData="formData"
- :formElements="formElements"
- :repeatingForm="repeatingForm"
- @update="handleFormUpdate" />
- </view>
-
- <!-- 已有附件列表 -->
- <view v-for="(item, index) in fileList" :key="index">
- <uni-card v-if="item.files && item.files.length > 0">
- <uni-section titleFontSize="1.3rem" title="附件" type="line"></uni-section>
- <attachment-list
- @clickDelete="deleteFile"
- :canEdit="flowInfo.seModel == '1'"
- :attachments="item.files">
- </attachment-list>
- </uni-card>
- </view>
-
- <!-- 上传附件(审批时) -->
- <view v-if="processInfo.tinsId || flowInfo.seModel == '1'" class="file_picker_container">
- <uni-card title="上传附件" :extra="`${subFileList.length}/50`" spacing="0">
- <uni-file-picker
- ref="filePicker"
- v-model="subFileList"
- :auto-upload="true"
- mode="list"
- :limit="50"
- file-mediatype="all"
- @select="handleFileSelect"
- @progress="handleFileProgress"
- @success="handleFileSuccess"
- @fail="handleFileFail"
- @delete="handleFileDelete" />
- </uni-card>
- </view>
-
- <!-- 流转过程 -->
- <uni-card>
- <view class="flow_step_container">
- <uni-section titleFontSize="1.3rem" title="流转过程" type="line"></uni-section>
- <up-steps :current="stepActive" activeColor="#18bc37" inactiveColor="#2979ff" direction="column">
- <view v-for="(step, index) in options" :key="index">
- <up-steps-item
- :contentClass="'redcontent'"
- v-if="step.state == 3"
- :title="step.title + ' 退回'"
- :desc="step.desc"
- error></up-steps-item>
- <up-steps-item
- :contentClass="'redcontent'"
- v-else-if="step.state == 0"
- :title="step.title + ' 撤销'"
- :desc="step.desc"
- error></up-steps-item>
- <up-steps-item
- v-else-if="index == stepActive"
- :title="step.title"
- :desc="step.desc">
- <template #icon>
- <view class="active_step_circle">
- <text class="active_step_text">{{ index + 1 }}</text>
- </view>
- </template>
- </up-steps-item>
- <up-steps-item
- v-else
- :title="step.title"
- :desc="step.desc"></up-steps-item>
- </view>
- </up-steps>
- </view>
- </uni-card>
-
- <!-- 环节备注 -->
- <view v-if="processInfo.tinsId">
- <uni-card>
- <uni-section titleFontSize="1.3rem" title="环节备注" type="line"></uni-section>
- <view class="remark_content">
- <uni-easyinput
- type="textarea"
- autoHeight
- v-model="remark"
- placeholder="请输入" />
- </view>
- </uni-card>
- </view>
-
- <!-- 通过按钮 -->
- <view v-if="processInfo.tinsId" class="approve_button">
- <uni-card spacing="0" padding="0">
- <button
- :disabled="!button_state"
- :loading="!button_state"
- type="primary"
- @click="handleSubmitProcess('1')">
- {{ flowInfo.seModel == '0' ? '通过' : '提交' }}
- </button>
- </uni-card>
- </view>
-
- <!-- 退回按钮组 -->
- <view v-if="processInfo.tinsId && flowInfo.seModel == '0'">
- <view class="reject_button">
- <uni-card spacing="0" padding="0" :is-shadow="false" :border="false">
- <uni-row>
- <uni-col :span="11">
- <button
- :disabled="!button_state"
- :loading="!button_state"
- type="warn"
- @click="handleSubmitProcess('0')">
- 退回上一级
- </button>
- </uni-col>
- <uni-col :span="11" :offset="2">
- <button
- :disabled="!button_state"
- :loading="!button_state"
- type="warn"
- @click="handleSubmitProcess('2')">
- 退回发起人
- </button>
- </uni-col>
- </uni-row>
- </uni-card>
- </view>
- </view>
-
- <!-- 撤销区域(查看页面专用) -->
- <view v-if="!processInfo.tinsId && isCancel">
- <view class="remark_container">
- <uni-card>
- <uni-section titleFontSize="1.3rem" title="撤销备注" type="line"></uni-section>
- <view class="remark_content">
- <uni-easyinput
- type="textarea"
- autoHeight
- v-model="remark"
- placeholder="请输入"
- placeholderStyle="font-size: calc(14px + 1.2*(1rem - 16px))"></uni-easyinput>
- </view>
- </uni-card>
- </view>
- <view class="cancel_button_container">
- <uni-card spacing="0" padding="0">
- <button
- :disabled="!button_state"
- :loading="!button_state"
- type="warn"
- @click="handleCancelProcess">
- 撤销
- </button>
- </uni-card>
- </view>
- </view>
- </view>
- </template>
- <script setup lang="ts">
- import { computed, onMounted, reactive, ref, nextTick } from 'vue'
- import { onLoad, onShow } from '@dcloudio/uni-app'
- import attachmentList from '@/components/ygoa/attachmentList.vue'
- import purchaseForm from '@/components/processForms/purchase-form.vue'
- import contractForm from '@/components/processForms/contract-form.vue'
- import paymentForm from '@/components/processForms/payment-form.vue'
- import defaultForm from '@/components/processForms/default-form.vue'
- import config from '@/config.js'
- import $modal from '@/plugins/modal.js'
- import $tab from '@/plugins/tab.js'
- import {
- getProcessFlowInfo,
- getProcessFormInfoInFlow,
- getProcessFormInfo, // 新增:没有 tinsId 时使用
- getProcessFlow,
- uploadFile,
- commonProcessApproval,
- cancelProcessFlow // 新增:撤销流程
- } from '@/api/process.js'
- import { useUserStore } from '@/store/user.js'
- import { keepSession } from '@/api/login.js'
- import { getPurchaseFormData, getPurchaseDataByInsId } from '@/api/purchase.js'
- import { getContractFormData, getContractDataByInsId } from '@/api/contract.js'
- import { getPaymentFormData, getPaymentDataByInsId } from '@/api/payment.js'
- const userStore = useUserStore()
- // 页面参数
- const processInfo = reactive({
- insId: '',
- insName: '',
- control: '1',
- username: '',
- reqOffice: 0, // 是否需要附件:0-不需要,1-需要
- reqRemark: 0, // 是否需要备注:0-不需要,1-需要
- tinsId: undefined as any,
- modelId: ''
- })
- onLoad((options) => {
- processInfo.insId = options.insId || ''
- // 注意:options.insName 可能是字符串 "undefined",需要特殊处理
- if (options.insName && options.insName !== 'undefined' && options.insName !== 'null') {
- processInfo.insName = options.insName
- }
- processInfo.control = options.control || '1'
- processInfo.modelId = options.modelId || ''
- if (options.tinsId) {
- processInfo.tinsId = options.tinsId
- }
- const title = processInfo.insName || '流程信息';
- // 设置导航栏标题
- uni.setNavigationBarTitle({
- title: title
- });
- })
- // 动态表单组件名称
- const formComponentName = computed(() => {
- // 根据 modelId 映射到对应的组件
- const componentMap: Record<string, string> = {
- '200001': 'purchase-form', // 采购流程表单组件
- '200002': 'contract-form', // 合同流程表单组件
- '200003': 'payment-form', // 付款流程表单组件
- // 后续添加更多映射
- }
- return componentMap[processInfo.modelId] || 'default-form'
- })
- // 表单数据(传递给自定义组件)
- const formData = ref<any>({}) // BPM 流程表单数据
- const purchaseData = ref<any>({}) // 采购单业务数据
- const contractData = ref<any>({}) // 合同业务数据
- const paymentData = ref<any>({}) // 付款申请业务数据
- const formElements = ref<any[]>([])
- const repeatingForm = ref<any>({ elementItem: [], elements: [] })
- const fileList = ref<any[]>([]) // 已有附件列表
- const dynamicFormRef = ref(null)
- const isCancel = ref(false) // 是否可撤销
- // 采购流程专用字段
- const editableFields = ref<string[]>([]) // 当前环节可编辑的字段列表
- const currentTacheOpinion = ref<any>(null) // 当前环节的审批意见配置
- const signatureData = ref<string>('') // 签名图片 base64
- // 上传附件相关
- const subFileList = ref<any[]>([]) // 新上传的附件
- const filePicker = ref(null)
- // 流转过程相关
- const flowInfo = ref<any>({
- seModel: '0' // 0-审批模式,1-办理模式
- })
- const stepActive = ref(0)
- const options = ref<any[]>([])
- // 环节备注
- const remark = ref('')
- // 按钮状态
- const button_state = ref(true)
- // 获取流程详情
- async function loadProcessDetail() {
- try {
- // 判断是否有 tinsId,选择不同的接口
- if (processInfo.tinsId) {
- // ✅ 有待办环节:调用 getProcessFormInfoInFlow(审批场景)
- const formRes = await getProcessFormInfoInFlow(userStore.user.useId, {
- tinsId: processInfo.tinsId,
- insId: processInfo.insId,
- control: processInfo.control
- })
-
- if (formRes.returnCode === '0' || formRes.returnCode === '1') {
- const formInfo = formRes.returnParams
-
- formElements.value = formInfo.formElements || []
- repeatingForm.value = formInfo.repeatingForm || { elementItem: [], elements: [] }
- formData.value = formInfo
- // 判断是否可撤销
- if (formInfo.isCancel == 1) {
- isCancel.value = true
- }
-
- // 处理附件列表 - 从后端接口获取(如果有)
- if (formInfo.fileList) {
- fileList.value = formInfo.fileList
- }
-
- // 从 formElements 中提取可编辑字段列表 (canEdit == '1')
-
- editableFields.value = formElements.value
- .filter(elem => elem.canEdit == '1')
- .map(elem => elem.tableField)
-
- }
-
- // 获取流转信息(必须在 loadPurchaseFormData 之前调用,因为需要 flowInfo 数据)
- await loadFlowSteps()
- await loadFlowInfo()
- } else {
- const formRes = await getProcessFormInfo(userStore.user.useId, processInfo.insId)
-
- if (formRes.returnCode === '0' || formRes.returnCode === '1') {
- const formInfo = formRes.returnParams
- formElements.value = formInfo.formElements || []
- repeatingForm.value = formInfo.repeatingForm || { elementItem: [], elements: [] }
- formData.value = formInfo
- // 判断是否可撤销
- if (formInfo.isCancel == 1) {
- isCancel.value = true
- }
-
- // 处理附件列表
- if (formInfo.fileList) {
- fileList.value = formInfo.fileList
- }
-
- editableFields.value = []
-
- }
-
- // 获取流转信息(不需要 tinsId 的版本)
- await loadFlowSteps()
- }
-
- // 如果是采购流程、合同流程或付款流程,额外加载业务数据(需要在 flowInfo 加载完成后才能获取 table_fields)
- if (processInfo.modelId === '200001') {
- await loadPurchaseFormData()
- } else if (processInfo.modelId === '200002') {
- await loadContractFormData()
- } else if (processInfo.modelId === '200003') {
- await loadPaymentFormData()
- }
- } catch (error) {
- console.error('加载流程详情失败:', error)
- $modal.msgError('加载失败')
- }
- }
- // 加载流转步骤
- async function loadFlowSteps() {
- try {
- const flowRes = await getProcessFlow(userStore.user.useId, {
- insId: processInfo.insId,
- control: processInfo.control
- })
-
- if (flowRes.returnCode === '1' || flowRes.returnCode === '0') {
- const flowList = flowRes.returnParams.list || []
-
- options.value = flowList.map((item: any, index: number) => {
- const { tmodelName, name, createdate, finishdate, remark, state, task, groupName, positionName } = item
- if (state == 1) {
- stepActive.value = index
- }
- const title = tmodelName + (name == '' ? '' : ' ( ' + name + ' ' + groupName + '-' + positionName + ' )')
- let desc = '创建时间:' + createdate
- + (finishdate == '' ? '\n' : '\n办理时间:' + finishdate)
- + (remark == '' ? '\n' : '\n环节意见:' + remark)
- if (task && task.length > 0) {
- desc += '\n抄送信息'
- task.forEach((taskitem: any) => {
- desc += `\n抄送对象:(${taskitem.username})抄送时间:${taskitem.createdate}`
- })
- }
- return {
- title,
- desc,
- state
- }
- })
- if (stepActive.value === -1) {
- stepActive.value = flowList.length
- }
- }
- } catch (error) {
- console.error('加载流转信息失败:', error)
- }
- }
- // 加载采购单数据(用于审批页面展示)
- async function loadPurchaseFormData() {
- try {
- // 优先使用 flowInfo 中的 formInsId
- let formInsId = flowInfo.value.formInsId || ''
-
- if (!formInsId) {
- // 如果 flowInfo 中没有,尝试从 formData 中获取
- formInsId = formData.value.formInsId || formData.value.universalid || ''
- }
-
- if (formInsId) {
- // ✅ 有 formInsId:调用 getPurchaseFormData
- const res = await getPurchaseFormData(userStore.user.useId, formInsId)
-
- if (res.returnCode === '1') {
- const purchaseDataRes = res.returnParams
-
- // 将采购单数据单独存储
- purchaseData.value = purchaseDataRes
-
- // 保存当前环节的审批意见配置
- currentTacheOpinion.value = flowInfo.value.tmodel
- }
- } else if (processInfo.insId && !processInfo.tinsId) {
- const res = await getPurchaseDataByInsId(userStore.user.useId, processInfo.insId)
-
- if (res.returnCode === '1') {
- const purchaseDataRes = res.returnParams
-
- // 将采购单数据单独存储
- purchaseData.value = purchaseDataRes
-
- // 注意:查看场景没有 table_fields,所以不设置 editableFields
- editableFields.value = [] // 查看场景不可编辑
- currentTacheOpinion.value = null
- }
- } else {
- console.warn('缺少 formInsId 和 insId,无法加载采购单数据')
- }
- } catch (error) {
- console.error('加载采购单数据失败:', error)
- }
- }
- // 加载合同数据(用于审批页面展示)
- async function loadContractFormData() {
- try {
- // 优先使用 flowInfo 中的 formInsId
- let formInsId = flowInfo.value.formInsId || ''
-
- if (!formInsId) {
- // 如果 flowInfo 中没有,尝试从 formData 中获取
- formInsId = formData.value.formInsId || formData.value.universalid || ''
- }
-
- if (formInsId) {
- // ✅ 有 formInsId:调用 getContractFormData
- const res = await getContractFormData(userStore.user.useId, formInsId)
-
- if (res.returnCode === '1') {
- const contractDataRes = res.returnParams
-
- // 将合同数据单独存储
- contractData.value = contractDataRes
-
- // 保存当前环节的审批意见配置
- currentTacheOpinion.value = flowInfo.value.tmodel
- }
- } else if (processInfo.insId && !processInfo.tinsId) {
- // TODO: 如果需要查看页面,调用 getContractDataByInsId
- const res = await getContractDataByInsId(userStore.user.useId, processInfo.insId)
-
- if (res.returnCode === '1') {
- const contractDataRes = res.returnParams
-
- // 将合同数据单独存储
- contractData.value = contractDataRes
-
- // 注意:查看场景没有 table_fields,所以不设置 editableFields
- editableFields.value = [] // 查看场景不可编辑
- currentTacheOpinion.value = null
- }
- } else {
- console.warn('缺少 formInsId 和 insId,无法加载合同数据')
- }
- } catch (error) {
- console.error('加载合同数据失败:', error)
- }
- }
- // 加载付款申请数据(用于审批页面展示)
- async function loadPaymentFormData() {
- try {
- // 优先使用 flowInfo 中的 formInsId
- let formInsId = flowInfo.value.formInsId || ''
-
- if (!formInsId) {
- // 如果 flowInfo 中没有,尝试从 formData 中获取
- formInsId = formData.value.formInsId || formData.value.universalid || ''
- }
-
- if (formInsId) {
- // ✅ 有 formInsId:调用 getPaymentFormData
- const res = await getPaymentFormData(userStore.user.useId, formInsId)
-
- if (res.returnCode === '1') {
- const paymentDataRes = res.returnParams
-
- // 将付款申请数据单独存储
- paymentData.value = paymentDataRes
-
- // 保存当前环节的审批意见配置
- currentTacheOpinion.value = flowInfo.value.tmodel
- }
- } else if (processInfo.insId && !processInfo.tinsId) {
- // 查看场景:调用 getPaymentDataByInsId
- const res = await getPaymentDataByInsId(userStore.user.useId, processInfo.insId)
-
- if (res.returnCode === '1') {
- const paymentDataRes = res.returnParams
-
- // 将付款申请数据单独存储
- paymentData.value = paymentDataRes
-
- // 注意:查看场景没有 table_fields,所以不设置 editableFields
- editableFields.value = [] // 查看场景不可编辑
- currentTacheOpinion.value = null
- }
- } else {
- console.warn('缺少 formInsId 和 insId,无法加载付款申请数据')
- }
- } catch (error) {
- console.error('加载付款申请数据失败:', error)
- }
- }
- // 获取流程控制信息
- async function loadFlowInfo() {
- try {
- const flowInfoRes = await getProcessFlowInfo(userStore.user.useId, {
- tinsId: processInfo.tinsId,
- control: processInfo.control
- })
-
- if (flowInfoRes.returnCode === '1' || flowInfoRes.returnCode === '0') {
- const params = flowInfoRes.returnParams
-
- if (params.flow && params.flow.length > 0) {
- flowInfo.value = params.flow[0]
-
- // 设置附件列表(从流转信息中获取)
- if (params.flow[0].files && params.flow[0].files.length > 0) {
- const newFileList = [{ files: params.flow[0].files }]
-
- // 使用 splice 清空再 push,确保响应式更新
- fileList.value.splice(0, fileList.value.length)
- newFileList.forEach(item => fileList.value.push(item))
- }
-
- // 添加下一环节到流转步骤
- if (params.nextTmodels && params.nextTmodels.length > 0) {
- options.value.push({
- title: params.nextTmodels[0].nextTmodelName,
- desc: '',
- state: -1
- })
- }
-
- // 保存其他必要信息
- processInfo.reqOffice = params.tmodel?.reqOffice || 0
- processInfo.reqRemark = params.tmodel?.reqRemark || 0
- }
- }
- } catch (error) {
- console.error('加载流程控制信息失败:', error)
- }
- }
- // 表单更新回调
- function handleFormUpdate(data: any) {
- // 只更新 BPM 流程表单数据,不影响采购单数据
- formData.value = data
- }
- // 处理签名变化
- function handleSignatureChange(signatureBase64: string) {
- signatureData.value = signatureBase64
- }
- // 文件上传相关
- async function handleFileSelect(files: any) {
- files.tempFiles.forEach((file: any) => {
- const data = {
- name: file.name,
- filePath: file.path,
- }
- uploadFile(data)
- .then(res => {
- file.seq = res.returnParams
- subFileList.value.push({ seq: res.returnParams, path: file.path })
- $modal.msgSuccess('文件' + data.name + '上传成功')
- })
- .catch(err => {
- $modal.msgError('文件' + data.name + '上传失败,请删除重新上传')
- })
- })
- }
- function handleFileProgress(file: any, progress: any) {}
- function handleFileSuccess(file: any, res: any) {}
- function handleFileFail(file: any, err: any) {}
- function handleFileDelete(file: any) {
- const index = subFileList.value.findIndex(({ path }) => path == file.tempFilePath)
- if (index !== -1) {
- subFileList.value.splice(index, 1)
- }
- }
- // 删除已有附件
- function deleteFile(file: any) {
- // TODO: 调用删除附件接口
- $modal.msgSuccess('删除成功')
- }
- // 提交审批
- function handleSubmitProcess(result) {
- let content = '确认退回'
- if (result == "1") {
- content = '确认通过'
- }
-
- $modal.confirm(content).then(() => {
- // 如果是退回操作且备注为"同意",则清空备注
- if ((result == '0' || result == '2') && remark.value == '同意') {
- remark.value = ''
- }
- button_state.value = false
- if (result == "1") {
- submitProcess(result)
- } else {
- submitProcess(result)
- }
- }).catch((err) => {
- console.log('用户取消操作', err)
- })
- }
- function submitProcess(result) {
- let flow = Object.assign({}, flowInfo.value)
- flow['staffId'] = userStore.user.useId
- flow['gxId'] = userStore.user.gxId
- flow['groupId'] = flowInfo.value.groupid
- if (result == "1") {
- const seqs = subFileList.value.map(({ seq }) => seq)
- if (flowInfo.value.seModel == '0' && processInfo.reqOffice == 1 && seqs.length == 0) {
- button_state.value = true
- $modal.msgError('请上传附件')
- return
- } else {
- flow['fileIds'] = seqs
- }
- if (processInfo.reqRemark == 1 && remark.value == '') {
- button_state.value = true
- $modal.msgError('请填写备注')
- return
- }
- } else {
- flow.fileIds = []
- flow.files = []
- }
- flow['remark'] = remark.value
- // result: 1 通过 2 退回发起人 0 退回上一级
- flow['result'] = result
- flow['nextTmodelId'] = 'undefined'
-
- // 构建 form 参数
- const form = {
- formId: flowInfo.value.formId || '',
- formInsId: '', // 稍后根据 modelId 设置
- formElements: formElements.value
- }
-
- // 根据不同的 modelId,从对应的业务数据中获取 formInsId
- if (processInfo.modelId === '200001') {
- // 采购流程:从 purchaseData 获取
- form.formInsId = purchaseData.value.lFormInsId || purchaseData.value.universalid || ''
- } else if (processInfo.modelId === '200002') {
- // 合同流程:从 contractData 获取
- form.formInsId = contractData.value.lFormInsId || contractData.value.universalid || ''
- } else if (processInfo.modelId === '200003') {
- // 付款流程:从 paymentData 获取
- form.formInsId = paymentData.value.lFormInsId || paymentData.value.universalid || ''
- } else {
- // 其他流程:从 formData 获取
- form.formInsId = formData.value.formInsId || formData.value.universalid || ''
- }
-
- // 如果是采购流程、合同流程或付款流程,需要特殊处理
- if ((processInfo.modelId === '200001' || processInfo.modelId === '200002' || processInfo.modelId === '200003') && dynamicFormRef.value) {
- // 只有“通过”操作才需要验证表单,退回不需要
- if (result == "1") {
- // 调用表单组件的 validate 方法进行验证
- dynamicFormRef.value.validate()
- .then(() => {
- // 从 formElements 中提取可编辑字段的 tableField
- // table_fields 应该只包含当前环节可编辑的字段 (canEdit == '1')
- const tableFieldsList = formElements.value
- .filter(elem => elem.canEdit == '1') // ✅ 只提取可编辑字段
- .map(elem => elem.tableField)
- .filter(f => f) // 过滤掉空值
- const tableFieldsStr = ',' + tableFieldsList.join(',') + ','
-
- // 验证通过,获取表单数据(包含审批意见和印章)
- const businessFormData = dynamicFormRef.value.getFormData()
-
- // 添加 table_fields 字段,后端需要它来判断哪些审批意见字段需要处理
- businessFormData.table_fields = tableFieldsStr
-
- // 直接将 businessFormData 转换为 formElements 格式
- const businessFormElements = []
- Object.keys(businessFormData).forEach(key => {
- // 跳过不需要提交的字段
- if (key !== 'details' && key !== 'detailList' && key !== 'contractMaterialList' && key !== 'contractPaymentList') {
- const value = businessFormData[key]
- businessFormElements.push({
- name: key,
- value: String(value),
- type: '0'
- })
- }
- })
-
- // 物料明细和付款明细需要转成 JSON 字符串
- if (businessFormData.detailList && Array.isArray(businessFormData.detailList)) {
- businessFormElements.push({
- name: 'detailList',
- value: JSON.stringify(businessFormData.detailList),
- type: '0'
- })
- }
- if (businessFormData.contractMaterialList && Array.isArray(businessFormData.contractMaterialList)) {
- businessFormElements.push({
- name: 'contractMaterialList',
- value: JSON.stringify(businessFormData.contractMaterialList),
- type: '0'
- })
- }
- if (businessFormData.contractPaymentList && Array.isArray(businessFormData.contractPaymentList)) {
- businessFormElements.push({
- name: 'contractPaymentList',
- value: JSON.stringify(businessFormData.contractPaymentList),
- type: '0'
- })
- }
-
- // 合并到 formElements 中
- form.formElements = [...formElements.value, ...businessFormElements]
-
- // 提交审批
- submitApproval(flow, form)
- })
- .catch(err => {
- console.error('表单验证失败:', err)
- button_state.value = true
- $modal.msgError(err.message || '表单验证失败')
- })
- } else {
- // 退回操作,不验证表单,直接提交
- submitApproval(flow, form)
- }
- } else {
- // 非采购/合同流程,直接提交
- submitApproval(flow, form)
- }
- }
- // 执行审批提交
- function submitApproval(flow, form) {
- // 调用通用审批接口
- commonProcessApproval(flow, form, processInfo.control).then(({ returnCode, returnMsg, returnParams }) => {
- if (returnMsg.includes('提交失败')) {
- // 启用提交按钮
- button_state.value = true
- $modal.msgError(returnMsg)
- } else {
- $modal.msgSuccess(returnMsg)
- // 通知列表刷新数据
- uni.$emit('ReloadProcessData');
- setTimeout(() => {
- $tab.navigateBack();
- }, 1000)
- }
- }).catch(error => {
- console.error('=== 接口调用失败 ===')
- console.error('错误信息:', error)
- button_state.value = true
- $modal.msgError('网络请求失败:' + (error.message || '未知错误'))
- })
- }
- // 取消流程
- function handleCancelProcess() {
- if (remark.value.trim() == '') {
- $modal.msgError('备注不能为空!')
- return
- }
- $modal.confirm('确认撤销').then(() => {
- cancelProcess()
- }).catch(() => { })
- }
- function cancelProcess() {
- cancelProcessFlow(userStore.user.useId, remark.value, processInfo).then(({ returnMsg }) => {
- if (returnMsg.includes('success')) {
- $modal.msgSuccess('撤销成功')
- // 通知列表刷新数据
- uni.$emit('ReloadProcessData');
- setTimeout(() => {
- $tab.navigateBack();
- }, 1000)
- } else {
- // 启用按钮
- button_state.value = true
- $modal.msgError(returnMsg)
- }
- })
- }
- // 保持会话
- onShow(() => {
- keepSession().catch(err => {
- console.error('保持会话失败:', err)
- })
- })
- onMounted(() => {
- loadProcessDetail()
- })
- </script>
- <style lang="scss" scoped>
- .process_detail_container {
- padding-bottom: 80px;
- }
- .dynamic-form-section {
- margin-top: 15px;
- }
- // 流转过程样式
- .flow_step_container {
- min-height: 100px;
-
- ::v-deep .u-steps {
- .u-steps-item {
- padding-bottom: 11px;
-
- .redcontent {
- .u-text__value--content {
- color: #ff4500;
- }
- }
-
- .active_step_circle {
- width: 20px;
- height: 20px;
- box-sizing: border-box;
- flex-shrink: 0;
- border-radius: 100px;
- border-width: 1px;
- border-color: #A78BFA;
- background-color: #A78BFA;
- border-style: solid;
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: center;
- transition: background-color .3s;
-
- .active_step_text {
- color: #fff;
- font-size: 0.6875rem;
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: center;
- text-align: center;
- line-height: 0.6875rem;
- }
- }
- }
- }
- }
- // 环节备注样式
- .remark_container {
- .remark_content {
- margin-top: 10px;
- }
- }
- // 审批按钮样式
- .approve_button {
- position: sticky;
- z-index: 10;
- width: 100%;
- bottom: 10px;
- margin-top: 15px;
-
- button {
- background-color: #007aff !important;
- color: #fff !important;
- }
- }
- // 退回按钮样式
- .reject_button {
- margin-top: 10px;
-
- button {
- font-size: calc(18px + .5*(1rem - 16px));
- }
- }
- // 附件上传容器
- .file_picker_container {
- margin-top: 15px;
-
- ::v-deep .uni-card {
- .uni-card__header-content-title {
- font-size: calc(15px + .5*(1rem - 16px));
- font-weight: 700;
- }
-
- .uni-card__header-extra-text {
- font-size: calc(15px + .5*(1rem - 16px));
- }
- }
- }
- // 基本信息中的禁用字段样式优化
- ::v-deep .uni-forms {
- .uni-forms-item__content {
- .uni-easyinput__content-input {
- font-size: calc(14px + 1.2*(1rem - 16px)) !important;
- font-weight: 500;
- color: #333;
- }
- .uni-date {
- .uni-icons {
- font-size: calc(22px + 1.2*(1rem - 16px)) !important;
- font-weight: 500;
- }
- .uni-date__x-input {
- height: auto;
- font-size: calc(14px + 1.2*(1rem - 16px)) !important;
- font-weight: 500;
- color: #333;
- }
- }
- }
- }
- </style>
|