content: package com.seezoon.admin.framework.service;
  
  import com.seezoon.admin.framework.context.UserContext;
  import java.util.Arrays;
  import java.util.Date;
  import java.util.List;
  
  import javax.validation.constraints.NotEmpty;
  import javax.validation.constraints.NotNull;
  
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.transaction.annotation.Transactional;
  import org.springframework.util.Assert;
  
  import com.github.pagehelper.PageHelper;
  import com.github.pagehelper.PageInfo;
  import com.github.pagehelper.PageSerializable;
  import com.seezoon.dao.framework.CrudDao;
  import com.seezoon.dao.framework.entity.AbstractQueryCondition;
  import com.seezoon.dao.framework.entity.BaseEntity;
  import com.seezoon.framework.utils.IdGen;
  
  /**
   * 增删改查service
   *
   * @author hdf
   */
  public abstract class AbstractCrudService<D extends CrudDao<T, PK>, T extends BaseEntity<PK>, PK>
      extends AbstractTransactionService {
  
      @SuppressWarnings("all")
      @Autowired
      protected D d;
  
      /**
       * 根据主键查询
       *
       * @param pk
       * @return
       */
      @Transactional(readOnly = true)
      public T find(@NotNull PK pk) {
          return this.d.selectByPrimaryKey(pk);
      }
  
      /**
       * 更具条件返回一个
       *
       * @param condition
       *            可以为null
       * @return
       */
      @Transactional(readOnly = true)
      public T findOne(AbstractQueryCondition condition) {
          List<T> ts = this.find(condition);
          Assert.isTrue(ts.size() <= 1,
              "Expected one result (or null) to be returned by findOne(), but found: " + ts.size());
          return ts.isEmpty() ? null : ts.get(0);
      }
  
      /**
       * 自定义条件查询
       *
       * @param condition
       * @return
       */
      @Transactional(readOnly = true)
      public List<T> find(AbstractQueryCondition condition) {
          return this.d.selectByCondition(condition);
      }
  
      /**
       * 分页查询
       *
       * @param condition
       * @param pageNum
       * @param pageSize
       * @param count
       * @return
       */
      @Transactional(readOnly = true)
      public PageInfo<T> find(AbstractQueryCondition condition, int pageNum, int pageSize, boolean count) {
          PageHelper.startPage(pageNum, pageSize, count);
          List<T> list = this.find(condition);
          PageInfo<T> pageInfo = new PageInfo<T>(list);
          return pageInfo;
      }
  
      /**
       * 分页查询
       *
       * {@code PageSerializable}属性较少，适合序列化，如果想要更多属性，可以使用{@link PageInfo}
       *
       * @param condition
       * @param pageNum
       * @param pageSize
       * @return
       */
      @Transactional(readOnly = true)
      public PageSerializable<T> find(AbstractQueryCondition condition, int pageNum, int pageSize) {
          PageHelper.startPage(pageNum, pageSize, Boolean.TRUE);
          List<T> list = this.find(condition);
          PageSerializable<T> pageInfo = new PageSerializable<T>(list);
          return pageInfo;
      }
  
      /**
       * 插入支持批量
       *
       * @param records
       * @return
       */
      public int save(@NotEmpty T... records) {
          Arrays.stream(records).forEach((t) -> {
              // 当为空且是字符串类型时候，默认为其生成主键
              if (null == t.getId() && t.getId() instanceof String) {
                  t.setId((PK)IdGen.uuid());
              }
              t.setCreateBy(UserContext.getUserId());
              t.setUpdateBy(UserContext.getUserId());
              t.setCreateTime(new Date());
              t.setUpdateTime(t.getCreateTime());
          });
          return this.d.insert(records);
      }
  
      /**
       * 按主键选择性更新，默认自动修改更新时间及更新人
       *
       * @param record
       * @return
       */
      public int updateSelective(@NotNull T record) {
          record.setUpdateTime(new Date());
          record.setUpdateBy(UserContext.getUserId());
          return this.d.updateByPrimaryKeySelective(record);
      }
  
      /**
       * 按主键全量更新,默认自动修改更新时间及更新人
       *
       * <pre>
       * 默认不更新创建时间及创建时间
       * </pre>
       *
       * @param record
       * @return
       */
      public int update(@NotNull T record) {
          record.setUpdateTime(new Date());
          record.setUpdateBy(UserContext.getUserId());
          return this.d.updateByPrimaryKey(record);
      }
  
      /**
       * 按主键删除，一般业务在逻辑上保证不会删除，如果非要删除建议使用逻辑删除
       *
       * <pre>
       * 该方法不做权限控制
       * </pre>
       *
       * @param pks
       * @return
       */
      public int delete(@NotEmpty PK... pks) {
          return this.d.deleteByPrimaryKey(pks);
      }
  }
  