From c05b81c7f50df80ab247a05f9f92af2d799e77cd Mon Sep 17 00:00:00 2001
From: liding <756868258@qq.com>
Date: 星期五, 10 四月 2026 15:59:04 +0800
Subject: [PATCH] feat:1.销售添加是否生产 2.生产订单添加备注

---
 src/views/salesManagement/salesLedger/index.vue | 1273 +++++++++++++++++++++++++++++++++++++--------------------
 1 files changed, 828 insertions(+), 445 deletions(-)

diff --git a/src/views/salesManagement/salesLedger/index.vue b/src/views/salesManagement/salesLedger/index.vue
index c813ed1..81a8313 100644
--- a/src/views/salesManagement/salesLedger/index.vue
+++ b/src/views/salesManagement/salesLedger/index.vue
@@ -4,15 +4,19 @@
 			<el-form :model="searchForm" :inline="true">
 				<el-form-item label="瀹㈡埛鍚嶇О锛�">
 					<el-input v-model="searchForm.customerName" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
-										@change="handleQuery" />
+						@change="handleQuery" />
 				</el-form-item>
 				<el-form-item label="閿�鍞悎鍚屽彿锛�">
 					<el-input v-model="searchForm.salesContractNo" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
-										@change="handleQuery" />
+						@change="handleQuery" />
+				</el-form-item>
+				<el-form-item label="椤圭洰鍚嶇О锛�">
+					<el-input v-model="searchForm.projectName" placeholder="璇疯緭鍏�" clearable prefix-icon="Search"
+						@change="handleQuery" />
 				</el-form-item>
 				<el-form-item label="褰曞叆鏃ユ湡锛�">
-					<el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
-													placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
+					<el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD"
+						type="daterange" placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
 				</el-form-item>
 				<el-form-item>
 					<el-button type="primary" @click="handleQuery"> 鎼滅储 </el-button>
@@ -26,95 +30,113 @@
 					<el-button type="primary" @click="openForm('add')">
 						鏂板鍙拌处
 					</el-button>
-					<el-button @click="handleImport">瀵煎叆</el-button>
+					<el-button type="primary" plain @click="handleImport">瀵煎叆</el-button>
 					<el-button @click="handleOut">瀵煎嚭</el-button>
 					<el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
 					<el-button type="primary" plain @click="handlePrint">鎵撳嵃</el-button>
 				</div>
 			</div>
 			<el-table :data="tableData" border v-loading="tableLoading" @selection-change="handleSelectionChange"
-								:expand-row-keys="expandedRowKeys" :row-key="(row) => row.id" show-summary style="width: 100%"
-								:summary-method="summarizeMainTable" @expand-change="expandChange" height="calc(100vh - 21em)">
-				<el-table-column align="center" type="selection" width="55" />
-				<el-table-column type="expand">
+				: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 - 18.5em)">
+				<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" width="60" />
+						<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="productCategory" />
 							<el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
 							<el-table-column label="鍗曚綅" prop="unit" />
-							<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 label="浜у搧鐘舵��"
-															 width="100px"
-															 align="center">
+							<el-table-column label="鏂欏彿" prop="materialCode" />
+							<el-table-column label="浜у搧鐘舵��" width="100px" align="center">
 								<template #default="scope">
-									<el-tag v-if="scope.row.approveStatus === 1"
-													type="success">鍏呰冻</el-tag>
-									<el-tag v-else
-													type="danger">涓嶈冻</el-tag>
+									<el-tag v-if="scope.row.approveStatus === 1" type="success">鍏呰冻</el-tag>
+									<el-tag v-else type="danger">涓嶈冻</el-tag>
 								</template>
 							</el-table-column>
-							<el-table-column label="鍙戣揣鐘舵��" prop="shippingStatus" width="140" align="center" show-overflow-tooltip />
-							<el-table-column label="鍙戣揣鏃ユ湡"
-															 minWidth="100px"
-															 align="center">
+							<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>
-										<div v-if="scope.row.shippingDate">{{ scope.row.shippingDate }}</div>
-										<el-tag v-else
-														type="info">-</el-tag>
+										<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 Width="60px"
-															 label="鎿嶄綔"
-															 align="center">
+							<el-table-column label="鍙戣揣鏃ユ湡" minWidth="100px" align="center">
 								<template #default="scope">
-									<el-button
-														 link
-														 type="primary"
-														 size="small"
-														 @click="openDeliveryForm(scope.row)">鍙戣揣</el-button>
+									<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" size="small" :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="閿�鍞悎鍚屽彿" prop="salesContractNo" show-overflow-tooltip />
-				<el-table-column label="瀹㈡埛鍚嶇О" prop="customerName" show-overflow-tooltip />
+				<el-table-column label="閿�鍞悎鍚屽彿" prop="salesContractNo" width="180" show-overflow-tooltip />
+				<el-table-column label="瀹㈡埛鍚嶇О" prop="customerName" width="300" show-overflow-tooltip />
 				<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="paymentMethod" show-overflow-tooltip />
 				<el-table-column label="鍚堝悓閲戦(鍏�)" prop="contractAmount" width="220" show-overflow-tooltip
-												 :formatter="formattedNumber" />
+					:formatter="formattedNumber" />
 				<el-table-column label="褰曞叆浜�" prop="entryPersonName" width="100" show-overflow-tooltip />
-				<el-table-column label="绛捐鏃ユ湡" prop="executionDate" width="120" show-overflow-tooltip />
 				<el-table-column label="褰曞叆鏃ユ湡" prop="entryDate" width="120" show-overflow-tooltip />
-				<el-table-column fixed="right" label="鎿嶄綔" width="120" align="center">
+				<el-table-column label="绛捐鏃ユ湡" prop="executionDate" width="120" show-overflow-tooltip />
+				<el-table-column label="浜や粯鏃ユ湡" prop="deliveryDate" width="120" show-overflow-tooltip />
+				<el-table-column label="澶囨敞" prop="remarks" width="200" show-overflow-tooltip />
+				<el-table-column fixed="right" label="鎿嶄綔" min-width="100" align="center">
 					<template #default="scope">
-						<el-button link type="primary" size="small" @click="openForm('edit', scope.row)">缂栬緫</el-button>
+						<el-button link type="primary" size="small" @click="openForm('edit', scope.row)"
+							:disabled="!scope.row.isEdit">缂栬緫</el-button>
+						<!--            <el-button link type="primary" size="small" @click="openForm('view', scope.row)">璇︽儏</el-button>-->
 						<el-button link type="primary" size="small" @click="downLoadFile(scope.row)">闄勪欢</el-button>
+						<!--            <el-button link type="primary" size="small" @click="openDeliveryForm(scope.row)">鍙戣揣</el-button>-->
 					</template>
 				</el-table-column>
 			</el-table>
 			<pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper"
-									:page="page.current" :limit="page.size" @pagination="paginationChange" />
+				:page="page.current" :limit="page.size" @pagination="paginationChange" />
 		</div>
-		<FormDialog
-			v-model="dialogFormVisible"
-			:title="operationType === 'add' ? '鏂板閿�鍞彴璐﹂〉闈�' : '缂栬緫閿�鍞彴璐﹂〉闈�'"
-			:width="'70%'"
-			:operation-type="operationType"
-			@close="closeDia"
-			@confirm="submitForm"
-			@cancel="closeDia">
+		<FormDialog v-model="dialogFormVisible" :title="operationType === 'add' ? '鏂板閿�鍞彴璐﹂〉闈�' : '缂栬緫閿�鍞彴璐﹂〉闈�'"
+			:width="'70%'" :operation-type="operationType" @close="closeDia" @confirm="submitForm" @cancel="closeDia">
 			<el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
-				<el-row v-if="operationType !== 'view'">
-					<el-col :span="24" style="display:flex; justify-content:flex-end; gap:10px; margin-bottom: 6px;">
-						<el-button type="primary" plain @click="openQuotationDialog">浠庡鎵归�氳繃鐨勬姤浠峰崟瀵煎叆</el-button>
+				<!-- 鎶ヤ环鍗曞鍏ュ叆鍙o細鏀惧湪琛ㄥ崟椤堕儴锛岄�夋嫨鍚庡弽鏄惧鎴�/涓氬姟鍛樼瓑 -->
+				<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">
@@ -125,11 +147,10 @@
 					</el-col>
 					<el-col :span="12">
 						<el-form-item label="涓氬姟鍛橈細" prop="salesman">
-							<el-select v-model="form.salesman"
-												 filterable
-												 :reserve-keyword="false" placeholder="璇烽�夋嫨" clearable :disabled="operationType === 'view'">
+							<el-select v-model="form.salesman" placeholder="璇烽�夋嫨" clearable
+								:disabled="operationType === 'view'">
 								<el-option v-for="item in userList" :key="item.nickName" :label="item.nickName"
-													 :value="item.nickName" />
+									:value="item.nickName" />
 							</el-select>
 						</el-form-item>
 					</el-col>
@@ -137,8 +158,10 @@
 				<el-row :gutter="30">
 					<el-col :span="12">
 						<el-form-item label="瀹㈡埛鍚嶇О锛�" prop="customerId">
-							<el-select v-model="form.customerId" placeholder="璇烽�夋嫨" clearable :disabled="operationType === 'view'" filterable>
-								<el-option v-for="item in customerOption" :key="item.id" :label="item.customerName" :value="item.id">
+							<el-select v-model="form.customerId" placeholder="璇烽�夋嫨" clearable
+								:disabled="operationType === 'view'">
+								<el-option v-for="item in customerOption" :key="item.id" :label="item.customerName"
+									:value="item.id">
 									{{
 										item.customerName + "鈥斺��" + item.taxpayerIdentificationNumber
 									}}
@@ -147,68 +170,105 @@
 						</el-form-item>
 					</el-col>
 					<el-col :span="12">
+						<el-form-item label="椤圭洰鍚嶇О锛�" prop="projectName">
+							<el-input v-model="form.projectName" placeholder="璇疯緭鍏�" clearable
+								:disabled="operationType === 'view'" />
+						</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="operationType === 'view'" />
+								format="YYYY-MM-DD" type="date" placeholder="璇烽�夋嫨" clearable
+								:disabled="operationType === 'view'" />
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="浠樻鏂瑰紡">
+							<el-input v-model="form.paymentMethod" placeholder="璇疯緭鍏�" clearable
+								:disabled="operationType === 'view'" />
 						</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">
