`

spring BeanPostProcessor 装在

 
阅读更多

spring实例化bean的前后执行一些附加操作。 

有时,你会发现需要立刻在Spring实例化一个bean的前后执行一些附件操作。这些操作可以简单到修改一个bean,也可以复杂到返回一个完全不同的对象。 
BeanPostProcessor接口包含两个method: 
postProcessBeforeInitialization方法:在Spring调用任何bean的初始化钩子(例如InitializingBean.afterPropertiesSet或者init方法)之前被调用。 
postProcessAfterInitialization方法:Spring在成功完成嵌入初始化以后调用他。

 

 

/** 

 * Copyright (C) 2014 Winbons Technology Software Co.,Ltd

 * All Rights Reserved.

 * Development of this softwareWinbons Technology Software Co.,Ltd.

 * Without the formal written consent of the Company, 

 * any other individuals, groups may not use, 

 * copy, modify, or distribute this software

 * @Title: IErrorListener.java 

 * @Package saas.crm.importer 

 * @Description: TODO(用一句话描述该文件做什么) 

 * @author star.ye 

 * @date 2014年11月6日 下午2:50:12 

 * @version 1.0 

 */

 

package saas.crm.importer;

 

import java.io.IOException;

import java.io.OutputStream;

import java.util.Map;

import java.util.concurrent.ConcurrentLinkedQueue;

 

/**

 * @ClassName: IErrorListener

 * @Description: TODO(这里用一句话描述这个类的作用)

 * @author star.ye

 * @date 2014年11月6日 下午2:50:12

 */

 

public interface ImportListener {

 

void onStart(String fileId, ImportType importType);

 

Object convertEntity(String propertyName, Object value, Object data) throws Exception;

 

/**

* 是否保存成功

* @return  1 - 保存成功

* 0 - 保存/覆盖失败

* -1 - 覆盖/忽略成功

*/

int onSaveData(Object obj, ImportType importType, int dataIndex,Long importLogId);

 

ImportData init(int type);

 

/**

* 导入结束后的操作

* @param totalCounttotalCount[0] - 成功导入记录数totalCount[1] - 成功覆盖/忽略记录数

* @param importDataEn

* @param importLog

* @param datas

*/

void onComplete(ImportDataEn importDataEn, Map<String, String> datas,Integer dataRowNum,ConcurrentLinkedQueue<Integer> queue);

 

String getModuleName();

 

void exportTemplete(OutputStream outputStream, int type) throws IOException;

 

Map<String, Object> getNewListItem();

 

}

 

/** 

 * Copyright (C) 2014 Winbons Technology Software Co.,Ltd

 * All Rights Reserved.

 * Development of this softwareWinbons Technology Software Co.,Ltd.

 * Without the formal written consent of the Company, 

 * any other individuals, groups may not use, 

 * copy, modify, or distribute this software

 * @Title: DefaultCellListener.java 

 * @Package saas.crm.importer 

 * @Description: TODO(用一句话描述该文件做什么) 

 * @author star.ye 

 * @date 2014年11月6日 下午2:57:03 

 * @version 1.0 

 */

 

package saas.crm.importer;

 

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.OutputStream;

import java.util.ArrayList;

import java.util.Date;

import java.util.HashMap;

import java.util.HashSet;

import java.util.Iterator;

import java.util.List;

import java.util.Map;

import java.util.Set;

import java.util.concurrent.ConcurrentHashMap;

import java.util.concurrent.ConcurrentLinkedQueue;

 

import org.apache.commons.beanutils.BeanUtils;

import org.apache.commons.lang.StringUtils;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import org.apache.poi.ss.usermodel.Cell;

import org.apache.poi.ss.usermodel.CellStyle;

import org.apache.poi.ss.usermodel.DataFormat;

import org.apache.poi.ss.usermodel.Row;

import org.apache.poi.ss.usermodel.Sheet;

import org.apache.poi.ss.usermodel.Workbook;

import org.joda.time.DateTime;

import org.slf4j.Logger;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.transaction.annotation.Transactional;

 

import saas.crm.Constant;

import saas.crm.base.manager.ITempFileManager;

import saas.crm.base.uisetting.IListService;

import saas.crm.base.uisetting.IUISetting;

import saas.crm.data.model.definition.DefinedFeild;

import saas.crm.data.model.log.ImportLog;

import saas.crm.importer.excel.WorkBookUtils;

import saas.data.manager.ISystemProfileManager;

import saas.framework.dao.BaseDao;

import saas.framework.data.model.ListItem;

import saas.framework.utils.Env;

import saas.framework.utils.SecurityUtils;

 

/**

 * @ClassName: DefaultCellListener

 * @Description: TODO(这里用一句话描述这个类的作用)

 * @author star.ye

 * @date 2014年11月6日 下午2:57:03

 */

 

public abstract class AbstractImportListener implements ImportListener {

 

protected static final Logger logger = org.slf4j.LoggerFactory.getLogger("IMPORT.ERROR");

 

@Autowired

private ISystemProfileManager systemProfileManager;

 

public String hightSeaActivated ="N";  //默认设置公海池开关为 关

 

private static ConcurrentHashMap<Long, ImportLog> importLogMap=new ConcurrentHashMap<Long, ImportLog>();

private static ConcurrentHashMap<Long, List<ErrorRow>> errorListMap=new ConcurrentHashMap<Long, List<ErrorRow>>();

 

@Autowired

private ITempFileManager tempFileManager;

 

public abstract String getEntityClassName();

 

protected static ThreadLocal<Map<String, Object>> cacheValue = new ThreadLocal<Map<String, Object>>() {

protected Map<String, Object> initialValue() {

return new HashMap<String, Object>();

}

};

 

protected static ThreadLocal<Map<String, Object>> newItemCache = new ThreadLocal<Map<String, Object>>() {

@Override

protected Map<String, Object> initialValue() {

return new HashMap<String, Object>();

}

};

 

public Map<String, Object> getInitData() {

return null;

}

 

@Autowired

protected BaseDao baseDao;

 

@Autowired

private IUISetting uiSetting;

 

@Autowired

private IListService listService;

 

public static final String ERROR_FOLDER = "importErrors";

 

public Object convertEntity(String propertyName, Object value, Object data) throws Exception {

BeanUtils.setProperty(data, propertyName, value);

return data;

}

 

public Map<String, Object> getNewListItem(){

return newItemCache.get();

}

 

public void onStart(String fileId, ImportType importType) {

logger.info("fileId:{} start to import...", fileId);

cacheValue.get().clear();

newItemCache.get().clear();

}

 

@Override

public ImportData init(int type) {

return getConfig(type);

}

 

public ImportData getConfig(int type) {

Modules modules = Modules.getByType(type);

List<DefinedFeild> definedFeilds = uiSetting.getModelDefineField(modules.tableName);

if(modules.equals(Modules.LEADS)){

clearSpeFields(definedFeilds, "ownerId");

}

 

if(modules.equals(Modules.CONTACT)){

clearSpeFields(definedFeilds, "ownerId");

}

 

hightSeaActivated = systemProfileManager.getSystemProfileNoCache(SecurityUtils.getTenantId(), "customerPool", "activated");

//如果是 联系人导入 ,增加 客户池 这个数据栏

if(modules.equals(Modules.CONTACT) && "Y".equals(hightSeaActivated)){

DefinedFeild definedFeild=new DefinedFeild();

definedFeild.setField_label("客户池");

definedFeild.setMapping_field_name("cust_pool");

definedFeild.setIs_mandatory(true);

definedFeild.setIs_updateable(true);

definedFeild.setField_type("autocomplete");

definedFeild.setMax_length(20);

definedFeild.setTable_name("t_crm_cust_contact");

definedFeilds.add(definedFeild);

 

}

 

ImportData importData = new ImportData();

Map<String, Column> cMap = new HashMap<String, Column>();

importData.setColumnMap(cMap);

Set<String> cSet = new HashSet<String>();

importData.setRequiredFields(cSet);

 

for (DefinedFeild definedFeild : definedFeilds) {

String lable = definedFeild.getField_label();

if (StringUtils.isNotBlank(lable)) {

String mappingName = definedFeild.getMapping_field_name();

if (definedFeild.isIs_updateable()) {

Column column = new Column(lable, mappingName, definedFeild.getField_type(), definedFeild.getMax_length());

cMap.put(definedFeild.getField_label(), column);

}

//设置必填项

if (definedFeild.getIs_mandatory() && !"owner_id".equals(mappingName) && !"deptId".equals(mappingName) 

&& !"deptName".equals(mappingName) && !"district".equals(mappingName) && !"area".equals(mappingName) ) {

cSet.add(definedFeild.getMapping_field_name());

}

 

if(!"Y".equals(hightSeaActivated)){

cSet.remove("cust_pool");// 如果公海未开启,那么cust_pool不能设为必填项

}

}

}

importData.setEntityClassName(getEntityClassName());

return importData;

}

 

/**

* @param totalCount

*            成功导入数据条数

* @param errorCells

*            失败记录集合

* @param importLog

*            导入日志

* @param totalNum

*            当前Sheet中的总列数

*/

@Override

@Transactional

public void onComplete(ImportDataEn importDataEn, Map<String, String> datas,Integer dataRowNum,ConcurrentLinkedQueue<Integer> queue) {

ImportLog importLog = importDataEn.getImportLog();

Long imLogId=importLog.getId();

logger.info("-----------onComplete()");

if (dataRowNum!=null && dataRowNum>Constant.importMutiOn){

ImportLog commImportLog = importLogMap.get(importLog.getId());

if (commImportLog==null || commImportLog.getId().longValue()!=importLog.getId().longValue()){

ImportLog finalLog;

try {

finalLog = (ImportLog)BeanUtils.cloneBean(importLog);

finalLog.setStatus(ImportStatus.COMPLETE.value);

importLogMap.put(importLog.getId(), finalLog);

} catch (Exception e) {

e.printStackTrace();

}

}

 

if (importLog.getStatus()==ImportStatus.FAIL.value){

importLogMap.get(importLog.getId()).setStatus(ImportStatus.FAIL.value);

}

}

 

List<ErrorRow> errorCells = importDataEn.getErrorCells();

if (dataRowNum!=null && dataRowNum>Constant.importMutiOn){

List<ErrorRow> comList = errorListMap.get(importLog.getId());

if (comList==null){

List<ErrorRow> re=new ArrayList<ErrorRow>();

errorListMap.put(importLog.getId(), re);

}

if (errorCells!=null && !errorCells.isEmpty()){

errorListMap.get(importLog.getId()).addAll(errorCells);

}

 

}

 

if (dataRowNum!=null && dataRowNum>Constant.importMutiOn){

 

ExcelBizImporter.numLock.lock();

int succ = ExcelBizImporter.importResultNums.get(imLogId)[0]+ExcelBizImporter.importResultNums.get(imLogId)[1];

int failRe=ExcelBizImporter.importResultNums.get(imLogId)[2];

String successMsg = "成功导入" + ExcelBizImporter.importResultNums.get(imLogId)[0] + "条数据," + importDataEn.getImportType().name

           + ExcelBizImporter.importResultNums.get(imLogId)[1] + "条数据";

ExcelBizImporter.numLock.unlock();

 

   if (!errorListMap.get(importLog.getId()).isEmpty()) {

importLog.setMsg(successMsg + ",失败 " + failRe + " 条,失败请查看日志");

} else {

importLog.setMsg(successMsg);

}

   

   //int totalImport=finalRe[0]+finalRe[1];

   int imortNum=ExcelBizImporter.importIngNum.get(importLog.getId());

   if (queue.isEmpty() && imortNum>= (dataRowNum-2)){

   if (importLogMap.get(importLog.getId()).getStatus()==ImportStatus.FAIL.value){

   importLog.setStatus(ImportStatus.FAIL.value);

   }

   List<ErrorRow> errList=errorListMap.get(importLog.getId());

   int actuRowNum=dataRowNum-ExcelBizImporter.emptyRowNum.get(importLog.getId());

   if (succ<actuRowNum){

if ((succ+failRe)<1 && dataRowNum>0){

errList.add(new ErrorRow(new String[]{""},new Integer[]{1},"模板数据有问题,请重新下载模板来填写数据!"));

}

   writeErrorLog(errList, importLog, datas); // add errorLog

   }

   tempFileManager.removeTempFile(importLog.getImportfile());

   errorListMap.remove(importLog.getId());

   importLogMap.remove(importLog.getId());

   ImportManagerImpl.conMap.remove(importLog.getId());

   ImportManagerImpl.leadsMap.remove(importLog.getId());

   ImportManagerImpl.custNamesMap.remove(importLog.getId());

   ImportManagerImpl.custMap.remove(importLog.getId());

   }

 

}else{

 

ExcelBizImporter.numLock.lock();

int succ = ExcelBizImporter.importResultNums.get(imLogId)[0]+ExcelBizImporter.importResultNums.get(imLogId)[1];

int failRe=ExcelBizImporter.importResultNums.get(imLogId)[2];

String successMsg = "成功导入" + ExcelBizImporter.importResultNums.get(imLogId)[0] + "条数据," + importDataEn.getImportType().name

           + ExcelBizImporter.importResultNums.get(imLogId)[1] + "条数据";

ExcelBizImporter.numLock.unlock();

int actuRowNum=dataRowNum-ExcelBizImporter.emptyRowNum.get(importLog.getId());

if (succ<actuRowNum) {

if ((succ+failRe)<1 && dataRowNum>0){

errorCells.add(new ErrorRow(new String[]{""},new Integer[]{1},"模板数据有问题,请重新下载模板来填写数据!"));

}

writeErrorLog(errorCells, importLog, datas); // add errorLog

importLog.setMsg(successMsg + ",失败 " + failRe + " 条,失败请查看日志");

} else {

importLog.setMsg(successMsg);

}

tempFileManager.removeTempFile(importLog.getImportfile());

ImportManagerImpl.conMap.remove(importLog.getId());

ImportManagerImpl.leadsMap.remove(importLog.getId());

ImportManagerImpl.custNamesMap.remove(importLog.getId());

ImportManagerImpl.custMap.remove(importLog.getId());

}

 

importLog.setCompletiondate(new Date());

baseDao.update(importLog);

baseDao.flush();

cacheValue.get().clear();

newItemCache.get().clear();

}

 

private void writeErrorLog(List<ErrorRow> errorCells, ImportLog importLog, Map<String, String> datas) {

int totalNum = datas.size();

HSSFWorkbook wb = new HSSFWorkbook();

Modules modules = Modules.getByType(importLog.getImporttype());

// createHeaderByTableName(wb, modules.tableName, true);

createHeaderByCurrentData(wb, modules.tableName, datas);

Sheet sheet = wb.getSheetAt(0);

int rowNum = 1;

for (ErrorRow errorCell : errorCells) {

Row row = sheet.createRow(rowNum);

String[] errorDatas = errorCell.getData();

Integer[] indexs = errorCell.getDataIndex();

 

if (datas != null) {

for (int i = 0; i < errorDatas.length; i++) {

if (indexs[i] != null) {

Cell cell = row.createCell(indexs[i]);

cell.setCellType(Cell.CELL_TYPE_STRING);

cell.setCellValue(errorDatas[i]);

}

}

}

Cell lastCell = row.createCell(totalNum + 1);

WorkBookUtils.setRedCellValue(wb, lastCell, errorCell.getErrorMsg());

rowNum++;

}

try {

logger.info("------------开始去写错误日志了");

saveWb(wb, importLog);

logger.info("------------完成写错误日志了");

} catch (Exception e) {

logger.error("写入错误日志失败", e);

}

}

 

private static String getFileOutDir() {

DateTime dateTime = new DateTime();

StringBuffer sb = new StringBuffer();

char s = File.separatorChar;

sb.append(SecurityUtils.getTenantId()).append(s);

sb.append(ERROR_FOLDER).append(s).append(dateTime.toString("yyyy" + s + "M" + s + "d" + s));

logger.info("-----------上传的路径是:"+sb.toString());

return sb.toString();

}

 

private String saveWb(Workbook sb, ImportLog importLog) throws Exception {

String logFile = getFileOutDir();

String outPutDir = Env.getInstatnce().getConfigProperty("fileserver.path") + getFileOutDir();

logger.info("------------outPutDir 是:"+outPutDir);

File outPutFile = new File(outPutDir);

logger.info("------------outPutFile 是:"+outPutFile);

if (!outPutFile.exists()) {

outPutFile.mkdirs();

logger.info("------------outPutFile不存在,所以 創建一個文件"+outPutFile);

}

String fileName = importLog.getImportfile() + "_error.xls";

String fileUrl = outPutDir + fileName;

importLog.setLogfile(logFile + fileName);

FileOutputStream fileOutputStream = new FileOutputStream(fileUrl);

sb.write(fileOutputStream);

fileOutputStream.close();

return fileUrl;

}

 

private List<String> createHeaderByTableName(Workbook wb, String tableName) {

return createHeaderByTableName(wb, tableName, false);

}

 

protected List<DefinedFeild> addOtherHeads(List<DefinedFeild> listDefinedFeild) {

return listDefinedFeild;

}

private List<String> createHeaderByTableName(Workbook wb, String tableName, boolean errorLog) {

List<DefinedFeild> definedFeilds = uiSetting.getModelDefineField(tableName);

clearFields(definedFeilds);

if(tableName.equals(Modules.LEADS.tableName)){//线索导入时 负责人 列删除

clearSpeFields(definedFeilds,"ownerId");

clearSpeFields(definedFeilds,"country");

clearSpeFields(definedFeilds,"deptName");

clearSpeFields(definedFeilds,"tag");    //删除  是否转为客户

clearSpeFields(definedFeilds,"followPeriod");    //总跟进时长

clearSpeFields(definedFeilds,"closeReason");    //关闭原因

clearSpeFields(definedFeilds,"distributeStatus");    //分配状态

clearSpeFields(definedFeilds,"distributeDate");    //最近跟进时长

clearSplit(definedFeilds,"splitline");

}

 

if(tableName.equals(Modules.CUSTOMER.tableName)){//客户导入时 负责人 列删除

 

//

 

clearSpeFields(definedFeilds,"deptName");

clearSpeFields(definedFeilds,"district");

clearSplit(definedFeilds,"splitline");

 

}

//如果下载的模板是联系人,则在表格里最后加一 栏 "客户池",是必填栏

if(tableName.equals(Modules.CONTACT.tableName)){

clearSpeFields(definedFeilds,"ownerId");

clearSplit(definedFeilds,"splitline");

/*String s = systemProfileManager.getSystemProfileNoCache(SecurityUtils.getTenantId(), "customerPool", "activated");

//如果开启公海,则excel 增加 客户池

if ("Y".equals(s)){

DefinedFeild definedFeild=new DefinedFeild();

definedFeild.setField_label("客户池");

definedFeild.setIs_mandatory(true);

definedFeild.setMapping_field_name("cust_pool");

definedFeilds.add(definedFeild);

}*/

}

if(tableName.equals(Modules.USER.tableName)){

definedFeilds = addOtherHeads(definedFeilds);

 

}

 

Sheet sh = wb.createSheet();

sh.setAutobreaks(true);

sh.setDefaultColumnWidth(16);

List<String> headerName = null;

//单元格式

CellStyle style = wb.createCellStyle();

DataFormat fmt = wb.createDataFormat();

style.setDataFormat(fmt.getFormat("@"));

 

if (!errorLog) {

headerName = new ArrayList<String>();

}

for (int rownum = 0; rownum < 1; rownum++) {

Row row = sh.createRow(rownum);

int i = 0;

for (DefinedFeild definedFeild : definedFeilds) {

Cell cell = row.createCell(i);

String cellValue = definedFeild.getField_label();

//设置 销售线索  公司电话,公司传真,电话 的格式是文本格式

if (!errorLog && tableName.equals(Modules.LEADS.tableName)){

String fieldName = definedFeild.getMapping_field_name();

if (fieldName!=null && (fieldName.equals("compTel") || fieldName.equals("compFax") || fieldName.equals("tel"))){

sh.setDefaultColumnStyle(i,style);

}

}

 

//设置 联系人  公司电话,传真 的格式是文本格式

if (!errorLog && tableName.equals(Modules.CONTACT.tableName)){

String fieldName = definedFeild.getMapping_field_name();

if (fieldName!=null && (fieldName.equals("tel") || fieldName.equals("fax"))){

sh.setDefaultColumnStyle(i,style);

}

}

 

if (!errorLog){

String fieldName = definedFeild.getMapping_field_name();

if (fieldName!=null && (fieldName.equals("name") || fieldName.equals("compName")

|| fieldName.equals("customerName") || fieldName.equals("cust_id"))){

sh.setDefaultColumnStyle(i,style);

}

}

 

if (definedFeild.getIs_mandatory()) {// 必填

WorkBookUtils.setRedCellValue(wb, cell, cellValue);

WorkBookUtils.addCommentCell(cell, "此列数据必填", wb, sh);

} else {

cell.setCellValue(cellValue);

}

i++;

if (!errorLog) {

headerName.add(definedFeild.getMapping_field_name());

}

}

if (errorLog) {

Cell cell = row.createCell(i + 1);

WorkBookUtils.setRedCellValue(wb, cell, "错误原因");

}

}

return headerName;

}

 

private void clearSpeFields(List<DefinedFeild> definedFeilds,String ... mapNames){

for(int i=0;i<definedFeilds.size();i++){

DefinedFeild df = definedFeilds.get(i);

for(String name : mapNames){

if(name.equals(df.getMapping_field_name())){

definedFeilds.remove(i);

}

}

}

}

 

private void clearSplit(List<DefinedFeild> definedFeilds,String ... fieldType){

List<DefinedFeild> needRemoveList = new ArrayList<DefinedFeild>();

for (int i = 0; i < definedFeilds.size(); i++) {

DefinedFeild df = definedFeilds.get(i);

for (String name : fieldType) {

if (name.equals(df.getField_type())) {

// definedFeilds.remove(i);

// update by 6031 修复过滤分割线问题

needRemoveList.add(definedFeilds.get(i));

}

}

}

definedFeilds.removeAll(needRemoveList);

}

 

/**

* 过滤不需要输出的字段

* @param definedFields

*/

private void clearFields(List<DefinedFeild> definedFields) {

Set<String> displayField = this.getDisplayNames(); // 不需要输出的字段集合

if (!displayField.isEmpty()) {

List<DefinedFeild> displayFields = new ArrayList<DefinedFeild>();

for (DefinedFeild field : definedFields) {

if (!(field.isIs_updateable() && StringUtils.isNotBlank(field.getField_label()) && !displayField

.contains(field.getMapping_field_name()))) {

displayFields.add(field);

}

}

definedFields.removeAll(displayFields);

}

}

 

public void exportTemplete(OutputStream outputStream, int type) throws IOException {

Modules modules = Modules.getByType(type);

Workbook wb = new HSSFWorkbook();

List<String> headerNames = createHeaderByTableName(wb, modules.tableName);

afterCreateHeaderSheet(wb, headerNames);

wb.write(outputStream);

outputStream.close();

}

 

protected void afterCreateHeaderSheet(Workbook wb, List<String> headerNames) {

Map<String, Object> initData = getInitData();

if (initData != null) {

Sheet sheet = wb.getSheetAt(0);

int lastRow = sheet.getLastRowNum();

Row row = sheet.createRow(lastRow + 1);

for (int i = 0, len = headerNames.size(); i < len; i++) {

String headerName = headerNames.get(i);

Cell cell = row.createCell(i);

Object data = initData.get(headerName);

if (data != null)

cell.setCellValue(String.valueOf(data));

}

}

}

 

/**

* 通过实际数据生成行首

* @param wb

* @param datas

*/

@SuppressWarnings("rawtypes")

private void createHeaderByCurrentData(Workbook wb, String tableName, Map<String, String> datas) {

Sheet sheet = wb.createSheet();

Row row = sheet.createRow(0);

 

List<DefinedFeild> definedFeilds = uiSetting.getModelDefineField(tableName);

List<String> required = new ArrayList<String>();

for (DefinedFeild field : definedFeilds) {

if (field.getIs_mandatory()) {

required.add(field.getField_label());

}

}

 

Set<String> keys = datas.keySet();

int i = 0;

for (Iterator iterator = keys.iterator(); iterator.hasNext();) {

String idx = (String) iterator.next();

String cellValue = datas.get(idx);

Cell cell = row.createCell(Integer.parseInt(idx));

if (required.contains(cellValue)) {

WorkBookUtils.setRedCellValue(wb, cell, cellValue);

WorkBookUtils.addCommentCell(cell, "此列数据必填", wb, sheet);

} else {

cell.setCellValue(cellValue);

}

i++;

}

Cell cell = row.createCell(i + 1);

WorkBookUtils.setRedCellValue(wb, cell, "错误原因");

}

 

protected Set<String> getDisplayNames() {

Set<String> displayField = new HashSet<String>();

displayField.add("owner_id");

return displayField;

}

 

protected Long getDbValue(String name, long listId) {

String key = listId + "_" + name;

Map<String, Object> caMap = cacheValue.get();

Long dbValue = (Long) caMap.get(key);

if (dbValue == null) {

dbValue = listService.findByName(name, listId);

//if (dbValue == null) {

//// 新增一个类型

//ListItem listItem = new ListItem();

//listItem.setItemLabel(name);

//listItem.setListId(listId);

//listItem.setValid(true);

//listItem.setEditable(true);

//listItem.setDeletable(true);

//listItem.setDescn(name);

//listService.addListItem(listItem);

//dbValue = listItem.getId();

//newItemCache.get().put(key, dbValue);

//}

caMap.put(key, dbValue);

}

return dbValue;

}

 

}

 

 

/** 

 * Copyright (C) 2014 Winbons Technology Software Co.,Ltd

 * All Rights Reserved.

 * Development of this softwareWinbons Technology Software Co.,Ltd.

 * Without the formal written consent of the Company, 

 * any other individuals, groups may not use, 

 * copy, modify, or distribute this software

 * @Title: CustomerExcelImporter.java 

 * @Package saas.crm.customer.service 

 * @Description: TODO(用一句话描述该文件做什么) 

 * @author star.ye 

 * @date 2014年11月4日 上午11:24:23 

 * @version 1.0 

 */

 

package saas.crm.market.data.event;

 

import java.lang.reflect.Field;

import java.util.HashMap;

import java.util.HashSet;

import java.util.List;

import java.util.Map;

import java.util.Set;

import java.util.concurrent.ConcurrentHashMap;

import java.util.concurrent.locks.ReentrantLock;

import java.util.regex.Matcher;

import java.util.regex.Pattern;

 

import org.apache.commons.lang.StringUtils;

import org.apache.commons.lang.reflect.FieldUtils;

import org.apache.poi.ss.usermodel.Cell;

import org.apache.poi.ss.usermodel.CellStyle;

import org.apache.poi.ss.usermodel.DataFormat;

import org.apache.poi.ss.usermodel.Row;

import org.apache.poi.ss.usermodel.Sheet;

import org.apache.poi.ss.usermodel.Workbook;

import org.springframework.beans.factory.InitializingBean;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Component;

 

import saas.crm.base.uisetting.ICheckRepeatCache;

import saas.crm.base.uisetting.IComboxCache;

import saas.crm.base.uisetting.IDateTimeCache;

import saas.crm.base.uisetting.IListService;

import saas.crm.base.uisetting.IUISetting;

import saas.crm.base.utils.BeanUtils;

import saas.crm.base.utils.IPropertyFilter;

import saas.crm.customer.data.manager.ICustomerManager;

import saas.crm.customer.data.manager.ICustomerPoolManager;

import saas.crm.customer.manager.IPoolActivatedService;

import saas.crm.data.constant.Gender;

import saas.crm.data.constant.Tag;

import saas.crm.data.model.customer.CustomerContact;

import saas.crm.data.model.definition.DefinedFeild;

import saas.crm.data.model.leads.Leads;

import saas.crm.data.vo.ListItemVO;

import saas.crm.global.IExistChecker;

import saas.crm.importer.AbstractImportListener;

import saas.crm.importer.IBizImporter;

import saas.crm.importer.ImportManagerImpl;

import saas.crm.importer.ImportType;

import saas.crm.importer.Modules;

import saas.crm.market.enumtype.LeadsConstant;

import saas.crm.market.manager.ILeadsManager;

import saas.crm.security.service.IPermission;

import saas.framework.event.EventAPI;

import saas.framework.event.entity.PreSaveEvent;

import saas.framework.freemarker.ITempleteService;

import saas.framework.utils.SecurityUtils;

 

import com.alibaba.fastjson.JSON;

 

/**

 * @ClassName: CustomerExcelImporter

 * @Description: TODO(这里用一句话描述这个类的作用)

 * @author star.ye

 * @date 2014年11月4日 上午11:24:23

 */

@Component

public class LeadsImportListener extends AbstractImportListener implements InitializingBean {

 

private BeanUtils beanUtils = null;

 

private static Map<String, Object> testData = new HashMap<String, Object>();

 

private static final String INIT_TPL = "leads/initData.ftl";

 

@Autowired

private ITempleteService templeteService;

 

@Autowired

private IComboxCache comboxCache;

 

@Autowired

private IDateTimeCache dateTimeCache;

 

@Autowired

private ICustomerManager customerManager;

 

@Autowired

private IListService listService;

 

@Autowired

protected EventAPI publisher;

 

@Autowired

private ILeadsManager leadsManager;

 

@Autowired

private IPoolActivatedService poolActivatedService;

 

@Autowired

private ICustomerPoolManager customerPoolManager;

 

@Autowired

private IPermission permissionManager;

 

@Autowired

private IUISetting uISetting;

 

@Autowired

private ICheckRepeatCache checkRepeatCache;

 

@Autowired

private IExistChecker existChecker;

 

private static final Integer DEFAULT_POOL_DAY = 30;// 默认的公海过期天数与人数

 

private ReentrantLock lockLeads=new ReentrantLock();

 

 

public Map<String, Object> getInitData() {

return testData;

}

 

protected void afterSaveData(Long cusId) {

// CustomerShareAcl customerShareAcl = new CustomerShareAcl();

// customerShareAcl.setDbId(SecurityUtils.getTenantId());

// customerShareAcl.setSecureId(CrmContext.getCurrentOwnerId());

// customerShareAcl.setCustId(cusId);

// customerShareAcl.setReadable(true);

// customerShareAcl.setOwner(true);

// baseDao.getSession().merge(customerShareAcl);

}

 

/**

* 校验日期、时间格式

* @param type

* @param value

* @return

*/

private boolean vaildDTFormat(String type, String value){

if(StringUtils.isNotBlank(type)){

String rep = "";

if("time".equals(type)){

rep = "^(([0-1][0-9])|2[0-3]):[0-5][0-9]$";

} else if("date".equals(type)){

rep = "^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)$";

} else if("dt".equals(type)){

rep = "^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)\\s+(([0-1][0-9])|2[0-3]):[0-5][0-9]$";

}

if(StringUtils.isNotBlank(type)){

Pattern pattern = Pattern.compile(rep);

Matcher matcher = pattern.matcher(value);

return matcher.matches();

}

}

return false;

}

 

public Object convertEntity(String propertyName, Object value, Object data) throws Exception {

Object tempValue = null;

Field field_ = FieldUtils.getField(Leads.class, propertyName, true);

if (field_ != null) {

Class type = field_.getType();

tempValue = beanUtils.convert(value, type);

}

String fieldStr = checkRepeatCache.getRepeatFieldName("t_crm_leads");

if(fieldStr.indexOf(propertyName)>=0){

if(existChecker.checkNameIsExistByClazzName(tempValue, "Leads", propertyName)){

String label = checkRepeatCache.getRepeatFieldLabel("t_crm_leads", propertyName);

String errorMsg = label!=null?"【" + label + "】字段值重复,请修改!!":null;

throw new IllegalArgumentException(errorMsg);

}

}

if ("name".equals(propertyName)) {

if (value == null || StringUtils.isEmpty(value.toString())) {

throw new IllegalArgumentException("联系人名称不能为空");

}

}

 

if ("compTel".equals(propertyName) || "mobile".equals(propertyName) || "tel".equals(propertyName)) {

if (value != null) {

String rep = "^[0-9]*$";

Pattern pattern = Pattern.compile(rep);

Matcher matcher = pattern.matcher(String.valueOf(value));

   if (!matcher.matches()){

   String ss="";

   if ("compTel".equals(propertyName)){

   ss="公司电话";

   }

if ("mobile".equals(propertyName)){

ss="手机";    

}

if ("tel".equals(propertyName)){

ss="电话";

}

   throw new IllegalArgumentException(ss+"填写错误,只能填数字!");

   }

}

}

 

if (value != null) {

Long dbValue = null;

LeadsConstant leadsConstant = LeadsConstant.getConstant(propertyName);

if (leadsConstant != null) {

if("source".equals(propertyName)){

dbValue = getDbValue(value.toString(), leadsConstant.dbValue);// 校验一下重要属性的值

if (dbValue != null){

return super.convertEntity(propertyName, dbValue, data);

}else{

DefinedFeild field = uISetting.getDefineField("t_crm_leads", propertyName);

String fieldName = propertyName;

if(field!=null){

fieldName = field.getField_label();

}

throw new IllegalArgumentException("没有对应的【" + fieldName + "】的值【"+value.toString()+"】,请先在系统中新建这个下拉项值");

}

}

} else {

// 校验单选框的值

Long listId = comboxCache.getListId(propertyName, "t_crm_leads");

if (listId != null) {

dbValue = getDbValue(value.toString(), listId);

if (dbValue != null){

return super.convertEntity(propertyName, dbValue, data);

}else{

DefinedFeild field = uISetting.getDefineField("t_crm_leads", propertyName);

String fieldName = propertyName;

if(field!=null){

fieldName = field.getField_label();

}

throw new IllegalArgumentException("没有对应的【" + fieldName + "】的值【"+value.toString()+"】,请先在系统中新建这个下拉项值");

}

} else {

// 校验日期、时间类型的值

String format = dateTimeCache.getTypeByFiled(propertyName, "t_crm_leads");

if(format != null){

if(!vaildDTFormat(format, value.toString())){

value = "";

}

}

}

}

super.convertEntity(propertyName, dbValue, data);

}

if("gender".equals(propertyName)){

if("0".equals(value) || "男".equals(value) || "male".equals(value)){

value = Gender.male;

}else if("1".equals(value) || "女".equals(value) || "female".equals(value)){

value = Gender.female;

}

}

if("tag".equals(propertyName)){

if("0".equals(value) || "未转".equals(value)){

value = Tag.notturn;

}else if("1".equals(value) || "已转".equals(value)){

value = Tag.turn;

}

}

if("status".equals(propertyName)){

if("未处理".equals(value)){

value = 0;

}else if("已联系".equals(value)){

value = 1;

}else if("关闭".equals(value)){

value = 2;

}

}

return super.convertEntity(propertyName, value, data);

}

 

public void afterPropertiesSet() throws Exception {

beanUtils = new BeanUtils(null);

beanUtils.addPropertyFilter(new IPropertyFilter() {

public boolean filter(String name, Object value) {

if (value == null) {

return true;

}

return false;

}

});

initTestData();

}

 

private synchronized void initTestData() {

String jsonString = templeteService.processTemplateIntoString(INIT_TPL, null);

testData.putAll(JSON.parseObject(jsonString));

}

 

public String getModuleName() {

return Modules.LEADS.name();

}

 

public String getEntityClassName() {

return Leads.class.getName();

}

 

public int onSaveData(Object data, ImportType importType, int index,Long importLogId) {

Leads leads = (Leads) data;

Leads dbLeads = null;

//List<Leads> leadsList = leadsManager.getRepeatLeadsByCompName(leads.getCompName());

 

//如果 是导入线索,则导入前,先把同一用户的公司名称缓存起来,以备有重复的公司名称时,可以直接代替更新(如果在导入过程中一条一条的更新,发现影响导入速度比较大)

HashMap<Long,ConcurrentHashMap<String,Leads>> leadsMap=ImportManagerImpl.leadsMap;

Long userId=SecurityUtils.getUserId();

if (leadsMap.get(importLogId)==null){

lockLeads.lock();

try{

if (leadsMap.get(importLogId)==null){

List<Leads> dbLeadsList=leadsManager.getLeadsByCompNameOwnerId(ImportManagerImpl.custNamesMap.get(importLogId),userId);

ConcurrentHashMap<String,Leads> hashMapCon=new ConcurrentHashMap<String,Leads>();

if (dbLeadsList!=null && !dbLeadsList.isEmpty()){

for (Leads con: dbLeadsList){

hashMapCon.put(con.getCompName(), con);

}

}

leadsMap.put(importLogId, hashMapCon);

}

} finally {

lockLeads.unlock();

}

}

 

ConcurrentHashMap<String,Leads> dbList=leadsMap.get(importLogId);

if (dbList!=null && dbList.get(leads.getCompName())!=null){

dbLeads=dbList.get(leads.getCompName());

}

 

int result = 1;

 

/** 设置地理位置信息 */

boolean isSave = true;// 是否为新增操作

if(dbLeads != null){

isSave = false;

}

 

//默认 负责人 为本用户

leads.setOwnerId(SecurityUtils.getUserId());

 

// 如果导入的数据与原数据poolId一致,再判断是否覆盖;否则直接保存

if (dbLeads != null) {

if (ImportType.COVER.equals(importType)) {

try {

beanUtils.copyProperties(dbLeads, leads);

} catch (Exception e) {

result = -1;

logger.error("copy customer error", e);

}

if(result != -1){

PreSaveEvent preSaveEvent = new PreSaveEvent(dbLeads, false);

publisher.publishEvent(preSaveEvent);

 

baseDao.update(dbLeads);

result=0;

}

}else if(ImportType.JUMP.equals(importType)){

result = 0;

return result;

}

} else {

leadsManager.save(leads);

dbList.put(leads.getCompName(), leads);

}

return result;

}

 

protected void afterCreateHeaderSheet(Workbook wb, List<String> headerNames) {

super.afterCreateHeaderSheet(wb, headerNames);

// 销售线索来源

for (LeadsConstant leadsConstant : LeadsConstant.values()) {

createDescSheet(wb, leadsConstant.title, leadsConstant.dbValue);

}

}

 

private void createDescSheet(Workbook wb, String title, long id) {

Sheet sheet = wb.createSheet(title + IBizImporter.DESC_SHEET);

sheet.setVerticallyCenter(true);

Row row = null;

Cell cell = null;

ListItemVO[] listItemVOs = null;

if(id==9999L && title.equals("性别")){

listItemVOs = new ListItemVO[2];

listItemVOs[0] = new ListItemVO(0,"男");

listItemVOs[1] = new ListItemVO(1,"女");

}else if(id==9998L && title.equals("转换状态")){

listItemVOs = new ListItemVO[2];

listItemVOs[0] = new ListItemVO(0,"未转");

listItemVOs[1] = new ListItemVO(1,"已转");

}else if(id==9997L && title.equals("跟进状态")){

listItemVOs = new ListItemVO[3];

listItemVOs[0] = new ListItemVO(0,"未处理");

listItemVOs[1] = new ListItemVO(1,"已联系");

listItemVOs[2] = new ListItemVO(2,"关闭");

}else {

listItemVOs = listService.findByListId(id);

}

 

// 设置单元格格式为文本格式

CellStyle style = wb.createCellStyle();

DataFormat fmt = wb.createDataFormat();

style.setDataFormat(fmt.getFormat("@"));

 

for (int i = 0; i < listItemVOs.length; i++) {

row = sheet.createRow(i);

cell = row.createCell(0);

cell.setCellStyle(style);

cell.setCellValue(listItemVOs[i].getLable());

}

}

 

@Override

protected Set<String> getDisplayNames() {

Set<String> displayField = new HashSet<String>();

displayField.add("owner_id");

displayField.add("firstContact");

displayField.add("pictureLocation");

displayField.add("valid");

displayField.add("deptId");

if(!poolActivatedService.isOpen()){

displayField.add("cust_pool");

}

return displayField;

}

 

 

}

 

 

 

 

/** 

 * Copyright (C) 2014 Winbons Technology Software Co.,Ltd

 * All Rights Reserved.

 * Development of this softwareWinbons Technology Software Co.,Ltd.

 * Without the formal written consent of the Company, 

 * any other individuals, groups may not use, 

 * copy, modify, or distribute this software

 * @Title: ImportListenerManagerImpl.java 

 * @Package saas.crm.importer 

 * @Description: TODO(用一句话描述该文件做什么) 

 * @author star.ye 

 * @date 2014年11月7日 上午9:16:06 

 * @version 1.0 

 */

 

package saas.crm.importer;

 

import java.util.Map;

import java.util.concurrent.ConcurrentHashMap;

 

import org.springframework.beans.BeansException;

import org.springframework.beans.factory.config.BeanPostProcessor;

import org.springframework.stereotype.Component;

 

/**

 * @ClassName: ImportListenerManagerImpl

 * @Description: TODO(这里用一句话描述这个类的作用)

 * @author star.ye

 * @date 2014年11月7日 上午9:16:06

 */

@Component

public class ImportListenerManagerImpl implements ImporterListenerManager, BeanPostProcessor {

 

private Map<String, ImportListener> importMap = new ConcurrentHashMap<String, ImportListener>();

 

public ImportListener getImporterListener(String moduleName) {

return importMap.get(moduleName);

}

 

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

return bean;

}

 

public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

if (bean instanceof ImportListener) {

ImportListener importListener = (ImportListener) bean;

importMap.put(importListener.getModuleName(), importListener);

}

return bean;

}

 

}

 

 

分享到:
评论

相关推荐

    spring ioc

    在本文中,我们将深入探讨 Spring IOC 的概念、工作原理以及如何在实际项目中应用。 首先,理解 IOC 的概念至关重要。IOC 是一种设计模式,它将对象的创建和管理权反转,由框架负责管理对象的生命周期,而不是由...

    Spring 5 Design Patterns

    Spring的BeanPostProcessor接口提供了一个适配器机制,允许开发者在bean初始化前后插入自定义逻辑,使得不同的组件能够相互协作。 以上只是Spring 5中设计模式的部分应用,实际上Spring框架充分利用了各种设计模式...

    Spring-Reference_zh_CN(Spring中文参考手册)

    12.2.2. 在Spring的application context中创建 SessionFactory 12.2.3. HibernateTemplate 12.2.4. 不使用回调的基于Spring的DAO实现 12.2.5. 基于Hibernate3的原生API实现DAO 12.2.6. 编程式的事务划分 12.2.7. ...

    spring5.0.2中文官网文档

    例如,可以通过实现BeanPostProcessor接口来对Bean进行额外的处理,或者通过实现ApplicationContextInitializer接口来在ApplicationContext启动前执行自定义操作。 针对Bean的配置,Spring支持多种方式。基于注解的...

    Spring系列面试题129道(附答案解析)

    在Spring中可以通过在XML配置文件中添加context命名空间并声明注解驱动元素,或者使用Java配置类上的注解(如@ComponentScan)来启动注解装配。 27、@Component,@Controller,@Repository,@Service有何区别? 这些...

    springAOP核心组件分析

    本知识点将围绕Spring AOP的核心组件进行分析,尤其是AnnotationAwareAspectJAutoProxyCreator类的作用,以及BeanPostProcessor接口在创建AOP代理中的角色。 首先,AnnotationAwareAspectJAutoProxyCreator是Spring...

    SPRING中文开发参考手册

    - **BeanPostProcessor**:可以在 Bean 初始化前后执行自定义逻辑。 ##### 3.6 使用 BeanFactoryPostprocessors 定制 Bean 工厂 - **BeanFactoryPostProcessor**:可以在 BeanFactory 初始化之后修改 Bean 的定义...

    Spring Reference - Core Technologies.pdf

    Spring框架允许开发者扩展容器行为,这包括自定义BeanPostProcessor、BeanFactoryPostProcessor等。 在Spring框架的学习和应用中,开发者需要深刻理解这些核心知识点,只有这样,才能充分利用Spring提供的强大功能...

    Spring 框架的设计理念与设计模式分析

    Bean在Spring中扮演着中心角色,如同OOP中的对象。Spring通过IoC容器管理Bean之间的依赖关系,实现了代码解耦和模块化。IoC容器(也称为依赖注入容器)通过配置文件或注解来定义Bean及其依赖,使得在运行时动态地...

    spring源码代码

    Spring 的核心特性之一是依赖注入,它允许开发者在运行时通过容器来管理对象及其依赖关系,而不是在代码中硬编码。这提高了代码的可测试性和可维护性,因为对象的创建和组装过程被解耦。 2. **Bean 容器(Bean ...

    Spring5.0中文开发手册

    - BeanPostProcessor接口允许开发者在bean初始化前后执行自定义操作。 - **3.8.2 使用BeanFactoryPostProcessor定制配置元数据** - 可以修改Spring容器中的bean定义。 - **3.8.3 使用FactoryBean定制实例化逻辑*...

    Spring容器 .ppt

    DI是Spring的核心特性,允许在运行时动态地将依赖关系注入到对象中,而不是由对象自行查找或创建。这使得代码更易于测试和维护,降低了组件之间的耦合度。 4. **Bean的范围** - Singleton:默认的Bean范围,...

    Spring 2.0 开发参考手册

    6.8.1. 在Spring中使用AspectJ来为domain object进行依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来配置AspectJ的切面 6.8.4. 在Spring应用中使用AspectJ Load-time weaving(LTW) 6.9. ...

    spring依赖注入的实现原理

    5. **BeanPostProcessor**:提供了在bean初始化前后进行自定义处理的机会,可以用来进行依赖注入的补充工作。 五、实战应用 在实际开发中,我们可以结合注解驱动和XML配置来实现依赖注入。例如,使用`@Autowired`...

    Spring中文帮助文档

    6.8.1. 在Spring中使用AspectJ进行domain object的依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来配置AspectJ的切面 6.8.4. 在Spring应用中使用AspectJ加载时织入(LTW) 6.9. 更多资源 7...

    spring chm文档

    6.8.4. 在Spring应用中使用AspectJ Load-time weaving(LTW) 6.9. 其它资源 7. Spring AOP APIs 7.1. 简介 7.2. Spring中的切入点API 7.2.1. 概念 7.2.2. 切入点实施 7.2.3. AspectJ切入点表达式 7.2.4. ...

    Spring Key tutorial PDF

    - **示例**:实现 BeanPostProcessor 接口,并重写 postProcessBeforeInitialization 和 postProcessAfterInitialization 方法来修改 bean 的行为。 #### Spring Bean 定义继承 Bean 定义也可以支持继承,子 bean ...

    Spring API

    6.8.1. 在Spring中使用AspectJ进行domain object的依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来配置AspectJ的切面 6.8.4. 在Spring应用中使用AspectJ加载时织入(LTW) 6.9. 更多资源 7...

Global site tag (gtag.js) - Google Analytics