| | |
| | | <text class="info-label">申请日期</text> |
| | | <text class="info-value">{{ approvalData.approveTime }}</text> |
| | | </view> |
| | | |
| | | <!-- approveType=2 请假相关字段 --> |
| | | <template v-if="approvalData.approveType === 2"> |
| | | <view class="info-row"> |
| | | <text class="info-label">请假开始时间</text> |
| | | <text class="info-value">{{ approvalData.startDate || '-' }}</text> |
| | | </view> |
| | | <view class="info-row"> |
| | | <text class="info-label">请假结束时间</text> |
| | | <text class="info-value">{{ approvalData.endDate || '-' }}</text> |
| | | </view> |
| | | </template> |
| | | |
| | | <!-- approveType=3 出差相关字段 --> |
| | | <view v-if="approvalData.approveType === 3" class="info-row"> |
| | | <text class="info-label">出差地点</text> |
| | | <text class="info-value">{{ approvalData.location || '-' }}</text> |
| | | </view> |
| | | |
| | | <!-- approveType=4 报销相关字段 --> |
| | | <view v-if="approvalData.approveType === 4" class="info-row"> |
| | | <text class="info-label">报销金额</text> |
| | | <text class="info-value">{{ approvalData.price ? `¥${approvalData.price}` : '-' }}</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 入库详情 --> |
| | | <view v-if="approvalData.approveType === 9" class="stockin-info"> |
| | | <view class="info-header stockin-header" @click="toggleStockInCollapse"> |
| | | <text class="info-title">入库详情</text> |
| | | <text class="collapse-text">{{ stockInCollapsed ? '展开' : '收起' }}</text> |
| | | </view> |
| | | <view v-show="!stockInCollapsed" class="stockin-table"> |
| | | <view class="stockin-row"> |
| | | <text class="stockin-label">销售合同号</text> |
| | | <text class="stockin-value">{{ stockInOrderInfoData.salesContractNo || '-' }}</text> |
| | | <text class="stockin-label">客户名称</text> |
| | | <text class="stockin-value">{{ stockInOrderInfoData.customerName || stockInOrderInfoData.supplierName || '-' }}</text> |
| | | </view> |
| | | <view class="stockin-row"> |
| | | <text class="stockin-label">项目名称</text> |
| | | <text class="stockin-value">{{ stockInOrderInfoData.projectName || '-' }}</text> |
| | | <text class="stockin-label">业务员</text> |
| | | <text class="stockin-value">{{ stockInOrderInfoData.businessUserName || stockInOrderInfoData.recorderName || '-' }}</text> |
| | | </view> |
| | | <view v-for="(product, index) in stockInProducts" :key="product.id || index"> |
| | | <view class="stockin-row"> |
| | | <text class="stockin-label">产品名称</text> |
| | | <text class="stockin-value">{{ product.speculativeTradingName || product.productCategory || '-' }}</text> |
| | | <text class="stockin-label">规格型号</text> |
| | | <text class="stockin-value">{{ product.specificationModel || '-' }}</text> |
| | | </view> |
| | | <view class="stockin-row"> |
| | | <text class="stockin-label">单位</text> |
| | | <text class="stockin-value">{{ product.unit || '-' }}</text> |
| | | <text class="stockin-label">数量</text> |
| | | <text class="stockin-value">{{ product.quantity ?? '-' }}</text> |
| | | </view> |
| | | </view> |
| | | <view v-if="!stockInProducts.length" class="stockin-row"> |
| | | <text class="stockin-label">产品名称</text> |
| | | <text class="stockin-value">-</text> |
| | | <text class="stockin-label">规格型号</text> |
| | | <text class="stockin-value">-</text> |
| | | </view> |
| | | <view v-if="!stockInProducts.length" class="stockin-row"> |
| | | <text class="stockin-label">单位</text> |
| | | <text class="stockin-value">-</text> |
| | | <text class="stockin-label">数量</text> |
| | | <text class="stockin-value">-</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | |
| | |
| | | </view> |
| | | |
| | | <view class="input-content"> |
| | | <van-field |
| | | <u-textarea |
| | | v-model="approvalOpinion" |
| | | type="textarea" |
| | | rows="4" |
| | | placeholder="请输入审核意见" |
| | | maxlength="200" |
| | | show-word-limit |
| | | count |
| | | /> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 底部操作按钮 --> |
| | | <view v-if="canApprove" class="footer-actions"> |
| | | <van-button class="reject-btn" @click="handleReject">驳回</van-button> |
| | | <van-button class="approve-btn" @click="handleApprove">通过</van-button> |
| | | <u-button class="reject-btn" @click="handleReject">驳回</u-button> |
| | | <u-button class="approve-btn" @click="handleApprove">通过</u-button> |
| | | </view> |
| | | </view> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, onMounted, computed } from 'vue' |
| | | import { approveProcessGetInfo, approveProcessDetails, updateApproveNode } from '@/api/collaborativeApproval/approvalProcess' |
| | | import { |
| | | approveProcessGetInfo, |
| | | approveProcessDetails, |
| | | updateApproveNode, |
| | | stockInOrderInfo, |
| | | stockInProductList |
| | | } from '@/api/collaborativeApproval/approvalProcess' |
| | | import useUserStore from '@/store/modules/user' |
| | | import { showToast } from 'vant' |
| | | const showToast = (message) => { |
| | | uni.showToast({ |
| | | title: message, |
| | | icon: 'none' |
| | | }) |
| | | } |
| | | import PageHeader from "@/components/PageHeader.vue"; |
| | | |
| | | const userStore = useUserStore() |
| | |
| | | const approvalSteps = ref([]) |
| | | const approvalOpinion = ref('') |
| | | const approveId = ref('') |
| | | const stockInOrderInfoData = ref({}) |
| | | const stockInProducts = ref([]) |
| | | const stockInCollapsed = ref(false) |
| | | |
| | | // 从详情接口字段对齐 canApprove:仅当有 isShen 的节点时可审批 |
| | | const canApprove = computed(() => { |
| | |
| | | }) |
| | | |
| | | onMounted(() => { |
| | | const pages = getCurrentPages() |
| | | const currentPage = pages[pages.length - 1] |
| | | approveId.value = currentPage.options.approveId |
| | | approveId.value = uni.getStorageSync('approveId') |
| | | if (approveId.value) { |
| | | loadApprovalData() |
| | | } |
| | |
| | | // 基本申请信息 |
| | | approveProcessGetInfo({ id: approveId.value }).then(res => { |
| | | approvalData.value = res.data || {} |
| | | if (approvalData.value.approveType === 9) { |
| | | loadStockInInfo() |
| | | } else { |
| | | stockInOrderInfoData.value = {} |
| | | stockInProducts.value = [] |
| | | } |
| | | }) |
| | | // 审批节点详情 |
| | | approveProcessDetails(approveId.value).then(res => { |
| | |
| | | }) |
| | | } |
| | | |
| | | const loadStockInInfo = () => { |
| | | const query = { approveId: approveId.value, id: approveId.value } |
| | | Promise.all([stockInOrderInfo(query), stockInProductList(query)]) |
| | | .then(([orderRes, productRes]) => { |
| | | const orderInfo = orderRes?.data?.orderInfo || {} |
| | | stockInOrderInfoData.value = orderInfo |
| | | stockInProducts.value = Array.isArray(productRes?.data) ? productRes.data : [] |
| | | }) |
| | | .catch(() => { |
| | | stockInOrderInfoData.value = {} |
| | | stockInProducts.value = [] |
| | | }) |
| | | } |
| | | |
| | | const toggleStockInCollapse = () => { |
| | | stockInCollapsed.value = !stockInCollapsed.value |
| | | } |
| | | |
| | | const goBack = () => { |
| | | uni.removeStorageSync('approveId'); |
| | | uni.navigateBack() |
| | | } |
| | | |
| | |
| | | margin: 16px; |
| | | border-radius: 12px; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .stockin-info { |
| | | background: #fff; |
| | | margin: 16px; |
| | | border-radius: 12px; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .stockin-header { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | } |
| | | |
| | | .collapse-text { |
| | | font-size: 10px; |
| | | color: #666; |
| | | } |
| | | |
| | | .stockin-table { |
| | | border-top: 1px solid #f0f0f0; |
| | | } |
| | | |
| | | .stockin-row { |
| | | display: grid; |
| | | grid-template-columns: 22% 28% 22% 28%; |
| | | } |
| | | |
| | | .stockin-label { |
| | | font-size: 11px; |
| | | color: #666; |
| | | padding: 12px 10px; |
| | | background: #f7f8fa; |
| | | border-right: 1px solid #f0f0f0; |
| | | border-bottom: 1px solid #f0f0f0; |
| | | } |
| | | |
| | | .stockin-value { |
| | | font-size: 11px; |
| | | color: #333; |
| | | padding: 12px 10px; |
| | | border-right: 1px solid #f0f0f0; |
| | | border-bottom: 1px solid #f0f0f0; |
| | | word-break: break-all; |
| | | } |
| | | |
| | | .stockin-row .stockin-value:last-child, |
| | | .stockin-row .stockin-label:last-child { |
| | | border-right: none; |
| | | } |
| | | |
| | | .process-header { |
| | |
| | | } |
| | | |
| | | .reject-btn { |
| | | width: 120px; |
| | | background: #ff4d4f; |
| | | color: #fff; |
| | | border: none; |
| | | } |
| | | width: 120px; |
| | | background: #ff4d4f; |
| | | color: #fff; |
| | | } |
| | | |
| | | .approve-btn { |
| | | width: 120px; |
| | | background: #52c41a; |
| | | color: #fff; |
| | | border: none; |
| | | } |
| | | .approve-btn { |
| | | width: 120px; |
| | | background: #52c41a; |
| | | color: #fff; |
| | | } |
| | | |
| | | /* 适配u-button样式 */ |
| | | :deep(.u-button) { |
| | | border-radius: 6px; |
| | | } |
| | | |
| | | @keyframes pulse { |
| | | 0% { |