package com.touchhealth.trade.service.afterSale;
import com.touchealth.common.page.Pager;
import com.touchhealth.trade.bo.afterSale.AfterSaleBo;
import com.touchhealth.trade.entity.AfterSaleDo;
import com.touchhealth.trade.entity.afterSale.AfterSale;
import com.touchhealth.trade.helper.afterSale.AfterSaleHelper;
import com.touchhealth.trade.repository.afterSale.AfterSaleRepository;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @Auther: dangshilin
* @Date: 2018/7/30
*/
@Service("afterSaleService")
public class AfterSaleServiceImpl implements AfterSaleService{
@Autowired
private AfterSaleRepository afterSaleRepository;
@PersistenceContext
private EntityManager em;
/**
* 分页获取售后单列表
* @param afterSaleBo
* @param pager
* @return
*/
@Override
public Pager list(AfterSaleBo afterSaleBo, Pager pager) {
String makerMobile = afterSaleBo.getMakerMobile();
Integer applyType = afterSaleBo.getApplyType();
Date endTime = afterSaleBo.getEndTime();
Date startTime = afterSaleBo.getStartTime();
String sourceCode = afterSaleBo.getSourceCode();
Integer processState = afterSaleBo.getProcessState();
int pageSize = pager.getPageSize();
int pageNo = pager.getPageNo();
int begin = pager.getPageSize()*(pager.getPageNo()-1);
// 查询售后申请单的jpql
String sql = "select new com.touchhealth.trade.entity.AfterSaleDo (a.id,a.afterSaleNo,a.reservationNo,a.makerId,a.makerName,a.makerMobile,a.createdAt,a.applyReason,a.examineFailReason,a.applyExpectTime,a.firstReservationTime,a.processState,a.applyType,a.deleteFlag,a.updatedAt,a.updatedOperatorId,a.updatedOperatorName,a.deletedAt,a.deletedOperatorId,a.deletedOperatorName,a.remark,s.sourceCode) from AfterSale a,Source s,Reservation r where a.reservationNo = r.reservationNo and r.id = s.typeObjectId and s.type = 1";
// 查询数量sql
String countSql = "select count(*) from t_after_sale a,t_source s,t_reservation r where a.reservation_no = r.reservation_no and r.id = s.type_object_id and s.type = 1";
// 动态参数
List<Object> params = new ArrayList<>();
int i = 1;
int j = 1;
if (StringUtils.isNotBlank(makerMobile)) {
sql = sql + " and a.makerMobile = ?" + i++;
countSql = countSql + " and a.maker_mobile = ?" + j++;
params.add(makerMobile);
}
if (null != applyType){
sql = sql + " and a.applyType = ?" + i++;
countSql = countSql + " and a.apply_type = ?" + j++;
params.add(applyType);
}
if (StringUtils.isNotBlank(sourceCode)){
sql = sql + " and s.sourceCode = ?" + i++;
countSql = countSql + " and s.source_code = ?" + j++;
params.add(sourceCode);
}
if (null != startTime){
Date createdAt = startTime;
sql = sql + " and s.createdAt >= ?" + i++;
countSql = countSql + " and s.created_at >= ?" + j++;
params.add(createdAt);
}
if (null != endTime){
Date createdAt = endTime;
sql = sql + " and a.createdAt <= ?" + i++;
countSql = countSql + " and a.created_at <= ?" + j++;
params.add(createdAt);
}
if (null != processState){
sql = sql + " and a.processState = ?" + i++;
countSql = countSql + " and a.process_state = ?" + j++;
params.add(processState);
}else {
// 申请单流程状态 1-待审核 2-审核通过 3-审核失败 4-已取消
sql = sql + " and a.processState in (2,3,4)";
countSql = countSql + " and a.process_state in (2,3,4)";
}
sql = sql + " ORDER by a.createdAt DESC ";
countSql = countSql + " ORDER by a.created_at DESC ";
Query query = em.createQuery(sql);
Query countQuery = em.createNativeQuery(countSql);
for (int k = 1; k < params.size() + 1; k++) {
query.setParameter(k, params.get(k - 1));
countQuery.setParameter(k, params.get(k - 1));
}
query.setFirstResult(begin);
query.setMaxResults(pageSize);
List<AfterSaleDo> resultList = query.getResultList();
// 关闭资源
em.close();
pager.setResultList(AfterSaleHelper.convertAfterSaleDoListToAfterSaleBoList(resultList));
BigInteger count = (BigInteger)countQuery.getSingleResult();
double records = count.intValue();
pager.setRecords((int) records);
double total = records/pageSize;
pager.setTotal((int) Math.ceil(total));
return pager;
}
/**
* 筛选获取售后申请单列表
* @param afterSaleBo
* @return
*/
@Override
public List<AfterSaleBo> exportList(AfterSaleBo afterSaleBo) {
String makerMobile = afterSaleBo.getMakerMobile();
Integer applyType = afterSaleBo.getApplyType();
Date endTime = afterSaleBo.getEndTime();
Date startTime = afterSaleBo.getStartTime();
String sourceCode = afterSaleBo.getSourceCode();
Integer processState = afterSaleBo.getProcessState();
// 查询售后申请单的jpql
String sql = "select new com.touchhealth.trade.entity.AfterSaleDo (a.id,a.afterSaleNo,a.reservationNo,a.makerId,a.makerName,a.makerMobile,a.createdAt,a.applyReason,a.examineFailReason,a.applyExpectTime,a.firstReservationTime,a.processState,a.applyType,a.deleteFlag,a.updatedAt,a.updatedOperatorId,a.updatedOperatorName,a.deletedAt,a.deletedOperatorId,a.deletedOperatorName,a.remark,s.sourceCode,r.serviceItemName,r.reservedPartyName,r.reservationPartyInfo) from AfterSale a,Source s,Reservation r where a.reservationNo = r.reservationNo and r.id = s.typeObjectId and s.type = 1";
// 动态参数
List<Object> params = new ArrayList<>();
int i = 1;
if (StringUtils.isNotBlank(makerMobile)) {
sql = sql + " and a.makerMobile = ?" + i++;
params.add(makerMobile);
}
if (null != applyType){
sql = sql + " and a.applyType = ?" + i++;
params.add(applyType);
}
if (StringUtils.isNotBlank(sourceCode)){
sql = sql + " and s.sourceCode = ?" + i++;
params.add(sourceCode);
}
if (null != startTime){
Date createdAt = startTime;
sql = sql + " and s.createdAt >= ?" + i++;
params.add(createdAt);
}
if (null != endTime){
Date createdAt = endTime;
sql = sql + " and a.createdAt <= ?" + i++;
params.add(createdAt);
}
if (null != processState){
sql = sql + " and a.processState = ?" + i++;
params.add(processState);
}else {
// 申请单流程状态 1-待审核 2-审核通过 3-审核失败 4-已取消
sql = sql + " and a.processState in (2,3,4)";
}
sql = sql + " ORDER by a.createdAt DESC ";
Query query = em.createQuery(sql);
for (int k = 1; k < params.size() + 1; k++) {
query.setParameter(k, params.get(k - 1));
}
List<AfterSaleDo> resultList = query.getResultList();
// 关闭资源
em.close();
List<AfterSaleBo> afterSaleBoList = AfterSaleHelper.convertAfterSaleDoListToAfterSaleBoList(resultList);
return afterSaleBoList;
}
}
以上是业务层代码.
@Autowired
private AfterSaleRepository afterSaleRepository;
持久层的服务就不解释了.
@PersistenceContext
private EntityManager em;
Persistence context是由一组受托管的实体对象实例所构成的集合。它受entity manager 的管理。Entity manager追踪persistence context中所有对象的修改和更新情况,并根据指定的flush模式将这些修改保存到数据库中。一旦persistence context被关闭,所有实体对象实例都会脱离EntityManager而成为非托管对象。对象一旦从persistence context中脱离,就不再受entity manager管理了,任何对此对象的状态变更也将不会被同步到数据库。Java Persistence中有两种类型的persistence context,分别是transaction-scoped persistence context和extended persistence context。Transaction-scoped persistence context的persistence context可能只在事务范围内存在,它们会在事务结束后被关闭。当事务结束时,transaction-scoped persistence context将被销毁,而所有的托管实体对象实例也将处于游离状态(detached)。只有受应用服务器管理的persistence context才可以是事务范围的。换言之,只有标注了@PersistenceContext注解(或是其XML的等价描述)的EntityManager实例才可以是事务范围的。
注意:
第一个坑:
因为Persistence context是由一组受托管的实体对象实例所构成的集合,并且受entity manager 的管理.所以拼接的sql 中 "......from AfterSale a,Source s,Reservation r......"AfterSale,Source,Reservation是数据库表映射的实体类的名字,而不是表名.查询的内容是实体类的属性而不是数据库表字段.又因为NativeQuery使用的是使用HQL查询,所以拼接的countSql中对应的是数据库表名和数据库子段名.
第二个坑:
查询结果需要一个对象来接收.这个对象除了要提供set,get方法还需要提供一个与之对应的有参构造方法.注意,是与结果属性完全对应的有参构造方法.
如果不需要分页的话,把countSql相关的和Pager相关的去掉就好了.以上仅是个人浅见,如有错误,欢迎指正!