Browse Source

[会员列表][修改]: 并发导入数据不成功问题修复

release_toaliyun_real
Stormeye Wu 7 years ago
parent
commit
e3713377ad
4 changed files with 196 additions and 183 deletions
  1. +90
    -3
      mallinkAdmin/src/main/java/com/iformall/controller/WxCUserBasicInfoController.java
  2. +3
    -3
      mallinkService/src/main/java/com/iformall/service/WxCUserBasicInfoService.java
  3. +98
    -175
      mallinkService/src/main/java/com/iformall/service/impl/WxCUserBasicInfoServiceImpl.java
  4. +5
    -2
      mallinkService/src/main/java/com/iformall/service/impl/WxMerchantServiceImpl.java

+ 90
- 3
mallinkAdmin/src/main/java/com/iformall/controller/WxCUserBasicInfoController.java View File

@@ -1,5 +1,10 @@
package com.iformall.controller;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;
import cn.afterturn.easypoi.handler.impl.ExcelDataHandlerDefaultImpl;
import cn.afterturn.easypoi.handler.inter.IExcelDataHandler;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
@@ -8,14 +13,19 @@ import com.iformall.common.ErrorCode;
import com.iformall.common.Result;
import com.iformall.common.ResultData;
import com.iformall.domain.po.*;
import com.iformall.domain.vo.CUserBaseInfoT;
import com.iformall.enums.EnumAssignTagsTrigger;
import com.iformall.exception.MallinkException;
import com.iformall.service.*;
import com.iformall.service.impl.WxCUserBasicInfoServiceImpl;
import com.iformall.shiro.UserSession;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -57,7 +67,10 @@ public class WxCUserBasicInfoController extends BaseController {
private WxCouponService wxCouponService;

@Autowired
WxLevelConfigService wxLevelConfigService;
private WxLevelConfigService wxLevelConfigService;

@Autowired
private WxTagsService wxTagsService;

@Autowired
StringRedisTemplate stringRedisTemplate;
@@ -252,6 +265,18 @@ public class WxCUserBasicInfoController extends BaseController {

}

private class UserExcelHandler extends ExcelDataHandlerDefaultImpl<CUserBaseInfoT> {
@Override
public Object importHandler(CUserBaseInfoT obj, String name, Object value) {
if (value == null) {
value = "";
}
System.out.println(name + " + " + value.toString());
return super.importHandler(obj, name, value);
}

}

@RequestMapping("/importTemplate")
public ResultData importTemplate(@RequestParam("file") MultipartFile file) {
logger.debug("[" + getIpAddr() + "] WxCUserBasicInfoController::importTemplate");
@@ -259,7 +284,8 @@ public class WxCUserBasicInfoController extends BaseController {
throw new MallinkException(Result.ERROR, "上传文件不能为空");
}
//得到当前用户ID
String userId = "" + getUser().getId();
final MallUserInfo user = getUser();
String userId = "" + user.getId();
String importKey = importMemPrev + userId;
//查询当前用户得到的值是否为空,为空继续,不为空,返回模板正在导入
Boolean allCount = stringRedisTemplate.opsForHash().hasKey(importKey, "allCount");
@@ -270,7 +296,68 @@ public class WxCUserBasicInfoController extends BaseController {
stringRedisTemplate.opsForHash().putIfAbsent(importKey, "allSuccessCount", 0 + "");
stringRedisTemplate.opsForHash().putIfAbsent(importKey, "processCount", "");
stringRedisTemplate.opsForHash().putIfAbsent(importKey, "failCount", "");
wxCUserBasicInfoService.importTemplate(file, getTenantId(), importKey);


ImportParams params = new ImportParams();
// 需要验证
params.setImportFields(new String[]{"姓名", "性别", "手机号", "微信昵称", "学历", "生日", "地址", "上次活跃时间", "注册时间", "标签", "成长值"});
IExcelDataHandler<CUserBaseInfoT> handler = new UserExcelHandler();
handler.setNeedHandlerFields(new String[] { "手机号" });
params.setNeedVerify(true);

ExcelImportResult<CUserBaseInfoT> datalist = null;
try {
datalist = ExcelImportUtil.importExcelMore(file.getInputStream(), CUserBaseInfoT.class, params);
} catch (Exception e) {
stringRedisTemplate.opsForHash().put(importKey, "allCount", "1");
stringRedisTemplate.opsForHash().put(importKey, "allSuccessCount", "0");
stringRedisTemplate.opsForHash().put(importKey, "processCount", "0");
stringRedisTemplate.opsForHash().put(importKey, "failCount", "1");
logger.error(e.getMessage());
return new ResultData(ErrorCode.MEM_IMPORT_ERR);
}

if(datalist == null) {
logger.error("导入模板失败: 模板数据解析失败");
return new ResultData(ErrorCode.MEM_IMPORT_ERR);
}

List<CUserBaseInfoT> successList = datalist.getList();
List<CUserBaseInfoT> failList = datalist.getFailList();

int total = successList.size() + failList.size();
int all_success = successList.size();
int all_fail = failList.size();

//添加到redis里
stringRedisTemplate.opsForHash().put(importKey, "allCount", "" + total);
stringRedisTemplate.opsForHash().put(importKey, "allSuccessCount", "" + all_success);
stringRedisTemplate.opsForHash().put(importKey, "processCount", "0");
stringRedisTemplate.opsForHash().put(importKey, "failCount", "" + all_fail);

logger.info("验证通过的数量: " + successList.size());
logger.info("验证未通过的数量: " + failList.size());

WxTags wxTagsQ = new WxTags();
List<WxTags> tagList = wxTagsService.findList(wxTagsQ);

final String tenantId = getTenantId();

try {
successList.parallelStream().forEach(uBase -> {
// 异步无法获取到原有的session,所以再注入一下session
Session session = SecurityUtils.getSubject().getSession();
session.setAttribute(UserSession.userInfo, user);
session.setAttribute(UserSession.userId, user.getId());
session.setAttribute(UserSession.tenantId, tenantId);

wxCUserBasicInfoService.importOneMem(tenantId, importKey, tagList, uBase);
});
} catch (Exception e) {
stringRedisTemplate.opsForHash().put(importKey, "allCount", "" + all_fail);
e.printStackTrace();
logger.error("导入模板失败:"+e.getMessage());
}
stringRedisTemplate.expire(importKey,30,TimeUnit.MINUTES);
return new ResultData(Result.SUCCESS, "模板正在导入");
}


+ 3
- 3
mallinkService/src/main/java/com/iformall/service/WxCUserBasicInfoService.java View File

@@ -1,10 +1,10 @@
package com.iformall.service;

import com.github.pagehelper.PageInfo;
import com.iformall.common.ResultData;
import com.iformall.domain.dto.WxCUserBasicInfoDto;
import com.iformall.domain.po.WxCUserBasicInfo;
import org.springframework.web.multipart.MultipartFile;
import com.iformall.domain.po.WxTags;
import com.iformall.domain.vo.CUserBaseInfoT;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -103,7 +103,7 @@ public interface WxCUserBasicInfoService {

void exportTemplate(HttpServletRequest request, HttpServletResponse response, String tenantId);

ResultData importTemplate(MultipartFile file, String tenantId, String importKey);
void importOneMem(String tenantId, String importKey, List<WxTags> tagList, CUserBaseInfoT uBase);

long findCount(WxCUserBasicInfoDto dto);



+ 98
- 175
mallinkService/src/main/java/com/iformall/service/impl/WxCUserBasicInfoServiceImpl.java View File

@@ -1,16 +1,9 @@
package com.iformall.service.impl;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;
import cn.afterturn.easypoi.handler.impl.ExcelDataHandlerDefaultImpl;
import cn.afterturn.easypoi.handler.inter.IExcelDataHandler;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.iformall.common.ErrorCode;
import com.iformall.common.IdWorker;
import com.iformall.common.ResultData;
import com.iformall.domain.dto.WxCUserBasicInfoDto;
import com.iformall.domain.po.WxCUser;
import com.iformall.domain.po.WxCUserBasicInfo;
@@ -39,9 +32,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -498,194 +489,126 @@ public class WxCUserBasicInfoServiceImpl implements WxCUserBasicInfoService {
return userBase;
}

private class UserExcelHandler extends ExcelDataHandlerDefaultImpl<CUserBaseInfoT> {
@Override
public Object importHandler(CUserBaseInfoT obj, String name, Object value) {
if (value == null) {
value = "";
}
System.out.println(name + " + " + value.toString());
return super.importHandler(obj, name, value);
}

}

@Async
@Override
public ResultData importTemplate(MultipartFile file, String tenantId, String importKey) {

public void importOneMem(String tenantId, String importKey, List<WxTags> tagList, CUserBaseInfoT uBase) {
final IdWorker idWorker = IdWorker.get();

ImportParams params = new ImportParams();
// 需要验证
params.setImportFields(new String[]{"姓名", "性别", "手机号", "微信昵称", "学历", "生日", "地址", "上次活跃时间", "注册时间", "标签", "成长值"});
IExcelDataHandler<CUserBaseInfoT> handler = new UserExcelHandler();
handler.setNeedHandlerFields(new String[] { "手机号" });
params.setNeedVerify(true);

ExcelImportResult<CUserBaseInfoT> datalist = null;
try {
datalist = ExcelImportUtil.importExcelMore(file.getInputStream(), CUserBaseInfoT.class, params);
} catch (Exception e) {
stringRedisTemplate.opsForHash().put(importKey, "allCount", "1");
stringRedisTemplate.opsForHash().put(importKey, "allSuccessCount", "0");
stringRedisTemplate.opsForHash().put(importKey, "processCount", "0");
stringRedisTemplate.opsForHash().put(importKey, "failCount", "1");
logger.error(e.getMessage());
return new ResultData(ErrorCode.MEM_IMPORT_ERR);
if (StringUtils.isBlank(uBase.getPhone())) {
stringRedisTemplate.opsForHash().increment(importKey, "processCount", 1);
logger.error("手机号为空", uBase.toString());
return;
}

if(datalist == null) {
logger.error("导入模板失败: 模板数据解析失败");
return new ResultData(ErrorCode.MEM_IMPORT_ERR);
WxCUserBasicInfo userBase = InitUserBaseInfo(uBase, tenantId);
if (userBase == null) {
stringRedisTemplate.opsForHash().increment(importKey, "processCount", 1);
logger.error("userBase为null", uBase.toString());
return;
}

List<CUserBaseInfoT> successList = datalist.getList();
List<CUserBaseInfoT> failList = datalist.getFailList();

int total = successList.size() + failList.size();
int all_success = successList.size();
int all_fail = failList.size();

//添加到redis里
stringRedisTemplate.opsForHash().put(importKey, "allCount", "" + total);
stringRedisTemplate.opsForHash().put(importKey, "allSuccessCount", "" + all_success);
stringRedisTemplate.opsForHash().put(importKey, "processCount", "0");
stringRedisTemplate.opsForHash().put(importKey, "failCount", "" + all_fail);

logger.info("验证通过的数量: " + successList.size());
logger.info("验证未通过的数量: " + failList.size());

WxTags wxTagsQ = new WxTags();
List<WxTags> tagList = wxTagsMapper.findList(wxTagsQ);

try {
successList.parallelStream().forEach(uBase -> {
WxCUserBasicInfo oldUserBase = null;
WxCUserBasicInfo userBaseQ = new WxCUserBasicInfo();
userBaseQ.setTenantId(tenantId);
userBaseQ.setPhone(userBase.getPhone());
List<WxCUserBasicInfo> userBList = wxCUserBasicInfoMapper.select(userBaseQ);
if (userBList.size() > 0) {
oldUserBase = userBList.get(0);
}

if (StringUtils.isBlank(uBase.getPhone())) {
stringRedisTemplate.opsForHash().increment(importKey, "processCount", 1);
logger.error("手机号为空", uBase.toString());
return;
}
WxCUserBasicInfo userBase = InitUserBaseInfo(uBase, tenantId);
if (userBase == null) {
stringRedisTemplate.opsForHash().increment(importKey, "processCount", 1);
logger.error("userBase为null", uBase.toString());
return;
}
if (oldUserBase != null) {
oldUserBase.setName(userBase.getName());
oldUserBase.setSex(userBase.getSex());
oldUserBase.setNickName(userBase.getNickName());
oldUserBase.setEducation(userBase.getEducation());
oldUserBase.setBirthdate(userBase.getBirthdate());
oldUserBase.setAddress(userBase.getAddress());
oldUserBase.setUpdateDate(new Date());
oldUserBase.setCreateDate(userBase.getCreateDate());
} else {
userBase.setId(idWorker.nextId());
}

WxCUserBasicInfo oldUserBase = null;
WxCUserBasicInfo userBaseQ = new WxCUserBasicInfo();
userBaseQ.setTenantId(tenantId);
userBaseQ.setPhone(userBase.getPhone());
List<WxCUserBasicInfo> userBList = wxCUserBasicInfoMapper.select(userBaseQ);
if (userBList.size() > 0) {
oldUserBase = userBList.get(0);
}
// update 昵称
{
// check c_user 是否存在
WxCUser cUserQ = new WxCUser();
cUserQ.setTenantId(tenantId);
cUserQ.setPhone(userBase.getPhone());
List<WxCUser> userList = wxCUserMapper.select(cUserQ);
if (userList.size() > 0) {
WxCUser user = userList.get(0);
if (user != null) {
if (oldUserBase != null) {
if(oldUserBase != null) {
oldUserBase.setNickName(user.getNickName());
}
userBase.setId(user.getId());
userBase.setNickName(user.getNickName());
} else {

if (oldUserBase != null) {
oldUserBase.setName(userBase.getName());
oldUserBase.setSex(userBase.getSex());
oldUserBase.setNickName(userBase.getNickName());
oldUserBase.setEducation(userBase.getEducation());
oldUserBase.setBirthdate(userBase.getBirthdate());
oldUserBase.setAddress(userBase.getAddress());
oldUserBase.setUpdateDate(new Date());
oldUserBase.setCreateDate(userBase.getCreateDate());
} else {
userBase.setId(idWorker.nextId());
userBase.setNickName(user.getNickName());
}
}
}
}

// update 昵称
{
// check c_user 是否存在
WxCUser cUserQ = new WxCUser();
cUserQ.setTenantId(tenantId);
cUserQ.setPhone(userBase.getPhone());
List<WxCUser> userList = wxCUserMapper.select(cUserQ);
if (userList.size() > 0) {
WxCUser user = userList.get(0);
if (user != null) {
if (oldUserBase != null) {
if(oldUserBase != null) {
oldUserBase.setNickName(user.getNickName());
}
userBase.setId(user.getId());
userBase.setNickName(user.getNickName());
} else {

userBase.setNickName(user.getNickName());
}
if (oldUserBase != null) {
logger.info("update user base: " + oldUserBase.getId());
wxCUserBasicInfoMapper.updateByPrimaryKeySelective(oldUserBase);
} else {
logger.info("insert user base: " + userBase.getId());
try {
wxCUserBasicInfoMapper.insertSelective(userBase);
} catch (Exception e) {
stringRedisTemplate.opsForHash().increment(importKey, "processCount", 1);
logger.error(e.getMessage());
return;
}
}
// update tags
try {
if (StringUtils.isNotBlank(userBase.getTagNames())) {
// get tag ids
String tagNames = userBase.getTagNames();
List<Long> tagIdList = new ArrayList<>();
for (String tagName : tagNames.split("/")) {
for(WxTags tag: tagList) {
if(tagName.equals(tag.getName())) {
tagIdList.add(Long.valueOf(tag.getId()));
break;
}
}
}

if (oldUserBase != null) {
logger.info("update user base: " + oldUserBase.getId());
wxCUserBasicInfoMapper.updateByPrimaryKeySelective(oldUserBase);
} else {
logger.info("insert user base: " + userBase.getId());
try {
wxCUserBasicInfoMapper.insertSelective(userBase);
} catch (Exception e) {
stringRedisTemplate.opsForHash().increment(importKey, "processCount", 1);
logger.error(e.getMessage());
return;
}
if (oldUserBase != null){
wxCUserTagsService.assignTags(tagIdList,oldUserBase);
}else{
wxCUserTagsService.assignTags(tagIdList,userBase);
}
// update tags
try {
if (StringUtils.isNotBlank(userBase.getTagNames())) {
// get tag ids
String tagNames = userBase.getTagNames();
List<Long> tagIdList = new ArrayList<>();
for (String tagName : tagNames.split("/")) {
for(WxTags tag: tagList) {
if(tagName.equals(tag.getName())) {
tagIdList.add(Long.valueOf(tag.getId()));
break;
}
}
}

if (oldUserBase != null){
wxCUserTagsService.assignTags(tagIdList,oldUserBase);
}else{
wxCUserTagsService.assignTags(tagIdList,userBase);
}
}
}

//触发自动打标签
if (oldUserBase != null) {
wxCUserTagsService.triggerAssignTags(EnumAssignTagsTrigger.ASSIGN_TAGS_TRIGGER_IMPORT,oldUserBase);
}
else{
wxCUserTagsService.triggerAssignTags(EnumAssignTagsTrigger.ASSIGN_TAGS_TRIGGER_IMPORT,userBase);
}
//触发自动打标签
if (oldUserBase != null) {
wxCUserTagsService.triggerAssignTags(EnumAssignTagsTrigger.ASSIGN_TAGS_TRIGGER_IMPORT,oldUserBase);
}
else{
wxCUserTagsService.triggerAssignTags(EnumAssignTagsTrigger.ASSIGN_TAGS_TRIGGER_IMPORT,userBase);
}

// 成长值
if (StringUtils.isNotBlank(uBase.getPoins())) {
if (oldUserBase != null) {
wxScoreRulesService.addScore2(EnumScoreType.MEM_IMPORT, oldUserBase, uBase.getPoins());
} else {
wxScoreRulesService.addScore2(EnumScoreType.MEM_IMPORT, userBase, uBase.getPoins());
}
}
} catch (Exception e) {
logger.error(e.getMessage());
logger.error("打标签+成长值失败--继续导入");
// 成长值
if (StringUtils.isNotBlank(uBase.getPoins())) {
if (oldUserBase != null) {
wxScoreRulesService.addScore2(EnumScoreType.MEM_IMPORT, oldUserBase, uBase.getPoins());
} else {
wxScoreRulesService.addScore2(EnumScoreType.MEM_IMPORT, userBase, uBase.getPoins());
}

//记数
stringRedisTemplate.opsForHash().increment(importKey,"processCount",1);
});
}
} catch (Exception e) {
stringRedisTemplate.opsForHash().put(importKey, "allCount", "" + all_fail);
e.printStackTrace();
logger.error("导入模板失败:"+e.getMessage());
logger.error(e.getMessage());
logger.error("打标签+成长值失败--继续导入");
}

return new ResultData();
//记数
stringRedisTemplate.opsForHash().increment(importKey,"processCount",1);
}

@Override


+ 5
- 2
mallinkService/src/main/java/com/iformall/service/impl/WxMerchantServiceImpl.java View File

@@ -220,6 +220,7 @@ public class WxMerchantServiceImpl implements WxMerchantService {
wxMerchantShopMapper.updateByPrimaryKeySelective(wxMerchantShop);
//更新商铺状态
WxShop wxShop = new WxShop();
wxShop.setTenantId(wxMerchant.getTenantId());
wxShop.setId(wxMerchantShop.getShopId());
wxShop.setStatus(EnumShopStatus.NOT_RENT.getCode());
wxShopMapper.updateByPrimaryKeySelective(wxShop);
@@ -234,12 +235,14 @@ public class WxMerchantServiceImpl implements WxMerchantService {
}
//作废卡券
WxCouponMerchant wxCouponMerchant = new WxCouponMerchant();
wxCouponMerchant.setTenantId(wxMerchant.getTenantId());
wxCouponMerchant.setMerchantId(wxMerchant.getId());
wxCouponMerchant.setStatus(EnumCouponMerchantStatus.COUPON_MERCHANT_STATUS_VALID.getCode());
List<WxCouponMerchant> wxCouponMerchantList = wxCouponMerchantMapper.findList(wxCouponMerchant);
List<Long> couponIds = wxCouponMerchantList.stream().map(cm->cm.getProductId()).collect(Collectors.toList());
WxCoupon wxCoupon = new WxCoupon();
couponIds.parallelStream().filter(cid->!isCouponMerchantValid(cid)).forEach(cid->{

couponIds.stream().filter(cid->!isCouponMerchantValid(cid)).forEach(cid->{
WxCoupon wxCoupon = new WxCoupon();
wxCoupon.setId(cid);
wxCoupon.setStatus(EnumCouponStatus.COUPON_STATUS_TAKE_OFFF.getCode());
wxCouponService.saveOrUpdate(wxCoupon);


Loading…
Cancel
Save