liding
5 天以前 ace1b66fe094e791216f6c46f4bd628e1c23b2dd
src/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue
@@ -1,466 +1,295 @@
<template>
  <div>
    <el-dialog
        v-model="dialogFormVisible"
        :title="operationType === 'add' ? '新增审批流程' : '编辑审批流程'"
        width="50%"
        @close="closeDia"
    >
      <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
        <el-row>
          <el-col :span="24">
            <el-form-item label="流程编号:" prop="approveId">
              <el-input v-model="form.approveId" placeholder="自动编号" clearable disabled/>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <!-- 申请部门:校验使用部门ID,便于下拉选择后立即通过校验 -->
            <el-form-item label="申请部门:" prop="approveDeptId">
<!--              <el-input v-model="form.approveDeptName" placeholder="请输入" clearable/>-->
                     <el-select
                        v-model="form.approveDeptId"
                        placeholder="选择部门"
                @change="handleDeptChange"
                     >
                        <el-option
                           v-for="user in productOptions"
                           :key="user.deptId"
                           :label="user.deptName"
                           :value="user.deptId"
                        />
                     </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item :label="props.approveType == 5 ? '采购说明:' : '审批事由:'" prop="approveReason">
              <el-input v-model="form.approveReason" placeholder="请输入" clearable type="textarea" />
            </el-form-item>
          </el-col>
        </el-row>
        <!-- 请假时间(仅当 approveType 为 2 时显示) -->
        <el-row :gutter="30" v-if="props.approveType == 2">
          <el-col :span="12">
            <el-form-item label="请假开始时间:" prop="startDate">
              <el-date-picker
                  v-model="form.startDate"
                  type="date"
                  placeholder="请选择开始日期"
                  value-format="YYYY-MM-DD"
                  format="YYYY-MM-DD"
                  clearable
                  style="width: 100%"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="请假结束时间:" prop="endDate">
              <el-date-picker
                  v-model="form.endDate"
                  type="date"
                  placeholder="请选择结束日期"
                  value-format="YYYY-MM-DD"
                  format="YYYY-MM-DD"
                  clearable
                  style="width: 100%"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <!-- 报销金额(仅当 approveType 为 4 时显示) -->
        <el-row v-if="props.approveType == 4">
          <el-col :span="24">
            <el-form-item label="报销金额:" prop="price">
              <el-input-number
                  v-model="form.price"
                  placeholder="请输入报销金额"
                  :min="0"
                  :precision="2"
                  :step="0.01"
                  style="width: 100%"
                  clearable
              />
            </el-form-item>
          </el-col>
        </el-row>
        <!-- 出差地点(仅当 approveType 为 3 时显示) -->
        <el-row v-if="props.approveType == 3">
          <el-col :span="24">
            <el-form-item label="备注:" prop="location">
              <el-input
                  v-model="form.location"
                  placeholder="请输入备注"
                  clearable
              />
            </el-form-item>
          </el-col>
        </el-row>
        <!-- 审批人选择(动态节点) -->
        <el-row>
          <el-col :span="24">
            <el-form-item>
              <template #label>
                <span>审批人选择:</span>
                <el-button type="primary" @click="addApproverNode" style="margin-left: 8px;">新增节点</el-button>
              </template>
              <div style="display: flex; align-items: flex-end; flex-wrap: wrap;">
                <div
                  v-for="(node, index) in approverNodes"
                  :key="node.id"
                  style="margin-right: 30px; text-align: center; margin-bottom: 10px;"
                >
                  <div>
                    <span>审批人</span>
                    →
                  </div>
                  <el-select
                    v-model="node.userId"
                    placeholder="选择人员"
                    style="width: 120px; margin-bottom: 8px;"
                  >
                    <el-option
                      v-for="user in userList"
                      :key="user.userId"
                      :label="user.nickName"
                      :value="user.userId"
                    />
                  </el-select>
                  <div>
                    <el-button
                      type="danger"
                      size="small"
                      @click="removeApproverNode(index)"
                      v-if="approverNodes.length > 1"
                    >删除</el-button>
                  </div>
                </div>
              </div>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="申请人:" prop="approveUser">
                     <el-select
                        v-model="form.approveUser"
                        placeholder="选择人员"
                filterable
                default-first-option
                :reserve-keyword="false"
                     >
                        <el-option
                           v-for="user in userList"
                           :key="user.userId"
                           :label="user.nickName"
                           :value="user.userId"
                        />
                     </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="申请日期:" prop="approveTime">
              <el-date-picker
                  v-model="form.approveTime"
                  type="date"
                  placeholder="请选择日期"
                  value-format="YYYY-MM-DD"
                  format="YYYY-MM-DD"
                  clearable
                  style="width: 100%"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30">
          <el-col :span="24">
            <el-form-item label="附件材料:" prop="remark">
              <el-upload v-model:file-list="fileList" :action="upload.url" multiple ref="fileUpload" auto-upload
                         :headers="upload.headers" :before-upload="handleBeforeUpload" :on-error="handleUploadError"
                         :on-success="handleUploadSuccess" :on-remove="handleRemove">
                <el-button type="primary" v-if="operationType !== 'view'">上传</el-button>
                <template #tip v-if="operationType !== 'view'">
                  <div class="el-upload__tip">
                    文件格式支持
                    doc,docx,xls,xlsx,ppt,pptx,pdf,txt,xml,jpg,jpeg,png,gif,bmp,rar,zip,7z
                  </div>
                </template>
              </el-upload>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确认</el-button>
          <el-button @click="closeDia">取消</el-button>
        </div>
  <el-dialog v-model="visible" :title="operationType === 'add' ? `新增${typeName}` : `编辑${typeName}`" width="760px" @close="closeDialog">
    <el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
      <el-form-item label="流程编号">
        <el-input v-model="form.approveId" disabled placeholder="提交后自动生成" />
      </el-form-item>
      <el-form-item v-if="approveTypeNumber === 3" label="销售合同" prop="businessId">
        <el-select v-model="form.businessId" filterable placeholder="请选择销售合同" style="width: 100%" @change="handleContractChange">
          <el-option v-for="item in contractOptions" :key="item.id" :value="item.id"
                     :label="`${item.salesContractNo || '-'} / ${item.customerName || '-'} / ¥${item.contractAmount || 0}`" />
        </el-select>
      </el-form-item>
      <el-form-item v-if="approveTypeNumber === 3 && selectedContract" label="合同信息">
        <el-descriptions :column="2" border style="width: 100%">
          <el-descriptions-item label="客户">{{ selectedContract.customerName || '-' }}</el-descriptions-item>
          <el-descriptions-item label="项目">{{ selectedContract.projectName || '-' }}</el-descriptions-item>
          <el-descriptions-item label="业务员">{{ selectedContract.salesman || '-' }}</el-descriptions-item>
          <el-descriptions-item label="合同金额">¥{{ selectedContract.contractAmount || 0 }}</el-descriptions-item>
        </el-descriptions>
      </el-form-item>
      <el-form-item v-if="[1, 5].includes(approveTypeNumber)" label="审批标题" prop="businessTitle">
        <el-input v-model="form.businessTitle" maxlength="200" show-word-limit />
      </el-form-item>
      <template v-if="approveTypeNumber === 1">
        <el-form-item label="事项类型" prop="category">
          <el-select v-model="form.category" style="width: 100%">
            <el-option label="临时费用报销" value="临时费用报销" />
            <el-option label="部门协作" value="部门协作" />
            <el-option label="其他" value="其他" />
          </el-select>
        </el-form-item>
        <el-form-item label="涉及金额">
          <el-input-number v-model="form.amount" :min="0" :precision="2" style="width: 100%" />
        </el-form-item>
      </template>
    </el-dialog>
  </div>
      <template v-if="approveTypeNumber === 5">
        <el-row :gutter="16">
          <el-col :span="12">
            <el-form-item label="采购类别" prop="category"><el-input v-model="form.category" /></el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="紧急程度" prop="urgency">
              <el-select v-model="form.urgency" style="width: 100%">
                <el-option label="普通" value="普通" /><el-option label="紧急" value="紧急" /><el-option label="特急" value="特急" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="采购内容" prop="purchaseContent"><el-input v-model="form.purchaseContent" type="textarea" /></el-form-item>
        <el-row :gutter="16">
          <el-col :span="8"><el-form-item label="数量" prop="quantity"><el-input-number v-model="form.quantity" :min="0.01" :precision="2" style="width: 100%" /></el-form-item></el-col>
          <el-col :span="8"><el-form-item label="单位" prop="unit"><el-input v-model="form.unit" /></el-form-item></el-col>
          <el-col :span="8"><el-form-item label="预算金额" prop="amount"><el-input-number v-model="form.amount" :min="0.01" :precision="2" style="width: 100%" /></el-form-item></el-col>
        </el-row>
        <el-form-item label="期望到货日期" prop="expectedDate">
          <el-date-picker v-model="form.expectedDate" type="date" value-format="YYYY-MM-DD" style="width: 100%" />
        </el-form-item>
      </template>
      <el-row v-if="approveTypeNumber === 2" :gutter="16">
        <el-col :span="12"><el-form-item label="请假开始日期" prop="startDate"><el-date-picker v-model="form.startDate" type="date" value-format="YYYY-MM-DD" style="width: 100%" /></el-form-item></el-col>
        <el-col :span="12"><el-form-item label="请假结束日期" prop="endDate"><el-date-picker v-model="form.endDate" type="date" value-format="YYYY-MM-DD" style="width: 100%" /></el-form-item></el-col>
      </el-row>
      <el-form-item v-if="approveTypeNumber === 4" label="报销金额" prop="amount">
        <el-input-number v-model="form.amount" :min="0.01" :precision="2" style="width: 100%" />
      </el-form-item>
      <el-form-item label="申请事由" prop="approveReason">
        <el-input v-model="form.approveReason" type="textarea" :rows="3" maxlength="1000" show-word-limit />
      </el-form-item>
      <el-form-item label="申请部门" prop="approveDeptId">
        <el-select v-model="form.approveDeptId" style="width: 100%">
          <el-option v-for="dept in departmentOptions" :key="dept.deptId" :label="dept.deptName" :value="dept.deptId" />
        </el-select>
      </el-form-item>
      <el-form-item v-if="[3, 5].includes(approveTypeNumber) && flowOptions.length" label="预设审批流程">
        <el-select v-model="form.flowDefinitionId" clearable placeholder="请选择预设流程;留空可手动设置节点" style="width: 100%">
          <el-option v-for="flow in flowOptions" :key="flow.id" :label="flow.flowName" :value="flow.id" />
        </el-select>
      </el-form-item>
      <el-divider content-position="left">审批节点</el-divider>
      <el-alert v-if="form.flowDefinitionId && operationType === 'add'" title="提交后将按预设流程生成审批节点" type="info" :closable="false" style="margin-bottom: 12px" />
      <div v-for="(node, index) in approverNodes" v-show="!form.flowDefinitionId || operationType === 'edit'" :key="node.key" class="node-row">
        <span class="node-order">{{ index + 1 }}</span>
        <el-input v-model="node.nodeName" placeholder="节点名称" style="width: 150px" />
        <el-select v-model="node.userId" filterable placeholder="审批人" style="width: 150px">
          <el-option v-for="user in userList" :key="user.userId" :label="user.nickName" :value="user.userId" />
        </el-select>
        <el-select v-model="node.conditionOperator" style="width: 130px" @change="handleConditionChange(node)">
          <el-option label="始终执行" value="ALWAYS" />
          <el-option label="金额大于" value="GT" />
          <el-option label="金额大于等于" value="GTE" />
          <el-option label="金额小于" value="LT" />
          <el-option label="金额小于等于" value="LTE" />
        </el-select>
        <el-input-number v-if="node.conditionOperator !== 'ALWAYS'" v-model="node.conditionValue" :min="0" :precision="2" style="width: 130px" />
        <el-button type="danger" link :disabled="approverNodes.length === 1" @click="removeNode(index)">删除</el-button>
        <el-button link :disabled="index === 0" @click="moveNode(index, -1)">上移</el-button>
        <el-button link :disabled="index === approverNodes.length - 1" @click="moveNode(index, 1)">下移</el-button>
      </div>
      <el-button v-if="!form.flowDefinitionId || operationType === 'edit'" type="primary" plain class="add-node" @click="addNode">新增审批节点</el-button>
      <el-form-item label="申请日期">
        <el-date-picker v-model="form.approveTime" type="date" value-format="YYYY-MM-DD" style="width: 100%" />
      </el-form-item>
      <el-form-item label="附件材料">
        <el-upload v-model:file-list="fileList" :action="upload.url" :headers="upload.headers" multiple
                   :before-upload="beforeUpload" :on-success="uploadSuccess" :on-error="uploadError" :on-remove="removeFile">
          <el-button type="primary">上传文件</el-button>
        </el-upload>
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="closeDialog">取消</el-button>
      <el-button type="primary" :loading="submitting" @click="submit">提交</el-button>
    </template>
  </el-dialog>
