Browse Source

【器件上传】-- 新版器件上传接口实现

wangyc 8 years ago
parent
commit
7e46b37499

+ 45 - 51
src/main/java/com/uas/platform/b2c/prod/product/component/controller/ComponentSubmitController.java

@@ -32,7 +32,6 @@ import java.io.UnsupportedEncodingException;
 import java.net.URLDecoder;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
 
 /**
  * @author wangyc
@@ -429,36 +428,6 @@ public class ComponentSubmitController {
 		return componentSubmitService.saveBatch(details);
 	}
 
-	/**
-	 * 上传器件数据到爬虫库(没有参数对应关系)
-	 * 
-	 * @param uploadItem 文件
-	 * @return 爬取器件信息
-	 */
-	@Transactional
-	@RequestMapping(value = "upload/componentCrawls", method = RequestMethod.POST)
-	public List<ComponentCrawl> uploadComponentCrawl(FileUpload uploadItem) {
-		String fileName = uploadItem.getFile().getOriginalFilename();
-		String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
-		InputStream is = null;
-		Workbook workbook = null;
-		List<ComponentCrawl> componentCrawls = new ArrayList<ComponentCrawl>();
-		try {
-			is = uploadItem.getFile().getInputStream();
-			if ("xls".equals(suffix)) {
-				workbook = new HSSFWorkbook(is);
-			} else if ("xlsx".equals(suffix)) {
-				workbook = new XSSFWorkbook(is);
-			} else {
-				throw new IllegalOperatorException("文件格不正确,请上传.xls或.xlsx的文件");
-			}
-			componentCrawls = componentSubmitService.uploadComponentCrawl(workbook, fileName);
-		} catch (IOException e) {
-			e.printStackTrace();
-		}
-		return componentCrawls;
-	}
-
 	/**
 	 * 上传器件数据到爬虫库(没有参数对应关系)
 	 *
@@ -468,31 +437,56 @@ public class ComponentSubmitController {
 	@Transactional
 	@RequestMapping(value = "upload/componentCrawls", method = RequestMethod.POST)
 	public List<ComponentCrawl> uploadComponentCrawlV2(FileUpload uploadItem) {
-		String fileName = uploadItem.getFile().getOriginalFilename();
+        String fileName = uploadItem.getFile().getOriginalFilename();
 		List<ComponentCrawl> componentCrawls = new ArrayList<ComponentCrawl>();
 
 		try {
 			InputStream is = uploadItem.getFile().getInputStream();
 			ExcelReader reader = ExcelUtil.getReader(is);
-			List<Map<String, Object>> maps = reader.readAll();
-
-			int size = maps.size();
-			if (size > 0 && size < 10000) {// 文件不得超过10000行
-				Map<String, Object> map = maps.get(0);
-				int rowSize = map.keySet().size();
-				if (rowSize < 50) {// 整体列数不得超过50
-					if (rowSize > 30 && size > 2000) {// 列数超过30的文件不得超过2000行
-						throw new IllegalOperatorException("属性超过22个时,文件只允许上传2000行");
-					}
-					componentCrawls = componentSubmitService.uploadComponentCrawl(maps);
-				} else {
-					throw new IllegalOperatorException("属性值不得超过42个");
-				}
-			} else {
-				throw new IllegalOperatorException("上传文件必须大于0行小于10000行");
-			}
-
 
+            // 获取表头数据
+            List<List<Object>> headers = reader.read(0, 0);
+            if (headers != null && headers.size() > 0) {
+
+                // 验证表头信息
+                List<Object> header = headers.get(0).subList(0, 8);
+                List<Object> exceptHeader = new ArrayList<Object>();
+                exceptHeader.add("型号");
+                exceptHeader.add("商城类目");
+                exceptHeader.add("目标类目");
+                exceptHeader.add("商城品牌");
+                exceptHeader.add("来源网址");
+                exceptHeader.add("规格书");
+                exceptHeader.add("图片");
+                exceptHeader.add("描述");
+
+                if (header.equals(exceptHeader)) {
+                    // 获取全表数据
+                    List<List<Object>> rows = reader.read();
+                    int size = rows.size();
+
+                    if (size > 0 && size < 10000) {
+                        int rowSize = headers.get(0).size();
+                        if (rowSize < 50) {
+                            // 列数超过30的文件不得超过2000行
+                            if (rowSize > 30 && size > 2000) {
+                                throw new IllegalOperatorException("属性超过22个时,文件只允许上传2000行");
+                            }
+                            componentCrawls = componentSubmitService.uploadComponentCrawl(rows, fileName);
+                        // 整体列数不得超过50
+                        } else {
+                            throw new IllegalOperatorException("属性值不得超过42个");
+                        }
+                    // 文件不得超过10000行
+                    } else {
+                        throw new IllegalOperatorException("上传文件必须大于0行小于10000行");
+                    }
+                } else {
+                    throw new IllegalOperatorException("表头格式错误,前8列应为 \'型号\',\'商城类目\',\'目标类目\',\'商城品牌\',\'来源网址\',\'规格书\',\'图片\',\'描述\'");
+                }
+            } else {
+                throw new IllegalOperatorException("表头信息错误,请核对后再上传");
+            }
 		} catch (IOException e) {
 			e.printStackTrace();
 		}
@@ -502,7 +496,7 @@ public class ComponentSubmitController {
 
 	/**
 	 * 上传器件数据到爬虫库(已有参数对应关系)
-	 * 
+	 *
 	 * @param uploadItem 文件
 	 * @param kindContrastId 对应关系id
 	 * @return 爬取器件信息

+ 2 - 2
src/main/java/com/uas/platform/b2c/prod/product/component/service/ComponentSubmitService.java

@@ -6,7 +6,6 @@ import org.apache.poi.ss.usermodel.Workbook;
 import org.springframework.data.domain.Page;
 
 import java.util.List;
-import java.util.Map;
 
 public interface ComponentSubmitService {
 
@@ -129,7 +128,7 @@ public interface ComponentSubmitService {
 	 *
 	 * @return 爬取器件
 	 */
