Browse Source

fleat: product update 2

igb 3 weeks ago
parent
commit
8c1204898e
1 changed files with 404 additions and 73 deletions
  1. 404 73
      order_edit.php

+ 404 - 73
order_edit.php

@@ -28,16 +28,21 @@ if (!empty($id) && is_numeric($id)) {
     }
 
     // 获取订单项信息
-    $sql = "SELECT oi.*, p.ProductName, pc.name as category_name 
+    $sql = "SELECT oi.*, p.ProductName, pc.name as category_name, 
+                   ps.id as product_spec_id, ps.spec_name, ps.spec_value,
+                   oi.specification_id  /* 显式获取数据库中的specification_id */
             FROM order_items oi 
             LEFT JOIN products p ON oi.product_id = p.id 
             LEFT JOIN product_categories pc ON p.category_id = pc.id
+            LEFT JOIN product_specifications ps ON oi.specification_id = ps.id
             WHERE oi.order_id = $id";
 
     $itemsResult = mysqli_query($conn, $sql);
 
     $orderItems = [];
     while ($itemRow = mysqli_fetch_assoc($itemsResult)) {
+        // 调试输出
+        error_log("订单项数据: " . print_r($itemRow, true));
         $orderItems[] = $itemRow;
     }
 } else {
@@ -295,11 +300,11 @@ if (!empty($id) && is_numeric($id)) {
                     
                     <div class="product-list-header" style="display: flex; background-color: #eee; padding: 8px 15px; margin-bottom: 10px; border-radius: 4px; font-weight: bold; color: #555; font-size: 13px; gap: 8px;">
                         <div style="flex: 2; min-width: 200px;">产品</div>
+                        <div style="flex: 2; min-width: 200px;">规格</div>
                         <div style="flex: 1; min-width: 80px;">数量</div>
                         <div style="flex: 0.5; min-width: 60px;">单位</div>
                         <div style="flex: 1; min-width: 100px;">单价</div>
                         <div style="flex: 1; min-width: 100px;">总价</div>
-                        <div style="flex: 2; min-width: 200px;">备注</div>
                     </div>
                     
                     <div id="product-container">
@@ -310,6 +315,8 @@ if (!empty($id) && is_numeric($id)) {
                                 <div class="row-section product-info">
                                     <div class="row-section-label"><span>产品</span></div>
                                         <input type="hidden" name="items[<?= $index ?>][product_id]" class="product-id-input" value="<?= $item['product_id'] ?>">
+                                    <input type="text" class="product-search" placeholder="输入产品名称搜索..." style="width: 100%; padding: 5px; border: 1px solid #ddd; border-radius: 4px; display: none;">
+                                    <div class="productlist" style="width: 100%; max-height: 200px;"><ul></ul></div>
                                     <div class="selected-product-info" style="cursor: pointer;" title="点击重新选择产品">
                                             <?= htmlspecialcharsFix($item['ProductName'] ?? '') ?>
                                             <?php if (!empty($item['category_name'])): ?>
@@ -318,6 +325,20 @@ if (!empty($id) && is_numeric($id)) {
                                         </div>
                                     </div>
                                 
+                                <div class="row-section product-spec">
+                                    <div class="row-section-label"><span>规格</span></div>
+                                    <input type="hidden" name="items[<?= $index ?>][spec_id]" class="spec-id-input" value="<?= $item['specification_id'] ?? 0 ?>">
+                                    <!-- 规格选择框将在加载产品时填充 -->
+                                    <select class="spec-select" name="items[<?= $index ?>][spec_select]" style="display: none;">
+                                        <option value="">请选择规格</option>
+                                    </select>
+                                    <div class="spec-info" style="cursor: pointer;" title="点击修改规格">
+                                        <?php if (!empty($item['spec_name'])): ?>
+                                            <?= htmlspecialcharsFix($item['spec_name']) ?>: <?= htmlspecialcharsFix($item['spec_value'] ?? '') ?>
+                                        <?php endif; ?>
+                                    </div>
+                                </div>
+                                
                                 <div class="row-section product-quantity">
                                     <div class="row-section-label"><span>数量</span></div>
                                     <input type="number" name="items[<?= $index ?>][quantity]" value="<?= $item['quantity'] ?>" min="1" class="quantity-input" onchange="calculateItemTotal(this)">
@@ -325,7 +346,8 @@ if (!empty($id) && is_numeric($id)) {
 
                                 <div class="row-section product-unit">
                                     <div class="row-section-label"><span>单位</span></div>
-                                    <input type="text" name="items[<?= $index ?>][unit]" value="<?= htmlspecialcharsFix($item['unit']) ?>" class="unit-input">
+                                    <span class="unit-label"><?= htmlspecialcharsFix($item['unit']) ?></span>
+                                    <input type="hidden" name="items[<?= $index ?>][unit]" value="<?= htmlspecialcharsFix($item['unit']) ?>" class="unit-input">
                                 </div>
                                 
                                 <div class="row-section product-price">
@@ -335,18 +357,14 @@ if (!empty($id) && is_numeric($id)) {
                     
                                 <div class="row-section product-total">
                                     <div class="row-section-label"><span>总价</span></div>
-                                    <span class="total-price-display"><?= number_format($item['total_price'], 2) ?></span>
+                                    <span class="total-price-display" style="display: inline-block; background-color: #f0f0f0; border: 1px solid #ddd; padding: 2px 8px; min-width: 60px; text-align: right;"><?= number_format($item['total_price'], 2) ?></span>
                                     <input type="hidden" name="items[<?= $index ?>][total_price]" value="<?= $item['total_price'] ?>" class="total-price-input">
                                 </div>
                                 
-                                <div class="row-section product-notes" style="flex: 2; min-width: 200px;">
-                                    <div class="row-section-label"><span>备注</span></div>
-                                    <input type="text" name="items[<?= $index ?>][notes]" value="<?= htmlspecialcharsFix($item['notes']) ?>" style="width: 100%;">
-                                    
-                                    <!-- 保留隐藏的折扣字段以便后端兼容 -->
-                                    <input type="hidden" name="items[<?= $index ?>][discount_amount]" value="0" class="discount-amount-input">
-                                    <input type="hidden" name="items[<?= $index ?>][discount_percent]" value="0" class="discount-percent-input">
-                                </div>
+                                <!-- 保留隐藏的折扣字段以便后端兼容 -->
+                                <input type="hidden" name="items[<?= $index ?>][discount_amount]" value="0" class="discount-amount-input">
+                                <input type="hidden" name="items[<?= $index ?>][discount_percent]" value="0" class="discount-percent-input">
+                                <input type="hidden" name="items[<?= $index ?>][notes]" value="<?= htmlspecialcharsFix($item['notes'] ?? '') ?>">
                             </div>
                         <?php endforeach; ?>
                         <!-- 产品行将通过搜索添加 -->
@@ -394,6 +412,19 @@ if (!empty($id) && is_numeric($id)) {
             // 初始化无产品消息
             updateNoProductsMessage();
             
+            // 初始化现有产品的规格选择
+            $('.product-row').each(function() {
+                var row = $(this);
+                var productId = row.find('.product-id-input').val();
+                var specId = row.find('.spec-id-input').val();
+                console.log("初始化行 - 行索引:", row.data('index'), "产品ID:", productId, "规格ID:", specId);
+                
+                if (productId) {
+                    // 加载产品规格
+                    getProductSpecifications(productId, row);
+                }
+            });
+            
             // 添加产品行按钮点击事件
             $('#add-product-btn').on('click', function() {
                 addEmptyProductRow();
@@ -476,16 +507,30 @@ if (!empty($id) && is_numeric($id)) {
                 $('.selected-customer-info').text(customerName);
                 $('.customerlist').hide();
             });
+
+            // 产品搜索框聚焦时显示搜索提示
+            $(document).on('focus', '.product-search', function() {
+                // 隐藏所有已打开的产品搜索列表
+                $('.productlist').hide();
+                
+                // 当前搜索框的值
+                var searchTerm = $(this).val().trim();
+                if (searchTerm.length >= 2) {
+                    // 找到当前行的产品列表并显示
+                    $(this).siblings('.productlist').show();
+                }
+            });
             
-            // 单一产品搜索功能 - 使用防抖动以减少请求数量
-            var productSearchTimeout = null;
-            $(document).on('keyup', '#product-search-single', function() {
+            // 产品搜索功能 - 行内搜索
+            var productSearchTimeouts = {};
+            $(document).on('keyup', '.product-search', function() {
                 var $this = $(this);
+                var rowIndex = $this.closest('.product-row').data('index');
                 var searchTerm = $this.val().trim();
-                var productList = $('#product-list-single');
+                var productList = $this.siblings('.productlist');
                 
                 // 清除之前的超时
-                clearTimeout(productSearchTimeout);
+                clearTimeout(productSearchTimeouts[rowIndex]);
                 
                 // 隐藏之前的结果
                 productList.hide();
@@ -496,7 +541,7 @@ if (!empty($id) && is_numeric($id)) {
                 }
                 
                 // 设置一个300毫秒的超时,以减少请求数量
-                productSearchTimeout = setTimeout(function() {
+                productSearchTimeouts[rowIndex] = setTimeout(function() {
                     $.ajax({
                         url: 'get_product_info.php',
                         type: 'GET',
@@ -523,51 +568,151 @@ if (!empty($id) && is_numeric($id)) {
                 }, 300);
             });
             
-            // 点击选择产品 - 从单一搜索框
-            $(document).on('click', '#product-list-single li', function() {
+            // 点击选择产品 - 行内搜索结果
+            $(document).on('click', '.productlist li', function() {
                 var $this = $(this);
                 var productId = $this.data('id');
                 var productName = $this.text(); // 这会包含分类名,需要清理
                 var categoryTag = $this.find('.category-tag').text();
+                var row = $this.closest('.product-row');
                 
                 // 清理产品名称,移除分类信息
                 if (categoryTag) {
                     productName = productName.replace(categoryTag, '').trim();
                 }
                 
-                // 检查产品是否已经添加
-                var isDuplicate = false;
-                $('.product-id-input').each(function() {
-                    if ($(this).val() == productId) {
-                        isDuplicate = true;
-                        return false; // 跳出循环
-                    }
-                });
+                // 设置产品ID和名称
+                row.find('.product-id-input').val(productId);
+                row.find('.product-search').hide();
                 
-                if (isDuplicate) {
-                    alert('该产品已添加,不能重复添加');
-                    $('#product-search-single').val('');
-                    $('#product-list-single').hide();
-                    return;
+                // 显示包含分类的完整产品信息
+                var displayName = productName;
+                if (categoryTag) {
+                    displayName += ' <span class="category-tag">' + categoryTag + '</span>';
                 }
+                row.find('.selected-product-info').html(displayName).show();
                 
-                // 添加产品行
-                addProductRowWithProduct(productId, productName, categoryTag);
+                // 隐藏产品搜索结果
+                row.find('.productlist').hide();
                 
-                // 清空搜索框并隐藏结果
-                $('#product-search-single').val('');
-                $('#product-list-single').hide();
+                // 获取产品规格信息
+                getProductSpecifications(productId, row);
+            });
+            
+            // 规格选择改变事件
+            $(document).on('change', '.spec-select', function() {
+                var $this = $(this);
+                var row = $this.closest('.product-row');
+                var specId = $this.val();
+                var specData = $this.find('option:selected').data();
+                
+                if (specId) {
+                    // 检查是否已存在相同的产品规格组合
+                    var isDuplicate = false;
+                    $('.spec-select').not($this).each(function() {
+                        if ($(this).val() == specId) {
+                            isDuplicate = true;
+                            return false; // 跳出循环
+                        }
+                    });
+                    
+                    if (isDuplicate) {
+                        alert('该产品规格已添加,不能重复添加');
+                        $this.val(''); // 重置选择
+                        return;
+                    }
+                    
+                    // 设置规格ID到隐藏字段
+                    row.find('.spec-id-input').val(specId);
+                    
+                    // 获取选中项的文本内容作为显示信息
+                    var displayText = $this.find('option:selected').text();
+                    row.find('.spec-info').html(displayText).show();
+                    
+                    // 隐藏下拉框
+                    $this.hide();
+                    
+                    // 存储规格价格作为最低价格限制
+                    var minPrice = specData.price || 0;
+                    var priceInput = row.find('.price-input');
+                    priceInput.attr('data-min-price', minPrice);
+                    if (minPrice > 0) {
+                        priceInput.attr('placeholder', '输入单价');
+                    } else {
+                        priceInput.attr('placeholder', '输入单价');
+                    }
+                    
+                    // 设置最小订购数量
+                    var minQty = specData.minQty || 1;
+                    var qtyInput = row.find('.quantity-input');
+                    if (parseInt(qtyInput.val()) < minQty) {
+                        qtyInput.val(minQty);
+                    }
+                    qtyInput.attr('min', minQty);
+                    
+                    // 重新计算总价
+                    calculateItemTotal(row.find('.price-input')[0]);
+                } else {
+                    // 清除规格相关信息
+                    row.find('.spec-id-input').val('');
+                    row.find('.price-input').attr('data-min-price', '0').attr('placeholder', '输入单价');
+                    row.find('.spec-info').html('').hide();
+                    calculateItemTotal(row.find('.price-input')[0]);
+                }
             });
             
             // 点击其他地方隐藏下拉列表
             $(document).on('click', function(e) {
-                if (!$(e.target).closest('#product-search-single').length) {
-                    $('#product-list-single').hide();
+                if (!$(e.target).closest('.product-search').length && !$(e.target).closest('.productlist').length) {
+                    $('.productlist').hide();
                 }
                 if (!$(e.target).closest('.customerinput').length) {
                     $('.customerlist').hide();
                 }
             });
+            
+            // 点击已选产品名显示的标签时,切换回搜索模式
+            $(document).on('click dblclick', '.selected-product-info', function() {
+                var row = $(this).closest('.product-row');
+                var productId = row.find('.product-id-input').val();
+                
+                // 只有当已经选择了产品时才允许重新选择
+                if (productId) {
+                    if (confirm('确定要重新选择产品吗?这将清除当前选择的产品及其规格信息。')) {
+                        // 清空产品ID和选择的规格
+                        row.find('.product-id-input').val('');
+                        row.find('.spec-id-input').val('');
+                        
+                        // 隐藏产品信息,显示搜索框
+                        $(this).hide();
+                        row.find('.product-search').val('').show();
+                        
+                        // 隐藏并清空规格选择
+                        row.find('.spec-select').hide().empty();
+                        row.find('.spec-info').html('');
+                        
+                        // 清除单位信息
+                        row.find('.unit-input').val('');
+                        row.find('.unit-label').text('');
+                        
+                        // 清除价格信息并重新计算总额
+                        row.find('.price-input').val('');
+                        calculateItemTotal(row.find('.price-input')[0]);
+                    }
+                }
+            });
+            
+            // 点击规格信息时显示规格选择下拉框
+            $(document).on('click', '.spec-info', function() {
+                var row = $(this).closest('.product-row');
+                var specSelect = row.find('.spec-select');
+                
+                if (specSelect.find('option').length > 1) {
+                    // 隐藏规格信息,显示规格选择下拉框
+                    $(this).hide();
+                    specSelect.show().focus();
+                }
+            });
         });
 
         function addEmptyProductRow() {
@@ -583,6 +728,15 @@ if (!empty($id) && is_numeric($id)) {
                     <div class="selected-product-info" style="cursor: pointer; display: none;" title="点击重新选择产品"></div>
                 </div>
                 
+                <div class="row-section product-spec">
+                    <div class="row-section-label"><span>规格</span></div>
+                    <input type="hidden" name="items[${productIndex}][spec_id]" class="spec-id-input" value="">
+                    <select class="spec-select" name="items[${productIndex}][spec_select]" style="display: none;">
+                        <option value="">请选择规格</option>
+                    </select>
+                    <div class="spec-info" style="cursor: pointer;" title="点击修改规格"></div>
+                </div>
+                
                 <div class="row-section product-quantity">
                     <div class="row-section-label"><span>数量</span></div>
                     <input type="number" name="items[${productIndex}][quantity]" value="1" min="1" class="quantity-input" onchange="calculateItemTotal(this)">
@@ -590,7 +744,8 @@ if (!empty($id) && is_numeric($id)) {
                 
                 <div class="row-section product-unit">
                     <div class="row-section-label"><span>单位</span></div>
-                    <input type="text" name="items[${productIndex}][unit]" value="" class="unit-input">
+                    <span class="unit-label" style="display: inline-block; padding: 2px 5px; min-width: 30px;"></span>
+                    <input type="hidden" name="items[${productIndex}][unit]" class="unit-input" value="">
                 </div>
                 
                 <div class="row-section product-price">
@@ -600,18 +755,14 @@ if (!empty($id) && is_numeric($id)) {
                 
                 <div class="row-section product-total">
                     <div class="row-section-label"><span>总价</span></div>
-                    <span class="total-price-display">0.00</span>
+                    <span class="total-price-display" style="display: inline-block; background-color: #f0f0f0; border: 1px solid #ddd; padding: 2px 8px; min-width: 60px; text-align: right;">0.00</span>
                     <input type="hidden" name="items[${productIndex}][total_price]" value="0.00" class="total-price-input">
                 </div>
                 
-                <div class="row-section product-notes" style="flex: 2; min-width: 200px;">
-                    <div class="row-section-label"><span>备注</span></div>
-                    <input type="text" name="items[${productIndex}][notes]" value="" style="width: 100%;">
-                    
-                    <!-- 保留隐藏的折扣字段以便后端兼容 -->
-                    <input type="hidden" name="items[${productIndex}][discount_amount]" value="0" class="discount-amount-input">
-                    <input type="hidden" name="items[${productIndex}][discount_percent]" value="0" class="discount-percent-input">
-                </div>
+                <!-- 保留隐藏的字段以便后端兼容 -->
+                <input type="hidden" name="items[${productIndex}][discount_amount]" value="0" class="discount-amount-input">
+                <input type="hidden" name="items[${productIndex}][discount_percent]" value="0" class="discount-percent-input">
+                <input type="hidden" name="items[${productIndex}][notes]" value="">
             </div>
             `;
 
@@ -633,10 +784,11 @@ if (!empty($id) && is_numeric($id)) {
             if (categoryTag) {
                 displayName += ' <span class="category-tag">' + categoryTag + '</span>';
             }
-            row.find('.selected-product-info').html(displayName);
+            row.find('.selected-product-info').html(displayName).show();
+            row.find('.product-search').hide();
             
-            // 获取产品信息
-            getProductInfo(productId, row);
+            // 获取产品规格信息
+            getProductSpecifications(productId, row);
             
             // 更新无产品消息显示
             updateNoProductsMessage();
@@ -656,6 +808,128 @@ if (!empty($id) && is_numeric($id)) {
             productIndex = $('.product-row').length;
         }
 
+        function getProductSpecifications(productId, row) {
+            if (!productId) return;
+            
+            // 获取当前选中的规格ID(如果有的话)
+            var currentSpecId = row.find('.spec-id-input').val();
+            console.log("加载规格 - 产品ID:", productId, "当前规格ID:", currentSpecId);
+            
+            $.ajax({
+                url: 'get_product_info.php',
+                type: 'GET',
+                data: {product_id: productId},
+                dataType: 'json',
+                success: function(data) {
+                    if (data && data.product && data.specifications) {
+                        console.log("获取到规格数据:", data.specifications);
+                        // 设置单位信息
+                        if (data.product.unit) {
+                            row.find('.unit-input').val(data.product.unit);
+                            row.find('.unit-label').text(data.product.unit);
+                        }
+                        
+                        // 处理规格信息
+                        var specifications = data.specifications;
+                        console.log("获取到的规格列表详情:", JSON.stringify(specifications)); // 打印完整的规格对象
+                        if (specifications.length === 0) {
+                            // 如果是编辑现有产品,不显示警告
+                            if (!currentSpecId) {
+                                alert('此产品没有规格信息,请添加规格后再选择');
+                                // 重置产品选择
+                                row.find('.product-id-input').val('');
+                                row.find('.selected-product-info').hide();
+                                row.find('.product-search').val('').show();
+                            }
+                            return;
+                        }
+                        
+                        // 填充规格选择下拉框
+                        var specSelect = row.find('.spec-select');
+                        specSelect.empty();
+                        specSelect.append('<option value="">请选择规格</option>');
+                        
+                        var foundSelectedSpec = false;
+                        
+                        $.each(specifications, function(i, spec) {
+                            var displayText = spec.spec_name + ': ' + spec.spec_value;
+                            if (spec.price) {
+                                displayText += ' (¥' + spec.price + ')';
+                            }
+                            
+                            var option = $('<option></option>')
+                                .attr('value', spec.id)
+                                .text(displayText)
+                                .data('price', spec.price)
+                                .data('minQty', spec.min_order_quantity)
+                                .data('code', spec.spec_code);
+                            
+                            // 如果是当前选中的规格,设置selected属性
+                            if (currentSpecId && parseInt(spec.id) === parseInt(currentSpecId)) {
+                                console.log("找到匹配的规格 - 规格ID:", spec.id, "当前规格ID:", currentSpecId, 
+                                           "规格名称:", spec.spec_name, "规格值:", spec.spec_value);
+                                option.prop('selected', true);
+                                foundSelectedSpec = true;
+                                
+                                // 更新规格信息显示
+                                row.find('.spec-info').html(displayText);
+                                
+                                // 设置参考价格
+                                var priceInput = row.find('.price-input');
+                                priceInput.attr('data-min-price', spec.price || 0);
+                            } else {
+                                console.log("规格不匹配 - 规格ID:", spec.id, "当前规格ID:", currentSpecId, 
+                                           "类型:", typeof spec.id, typeof currentSpecId);
+                            }
+                            
+                            specSelect.append(option);
+                        });
+                        
+                        // 显示规格选择下拉框并隐藏spec-info
+                        if (!currentSpecId || !foundSelectedSpec) {
+                            // 如果没有选中规格,显示下拉框
+                            specSelect.show();
+                            row.find('.spec-info').hide();
+                        } else {
+                            // 如果已选中规格,显示规格信息
+                            specSelect.hide();
+                            row.find('.spec-info').show();
+                        }
+                        
+                        // 如果在规格列表中找不到已选择的规格
+                        if (currentSpecId && !foundSelectedSpec) {
+                            console.log("在规格列表中找不到已选择的规格ID:", currentSpecId);
+                            // 不清除规格ID,保留数据库中的值
+                            // row.find('.spec-id-input').val('');
+                            
+                            // 隐藏规格选择下拉框,保留现有规格信息
+                            specSelect.hide();
+                            row.find('.spec-info').show();
+                        }
+                    } else {
+                        // 如果是编辑现有产品,不显示警告
+                        if (!currentSpecId) {
+                            alert('获取产品规格失败');
+                            // 重置产品选择
+                            row.find('.product-id-input').val('');
+                            row.find('.selected-product-info').hide();
+                            row.find('.product-search').val('').show();
+                        }
+                    }
+                },
+                error: function() {
+                    // 如果是编辑现有产品,不显示警告
+                    if (!currentSpecId) {
+                        alert('获取产品规格失败,请重试');
+                        // 重置产品选择
+                        row.find('.product-id-input').val('');
+                        row.find('.selected-product-info').hide();
+                        row.find('.product-search').val('').show();
+                    }
+                }
+            });
+        }
+
         function getProductInfo(productId, row) {
             if (!productId) return;
             
@@ -667,6 +941,7 @@ if (!empty($id) && is_numeric($id)) {
                 success: function(data) {
                     if (data) {
                         row.find('.unit-input').val(data.unit);
+                        row.find('.unit-label').text(data.unit);
                         // 只有当数据库中有价格信息时才设置价格
                         if (data.price && data.price !== '0' && data.price !== '0.00') {
                             //默认不设置单价
@@ -712,23 +987,59 @@ if (!empty($id) && is_numeric($id)) {
             var customerId = $('#customer_id').val();
             var customerName = $('.customer-search').val();
             var hasProducts = false;
+            var allSpecsSelected = true;
             var allPricesValid = true;
-            var firstEmptyPriceField = null;
+            var allPricesHighEnough = true;
+            var firstInvalidField = null;
 
-            $('.product-id-input').each(function() {
-                if ($(this).val()) {
-                    hasProducts = true;
-                    
-                    // 检查该产品的单价是否已填写
-                    var row = $(this).closest('.product-row');
-                    var priceInput = row.find('.price-input');
-                    var priceValue = priceInput.val().trim();
-                    
-                    if (priceValue === '' || isNaN(parseFloat(priceValue))) {
-                        allPricesValid = false;
-                        if (!firstEmptyPriceField) {
-                            firstEmptyPriceField = priceInput;
-                        }
+            // 检查是否有产品行
+            if ($('.product-row').length === 0) {
+                alert('请至少添加一个产品');
+                $('#add-product-btn').focus();
+                return false;
+            }
+
+            $('.product-row').each(function() {
+                var productId = $(this).find('.product-id-input').val();
+                var specId = $(this).find('.spec-id-input').val();
+                var priceInput = $(this).find('.price-input');
+                var priceValue = priceInput.val().trim();
+                var price = parseFloat(priceValue) || 0;
+                var minPrice = parseFloat(priceInput.attr('data-min-price')) || 0;
+                var specSelect = $(this).find('.spec-select');
+                var productSearch = $(this).find('.product-search');
+                
+                // 检查产品是否已选择
+                if (!productId) {
+                    if (!firstInvalidField) {
+                        firstInvalidField = productSearch;
+                    }
+                    return true; // continue
+                }
+                
+                hasProducts = true;
+                
+                // 检查规格是否已选择
+                if (!specId && specSelect.is(':visible')) {
+                    allSpecsSelected = false;
+                    if (!firstInvalidField) {
+                        firstInvalidField = specSelect;
+                    }
+                }
+                
+                // 检查单价是否有效
+                if (priceValue === '' || isNaN(parseFloat(priceValue))) {
+                    allPricesValid = false;
+                    if (!firstInvalidField) {
+                        firstInvalidField = priceInput;
+                    }
+                }
+                
+                // 检查单价是否大于等于规格价格
+                if (minPrice > 0 && price < minPrice) {
+                    allPricesHighEnough = false;
+                    if (!firstInvalidField) {
+                        firstInvalidField = priceInput;
                     }
                 }
             });
@@ -739,7 +1050,7 @@ if (!empty($id) && is_numeric($id)) {
                 return false;
             }
 
-            if (!customerId || customerId <= 0) {
+            if (!customerId || customerId == '0') {
                 alert('请选择客户');
                 $('.customer-search').focus();
                 return false;
@@ -752,15 +1063,35 @@ if (!empty($id) && is_numeric($id)) {
             }
             
             if (!hasProducts) {
-                alert('请至少添加一个产品');
-                $('#product-search-single').focus();
+                alert('请至少添加一个有效的产品');
+                if (firstInvalidField) {
+                    firstInvalidField.focus();
+                } else {
+                    $('#add-product-btn').focus();
+                }
+                return false;
+            }
+            
+            if (!allSpecsSelected) {
+                alert('请为所有产品选择规格');
+                if (firstInvalidField) {
+                    firstInvalidField.focus();
+                }
                 return false;
             }
             
             if (!allPricesValid) {
                 alert('请为所有产品输入有效的单价');
-                if (firstEmptyPriceField) {
-                    firstEmptyPriceField.focus();
+                if (firstInvalidField) {
+                    firstInvalidField.focus();
+                }
+                return false;
+            }
+            
+            if (!allPricesHighEnough) {
+                alert('单价不能低于规格设定的参考价格');
+                if (firstInvalidField) {
+                    firstInvalidField.focus();
                 }
                 return false;
             }