Explorar o código

小程序合同优化

ouyj hai 1 semana
pai
achega
c79619cfb6
Modificáronse 2 ficheiros con 180 adicións e 26 borrados
  1. 110 15
      components/processForms/contract-form.vue
  2. 70 11
      pages/work/contract/start.vue

+ 110 - 15
components/processForms/contract-form.vue

@@ -307,9 +307,10 @@
 
           <!-- 展开的详细信息 -->
           <view v-show="item.expanded" class="material-detail">
-            <view class="detail-row">
+            <!-- 采购申请单编号(仅当从采购申请单添加且非销售合同时显示) -->
+            <view v-if="!isSalesContract && item.purchaseNumber" class="detail-row purchase-number-row">
               <text class="detail-label">采购申请单号:</text>
-              <text class="detail-value purchase-number">{{ item.purchaseNumber || '-' }}</text>
+              <text class="detail-value purchase-number">{{ item.purchaseNumber }}</text>
             </view>
             <view class="detail-row">
               <text class="detail-label">规格型号:</text>
@@ -506,8 +507,8 @@
 		      <uni-icons type="closeempty" size="20" @click="closePopup"></uni-icons>
 		    </view>
 
-		    <!-- 物料来源选择(仅物料选择时显示) -->
-		    <view v-if="selectorType === 'material'" class="material-source-selector">
+		    <!-- 物料来源选择(仅物料选择时显示,且非销售合同) -->
+		    <view v-if="selectorType === 'material' && !isSalesContract" class="material-source-selector">
 		      <view class="source-options">
 		        <view 
 		            :class="['source-option', materialSource === 'mes' ? 'active' : '']"
@@ -533,8 +534,8 @@
 		      <button type="primary" size="mini" @click="handleSearch">搜索</button>
 		    </view>
 
-		    <!-- 采购申请单选择器(采购申请模式) -->
-		    <view v-if="selectorType === 'material' && materialSource === 'purchase'" class="purchase-selector">
+		    <!-- 采购申请单选择器(采购申请模式,且非销售合同) -->
+		    <view v-if="selectorType === 'material' && materialSource === 'purchase' && !isSalesContract" class="purchase-selector">
 		      <picker @change="onPurchaseChange" :range="purchaseApplyList" range-key="contractPurchaseFormNumber">
 		        <view class="picker">
 		          {{ selectedPurchaseApply ? selectedPurchaseApply.contractPurchaseFormNumber : '全部采购申请单' }}
@@ -558,8 +559,8 @@
 		        <view class="selector-item-content">
 		          <view class="item-info">
 		            <text class="item-name">{{ getSelectorItemName(item) }}</text>
-		            <!-- 采购申请模式显示采购单号 -->
-		            <text v-if="materialSource === 'purchase' && item.purchaseNumber" class="item-purchase">
+		            <!-- 采购申请模式显示采购单号(仅非销售合同) -->
+		            <text v-if="!isSalesContract && materialSource === 'purchase' && item.purchaseNumber" class="item-purchase">
 		              采购单:{{ item.purchaseNumber }}
 		            </text>
 		            <text v-if="getItemCode(item)" class="item-code">{{ getItemCode(item) }}</text>