</template>
<script setup>
import {ref, reactive, toRefs, getCurrentInstance} from "vue";
import {
  approveProcessAdd, approveProcessGetInfo,
  approveProcessUpdate,
  getDept
} from "@/api/collaborativeApproval/approvalProcess.js";
import {
  delLedgerFile,
} from "@/api/salesManagement/salesLedger.js";
import {userListNoPageByTenantId} from "@/api/system/user.js";
import { getToken } from "@/utils/auth";
const { proxy } = getCurrentInstance()
import { computed, getCurrentInstance, reactive, ref } from 'vue'
import { approveFlowDefinitionList, approveProcessAdd, approveProcessDetails, approveProcessGetInfo, approveProcessUpdate, getDept } from '@/api/collaborativeApproval/approvalProcess'
import { delLedgerFile, ledgerListNoPage } from '@/api/salesManagement/salesLedger'
import { userListNoPageByTenantId } from '@/api/system/user'
import { getToken } from '@/utils/auth'
import { getCurrentDate } from '@/utils'
import useUserStore from '@/store/modules/user'
const props = defineProps({ approveType: { type: [Number, String], default: 1 } })
const emit = defineEmits(['close'])
import useUserStore from "@/store/modules/user";
import { getCurrentDate } from "@/utils/index.js";
import log from "@/views/monitor/job/log.vue";
const userStore = useUserStore();
const { proxy } = getCurrentInstance()
const userStore = useUserStore()
const approveTypeNumber = computed(() => Number(props.approveType))
const typeName = computed(() => ({ 1: '自由协同审批', 3: '销售审批', 5: '采购审批' }[approveTypeNumber.value] || '审批流程'))
const dialogFormVisible = ref(false);
const operationType = ref('')
const fileList = ref([]);
const upload = reactive({
  // 上传的地址
  url: import.meta.env.VITE_APP_BASE_API + "/file/upload",
  // 设置上传的请求头部
  headers: { Authorization: "Bearer " + getToken() },
});
const data = reactive({
  form: {
    approveTime: "",
    approveId: "",
    approveUser: "",
    approveDeptId: "",
    approveDeptName: "",
    approveReason: "",
    checkResult: "",
    tempFileIds: [],
    approverList: [], // 新增字段,存储所有节点的审批人id
    startDate: "", // 请假开始时间
    endDate: "", // 请假结束时间
    price: null, // 报销金额
    location: "" // 出差地点
  },
  rules: {
    approveTime: [{ required: false, message: "请输入", trigger: "change" }],
    approveId: [{ required: false, message: "请输入", trigger: "blur" }],
    approveUser: [{ required: false, message: "请输入", trigger: "blur" }],
    // 使用部门ID做必填校验,避免名称未同步导致误报
    approveDeptId: [{ required: true, message: "请选择申请部门", trigger: "change" }],
    approveReason: [{ required: true, message: "请输入", trigger: "blur" }],
    checkResult: [{ required: false, message: "请输入", trigger: "blur" }],
    startDate: [{ required: true, message: "请选择请假开始时间", trigger: "change" }],
    endDate: [{ required: true, message: "请选择请假结束时间", trigger: "change" }],
    price: [{ required: true, message: "请输入报销金额", trigger: "blur" }],
    location: [{ required: true, message: "请输入出差地点", trigger: "blur" }],
  },
});
const { form, rules } = toRefs(data);
const productOptions = ref([]);
const currentApproveStatus = ref(0)
const props = defineProps({
  approveType: {
    type: [Number, String],
    default: 0
  }
})
// 审批人节点相关
const approverNodes = ref([
  { id: 1, userId: null }
])
let nextApproverId = 2
const visible = ref(false)
const submitting = ref(false)
const operationType = ref('add')
const formRef = ref()
const userList = ref([])
function addApproverNode() {
  approverNodes.value.push({ id: nextApproverId++, userId: null })
const departmentOptions = ref([])
const contractOptions = ref([])
const flowOptions = ref([])
const selectedContract = ref(null)
const fileList = ref([])
let nodeKey = 1
const approverNodes = ref([])
const upload = reactive({ url: import.meta.env.VITE_APP_BASE_API + '/file/upload', headers: { Authorization: 'Bearer ' + getToken() } })
const emptyForm = () => ({
  id: null, approveId: '', approveUser: userStore.id, approveDeptId: userStore.currentDeptId,
  approveTime: getCurrentDate(), approveReason: '', businessId: null, businessNo: '', businessTitle: '',
  amount: null, businessData: '', flowDefinitionId: null, category: '', urgency: '普通', purchaseContent: '', quantity: null,
  unit: '', expectedDate: '', startDate: '', endDate: '', tempFileIds: []
})
const form = ref(emptyForm())
const rules = {
  approveDeptId: [{ required: true, message: '请选择申请部门', trigger: 'change' }],
  approveReason: [{ required: true, message: '请输入申请事由', trigger: 'blur' }],
  businessId: [{ required: true, message: '请选择销售合同', trigger: 'change' }],
  businessTitle: [{ required: true, message: '请输入审批标题', trigger: 'blur' }],
  category: [{ required: true, message: '请输入或选择类别', trigger: 'blur' }],
  urgency: [{ required: true, message: '请选择紧急程度', trigger: 'change' }],
  purchaseContent: [{ required: true, message: '请输入采购内容', trigger: 'blur' }],
  quantity: [{ required: true, message: '请输入数量', trigger: 'blur' }],
  unit: [{ required: true, message: '请输入单位', trigger: 'blur' }],
  amount: [{ required: true, message: '请输入预算金额', trigger: 'blur' }],
  expectedDate: [{ required: true, message: '请选择期望到货日期', trigger: 'change' }],
  startDate: [{ required: true, message: '请选择请假开始日期', trigger: 'change' }],
  endDate: [{ required: true, message: '请选择请假结束日期', trigger: 'change' }]
}
function removeApproverNode(index) {
  approverNodes.value.splice(index, 1)
const createNode = (data = {}) => ({ key: nodeKey++, userId: data.userId || null, nodeName: data.nodeName || '审批', conditionField: data.conditionField || null, conditionOperator: data.conditionOperator || 'ALWAYS', conditionValue: data.conditionValue == null ? null : Number(data.conditionValue) })
const addNode = () => approverNodes.value.push(createNode())
const removeNode = index => approverNodes.value.splice(index, 1)
const moveNode = (index, offset) => {
  const target = index + offset
  if (target < 0 || target >= approverNodes.value.length) return
  const item = approverNodes.value.splice(index, 1)[0]
  approverNodes.value.splice(target, 0, item)
}
// 处理部门选择变化
const handleDeptChange = (deptId) => {
  if (deptId) {
    const selectedDept = productOptions.value.find(dept => dept.deptId === deptId);
    if (selectedDept) {
      form.value.approveDeptName = selectedDept.deptName;
    }
const handleConditionChange = node => {
  node.conditionField = node.conditionOperator === 'ALWAYS' ? null : 'amount'
  if (node.conditionOperator === 'ALWAYS') node.conditionValue = null
}
const loadOptions = async () => {
  const tasks = [userListNoPageByTenantId(), getDept()]
  if (approveTypeNumber.value === 3) tasks.push(ledgerListNoPage({}))
  const flowPromise = [3, 5].includes(approveTypeNumber.value) ? approveFlowDefinitionList({ approveType: approveTypeNumber.value }) : Promise.resolve({ data: [] })
  tasks.push(flowPromise)
  const results = await Promise.all(tasks)
  userList.value = results[0].data || []
  departmentOptions.value = results[1].data || []
  if (approveTypeNumber.value === 3) {
    contractOptions.value = results[2]?.data || []
    flowOptions.value = results[3]?.data || []
  } else {
    form.value.approveDeptName = '';
    contractOptions.value = []
    flowOptions.value = results[2]?.data || []
  }
};
// 打开弹框
const openDialog = (type, row) => {
  operationType.value = type;
  dialogFormVisible.value = true;
   userListNoPageByTenantId().then((res) => {
    userList.value = res.data;
  });
  getProductOptions();
   form.value = {}
   approverNodes.value = [
      { id: 1, userId: null }
   ]
  form.value.approveUser = userStore.id;
  form.value.approveTime = getCurrentDate();
  // 获取当前用户信息并设置部门ID
  form.value.approveDeptId = userStore.currentDeptId
  if (operationType.value === 'edit') {
    fileList.value = row.commonFileList
    form.value.tempFileIds = fileList.value.map(file => file.id)
      currentApproveStatus.value = row.approveStatus
    approveProcessGetInfo({id: row.approveId,approveReason: '1'}).then(res => {
         form.value = {...res.data}
      // 反显审批人
      if (res.data && res.data.approveUserIds) {
        const userIds = res.data.approveUserIds.split(',')
        approverNodes.value = userIds.map((userId, idx) => ({
          id: idx + 1,
          userId: parseInt(userId.trim())
        }))
        nextApproverId = userIds.length + 1
      } else {
        approverNodes.value = [{ id: 1, userId: null }]
        nextApproverId = 2
      }
    })
  }
  const defaultFlow = flowOptions.value.find(item => item.isDefault === 1 && item.enabled === 1)
  if (defaultFlow && operationType.value === 'add') form.value.flowDefinitionId = defaultFlow.id
}
const getProductOptions = () => {
  getDept().then((res) => {
    productOptions.value = res.data;
  });
};
function convertIdToValue(data) {
  return data.map((item) => {
    const { id, children, ...rest } = item;
    const newItem = {
      ...rest,
      value: id, // 将 id 改为 value
    };
    if (children && children.length > 0) {
      newItem.children = convertIdToValue(children);
    }
    return newItem;
  });
}
// 提交产品表单
const submitForm = () => {
  // 收集所有节点的审批人id
  form.value.approveUserIds = approverNodes.value.map(node => node.userId).join(',')
  form.value.approveType = props.approveType
  // 审批人必填校验
  const hasEmptyApprover = approverNodes.value.some(node => !node.userId)
  if (hasEmptyApprover) {
    proxy.$modal.msgError("请为所有审批节点选择审批人!")
    return
  }
  // 当 approveType 为 2 时,校验请假时间
  if (props.approveType == 2) {
    if (!form.value.startDate) {
      proxy.$modal.msgError("请选择请假开始时间!")
      return
    }
    if (!form.value.endDate) {
      proxy.$modal.msgError("请选择请假结束时间!")
      return
    }
    // 校验结束时间不能早于开始时间
    if (new Date(form.value.endDate) < new Date(form.value.startDate)) {
      proxy.$modal.msgError("请假结束时间不能早于开始时间!")
      return
    }
  }
  // 当 approveType 为 3 时,校验出差地点
  if (props.approveType == 3) {
    if (!form.value.location || form.value.location.trim() === '') {
      proxy.$modal.msgError("请输入出差地点!")
      return
    }
  }
  // 当 approveType 为 4 时,校验报销金额
  if (props.approveType == 4) {
    if (!form.value.price || form.value.price <= 0) {
      proxy.$modal.msgError("请输入有效的报销金额!")
      return
    }
  }
  proxy.$refs.formRef.validate(valid => {
    if (valid) {
      if (operationType.value === "add" || currentApproveStatus.value == 3) {
        approveProcessAdd(form.value).then(res => {
          proxy.$modal.msgSuccess("提交成功");
          closeDia();
        })
      } else {
        approveProcessUpdate(form.value).then(res => {
          proxy.$modal.msgSuccess("提交成功");
          closeDia();
        })
      }
    }
  })
}
// 关闭弹框
const closeDia = () => {
const openDialog = async (type, row) => {
  operationType.value = type
  visible.value = true
  form.value = emptyForm()
  approverNodes.value = [createNode()]
  fileList.value = []
  proxy.resetForm("formRef");
  dialogFormVisible.value = false;
  emit('close')
};
// 上传前校检
function handleBeforeUpload(file) {
  // 校检文件大小
  // if (file.size > 1024 * 1024 * 10) {
  //   proxy.$modal.msgError("上传文件大小不能超过10MB!");
  //   return false;
  // }
  proxy.$modal.loading("正在上传文件,请稍候...");
  return true;
}
// 上传失败
function handleUploadError(err) {
  proxy.$modal.msgError("上传文件失败");
  proxy.$modal.closeLoading();
}
// 上传成功回调
function handleUploadSuccess(res, file, uploadFiles) {
  proxy.$modal.closeLoading();
  if (res.code === 200) {
    // 确保 tempFileIds 存在且为数组
    if (!form.value.tempFileIds) {
      form.value.tempFileIds = [];
  selectedContract.value = null
  await loadOptions()
  if (type === 'edit' && row?.approveId) {
    const [processRes, nodeRes] = await Promise.all([approveProcessGetInfo({ id: row.approveId }), approveProcessDetails(row.approveId)])
    const process = processRes.data || {}
    let business = {}
    try { business = process.businessData ? JSON.parse(process.businessData) : {} } catch (_) { business = {} }
    form.value = { ...emptyForm(), ...process, ...business, tempFileIds: [] }
    fileList.value = process.commonFileList || []
    approverNodes.value = (nodeRes.data || []).map(item => createNode({
      userId: item.approveNodeUserId,
      nodeName: item.approveNodeName,
      conditionField: item.conditionField,
      conditionOperator: item.conditionOperator,
      conditionValue: item.conditionValue
    }))
    if (!approverNodes.value.length) approverNodes.value = [createNode()]
    if (approveTypeNumber.value === 3) {
      selectedContract.value = contractOptions.value.find(item => item.id === process.businessId) || business
    }
    form.value.tempFileIds.push(res.data.tempId);
    proxy.$modal.msgSuccess("上传成功");
  } else {
    proxy.$modal.msgError(res.msg);
    proxy.$refs.fileUpload.handleRemove(file);
  }
}
// 移除文件
function handleRemove(file) {
  if (operationType.value === "edit") {
    let ids = [];
    ids.push(file.id);
    delLedgerFile(ids).then((res) => {
      proxy.$modal.msgSuccess("删除成功");
    });
  }
}
defineExpose({
  openDialog,
});
const handleContractChange = id => {
  selectedContract.value = contractOptions.value.find(item => item.id === id) || null
  if (selectedContract.value) form.value.businessTitle = `销售合同审批-${selectedContract.value.salesContractNo || ''}`
}
const buildBusinessData = () => {
  if (approveTypeNumber.value === 5) return JSON.stringify({ category: form.value.category, urgency: form.value.urgency, purchaseContent: form.value.purchaseContent, quantity: form.value.quantity, unit: form.value.unit, expectedDate: form.value.expectedDate })
  if (approveTypeNumber.value === 1) return JSON.stringify({ category: form.value.category })
  if (approveTypeNumber.value === 2) return JSON.stringify({ startDate: form.value.startDate, endDate: form.value.endDate })
  if (approveTypeNumber.value === 4) return JSON.stringify({ amount: form.value.amount })
  return form.value.businessData || ''
}
const submit = async () => {
  await formRef.value.validate()
  if (approveTypeNumber.value === 2 && new Date(form.value.endDate) < new Date(form.value.startDate)) return proxy.$modal.msgError('请假结束日期不能早于开始日期')
  const usePresetFlow = operationType.value === 'add' && !!form.value.flowDefinitionId
  if (!usePresetFlow && approverNodes.value.some(item => !item.userId || !item.nodeName)) return proxy.$modal.msgError('请完整填写审批节点')
  if (!usePresetFlow && approverNodes.value.some((item, index) => index > 0 && item.userId === approverNodes.value[index - 1].userId)) return proxy.$modal.msgError('相邻审批节点不能选择同一审批人')
  if (!usePresetFlow && approverNodes.value.some(item => item.conditionOperator !== 'ALWAYS' && item.conditionValue == null)) return proxy.$modal.msgError('请填写节点条件金额')
  const nodes = usePresetFlow ? [] : approverNodes.value.map(item => ({ userId: item.userId, nodeName: item.nodeName, conditionField: item.conditionOperator === 'ALWAYS' ? null : 'amount', conditionOperator: item.conditionOperator, conditionValue: item.conditionValue == null ? null : String(item.conditionValue) }))
  const payload = { ...form.value, approveType: approveTypeNumber.value, approveUser: userStore.id, nodes, approveUserIds: nodes.map(item => item.userId).join(','), businessData: buildBusinessData() }
  submitting.value = true
  try {
    if (operationType.value === 'add') await approveProcessAdd(payload)
    else await approveProcessUpdate(payload)
    proxy.$modal.msgSuccess('提交成功')
    closeDialog()
  } finally {
    submitting.value = false
  }
}
const beforeUpload = () => { proxy.$modal.loading('正在上传文件,请稍候...'); return true }
const uploadSuccess = (res, file) => {
  proxy.$modal.closeLoading()
  if (res.code === 200) form.value.tempFileIds.push(res.data.tempId)
  else { proxy.$modal.msgError(res.msg); proxy.$refs.fileUpload?.handleRemove(file) }
}
const uploadError = () => { proxy.$modal.closeLoading(); proxy.$modal.msgError('上传失败') }
const removeFile = file => {
  if (file.id) delLedgerFile([file.id])
  if (file.response?.data?.tempId) form.value.tempFileIds = form.value.tempFileIds.filter(id => id !== file.response.data.tempId)
}
const closeDialog = () => { visible.value = false; emit('close') }
defineExpose({ openDialog })
</script>
<style scoped>
</style>
.node-row { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; flex-wrap: wrap; }
.node-order { display: inline-flex; width: 26px; height: 26px; align-items: center; justify-content: center; border-radius: 50%; color: #fff; background: #409eff; }
.add-node { margin: 0 0 20px 120px; }
</style>