package cn.iocoder.yudao.framework.mybatis.core.service;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.vo.PageVO;
import cn.iocoder.yudao.framework.mybatis.core.mapper.AbstractMapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collection;
import java.util.List;

/**
 * 功能描述: 基于通用MyBatis Mapper插件的Service接口的实现
 * <p>
 * 作者:
 * 日期: 2020-09-16 18:58
 * @author Administrator
 */
public abstract class AbstractService<M extends AbstractMapper<T>, T> extends ServiceImpl<M, T> implements IService<T> {
    @Autowired
    protected M abstractMapper;

    @Override
    public PageResult<T> selectPage(PageVO vo, Object object) {
        return abstractMapper.selectPage(vo, object);
    }

    @Override
    public PageResult<T> selectPage(PageVO vo, Wrapper<T> queryWrapper) {
        return abstractMapper.selectPage(vo, queryWrapper);
    }

    @Override
    public PageResult<T> selectPage(PageParam pageParam, Wrapper<T> queryWrapper) {
        return abstractMapper.selectPage(pageParam, queryWrapper);
    }

    @Override
    public T selectOne(String field, Object value) {
        return abstractMapper.selectOne(field, value);
    }

    @Override
    public T selectOne(Wrapper<T> queryWrapper) {
        return abstractMapper.selectOne(queryWrapper);
    }

    @Override
    public T selectOne(SFunction<T, ?> field, Object value) {
        return abstractMapper.selectOne(field, value);
    }

    @Override
    public T selectOne(String field1, Object value1, String field2, Object value2) {
        return abstractMapper.selectOne(field1, value1, field2, value2);
    }

    @Override
    public T selectOne(SFunction<T, ?> field1, Object value1, SFunction<T, ?> field2, Object value2) {
        return abstractMapper.selectOne(field1, value1, field2, value2);
    }

    @Override
    public Long selectCount() {
        return abstractMapper.selectCount();
    }

    @Override
    public Long selectCount(Wrapper<T> queryWrapper) {
        return abstractMapper.selectCount(queryWrapper);
    }

    @Override
    public Long selectCount(String field, Object value) {
        return abstractMapper.selectCount(field, value);
    }

    @Override
    public Long selectCount(SFunction<T, ?> field, Object value) {
        return abstractMapper.selectCount(field, value);
    }

    @Override
    public List<T> selectList() {
        return abstractMapper.selectList();
    }

    @Override
    public List<T> selectList(Wrapper<T> queryWrapper) {
        return abstractMapper.selectList(queryWrapper);
    }

    @Override
    public List<T> selectList(Object object) {
        return abstractMapper.selectList(object);
    }

    @Override
    public List<T> selectList(String field, Object value) {
        return abstractMapper.selectList(field, value);
    }

    @Override
    public List<T> selectList(SFunction<T, ?> field, Object value) {
        return abstractMapper.selectList(field, value);
    }

    @Override
    public List<T> selectList(String field, Collection<?> values) {
        return abstractMapper.selectList(field, values);
    }

    @Override
    public List<T> selectList(SFunction<T, ?> field, Collection<?> values) {
        return abstractMapper.selectList(field, values);
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void insertBatch(Collection<T> entities) {
        abstractMapper.insertBatch(entities);
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void updateBatch(T update) {
        abstractMapper.updateBatch(update);
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void updateBatch(Collection<T> entities) {
        abstractMapper.updateBatch(entities);
    }

    @Override
    public PageResult<T> pager(PageVO form, Object object) {
        return PageResult.of(pager(form, object, Boolean.TRUE));
    }

    @Override
    public List<T> pagerList(PageVO form, Object object) {
        return pager(form, object, Boolean.FALSE).getList();
    }

    /****
     * 分页
     * @param object
     * @param counted
     * @return
     */
    private PageInfo<T> pager(PageVO form, Object object, boolean counted) {
        try {
            // 前置参数校检
            beforeHandler(object);

            // 进行分页查询请求
            PageInfo<T> pager = com.github.pagehelper.PageHelper
                    .startPage(form.getPage(), form.getRows(), counted)
                    .setOrderBy(form.getBy())
                    .doSelectPageInfo(() -> selectList(object));

            // 返回的数据列表
            List<T> list = pager.getList();

            // 处理列表返回的数据
            if (CollUtil.isNotEmpty(list)) {
                afterHandler(list);
            }

            return pager;
        }
        finally {
            //清理 ThreadLocal 存储的分页参数,保证线程安全
            com.github.pagehelper.PageHelper.clearPage();
        }
    }

    /**
     * 处理分页查询参数
     */
    @Override
    public void beforeHandler(Object object) {}

    /**
     * 处理分页查询返回的数据
     */
    @Override
    public void afterHandler(List<T> list) {}
}
