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