From 8c01075060e396ae93b3fbb1f1db59903d2acf9c Mon Sep 17 00:00:00 2001
From: huminmin <mac@MacBook-Pro.local>
Date: 星期三, 10 六月 2026 14:40:14 +0800
Subject: [PATCH] 新增/编辑台账。新增台账的表单换成跳转到页面新增,否则表单太小查看很不方便。新增完成之后再回到台账页面。需要汇总出数量、结算单片面积、面积。

---
 src/views/salesManagement/salesLedger/index.vue |  904 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/components/Dialog/FormDialog.vue            |    6 
 2 files changed, 899 insertions(+), 11 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 ea29a62..b79d143 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">
@@ -348,10 +1055,12 @@
                   :limit="page.size"
                   @pagination="paginationChange" />
     </div>
-    <FormDialog v-model="dialogFormVisible"
+    </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">
@@ -507,7 +1216,7 @@
                   border
                   @selection-change="productSelected"
                   show-summary
-                  :summary-method="summarizeMainTable">
+                  :summary-method="summarizeProductTable">
           <el-table-column align="center"
                            type="selection"
                            width="55"
@@ -1769,7 +2478,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";
@@ -1814,10 +2523,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([]);
@@ -1861,6 +2573,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)
@@ -3074,7 +3799,7 @@
         if (res.newLedgerIds.length === 1) {
           const newId = res.newLedgerIds[0];
           getSalesLedgerWithProducts({ id: newId, type: 1 }).then(detail => {
-            openFormWithPreFill(detail);
+            enterAddPage(detail);
           });
         }
       }
@@ -3113,11 +3838,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 => {
@@ -3138,7 +3864,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 => {
@@ -3614,8 +4340,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;
@@ -3868,6 +4702,10 @@
         delete submitPayload.paymentMethod;
         addOrUpdateSalesLedger(submitPayload).then(res => {
           proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+          if (isFormPageMode.value) {
+            exitFormPage(true);
+            return;
+          }
           closeDia();
           getList();
         });
@@ -3875,11 +4713,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);
@@ -5180,6 +6023,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;
@@ -5241,6 +6122,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