-	public List<ComponentCrawl> uploadComponentCrawl(List<Map<String, Object>> maps);
+	public List<ComponentCrawl> uploadComponentCrawl(List<List<Object>> rows, String fileName);
 
 	/**
 	 * 上传器件爬取数据(已有参数对应关系)
@@ -139,4 +138,5 @@ public interface ComponentSubmitService {
 	 * @return 爬取器件
 	 */
 	public List<ComponentCrawl> uploadComponentCrawlWithSame(Workbook workbook, String fileName, Long kindContrastId);
+
 }

+ 190 - 23
src/main/java/com/uas/platform/b2c/prod/product/component/service/impl/ComponentSubmitServiceImpl.java

@@ -1,7 +1,5 @@
 package com.uas.platform.b2c.prod.product.component.service.impl;
 
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
 import com.uas.platform.b2c.common.account.dao.UserBaseInfoDao;
 import com.uas.platform.b2c.common.base.service.SendMessageService;
 import com.uas.platform.b2c.core.support.SystemSession;
@@ -34,6 +32,7 @@ import com.uas.platform.core.persistence.criteria.LogicalExpression;
 import com.uas.platform.core.persistence.criteria.PredicateUtils;
 import com.uas.platform.core.persistence.criteria.SimpleExpression;
 import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.map.HashedMap;
 import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.usermodel.Row;
 import org.apache.poi.ss.usermodel.Sheet;
@@ -724,27 +723,195 @@ public class ComponentSubmitServiceImpl implements ComponentSubmitService {
 	}
 
 	@Override