-								<el-option v-for="item in userList" :key="item.userId" :label="item.nickName" :value="item.userId" />
+							<el-select v-model="form.entryPerson" filterable default-first-option
+								:reserve-keyword="false" placeholder="璇烽�夋嫨" clearable @change="changs">
+								<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 />
+							<el-date-picker style="width: 100%" v-model="form.entryDate" value-format="YYYY-MM-DD"
+								format="YYYY-MM-DD" type="date" placeholder="璇烽�夋嫨" clearable />
 						</el-form-item>
 					</el-col>
 				</el-row>
-				
+				<el-row :gutter="30">
+					<el-col :span="12">
+						<el-form-item label="浜よ揣鏃ユ湡锛�" prop="entryDate">
+							<el-date-picker style="width: 100%" v-model="form.deliveryDate" value-format="YYYY-MM-DD"
+								format="YYYY-MM-DD" type="date" placeholder="璇烽�夋嫨" clearable />
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="鏄惁鐢熶骇锛�" prop="produce">
+							<el-radio-group v-model="form.produce">
+								<el-radio :label="true">鏄�</el-radio>
+								<el-radio :label="false">鍚�</el-radio>
+							</el-radio-group>
+						</el-form-item>
+					</el-col>
+				</el-row>
 				<el-row>
 					<el-form-item label="浜у搧淇℃伅锛�" prop="entryDate">
-						<el-button v-if="operationType !== 'view'" type="primary" @click="openProductForm('add')">娣诲姞</el-button>
-						<el-button v-if="operationType !== 'view'" plain type="danger" @click="deleteProduct" >鍒犻櫎</el-button>
+						<el-button v-if="operationType !== 'view'" type="primary"
+							@click="openProductForm('add')">娣诲姞</el-button>
+						<el-button v-if="operationType !== 'view'" plain type="danger"
+							@click="deleteProduct">鍒犻櫎</el-button>
 					</el-form-item>
 				</el-row>
 				<el-table :data="productData" border @selection-change="productSelected" show-summary
-									:summary-method="summarizeMainTable">
-					<el-table-column align="center" type="selection" width="55" v-if="operationType !== 'view'" />
+					:summary-method="summarizeMainTable">
+					<el-table-column align="center" type="selection" width="55" v-if="operationType !== 'view'"
+						:selectable="(row) => !isProductShipped(row)" />
 					<el-table-column align="center" label="搴忓彿" type="index" width="60" />
 					<el-table-column label="浜у搧澶х被" prop="productCategory" />
 					<el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
 					<el-table-column label="鍗曚綅" prop="unit" />
+					<el-table-column label="鏂欏彿" prop="materialCode" />
 					<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 fixed="right" label="鎿嶄綔" min-width="60" align="center" v-if="operationType !== 'view'">
+					<el-table-column fixed="right" label="鎿嶄綔" min-width="60" align="center"
+						v-if="operationType !== 'view'">
 						<template #default="scope">
-							<el-button link type="primary" size="small" @click="openProductForm('edit', scope.row,scope.$index)">缂栬緫</el-button>
+							<el-button link type="primary" size="small" :disabled="isProductShipped(scope.row)"
+								@click="openProductForm('edit', scope.row, scope.$index)">缂栬緫</el-button>
 						</template>
 					</el-table-column>
 				</el-table>
 				<el-row :gutter="30">
 					<el-col :span="24">
-						<el-form-item label="澶囨敞路锛�" prop="remark">
-							<el-input v-model="form.remark" placeholder="璇疯緭鍏�" clearable type="textarea" :rows="2" :disabled="operationType === 'view'" />
+						<el-form-item label="澶囨敞锛�" prop="remarks">
+							<el-input v-model="form.remarks" placeholder="璇疯緭鍏�" clearable type="textarea" :rows="2"
+								:disabled="operationType === 'view'" />
 						</el-form-item>
 					</el-col>
 				</el-row>
 				<el-row :gutter="30">
 					<el-col :span="24">
-						<el-form-item label="闄勪欢鏉愭枡锛�" prop="remark">
-							<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-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" v-if="operationType !== 'view'">涓婁紶</el-button>
 								<template #tip v-if="operationType !== 'view'">
 									<div class="el-upload__tip">
@@ -222,40 +282,19 @@
 				</el-row>
 			</el-form>
 		</FormDialog>
-		
+
 		<!-- 浠庢姤浠峰崟瀵煎叆锛堜粎瀹℃壒閫氳繃锛� -->
-		<el-dialog
-			v-model="quotationDialogVisible"
-			title="閫夋嫨瀹℃壒閫氳繃鐨勯攢鍞姤浠峰崟"
-			width="80%"
-			:close-on-click-modal="false"
-		>
+		<el-dialog v-model="quotationDialogVisible" title="閫夋嫨瀹℃壒閫氳繃鐨勯攢鍞姤浠峰崟" width="80%" :close-on-click-modal="false">
 			<div style="margin-bottom: 12px; display:flex; gap: 12px; align-items:center;">
-				<el-input
-					v-model="quotationSearchForm.quotationNo"
-					placeholder="璇疯緭鍏ユ姤浠峰崟鍙�"
-					clearable
-					style="max-width: 260px;"
-					@change="fetchQuotationList"
-				/>
-				<el-input
-					v-model="quotationSearchForm.customer"
-					placeholder="璇疯緭鍏ュ鎴峰悕绉�"
-					clearable
-					style="max-width: 260px;"
-					@change="fetchQuotationList"
-				/>
+				<el-input v-model="quotationSearchForm.quotationNo" placeholder="璇疯緭鍏ユ姤浠峰崟鍙�" clearable
+					style="max-width: 260px;" @change="fetchQuotationList" />
+				<el-input v-model="quotationSearchForm.customer" placeholder="璇疯緭鍏ュ鎴峰悕绉�" clearable
+					style="max-width: 260px;" @change="fetchQuotationList" />
 				<el-button type="primary" @click="fetchQuotationList">鎼滅储</el-button>
 				<el-button @click="resetQuotationSearch">閲嶇疆</el-button>
 			</div>
-			
-			<el-table
-				:data="quotationList"
-				border
-				stripe
-				v-loading="quotationLoading"
-				height="420px"
-			>
+
+			<el-table :data="quotationList" border stripe v-loading="quotationLoading" height="420px">
 				<el-table-column align="center" label="搴忓彿" type="index" width="60" />
 				<el-table-column prop="quotationNo" label="鎶ヤ环鍗曞彿" width="180" show-overflow-tooltip />
 				<el-table-column prop="customer" label="瀹㈡埛鍚嶇О" min-width="220" show-overflow-tooltip />
@@ -273,37 +312,45 @@
 					</template>
 				</el-table-column>
 			</el-table>
-			
+
+			<pagination v-show="quotationPage.total > 0" :total="quotationPage.total"
+				layout="total, sizes, prev, pager, next, jumper" :page="quotationPage.current"
+				:limit="quotationPage.size" @pagination="quotationPaginationChange" />
+
 			<template #footer>
 				<el-button @click="quotationDialogVisible = false">鍏抽棴</el-button>
 			</template>
 		</el-dialog>
-		<FormDialog
-			v-model="productFormVisible"
-			:title="productOperationType === 'add' ? '鏂板浜у搧' : '缂栬緫浜у搧'"
-			:width="'40%'"
-			:operation-type="productOperationType"
-			@close="closeProductDia"
-			@confirm="submitProduct"
+		<FormDialog v-model="productFormVisible" :title="productOperationType === 'add' ? '鏂板浜у搧' : '缂栬緫浜у搧'"
+			:width="'40%'" :operation-type="productOperationType" @close="closeProductDia" @confirm="submitProduct"
 			@cancel="closeProductDia">
-			<el-form :model="productForm" label-width="140px" label-position="top" :rules="productRules" ref="productFormRef">
+			<el-form :model="productForm" label-width="140px" label-position="top" :rules="productRules"
+				ref="productFormRef">
 				<el-row :gutter="30">
 					<el-col :span="24">
 						<el-form-item label="浜у搧澶х被锛�" prop="productCategory">
 							<!-- <el-select v-model="productForm.productCategory" placeholder="璇烽�夋嫨" clearable>
 								<el-option v-for="item in userList" :key="item.nickName" :label="item.nickName" :value="item.nickName"/>
 							</el-select> -->
-							<el-tree-select v-model="productForm.productCategory" placeholder="璇烽�夋嫨" clearable check-strictly
-															@change="getModels" :data="productOptions" :render-after-expand="false" style="width: 100%" />
+							<el-tree-select v-model="productForm.productCategory" placeholder="璇烽�夋嫨" clearable
+								check-strictly @change="getModels" :data="productOptions" :render-after-expand="false"
+								style="width: 100%" />
 						</el-form-item>
 					</el-col>
 				</el-row>
 				<el-row :gutter="30">
 					<el-col :span="24">
 						<el-form-item label="瑙勬牸鍨嬪彿锛�" prop="productModelId">
-							<el-select v-model="productForm.productModelId" placeholder="璇烽�夋嫨" clearable @change="getProductModel" filterable>
-								<el-option v-for="item in modelOptions" :key="item.id" :label="item.model" :value="item.id" />
+							<el-select v-model="productForm.productModelId" placeholder="璇烽�夋嫨" clearable
+								@change="getProductModel" filterable>
+								<el-option v-for="item in modelOptions" :key="item.id" :label="item.model"
+									:value="item.id" />
 							</el-select>
+						</el-form-item>
+					</el-col>
+					<el-col :span="24">
+						<el-form-item label="鏂欏彿锛�" prop="materialCode">
+							<el-input v-model="productForm.materialCode" placeholder="璇疯緭鍏�" disabled />
 						</el-form-item>
 					</el-col>
 				</el-row>
@@ -315,7 +362,8 @@
 					</el-col>
 					<el-col :span="12">
 						<el-form-item label="绋庣巼(%)锛�" prop="taxRate">
-							<el-select v-model="productForm.taxRate" placeholder="璇烽�夋嫨" clearable @change="calculateFromTaxRate">
+							<el-select v-model="productForm.taxRate" placeholder="璇烽�夋嫨" clearable
+								@change="calculateFromTaxRate">
 								<el-option label="1" value="1" />
 								<el-option label="6" value="6" />
 								<el-option label="13" value="13" />