@@ -836,6 +837,9 @@ watch(() => props.formData, (newVal) => {
 			universalid: newVal.universalid || ''
 		}
 		
+		// 初始化 lastContractType
+		lastContractType = String(newVal.contract_type || '')
+		
 		// 从 contractMaterialList 中获取物料列表
 		const rawMaterialList = newVal.details || newVal.contractMaterialList || []
 				
@@ -859,6 +863,30 @@ watch(() => props.formData, (newVal) => {
 			materialList.value = []
 		}
 		
+		// 如果是销售合同,立即清理来自采购申请单的物料(与 onContractTypeChange 逻辑一致)
+		if ((newVal.contract_type === '1' || newVal.contract_type === 1) && materialList.value.length > 0) {
+			const invalidMaterials: number[] = []
+			materialList.value.forEach((item, idx) => {
+				const purchaseId = item.purchaseId || ''
+				const purchaseNumber = item.purchaseNumber || ''
+				// 排除空值、null字符串、0等无效值
+				if ((purchaseId && purchaseId !== 'null' && purchaseId !== '0' && purchaseId !== 'undefined') || 
+				    (purchaseNumber && purchaseNumber !== 'null' && purchaseNumber !== 'undefined')) {
+					invalidMaterials.push(idx)
+				}
+			})
+			
+			if (invalidMaterials.length > 0) {
+				// 直接删除不符合要求的物料(从后往前删,避免索引错乱)
+				for (let i = invalidMaterials.length - 1; i >= 0; i--) {
+					materialList.value.splice(invalidMaterials[i], 1)
+				}
+				// 重新计算总价
+				calculateTotalPrice()
+				console.log(`销售合同初始化:已清除 ${invalidMaterials.length} 条来自采购申请单的物料`)
+			}
+		}
+		
 		// 从 contractPaymentList 中获取付款列表
 		const rawPaymentList = newVal.contractPaymentList || []
 						
@@ -1308,6 +1336,17 @@ function selectItem(item: any) {
       return
     }
     
+    // 销售合同不允许选择有采购申请单的物料
+    if (isSalesContract.value) {
+      const purchaseId = item.purchaseId || ''
+      const purchaseNumber = item.purchaseNumber || ''
+      if ((purchaseId && purchaseId !== 'null' && purchaseId !== '0' && purchaseId !== 'undefined') || 
+          (purchaseNumber && purchaseNumber !== 'null' && purchaseNumber !== 'undefined')) {
+        $modal.msgWarn('销售合同不允许选择来自采购申请单的物料')
+        return
+      }
+    }
+    
     // 确保数值字段正确转换(防止后端返回对象或字符串)
     const qty = parseFloat(item.qty) || 0
     const price = parseFloat(item.price) || 0
@@ -1324,8 +1363,8 @@ function selectItem(item: any) {
       price: price,
       cess: cess,
       priceTax: priceTax,
-      purchaseId: item.purchaseId || selectedPurchaseApply.value?.contractPurchaseFormId || '',
-      purchaseNumber: item.purchaseNumber || selectedPurchaseApply.value?.contractPurchaseFormNumber || '',
+      purchaseId: isSalesContract.value ? '' : (item.purchaseId || selectedPurchaseApply.value?.contractPurchaseFormId || ''),
+      purchaseNumber: isSalesContract.value ? '' : (item.purchaseNumber || selectedPurchaseApply.value?.contractPurchaseFormNumber || ''),
       expanded: true
     })
     
@@ -1347,11 +1386,59 @@ function selectItem(item: any) {
 }
 
 // 合同类型变化
+let lastContractType = '' // 保存上一次的合同类型
+
 function onContractTypeChange(e: any) {
 	const index = e.detail.value
 	if (contractTypeList.value[index]) {
-		baseForm.value.contract_type = contractTypeList.value[index].contract_type
+		const oldContractType = lastContractType
+		const newContractType = contractTypeList.value[index].contract_type
+		
+		// 如果合同类型发生变化,检查是否需要清理物料
+		if (oldContractType !== String(newContractType)) {
+			// 切换到销售合同时,检查是否有来自采购申请单的物料
+			if (newContractType === '1' || newContractType === 1) {
+				const invalidMaterials: number[] = []
+				materialList.value.forEach((item, idx) => {
+					const purchaseId = item.purchaseId || ''
+					const purchaseNumber = item.purchaseNumber || ''
+					// 排除空值、null字符串、0等无效值
+					if ((purchaseId && purchaseId !== 'null' && purchaseId !== '0' && purchaseId !== 'undefined') || 
+					    (purchaseNumber && purchaseNumber !== 'null' && purchaseNumber !== 'undefined')) {
+						invalidMaterials.push(idx)
+					}
+				})
+				
+				if (invalidMaterials.length > 0) {
+					$modal.confirm('', `检测到已选择的物料中有 ${invalidMaterials.length} 条来自采购申请单的数据,销售合同不允许使用采购申请单物料,是否清除这些不符合要求的物料?`)
+						.then(() => {
+							// 用户确认,删除不符合要求的物料(从后往前删,避免索引错乱)
+							for (let i = invalidMaterials.length - 1; i >= 0; i--) {
+								materialList.value.splice(invalidMaterials[i], 1)
+							}
+							// 重新计算总价
+							calculateTotalPrice()
+							// 更新合同类型为销售合同
+							baseForm.value.contract_type = newContractType
+							baseForm.value.contract_type_name = contractTypeList.value[index].contract_type_name
+							lastContractType = String(newContractType)
+							// 调整需方供方显示
+							adjustPartyDisplay()
+							$modal.msgSuccess(`已清除 ${invalidMaterials.length} 条不符合要求的物料`)
+						})
+						.catch(() => {
+							// 用户取消,恢复原来的合同类型
+							// 不需要做任何事,因为还没有更新 contract_type
+						})
+						return // 等待用户确认后再继续
+				}
+			}
+		}
+		
+		// 更新合同类型
+		baseForm.value.contract_type = newContractType
 		baseForm.value.contract_type_name = contractTypeList.value[index].contract_type_name
+		lastContractType = String(newContractType)
 		
 		// 根据合同类型调整需方和供方的显示
 		adjustPartyDisplay()
@@ -1759,10 +1846,18 @@ defineExpose({
 			}
 		}
 		
-		// 供方验证(发起环节或字段可编辑时需要验证)
-		if (isSeModel.value || getFieldEditable('secondparty_name')) {
-			if (!baseForm.value.secondparty_name || !baseForm.value.secondparty_name.trim()) {
-				return Promise.reject(new Error('供方不能为空!'))
+		// 根据合同类型验证不同字段:销售合同验证需方(客户),其他合同验证供方(供应商)
+		if (isSeModel.value || getFieldEditable(isSalesContract.value ? 'firstparty_name' : 'secondparty_name')) {
+			if (isSalesContract.value) {
+				// 销售合同:验证需方(客户)
+				if (!baseForm.value.firstparty_name || !baseForm.value.firstparty_name.trim()) {
+					return Promise.reject(new Error('需方不能为空!'))
+				}
+			} else {
+				// 其他合同:验证供方(供应商)
+				if (!baseForm.value.secondparty_name || !baseForm.value.secondparty_name.trim()) {
+					return Promise.reject(new Error('供方不能为空!'))
+				}
 			}
 		}
 		

+ 70 - 11
pages/work/contract/start.vue

@@ -136,8 +136,8 @@
               <text class="detail-label">税后单价:</text>
               <text class="detail-value price-value">{{ item.priceTax }}</text>
             </view>
-            <!-- 采购申请单编号(仅当从采购申请单添加时显示) -->
-            <view v-if="item.purchaseNumber" class="detail-row purchase-number-row">
+            <!-- 采购申请单编号(仅当从采购申请单添加且非销售合同时显示) -->
+            <view v-if="!isSalesContract && item.purchaseNumber" class="detail-row purchase-number-row">
               <text class="detail-label">采购申请单:</text>
               <text class="detail-value purchase-number">{{ item.purchaseNumber }}</text>
             </view>
@@ -275,8 +275,8 @@
           <uni-icons type="closeempty" size="20" @click="closePopup"></uni-icons>
         </view>
 
-        <!-- 物料来源选择(仅物料选择时显示) -->
-        <view v-if="selectorType === 'material'" class="material-source-selector">
+        <!-- 物料来源选择(仅物料选择时显示,且非销售合同) -->
+        <view v-if="selectorType === 'material' && !isSalesContract" class="material-source-selector">
           <view class="source-options">
             <view 
                 :class="['source-option', materialSource === 'mes' ? 'active' : '']"
@@ -302,8 +302,8 @@
           <button type="primary" size="mini" @click="handleSearch">搜索</button>
         </view>
 
-        <!-- 采购申请单选择器(采购申请模式) -->
-        <view v-if="selectorType === 'material' && materialSource === 'purchase'" class="purchase-selector">
+        <!-- 采购申请单选择器(采购申请模式,且非销售合同) -->
+        <view v-if="selectorType === 'material' && materialSource === 'purchase' && !isSalesContract" class="purchase-selector">
           <picker @change="onPurchaseChange" :range="purchaseApplyList" range-key="contractPurchaseFormNumber">
             <view class="picker">
               {{ selectedPurchaseApply ? selectedPurchaseApply.contractPurchaseFormNumber : '全部采购申请单' }}
@@ -327,8 +327,8 @@
             <view class="selector-item-content">
               <view class="item-info">
                 <text class="item-name">{{ getSelectorItemName(item) }}</text>
-                <!-- 采购申请模式显示采购单号 -->
-                <text v-if="materialSource === 'purchase' && item.purchaseNumber" class="item-purchase">
+                <!-- 采购申请模式显示采购单号(仅非销售合同) -->
+                <text v-if="!isSalesContract && materialSource === 'purchase' && item.purchaseNumber" class="item-purchase">
                   采购单:{{ item.purchaseNumber }}
                 </text>
                 <text v-if="getItemCode(item)" class="item-code">{{ getItemCode(item) }}</text>
@@ -1082,6 +1082,17 @@ function addMaterial(item: any) {
     $modal.msgWarn('该物料已存在')
     return
   }
+  
+  // 销售合同不允许选择有采购申请单的物料
+  if (isSalesContract.value) {
+    const purchaseId = item.purchaseId || ''
+    const purchaseNumber = item.purchaseNumber || ''
+    if ((purchaseId && purchaseId !== 'null' && purchaseId !== '0' && purchaseId !== 'undefined') || 
+        (purchaseNumber && purchaseNumber !== 'null' && purchaseNumber !== 'undefined')) {
+      $modal.msgWarn('销售合同不允许选择来自采购申请单的物料')
+      return
+    }
+  }
 
   // 确保数值字段正确转换(防止后端返回对象或字符串)
   const qty = parseFloat(item.qty) || 0
@@ -1098,8 +1109,8 @@ function addMaterial(item: any) {
     price: price,
     cess: cess,
     priceTax: priceTax,
-    purchaseId: item.purchaseId || selectedPurchaseApply.value?.contractPurchaseFormId || '',
-    purchaseNumber: item.purchaseNumber || selectedPurchaseApply.value?.contractPurchaseFormNumber || '',
+    purchaseId: isSalesContract.value ? '' : (item.purchaseId || selectedPurchaseApply.value?.contractPurchaseFormId || ''),
+    purchaseNumber: isSalesContract.value ? '' : (item.purchaseNumber || selectedPurchaseApply.value?.contractPurchaseFormNumber || ''),
     expanded: true
   })
 
@@ -1196,10 +1207,58 @@ function removePayment(index: number) {
 }
 
 // 合同类型变化
+let lastContractType = '' // 保存上一次的合同类型
+
 function onContractTypeChange(e: any) {
   const index = e.detail.value
-  baseForm.contract_type = contractTypeList.value[index].contract_type
+  const oldContractType = lastContractType
+  const newContractType = contractTypeList.value[index].contract_type
+  
+  // 如果合同类型发生变化,检查是否需要清理物料
+  if (oldContractType !== String(newContractType)) {
+    // 切换到销售合同时,检查是否有来自采购申请单的物料
+    if (newContractType === '1' || newContractType === 1) {
+      const invalidMaterials: number[] = []
+      materialList.value.forEach((item, idx) => {
+        const purchaseId = item.purchaseId || ''
+        const purchaseNumber = item.purchaseNumber || ''
+        // 排除空值、null字符串、0等无效值
+        if ((purchaseId && purchaseId !== 'null' && purchaseId !== '0' && purchaseId !== 'undefined') || 
+            (purchaseNumber && purchaseNumber !== 'null' && purchaseNumber !== 'undefined')) {
+          invalidMaterials.push(idx)
+        }
+      })
+      
+      if (invalidMaterials.length > 0) {
+        $modal.confirm('', `检测到已选择的物料中有 ${invalidMaterials.length} 条来自采购申请单的数据,销售合同不允许使用采购申请单物料,是否清除这些不符合要求的物料?`)
+          .then(() => {
+            // 用户确认,删除不符合要求的物料(从后往前删,避免索引错乱)
+            for (let i = invalidMaterials.length - 1; i >= 0; i--) {
+              materialList.value.splice(invalidMaterials[i], 1)
+            }
+            // 重新计算总价
+            calculateTotalPrice()
+            // 更新合同类型为销售合同
+            baseForm.contract_type = newContractType
+            baseForm.contract_type_name = contractTypeList.value[index].contract_type_name
+            lastContractType = String(newContractType)
+            // 调整需方供方显示
+            adjustPartyDisplay()
+            $modal.msgSuccess(`已清除 ${invalidMaterials.length} 条不符合要求的物料`)
+          })
+          .catch(() => {
+            // 用户取消,恢复原来的合同类型
+            // 不需要做任何事,因为还没有更新 contract_type
+          })
+        return // 等待用户确认后再继续
+      }
+    }
+  }
+  
+  // 更新合同类型
+  baseForm.contract_type = newContractType
   baseForm.contract_type_name = contractTypeList.value[index].contract_type_name
+  lastContractType = String(newContractType)
   
   // 根据合同类型调整需方和供方的显示
   adjustPartyDisplay()