|
@@ -50,26 +50,132 @@ if ($customerId > 0) {
|
|
|
margin-left: 0;
|
|
|
}
|
|
|
.product-row {
|
|
|
- border: 1px solid
|
|
|
- padding: 10px;
|
|
|
- margin-bottom: 10px;
|
|
|
- background-color:
|
|
|
position: relative;
|
|
|
+ padding: 12px 15px;
|
|
|
+ padding-right: 40px;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ border-radius: 4px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ gap: 8px;
|
|
|
+ background-color:
|
|
|
+ box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
|
|
}
|
|
|
.delete-product {
|
|
|
position: absolute;
|
|
|
right: 10px;
|
|
|
- top: 10px;
|
|
|
- color: red;
|
|
|
+ top: 50%;
|
|
|
+ transform: translateY(-50%);
|
|
|
+ color:
|
|
|
+ font-weight: bold;
|
|
|
+ font-size: 18px;
|
|
|
cursor: pointer;
|
|
|
+ width: 24px;
|
|
|
+ height: 24px;
|
|
|
+ line-height: 24px;
|
|
|
+ text-align: center;
|
|
|
+ border-radius: 50%;
|
|
|
+ z-index: 5;
|
|
|
+ }
|
|
|
+ .delete-product:hover {
|
|
|
+ background-color:
|
|
|
+ color: white;
|
|
|
+ }
|
|
|
+ .product-info {
|
|
|
+ flex: 2;
|
|
|
+ min-width: 200px;
|
|
|
+ }
|
|
|
+ .product-spec {
|
|
|
+ flex: 2;
|
|
|
+ min-width: 200px;
|
|
|
+ }
|
|
|
+ .product-quantity {
|
|
|
+ flex: 1;
|
|
|
+ min-width: 80px;
|
|
|
+ }
|
|
|
+ .product-unit {
|
|
|
+ flex: 0.5;
|
|
|
+ min-width: 60px;
|
|
|
+ }
|
|
|
+ .product-price {
|
|
|
+ flex: 1;
|
|
|
+ min-width: 100px;
|
|
|
+ }
|
|
|
+ .product-total {
|
|
|
+ flex: 1;
|
|
|
+ min-width: 100px;
|
|
|
+ font-weight: bold;
|
|
|
+ }
|
|
|
+ .product-row input[type="number"] {
|
|
|
+ width: 80px;
|
|
|
+ padding: 5px;
|
|
|
+ border: 1px solid
|
|
|
+ border-radius: 4px;
|
|
|
+ }
|
|
|
+ .product-row select {
|
|
|
+ width: 100%;
|
|
|
+ padding: 5px;
|
|
|
+ }
|
|
|
+ .selected-product-info {
|
|
|
+ font-weight: bold;
|
|
|
+ margin-bottom: 3px;
|
|
|
+ }
|
|
|
+ .row-section {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ }
|
|
|
+ .row-section-label {
|
|
|
+ font-size: 12px;
|
|
|
+ color:
|
|
|
+ margin-bottom: 3px;
|
|
|
+ }
|
|
|
+ .row-section-label span {
|
|
|
+ display: none;
|
|
|
+ }
|
|
|
+ .spec-info {
|
|
|
+ margin-top: 2px;
|
|
|
+ font-size: 12px;
|
|
|
+ color:
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @media (max-width: 768px) {
|
|
|
+ .product-row {
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: flex-start;
|
|
|
+ }
|
|
|
+ .product-info, .product-spec, .product-quantity,
|
|
|
+ .product-unit, .product-price, .product-total {
|
|
|
+ width: 100%;
|
|
|
+ min-width: 100%;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ }
|
|
|
+ .row-section-label span {
|
|
|
+ display: inline;
|
|
|
+ }
|
|
|
+ .product-list-header {
|
|
|
+ display: none !important;
|
|
|
+ }
|
|
|
}
|
|
|
.add-product-btn {
|
|
|
background-color:
|
|
|
color: white;
|
|
|
- padding: 8px 12px;
|
|
|
+ padding: 10px 15px;
|
|
|
border: none;
|
|
|
+ border-radius: 4px;
|
|
|
cursor: pointer;
|
|
|
margin-bottom: 15px;
|
|
|
+ font-size: 14px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ gap: 8px;
|
|
|
+ transition: background-color 0.2s;
|
|
|
+ box-shadow: 0 2px 5px rgba(0,0,0,0.1);
|
|
|
+ }
|
|
|
+ .add-product-btn:hover {
|
|
|
+ background-color:
|
|
|
}
|
|
|
.total-section {
|
|
|
margin-top: 20px;
|
|
@@ -89,7 +195,10 @@ if ($customerId > 0) {
|
|
|
overflow-y: auto;
|
|
|
width: 100%;
|
|
|
z-index: 1000;
|
|
|
- box-shadow: 0 2px 5px rgba(0,0,0,0.2);
|
|
|
+ box-shadow: 0 3px 8px rgba(0,0,0,0.25);
|
|
|
+ border-radius: 0 0 4px 4px;
|
|
|
+ top: 100%;
|
|
|
+ left: 0;
|
|
|
}
|
|
|
.productlist ul {
|
|
|
list-style: none;
|
|
@@ -97,12 +206,16 @@ if ($customerId > 0) {
|
|
|
margin: 0;
|
|
|
}
|
|
|
.productlist li {
|
|
|
- padding: 8px 10px;
|
|
|
+ padding: 10px 12px;
|
|
|
cursor: pointer;
|
|
|
border-bottom: 1px solid
|
|
|
+ transition: background-color 0.2s;
|
|
|
}
|
|
|
.productlist li:hover {
|
|
|
- background-color:
|
|
|
+ background-color:
|
|
|
+ }
|
|
|
+ .productlist li:last-child {
|
|
|
+ border-bottom: none;
|
|
|
}
|
|
|
.productinput {
|
|
|
position: relative;
|
|
@@ -113,6 +226,22 @@ if ($customerId > 0) {
|
|
|
font-style: italic;
|
|
|
margin-left: 5px;
|
|
|
}
|
|
|
+
|
|
|
+ .spec-select {
|
|
|
+ width: 100%;
|
|
|
+ padding: 6px;
|
|
|
+ margin-top: 5px;
|
|
|
+ border: 1px solid
|
|
|
+ border-radius: 4px;
|
|
|
+ }
|
|
|
+ .spec-select:disabled {
|
|
|
+ background-color:
|
|
|
+ }
|
|
|
+ .spec-price {
|
|
|
+ font-weight: bold;
|
|
|
+ color:
|
|
|
+ }
|
|
|
+
|
|
|
</style>
|
|
|
</head>
|
|
|
<body>
|
|
@@ -158,28 +287,31 @@ if ($customerId > 0) {
|
|
|
<tr>
|
|
|
<th width="8%" valign="top">产品列表</th>
|
|
|
<td>
|
|
|
+ <button type="button" id="add-product-btn" class="add-product-btn">添加产品</button>
|
|
|
+
|
|
|
+ <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>
|
|
|
+
|
|
|
<div id="product-container">
|
|
|
- <!-- 产品行将通过搜索添加 -->
|
|
|
- <div id="no-products-message" style="padding: 20px; text-align: center; color: #777; background-color: #f9f9f9; border: 1px dashed #ddd; display: block;">
|
|
|
- 请使用下方的产品搜索框添加产品
|
|
|
+ <!-- 产品行将通过添加按钮添加 -->
|
|
|
+ <div id="no-products-message" style="padding: 15px; text-align: center; color: #777; background-color: #f5f5f5; border: 1px dashed #ddd; border-radius: 4px; margin-bottom: 15px; display: block;">
|
|
|
+ <i class="fa fa-info-circle"></i> 请点击"添加产品"按钮添加产品
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div class="total-section">
|
|
|
- <div>
|
|
|
- <label>订单总额:</label>
|
|
|
- <span id="total-amount">0.00</span>
|
|
|
+ <div class="total-section" style="margin-top: 20px; padding: 15px; background-color: #f5f5f5; border-radius: 4px; box-shadow: 0 1px 3px rgba(0,0,0,0.1);">
|
|
|
+ <div style="display: flex; justify-content: flex-end; align-items: center;">
|
|
|
+ <label style="font-size: 16px; margin-right: 10px;">订单总额:</label>
|
|
|
+ <span id="total-amount" style="font-size: 18px; font-weight: bold; color: #e74c3c;">0.00</span>
|
|
|
<input type="hidden" name="total_amount" id="total-amount-input" value="0.00">
|
|
|
<input type="hidden" name="subtotal" id="subtotal-input" value="0.00">
|
|
|
</div>
|
|
|
</div>
|
|
|
-
|
|
|
- <div style="margin-top: 15px; border-top: 1px dashed #ccc; padding-top: 15px;">
|
|
|
- <div class="productinput" style="position: relative; width: 60%;">
|
|
|
- <label>产品搜索:</label>
|
|
|
- <input type="text" id="product-search-single" class="fastsearch" placeholder="输入产品名称搜索并添加..." style="width: 100%;">
|
|
|
- <div id="product-list-single" class="productlist" style="width: 100%;"><ul></ul></div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
</td>
|
|
|
</tr>
|
|
|
<tr>
|
|
@@ -211,6 +343,16 @@ if ($customerId > 0) {
|
|
|
$('.product-row').first().remove();
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ addEmptyProductRow();
|
|
|
+ updateNoProductsMessage();
|
|
|
+
|
|
|
+
|
|
|
+ $('#add-product-btn').on('click', function() {
|
|
|
+ addEmptyProductRow();
|
|
|
+ updateNoProductsMessage();
|
|
|
+ });
|
|
|
+
|
|
|
|
|
|
$(document).on('click', '.delete-product', function() {
|
|
|
if ($('.product-row').length > 1) {
|
|
@@ -291,15 +433,29 @@ if ($customerId > 0) {
|
|
|
loadCustomerContacts(customerId);
|
|
|
});
|
|
|
|
|
|
-
|
|
|
- var productSearchTimeout = null;
|
|
|
- $(document).on('keyup', '#product-search-single', function() {
|
|
|
+
|
|
|
+ $(document).on('focus', '.product-search', function() {
|
|
|
+
|
|
|
+ $('.productlist').hide();
|
|
|
+
|
|
|
+
|
|
|
+ var searchTerm = $(this).val().trim();
|
|
|
+ if (searchTerm.length >= 2) {
|
|
|
+
|
|
|
+ $(this).siblings('.productlist').show();
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+
|
|
|
+ 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();
|
|
@@ -310,7 +466,7 @@ if ($customerId > 0) {
|
|
|
}
|
|
|
|
|
|
|
|
|
- productSearchTimeout = setTimeout(function() {
|
|
|
+ productSearchTimeouts[rowIndex] = setTimeout(function() {
|
|
|
$.ajax({
|
|
|
url: 'get_product_info.php',
|
|
|
type: 'GET',
|
|
@@ -337,78 +493,197 @@ if ($customerId > 0) {
|
|
|
}, 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;
|
|
|
- }
|
|
|
- });
|
|
|
+
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ row.find('.spec-id-input').val(specId);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ 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('');
|
|
|
+ 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', '.selected-product-info', function() {
|
|
|
+ var row = $(this).closest('.product-row');
|
|
|
+ var productId = row.find('.product-id-input').val();
|
|
|
+
|
|
|
+
|
|
|
+ if (productId) {
|
|
|
+ if (confirm('确定要重新选择产品吗?这将清除当前选择的产品及其规格信息。')) {
|
|
|
+
|
|
|
+ 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]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
});
|
|
|
|
|
|
function addEmptyProductRow() {
|
|
|
var html = `
|
|
|
<div class="product-row" data-index="${productIndex}">
|
|
|
<span class="delete-product">×</span>
|
|
|
- <div>
|
|
|
- <label>产品:</label>
|
|
|
- <div style="display: inline-block; width: 60%;">
|
|
|
- <input type="hidden" name="items[${productIndex}][product_id]" class="product-id-input" value="">
|
|
|
- <div class="selected-product-info" style="margin-top: 5px; font-weight: bold;"></div>
|
|
|
- </div>
|
|
|
+
|
|
|
+ <div class="row-section product-info">
|
|
|
+ <div class="row-section-label"><span>产品</span></div>
|
|
|
+ <input type="hidden" name="items[${productIndex}][product_id]" class="product-id-input" value="">
|
|
|
+ <input type="text" class="product-search" placeholder="输入产品名称搜索..." style="width: 100%; padding: 5px; border: 1px solid #ddd; border-radius: 4px;">
|
|
|
+ <div class="productlist" style="width: 100%; max-height: 200px;"><ul></ul></div>
|
|
|
+ <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"></div>
|
|
|
</div>
|
|
|
- <div style="margin-top: 5px;">
|
|
|
- <label>数量:</label>
|
|
|
+
|
|
|
+ <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)">
|
|
|
-
|
|
|
- <label style="margin-left: 10px;">单位:</label>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="row-section product-unit">
|
|
|
+ <div class="row-section-label"><span>单位</span></div>
|
|
|
<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="">
|
|
|
-
|
|
|
- <label style="margin-left: 10px;">单价:</label>
|
|
|
- <input type="number" step="0.01" name="items[${productIndex}][unit_price]" value="" class="price-input" placeholder="请输入单价" onchange="calculateItemTotal(this)">
|
|
|
-
|
|
|
- <label style="margin-left: 10px;">总价:</label>
|
|
|
- <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; font-weight: bold;">0.00</span>
|
|
|
-
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="row-section product-price">
|
|
|
+ <div class="row-section-label"><span>单价</span></div>
|
|
|
+ <input type="number" step="0.01" name="items[${productIndex}][unit_price]" value="" class="price-input" placeholder="输入单价" onchange="calculateItemTotal(this)">
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="row-section product-total">
|
|
|
+ <div class="row-section-label"><span>总价</span></div>
|
|
|
+ <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>
|
|
@@ -419,26 +694,72 @@ if ($customerId > 0) {
|
|
|
return productIndex - 1;
|
|
|
}
|
|
|
|
|
|
- function addProductRowWithProduct(productId, productName, categoryTag) {
|
|
|
-
|
|
|
- var rowIndex = addEmptyProductRow();
|
|
|
- var row = $('.product-row[data-index="' + rowIndex + '"]');
|
|
|
-
|
|
|
-
|
|
|
- row.find('.product-id-input').val(productId);
|
|
|
-
|
|
|
-
|
|
|
- var displayName = productName;
|
|
|
- if (categoryTag) {
|
|
|
- displayName += ' <span class="category-tag">' + categoryTag + '</span>';
|
|
|
- }
|
|
|
- row.find('.selected-product-info').html(displayName);
|
|
|
-
|
|
|
-
|
|
|
- getProductInfo(productId, row);
|
|
|
+ function getProductSpecifications(productId, row) {
|
|
|
+ if (!productId) return;
|
|
|
|
|
|
-
|
|
|
- updateNoProductsMessage();
|
|
|
+ $.ajax({
|
|
|
+ url: 'get_product_info.php',
|
|
|
+ type: 'GET',
|
|
|
+ data: {product_id: productId},
|
|
|
+ dataType: 'json',
|
|
|
+ success: function(data) {
|
|
|
+ if (data && data.product && 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;
|
|
|
+ if (specifications.length === 0) {
|
|
|
+ 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>');
|
|
|
+
|
|
|
+ $.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);
|
|
|
+
|
|
|
+ specSelect.append(option);
|
|
|
+ });
|
|
|
+
|
|
|
+
|
|
|
+ specSelect.show();
|
|
|
+ } else {
|
|
|
+ alert('获取产品规格失败');
|
|
|
+
|
|
|
+ row.find('.product-id-input').val('');
|
|
|
+ row.find('.selected-product-info').hide();
|
|
|
+ row.find('.product-search').val('').show();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ error: function() {
|
|
|
+ alert('获取产品规格失败,请重试');
|
|
|
+
|
|
|
+ row.find('.product-id-input').val('');
|
|
|
+ row.find('.selected-product-info').hide();
|
|
|
+ row.find('.product-search').val('').show();
|
|
|
+ }
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
function reindexProductRows() {
|
|
@@ -455,38 +776,20 @@ if ($customerId > 0) {
|
|
|
productIndex = $('.product-row').length;
|
|
|
}
|
|
|
|
|
|
- function getProductInfo(productId, row) {
|
|
|
- if (!productId) return;
|
|
|
-
|
|
|
- $.ajax({
|
|
|
- url: 'get_product_info.php',
|
|
|
- type: 'GET',
|
|
|
- data: {id: productId},
|
|
|
- dataType: 'json',
|
|
|
- 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') {
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- }
|
|
|
- calculateItemTotal(row.find('.price-input')[0]);
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
function calculateItemTotal(element) {
|
|
|
var row = $(element).closest('.product-row');
|
|
|
var quantity = parseInt(row.find('.quantity-input').val()) || 0;
|
|
|
var priceInput = row.find('.price-input');
|
|
|
var priceValue = priceInput.val().trim();
|
|
|
var price = (priceValue === '') ? 0 : (parseFloat(priceValue) || 0);
|
|
|
+ var minPrice = parseFloat(priceInput.attr('data-min-price')) || 0;
|
|
|
+
|
|
|
+
|
|
|
+ if (price > 0 && minPrice > 0 && price < minPrice) {
|
|
|
+ priceInput.css('color', 'red');
|
|
|
+ } else {
|
|
|
+ priceInput.css('color', '');
|
|
|
+ }
|
|
|
|
|
|
var total = quantity * price;
|
|
|
if (total < 0) total = 0;
|
|
@@ -532,23 +835,59 @@ if ($customerId > 0) {
|
|
|
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;
|
|
|
+ }
|
|
|
+
|
|
|
+ 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;
|
|
|
}
|
|
|
}
|
|
|
});
|
|
@@ -573,19 +912,39 @@ if ($customerId > 0) {
|
|
|
}
|
|
|
|
|
|
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;
|
|
|
+ }
|
|
|
+
|
|
|
return true;
|
|
|
}
|
|
|
|