| | |
| | | :rules="rules" |
| | | :model="form" |
| | | label-width="140rpx"> |
| | | <template v-if="operationType !== 'detail'"> |
| | | <u-form-item prop="approveReason" |
| | | label="流程编号"> |
| | | <u-input v-model="form.approveId" |
| | | disabled |
| | | placeholder="自动编号" /> |
| | | </u-form-item> |
| | | <u-form-item prop="approveReason" |
| | | :label="approveType === 5 ? '采购事由' : '申请事由'" |
| | | required> |
| | | <u-input v-model="form.approveReason" |
| | | type="textarea" |
| | | rows="2" |
| | | auto-height |
| | | maxlength="200" |
| | | :placeholder="approveType === 5 ? '请输入采购事由' : '请输入申请事由'" |
| | | show-word-limit /> |
| | | </u-form-item> |
| | | <u-form-item prop="approveDeptName" |
| | | label="申请部门" |
| | | required> |
| | | <!-- <u-input v-model="form.approveDeptName" |
| | | placeholder="请选择申请部门" /> --> |
| | | <u-input v-model="form.approveDeptName" |
| | | readonly |
| | | placeholder="请选择申请部门" |
| | | @click="showPicker = true" /> |
| | | <template #right> |
| | | <up-icon name="arrow-right" |
| | | @click="showPicker = true"></up-icon> |
| | | </template> |
| | | </u-form-item> |
| | | <!-- <u-form-item prop="approveUser" |
| | | <u-form-item prop="approveReason" |
| | | label="流程编号"> |
| | | <u-input v-model="form.approveId" |
| | | disabled |
| | | placeholder="自动编号" /> |
| | | </u-form-item> |
| | | <u-form-item prop="approveReason" |
| | | :label="approveType === 5 ? '采购事由' : '申请事由'" |
| | | required> |
| | | <u-input v-model="form.approveReason" |
| | | type="textarea" |
| | | rows="2" |
| | | auto-height |
| | | maxlength="200" |
| | | :disabled="isDetailMode" |
| | | :placeholder="approveType === 5 ? '请输入采购事由' : '请输入申请事由'" |
| | | show-word-limit /> |
| | | </u-form-item> |
| | | <u-form-item prop="approveDeptName" |
| | | label="申请部门" |
| | | required> |
| | | <u-input v-model="form.approveDeptName" |
| | | readonly |
| | | :disabled="isDetailMode" |
| | | placeholder="请选择申请部门" |
| | | @click="isDetailMode || (showPicker = true)" /> |
| | | <template #right> |
| | | <up-icon name="arrow-right" |
| | | @click="isDetailMode || (showPicker = true)"></up-icon> |
| | | </template> |
| | | </u-form-item> |
| | | <!-- <u-form-item prop="approveUser" |
| | | label="申请人" |
| | | required> |
| | | <u-input v-model="form.approveUserName" |
| | |
| | | @click="showDatePicker"></up-icon> |
| | | </template> |
| | | </u-form-item> --> |
| | | <!-- approveType=2 请假相关字段 --> |
| | | <template v-if="approveType === 2"> |
| | | <u-form-item prop="startDate" |
| | | label="开始时间" |
| | | required> |
| | | <u-input v-model="form.startDate" |
| | | readonly |
| | | placeholder="请假开始时间" |
| | | @click="showStartDatePicker" /> |
| | | <template #right> |
| | | <up-icon name="arrow-right" |
| | | @click="showStartDatePicker"></up-icon> |
| | | </template> |
| | | </u-form-item> |
| | | <u-form-item prop="endDate" |
| | | label="结束时间" |
| | | required> |
| | | <u-input v-model="form.endDate" |
| | | readonly |
| | | placeholder="请假结束时间" |
| | | @click="showEndDatePicker" /> |
| | | <template #right> |
| | | <up-icon name="arrow-right" |
| | | @click="showEndDatePicker"></up-icon> |
| | | </template> |
| | | </u-form-item> |
| | | <!-- approveType=2 请假相关字段 --> |
| | | <u-form-item v-if="approveType === 2" |
| | | prop="startDate" |
| | | label="开始时间" |
| | | required> |
| | | <u-input v-model="form.startDate" |
| | | readonly |
| | | :disabled="isDetailMode" |
| | | placeholder="请假开始时间" |
| | | @click="showStartDatePicker" /> |
| | | <template #right> |
| | | <up-icon name="arrow-right" |
| | | @click="showStartDatePicker"></up-icon> |
| | | </template> |
| | | <!-- approveType=3 出差相关字段 --> |
| | | <u-form-item v-if="approveType === 3" |
| | | prop="location" |
| | | label="出差地点" |
| | | required> |
| | | <u-input v-model="form.location" |
| | | placeholder="请输入出差地点" |
| | | clearable /> |
| | | </u-form-item> |
| | | <!-- approveType=4 报销相关字段 --> |
| | | <u-form-item v-if="approveType === 4" |
| | | prop="price" |
| | | label="报销金额" |
| | | required> |
| | | <u-input v-model="form.price" |
| | | type="number" |
| | | placeholder="请输入报销金额" |
| | | clearable /> |
| | | </u-form-item> |
| | | </template> |
| | | <!-- 报价审批详情 --> |
| | | <view v-if="isQuotationApproval" |
| | | style="margin: 20rpx 0;"> |
| | | <u-divider text="报价详情" |
| | | text-size="28rpx" |
| | | color="#2979ff"></u-divider> |
| | | <u-skeleton :loading="quotationLoading" |
| | | rows="3" |
| | | animated> |
| | | <view v-if="!currentQuotation || !currentQuotation.quotationNo" |
| | | style="padding: 40rpx; text-align: center; color: #999;"> |
| | | 未查询到对应报价详情 |
| | | </view> |
| | | <view v-else> |
| | | <u-cell-group :border="false"> |
| | | <u-cell title="报价单号" |
| | | :value="currentQuotation.quotationNo"></u-cell> |
| | | <u-cell title="客户名称" |
| | | :value="currentQuotation.customer"></u-cell> |
| | | <u-cell title="业务员" |
| | | :value="currentQuotation.salesperson"></u-cell> |
| | | <u-cell title="报价日期" |
| | | :value="currentQuotation.quotationDate"></u-cell> |
| | | <u-cell title="有效期至" |
| | | :value="currentQuotation.validDate"></u-cell> |
| | | <u-cell title="付款方式" |
| | | :value="currentQuotation.paymentMethod"></u-cell> |
| | | <u-cell title="报价总额"> |
| | | <template #value> |
| | | <text style="font-size: 32rpx; color: #e6a23c; font-weight: bold;"> |
| | | ¥{{ Number(currentQuotation.totalAmount ?? 0).toFixed(2) }} |
| | | </text> |
| | | </template> |
| | | </u-cell> |
| | | </u-cell-group> |
| | | <view style="margin-top: 20rpx; padding: 0 30rpx;"> |
| | | <view style="font-size: 28rpx; font-weight: bold; margin-bottom: 10rpx;">产品明细</view> |
| | | <view v-for="(item, index) in (currentQuotation.products || [])" |
| | | :key="index" |
| | | style="background: #f8f8f8; border-radius: 8rpx; padding: 20rpx; margin-bottom: 10rpx;"> |
| | | <view style="display: flex; justify-content: space-between;"> |
| | | <text style="font-weight: bold;">{{ item.product }}</text> |
| | | <text style="color: #e6a23c;">¥{{ Number(item.unitPrice ?? 0).toFixed(2) }}</text> |
| | | </view> |
| | | <view style="font-size: 24rpx; color: #666; margin-top: 10rpx;"> |
| | | 规格: {{ item.specification }} | 单位: {{ item.unit }} |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <view v-if="currentQuotation.remark" |
| | | style="margin-top: 20rpx; padding: 0 30rpx;"> |
| | | <view style="font-size: 28rpx; font-weight: bold;">备注</view> |
| | | <view style="font-size: 26rpx; color: #666; margin-top: 10rpx;">{{ currentQuotation.remark }}</view> |
| | | </view> |
| | | </view> |
| | | </u-skeleton> |
| | | </view> |
| | | <!-- 采购审批详情 --> |
| | | <view v-if="isPurchaseApproval" |
| | | style="margin: 20rpx 0;"> |
| | | <u-divider text="采购详情" |
| | | text-size="28rpx" |
| | | color="#2979ff"></u-divider> |
| | | <u-skeleton :loading="purchaseLoading" |
| | | rows="3" |
| | | animated> |
| | | <view v-if="!currentPurchase || !currentPurchase.purchaseContractNumber" |
| | | style="padding: 40rpx; text-align: center; color: #999;"> |
| | | 未查询到对应采购详情 |
| | | </view> |
| | | <view v-else> |
| | | <u-cell-group :border="false"> |
| | | <u-cell title="采购合同号" |
| | | :value="currentPurchase.purchaseContractNumber"></u-cell> |
| | | <u-cell title="供应商名称" |
| | | :value="currentPurchase.supplierName"></u-cell> |
| | | <u-cell title="项目名称" |
| | | :value="currentPurchase.projectName"></u-cell> |
| | | <u-cell title="销售合同号" |
| | | :value="currentPurchase.salesContractNo"></u-cell> |
| | | <u-cell title="签订日期" |
| | | :value="currentPurchase.executionDate"></u-cell> |
| | | <u-cell title="录入日期" |
| | | :value="currentPurchase.entryDate"></u-cell> |
| | | <u-cell title="付款方式" |
| | | :value="currentPurchase.paymentMethod"></u-cell> |
| | | <u-cell title="合同金额"> |
| | | <template #value> |
| | | <text style="font-size: 32rpx; color: #e6a23c; font-weight: bold;"> |
| | | ¥{{ Number(currentPurchase.contractAmount ?? 0).toFixed(2) }} |
| | | </text> |
| | | </template> |
| | | </u-cell> |
| | | </u-cell-group> |
| | | <view style="margin-top: 20rpx; padding: 0 30rpx;"> |
| | | <view style="font-size: 28rpx; font-weight: bold; margin-bottom: 10rpx;">产品明细</view> |
| | | <view v-for="(item, index) in (currentPurchase.productData || [])" |
| | | :key="index" |
| | | style="background: #f8f8f8; border-radius: 8rpx; padding: 20rpx; margin-bottom: 10rpx;"> |
| | | <view style="display: flex; justify-content: space-between;"> |
| | | <text style="font-weight: bold;">{{ item.productCategory }}</text> |
| | | <text style="color: #e6a23c;">¥{{ Number(item.taxInclusiveTotalPrice ?? 0).toFixed(2) }}</text> |
| | | </view> |
| | | <view style="font-size: 24rpx; color: #666; margin-top: 10rpx;"> |
| | | 规格: {{ item.specificationModel }} | 数量: {{ item.quantity }} {{ item.unit }} |
| | | </view> |
| | | <view style="font-size: 24rpx; color: #999; margin-top: 4rpx;"> |
| | | 含税单价: ¥{{ Number(item.taxInclusiveUnitPrice ?? 0).toFixed(2) }} |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </u-skeleton> |
| | | </view> |
| | | <!-- 发货审批详情 --> |
| | | <view v-if="isDeliveryApproval" |
| | | style="margin: 20rpx 0;"> |
| | | <u-divider text="发货详情" |
| | | text-size="28rpx" |
| | | color="#2979ff"></u-divider> |
| | | <u-skeleton :loading="deliveryLoading" |
| | | rows="3" |
| | | animated> |
| | | <view v-if="!currentDelivery || !currentDelivery.shippingInfo" |
| | | style="padding: 40rpx; text-align: center; color: #999;"> |
| | | 未查询到对应发货详情 |
| | | </view> |
| | | <view v-else> |
| | | <u-cell-group :border="false"> |
| | | <u-cell title="销售订单" |
| | | :value="currentDelivery.shippingInfo.salesContractNo || '--'"></u-cell> |
| | | <u-cell title="发货订单号" |
| | | :value="currentDelivery.shippingInfo.shippingNo || '--'"></u-cell> |
| | | <u-cell title="客户名称" |
| | | :value="currentDelivery.shippingInfo.customerName || '--'"></u-cell> |
| | | <u-cell title="发货类型" |
| | | :value="currentDelivery.shippingInfo.type || '--'"></u-cell> |
| | | <u-cell title="发货日期" |
| | | :value="currentDelivery.shippingInfo.shippingDate || '--'"></u-cell> |
| | | <u-cell title="审核状态" |
| | | :value="currentDelivery.shippingInfo.status || '--'"></u-cell> |
| | | <u-cell title="发货车牌号" |
| | | :value="currentDelivery.shippingInfo.shippingCarNumber || '--'"></u-cell> |
| | | <u-cell title="快递公司" |
| | | :value="currentDelivery.shippingInfo.expressCompany || '--'"></u-cell> |
| | | <u-cell title="快递单号" |
| | | :value="currentDelivery.shippingInfo.expressNumber || '--'"></u-cell> |
| | | </u-cell-group> |
| | | <view style="margin-top: 20rpx; padding: 0 30rpx;"> |
| | | <view style="font-size: 28rpx; font-weight: bold; margin-bottom: 10rpx;">产品明细</view> |
| | | <view v-for="(item, index) in deliveryProductList" |
| | | :key="index" |
| | | style="background: #f8f8f8; border-radius: 8rpx; padding: 20rpx; margin-bottom: 10rpx;"> |
| | | <view style="display: flex; justify-content: space-between;"> |
| | | <text style="font-weight: bold;">{{ item.productName }}</text> |
| | | <text style="color: #2979ff;">数量: {{ item.deliveryQuantity }}</text> |
| | | </view> |
| | | <view style="font-size: 24rpx; color: #666; margin-top: 10rpx;"> |
| | | 规格: {{ item.specificationModel }} |
| | | </view> |
| | | <view v-if="item.batchNo" |
| | | style="font-size: 24rpx; color: #999; margin-top: 4rpx;"> |
| | | 批号: {{ item.batchNo }} |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <view v-if="currentDelivery.shippingInfo.storageBlobVOs && currentDelivery.shippingInfo.storageBlobVOs.length" |
| | | style="margin-top: 20rpx; padding: 0 30rpx;"> |
| | | <view style="font-size: 28rpx; font-weight: bold; margin-bottom: 10rpx;">发货图片</view> |
| | | <CommonUpload :model-value="currentDelivery.shippingInfo.storageBlobVOs" |
| | | disabled /> |
| | | </view> |
| | | </view> |
| | | </u-skeleton> |
| | | </view> |
| | | </u-form-item> |
| | | <u-form-item v-if="approveType === 2" |
| | | prop="endDate" |
| | | label="结束时间" |
| | | required> |
| | | <u-input v-model="form.endDate" |
| | | readonly |
| | | :disabled="isDetailMode" |
| | | placeholder="请假结束时间" |
| | | @click="showEndDatePicker" /> |
| | | <template #right> |
| | | <up-icon name="arrow-right" |
| | | @click="showEndDatePicker"></up-icon> |
| | | </template> |
| | | </u-form-item> |
| | | <!-- approveType=3 出差相关字段 --> |
| | | <u-form-item v-if="approveType === 3" |
| | | prop="startDateTime" |
| | | label="出差开始时间" |
| | | required> |
| | | <u-input v-model="form.startDateTime" |
| | | readonly |
| | | :disabled="isDetailMode" |
| | | placeholder="请选择开始时间" |
| | | @click="showStartDateTimePicker" /> |
| | | <template #right> |
| | | <up-icon name="arrow-right" |
| | | @click="showStartDateTimePicker"></up-icon> |
| | | </template> |
| | | </u-form-item> |
| | | <u-form-item v-if="approveType === 3" |
| | | prop="endDateTime" |
| | | label="出差结束时间" |
| | | required> |
| | | <u-input v-model="form.endDateTime" |
| | | readonly |
| | | :disabled="isDetailMode" |
| | | placeholder="请选择结束时间" |
| | | @click="showEndDateTimePicker" /> |
| | | <template #right> |
| | | <up-icon name="arrow-right" |
| | | @click="showEndDateTimePicker"></up-icon> |
| | | </template> |
| | | </u-form-item> |
| | | <u-form-item v-if="approveType === 3" |
| | | prop="location" |
| | | label="出差地点" |
| | | required> |
| | | <u-input v-model="form.location" |
| | | :disabled="isDetailMode" |
| | | placeholder="请输入出差地点" |
| | | clearable /> |
| | | </u-form-item> |
| | | <!-- approveType=4 报销相关字段 --> |
| | | <u-form-item v-if="approveType === 4" |
| | | prop="price" |
| | | label="报销金额" |
| | | required> |
| | | <u-input v-model="form.price" |
| | | type="number" |
| | | :disabled="isDetailMode" |
| | | placeholder="请输入报销金额" |
| | | clearable /> |
| | | </u-form-item> |
| | | <!-- 采购/报价/发货审批详情 --> |
| | | <ApprovalBusinessDetail :approve-type="approveType" |
| | | :business-no="form.approveReason" /> |
| | | <!-- 审批流程(仅详情模式展示,与 Web 一致) --> |
| | | <ApproveFlowSteps v-if="isDetailMode" |
| | | :steps="approvalSteps" |
| | | show-pending-opinion /> |
| | | <u-form-item v-if="operationType !== 'detail'" |
| | | label="图片附件" |
| | | prop="storageBlobDTOS" |
| | |
| | | </u-form-item> |
| | | </u-form> |
| | | <!-- 选择器弹窗 --> |
| | | <template v-if="operationType !== 'detail'"> |
| | | <view v-if="operationType !== 'detail'"> |
| | | <up-action-sheet :show="showPicker" |
| | | :actions="productOptions" |
| | | title="选择部门" |
| | |
| | | @cancel="showEndDate = false" |
| | | mode="date" /> |
| | | </up-popup> |
| | | </template> |
| | | <!-- 出差开始时间选择器 --> |
| | | <up-popup :show="showStartDateTime" |
| | | mode="bottom" |
| | | @close="showStartDateTime = false"> |
| | | <up-datetime-picker :show="true" |
| | | v-model="startDateTimeValue" |
| | | @confirm="onStartDateTimeConfirm" |
| | | @cancel="showStartDateTime = false" |
| | | mode="datetime" /> |
| | | </up-popup> |
| | | <!-- 出差结束时间选择器 --> |
| | | <up-popup :show="showEndDateTime" |
| | | mode="bottom" |
| | | @close="showEndDateTime = false"> |
| | | <up-datetime-picker :show="true" |
| | | v-model="endDateTimeValue" |
| | | @confirm="onEndDateTimeConfirm" |
| | | @cancel="showEndDateTime = false" |
| | | mode="datetime" /> |
| | | </up-popup> |
| | | </view> |
| | | <!-- 底部按钮 --> |
| | | <view class="footer-btns" |
| | | v-if="operationType !== 'detail'"> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { |
| | | ref, |
| | | onMounted, |
| | | onUnmounted, |
| | | reactive, |
| | | toRefs, |
| | | computed, |
| | | watch, |
| | | } from "vue"; |
| | | import { ref, onMounted, onUnmounted, reactive, toRefs, computed } from "vue"; |
| | | import PageHeader from "@/components/PageHeader.vue"; |
| | | import CommonUpload from "@/components/CommonUpload.vue"; |
| | | import ApprovalBusinessDetail from "./_components/ApprovalBusinessDetail.vue"; |
| | | import ApproveFlowSteps from "./_components/ApproveFlowSteps.vue"; |
| | | import { mapApprovalSteps } from "./_utils/approveFlowSteps.js"; |
| | | import useUserStore from "@/store/modules/user"; |
| | | import { formatDateToYMD } from "@/utils/ruoyi"; |
| | | import { formatDateToYMD, parseTime } from "@/utils/ruoyi"; |
| | | import { |
| | | getDept, |
| | | approveProcessGetInfo, |
| | | approveProcessAdd, |
| | | approveProcessUpdate, |
| | | getDeliveryDetailByShippingNo, |
| | | approveProcessDetails, |
| | | } from "@/api/collaborativeApproval/approvalProcess"; |
| | | import { getQuotationList } from "@/api/salesManagement/salesQuotation"; |
| | | import { getPurchaseByCode } from "@/api/procurementManagement/procurementLedger"; |
| | | const showToast = message => { |
| | | uni.showToast({ |
| | | title: message, |
| | |
| | | storageBlobDTOS: [], |
| | | startDate: "", |
| | | endDate: "", |
| | | startDateTime: "", |
| | | endDateTime: "", |
| | | location: "", |
| | | price: "", |
| | | }, |
| | |
| | | endDate: [ |
| | | { required: false, message: "请选择结束时间", trigger: "change" }, |
| | | ], |
| | | startDateTime: [ |
| | | { required: false, message: "请选择出差开始时间", trigger: "change" }, |
| | | ], |
| | | endDateTime: [ |
| | | { required: false, message: "请选择出差结束时间", trigger: "change" }, |
| | | ], |
| | | location: [{ required: false, message: "请输入出差地点", trigger: "blur" }], |
| | | price: [{ required: false, message: "请输入报销金额", trigger: "blur" }], |
| | | }, |
| | |
| | | const showPicker = ref(false); |
| | | const productOptions = ref([]); |
| | | const operationType = ref(""); |
| | | const isDetailMode = computed(() => operationType.value === "detail"); |
| | | |
| | | /** 审批流程节点(仅详情模式展示) */ |
| | | const approvalSteps = ref([]); |
| | | |
| | | const loadApprovalSteps = approveIdValue => { |
| | | if (!approveIdValue) return; |
| | | approveProcessDetails(approveIdValue) |
| | | .then(res => { |
| | | approvalSteps.value = mapApprovalSteps(res?.data); |
| | | }) |
| | | .catch(() => { |
| | | approvalSteps.value = []; |
| | | }); |
| | | }; |
| | | const currentApproveStatus = ref(""); |
| | | const formRef = ref(null); |
| | | const message = ref(""); |
| | |
| | | const startDateValue = ref(Date.now()); |
| | | const showEndDate = ref(false); |
| | | const endDateValue = ref(Date.now()); |
| | | const showStartDateTime = ref(false); |
| | | const startDateTimeValue = ref(Date.now()); |
| | | const showEndDateTime = ref(false); |
| | | const endDateTimeValue = ref(Date.now()); |
| | | const userStore = useUserStore(); |
| | | const approveType = ref(0); |
| | | const isInitialLoading = ref(false); |
| | | |
| | | const quotationLoading = ref(false); |
| | | const currentQuotation = ref({}); |
| | | const purchaseLoading = ref(false); |
| | | const currentPurchase = ref({}); |
| | | const deliveryLoading = ref(false); |
| | | const currentDelivery = ref({}); |
| | | const deliveryProductList = ref([]); |
| | | |
| | | const isQuotationApproval = computed(() => Number(approveType.value) === 6); |
| | | const isPurchaseApproval = computed(() => Number(approveType.value) === 5); |
| | | const isDeliveryApproval = computed(() => Number(approveType.value) === 7); |
| | | |
| | | const getProductOptions = () => { |
| | | getDept().then(res => { |
| | |
| | | |
| | | // 显示日期选择器 |
| | | const showDatePicker = () => { |
| | | if (isDetailMode.value) return; |
| | | showDate.value = true; |
| | | }; |
| | | |
| | |
| | | |
| | | // 显示请假开始时间选择器 |
| | | const showStartDatePicker = () => { |
| | | if (isDetailMode.value) return; |
| | | showStartDate.value = true; |
| | | }; |
| | | |
| | |
| | | }; |
| | | |
| | | const showEndDatePicker = () => { |
| | | if (isDetailMode.value) return; |
| | | showEndDate.value = true; |
| | | }; |
| | | |
| | |
| | | showEndDate.value = false; |
| | | }; |
| | | |
| | | const fetchDetailData = async row => { |
| | | // 报价审批 |
| | | if (isQuotationApproval.value) { |
| | | const quotationNo = row?.approveReason; |
| | | if (quotationNo) { |
| | | quotationLoading.value = true; |
| | | getQuotationList({ quotationNo }) |
| | | .then(res => { |
| | | const records = res?.data?.records || []; |
| | | currentQuotation.value = records[0] || {}; |
| | | }) |
| | | .finally(() => { |
| | | quotationLoading.value = false; |
| | | }); |
| | | } |
| | | } |
| | | |
| | | // 采购审批 |
| | | if (isPurchaseApproval.value) { |
| | | const purchaseContractNumber = row?.approveReason; |
| | | if (purchaseContractNumber) { |
| | | purchaseLoading.value = true; |
| | | getPurchaseByCode({ purchaseContractNumber }) |
| | | .then(res => { |
| | | currentPurchase.value = res; |
| | | }) |
| | | .catch(err => { |
| | | console.error("查询采购详情失败:", err); |
| | | }) |
| | | .finally(() => { |
| | | purchaseLoading.value = false; |
| | | }); |
| | | } |
| | | } |
| | | |
| | | // 发货审批 |
| | | if (isDeliveryApproval.value) { |
| | | const deliveryNo = row?.approveReason; |
| | | if (deliveryNo) { |
| | | deliveryLoading.value = true; |
| | | currentDelivery.value = {}; |
| | | deliveryProductList.value = []; |
| | | getDeliveryDetailByShippingNo({ shippingNo: deliveryNo }) |
| | | .then(res => { |
| | | const detailData = res?.data || res || {}; |
| | | currentDelivery.value = detailData; |
| | | deliveryProductList.value = |
| | | detailData.shippingProductDetailDtoList || []; |
| | | }) |
| | | .catch(err => { |
| | | console.error("查询发货详情失败:", err); |
| | | }) |
| | | .finally(() => { |
| | | deliveryLoading.value = false; |
| | | }); |
| | | } |
| | | } |
| | | // 显示出差开始时间选择器(YYYY-MM-DD HH:mm,与 Web 一致) |
| | | const showStartDateTimePicker = () => { |
| | | if (isDetailMode.value) return; |
| | | startDateTimeValue.value = parseTime( |
| | | form.value.startDateTime, |
| | | "{y}-{m}-{d} {h}:{i}" |
| | | ) |
| | | ? new Date(form.value.startDateTime).getTime() |
| | | : Date.now(); |
| | | showStartDateTime.value = true; |
| | | }; |
| | | |
| | | // 监听审批事由变化,如果是特定审批类型则尝试获取详情 |
| | | watch( |
| | | () => form.value.approveReason, |
| | | newVal => { |
| | | if (isInitialLoading.value) return; |
| | | if ( |
| | | newVal && |
| | | (isQuotationApproval.value || |
| | | isPurchaseApproval.value || |
| | | isDeliveryApproval.value) |
| | | ) { |
| | | // 延迟一会再请求,避免输入过程中频繁触发 |
| | | debounceFetchDetail(); |
| | | } |
| | | } |
| | | ); |
| | | const onStartDateTimeConfirm = e => { |
| | | form.value.startDateTime = parseTime(e.value, "{y}-{m}-{d} {h}:{i}"); |
| | | showStartDateTime.value = false; |
| | | }; |
| | | |
| | | let timer = null; |
| | | const debounceFetchDetail = () => { |
| | | if (timer) clearTimeout(timer); |
| | | timer = setTimeout(() => { |
| | | fetchDetailData(form.value); |
| | | }, 800); |
| | | // 显示出差结束时间选择器 |
| | | const showEndDateTimePicker = () => { |
| | | if (isDetailMode.value) return; |
| | | endDateTimeValue.value = parseTime( |
| | | form.value.endDateTime, |
| | | "{y}-{m}-{d} {h}:{i}" |
| | | ) |
| | | ? new Date(form.value.endDateTime).getTime() |
| | | : Date.now(); |
| | | showEndDateTime.value = true; |
| | | }; |
| | | |
| | | const onEndDateTimeConfirm = e => { |
| | | form.value.endDateTime = parseTime(e.value, "{y}-{m}-{d} {h}:{i}"); |
| | | showEndDateTime.value = false; |
| | | }; |
| | | |
| | | onMounted(async () => { |
| | |
| | | const row = JSON.parse(storedData); |
| | | currentApproveStatus.value = row.approveStatus; |
| | | |
| | | isInitialLoading.value = true; |
| | | approveProcessGetInfo({ id: row.approveId, approveReason: "1" }) |
| | | .then(res => { |
| | | // 详情模式:拉取审批流程节点 |
| | | if (operationType.value === "detail") { |
| | | loadApprovalSteps(row.approveId); |
| | | } |
| | | |
| | | approveProcessGetInfo({ id: row.approveId, approveReason: "1" }).then( |
| | | res => { |
| | | form.value = { ...res.data }; |
| | | // 设置图片列表显示 |
| | | const fileData = |
| | |
| | | if (fileData.length > 0) { |
| | | form.value.storageBlobDTOS = fileData; |
| | | } |
| | | // 获取额外详情 |
| | | fetchDetailData(res.data); |
| | | }) |
| | | .finally(() => { |
| | | // 延迟一会重置,确保 watch 不会被触发 |
| | | setTimeout(() => { |
| | | isInitialLoading.value = false; |
| | | }, 100); |
| | | }); |
| | | } |
| | | ); |
| | | } |
| | | } |
| | | } catch (error) { |