在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 BeanPostProcessor接口使用详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
NULL 博文链接:https://747017186.iteye.com/blog/2370422
spring使用模板模式,在bean的创建过程中安插了许多锚点,用户寻找对应的锚点,通过重写方法介入到bean的创建过程当中。本节通过重写这些锚点,学习如何使用BeanPostProcessor、获取各类BeanAware并且理清bean的生命...
主要介绍了详解使用Spring的BeanPostProcessor优雅的实现工厂模式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
com-spring-ioc-demo:源码主要是学习Spring IOC的原理,以及对Bean的注册及控制,主要运用以下类对Spring进行扩展学习:BeanPostProcessor,BeanFactoryAware,BeanNameAware,ApplicationContextAware,FactoryBean...
1.3 Spring开闭原则的表现-BeanPostProcessor的扩展点-1 1.4 我对IoC/DI的理解 1.5 SpringMVC + spring3.1.1 + hibernate4.1.0 集成及常见问题总结 1.6 »Spring 之AOP AspectJ切入点语法详解(最全了,不需要再去...
spring的生命周期及BeanPostProcessor的使用,注解方式创建bean 及使用Autowried标签关联类的属性 ,泛型依赖注入的使用 spring-3 演示使用动态代理模式实现面向切面编程 使用注解方式进行AOP编程及使用配置xml方式...
通过spring 的BeanPostProcessor 将对象注入到spring之前创建一个代理对象注入到spring容器中,通过@autowired 注入的对象就是指定的代理对象内容
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. ...
第一个 Struts 程式 在 Struts 中整合 Spring 第一个 JSF 程式 在 JSF 中整合 Spring <br> 其它 Spring 提供了简化且一致的方式,让您在使用一些 API 或服务时更加简单。 远程...
主要介绍了Spring中的后置处理器BeanPostProcessor详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
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. ...
主要介绍了Java的Spring框架的BeanPostProcessor发布处理器,Spring是Java的SSH三大web开发框架之一,需要的朋友可以参考下
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...
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. ...
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还提供了扩展点(如BeanPostProcessor和InitializingBean接口),允许开发人员在Bean生命周期的不同阶段进行自定义操作。 AOP(面向切面编程)功能:Spring框架提供了AOP功能,通过切面(Aspect)来...
Spring JavaMailSenderImpl does not show proper message when recipient list is empty [SPR-17540] #22072 Potential resource leak in DataSourceUtils.doGetConnection [SPR-17559] #22091 SpEL, error parsing...
了解spring的加载机制 beanPostProcessor,beanFactoryPostProcessor 的使用 springmvc 的父子容器 aop切面说明 公司内部培训课件