-	public List<ComponentCrawl> uploadComponentCrawl(List<Map<String, Object>> maps) {
-		// 验证表头信息是否一致
-		Map<String, Object> firstRow = maps.get(0);
-		Set<String> theads = ImmutableSet.copyOf(Iterables.limit(firstRow.keySet(), 8));
-
-		// 模板表头
-		Set<String> expectHeads = new HashSet<String>();
-		expectHeads.add("型号");
-		expectHeads.add("商城类目");
-		expectHeads.add("目标类目");
-		expectHeads.add("商城品牌");
-		expectHeads.add("来源网址");
-		expectHeads.add("规格书");
-		expectHeads.add("图片");
-		expectHeads.add("描述");
-
-		if (!expectHeads.containsAll(theads)) {
-			throw new IllegalOperatorException("表格表头内容不对,请重新确认模板");
-		}
-
-		return null;
+	public List<ComponentCrawl> uploadComponentCrawl(List<List<Object>> rows, String fileName) {
+		List<ComponentCrawl> components = new ArrayList<ComponentCrawl>();
+
+		// 提取公共数据
+		List<Object> firstRow = rows.get(1);
+		Map<String, Object> commonData = validateCommonData(firstRow);
+		// 商城类目
+		Kind b2cKind = (Kind)commonData.get("b2cKind");
+		// 目标类目
+		String kindName = commonData.get("kindName").toString();
+		// 商城品牌
+		Brand b2cBrand = (Brand)commonData.get("b2cBrand");
+		// url
+		String url = commonData.get("url").toString();
+
+		// 如果参数参数对应关系出现重复返回前台提示是否新增参数对应关系
+		List<KindCrawl> existKindCrawls = kindContrastDao.findByKindNameAndB2cKiIdAndResourceAndB2cBrIdAndUrl(kindName, b2cKind.getId(), b2cBrand.getNameEn(), b2cBrand.getId(), url);
+		if (CollectionUtils.isNotEmpty(existKindCrawls)) {
+			ComponentCrawl isRepeated = new ComponentCrawl();
+			isRepeated.setB2cKiId(existKindCrawls.get(0).getId());
+			isRepeated.setVersion((short) -1);
+			components.add(isRepeated);
+			return components;
+		}
+
+		// 生成参数对应关系
+		KindCrawl kindCrawl = initKindCrawl(b2cKind.getId(), b2cBrand, kindName, url, fileName);
+
+		// 生成数据解析任务
+		ComponentCrawlTask task = initComponentCrawlTask(kindCrawl, fileName);
+
+		// 取表头信息
+		List<String> propertyNames = (List<String>)(List)rows.get(0);
+		int maxSize = propertyNames.size();
+
+		for (int i = 1; i < rows.size(); i++) {
+			List<Object> row = rows.get(i);
+			ComponentCrawl component = new ComponentCrawl();
+
+			// 型号
+			Object code = row.get(0);
+			if (code != null && StringUtils.hasText(code.toString())) {
+				component.setCode(code.toString().trim());
+			} else {
+				throw new IllegalOperatorException(String.format("第%s行型号为空", (i + 1)));
+			}
+
+			// 规格书
+			Object attach = row.get(5);
+			if (attach != null && StringUtils.hasText(attach.toString())) {
+				component.setAttach(attach.toString().trim());
+			}
+
+			// 图片
+			Object img = row.get(6);
+			if (img != null && StringUtils.hasText(img.toString())) {
+				component.setImg(img.toString().trim());
+			}
+
+			// 描述
+			Object description = row.get(7);
+			if (description != null && StringUtils.hasText(description.toString())) {
+				component.setDescription(description.toString().trim());
+			}
+
+			// 参数值
+			Set<PropertyValueCrawl> propertyValues = new HashSet<PropertyValueCrawl>();
+			for (int j = 8; j < maxSize && j < row.size(); j++) {
+				Object property = row.get(j);
+				if (property != null && StringUtils.hasText(property.toString())) {
+					PropertyValueCrawl propertyValue = new PropertyValueCrawl();
+					propertyValue.setValue(property.toString().trim());
+					propertyValue.setPropertyName(propertyNames.get(j));
+					propertyValues.add(propertyValue);
+				}
+			}
+
+			component.setProperties(propertyValues);
+			// 设置基本参数
+			component.setB2cBrId(b2cBrand.getId());
+			component.setB2cKiId(b2cKind.getId());
+			component.setKindName(kindName);
+			component.setTask(task.getId());
+
+			components.add(component);
+		}
+		return componentCrawlDao.save(components);
+	}
+
+	/**
+	 * 初始化数据解析任务
+	 * @param kindCrawl 参数对应关系
+	 * @param fileName 上传文件名
+	 * @return
+	 */
+	private ComponentCrawlTask initComponentCrawlTask(KindCrawl kindCrawl, String fileName) {
+		// 生成数据解析任务
+		ComponentCrawlTask task = new ComponentCrawlTask();
+		task.setContrastId(kindCrawl.getId());
+		task.setContrast(FastjsonUtils.toJson(kindCrawl));
+		task.setCreateDate(new Date());
+		task.setCreaterUu(SystemSession.getUser().getUserUU());
+		task.setStatus(Status.TO_CROWL.value());
+		task.setFile(fileName);
+		task.setTaskId(EncodingRulesConstant.COMPONENT_CRAWL_TASK.replaceFirst("_TIMESTAP_NUMBER", createNumberService.getTimeNumber("product$component_crawl_task", 8)));
+
+		kindCrawl.setTaskid(task.getTaskId());// 将数据解析任务号回写到参数对应关系中
+		kindContrastDao.save(kindCrawl);
+
+		return componentCrawlTaskDao.save(task);
+	}
+
+	/**
+	 * 初始化标准参数对应关系
+	 * @param b2cKindId 商城类目id
+	 * @param b2cBrand 商城品牌
+	 * @param kindName 目标类目
+	 * @param url 官网地址
+	 * @param fileName 上传文件名
+	 * @return
+	 */
+	private KindCrawl initKindCrawl(Long b2cKindId, Brand b2cBrand, String kindName, String url, String fileName) {
+		Date date = new Date();
+		KindCrawl kindCrawl = new KindCrawl();
+		kindCrawl.setResource(b2cBrand.getNameEn());
+		kindCrawl.setB2cBrId(b2cBrand.getId());
+		kindCrawl.setKindName(kindName);
+		kindCrawl.setB2cKiId(b2cKindId);
+		kindCrawl.setUrl(url);
+		kindCrawl.setCreateDate(date);
+		kindCrawl.setCreaterUu(SystemSession.getUser().getUserUU());
+		kindCrawl.setInTask((short) 1);// 参数对应关系直接设置为已提交
+		kindCrawl.setUpdateDate(date);
+		kindCrawl.setUpdaterUu(SystemSession.getUser().getUserUU());
+		kindCrawl.setFile(fileName);// 设置上传文件名
+
+		kindCrawl = kindContrastDao.save(kindCrawl);
+		return kindContrastDao.findOne(kindCrawl.getId());// 因为save返回的对象没有关联的实体信息只有id,所以需要重新查询一次,为后续生成json存入任务做准备
+	}
+
+	/**
+	 * 验证公共数据
+	 * @param firstRow
+	 * @return
+	 */
+	private Map<String, Object> validateCommonData(List<Object> firstRow) {
+		if (CollectionUtils.isNotEmpty(firstRow)) {
+			Map<String, Object> commonData = new HashedMap();
+
+			// 商城类目
+			Object b2cKindName = firstRow.get(1);
+			if (b2cKindName != null && StringUtils.hasText(b2cKindName.toString())) {
+				List<Kind> kinds = kindDao.findByNameCn(b2cKindName.toString().trim());
+				if (CollectionUtils.isEmpty(kinds)) {
+					throw new IllegalOperatorException("商城类目不存在");
+				}
+				commonData.put("b2cKind", kinds.get(0));
+			} else {
+				throw new IllegalOperatorException("商城类目为空");
+			}
+
+			// 目标类目
+			Object kindName = firstRow.get(2);
+			if (kindName != null &&  StringUtils.hasText(kindName.toString())) {
+				commonData.put("kindName", kindName.toString().trim());
+			} else {
+				throw new IllegalOperatorException("目标类目为空");
+			}
+
+			// 商城品牌
+			Object brandName = firstRow.get(3);
+			if (brandName != null && StringUtils.hasText(brandName.toString())) {
+				List<Brand> brands = brandDao.findByUpperNameEn(brandName.toString().trim());
+				if (CollectionUtils.isEmpty(brands)) {
+					throw new IllegalOperatorException("商城品牌不存在");
+				}
+				commonData.put("b2cBrand", brands.get(0));
+			}
+
+			// url
+			Object url = firstRow.get(4);
+			if (url != null && StringUtils.hasText(url.toString())) {
+				commonData.put("url", url.toString().trim());
+			}
+
+			return commonData;
+		} else {
+			throw new IllegalOperatorException("第二列数据不存在");
+		}
 	}
 
 	@Override