@@ -326,28 +374,29 @@
 				<el-row :gutter="30">
 					<el-col :span="12">
 						<el-form-item label="鍚◣鍗曚环(鍏�)锛�" prop="taxInclusiveUnitPrice">
-							<el-input-number :step="0.01" :min="0" v-model="productForm.taxInclusiveUnitPrice" style="width: 100%"
-															 :precision="2"
-															 placeholder="璇疯緭鍏�" clearable @change="calculateFromUnitPrice" />
+							<el-input-number :step="0.01" :min="0" v-model="productForm.taxInclusiveUnitPrice"
+								style="width: 100%" :precision="2" placeholder="璇疯緭鍏�" clearable
+								@change="calculateFromUnitPrice" />
 						</el-form-item>
 					</el-col>
 					<el-col :span="12">
 						<el-form-item label="鏁伴噺锛�" prop="quantity">
-							<el-input-number  :step="0.1" :min="0" v-model="productForm.quantity" placeholder="璇疯緭鍏�" clearable
-																:precision="2"
-																@change="calculateFromQuantity" style="width: 100%" />
+							<el-input-number :step="0.1" :min="0" v-model="productForm.quantity" placeholder="璇疯緭鍏�"
+								clearable :precision="2" @change="calculateFromQuantity" style="width: 100%" />
 						</el-form-item>
 					</el-col>
 				</el-row>
 				<el-row :gutter="30">
 					<el-col :span="12">
 						<el-form-item label="鍚◣鎬讳环(鍏�)锛�" prop="taxInclusiveTotalPrice">
-							<el-input v-model="productForm.taxInclusiveTotalPrice" placeholder="璇疯緭鍏�" clearable @change="calculateFromTotalPrice" />
+							<el-input v-model="productForm.taxInclusiveTotalPrice" placeholder="璇疯緭鍏�" clearable
+								@change="calculateFromTotalPrice" />
 						</el-form-item>
 					</el-col>
 					<el-col :span="12">
 						<el-form-item label="涓嶅惈绋庢�讳环(鍏�)锛�" prop="taxExclusiveTotalPrice">
-							<el-input v-model="productForm.taxExclusiveTotalPrice" placeholder="璇疯緭鍏�" clearable @change="calculateFromExclusiveTotalPrice" />
+							<el-input v-model="productForm.taxExclusiveTotalPrice" placeholder="璇疯緭鍏�" clearable
+								@change="calculateFromExclusiveTotalPrice" />
 						</el-form-item>
 					</el-col>
 				</el-row>
@@ -363,14 +412,30 @@
 				</el-row>
 			</el-form>
 		</FormDialog>
+		<!-- 瀵煎叆寮圭獥 -->
+		<FormDialog v-model="importUpload.open" :title="importUpload.title" :width="'600px'"
+			@close="importUpload.open = false" @confirm="submitImportFile" @cancel="importUpload.open = false">
+			<el-upload ref="importUploadRef" :limit="1" accept=".xlsx,.xls" :action="importUpload.url"
+				:headers="importUpload.headers" :before-upload="importUpload.beforeUpload"
+				:on-success="importUpload.onSuccess" :on-error="importUpload.onError"
+				:on-progress="importUpload.onProgress" :on-change="importUpload.onChange" :auto-upload="false" drag>
+				<i class="el-icon-upload"></i>
+				<div class="el-upload__text">
+					灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em>
+				</div>
+				<template #tip>
+					<div class="el-upload__tip">
+						浠呮敮鎸� xls/xlsx锛屽ぇ灏忎笉瓒呰繃 10MB銆�
+						<el-button link type="primary" @click="downloadTemplate">涓嬭浇瀵煎叆妯℃澘</el-button>
+					</div>
+				</template>
+			</el-upload>
+		</FormDialog>
+		<!-- 闄勪欢鍒楄〃寮圭獥 -->
+		<FileListDialog ref="fileListRef" v-model="fileListDialogVisible" title="闄勪欢鍒楄〃" />
 		<!-- 鎵撳嵃棰勮寮圭獥 -->
-		<el-dialog
-			v-model="printPreviewVisible"
-			title="鎵撳嵃棰勮"
-			width="90%"
-			:close-on-click-modal="false"
-			class="print-preview-dialog"
-		>
+		<el-dialog v-model="printPreviewVisible" title="鎵撳嵃棰勮" width="90%" :close-on-click-modal="false"
+			class="print-preview-dialog">
 			<div class="print-preview-container">
 				<div class="print-preview-header">
 					<el-button type="primary" @click="executePrint">鎵ц鎵撳嵃</el-button>
@@ -380,122 +445,130 @@
 					<div v-if="printData.length === 0" style="text-align: center; padding: 50px; color: #999;">
 						鏆傛棤鎵撳嵃鏁版嵁
 					</div>
-					<div v-else style="text-align: center; padding: 10px; color: #666; font-size: 14px; background: #e8f4fd; margin-bottom: 10px;">
+					<div v-else
+						style="text-align: center; padding: 10px; color: #666; font-size: 14px; background: #e8f4fd; margin-bottom: 10px;">
 						鍏� {{ printData.length }} 鏉℃暟鎹緟鎵撳嵃
 					</div>
 					<div v-for="(item, index) in printData" :key="index" class="print-page">
 						<div class="delivery-note">
 							<div class="header">
-								<div class="company-name">榧庤瘹鐟炲疄涓氭湁闄愯矗浠诲叕鍙�</div>
-								<div class="document-title">闆跺敭鍙戣揣鍗�</div>
+								<div class="company-name">婀栧崡楣忓垱鐢靛瓙鏈夐檺鍏徃</div>
+								<div class="document-title">閫佽揣鍗�</div>
 							</div>
-							
+
 							<div class="info-section">
 								<div class="info-row">
 									<div>
-										<span class="label">鍙戣揣鏃ユ湡锛�</span>
-										<span class="value">{{ formatDate(item.createTime) }}</span>
+										<span class="label">瀹㈡埛鍚嶇О锛�</span>
+										<span class="value">{{ item.customerName }}</span>
 									</div>
 									<div>
-										<span class="label">鍙戣揣杞︾墝鍙凤細</span>
-										<span class="value">{{ item.shippingCarNumber }}</span>
+										<span class="label">閫佽揣鍦板潃锛�</span>
+										<span class="value">{{ item.companyAddress }}</span>
 									</div>
 								</div>
 								<div class="info-row">
 									<div>
-										<span class="label">瀹㈡埛鍚嶇О锛�</span>
-										<span class="value">{{ item.customerName || '寮犵埍鏈�' }}</span>
+										<span class="label">鍗曟嵁缂栧彿锛�</span>
+										<span class="value">{{ item.salesContractNo }}</span>
 									</div>
-									<span class="label">鍗曞彿锛�</span>
-									<span class="value">{{ item.salesContractNo }}</span>
+
+									<div>
+										<span class="label">閫佽揣鏃ユ湡锛�</span>
+										<span class="value">{{ formatDate(null) }}</span>
+									</div>
+
+									<div>
+										<span class="label">鑱旂郴鐢佃瘽锛�</span>
+										<span class="value">{{ item.contactPhone }}</span>
+									</div>
 								</div>
 							</div>
-							
+
+							<div class="info-section">
+								<div class="info-row">
+									<div>
+										<span class="label">鑱旂郴鏂瑰紡锛�</span>
+										<span class="value"></span>
+									</div>
+									<div>
+										<span class="label">閫佽揣鍗曚綅锛�</span>
+										<span class="value">婀栧崡楣忓垱鐢靛瓙鏈夐檺鍏徃</span>
+									</div>
+									<div>
+										<span class="label">鍦板潃锛�</span>
+										<span class="value">婀栧崡鑰掗槼甯傚垱鏂板垱涓氬洯A1鏍�</span>
+									</div>
+								</div>
+							</div>
+
+							<span style="font-size: 16px;">璐х墿璇︾粏淇℃伅锛�</span>
 							<div class="table-section">
 								<table class="product-table">
 									<thead>
-									<tr>
-										<th>浜у搧鍚嶇О</th>
-										<th>瑙勬牸鍨嬪彿</th>
-										<th>鍗曚綅</th>
-										<th>鍗曚环</th>
-										<th>闆跺敭鏁伴噺</th>
-										<th>闆跺敭閲戦</th>
-									</tr>
+										<tr>
+											<th>搴忓彿</th>
+											<th>鏂欏彿</th>
+											<th>鍝佸悕/瑙勬牸</th>
+											<th>鍗曚綅</th>
+											<th>鏁伴噺</th>
+											<th>璁㈠崟鍙�</th>
+										</tr>
 									</thead>
 									<tbody>
-									<tr v-for="product in item.products" :key="product.id">
-										<td>{{ product.productCategory || '' }}</td>
-										<td>{{ product.specificationModel || '' }}</td>
-										<td>{{ product.unit || '' }}</td>
-										<td>{{ product.taxInclusiveUnitPrice || '0' }}</td>
-										<td>{{ product.quantity || '0' }}</td>
-										<td>{{ product.taxInclusiveTotalPrice || '0' }}</td>
-									</tr>
-									<tr v-if="!item.products || item.products.length === 0">
-										<td colspan="6" style="text-align: center; color: #999;">鏆傛棤浜у搧鏁版嵁</td>
-									</tr>
+										<tr v-for="(product, index) in item.products" :key="product.id">
+											<td>{{ index + 1 }}</td>
+											<td>{{ product.materialCode || '' }}</td>
+											<td>{{ `${product.productCategory || ''}/${product.specificationModel || ''}`
+												}}</td>
+											<td>{{ product.unit || '' }}</td>
+											<td>{{ product.quantity || '0' }}</td>
+											<td>{{ item.salesContractNo || '' }}</td>
+										</tr>
+										<tr v-if="!item.products || item.products.length === 0">
+											<td colspan="6" style="text-align: center; color: #999;">鏆傛棤浜у搧鏁版嵁</td>
+										</tr>
 									</tbody>
 									<tfoot>
-									<tr>
-										<td class="label">鍚堣</td>
-										<td class="total-value"></td>
-										<td class="total-value"></td>
-										<td class="total-value"></td>
-										<td class="total-value">{{ getTotalQuantity(item.products) }}</td>
-										<td class="total-value">{{ getTotalAmount(item.products) }}</td>
-									</tr>
+										<tr>
+											<td class="label"></td>
+											<td class="label">鍚堣</td>
+											<td class="total-value"></td>
+											<td class="total-value"></td>
+											<td class="total-value">{{ getTotalQuantity(item.products) }}</td>
+											<td class="total-value"></td>
+										</tr>
 									</tfoot>
 								</table>
