|
@@ -1056,56 +1056,84 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|
// 多规格验证
|
|
// 多规格验证
|
|
console.log('验证多规格');
|
|
console.log('验证多规格');
|
|
|
|
|
|
- if (typeof vm !== 'undefined' && vm && vm.tableData) {
|
|
|
|
- var hasValidSku = false;
|
|
|
|
- var validSkuCount = 0;
|
|
|
|
-
|
|
|
|
- console.log('检查SKU数据, tableData长度:', vm.tableData.length);
|
|
|
|
-
|
|
|
|
- for (var i = 0; i < vm.tableData.length; i++) {
|
|
|
|
- var sku = vm.tableData[i];
|
|
|
|
- console.log('检查SKU[' + i + ']:', {
|
|
|
|
- status: sku.status,
|
|
|
|
- price: sku.price,
|
|
|
|
- stocks: sku.stocks,
|
|
|
|
- sku_sn: sku.sku_sn
|
|
|
|
- });
|
|
|
|
|
|
+ if (typeof vm !== 'undefined' && vm && vm.specList && vm.specList.length > 0) {
|
|
|
|
+ // 验证规格值图片 - 定制规格必须上传图片
|
|
|
|
+ console.log('验证规格值图片');
|
|
|
|
+ for (var i = 0; i < vm.specList.length; i++) {
|
|
|
|
+ var spec = vm.specList[i];
|
|
|
|
+ console.log('检查规格[' + i + ']:', spec);
|
|
|
|
|
|
- // 只检查状态为显示的SKU
|
|
|
|
- var isVisible = (sku.status === 1 || sku.status === '1' || sku.status === true);
|
|
|
|
|
|
+ if (spec.type === 'custom') {
|
|
|
|
+ // 定制规格必须上传图片
|
|
|
|
+ if (spec.value && spec.value.length > 0) {
|
|
|
|
+ for (var j = 0; j < spec.value.length; j++) {
|
|
|
|
+ var value = spec.value[j];
|
|
|
|
+ if (value.name && value.name.trim() !== '') {
|
|
|
|
+ if (!value.image || value.image.trim() === '') {
|
|
|
|
+ errors.push('定制规格"' + spec.name + '"的规格值"' + value.name + '"必须上传图片');
|
|
|
|
+ console.log('定制规格值图片验证失败:', spec.name, value.name);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 验证SKU数据
|
|
|
|
+ if (vm.tableData && vm.tableData.length > 0) {
|
|
|
|
+ var hasValidSku = false;
|
|
|
|
+ var validSkuCount = 0;
|
|
|
|
|
|
- console.log('SKU[' + i + '] 显示状态:', sku.status, '可见:', isVisible);
|
|
|
|
|
|
+ console.log('检查SKU数据, tableData长度:', vm.tableData.length);
|
|
|
|
|
|
- if (isVisible) {
|
|
|
|
- var price = parseFloat(sku.price);
|
|
|
|
- var stocks = parseInt(sku.stocks);
|
|
|
|
-
|
|
|
|
- console.log('SKU[' + i + '] 检查通过, price:', price, 'stocks:', stocks);
|
|
|
|
|
|
+ for (var i = 0; i < vm.tableData.length; i++) {
|
|
|
|
+ var sku = vm.tableData[i];
|
|
|
|
+ console.log('检查SKU[' + i + ']:', {
|
|
|
|
+ status: sku.status,
|
|
|
|
+ price: sku.price,
|
|
|
|
+ stocks: sku.stocks,
|
|
|
|
+ sku_sn: sku.sku_sn
|
|
|
|
+ });
|
|
|
|
|
|
- hasValidSku = true;
|
|
|
|
- validSkuCount++;
|
|
|
|
|
|
+ // 只检查状态为显示的SKU
|
|
|
|
+ var isVisible = (sku.status === 1 || sku.status === '1' || sku.status === true);
|
|
|
|
|
|
- // 验证价格必须大于0
|
|
|
|
- if (!price || price <= 0) {
|
|
|
|
- errors.push('SKU销售价必须大于0');
|
|
|
|
- console.log('SKU[' + i + ']销售价验证失败:', price);
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
|
|
+ console.log('SKU[' + i + '] 显示状态:', sku.status, '可见:', isVisible);
|
|
|
|
|
|
- // 验证库存
|
|
|
|
- if (isNaN(stocks) || stocks <= 0) {
|
|
|
|
- errors.push('SKU库存必须大于0');
|
|
|
|
- console.log('SKU[' + i + ']库存验证失败:', stocks);
|
|
|
|
- break;
|
|
|
|
|
|
+ if (isVisible) {
|
|
|
|
+ var price = parseFloat(sku.price);
|
|
|
|
+ var stocks = parseInt(sku.stocks);
|
|
|
|
+
|
|
|
|
+ console.log('SKU[' + i + '] 检查通过, price:', price, 'stocks:', stocks);
|
|
|
|
+
|
|
|
|
+ hasValidSku = true;
|
|
|
|
+ validSkuCount++;
|
|
|
|
+
|
|
|
|
+ // 验证价格必须大于0
|
|
|
|
+ if (!price || price <= 0) {
|
|
|
|
+ errors.push('SKU销售价必须大于0');
|
|
|
|
+ console.log('SKU[' + i + ']销售价验证失败:', price);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 验证库存
|
|
|
|
+ if (isNaN(stocks) || stocks <= 0) {
|
|
|
|
+ errors.push('SKU库存必须大于0');
|
|
|
|
+ console.log('SKU[' + i + ']库存验证失败:', stocks);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- }
|
|
|
|
-
|
|
|
|
- console.log('有效SKU数量:', validSkuCount);
|
|
|
|
-
|
|
|
|
- if (!hasValidSku) {
|
|
|
|
- errors.push('请至少设置一个有效的SKU');
|
|
|
|
- console.log('没有有效的SKU');
|
|
|
|
|
|
+
|
|
|
|
+ console.log('有效SKU数量:', validSkuCount);
|
|
|
|
+
|
|
|
|
+ if (!hasValidSku) {
|
|
|
|
+ errors.push('请至少设置一个有效的SKU');
|
|
|
|
+ console.log('没有有效的SKU');
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ errors.push('请设置SKU数据');
|
|
|
|
+ console.log('SKU数据不存在');
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
errors.push('请设置商品规格');
|
|
errors.push('请设置商品规格');
|
|
@@ -2065,6 +2093,29 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|
isValid = false;
|
|
isValid = false;
|
|
errors.push('请设置商品规格');
|
|
errors.push('请设置商品规格');
|
|
} else {
|
|
} else {
|
|
|
|
+ // 验证规格值图片 - 定制规格必须上传图片
|
|
|
|
+ console.log('第二次验证: 验证规格值图片');
|
|
|
|
+ for (var i = 0; i < vm.specList.length; i++) {
|
|
|
|
+ var spec = vm.specList[i];
|
|
|
|
+ console.log('第二次验证: 检查规格[' + i + ']:', spec);
|
|
|
|
+
|
|
|
|
+ if (spec.type === 'custom') {
|
|
|
|
+ // 定制规格必须上传图片
|
|
|
|
+ if (spec.value && spec.value.length > 0) {
|
|
|
|
+ for (var j = 0; j < spec.value.length; j++) {
|
|
|
|
+ var value = spec.value[j];
|
|
|
|
+ if (value.name && value.name.trim() !== '') {
|
|
|
|
+ if (!value.image || value.image.trim() === '') {
|
|
|
|
+ isValid = false;
|
|
|
|
+ errors.push('定制规格"' + spec.name + '"的规格值"' + value.name + '"必须上传图片');
|
|
|
|
+ console.log('第二次验证: 定制规格值图片验证失败:', spec.name, value.name);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
// 检查是否有有效的规格组合
|
|
// 检查是否有有效的规格组合
|
|
if (!vm.tableData || vm.tableData.length === 0) {
|
|
if (!vm.tableData || vm.tableData.length === 0) {
|
|
isValid = false;
|
|
isValid = false;
|
|
@@ -2607,116 +2658,179 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
|
|
if (Config.goods && Config.goods.spec_type == '1') {
|
|
if (Config.goods && Config.goods.spec_type == '1') {
|
|
console.log('初始化多规格数据');
|
|
console.log('初始化多规格数据');
|
|
let specList = [];
|
|
let specList = [];
|
|
- let specName = {};
|
|
|
|
|
|
|
|
- for (let item of Config.goods_skus) {
|
|
|
|
- console.log('处理SKU项:', item);
|
|
|
|
- if (item.sku_attr) {
|
|
|
|
- console.log('SKU属性数据:', item.sku_attr);
|
|
|
|
- let attr = [];
|
|
|
|
- let skuAttrs = [];
|
|
|
|
-
|
|
|
|
- // 尝试解析JSON格式
|
|
|
|
- try {
|
|
|
|
- skuAttrs = JSON.parse(item.sku_attr);
|
|
|
|
- console.log('解析JSON格式成功:', skuAttrs);
|
|
|
|
- } catch (e) {
|
|
|
|
- // 如果JSON解析失败,尝试旧的字符串格式
|
|
|
|
- console.log('JSON解析失败,尝试字符串格式:', e);
|
|
|
|
- let sku_attr = item.sku_attr.split(',');
|
|
|
|
- skuAttrs = [];
|
|
|
|
- for (let res of sku_attr) {
|
|
|
|
- let sku = res.split(':');
|
|
|
|
- if (sku.length >= 2) {
|
|
|
|
- skuAttrs.push({
|
|
|
|
- name: sku[0],
|
|
|
|
- value: sku[1]
|
|
|
|
- });
|
|
|
|
|
|
+ // 优先使用后端传递的spec_data结构化数据(编辑模式)
|
|
|
|
+ if (Config.spec_data && Config.spec_data.length > 0) {
|
|
|
|
+ console.log('使用后端提供的spec_data结构化数据:', Config.spec_data);
|
|
|
|
+
|
|
|
|
+ // 直接使用后端传递的结构化规格数据
|
|
|
|
+ specList = Config.spec_data.map(spec => {
|
|
|
|
+ return {
|
|
|
|
+ name: spec.name,
|
|
|
|
+ type: spec.type || 'basic',
|
|
|
|
+ value: spec.value || []
|
|
|
|
+ };
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ // 重构SKU映射,基于新的规格结构
|
|
|
|
+ for (let item of Config.goods_skus) {
|
|
|
|
+ if (item.sku_attr) {
|
|
|
|
+ let attr = [];
|
|
|
|
+ let skuAttrs = [];
|
|
|
|
+
|
|
|
|
+ try {
|
|
|
|
+ skuAttrs = JSON.parse(item.sku_attr);
|
|
|
|
+ } catch (e) {
|
|
|
|
+ let sku_attr = item.sku_attr.split(',');
|
|
|
|
+ skuAttrs = [];
|
|
|
|
+ for (let res of sku_attr) {
|
|
|
|
+ let sku = res.split(':');
|
|
|
|
+ if (sku.length >= 2) {
|
|
|
|
+ skuAttrs.push({
|
|
|
|
+ key: sku[0],
|
|
|
|
+ value: sku[1]
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for (let attrObj of skuAttrs) {
|
|
|
|
+ let specName_key = attrObj.key || attrObj.name;
|
|
|
|
+ let specValue = attrObj.value;
|
|
|
|
+ if (specName_key && specValue) {
|
|
|
|
+ attr.push(specValue);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- console.log('转换字符串格式为对象:', skuAttrs);
|
|
|
|
|
|
+
|
|
|
|
+ let attrKey = attr.join(',');
|
|
|
|
+ skus[attrKey] = item;
|
|
}
|
|
}
|
|
-
|
|
|
|
- // 处理规格属性数组
|
|
|
|
- for (let attrObj of skuAttrs) {
|
|
|
|
- if (attrObj.name && attrObj.value) {
|
|
|
|
- attr.push(attrObj.value);
|
|
|
|
- //属性名
|
|
|
|
- if (!specName[attrObj.name]) {
|
|
|
|
- specName[attrObj.name] = [];
|
|
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ console.log('使用结构化数据初始化规格列表:', specList);
|
|
|
|
+ } else {
|
|
|
|
+ // 回退到原有的解析逻辑(新增模式或无结构化数据)
|
|
|
|
+ console.log('使用原有解析逻辑初始化规格数据');
|
|
|
|
+ let specName = {};
|
|
|
|
+ let specTypeMap = {}; // 用于记录规格类型
|
|
|
|
+
|
|
|
|
+ for (let item of Config.goods_skus) {
|
|
|
|
+ console.log('处理SKU项:', item);
|
|
|
|
+ if (item.sku_attr) {
|
|
|
|
+ console.log('SKU属性数据:', item.sku_attr);
|
|
|
|
+ let attr = [];
|
|
|
|
+ let skuAttrs = [];
|
|
|
|
+
|
|
|
|
+ // 尝试解析JSON格式
|
|
|
|
+ try {
|
|
|
|
+ skuAttrs = JSON.parse(item.sku_attr);
|
|
|
|
+ console.log('解析JSON格式成功:', skuAttrs);
|
|
|
|
+ } catch (e) {
|
|
|
|
+ // 如果JSON解析失败,尝试旧的字符串格式
|
|
|
|
+ console.log('JSON解析失败,尝试字符串格式:', e);
|
|
|
|
+ let sku_attr = item.sku_attr.split(',');
|
|
|
|
+ skuAttrs = [];
|
|
|
|
+ for (let res of sku_attr) {
|
|
|
|
+ let sku = res.split(':');
|
|
|
|
+ if (sku.length >= 2) {
|
|
|
|
+ skuAttrs.push({
|
|
|
|
+ key: sku[0],
|
|
|
|
+ value: sku[1],
|
|
|
|
+ type: 'basic' // 默认为基础规格类型
|
|
|
|
+ });
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- if (!specName[attrObj.name].includes(attrObj.value)) {
|
|
|
|
- specName[attrObj.name].push(attrObj.value);
|
|
|
|
|
|
+ console.log('转换字符串格式为对象:', skuAttrs);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 处理规格属性数组
|
|
|
|
+ for (let attrObj of skuAttrs) {
|
|
|
|
+ let specName_key = attrObj.key || attrObj.name;
|
|
|
|
+ let specValue = attrObj.value;
|
|
|
|
+ let specType = attrObj.type || 'basic';
|
|
|
|
+
|
|
|
|
+ if (specName_key && specValue) {
|
|
|
|
+ attr.push(specValue);
|
|
|
|
+ //属性名和类型
|
|
|
|
+ if (!specName[specName_key]) {
|
|
|
|
+ specName[specName_key] = [];
|
|
|
|
+ }
|
|
|
|
+ if (!specName[specName_key].includes(specValue)) {
|
|
|
|
+ specName[specName_key].push(specValue);
|
|
|
|
+ }
|
|
|
|
+ // 记录规格类型
|
|
|
|
+ specTypeMap[specName_key] = specType;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ // 使用字符串作为键,与renderTableData中的查找方式一致
|
|
|
|
+ let attrKey = attr.join(',');
|
|
|
|
+ skus[attrKey] = item;
|
|
|
|
+ console.log('SKU映射:', attrKey, '->', item);
|
|
|
|
+ } else {
|
|
|
|
+ console.warn('SKU缺少sku_attr字段:', item);
|
|
}
|
|
}
|
|
- // 使用字符串作为键,与renderTableData中的查找方式一致
|
|
|
|
- let attrKey = attr.join(',');
|
|
|
|
- skus[attrKey] = item;
|
|
|
|
- console.log('SKU映射:', attrKey, '->', item);
|
|
|
|
- } else {
|
|
|
|
- console.warn('SKU缺少sku_attr字段:', item);
|
|
|
|
}
|
|
}
|
|
- }
|
|
|
|
- console.log('解析完成的规格名称映射:', specName);
|
|
|
|
-
|
|
|
|
- // 构建规格值映射表(从数据库获取的完整数据)
|
|
|
|
- let specValueMap = {};
|
|
|
|
- if (Config.spec_values && Config.spec_values.length > 0) {
|
|
|
|
- console.log('发现规格值数据:', Config.spec_values);
|
|
|
|
- console.log('规格值数据类型:', typeof Config.spec_values);
|
|
|
|
- console.log('规格值数据结构样例:', Config.spec_values[0]);
|
|
|
|
-
|
|
|
|
- Config.spec_values.forEach(function(item) {
|
|
|
|
- if (!specValueMap[item.spec_name]) {
|
|
|
|
- specValueMap[item.spec_name] = {};
|
|
|
|
- }
|
|
|
|
- specValueMap[item.spec_name][item.value] = {
|
|
|
|
- name: item.value,
|
|
|
|
- image: item.image || '',
|
|
|
|
- description: item.description || ''
|
|
|
|
- };
|
|
|
|
- });
|
|
|
|
- console.log('规格值映射表:', specValueMap);
|
|
|
|
- } else {
|
|
|
|
- console.log('没有发现规格值数据,使用默认处理方式');
|
|
|
|
- console.log('Config.spec_values:', Config.spec_values);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- for (let i in specName) {
|
|
|
|
- // 转换旧格式数据为新格式,优先使用数据库中的完整数据
|
|
|
|
- let valueList = specName[i].map(val => {
|
|
|
|
- if (typeof val === 'string') {
|
|
|
|
- // 从映射表中查找完整数据,如果没有则使用默认值
|
|
|
|
- if (specValueMap[i] && specValueMap[i][val]) {
|
|
|
|
- console.log('找到规格值完整数据:', i, val, specValueMap[i][val]);
|
|
|
|
- return {
|
|
|
|
- name: specValueMap[i][val].name,
|
|
|
|
- image: specValueMap[i][val].image || '',
|
|
|
|
- description: specValueMap[i][val].description || ''
|
|
|
|
- };
|
|
|
|
- } else {
|
|
|
|
- console.log('使用默认规格值数据:', i, val);
|
|
|
|
- return {
|
|
|
|
- name: val,
|
|
|
|
- image: '',
|
|
|
|
- description: ''
|
|
|
|
- };
|
|
|
|
|
|
+ console.log('解析完成的规格名称映射:', specName);
|
|
|
|
+ console.log('规格类型映射:', specTypeMap);
|
|
|
|
+
|
|
|
|
+ // 构建规格值映射表(从数据库获取的完整数据)
|
|
|
|
+ let specValueMap = {};
|
|
|
|
+ if (Config.spec_values && Config.spec_values.length > 0) {
|
|
|
|
+ console.log('发现规格值数据:', Config.spec_values);
|
|
|
|
+ console.log('规格值数据类型:', typeof Config.spec_values);
|
|
|
|
+ console.log('规格值数据结构样例:', Config.spec_values[0]);
|
|
|
|
+
|
|
|
|
+ Config.spec_values.forEach(function(item) {
|
|
|
|
+ if (!specValueMap[item.spec_name]) {
|
|
|
|
+ specValueMap[item.spec_name] = {};
|
|
}
|
|
}
|
|
- }
|
|
|
|
- // 如果已经是对象格式,确保结构完整
|
|
|
|
- return {
|
|
|
|
- name: val.name || val,
|
|
|
|
- image: val.image || '',
|
|
|
|
- description: val.description || ''
|
|
|
|
- };
|
|
|
|
- });
|
|
|
|
|
|
+ specValueMap[item.spec_name][item.value] = {
|
|
|
|
+ name: item.value,
|
|
|
|
+ image: item.image || '',
|
|
|
|
+ description: item.description || ''
|
|
|
|
+ };
|
|
|
|
+ });
|
|
|
|
+ console.log('规格值映射表:', specValueMap);
|
|
|
|
+ } else {
|
|
|
|
+ console.log('没有发现规格值数据,使用默认处理方式');
|
|
|
|
+ console.log('Config.spec_values:', Config.spec_values);
|
|
|
|
+ }
|
|
|
|
|
|
- specList.push({
|
|
|
|
- name: i,
|
|
|
|
- type: 'basic', // 默认为基础规格
|
|
|
|
- value: valueList
|
|
|
|
- });
|
|
|
|
|
|
+ for (let i in specName) {
|
|
|
|
+ // 转换旧格式数据为新格式,优先使用数据库中的完整数据
|
|
|
|
+ let valueList = specName[i].map(val => {
|
|
|
|
+ if (typeof val === 'string') {
|
|
|
|
+ // 从映射表中查找完整数据,如果没有则使用默认值
|
|
|
|
+ if (specValueMap[i] && specValueMap[i][val]) {
|
|
|
|
+ console.log('找到规格值完整数据:', i, val, specValueMap[i][val]);
|
|
|
|
+ return {
|
|
|
|
+ name: specValueMap[i][val].name,
|
|
|
|
+ image: specValueMap[i][val].image || '',
|
|
|
|
+ description: specValueMap[i][val].description || ''
|
|
|
|
+ };
|
|
|
|
+ } else {
|
|
|
|
+ console.log('使用默认规格值数据:', i, val);
|
|
|
|
+ return {
|
|
|
|
+ name: val,
|
|
|
|
+ image: '',
|
|
|
|
+ description: ''
|
|
|
|
+ };
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // 如果已经是对象格式,确保结构完整
|
|
|
|
+ return {
|
|
|
|
+ name: val.name || val,
|
|
|
|
+ image: val.image || '',
|
|
|
|
+ description: val.description || ''
|
|
|
|
+ };
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ specList.push({
|
|
|
|
+ name: i,
|
|
|
|
+ type: specTypeMap[i] || 'basic', // 使用从SKU属性中解析的规格类型
|
|
|
|
+ value: valueList
|
|
|
|
+ });
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
this.skus = skus;
|
|
this.skus = skus;
|