| @@ -0,0 +1,115 @@ | |||||
| package com.iformall.controller.mem; | |||||
| 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.iformall.domain.po.MallUserInfo; | |||||
| import com.iformall.domain.vo.WxBillDailyVo; | |||||
| import com.iformall.service.WxBillDailyService; | |||||
| import org.apache.shiro.session.UnknownSessionException; | |||||
| 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.Component; | |||||
| import java.io.File; | |||||
| import java.util.List; | |||||
| import java.util.concurrent.TimeUnit; | |||||
| @Component | |||||
| public class BillDailyAsyncTask { | |||||
| private final Logger logger = LoggerFactory.getLogger(this.getClass()); | |||||
| @Autowired | |||||
| private WxBillDailyService wxBillDailyService; | |||||
| @Autowired | |||||
| StringRedisTemplate stringRedisTemplate; | |||||
| private class BillDailyExcelHandler extends ExcelDataHandlerDefaultImpl<WxBillDailyVo> { | |||||
| @Override | |||||
| public Object importHandler(WxBillDailyVo obj, String name, Object value) { | |||||
| if (value == null) { | |||||
| value = ""; | |||||
| } | |||||
| System.out.println(name + " + " + value.toString()); | |||||
| return super.importHandler(obj, name, value); | |||||
| } | |||||
| } | |||||
| private void set_redis_value(String importKey, String allCount, String allSuccessCount, String processCount, String failCount, boolean fail) { | |||||
| stringRedisTemplate.opsForHash().put(importKey, "allCount", allCount); | |||||
| stringRedisTemplate.opsForHash().put(importKey, "allSuccessCount", allSuccessCount); | |||||
| stringRedisTemplate.opsForHash().put(importKey, "processCount", processCount); | |||||
| stringRedisTemplate.opsForHash().put(importKey, "failCount", failCount); | |||||
| if (fail) { | |||||
| stringRedisTemplate.expire(importKey, 10, TimeUnit.SECONDS); | |||||
| } | |||||
| } | |||||
| @Async | |||||
| public void importExcelData(File file, MallUserInfo user, String importKey, String tenantId) { | |||||
| ImportParams params = new ImportParams(); | |||||
| // 需要验证 | |||||
| params.setImportFields(new String[]{"商铺号", "费用类型", "实际应收金额", "实收金额", "欠缴金额", "截止收款日期", "逾期天数"}); | |||||
| IExcelDataHandler<WxBillDailyVo> handler = new BillDailyAsyncTask.BillDailyExcelHandler(); | |||||
| handler.setNeedHandlerFields(new String[]{"商铺号", "费用类型", "实际应收金额", "实收金额", "欠缴金额", "截止收款日期", "逾期天数"}); | |||||
| params.setNeedVerify(true); | |||||
| ExcelImportResult<WxBillDailyVo> datalist = null; | |||||
| try { | |||||
| datalist = ExcelImportUtil.importExcelMore(file, WxBillDailyVo.class, params); | |||||
| } catch (Exception e) { | |||||
| set_redis_value(importKey, "1", "0", "0", "1", true); | |||||
| logger.error(e.getMessage()); | |||||
| // 删除缓存文件 | |||||
| file.delete(); | |||||
| return; | |||||
| } | |||||
| // 删除缓存文件 | |||||
| file.delete(); | |||||
| if (datalist == null) { | |||||
| logger.error("导入模板失败: 模板数据解析失败"); | |||||
| set_redis_value(importKey, "1", "0", "0", "1", true); | |||||
| return; | |||||
| } | |||||
| List<WxBillDailyVo> successList = datalist.getList(); | |||||
| List<WxBillDailyVo> failList = datalist.getFailList(); | |||||
| logger.info("验证通过的数量: " + successList.size()); | |||||
| logger.info("验证未通过的数量: " + failList.size()); | |||||
| int total = successList.size() + failList.size(); | |||||
| int all_success = successList.size(); | |||||
| int all_fail = failList.size(); | |||||
| //添加到redis里 | |||||
| set_redis_value(importKey, "" + total, "" + all_success, "0", "" + all_fail, total == all_fail); | |||||
| if (successList.size() > 0) { | |||||
| try { | |||||
| successList.parallelStream().forEach(billDaily -> { | |||||
| try { | |||||
| //插入数据 | |||||
| billDaily.setTenantId(tenantId); | |||||
| wxBillDailyService.insertData(billDaily, importKey, user); | |||||
| } catch (UnknownSessionException ue) { | |||||
| logger.error("session :" + ue.getMessage()); | |||||
| } | |||||
| }); | |||||
| } catch (Exception e) { | |||||
| set_redis_value(importKey, "1", "0", "0", "1", true); | |||||
| e.printStackTrace(); | |||||
| logger.error("导入模板失败:" + e.getMessage()); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -2,22 +2,33 @@ package com.iformall.controller.rent; | |||||
| import com.github.pagehelper.PageInfo; | import com.github.pagehelper.PageInfo; | ||||
| import com.iformall.annotation.SystemControllerLog; | import com.iformall.annotation.SystemControllerLog; | ||||
| import com.iformall.common.ErrorCode; | |||||
| import com.iformall.common.Result; | import com.iformall.common.Result; | ||||
| import com.iformall.common.ResultData; | import com.iformall.common.ResultData; | ||||
| import com.iformall.controller.base.BaseController; | import com.iformall.controller.base.BaseController; | ||||
| import com.iformall.controller.mem.BillDailyAsyncTask; | |||||
| import com.iformall.domain.po.MallUserInfo; | import com.iformall.domain.po.MallUserInfo; | ||||
| import com.iformall.domain.po.WxBillDaily; | import com.iformall.domain.po.WxBillDaily; | ||||
| import com.iformall.exception.MallinkException; | |||||
| import com.iformall.service.WxBillDailyService; | import com.iformall.service.WxBillDailyService; | ||||
| import com.iformall.utils.Constant; | |||||
| import io.swagger.annotations.ApiImplicitParam; | import io.swagger.annotations.ApiImplicitParam; | ||||
| import io.swagger.annotations.ApiImplicitParams; | import io.swagger.annotations.ApiImplicitParams; | ||||
| import org.slf4j.Logger; | import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.data.redis.core.StringRedisTemplate; | |||||
| import org.springframework.web.bind.annotation.*; | import org.springframework.web.bind.annotation.*; | ||||
| import org.springframework.web.multipart.MultipartFile; | |||||
| import javax.servlet.http.HttpServletRequest; | import javax.servlet.http.HttpServletRequest; | ||||
| import javax.servlet.http.HttpServletResponse; | import javax.servlet.http.HttpServletResponse; | ||||
| import java.io.BufferedInputStream; | |||||
| import java.io.File; | |||||
| import java.io.FileOutputStream; | |||||
| import java.io.IOException; | |||||
| import java.util.Map; | import java.util.Map; | ||||
| import java.util.concurrent.TimeUnit; | |||||
| /** | /** | ||||
| * @author gongbiao | * @author gongbiao | ||||
| @@ -28,6 +39,12 @@ public class WxBillDailyController extends BaseController { | |||||
| @Autowired | @Autowired | ||||
| private WxBillDailyService wxBillDailyService; | private WxBillDailyService wxBillDailyService; | ||||
| @Autowired | |||||
| StringRedisTemplate stringRedisTemplate; | |||||
| @Autowired | |||||
| private BillDailyAsyncTask billDailyAsyncTask; | |||||
| private Logger logger = LoggerFactory.getLogger(this.getClass()); | private Logger logger = LoggerFactory.getLogger(this.getClass()); | ||||
| @GetMapping("list") | @GetMapping("list") | ||||
| @@ -97,4 +114,88 @@ public class WxBillDailyController extends BaseController { | |||||
| } | } | ||||
| @PostMapping(value = "/importTemplate", consumes = "multipart/*") | |||||
| @SystemControllerLog(description = "会员管理-导入数据") | |||||
| public ResultData importTemplate(@RequestParam("file") MultipartFile mFile) { | |||||
| logger.debug("[" + getIpAddr() + "] WxCUserBasicInfoController::importTemplate"); | |||||
| if (mFile.isEmpty()) { | |||||
| throw new MallinkException(Result.ERROR, "上传文件不能为空"); | |||||
| } | |||||
| //得到当前用户ID | |||||
| final MallUserInfo user = getUser(); | |||||
| String userId = "bill_daily_" + user.getId(); | |||||
| String importKey = Constant.importMemPrev + userId; | |||||
| final String tenantId = getTenantId(); | |||||
| //查询当前用户得到的值是否为空,为空继续,不为空,返回模板正在导入 | |||||
| Boolean allCount = stringRedisTemplate.opsForHash().hasKey(importKey, "allCount"); | |||||
| if (allCount) { | |||||
| return new ResultData(Result.SUCCESS, "模板正在导入"); | |||||
| } | |||||
| stringRedisTemplate.opsForHash().putIfAbsent(importKey, "allCount", 0 + ""); | |||||
| stringRedisTemplate.expire(importKey, 30, TimeUnit.MINUTES); | |||||
| stringRedisTemplate.opsForHash().putIfAbsent(importKey, "allSuccessCount", 0 + ""); | |||||
| stringRedisTemplate.opsForHash().putIfAbsent(importKey, "processCount", ""); | |||||
| stringRedisTemplate.opsForHash().putIfAbsent(importKey, "failCount", ""); | |||||
| String fpath = Constant.fileDirectory; | |||||
| File targetFile = new File(fpath); | |||||
| if (!targetFile.exists()) { | |||||
| targetFile.mkdirs(); | |||||
| } | |||||
| String fileName = "bill_daily.xls"; | |||||
| int dot = mFile.getOriginalFilename().lastIndexOf('.'); | |||||
| fileName = fileName + mFile.getOriginalFilename().substring(dot, mFile.getOriginalFilename().length()); | |||||
| File lFile = new File(fpath + File.separator + fileName); | |||||
| FileOutputStream fos = null; | |||||
| BufferedInputStream fs = null; | |||||
| try { | |||||
| fos = new FileOutputStream(lFile); | |||||
| fs = (BufferedInputStream) mFile.getInputStream(); | |||||
| byte[] buffer = new byte[1024]; | |||||
| int len = 0; | |||||
| while ((len = fs.read(buffer)) != -1) { | |||||
| fos.write(buffer, 0, len); | |||||
| } | |||||
| fos.close(); | |||||
| fs.close(); | |||||
| } catch (Exception e) { | |||||
| stringRedisTemplate.expire(importKey, 3, TimeUnit.SECONDS); | |||||
| stringRedisTemplate.opsForHash().putIfAbsent(importKey, "allCount", "1"); | |||||
| stringRedisTemplate.opsForHash().putIfAbsent(importKey, "failCount", "1"); | |||||
| logger.error(e.getMessage()); | |||||
| return new ResultData(ErrorCode.MEM_IMPORT_ERR.getCode(), "模板上传失败"); | |||||
| } finally { | |||||
| if (fos != null) { | |||||
| try { | |||||
| fos.close(); | |||||
| } catch (IOException e) { | |||||
| stringRedisTemplate.expire(importKey, 3, TimeUnit.SECONDS); | |||||
| stringRedisTemplate.opsForHash().putIfAbsent(importKey, "allCount", "1"); | |||||
| stringRedisTemplate.opsForHash().putIfAbsent(importKey, "failCount", "1"); | |||||
| logger.error(e.getMessage()); | |||||
| return new ResultData(ErrorCode.MEM_IMPORT_ERR.getCode(), "模板上传失败"); | |||||
| } | |||||
| } | |||||
| if (fs != null) { | |||||
| try { | |||||
| fs.close(); | |||||
| } catch (IOException e) { | |||||
| stringRedisTemplate.expire(importKey, 3, TimeUnit.SECONDS); | |||||
| stringRedisTemplate.opsForHash().putIfAbsent(importKey, "allCount", "1"); | |||||
| stringRedisTemplate.opsForHash().putIfAbsent(importKey, "failCount", "1"); | |||||
| logger.error(e.getMessage()); | |||||
| return new ResultData(ErrorCode.MEM_IMPORT_ERR.getCode(), "模板上传失败"); | |||||
| } | |||||
| } | |||||
| } | |||||
| billDailyAsyncTask.importExcelData(lFile, user, importKey, tenantId); | |||||
| return new ResultData(Result.SUCCESS, "模板正在导入"); | |||||
| } | |||||
| } | } | ||||
| @@ -6,6 +6,9 @@ import com.iformall.domain.po.WxBillDaily; | |||||
| import javax.validation.constraints.NotNull; | import javax.validation.constraints.NotNull; | ||||
| /** | |||||
| * @author gongbiao | |||||
| */ | |||||
| public class WxBillDailyVo extends WxBillDaily { | public class WxBillDailyVo extends WxBillDaily { | ||||
| @Excel(name = "商铺号", width = 20, orderNum = "1") | @Excel(name = "商铺号", width = 20, orderNum = "1") | ||||
| @@ -4,6 +4,7 @@ import com.github.pagehelper.PageInfo; | |||||
| import com.iformall.common.ResultData; | import com.iformall.common.ResultData; | ||||
| import com.iformall.domain.po.MallUserInfo; | import com.iformall.domain.po.MallUserInfo; | ||||
| import com.iformall.domain.po.WxBillDaily; | import com.iformall.domain.po.WxBillDaily; | ||||
| import com.iformall.domain.vo.WxBillDailyVo; | |||||
| import javax.servlet.http.HttpServletRequest; | import javax.servlet.http.HttpServletRequest; | ||||
| import javax.servlet.http.HttpServletResponse; | import javax.servlet.http.HttpServletResponse; | ||||
| @@ -54,4 +55,6 @@ public interface WxBillDailyService { | |||||
| void exportTemplate(HttpServletRequest request, HttpServletResponse response, String tenantId); | void exportTemplate(HttpServletRequest request, HttpServletResponse response, String tenantId); | ||||
| void insertData(WxBillDailyVo billDaily, String importKey, MallUserInfo user); | |||||
| } | } | ||||
| @@ -6,21 +6,22 @@ import com.iformall.common.ErrorCode; | |||||
| import com.iformall.common.IdWorker; | import com.iformall.common.IdWorker; | ||||
| import com.iformall.common.Result; | import com.iformall.common.Result; | ||||
| import com.iformall.common.ResultData; | import com.iformall.common.ResultData; | ||||
| import com.iformall.domain.po.MallUserInfo; | |||||
| import com.iformall.domain.po.WxBillAction; | |||||
| import com.iformall.domain.po.WxBillDaily; | |||||
| import com.iformall.domain.po.WxShop; | |||||
| import com.iformall.domain.po.*; | |||||
| import com.iformall.domain.vo.WxBillDailyVo; | import com.iformall.domain.vo.WxBillDailyVo; | ||||
| import com.iformall.enums.*; | import com.iformall.enums.*; | ||||
| import com.iformall.exception.MallinkException; | import com.iformall.exception.MallinkException; | ||||
| import com.iformall.mapper.WxBillDailyMapper; | import com.iformall.mapper.WxBillDailyMapper; | ||||
| import com.iformall.mapper.WxMerchantShopMapper; | |||||
| import com.iformall.mapper.WxShopMapper; | import com.iformall.mapper.WxShopMapper; | ||||
| import com.iformall.service.ExcelService; | import com.iformall.service.ExcelService; | ||||
| import com.iformall.service.WxBillActionService; | import com.iformall.service.WxBillActionService; | ||||
| import com.iformall.service.WxBillDailyService; | import com.iformall.service.WxBillDailyService; | ||||
| import com.iformall.utils.DateUtils; | |||||
| import org.apache.commons.lang3.StringUtils; | |||||
| import org.slf4j.Logger; | import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.data.redis.core.StringRedisTemplate; | |||||
| import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||
| import org.springframework.transaction.annotation.Transactional; | import org.springframework.transaction.annotation.Transactional; | ||||
| @@ -28,6 +29,7 @@ import javax.servlet.http.HttpServletRequest; | |||||
| import javax.servlet.http.HttpServletResponse; | import javax.servlet.http.HttpServletResponse; | ||||
| import java.math.BigDecimal; | import java.math.BigDecimal; | ||||
| import java.util.*; | import java.util.*; | ||||
| import java.util.concurrent.TimeUnit; | |||||
| /** | /** | ||||
| * @author gongbiao | * @author gongbiao | ||||
| @@ -45,6 +47,10 @@ public class WxBillDailyServiceImpl implements WxBillDailyService { | |||||
| WxBillActionService wxBillActionService; | WxBillActionService wxBillActionService; | ||||
| @Autowired | @Autowired | ||||
| ExcelService excelService; | ExcelService excelService; | ||||
| @Autowired | |||||
| StringRedisTemplate stringRedisTemplate; | |||||
| @Autowired | |||||
| WxMerchantShopMapper wxMerchantShopMapper; | |||||
| @Override | @Override | ||||
| public PageInfo<Map<String, Object>> listAsPage(WxBillDaily record, Integer pageIndex, Integer pageSize) { | public PageInfo<Map<String, Object>> listAsPage(WxBillDaily record, Integer pageIndex, Integer pageSize) { | ||||
| //更新账单状态 | //更新账单状态 | ||||
| @@ -236,5 +242,104 @@ public class WxBillDailyServiceImpl implements WxBillDailyService { | |||||
| } | } | ||||
| @Override | |||||
| public void insertData(WxBillDailyVo billDaily, String importKey, MallUserInfo user) { | |||||
| String shopNumber = billDaily.getShopNumber(); | |||||
| if (StringUtils.isBlank(shopNumber)) { | |||||
| stringRedisTemplate.opsForHash().increment(importKey, "processCount", 1); | |||||
| logger.error("商铺号为空", billDaily.toString()); | |||||
| return; | |||||
| } | |||||
| //店铺 | |||||
| WxShop shop = new WxShop(); | |||||
| shop.setShopNumber(shopNumber); | |||||
| shop.setTenantId(billDaily.getTenantId()); | |||||
| shop.setStatus(EnumShopStatus.RENT.getCode()); | |||||
| shop.setIsDel(EnumDelStatus.NOT_DEL.getCode()); | |||||
| WxShop wxShop = wxShopMapper.selectOne(shop); | |||||
| if (wxShop == null) { | |||||
| stringRedisTemplate.opsForHash().increment(importKey, "processCount", 1); | |||||
| logger.error("商铺未找到", billDaily.toString()); | |||||
| return; | |||||
| } | |||||
| Integer type = billDaily.getType(); | |||||
| if (type != null && (type.equals(EnumBillDailyType.WATER.getCode()) || type.equals(EnumBillDailyType.POWER.getCode()))) { | |||||
| stringRedisTemplate.opsForHash().increment(importKey, "processCount", 1); | |||||
| logger.error("账单类型为空", billDaily.toString()); | |||||
| return; | |||||
| } | |||||
| String receivePayStr = billDaily.getReceivePayStr(); | |||||
| if (StringUtils.isBlank(receivePayStr)) { | |||||
| stringRedisTemplate.opsForHash().increment(importKey, "processCount", 1); | |||||
| logger.error("实际应收金额为空", billDaily.toString()); | |||||
| return; | |||||
| } | |||||
| double receivePayD = new BigDecimal(receivePayStr).doubleValue(); | |||||
| if (receivePayD <= 0) { | |||||
| stringRedisTemplate.opsForHash().increment(importKey, "processCount", 1); | |||||
| logger.error("实际应收金额小于等于0", billDaily.toString()); | |||||
| return; | |||||
| } | |||||
| String payStr = billDaily.getPayStr(); | |||||
| if (StringUtils.isBlank(payStr)) { | |||||
| stringRedisTemplate.opsForHash().increment(importKey, "processCount", 1); | |||||
| logger.error("实收金额为空", billDaily.toString()); | |||||
| return; | |||||
| } | |||||
| double payD = new BigDecimal(payStr).doubleValue(); | |||||
| if (payD < 0) { | |||||
| stringRedisTemplate.opsForHash().increment(importKey, "processCount", 1); | |||||
| logger.error("实收金额小于0", billDaily.toString()); | |||||
| return; | |||||
| } | |||||
| String oweStr = billDaily.getOweStr(); | |||||
| if (StringUtils.isBlank(oweStr)) { | |||||
| stringRedisTemplate.opsForHash().increment(importKey, "processCount", 1); | |||||
| logger.error("欠缴金额为空", billDaily.toString()); | |||||
| return; | |||||
| } | |||||
| double oweD = new BigDecimal(oweStr).doubleValue(); | |||||
| if (oweD < 0) { | |||||
| stringRedisTemplate.opsForHash().increment(importKey, "processCount", 1); | |||||
| logger.error("欠缴金额小于0", billDaily.toString()); | |||||
| return; | |||||
| } | |||||
| long owe = new BigDecimal(oweD).multiply(new BigDecimal(100)).longValue(); | |||||
| billDaily.setOwe(owe); | |||||
| Date receiveDate = billDaily.getReceiveDate(); | |||||
| Date date = new Date(); | |||||
| int expiredDay = DateUtils.daysBetween(receiveDate, date); | |||||
| billDaily.setExpiredDay((long) expiredDay); | |||||
| if (expiredDay > 0) { | |||||
| billDaily.setStatus(EnumBillRentStatus.NOT_PAID.getCode()); | |||||
| } else { | |||||
| billDaily.setStatus(EnumBillRentStatus.WAIT_PAY.getCode()); | |||||
| } | |||||
| if (receivePayD == payD) { | |||||
| billDaily.setStatus(EnumBillRentStatus.PAID.getCode()); | |||||
| } | |||||
| billDaily.setShopId(wxShop.getId()); | |||||
| billDaily.setRentShopType(wxShop.getType()); | |||||
| billDaily.setPayWay(EnumBillPayWay.OTHER.getCode()); | |||||
| billDaily.setCreatetime(date); | |||||
| billDaily.setUpdatetime(date); | |||||
| //商户 | |||||
| WxMerchantShop merchantShop = new WxMerchantShop(); | |||||
| merchantShop.setShopId(wxShop.getId()); | |||||
| merchantShop.setIsDel(EnumDelStatus.NOT_DEL.getCode()); | |||||
| WxMerchantShop wxMerchantShop = wxMerchantShopMapper.selectOne(merchantShop); | |||||
| billDaily.setMerchantId(wxMerchantShop.getMerchantId()); | |||||
| final IdWorker idWorker = IdWorker.get(); | |||||
| billDaily.setId(idWorker.nextId()); | |||||
| wxBillDailyMapper.insertSelective(billDaily); | |||||
| //记数 | |||||
| stringRedisTemplate.opsForHash().increment(importKey, "processCount", 1); | |||||
| stringRedisTemplate.expire(importKey, 10, TimeUnit.SECONDS); | |||||
| } | |||||
| } | } | ||||