-							</div>
-							
-							<div class="footer-section">
-								<div class="footer-row">
-									<div class="footer-item">
-										<span class="label">鏀惰揣鐢佃瘽锛�</span>
-										<span class="value"></span>
-									</div>
-									<div class="footer-item">
-										<span class="label">鏀惰揣浜猴細</span>
-										<span class="value"></span>
-									</div>
-									<div class="footer-item address-item">
-										<span class="label">鏀惰揣鍦板潃锛�</span>
-										<span class="value address-value"></span>
-									</div>
-								</div>
-								<div class="footer-row">
-									<div class="footer-item">
-										<span class="label">鎿嶄綔鍛橈細</span>
-										<span class="value">{{ userStore.nickName || '鎾曞紑鍓�' }}</span>
-									</div>
-									<div class="footer-item">
-										<span class="label">鎵撳嵃鏃ユ湡锛�</span>
-										<span class="value">{{ formatDateTime(new Date()) }}</span>
-									</div>
+
+								<div style="width: 30px;">
+									鍏卞洓鑱斿瓨鏍瑰洖鍗曞鎴蜂粨搴�
 								</div>
 							</div>
+
+							<el-descriptions :column="1">
+								<el-descriptions-item
+									label="澶囨敞锛�">璐靛叕鍙稿湪鏀惰揣鍚庤鍗冲埢鏍稿疄鏁伴噺鍙婂搧璐紝鑻ユ湁寮傝锛岃鍦�3鏃ュ唴鎻愬嚭锛屽惁鍒欒涓烘敹濡ャ��</el-descriptions-item>
+							</el-descriptions>
+							<el-descriptions :column="2">
+								<el-descriptions-item label="閫佽揣鍗曚綅锛堢绔狅級锛�" />
+								<el-descriptions-item label="鏀惰揣鍗曚綅锛�" />
+								<el-descriptions-item label="閫佽揣浜猴細" />
+								<el-descriptions-item label="鏀惰揣浜猴細" />
+							</el-descriptions>
 						</div>
 					</div>
 				</div>
 			</div>
 		</el-dialog>
 		<!-- 鍙戣揣寮规 -->
-		<el-dialog
-			v-model="deliveryFormVisible"
-			title="鍙戣揣淇℃伅"
-		width="40%"
-			@close="closeDeliveryDia"
-		>
-			<el-form :model="deliveryForm" label-width="120px" label-position="top" :rules="deliveryRules" ref="deliveryFormRef">
+		<el-dialog v-model="deliveryFormVisible" title="鍙戣揣淇℃伅" width="40%" @close="closeDeliveryDia">
+			<el-form :model="deliveryForm" label-width="120px" label-position="top" :rules="deliveryRules"
+				ref="deliveryFormRef">
 				<el-row :gutter="30">
 					<el-col :span="24">
 						<el-form-item label="鍙戣揣绫诲瀷锛�" prop="type">
-							<el-select
-								v-model="deliveryForm.type"
-								placeholder="璇烽�夋嫨鍙戣揣绫诲瀷"
-								style="width: 100%"
-							>
+							<el-select v-model="deliveryForm.type" placeholder="璇烽�夋嫨鍙戣揣绫诲瀷" style="width: 100%">
 								<el-option label="璐ц溅" value="璐ц溅" />
 								<el-option label="蹇��" value="蹇��" />
 							</el-select>
@@ -503,50 +576,36 @@
 					</el-col>
 				</el-row>
 
-        <!-- 瀹℃壒浜洪�夋嫨锛堜豢鍗忓悓瀹℃壒閲岀殑瀹℃壒浜鸿妭鐐归�夋嫨锛� -->
-        <el-row>
-          <el-col :span="24">
-            <el-form-item>
-              <template #label>
-                <span>瀹℃壒浜洪�夋嫨锛�</span>
-                <el-button type="primary" @click="addApproverNode" style="margin-left: 8px;">鏂板鑺傜偣</el-button>
-              </template>
-              <div style="display: flex; align-items: flex-end; flex-wrap: wrap;">
-                <div
-                  v-for="(node, index) in approverNodes"
-                  :key="node.id"
-                  style="margin-right: 20px; text-align: center; margin-bottom: 10px;"
-                >
-                  <div>
-                    <span>瀹℃壒浜�</span>
-                    鈫�
-                  </div>
-                  <el-select
-                    v-model="node.userId"
-                    placeholder="閫夋嫨浜哄憳"
-                    filterable
-                    style="width: 140px; margin-bottom: 8px;"
-                  >
-                    <el-option
-                      v-for="user in userList"
-                      :key="user.userId"
-                      :label="user.nickName"
-                      :value="user.userId"
-                    />
-                  </el-select>
-                  <div>
-                    <el-button
-                      type="danger"
-                      size="small"
-                      @click="removeApproverNode(index)"
-                      v-if="approverNodes.length > 1"
-                    >鍒犻櫎</el-button>
-                  </div>
-                </div>
-              </div>
-            </el-form-item>
-          </el-col>
-        </el-row>
+				<!-- 瀹℃壒浜洪�夋嫨锛堜豢鍗忓悓瀹℃壒閲岀殑瀹℃壒浜鸿妭鐐归�夋嫨锛� -->
+				<el-row>
+					<el-col :span="24">
+						<el-form-item>
+							<template #label>
+								<span>瀹℃壒浜洪�夋嫨锛�</span>
+								<el-button type="primary" @click="addApproverNode"
+									style="margin-left: 8px;">鏂板鑺傜偣</el-button>
+							</template>
+							<div style="display: flex; align-items: flex-end; flex-wrap: wrap;">
+								<div v-for="(node, index) in approverNodes" :key="node.id"
+									style="margin-right: 20px; text-align: center; margin-bottom: 10px;">
+									<div>
+										<span>瀹℃壒浜�</span>
+										鈫�
+									</div>
+									<el-select v-model="node.userId" placeholder="閫夋嫨浜哄憳" filterable
+										style="width: 140px; margin-bottom: 8px;">
+										<el-option v-for="user in userList" :key="user.userId" :label="user.nickName"
+											:value="user.userId" />
+									</el-select>
+									<div>
+										<el-button type="danger" size="small" @click="removeApproverNode(index)"
+											v-if="approverNodes.length > 1">鍒犻櫎</el-button>
+									</div>
+								</div>
+							</div>
+						</el-form-item>
+					</el-col>
+				</el-row>
 			</el-form>
 			<template #footer>
 				<div class="dialog-footer">
@@ -561,7 +620,7 @@
 <script setup>
 import { getToken } from "@/utils/auth";
 import pagination from "@/components/PIMTable/Pagination.vue";
-import {onMounted, ref, getCurrentInstance} from "vue";
+import { onMounted, ref, getCurrentInstance } from "vue";
 import { addShippingInfo } from "@/api/salesManagement/deliveryLedger.js";
 import { ElMessageBox, ElMessage } from "element-plus";
 import { UploadFilled, Download } from "@element-plus/icons-vue";
@@ -621,6 +680,8 @@
 		customerId: "",
 		entryPerson: "",
 		entryDate: "",
+		deliveryDate: "",
+		produce: false,
 		maintenanceTime: "",
 		productData: [],
 		executionDate: "",
@@ -630,6 +691,7 @@
 		customerId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
 		entryPerson: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
 		entryDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+		deliveryDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
 		executionDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
 	},
 });
@@ -643,6 +705,7 @@
 	productForm: {
 		productCategory: "",
 		specificationModel: "",
+		materialCode: "",
 		unit: "",
 		quantity: "",
 		taxInclusiveUnitPrice: "",
@@ -693,20 +756,26 @@
 	quotationNo: "",
 	customer: "",
 });
+// 鎶ヤ环鍗曞脊妗嗗垎椤�
+const quotationPage = reactive({
+	current: 1,
+	size: 10,
+	total: 0,
+});
 const selectedQuotation = ref(null);
 
 // 鍙戣揣鐩稿叧
 const deliveryFormVisible = ref(false);
 const currentDeliveryRow = ref(null);
 const deliveryFormData = reactive({
-  deliveryForm: {
-    type: "璐ц溅", // 璐ц溅, 蹇��
-  },
-  deliveryRules: {
-    type: [
-      { required: true, message: "璇烽�夋嫨鍙戣揣绫诲瀷", trigger: "change" }
-    ]
-  },
+	deliveryForm: {
+		type: "璐ц溅", // 璐ц溅, 蹇��
+	},
+	deliveryRules: {
+		type: [
+			{ required: true, message: "璇烽�夋嫨鍙戣揣绫诲瀷", trigger: "change" }
+		]
+	},
 });
 const { deliveryForm, deliveryRules } = toRefs(deliveryFormData);
 
@@ -714,10 +783,10 @@
 const approverNodes = ref([{ id: 1, userId: null }]);
 let nextApproverId = 2;
 const addApproverNode = () => {
-  approverNodes.value.push({ id: nextApproverId++, userId: null });
+	approverNodes.value.push({ id: nextApproverId++, userId: null });
 };
 const removeApproverNode = (index) => {
-  approverNodes.value.splice(index, 1);
+	approverNodes.value.splice(index, 1);
 };
 
 // 瀵煎叆鐩稿叧
@@ -802,7 +871,7 @@
 	const params = { ...rest, ...page };
 	// 绉婚櫎褰曞叆鏃ユ湡鐨勯粯璁ゅ�艰缃紝鍙繚鐣欒寖鍥存棩鏈熷瓧娈�
 	delete params.entryDate;
-	ledgerListPage(params)
+	return ledgerListPage(params)
 		.then((res) => {
 			tableLoading.value = false;
 			tableData.value = res.records;
@@ -810,6 +879,7 @@
 				item.children = [];
 			});
 			total.value = res.total;
