From 16946ce59ff3218c8a271e55826bc69a1af55408 Mon Sep 17 00:00:00 2001
From: liding <756868258@qq.com>
Date: 星期三, 10 六月 2026 17:19:11 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_河南_鹤壁天沐玻璃厂' into dev_河南_鹤壁天沐玻璃厂
---
src/views/salesManagement/salesLedger/index.vue | 1087 +++++++++++++++++++++++++++++++++++++++++++++++---------
src/components/Dialog/FormDialog.vue | 6
2 files changed, 908 insertions(+), 185 deletions(-)
diff --git a/src/components/Dialog/FormDialog.vue b/src/components/Dialog/FormDialog.vue
index 3c6a40d..a9ec7b4 100644
--- a/src/components/Dialog/FormDialog.vue
+++ b/src/components/Dialog/FormDialog.vue
@@ -14,7 +14,7 @@
@click="handleConfirm">
纭
</el-button>
- <el-button :disabled="loading" @click="handleCancel">鍙栨秷</el-button>
+ <el-button :disabled="loading" @click="handleCancel">{{ cancelButtonText }}</el-button>
</slot>
</div>
</template>
@@ -56,6 +56,9 @@
// 璇︽儏妯″紡涓嶅睍绀衡�滅‘璁も�濇寜閽紝鍏跺畠绫诲瀷姝e父鏄剧ず
const showConfirm = computed(() => props.operationType !== "detail");
+ const cancelButtonText = computed(() =>
+ props.operationType === "detail" ? "鍏抽棴" : "鍙栨秷"
+ );
const computedTitle = computed(() => {
if (typeof props.title === "function") {
@@ -83,4 +86,3 @@
text-align: center;
}
</style>
-
diff --git a/src/views/salesManagement/salesLedger/index.vue b/src/views/salesManagement/salesLedger/index.vue
index 3498e5c..be72749 100644
--- a/src/views/salesManagement/salesLedger/index.vue
+++ b/src/views/salesManagement/salesLedger/index.vue
@@ -1,5 +1,712 @@
<template>
<div class="app-container">
+ <template v-if="isFormPageMode">
+ <div class="sales-ledger-page-header">
+ <div>
+ <el-button class="sales-ledger-page-back"
+ @click="exitFormPage()">杩斿洖鍙拌处</el-button>
+ <div class="sales-ledger-page-title">{{ pageFormTitle }}</div>
+ <div class="sales-ledger-page-subtitle">{{ pageFormSubtitle }}</div>
+ </div>
+ </div>
+ <div class="sales-ledger-page-form">
+ <el-form :model="form"
+ label-width="140px"
+ label-position="top"
+ :rules="rules"
+ @keydown.capture="handleTabScrollFollow"
+ ref="formRef">
+ <el-row v-if="operationType === 'add'"
+ style="margin-bottom: 10px;">
+ <el-col :span="24"
+ style="text-align: right;">
+ <el-button type="primary"
+ plain
+ @click="openQuotationDialog">
+ 浠庨攢鍞姤浠峰鍏�
+ </el-button>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="閿�鍞悎鍚屽彿锛�"
+ prop="salesContractNo">
+ <el-input v-model="form.salesContractNo"
+ placeholder="鑷姩鐢熸垚"
+ clearable
+ disabled />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="涓氬姟鍛橈細"
+ prop="salesman">
+ <el-select v-model="form.salesman"
+ placeholder="璇烽�夋嫨"
+ clearable
+ :disabled="isReviewedEdit">
+ <el-option v-for="item in userList"
+ :key="item.nickName"
+ :label="item.nickName"
+ :value="item.nickName" />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="瀹㈡埛鍚嶇О锛�"
+ prop="customerId">
+ <el-select v-model="form.customerId"
+ filterable
+ placeholder="璇烽�夋嫨"
+ clearable
+ :disabled="isReviewedEdit">
+ <el-option v-for="item in customerOption"
+ :key="item.id"
+ :label="item.customerName"
+ :value="item.id">
+ {{ item.customerName + (item.taxpayerIdentificationNumber ? "鈥斺��" + item.taxpayerIdentificationNumber : "") }}
+ </el-option>
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="椤圭洰鍚嶇О锛�"
+ prop="projectName">
+ <el-input v-model="form.projectName"
+ placeholder="璇疯緭鍏�"
+ clearable
+ :disabled="isReviewedEdit" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="绛捐鏃ユ湡锛�"
+ prop="executionDate">
+ <el-date-picker style="width: 100%"
+ v-model="form.executionDate"
+ value-format="YYYY-MM-DD"
+ format="YYYY-MM-DD"
+ type="date"
+ placeholder="璇烽�夋嫨"
+ clearable
+ :disabled="isReviewedEdit" />
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="浜よ揣鏃ユ湡锛�"
+ prop="deliveryDate">
+ <el-date-picker style="width: 100%"
+ v-model="form.deliveryDate"
+ value-format="YYYY-MM-DD"
+ format="YYYY-MM-DD"
+ type="date"
+ placeholder="璇烽�夋嫨"
+ clearable
+ :disabled="isReviewedEdit" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="12">
+ <el-form-item label="褰曞叆浜猴細"
+ prop="entryPerson">
+ <el-select v-model="form.entryPerson"
+ filterable
+ default-first-option
+ :reserve-keyword="false"
+ placeholder="璇烽�夋嫨"
+ clearable
+ @change="changs"
+ :disabled="isReviewedEdit">
+ <el-option v-for="item in userList"
+ :key="item.userId"
+ :label="item.nickName"
+ :value="item.userId" />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="褰曞叆鏃ユ湡锛�"
+ prop="entryDate">
+ <el-date-picker style="width: 100%"
+ v-model="form.entryDate"
+ value-format="YYYY-MM-DD"
+ format="YYYY-MM-DD"
+ type="date"
+ placeholder="璇烽�夋嫨"
+ clearable
+ :disabled="isReviewedEdit" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row>
+ <el-form-item label="浜у搧淇℃伅锛�"
+ prop="entryDate">
+ <el-button type="primary"
+ :disabled="hasEditingProductRow() || isReviewedEdit"
+ @click="addProductInline">
+ 娣诲姞
+ </el-button>
+ <el-button plain
+ type="danger"
+ :disabled="isReviewedEdit"
+ @click="deleteProduct">鍒犻櫎</el-button>
+ </el-form-item>
+ </el-row>
+ <el-table :data="productData"
+ border
+ @selection-change="productSelected"
+ show-summary
+ :summary-method="summarizeProductTable">
+ <el-table-column align="center"
+ type="selection"
+ width="55"
+ :selectable="(row) => !isProductShipped(row)" />
+ <el-table-column align="center"
+ label="搴忓彿"
+ type="index"
+ width="60" />
+ <el-table-column label="浜у搧澶х被"
+ prop="productCategory"
+ min-width="160">
+ <template #default="scope">
+ <el-tree-select v-if="scope.row.__editing"
+ v-model="scope.row.__productCategoryId"
+ placeholder="璇烽�夋嫨"
+ clearable
+ filterable
+ check-strictly
+ :data="productOptions"
+ :render-after-expand="false"
+ style="width: 100%"
+ :filter-node-method="filterProductCategoryNode"
+ @change="(val) => handleInlineProductCategoryChange(scope.row, val)"
+ :disabled="isReviewedEdit" />
+ <span v-else>{{ scope.row.productCategory ?? "" }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column label="瑙勬牸鍨嬪彿"
+ prop="specificationModel"
+ min-width="200">
+ <template #default="scope">
+ <el-select v-if="scope.row.__editing"
+ v-model="scope.row.productModelId"
+ placeholder="璇烽�夋嫨"
+ clearable
+ filterable
+ style="width: 100%"
+ @change="(val) => handleInlineProductModelChange(scope.row, val)"
+ :disabled="isReviewedEdit">
+ <el-option v-for="item in modelOptions"
+ :key="item.id"
+ :label="item.model"
+ :value="item.id" />
+ </el-select>
+ <span v-else>{{ scope.row.specificationModel ?? "" }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column label="鍘氬害(mm)"
+ prop="thickness"
+ min-width="160">
+ <template #default="scope">
+ <el-input-number v-if="scope.row.__editing"
+ controls-position="right"
+ v-model="scope.row.thickness"
+ :min="0"
+ :step="1"
+ :precision="2"
+ style="width: 100%"
+ placeholder="璇疯緭鍏�"
+ clearable
+ :disabled="isReviewedEdit" />
+ <span v-else>{{ scope.row.thickness ?? "" }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column label="妤煎眰缂栧彿"
+ prop="floorCode"
+ min-width="250"
+ show-overflow-tooltip>
+ <template #default="scope">
+ <el-input v-if="scope.row.__editing"
+ v-model="scope.row.floorCode"
+ placeholder="璇疯緭鍏�"
+ clearable
+ style="width: 100%"
+ :disabled="isReviewedEdit" />
+ <span v-else>{{ scope.row.floorCode ?? "" }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column label="鍚◣鍗曚环(鍏�)"
+ prop="taxInclusiveUnitPrice"
+ min-width="160">
+ <template #default="scope">
+ <el-input-number v-if="scope.row.__editing"
+ :step="0.01"
+ :min="0"
+ :precision="2"
+ style="width: 100%"
+ v-model="scope.row.taxInclusiveUnitPrice"
+ placeholder="璇疯緭鍏�"
+ clearable
+ @change="() => handleInlineUnitPriceChange(scope.row)"
+ @input="() => handleInlineUnitPriceChange(scope.row)" />
+ <span v-else>{{ formattedNumber(null, null, scope.row.taxInclusiveUnitPrice) }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column label="瀹�(mm)"
+ prop="width"
+ min-width="160">
+ <template #default="scope">
+ <el-input-number v-if="scope.row.__editing"
+ controls-position="right"
+ v-model="scope.row.width"
+ :min="0"
+ :step="1"
+ :precision="2"
+ style="width:100%"
+ placeholder="璇疯緭鍏�"
+ clearable
+ @change="() => handleInlineSizeChange(scope.row)"
+ @input="() => handleInlineSizeChange(scope.row)"
+ :disabled="isReviewedEdit" />
+ <span v-else>{{ scope.row.width ?? "" }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column label="楂�(mm)"
+ prop="height"
+ min-width="160">
+ <template #default="scope">
+ <el-input-number v-if="scope.row.__editing"
+ controls-position="right"
+ v-model="scope.row.height"
+ :min="0"
+ :step="1"
+ :precision="2"
+ style="width: 100%"
+ placeholder="璇疯緭鍏�"
+ clearable
+ @change="() => handleInlineSizeChange(scope.row)"
+ @input="() => handleInlineSizeChange(scope.row)"
+ :disabled="isReviewedEdit" />
+ <span v-else>{{ scope.row.height ?? "" }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column label="鏁伴噺"
+ prop="quantity"
+ min-width="150">
+ <template #default="scope">
+ <el-input-number v-if="scope.row.__editing"
+ controls-position="right"
+ v-model="scope.row.quantity"
+ :step="1"
+ :min="0"
+ :precision="0"
+ style="width: 100%"
+ placeholder="璇疯緭鍏�"
+ clearable
+ @change="() => handleInlineQuantityChange(scope.row)"
+ @input="() => handleInlineQuantityChange(scope.row)"
+ :disabled="isReviewedEdit" />
+ <span v-else>{{ scope.row.quantity ?? "" }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column label="缁撶畻鍗曠墖闈㈢Н(銕�)"
+ prop="settlePieceArea"
+ min-width="200">
+ <template #default="scope">
+ <el-input-number v-if="scope.row.__editing"
+ controls-position="right"
+ v-model="scope.row.settlePieceArea"
+ :min="0"
+ :step="1"
+ :precision="4"
+ style="width: 100%"
+ placeholder="璇疯緭鍏�"
+ clearable
+ @change="() => handleInlineSettleAreaChange(scope.row)"
+ :disabled="isReviewedEdit" />
+ <span v-else>{{ scope.row.settlePieceArea ? Number(scope.row.settlePieceArea).toFixed(4) : "" }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column label="闈㈢Н(m虏)"
+ prop="actualTotalArea"
+ min-width="200">
+ <template #default="scope">
+ <el-input-number v-if="scope.row.__editing"
+ controls-position="right"
+ v-model="scope.row.actualTotalArea"
+ :min="0"
+ :step="1"
+ :precision="4"
+ style="width: 100%"
+ placeholder="鑷姩璁$畻"
+ :disabled="isReviewedEdit" />
+ <span v-else>{{ scope.row.actualTotalArea ? Number(scope.row.actualTotalArea).toFixed(4) : "" }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column label="绋庣巼(%)"
+ prop="taxRate"
+ min-width="120">
+ <template #default="scope">
+ <el-select v-if="scope.row.__editing"
+ v-model="scope.row.taxRate"
+ placeholder="璇烽�夋嫨"
+ clearable
+ style="width: 100%"
+ @change="() => handleInlineTaxRateChange(scope.row)"
+ :disabled="isReviewedEdit">
+ <el-option label="1"
+ value="1" />
+ <el-option label="3"
+ value="3" />
+ <el-option label="6"
+ value="6" />
+ <el-option label="9"
+ value="9" />
+ <el-option label="13"
+ value="13" />
+ </el-select>
+ <span v-else>{{ scope.row.taxRate ?? "" }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column label="鍚◣鎬讳环(鍏�)"
+ prop="taxInclusiveTotalPrice"
+ :formatter="formattedNumber"
+ min-width="120" />
+ <el-table-column label="涓嶅惈绋庢�讳环(鍏�)"
+ prop="taxExclusiveTotalPrice"
+ :formatter="formattedNumber"
+ min-width="120" />
+ <el-table-column label="鍔犲伐瑕佹眰"
+ prop="processRequirement"
+ min-width="160"
+ show-overflow-tooltip>
+ <template #default="scope">
+ <el-input v-if="scope.row.__editing"
+ v-model="scope.row.processRequirement"
+ placeholder="璇疯緭鍏�"
+ clearable
+ style="width: 100%"
+ :disabled="isReviewedEdit" />
+ <span v-else>{{ scope.row.processRequirement ?? "" }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column label="鍙戠エ绫诲瀷"
+ prop="invoiceType"
+ min-width="120">
+ <template #default="scope">
+ <el-select v-if="scope.row.__editing"
+ v-model="scope.row.invoiceType"
+ placeholder="璇烽�夋嫨"
+ clearable
+ style="width: 100%"
+ :disabled="isReviewedEdit">
+ <el-option label="澧炴櫘绁�"
+ value="澧炴櫘绁�" />
+ <el-option label="澧炰笓绁�"
+ value="澧炰笓绁�" />
+ </el-select>
+ <span v-else>{{ scope.row.invoiceType ?? "" }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column label="澶囨敞"
+ prop="remark"
+ min-width="140"
+ show-overflow-tooltip>
+ <template #default="scope">
+ <el-input v-if="scope.row.__editing"
+ v-model="scope.row.remark"
+ placeholder="璇疯緭鍏�"
+ clearable
+ style="width: 100%"
+ :disabled="isReviewedEdit" />
+ <span v-else>{{ scope.row.remark ?? "" }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column label="閲嶇"
+ prop="heavyBox"
+ min-width="100">
+ <template #default="scope">
+ <el-input v-if="scope.row.__editing"
+ v-model="scope.row.heavyBox"
+ placeholder="璇疯緭鍏�"
+ clearable
+ style="width: 100%"
+ :disabled="isReviewedEdit" />
+ <span v-else>{{ scope.row.heavyBox ?? "" }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column fixed="right"
+ label="鎿嶄綔"
+ min-width="220"
+ align="center">
+ <template #default="scope">
+ <template v-if="scope.row.__editing">
+ <el-button link
+ type="primary"
+ size="small"
+ @click="saveProductInline(scope.row, scope.$index)">淇濆瓨</el-button>
+ <el-button link
+ type="danger"
+ size="small"
+ @click="cancelProductInline(scope.row, scope.$index)">鍙栨秷</el-button>
+ <el-popover :width="560"
+ trigger="click"
+ :hide-after="0"
+ :visible="scope.row.__otherAmountPopoverVisible"
+ @update:visible="(val) => handleOtherAmountPopoverVisibleChange(scope.row, val)">
+ <template #reference>
+ <el-button link
+ type="primary"
+ size="small"
+ @click="openOtherAmountInline(scope.row)">
+ 棰濆鍔犲伐({{ (scope.row.salesProductProcessList || []).length || 0 }})
+ </el-button>
+ </template>
+ <div style="display:flex; align-items:center; justify-content:space-between; gap: 10px; margin-bottom: 8px;">
+ <div style="font-weight: 600; color:#303133;">
+ 棰濆鍔犲伐
+ </div>
+ <el-button type="primary"
+ plain
+ size="small"
+ :disabled="isReviewedEdit"
+ @click="startAddOtherAmountForRow(scope.row)">
+ 鏂板
+ </el-button>
+ </div>
+ <div v-if="scope.row.__inlineOtherAmountAdding"
+ style="display:flex; flex-direction:column; gap: 8px; margin-bottom: 10px;"
+ @click.stop>
+ <el-select v-model="scope.row.__inlineOtherAmountAddId"
+ filterable
+ clearable
+ placeholder="璇烽�夋嫨棰濆鍔犲伐椤圭洰"
+ style="width: 100%;">
+ <el-option v-for="item in otherAmountSelectOptions"
+ :key="item.id"
+ :label="item.processName"
+ :value="item.id" />
+ </el-select>
+ <div style="display:flex; justify-content:flex-end; gap: 8px;">
+ <el-button size="small"
+ @click="scope.row.__inlineOtherAmountAdding = false; scope.row.__inlineOtherAmountAddId = null">
+ 鍙栨秷
+ </el-button>
+ <el-button type="primary"
+ size="small"
+ :disabled="isReviewedEdit || scope.row.__inlineOtherAmountAddId === null || scope.row.__inlineOtherAmountAddId === undefined || scope.row.__inlineOtherAmountAddId === ''"
+ @click="confirmAddOtherAmountForRow(scope.row)">
+ 纭娣诲姞
+ </el-button>
+ </div>
+ </div>
+ <div v-if="Array.isArray(scope.row.salesProductProcessList) && scope.row.salesProductProcessList.length > 0"
+ style="display:flex; flex-wrap:wrap; gap: 8px;">
+ <div v-for="(item, idx) in scope.row.salesProductProcessList"
+ :key="String(item.id) + '_' + idx"
+ style="display:flex; align-items:center; gap: 8px; flex: 0 0 calc(50% - 4px); max-width: calc(50% - 4px);">
+ <el-tag type="info"
+ style="max-width: 170px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;">
+ {{ item.processName }}
+ </el-tag>
+ <el-input-number v-model="item.quantity"
+ :min="0"
+ :step="1"
+ :precision="0"
+ style="width: 120px;"
+ placeholder="鏁伴噺"
+ :disabled="isReviewedEdit"
+ @change="handleOtherAmountQuantityChange(scope.row)" />
+ <el-button type="danger"
+ link
+ size="small"
+ :disabled="isReviewedEdit"
+ @click="removeOtherAmountAtForRow(scope.row, idx)">
+ 鍒犻櫎
+ </el-button>
+ </div>
+ </div>
+ <div v-else
+ style="color:#909399; font-size: 13px;">
+ 鏆傛棤棰濆鍔犲伐
+ </div>
+ </el-popover>
+ </template>
+ <template v-else>
+ <el-button v-if="isReviewedEdit"
+ link
+ type="primary"
+ size="small"
+ :disabled="isProductShipped(scope.row)"
+ @click="editPriceOnly(scope.row)">
+ 淇敼鍗曚环
+ </el-button>
+ <template v-if="!isReviewedEdit">
+ <el-button link
+ type="primary"
+ size="small"
+ :disabled="isProductShipped(scope.row)"
+ @click="editProductInline(scope.row, scope.$index)">
+ 缂栬緫
+ </el-button>
+ <el-button link
+ type="primary"
+ size="small"
+ :disabled="isProductShipped(scope.row)"
+ @click="copyProductInline(scope.row, scope.$index)">
+ 澶嶅埗鏂板缓
+ </el-button>
+ </template>
+ <el-popover :width="560"
+ trigger="click"
+ :hide-after="0"
+ :visible="scope.row.__otherAmountPopoverVisible"
+ @update:visible="(val) => handleOtherAmountPopoverVisibleChange(scope.row, val)">
+ <template #reference>
+ <el-button link
+ type="primary"
+ size="small"
+ :disabled="isProductShipped(scope.row)"
+ @click="openOtherAmountInline(scope.row)">
+ 棰濆鍔犲伐({{ (scope.row.salesProductProcessList || []).length || 0 }})
+ </el-button>
+ </template>
+ <div style="display:flex; align-items:center; justify-content:space-between; gap: 10px; margin-bottom: 8px;">
+ <div style="font-weight: 600; color:#303133;">
+ 棰濆鍔犲伐
+ </div>
+ <el-button type="primary"
+ plain
+ size="small"
+ :disabled="isProductShipped(scope.row) || isReviewedEdit"
+ @click="startAddOtherAmountForRow(scope.row)">
+ 鏂板
+ </el-button>
+ </div>
+ <div v-if="scope.row.__inlineOtherAmountAdding"
+ style="display:flex; flex-direction:column; gap: 8px; margin-bottom: 10px;"
+ @click.stop>
+ <el-select v-model="scope.row.__inlineOtherAmountAddId"
+ filterable
+ clearable
+ placeholder="璇烽�夋嫨棰濆鍔犲伐椤圭洰"
+ style="width: 100%;"
+ :disabled="isProductShipped(scope.row) || isReviewedEdit">
+ <el-option v-for="item in otherAmountSelectOptions"
+ :key="item.id"
+ :label="item.processName"
+ :value="item.id" />
+ </el-select>
+ <div style="display:flex; justify-content:flex-end; gap: 8px;">
+ <el-button size="small"
+ :disabled="isProductShipped(scope.row) || isReviewedEdit"
+ @click="scope.row.__inlineOtherAmountAdding = false; scope.row.__inlineOtherAmountAddId = null">
+ 鍙栨秷
+ </el-button>
+ <el-button type="primary"
+ size="small"
+ :disabled="isProductShipped(scope.row) || isReviewedEdit || scope.row.__inlineOtherAmountAddId === null || scope.row.__inlineOtherAmountAddId === undefined || scope.row.__inlineOtherAmountAddId === ''"
+ @click="confirmAddOtherAmountForRow(scope.row)">
+ 纭娣诲姞
+ </el-button>
+ </div>
+ </div>
+ <div v-if="Array.isArray(scope.row.salesProductProcessList) && scope.row.salesProductProcessList.length > 0"
+ style="display:flex; flex-wrap:wrap; gap: 8px;">
+ <div v-for="(item, idx) in scope.row.salesProductProcessList"
+ :key="String(item.id) + '_' + idx"
+ style="display:flex; align-items:center; gap: 8px; flex: 0 0 calc(50% - 4px); max-width: calc(50% - 4px);">
+ <el-tag type="info"
+ style="max-width: 170px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;">
+ {{ item.processName }}
+ </el-tag>
+ <el-input-number v-model="item.quantity"
+ :min="0"
+ :step="1"
+ :precision="0"
+ style="width: 120px;"
+ placeholder="鏁伴噺"
+ :disabled="isProductShipped(scope.row) || isReviewedEdit"
+ @change="handleOtherAmountQuantityChange(scope.row)" />
+ <el-button type="danger"
+ link
+ size="small"
+ :disabled="isProductShipped(scope.row) || isReviewedEdit"
+ @click="removeOtherAmountAtForRow(scope.row, idx)">
+ 鍒犻櫎
+ </el-button>
+ </div>
+ </div>
+ <div v-else
+ style="color:#909399; font-size: 13px;">
+ 鏆傛棤棰濆鍔犲伐
+ </div>
+ </el-popover>
+ </template>
+ </template>
+ </el-table-column>
+ </el-table>
+ <el-row :gutter="30">
+ <el-col :span="24">
+ <el-form-item label="澶囨敞锛�"
+ prop="remarks">
+ <el-input v-model="form.remarks"
+ placeholder="璇疯緭鍏�"
+ clearable
+ type="textarea"
+ :rows="2"
+ :disabled="isReviewedEdit" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="24">
+ <el-form-item label="瀹㈡埛澶囨敞锛�"
+ prop="customerRemarks">
+ <el-input v-model="form.customerRemarks"
+ placeholder="璇疯緭鍏�"
+ clearable
+ type="textarea"
+ :rows="2"
+ :disabled="isReviewedEdit" />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="24">
+ <el-form-item label="闄勪欢鏉愭枡锛�"
+ prop="salesLedgerFiles">
+ <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">涓婁紶</el-button>
+ <template #tip>
+ <div class="el-upload__tip">
+ 鏂囦欢鏍煎紡鏀寔
+ doc锛宒ocx锛寈ls锛寈lsx锛宲pt锛宲ptx锛宲df锛宼xt锛寈ml锛宩pg锛宩peg锛宲ng锛実if锛宐mp锛宺ar锛寊ip锛�7z
+ </div>
+ </template>
+ </el-upload>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <div class="sales-ledger-page-actions">
+ <el-button type="primary" @click="submitForm">鎻愪氦</el-button>
+ </div>
+ </el-form>
+ </div>
+ </template>
+ <template v-else>
<div class="search_form">
<el-form :model="searchForm"
:inline="true">
@@ -180,187 +887,30 @@
border
v-loading="tableLoading"
@selection-change="handleSelectionChange"
- :expand-row-keys="expandedRowKeys"
:row-key="(row) => row.id"
:row-class-name="tableRowClassName"
show-summary
style="width: 100%"
:summary-method="summarizeMainTable"
- @expand-change="expandChange"
height="calc(100vh - 22em)">
<el-table-column align="center"
type="selection"
width="55"
fixed="left" />
- <el-table-column type="expand"
- width="60"
- fixed="left">
- <template #default="props">
- <el-table :data="props.row.children"
- border
- show-summary
- :summary-method="summarizeChildrenTable">
- <el-table-column align="center"
- label="搴忓彿"
- type="index" />
- <el-table-column label="妤煎眰缂栧彿"
- prop="floorCode"
- min-width="100"
- show-overflow-tooltip />
- <el-table-column label="浜у搧澶х被"
- prop="productCategory" />
- <el-table-column label="瑙勬牸鍨嬪彿"
- prop="specificationModel" />
- <el-table-column label="鍘氬害"
- prop="thickness"
- min-width="90">
- <template #default="scope">
- {{ scope.row.thickness ?? "" }}
- </template>
- </el-table-column>
- <el-table-column label="瀹�(mm)"
- prop="width"
- min-width="80">
- <template #default="scope">
- {{ scope.row.width ?? "" }}
- </template>
- </el-table-column>
- <el-table-column label="楂�(mm)"
- prop="height"
- min-width="80">
- <template #default="scope">
- {{ scope.row.height ?? "" }}
- </template>
- </el-table-column>
- <el-table-column label="鍛ㄩ暱(cm)"
- prop="perimeter"
- min-width="90">
- <template #default="scope">
- {{ scope.row.perimeter ?? "" }}
- </template>
- </el-table-column>
- <el-table-column label="鎬婚潰绉�(m虏)"
- prop="actualTotalArea"
- min-width="100">
- <template #default="scope">
- {{ scope.row.actualTotalArea ?? "" }}
- </template>
- </el-table-column>
- <el-table-column label="鍔犲伐瑕佹眰"
- prop="processRequirement"
- min-width="120"
- show-overflow-tooltip />
- <el-table-column label="澶囨敞"
- prop="remark"
- min-width="120"
- show-overflow-tooltip />
- <el-table-column label="閲嶇"
- prop="heavyBox"
- min-width="80">
- <template #default="scope">
- {{ scope.row.heavyBox ?? "" }}
- </template>
- </el-table-column>
- <el-table-column label="浜у搧鐘舵��"
- width="100px"
- align="center">
- <template #default="scope">
- <el-tag v-if="scope.row.approveStatus === 1 && (!scope.row.shippingDate || !scope.row.shippingCarNumber)"
- type="success">鍏呰冻</el-tag>
- <el-tag v-else-if="scope.row.approveStatus === 1 && scope.row.shippingDate && scope.row.shippingCarNumber"
- type="success">宸插嚭搴�</el-tag>
- <el-tag v-else-if="scope.row.approveStatus === 0 && (scope.row.shippingDate || scope.row.shippingCarNumber)"
- type="success">宸插嚭搴�</el-tag>
- <el-tag v-else
- type="danger">涓嶈冻</el-tag>
- </template>
- </el-table-column>
- <el-table-column label="鍏ュ簱鐘舵��"
- width="100px"
- align="center">
- <template #default="scope">
- <el-tag v-if="scope.row.productStockStatus == 1"
- type="warning">閮ㄥ垎鍏ュ簱</el-tag>
- <el-tag v-else-if="scope.row.productStockStatus == 2"
- type="success">宸插叆搴�</el-tag>
- <el-tag v-else-if="scope.row.productStockStatus == 0"
- type="info">鏈叆搴�</el-tag>
- <el-tag v-else
- type="danger">鏈叆搴�</el-tag>
- </template>
- </el-table-column>
- <!-- <el-table-column label="鍙戣揣鐘舵��" width="140" align="center">
- <template #default="scope">
- <el-tag :type="getShippingStatusType(scope.row)" size="small">
- {{ getShippingStatusText(scope.row) }}
- </el-tag>
- </template>
- </el-table-column> -->
- <el-table-column label="蹇�掑叕鍙�"
- prop="expressCompany"
- show-overflow-tooltip />
- <el-table-column label="蹇�掑崟鍙�"
- prop="expressNumber"
- show-overflow-tooltip />
- <el-table-column label="鍙戣揣杞︾墝"
- minWidth="100px"
- align="center">
- <template #default="scope">
- <div>
- <el-tag type="success"
- v-if="scope.row.shippingCarNumber">{{ scope.row.shippingCarNumber }}</el-tag>
- <el-tag v-else
- type="info">-</el-tag>
- </div>
- </template>
- </el-table-column>
- <el-table-column label="鍙戣揣鏃ユ湡"
- minWidth="100px"
- align="center">
- <template #default="scope">
- <div>
- <div v-if="scope.row.shippingDate">{{ scope.row.shippingDate }}</div>
- <el-tag v-else
- type="info">-</el-tag>
- </div>
- </template>
- </el-table-column>
- <el-table-column label="鏁伴噺"
- prop="quantity" />
- <el-table-column label="绋庣巼(%)"
- prop="taxRate" />
- <el-table-column label="鍚◣鍗曚环(鍏�)"
- prop="taxInclusiveUnitPrice"
- :formatter="formattedNumber" />
- <el-table-column label="鍚◣鎬讳环(鍏�)"
- prop="taxInclusiveTotalPrice"
- :formatter="formattedNumber" />
- <el-table-column label="涓嶅惈绋庢�讳环(鍏�)"
- prop="taxExclusiveTotalPrice"
- :formatter="formattedNumber" />
- <!--鎿嶄綔-->
- <!-- <el-table-column Width="60px" label="鎿嶄綔" align="center">
- <template #default="scope">
- <el-button
- link
- type="primary"
- :disabled="!canShip(scope.row)"
- @click="openDeliveryForm(scope.row)">
- 鍙戣揣
- </el-button>
- </template>
- </el-table-column> -->
- </el-table>
- </template>
- </el-table-column>
<el-table-column align="center"
label="搴忓彿"
type="index"
width="60" />
- <el-table-column label="閿�鍞悎鍚屽彿"
+ <el-table-column label="璁㈠崟鍙�"
prop="salesContractNo"
width="180"
- show-overflow-tooltip />
+ show-overflow-tooltip>
+ <template #default="scope">
+ <el-button link
+ type="primary"
+ @click="openForm('view', scope.row)">{{ scope.row.salesContractNo || "-" }}</el-button>
+ </template>
+ </el-table-column>
<el-table-column label="瀹㈡埛鍚嶇О"
prop="customerName"
width="300"
@@ -368,10 +918,6 @@
<el-table-column label="涓氬姟鍛�"
prop="salesman"
width="100"
- show-overflow-tooltip />
- <el-table-column label="椤圭洰鍚嶇О"
- prop="projectName"
- width="180"
show-overflow-tooltip />
<el-table-column label="鍚堝悓閲戦(鍏�)"
prop="contractAmount"
@@ -466,10 +1012,6 @@
prop="entryDate"
width="120"
show-overflow-tooltip />
- <el-table-column label="绛捐鏃ユ湡"
- prop="executionDate"
- width="120"
- show-overflow-tooltip />
<el-table-column label="浜や粯鏃ユ湡"
prop="deliveryDate"
width="120"
@@ -512,10 +1054,12 @@
:limit="page.size"
@pagination="paginationChange" />
</div>
- <FormDialog v-model="dialogFormVisible"
- :title="isCompletedOrder ? '鏌ョ湅閿�鍞彴璐﹂〉闈紙宸插畬鎴愶級' : operationType === 'add' ? '鏂板閿�鍞彴璐﹂〉闈�' : '缂栬緫閿�鍞彴璐﹂〉闈�'"
+ </template>
+ <FormDialog v-if="!isFormPageMode"
+ v-model="dialogFormVisible"
+ :title="isCompletedOrder ? '鏌ョ湅閿�鍞彴璐﹂〉闈紙宸插畬鎴愶級' : operationType === 'add' ? '鏂板閿�鍞彴璐﹂〉闈�' : operationType === 'view' ? '鏌ョ湅閿�鍞彴璐﹂〉闈�' : '缂栬緫閿�鍞彴璐﹂〉闈�'"
:width="'70%'"
- :operation-type="isCompletedOrder ? 'detail' : operationType"
+ :operation-type="isCompletedOrder || operationType === 'view' ? 'detail' : operationType"
@close="closeDia"
@confirm="submitForm"
@cancel="closeDia">
@@ -671,7 +1215,7 @@
border
@selection-change="productSelected"
show-summary
- :summary-method="summarizeMainTable">
+ :summary-method="summarizeProductTable">
<el-table-column align="center"
type="selection"
width="55"
@@ -1933,7 +2477,7 @@
<script setup>
import { getToken } from "@/utils/auth";
import pagination from "@/components/PIMTable/Pagination.vue";
- import { onMounted, ref, reactive, getCurrentInstance, watch, nextTick } from "vue";
+ import { onMounted, ref, reactive, getCurrentInstance, watch, nextTick, computed } from "vue";
import { addShippingInfo } from "@/api/salesManagement/deliveryLedger.js";
import { ElMessageBox, ElMessage } from "element-plus";
import { ArrowDown, WarningFilled } from "@element-plus/icons-vue";
@@ -1978,10 +2522,13 @@
import { printSalesDeliveryNote } from "./components/salesDeliveryPrint.js";
import { printSalesLabel } from "./components/salesLabelPrint.js";
import QRCode from "qrcode";
+ import { useRoute, useRouter } from "vue-router";
// import { salesLedgerProductSetProcessFlowConfig } from "@/api/salesManagement/salesProcessFlowConfig.js";
const userStore = useUserStore();
const { proxy } = getCurrentInstance();
+ const route = useRoute();
+ const router = useRouter();
const tableData = ref([]);
const productData = ref([]);
const selectedRows = ref([]);
@@ -2025,6 +2572,19 @@
const ledgerQrDialogVisible = ref(false);
const ledgerQrCompositeUrl = ref("");
const ledgerQrDownloadBaseName = ref("");
+ const pendingAddPrefillDetail = ref(null);
+ const pageMode = computed(() => String(route.query.mode || ""));
+ const isFormPageMode = computed(() =>
+ pageMode.value === "add" || pageMode.value === "edit"
+ );
+ const pageFormTitle = computed(() =>
+ pageMode.value === "edit" ? "缂栬緫閿�鍞彴璐�" : "鏂板閿�鍞彴璐�"
+ );
+ const pageFormSubtitle = computed(() =>
+ pageMode.value === "edit"
+ ? "缂栬緫瀹屾垚鍚庡皢鑷姩杩斿洖閿�鍞彴璐﹀垪琛�"
+ : "鏂板瀹屾垚鍚庡皢鑷姩杩斿洖閿�鍞彴璐﹀垪琛�"
+ );
const sanitizeLedgerQrFilename = s =>
String(s)
@@ -3238,7 +3798,7 @@
if (res.newLedgerIds.length === 1) {
const newId = res.newLedgerIds[0];
getSalesLedgerWithProducts({ id: newId, type: 1 }).then(detail => {
- openFormWithPreFill(detail);
+ enterAddPage(detail);
});
}
}
@@ -3277,11 +3837,12 @@
};
/** 鐢ㄩ濉暟鎹墦寮�鏂板鍙拌处椤甸潰锛堥噸鏂扮敓鎴愬満鏅級 */
- const openFormWithPreFill = async (detail) => {
+ const openFormWithPreFill = async (detail, keepPageMode = false) => {
operationType.value = "add";
form.value = {};
productData.value = [];
selectedQuotation.value = null;
+ fileList.value = [];
let userLists = await userListNoPage();
userList.value = userLists.data;
customerList().then(res => {
@@ -3302,7 +3863,7 @@
form.value.customerRemarks = detail.customerRemarks ?? detail.customer_remarks ?? "";
productData.value = detail.productData || [];
form.value.deliveryDate = dayjs(form.value.entryDate).add(7, "day").format("YYYY-MM-DD");
- dialogFormVisible.value = true;
+ dialogFormVisible.value = !keepPageMode;
};
const paginationChange = obj => {
@@ -3778,8 +4339,116 @@
"taxExclusiveTotalPrice",
]);
};
+ const summarizeProductTable = param => {
+ return proxy.summarizeTable(param, [
+ "quantity",
+ "settlePieceArea",
+ "actualTotalArea",
+ "taxInclusiveTotalPrice",
+ "taxExclusiveTotalPrice",
+ ]);
+ };
+
+ const initAddFormState = async () => {
+ operationType.value = "add";
+ isCompletedOrder.value = false;
+ isReviewedEdit.value = false;
+ form.value = {};
+ productData.value = [];
+ fileList.value = [];
+ selectedQuotation.value = null;
+
+ const userLists = await userListNoPage();
+ userList.value = userLists.data;
+ customerList().then(res => {
+ customerOption.value = res;
+ });
+
+ form.value.entryPerson = userStore.id;
+ form.value.entryDate = getCurrentDate();
+ form.value.executionDate = getCurrentDate();
+ form.value.customerRemarks = "";
+ form.value.deliveryDate = dayjs(form.value.entryDate)
+ .add(7, "day")
+ .format("YYYY-MM-DD");
+ };
+
+ const initEditFormState = async rowId => {
+ operationType.value = "edit";
+ isCompletedOrder.value = false;
+ form.value = {};
+ productData.value = [];
+ fileList.value = [];
+ selectedQuotation.value = null;
+
+ const userLists = await userListNoPage();
+ userList.value = userLists.data;
+ customerList().then(res => {
+ customerOption.value = res;
+ });
+
+ currentId.value = rowId;
+ const res = await getSalesLedgerWithProducts({ id: rowId, type: 1 });
+ form.value = { ...res };
+ form.value.entryPerson = Number(res.entryPerson);
+ form.value.customerRemarks =
+ res?.customerRemarks ?? res?.customer_remarks ?? "";
+ productData.value = form.value.productData || [];
+ fileList.value = form.value.salesLedgerFiles || [];
+ isReviewedEdit.value = Number(res?.reviewStatus) === 1;
+ };
+
+ const enterAddPage = async detail => {
+ pendingAddPrefillDetail.value = detail || null;
+ const query = { ...route.query, mode: "add" };
+ await router.push({ path: route.path, query });
+ };
+
+ const enterEditPage = async row => {
+ const query = { ...route.query, mode: "edit", id: row?.id };
+ await router.push({ path: route.path, query });
+ };
+
+ const exitFormPage = async (shouldRefresh = false) => {
+ const query = { ...route.query };
+ delete query.mode;
+ delete query.id;
+ pendingAddPrefillDetail.value = null;
+ await router.push({ path: route.path, query });
+ closeDia(false);
+ if (shouldRefresh) {
+ getList();
+ }
+ };
+
+ watch(
+ pageMode,
+ async enabled => {
+ if (enabled === "add") {
+ await initAddFormState();
+ if (pendingAddPrefillDetail.value) {
+ await openFormWithPreFill(pendingAddPrefillDetail.value, true);
+ pendingAddPrefillDetail.value = null;
+ }
+ return;
+ }
+ if (enabled === "edit" && route.query.id) {
+ await initEditFormState(route.query.id);
+ }
+ },
+ { immediate: true }
+ );
+
// 鎵撳紑寮规
const openForm = async (type, row) => {
+ if (type === "add") {
+ await enterAddPage();
+ return;
+ }
+ if (type === "edit") {
+ await enterEditPage(row);
+ return;
+ }
// 宸插畬鎴愯鍗曞己鍒朵负鍙妯″紡锛屼絾闄勪欢涓婁紶浠嶅彲鐢�
const isCompleted = Number(row?.orderStatus) === 1;
const effectiveType = isCompleted ? 'view' : type;
@@ -4032,6 +4701,10 @@
delete submitPayload.paymentMethod;
addOrUpdateSalesLedger(submitPayload).then(res => {
proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+ if (isFormPageMode.value) {
+ exitFormPage(true);
+ return;
+ }
closeDia();
getList();
});
@@ -4039,11 +4712,16 @@
});
};
// 鍏抽棴寮规
- const closeDia = () => {
- proxy.resetForm("formRef");
+ const closeDia = (resetFormRef = true) => {
+ if (resetFormRef) {
+ proxy.resetForm("formRef");
+ }
dialogFormVisible.value = false;
isCompletedOrder.value = false;
isReviewedEdit.value = false;
+ if (!isFormPageMode.value) {
+ fileList.value = [];
+ }
};
const productIndex = ref(0);
@@ -5348,6 +6026,44 @@
margin-bottom: 10px;
}
+ .sales-ledger-page-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: flex-start;
+ gap: 16px;
+ margin-bottom: 16px;
+ }
+
+ .sales-ledger-page-title {
+ font-size: 22px;
+ font-weight: 600;
+ color: #303133;
+ line-height: 1.3;
+ }
+
+ .sales-ledger-page-back {
+ margin-bottom: 12px;
+ }
+
+ .sales-ledger-page-subtitle {
+ margin-top: 6px;
+ font-size: 13px;
+ color: #909399;
+ }
+
+ .sales-ledger-page-form {
+ padding: 20px;
+ background: #fff;
+ border-radius: 8px;
+ }
+
+ .sales-ledger-page-actions {
+ display: flex;
+ justify-content: center;
+ gap: 16px;
+ margin-top: 24px;
+ }
+
.ledger-qr-dialog {
text-align: center;
padding-bottom: 8px;
@@ -5409,6 +6125,11 @@
}
@media (max-width: 768px) {
+ .sales-ledger-page-header {
+ flex-direction: column;
+ align-items: stretch;
+ }
+
.approver-node-item {
flex: 0 0 100%;
}
--
Gitblit v1.9.3