+			return res;
 		})
 		.catch(() => {
 			tableLoading.value = false;
@@ -838,9 +908,11 @@
 	if (index !== -1) {
 		productForm.value.specificationModel = modelOptions.value[index].model;
 		productForm.value.unit = modelOptions.value[index].unit;
+		productForm.value.materialCode = modelOptions.value[index].materialCode;
 	} else {
 		productForm.value.specificationModel = null;
 		productForm.value.unit = null;
+		productForm.value.materialCode = null;
 	}
 };
 const findNodeById = (nodes, productId) => {
@@ -867,7 +939,7 @@
 		if (children && children.length > 0) {
 			newItem.children = convertIdToValue(children);
 		}
-		
+
 		return newItem;
 	});
 }
@@ -913,6 +985,23 @@
 		expandedRowKeys.value = [];
 	}
 };
+
+// 娣诲姞琛ㄨ绫诲悕鏂规硶
+const tableRowClassName = ({ row }) => {
+	if (!row.deliveryDate) return '';
+	if (row.isFh) return '';
+
+	const diff = row.deliveryDaysDiff;
+	if (diff === 15) {
+		return 'yellow';
+	} else if (diff === 10) {
+		return 'pink';
+	} else if (diff === 2) {
+		return 'purple';
+	} else if (diff < 2) {
+		return 'red';
+	}
+};
 // 涓昏〃鍚堣鏂规硶
 const summarizeMainTable = (param) => {
 	return proxy.summarizeTable(param, [
@@ -946,6 +1035,8 @@
 		form.value.entryDate = getCurrentDate();
 		// 绛捐鏃ユ湡榛樿涓哄綋澶�
 		form.value.executionDate = getCurrentDate();
+		// 鏄惁鐢熶骇榛樿涓哄惁
+		form.value.produce = false;
 	} else {
 		currentId.value = row.id;
 		getSalesLedgerWithProducts({ id: row.id, type: 1 }).then((res) => {
@@ -969,6 +1060,8 @@
 const openQuotationDialog = async () => {
 	if (operationType.value === "view") return;
 	quotationDialogVisible.value = true;
+	// 鎵撳紑寮圭獥鏃堕噸缃垎椤靛埌绗竴椤�
+	quotationPage.current = 1;
 	// 鍏堢‘淇濆鎴峰垪琛ㄥ凡鍔犺浇锛屼究浜庡悗缁洖濉� customerId
 	if (!customerOption.value || customerOption.value.length === 0) {
 		try {
@@ -985,14 +1078,15 @@
 	quotationLoading.value = true;
 	try {
 		const params = {
-			// 鍏煎鍚庣鍒嗛〉瀛楁锛氳繖閲屾部鐢ㄦ姤浠烽〉闈㈠凡鏈夊彲鐢ㄧ殑瀛楁鍛藉悕
-			currentPage: 1,
-			pageSize: 100,
+			// 鍚庣鍒嗛〉瀛楁锛歝urrent / size
+			current: quotationPage.current,
+			size: quotationPage.size,
 			...quotationSearchForm,
 			status: "閫氳繃",
 		};
 		const res = await getQuotationList(params);
 		quotationList.value = res?.data?.records || [];
+		quotationPage.total = res?.data?.total || 0;
 	} finally {
 		quotationLoading.value = false;
 	}
@@ -1001,26 +1095,38 @@
 const resetQuotationSearch = async () => {
 	quotationSearchForm.quotationNo = "";
 	quotationSearchForm.customer = "";
+	quotationPage.current = 1;
 	await fetchQuotationList();
+};
+
+// 鎶ヤ环鍗曞脊妗嗗垎椤靛垏鎹�
+const quotationPaginationChange = (obj) => {
+	quotationPage.current = obj.page;
+	quotationPage.size = obj.limit;
+	fetchQuotationList();
 };
 
 // 閫変腑鎶ヤ环鍗曞悗鍥炲~鍒板彴璐﹁〃鍗�
 const applyQuotation = (row) => {
 	if (!row) return;
 	selectedQuotation.value = row;
-	
+
 	// 涓氬姟鍛�
-	form.value.salesman = row.salesperson || "";
-	
+	form.value.salesman = (row.salesperson || "").trim();
+
 	// 瀹㈡埛鍚嶇О -> customerId
-	const customer = (customerOption.value || []).find((c) => c.customerName === row.customer);
+	const qCustomerName = String(row.customer || "").trim();
+	const customer = (customerOption.value || []).find((c) => {
+		const name = String(c.customerName || "").trim();
+		return name === qCustomerName || name.includes(qCustomerName) || qCustomerName.includes(name);
+	});
 	if (customer?.id) {
 		form.value.customerId = customer.id;
 	} else {
 		// 濡傛灉鎵句笉鍒帮紝淇濈暀鍘熷�硷紙鍏佽鐢ㄦ埛鎵嬪姩閫夋嫨/涓嶆墦鏂凡鏈夎緭鍏ワ級
 		form.value.customerId = form.value.customerId || "";
 	}
-	
+
 	// 浜у搧淇℃伅鏄犲皠锛氭姤浠� products -> 鍙拌处 productData
 	const products = Array.isArray(row.products) ? row.products : [];
 	productData.value = products.map((p) => {
@@ -1042,7 +1148,7 @@
 			invoiceType: "澧炴櫘绁�",
 		};
 	});
-	
+
 	quotationDialogVisible.value = false;
 };
 function changs(val) {
@@ -1118,6 +1224,12 @@
 const productIndex = ref(0);
 // 鎵撳紑浜у搧寮规
 const openProductForm = async (type, row, index) => {
+	// 缂栬緫鏃舵鏌ヤ骇鍝佹槸鍚﹀凡鍙戣揣鎴栧鏍搁�氳繃
+	if (type === "edit" && isProductShipped(row)) {
+		proxy.$modal.msgWarning("宸插彂璐ф垨瀹℃牳閫氳繃鐨勪骇鍝佷笉鑳界紪杈�");
+		return;
+	}
+
 	productOperationType.value = type;
 	productForm.value = {};
 	proxy.resetForm("productFormRef");
@@ -1145,6 +1257,8 @@
 			// 鍔犺浇澶辫触鏃朵繚鎸佸彲缂栬緫锛屼笉涓柇寮圭獥
 			console.error("鍔犺浇浜у搧瑙勬牸鍨嬪彿澶辫触", e);
 		}
+	} else {
+		getProductOptions()
 	}
 	productFormVisible.value = true;
 };
@@ -1155,9 +1269,9 @@
 			if (operationType.value === "edit") {
 				submitProductEdit();
 			} else {
-				if(productOperationType.value === "add"){
+				if (productOperationType.value === "add") {
 					productData.value.push({ ...productForm.value });
-				}else{
+				} else {
 					productData.value[productIndex.value] = { ...productForm.value }
 				}
 				closeProductDia();
@@ -1182,6 +1296,14 @@
 		proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
 		return;
 	}
+
+	// 妫�鏌ユ槸鍚︽湁宸插彂璐ф垨瀹℃牳閫氳繃鐨勪骇鍝�
+	const shippedProducts = productSelectedRows.value.filter(row => isProductShipped(row));
+	if (shippedProducts.length > 0) {
+		proxy.$modal.msgWarning("宸插彂璐ф垨瀹℃牳閫氳繃鐨勪骇鍝佷笉鑳藉垹闄�");
+		return;
+	}
+
 	if (operationType.value === "add") {
 		productSelectedRows.value.forEach((selectedRow) => {
 			const index = productData.value.findIndex(
@@ -1256,15 +1378,55 @@
 			proxy.$modal.msg("宸插彇娑�");
 		});
 };
+/** 鍒ゆ柇鍗曚釜浜у搧鏄惁宸插彂璐э紙鏍规嵁shippingStatus鍒ゆ柇锛屽凡鍙戣揣鎴栧鏍搁�氳繃涓嶅彲缂栬緫鍜屽垹闄わ級 */
+const isProductShipped = (product) => {
+	if (!product) return false;
+	const status = String(product.shippingStatus || "").trim();
+	// 濡傛灉鍙戣揣鐘舵�佹槸"宸插彂璐�"鎴�"瀹℃牳閫氳繃"锛屽垯涓嶅彲缂栬緫鍜屽垹闄�
+	return status === "宸插彂璐�" || status === "瀹℃牳閫氳繃";
+};
+
+/** 鍒ゆ柇閿�鍞鍗曚笅鏄惁瀛樺湪宸插彂璐�/鍙戣揣瀹屾垚鐨勪骇鍝侊紙涓嶅彲鍒犻櫎锛� */
+const hasShippedProducts = (products) => {
+	if (!products || !products.length) return false;
+	return products.some((p) => {
+		const status = String(p.shippingStatus || "").trim();
+		// 鏈夊彂璐ф棩鏈熸垨杞︾墝鍙疯涓哄凡鍙戣揣
+		if (p.shippingDate || p.shippingCarNumber) return true;
+		// 宸茶繘琛屽彂璐с�佸彂璐у畬鎴愩�佸凡鍙戣揣 鍧囦笉鍙垹闄�
+		return status === "宸茶繘琛屽彂璐�" || status === "鍙戣揣瀹屾垚" || status === "宸插彂璐�";
+	});
+};
+
 // 鍒犻櫎
-const handleDelete = () => {
-	let ids = [];
-	if (selectedRows.value.length > 0) {
-		ids = selectedRows.value.map((item) => item.id);
-	} else {
+const handleDelete = async () => {
+	if (selectedRows.value.length === 0) {
 		proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
 		return;
 	}
+	const ids = selectedRows.value.map((item) => item.id);
+
+	// 妫�鏌ユ槸鍚︽湁宸茶繘琛屽彂璐ф垨鍙戣揣瀹屾垚鐨勯攢鍞鍗曪紝鑻ユ湁鍒欎笉鍏佽鍒犻櫎
+	const cannotDeleteNames = [];
+	for (const row of selectedRows.value) {
+		let products = row.children && row.children.length > 0 ? row.children : null;
+		if (!products) {
+			try {
+				const res = await productList({ salesLedgerId: row.id, type: 1 });
+				products = res.data || [];
+			} catch {
+				products = [];
+			}
+		}
+		if (hasShippedProducts(products)) {
+			cannotDeleteNames.push(row.salesContractNo || `ID:${row.id}`);
+		}
+	}
+	if (cannotDeleteNames.length > 0) {
+		proxy.$modal.msgWarning("宸茶繘琛屽彂璐ф垨鍙戣揣瀹屾垚鐨勯攢鍞鍗曚笉鑳藉垹闄わ細" + cannotDeleteNames.join("銆�"));
+		return;
+	}
+
 	ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
 		confirmButtonText: "纭",
 		cancelButtonText: "鍙栨秷",
@@ -1287,25 +1449,25 @@
 		proxy.$modal.msgWarning("璇烽�夋嫨瑕佹墦鍗扮殑鏁版嵁");
 		return;
 	}
-	
+
 	// 鏄剧ず鍔犺浇鐘舵��
 	proxy.$modal.loading("姝e湪鑾峰彇浜у搧鏁版嵁锛岃绋嶅��...");
-	
+
 	try {
 		// 涓烘瘡涓�変腑鐨勯攢鍞彴璐﹁褰曟煡璇㈠搴旂殑浜у搧鏁版嵁
 		const printDataWithProducts = [];
-		
+
 		for (const row of selectedRows.value) {
 			try {
 				// 璋冪敤productList鎺ュ彛鏌ヨ浜у搧鏁版嵁
 				const productRes = await productList({ salesLedgerId: row.id, type: 1 });
-				
+
 				// 灏嗕骇鍝佹暟鎹暣鍚堝埌閿�鍞彴璐﹁褰曚腑
 				const rowWithProducts = {
 					...row,
 					products: productRes.data || []
 				};
-				
+
 				printDataWithProducts.push(rowWithProducts);
 			} catch (error) {
 				console.error(`鑾峰彇閿�鍞彴璐� ${row.id} 鐨勪骇鍝佹暟鎹け璐�:`, error);
@@ -1316,11 +1478,11 @@
 				});
 			}
 		}
-		
+
 		printData.value = printDataWithProducts;
 		console.log('鎵撳嵃鏁版嵁锛堝寘鍚骇鍝侊級:', printData.value);
 		printPreviewVisible.value = true;
-		
+
 	} catch (error) {
 		console.error('鑾峰彇浜у搧鏁版嵁澶辫触:', error);
 		proxy.$modal.msgError("鑾峰彇浜у搧鏁版嵁澶辫触锛岃閲嶈瘯");
@@ -1332,10 +1494,10 @@
 const executePrint = () => {
 	console.log('寮�濮嬫墽琛屾墦鍗帮紝鏁版嵁鏉℃暟:', printData.value.length);
 	console.log('鎵撳嵃鏁版嵁:', printData.value);
-	
+
 	// 鍒涘缓涓�涓柊鐨勬墦鍗扮獥鍙�
 	const printWindow = window.open('', '_blank', 'width=800,height=600');
-	
+
 	// 鏋勫缓鎵撳嵃鍐呭
 	let printContent = `
     <!DOCTYPE html>
@@ -1396,7 +1558,7 @@
         }
         .label {
           font-weight: bold;
-          width: 60px;
+          min-width: 60px;
           font-size: 12px;
         }
         .value {
@@ -1404,10 +1566,11 @@
           min-width: 80px;
           font-size: 12px;
         }
-                 .table-section {
-                 margin-bottom: 40px;
-          //  flex: 0.6;
-         }
+        .table-section {
+          margin-bottom: 4px;
+          flex: 1;
+          display: flex;
+        }
         .product-table {
           width: 100%;
           border-collapse: collapse;
@@ -1435,13 +1598,66 @@
           line-height: 22px;
           justify-content: space-between;
         }
+        .remarks-section {
+          margin: 10px 0;
+
+          .remark-item {
+            display: flex;
+            align-items: flex-start;
+
+            .label {
+              font-weight: bold;
+              min-width: 30px;
+              font-size: 14px;
+              margin-right: 10px;
+              white-space: nowrap;
+            }
+
+            .value {
+              flex: 1;
+              font-size: 14px;
+              line-height: 1.4;
+            }
+          }
+        }
+
+        .sign-section {
+          margin-top: 15px;
+
+          .sign-row {
+            display: flex;
+            justify-content: space-between;
+            margin-bottom: 10px;
+
+            .sign-item {
+              display: flex;
+              align-items: center;
+              width: 48%;
+
+              .label {
+                font-weight: bold;
+                font-size: 14px;
+                margin-right: 10px;
+                white-space: nowrap;
+              }
+
+              .value {
+                flex: 1;
+                min-height: 30px;
+                border-bottom: 1px solid #000;
+                font-size: 14px;
+              }
+            }
+          }
+        }
+
         .footer-item {
           display: flex;
           margin-right: 20px;
         }
         .footer-item .label {
           font-weight: bold;
-          width: 80px;
+          min-width: 80px;
           font-size: 12px;
         }
         .footer-item .value {
@@ -1471,114 +1687,146 @@
     </head>
     <body>
   `;
-	
+
 	// 涓烘瘡鏉℃暟鎹敓鎴愭墦鍗伴〉闈�
 	printData.value.forEach((item, index) => {
 		printContent += `
       <div class="print-page">
         <div class="delivery-note">
           <div class="header">
-            <div class="company-name">榧庤瘹鐟炲疄涓氭湁闄愯矗浠诲叕鍙�</div>
-            <div class="document-title">闆跺敭鍙戣揣鍗�</div>
+              <div class="company-name">婀栧崡楣忓垱鐢靛瓙鏈夐檺鍏徃</div>
+              <div class="document-title">閫佽揣鍗�</div>
           </div>
-          
           <div class="info-section">
-            <div class="info-row">
-              <div>
-                <span class="label">鍙戣揣鏃ユ湡锛�</span>
-                <span class="value">${formatDate(item.createTime)}</span>
+              <div class="info-row">
+                <div>
+                  <span class="label">瀹㈡埛鍚嶇О锛�</span>
+                  <span class="value">${item.customerName || ''}</span>
+                </div>
+                <div>
+                  <span class="label">閫佽揣鍦板潃锛�</span>
+                  <span class="value">${item.companyAddress || ''}</span>
+                </div>
               </div>
-              <div>
-                <span class="label">瀹㈡埛鍚嶇О锛�</span>
-                <span class="value">${item.customerName || '寮犵埍鏈�'}</span>
-              </div>
-            </div>
-            <div class="info-row">
-              <span class="label">鍗曞彿锛�</span>
-              <span class="value">${item.salesContractNo || ''}</span>
-            </div>
-          </div>
+              <div class="info-row">
+                <div>
+                  <span class="label">鍗曟嵁缂栧彿锛�</span>
+                  <span class="value">${item.salesContractNo || ''}</span>
+                </div>
 
+                <div>
+                  <span class="label">閫佽揣鏃ユ湡锛�</span>
+                  <span class="value">${formatDate(null)}</span>
+                </div>
+
+                <div>
+                  <span class="label">鑱旂郴鐢佃瘽锛�</span>
+                  <span class="value">${item.contactPhone || ''}</span>
+                </div>
+              </div>
+            </div>
+
+          <div class="info-section">
+              <div class="info-row">
+                <div>
+                  <span class="label">鑱旂郴鏂瑰紡锛�</span>
+                  <span class="value"></span>
+                </div>
+                <div>
+                  <span class="label">閫佽揣鍗曚綅锛�</span>
+                  <span class="value">婀栧崡楣忓垱鐢靛瓙鏈夐檺鍏徃</span>
+                </div>
+                <div>
+                  <span class="label">鍦板潃锛�</span>
+                  <span class="value">婀栧崡鑰掗槼甯傚垱鏂板垱涓氬洯A1鏍�</span>
+                </div>
+              </div>
+            </div>
+
+          <span style="font-size: 16px;">璐х墿璇︾粏淇℃伅锛�</span>
           <div class="table-section">
             <table class="product-table">
               <thead>
                 <tr>
-                  <th>浜у搧鍚嶇О</th>
-                  <th>瑙勬牸鍨嬪彿</th>
+                  <th>搴忓彿</th>
+                  <th>鏂欏彿</th>
+                  <th>鍝佸悕/瑙勬牸</th>
                   <th>鍗曚綅</th>
-                  <th>鍗曚环</th>
-                  <th>闆跺敭鏁伴噺</th>
-                  <th>闆跺敭閲戦</th>
+                  <th>鏁伴噺</th>
+                  <th>璁㈠崟鍙�</th>
                 </tr>
               </thead>
-              <tbody>
+                  <tbody>
                 ${item.products && item.products.length > 0 ?
-			item.products.map(product => `
+				item.products.map((product, index) => `
                     <tr>
-                      <td>${product.productCategory || ''}</td>
-                      <td>${product.specificationModel || ''}</td>
+                      <td>${index + 1}</td>
+                      <td>${product.materialCode || ''}</td>
+                      <td>${product.productCategory || ''}/${product.specificationModel || ''}</td>
                       <td>${product.unit || ''}</td>
-                      <td>${product.taxInclusiveUnitPrice || '0'}</td>
                       <td>${product.quantity || '0'}</td>
-                      <td>${product.taxInclusiveTotalPrice || '0'}</td>
+                      <td>${item.salesContractNo || ''}</td>
                     </tr>
                   `).join('') :
-			'<tr><td colspan="6" style="text-align: center; color: #999;">鏆傛棤浜у搧鏁版嵁</td></tr>'
-		}
+				'<tr><td colspan="6" style="text-align: center; color: #999;">鏆傛棤浜у搧鏁版嵁</td></tr>'
+			}
               </tbody>
               <tfoot>
                 <tr>
+                  <td></td>
                   <td class="label">鍚堣</td>
                   <td class="total-value"></td>
                   <td class="total-value"></td>
+                  <td class="total-value">${getTotalQuantity(item.products) || '0'}</td>
                   <td class="total-value"></td>
-                  <td class="total-value">${getTotalQuantityForPrint(item.products)}</td>
-                  <td class="total-value">${getTotalAmountForPrint(item.products)}</td>
                 </tr>
               </tfoot>
             </table>
+
+            <div style="width: 30px;">
+              鍏卞洓鑱斿瓨鏍瑰洖鍗曞鎴蜂粨搴�
+            </div>
           </div>
 
-          <div class="footer-section">
-            <div class="footer-row">
-              <div class="footer-item">
-                <span class="label">鏀惰揣鐢佃瘽锛�</span>
-                <span class="value"></span>
+          <div class="remarks-section">
+            <div class="remark-item">
+              <span class="label">澶囨敞锛�</span>
+              <span class="value">璐靛叕鍙稿湪鏀惰揣鍚庤鍗冲埢鏍稿疄鏁伴噺鍙婂搧璐紝鑻ユ湁寮傝锛岃鍦�3鏃ュ唴鎻愬嚭锛屽惁鍒欒涓烘敹濡ャ��</span>
+            </div>
+          </div>
+          <div class="sign-section">
+            <div class="sign-row">
+              <div class="sign-item">
+                <span class="label">閫佽揣鍗曚綅锛堢绔狅級锛�</span>
               </div>
-              <div class="footer-item">
-                <span class="label">鏀惰揣浜猴細</span>
-                <span class="value"></span>
-              </div>
-              <div class="footer-item address-item">
-                <span class="label">鏀惰揣鍦板潃锛�</span>
-                <span class="value address-value"></span>
+              <div class="sign-item">
+                <span class="label">鏀惰揣鍗曚綅锛�</span>
               </div>
             </div>
-            <div class="footer-row">
-              <div class="footer-item">
-                <span class="label">鎿嶄綔鍛橈細</span>
-                <span class="value">${userStore.nickName || '鎾曞紑鍓�'}</span>
+            <div class="sign-row">
+              <div class="sign-item">
+                <span class="label">閫佽揣浜猴細</span>
               </div>
-              <div class="footer-item">
-                <span class="label">鎵撳嵃鏃ユ湡锛�</span>
-                <span class="value">${formatDateTime(new Date())}</span>
+              <div class="sign-item">
+                <span class="label">鏀惰揣浜猴細</span>
               </div>
             </div>
           </div>
+
         </div>
       </div>
     `;
 	});
-	
+
 	printContent += `
     </body>
     </html>
   `;
-	
+
 	// 鍐欏叆鍐呭鍒版柊绐楀彛
 	printWindow.document.write(printContent);
 	printWindow.document.close();
-	
+
 	// 绛夊緟鍐呭鍔犺浇瀹屾垚鍚庢墦鍗�
 	printWindow.onload = () => {
 		setTimeout(() => {
@@ -1590,13 +1838,14 @@
 };
 // 鏍煎紡鍖栨棩鏈�
 const formatDate = (dateString) => {
-	if (!dateString) return getCurrentDate();
+	if (!dateString) return getCurrentDate().replace(/-/g, '/');
 	const date = new Date(dateString);
 	const year = date.getFullYear();
 	const month = String(date.getMonth() + 1).padStart(2, "0");
 	const day = String(date.getDate()).padStart(2, "0");
 	return `${year}/${month}/${day}`;
 };
+
 // 鏍煎紡鍖栨棩鏈熸椂闂�
 const formatDateTime = (date) => {
 	const year = date.getFullYear();
@@ -1669,19 +1918,19 @@
 // 鏍规嵁鍚◣鎬讳环璁$畻鍚◣鍗曚环鍜屾暟閲�
 const calculateFromTotalPrice = () => {
 	if (isCalculating.value) return;
-	
+
 	const totalPrice = parseFloat(productForm.value.taxInclusiveTotalPrice);
 	const quantity = parseFloat(productForm.value.quantity);
-	
+
 	if (!totalPrice || !quantity || quantity <= 0) {
 		return;
 	}
-	
+
 	isCalculating.value = true;
-	
+
 	// 璁$畻鍚◣鍗曚环 = 鍚◣鎬讳环 / 鏁伴噺
 	productForm.value.taxInclusiveUnitPrice = (totalPrice / quantity).toFixed(2);
-	
+
 	// 濡傛灉鏈夌◣鐜囷紝璁$畻涓嶅惈绋庢�讳环
 	if (productForm.value.taxRate) {
 		productForm.value.taxExclusiveTotalPrice =
@@ -1690,7 +1939,7 @@
 				productForm.value.taxRate
 			);
 	}
-	
+
 	isCalculating.value = false;
 };
 
@@ -1701,25 +1950,25 @@
 		return;
 	}
 	if (isCalculating.value) return;
-	
+
 	const exclusiveTotalPrice = parseFloat(productForm.value.taxExclusiveTotalPrice);
 	const quantity = parseFloat(productForm.value.quantity);
 	const taxRate = parseFloat(productForm.value.taxRate);
-	
+
 	if (!exclusiveTotalPrice || !quantity || quantity <= 0 || !taxRate) {
 		return;
 	}
-	
+
 	isCalculating.value = true;
-	
+
 	// 鍏堣绠楀惈绋庢�讳环 = 涓嶅惈绋庢�讳环 / (1 - 绋庣巼/100)
 	const taxRateDecimal = taxRate / 100;
 	const inclusiveTotalPrice = exclusiveTotalPrice / (1 - taxRateDecimal);
 	productForm.value.taxInclusiveTotalPrice = inclusiveTotalPrice.toFixed(2);
-	
+
 	// 璁$畻鍚◣鍗曚环 = 鍚◣鎬讳环 / 鏁伴噺
 	productForm.value.taxInclusiveUnitPrice = (inclusiveTotalPrice / quantity).toFixed(2);
-	
+
 	isCalculating.value = false;
 };
 
@@ -1730,19 +1979,19 @@
 		return;
 	}
 	if (isCalculating.value) return;
-	
+
 	const quantity = parseFloat(productForm.value.quantity);
 	const unitPrice = parseFloat(productForm.value.taxInclusiveUnitPrice);
-	
+
 	if (!quantity || quantity <= 0 || !unitPrice) {
 		return;
 	}
-	
+
 	isCalculating.value = true;
-	
+
 	// 璁$畻鍚◣鎬讳环
 	productForm.value.taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2);
-	
+
 	// 濡傛灉鏈夌◣鐜囷紝璁$畻涓嶅惈绋庢�讳环
 	if (productForm.value.taxRate) {
 		productForm.value.taxExclusiveTotalPrice =
@@ -1751,7 +2000,7 @@
 				productForm.value.taxRate
 			);
 	}
-	
+
 	isCalculating.value = false;
 };
 
@@ -1762,19 +2011,19 @@
 		return;
 	}
 	if (isCalculating.value) return;
-	
+
 	const quantity = parseFloat(productForm.value.quantity);
 	const unitPrice = parseFloat(productForm.value.taxInclusiveUnitPrice);
-	
+
 	if (!quantity || quantity <= 0 || !unitPrice) {
 		return;
 	}
-	
+
 	isCalculating.value = true;
-	
+
 	// 璁$畻鍚◣鎬讳环
 	productForm.value.taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2);
-	
+
 	// 濡傛灉鏈夌◣鐜囷紝璁$畻涓嶅惈绋庢�讳环
 	if (productForm.value.taxRate) {
 		productForm.value.taxExclusiveTotalPrice =
@@ -1783,7 +2032,7 @@
 				productForm.value.taxRate
 			);
 	}
-	
+
 	isCalculating.value = false;
 };
 
@@ -1794,25 +2043,111 @@
 		return;
 	}
 	if (isCalculating.value) return;
-	
+
 	const inclusiveTotalPrice = parseFloat(productForm.value.taxInclusiveTotalPrice);
 	const taxRate = parseFloat(productForm.value.taxRate);
-	
+
 	if (!inclusiveTotalPrice || !taxRate) {
 		return;
 	}
-	
+
 	isCalculating.value = true;
-	
+
 	// 璁$畻涓嶅惈绋庢�讳环
 	productForm.value.taxExclusiveTotalPrice =
 		proxy.calculateTaxExclusiveTotalPrice(
 			inclusiveTotalPrice,
 			taxRate
 		);
-	
+
 	isCalculating.value = false;
 };
+/**
+ * 鑾峰彇鍙戣揣鐘舵�佹枃鏈�
+ * @param row 琛屾暟鎹�
+ */
+const getShippingStatusText = (row) => {
+	// 濡傛灉宸插彂璐э紙鏈夊彂璐ф棩鏈熸垨杞︾墝鍙凤級锛屾樉绀�"宸插彂璐�"
+	if (row.shippingDate || row.shippingCarNumber) {
+		return '宸插彂璐�';
+	}
+
+	// 鑾峰彇鍙戣揣鐘舵�佸瓧娈�
+	const status = row.shippingStatus;
+
+	// 濡傛灉鐘舵�佷负绌烘垨鏈畾涔夛紝榛樿涓�"寰呭彂璐�"
+	if (status === null || status === undefined || status === '') {
+		return '寰呭彂璐�';
+	}
+
+	// 鐘舵�佹槸瀛楃涓�
+	const statusStr = String(status).trim();
+	const statusTextMap = {
+		'寰呭彂璐�': '寰呭彂璐�',
+		'寰呭鏍�': '寰呭鏍�',
+		'瀹℃牳涓�': '瀹℃牳涓�',
+		'瀹℃牳鎷掔粷': '瀹℃牳鎷掔粷',
+		'瀹℃牳閫氳繃': '瀹℃牳閫氳繃',
+		'宸插彂璐�': '宸插彂璐�'
+	};
+	return statusTextMap[statusStr] || '寰呭彂璐�';
+};
+
+/**
+ * 鑾峰彇鍙戣揣鐘舵�佹爣绛剧被鍨嬶紙棰滆壊锛�
+ * @param row 琛屾暟鎹�
+ */
+const getShippingStatusType = (row) => {
+	// 濡傛灉宸插彂璐э紙鏈夊彂璐ф棩鏈熸垨杞︾墝鍙凤級锛屾樉绀虹豢鑹�
+	if (row.shippingDate || row.shippingCarNumber) {
+		return 'success';
+	}
+
+	// 鑾峰彇鍙戣揣鐘舵�佸瓧娈�
+	const status = row.shippingStatus;
+
+	// 濡傛灉鐘舵�佷负绌烘垨鏈畾涔夛紝榛樿涓虹伆鑹诧紙寰呭彂璐э級
+	if (status === null || status === undefined || status === '') {
+		return 'info';
+	}
+
+	// 鐘舵�佹槸瀛楃涓�
+	const statusStr = String(status).trim();
+	const typeTextMap = {
+		'寰呭彂璐�': 'info',
+		'寰呭鏍�': 'info',
+		'瀹℃牳涓�': 'warning',
+		'瀹℃牳鎷掔粷': 'danger',
+		'瀹℃牳閫氳繃': 'success',
+		'宸插彂璐�': 'success'
+	};
+	return typeTextMap[statusStr] || 'info';
+};
+
+/**
+ * 鍒ゆ柇鏄惁鍙互鍙戣揣
+ * 鍙湁鍦ㄤ骇鍝佺姸鎬佹槸鍏呰冻锛屽彂璐х姸鎬佹槸寰呭彂璐у拰瀹℃牳鎷掔粷鐨勬椂鍊欐墠鍙互鍙戣揣
+ * @param row 琛屾暟鎹�
+ */
+const canShip = (row) => {
+	// 浜у搧鐘舵�佸繀椤绘槸鍏呰冻锛坅pproveStatus === 1锛�
+	if (row.approveStatus !== 1) {
+		return false;
+	}
+
+	// 鑾峰彇鍙戣揣鐘舵��
+	const shippingStatus = row.shippingStatus;
+
+	// 濡傛灉宸插彂璐э紙鏈夊彂璐ф棩鏈熸垨杞︾墝鍙凤級锛屼笉鑳藉啀娆″彂璐�
+	if (row.shippingDate || row.shippingCarNumber) {
+		return false;
+	}
+
+	// 鍙戣揣鐘舵�佸繀椤绘槸"寰呭彂璐�"鎴�"瀹℃牳鎷掔粷"
+	const statusStr = shippingStatus ? String(shippingStatus).trim() : '';
+	return statusStr === '寰呭彂璐�' || statusStr === '瀹℃牳鎷掔粷';
+};
+
 /**
  * 涓嬭浇鏂囦欢
  *
@@ -1824,54 +2159,80 @@
 	getSalesLedgerWithProducts({ id: row.id, type: 1 }).then((res) => {
 		if (fileListRef.value) {
 			fileListRef.value.open(res.salesLedgerFiles)
-			fileListDialogVisible.value = true
 		}
 	});
 }
 
 // 鎵撳紑鍙戣揣寮规
 const openDeliveryForm = (row) => {
+	// 妫�鏌ユ槸鍚﹀彲浠ュ彂璐�
+	if (!canShip(row)) {
+		proxy.$modal.msgWarning("鍙湁鍦ㄤ骇鍝佺姸鎬佹槸鍏呰冻锛屽彂璐х姸鎬佹槸寰呭彂璐ф垨瀹℃牳鎷掔粷鐨勬椂鍊欐墠鍙互鍙戣揣");
+		return;
+	}
+
 	currentDeliveryRow.value = row;
-  deliveryForm.value = {
-    type: "璐ц溅",
-  };
-  // 閲嶇疆瀹℃壒浜鸿妭鐐癸紙榛樿涓�涓┖鑺傜偣锛�
-  approverNodes.value = [{ id: 1, userId: null }];
-  nextApproverId = 2;
+	deliveryForm.value = {
+		type: "璐ц溅",
+	};
+	// 閲嶇疆瀹℃壒浜鸿妭鐐癸紙榛樿涓�涓┖鑺傜偣锛�
+	approverNodes.value = [{ id: 1, userId: null }];
+	nextApproverId = 2;
 	deliveryFormVisible.value = true;
 };
 
 // 鎻愪氦鍙戣揣琛ㄥ崟
 const submitDelivery = () => {
-  proxy.$refs["deliveryFormRef"].validate((valid) => {
-    if (valid) {
-      // 瀹℃壒浜哄繀濉牎楠岋紙鎵�鏈夎妭鐐归兘瑕侀�変汉锛�
-      const hasEmptyApprover = approverNodes.value.some(node => !node.userId);
-      if (hasEmptyApprover) {
-        proxy.$modal.msgError("璇蜂负鎵�鏈夊鎵硅妭鐐归�夋嫨瀹℃壒浜猴紒");
-        return;
-      }
-      const approveUserIds = approverNodes.value.map(node => node.userId).join(",");
-      addShippingInfo({
-        salesLedgerId: currentDeliveryRow.value.salesLedgerId,
-        salesLedgerProductId: currentDeliveryRow.value.id,
-        type: deliveryForm.value.type,
+	proxy.$refs["deliveryFormRef"].validate((valid) => {
+		if (valid) {
+			// 瀹℃壒浜哄繀濉牎楠岋紙鎵�鏈夎妭鐐归兘瑕侀�変汉锛�
+			const hasEmptyApprover = approverNodes.value.some(node => !node.userId);
+			if (hasEmptyApprover) {
+				proxy.$modal.msgError("璇蜂负鎵�鏈夊鎵硅妭鐐归�夋嫨瀹℃壒浜猴紒");
+				return;
+			}
+			const approveUserIds = approverNodes.value.map(node => node.userId).join(",");
+			// 淇濆瓨褰撳墠灞曞紑鐨勮ID锛屼互渚垮彂璐у悗閲嶆柊鍔犺浇瀛愯〃鏍兼暟鎹�
+			const currentExpandedKeys = [...expandedRowKeys.value];
+			const salesLedgerId = currentDeliveryRow.value.salesLedgerId;
+			addShippingInfo({
+				salesLedgerId: salesLedgerId,
+				salesLedgerProductId: currentDeliveryRow.value.id,
+				type: deliveryForm.value.type,
 				approveUserIds,
-      })
-        .then(() => {
-          proxy.$modal.msgSuccess("鍙戣揣鎴愬姛");
-          closeDeliveryDia();
-          getList();
-        })
-    }
-  });
+			})
+				.then(() => {
+					proxy.$modal.msgSuccess("鍙戣揣鎴愬姛");
+					closeDeliveryDia();
+					// 鍒锋柊涓昏〃鏁版嵁
+					getList().then(() => {
+						// 濡傛灉涔嬪墠鏈夊睍寮�鐨勮锛岄噸鏂板姞杞借繖浜涜鐨勫瓙琛ㄦ牸鏁版嵁
+						if (currentExpandedKeys.length > 0) {
+							// 浣跨敤 Promise.all 骞惰鍔犺浇鎵�鏈夊睍寮�琛岀殑瀛愯〃鏍兼暟鎹�
+							const loadPromises = currentExpandedKeys.map(ledgerId => {
+								return productList({ salesLedgerId: ledgerId, type: 1 }).then((res) => {
+									const index = tableData.value.findIndex((item) => item.id === ledgerId);
+									if (index > -1) {
+										tableData.value[index].children = res.data;
+									}
+								});
+							});
+							Promise.all(loadPromises).then(() => {
+								// 鎭㈠灞曞紑鐘舵��
+								expandedRowKeys.value = currentExpandedKeys;
+							});
+						}
+					});
+				})
+		}
+	});
 };
 
 // 鍏抽棴鍙戣揣寮规
 const closeDeliveryDia = () => {
-  proxy.resetForm("deliveryFormRef");
-  deliveryFormVisible.value = false;
-  currentDeliveryRow.value = null;
+	proxy.resetForm("deliveryFormRef");
+	deliveryFormVisible.value = false;
+	currentDeliveryRow.value = null;
 };
 const currentFactoryName = ref("");
 const getCurrentFactoryName = async () => {
@@ -1892,6 +2253,22 @@
 	margin-left: 10px;
 }
 
+::v-deep .yellow {
+	background-color: #FAF0DE;
+}
+
+::v-deep .pink {
+	background-color: #FAE1DE;
+}
+
+::v-deep .red {
+	background-color: #FAE1DE;
+}
+
+::v-deep .purple {
+	background-color: #F4DEFA;
+}
+
 .table_list {
 	margin-top: unset;
 }
@@ -1901,6 +2278,7 @@
 	justify-content: space-between;
 	margin-bottom: 10px;
 }
+
 .print-preview-dialog {
 	.el-dialog__body {
 		padding: 0;
@@ -1914,12 +2292,12 @@
 		padding: 15px;
 		border-bottom: 1px solid #e4e7ed;
 		text-align: center;
-		
+
 		.el-button {
 			margin: 0 10px;
 		}
 	}
-	
+
 	.print-preview-content {
 		padding: 20px;
 		background-color: #f5f5f5;
@@ -1929,7 +2307,7 @@
 
 .print-page {
 	width: 220mm;
-	height: 90mm;
+	min-height: 90mm;
 	padding: 10mm;
 	margin: 0 auto;
 	background: white;
@@ -1951,13 +2329,13 @@
 .header {
 	text-align: center;
 	margin-bottom: 8px;
-	
+
 	.company-name {
 		font-size: 18px;
 		font-weight: bold;
 		margin-bottom: 4px;
 	}
-	
+
 	.document-title {
 		font-size: 16px;
 		font-weight: bold;
@@ -1969,16 +2347,16 @@
 	display: flex;
 	justify-content: space-between;
 	align-items: center;
-	
+
 	.info-row {
 		line-height: 20px;
-		
+
 		.label {
 			font-weight: bold;
 			width: 60px;
 			font-size: 14px;
 		}
-		
+
 		.value {
 			margin-right: 20px;
 			min-width: 80px;
@@ -1990,29 +2368,31 @@
 .table-section {
 	margin-bottom: 4px;
 	flex: 1;
-	
+	display: flex;
+
 	.product-table {
 		width: 100%;
 		border-collapse: collapse;
 		border: 1px solid #000;
-		
-		th, td {
+
+		th,
+		td {
 			border: 1px solid #000;
 			padding: 6px;
 			text-align: center;
 			font-size: 14px;
 			line-height: 1.4;
 		}
-		
+
 		th {
 			font-weight: bold;
 		}
-		
+
 		.total-label {
 			text-align: right;
 			font-weight: bold;
 		}
-		
+
 		.total-value {
 			font-weight: bold;
 		}
@@ -2024,23 +2404,25 @@
 		display: flex;
 		margin-bottom: 3px;
 		line-height: 20px;
-		justify-content: space-between;
-		
+		justify-content: flex-start;
+
 		.footer-item {
 			display: flex;
+			align-items: center;
 			margin-right: 20px;
-			
+
 			.label {
 				font-weight: bold;
-				width: 80px;
+				white-space: nowrap;
+				margin-right: 10px;
 				font-size: 14px;
 			}
-			
+
 			.value {
-				min-width: 80px;
+				min-width: 300px;
 				font-size: 14px;
 			}
-			
+
 			&.address-item {
 				.address-value {
 					min-width: 200px;
@@ -2054,7 +2436,7 @@
 	.app-container {
 		display: none;
 	}
-	
+
 	.print-page {
 		box-shadow: none;
 		margin: 0;
@@ -2063,6 +2445,7 @@
 		page-break-inside: avoid;
 		page-break-after: always;
 	}
+
 	.print-page:last-child {
 		page-break-after: avoid;
 	}

--
Gitblit v1.9.3