/*
 * XzqhDomain.java
 * 版权所有 © 2011-2017 北京神舟良实信息技术有限公司
 * Copyright © 2011-2017 All Rights Reserved    京ICP备13013562号
 *  created by lipenghe with LAPTOP-DPSC399A
 */
package com.unis.base.server.domain;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.unis.base.common.util.IdWorkerUtils;
import com.unis.base.common.vo.XzqhVO;
import com.unis.base.server.dao.XzqhDao;
import com.unis.base.server.entity.XzqhDO;
import com.unis.common.utils.JsonUtils;
import com.unis.common.utils.LsBeanUtils;
import com.unis.common.utils.ResponseWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;


/**
 * TY_XZQHB-无表注释
 * DO处理自身, VO处理包括子表
 * @author lipenghe at 
 */
@Component
//Transactional注解加在service
//@Transactional
@Slf4j
public class XzqhDomain {

    @Autowired
    XzqhDao xzqhDao;

    @Autowired
    IdWorkerUtils idWorkerUtils;

    @Autowired
    SqlSessionTemplate sqlSessionTemplate;

    /**
     * 通用的数据处理,只对VO参数接口有效,早于buildInsertData, buildUpdateData
     * @param xzqhVO    <无表注释>对象
     */
    private void buildData(XzqhVO xzqhVO){
        //XzqhVO xzqhVODb= selectById(xzqhVO);
    }

    /**
     * 通用的插入处理,通用最晚执行
     * @param entity    <无表注释>对象
     */
    private void buildInsertData(XzqhDO entity){
        Long pk= null;
        //当前为主表
        pk= idWorkerUtils.nextId();
        entity.setQhid(String.valueOf(pk));
        entity.buildInsertData(String.valueOf(pk));
    }

    /**
     * 通用的插入处理,只对VO参数接口有效,晚于buildData
     * @param xzqhVO    <无表注释>对象
     */
    private void buildInsertData(XzqhVO xzqhVO){

    }

    /**
     * 通用的插入处理,只对VO参数接口有效,晚于buildInsertData
     * 专用于处理 VO 部分字段因安全等原因不能序列化为字符串的情况
     * @param xzqhVO    <无表注释>对象
     */
    private void buildInsertVoToDoData(XzqhVO xzqhVO, XzqhDO entity){

    }

    /**
     * 通用的更新处理,通用最晚执行
     * @param entity    <无表注释>对象
     */
    private void buildUpdateData(XzqhDO entity){
        entity.buildUpdateData();
    }

    /**
     * 新增成功后,只对VO参数接口有效
     * @param xzqhVO    <无表注释>对象
     */
    private void insertSuccess(XzqhVO xzqhVO){

    }

    /**
     * 修改成功后,只对VO参数接口有效
     * @param xzqhVO    <无表注释>对象
     */
    private void updateSuccess(XzqhVO xzqhVO){

    }

    /**
     * 新增和修改成功后,只对VO参数接口有效,早于insertSuccess, updateSuccess
     * @param xzqhVO    <无表注释>对象
     */
    private void saveSuccess(XzqhVO xzqhVO){

    }

    /**
     * 通用的返回数据处理,只对VO参数接口有效
     * @param xzqhVO    <无表注释>对象
     */
    private XzqhVO buildResult(XzqhVO xzqhVO){
        XzqhVO xzqhVOResult= new XzqhVO();
        xzqhVOResult.setQhid(xzqhVO.getQhid());
        return xzqhVOResult;
    }

    /**
     * <TY_XZQHB-无表注释>非主键的业务唯一属性校验
     * @param xzqhVO    <无表注释>对象
     * @param check    是否进行非主键的唯一校验
     * @author lipenghe with LAPTOP-DPSC399A
     */
    public ResponseWrapper uniqueCheck(XzqhVO xzqhVO, boolean check) {
        return ResponseWrapper.success();
    }

    /**
     * <TY_XZQHB-无表注释>插入校验
     * @param xzqhVO    <无表注释>对象
     * @author lipenghe with LAPTOP-DPSC399A
     */
    public ResponseWrapper insertCheck(XzqhVO xzqhVO) {
        //数据校验
        boolean enable= true;
        if(enable){
            return ResponseWrapper.success();
        }else{
            return ResponseWrapper.fail("不允许新增");
        }
    }

    /**
     * <TY_XZQHB-无表注释>修改校验
     * @param xzqhVO    <无表注释>对象
     * @author lipenghe with LAPTOP-DPSC399A
     */
    public ResponseWrapper updateCheck(XzqhVO xzqhVO) {
        //数据校验
        boolean enable= true;
        /*List<XzqhVO> xzqhVOList= xzqhDao.selectByEntity(xzqhVO);
        for(XzqhVO temp : xzqhVOList){
            if(1== 1){
                //..................
                break;
            }
        }*/
        if(enable){
            return ResponseWrapper.success();
        }else{
            return ResponseWrapper.fail("存在不可更新的数据");
        }
    }

    /**
     * <TY_XZQHB-无表注释>删除校验
     * @param xzqhVO    <无表注释>对象
     * @author lipenghe with LAPTOP-DPSC399A
     */
    public ResponseWrapper deleteCheck(XzqhVO xzqhVO) {
        //数据校验
        boolean enable= true;
        /*List<XzqhVO> xzqhVOList= xzqhDao.selectByEntity(xzqhVO);
        for(XzqhVO temp : xzqhVOList){
            if(1== 1){
                //..................
                break;
            }
        }*/
        if(enable){
            return ResponseWrapper.success();
        }else{
            return ResponseWrapper.fail("存在不可删除的数据或无权限操作");
        }
    }

    /**
     * <TY_XZQHB-无表注释>选择性保存,包含新增和修改
     * @param xzqhVO    <无表注释>对象
     * @author lipenghe with LAPTOP-DPSC399A
     */
    public ResponseWrapper saveEntitySelective(XzqhVO xzqhVO) {
        if((StringUtils.isNotEmpty(xzqhVO.getQhid()))){
            return updateByEntitySelective(xzqhVO);
        }else{
            return insertEntitySelective(xzqhVO, true);
        }
    }

    /**
     * <TY_XZQHB-无表注释>插入全部字段
     * @param entity    <无表注释>对象
     * @author lipenghe with LAPTOP-DPSC399A
     */
    public int insertEntity(XzqhDO entity) {
        buildInsertData(entity);
        return xzqhDao.insert(entity);
    }

    /**
     * <TY_XZQHB-无表注释>插入全部字段
     * @param xzqhVO    <无表注释>对象
     * @author lipenghe with LAPTOP-DPSC399A
     */
    public ResponseWrapper insertEntity(XzqhVO xzqhVO) {
        ResponseWrapper responseWrapperCheck = insertCheck(xzqhVO);
        if(responseWrapperCheck.isSuccess()){
            ResponseWrapper responseWrapper= uniqueCheck(xzqhVO, true);
            if(responseWrapper.isSuccess()){
                buildData(xzqhVO);
                buildInsertData(xzqhVO);

                //有属性操作则优先在vo处理
                XzqhDO entity= LsBeanUtils.copyProperties(xzqhVO, XzqhDO.class);
                //处理不能序列化的字段
                buildInsertVoToDoData(xzqhVO, entity);
                int num= insertEntity(entity);
                if(num> 0){
                    //新增成功后
                    saveSuccess(xzqhVO);
                    insertSuccess(xzqhVO);

                    //主键设置回去
                    xzqhVO.setQhid(entity.getQhid());
                    return ResponseWrapper.success(buildResult(xzqhVO));
                }
                return ResponseWrapper.fail();
            }else{
                return responseWrapper;
            }
        }else{
            return responseWrapperCheck;
        }
    }

    /**
     * <TY_XZQHB-无表注释>选择性插入字段
     * @param entity    <无表注释>对象
     * @author lipenghe with LAPTOP-DPSC399A
     */
    public int insertEntitySelective(XzqhDO entity) {
        buildInsertData(entity);
        return xzqhDao.insertSelective(entity);
    }

    /**
     * <TY_XZQHB-无表注释>选择性插入字段
     * @param xzqhVO    <无表注释>对象
     * @param check    是否进行非主键的唯一校验
     * @author lipenghe with LAPTOP-DPSC399A
     */
    public ResponseWrapper insertEntitySelective(XzqhVO xzqhVO, boolean check) {
        ResponseWrapper responseWrapperCheck = insertCheck(xzqhVO);
        if(responseWrapperCheck.isSuccess()){
            ResponseWrapper responseWrapper= uniqueCheck(xzqhVO, check);
            if(responseWrapper.isSuccess()){
                buildData(xzqhVO);
                buildInsertData(xzqhVO);

                //有属性操作则优先在vo处理
                XzqhDO entity= LsBeanUtils.copyProperties(xzqhVO, XzqhDO.class);
                //处理不能序列化的字段
                buildInsertVoToDoData(xzqhVO, entity);
                int num= insertEntitySelective(entity);
                if(num> 0){
                    //新增成功后
                    saveSuccess(xzqhVO);
                    insertSuccess(xzqhVO);

                    //主键设置回去
                    xzqhVO.setQhid(entity.getQhid());
                    return ResponseWrapper.success(buildResult(xzqhVO));
                }
                return ResponseWrapper.fail();
            }else{
                return responseWrapper;
            }
        }else{
            return responseWrapperCheck;
        }
    }

    /**
     * <TY_XZQHB-无表注释>批量插入全部字段
     * @param xzqhVOList    <无表注释>对象列表
     * @author lipenghe with LAPTOP-DPSC399A
     */
    public int insertBatchEntityList(List<XzqhVO> xzqhVOList) {
        int eachNum= 500;

        SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);

        XzqhVO xzqhVO= null;
        for(int i=0, size= xzqhVOList.size(); i< size; i++){
            xzqhVO= xzqhVOList.get(i);
            insertEntitySelective(xzqhVO, false);
            if(i % eachNum == 0 || i == size-1){
                //手动每eachNum条提交一次，提交后无法回滚
                sqlSession.commit();
                //清理缓存，防止溢出
                sqlSession.clearCache();
            }
        }
        return xzqhVOList.size();

        /*
        for(XzqhVO xzqhVOTemp : xzqhVOList){
            buildData(xzqhVOTemp);
            buildInsertData(xzqhVOTemp);
        }
        List<XzqhDO> xzqhDOList= JsonUtils.parseList(
            JsonUtils.serialize(xzqhVOList), XzqhDO.class);
        int num= 0;
        int max= xzqhDOList.size();
        int step= Math.min(eachNum, max);
        for(int i= 0; i< max; i+= step){
            List<XzqhDO> listEach= xzqhDOList.subList(i, Math.min(i+step, max));
            num+= xzqhDao.insertBatchEntityList(listEach);
        }
        return num;*/
    }

    /**
     * <TY_XZQHB-无表注释>更改状态
     * @param entity    <无表注释>对象
     * @author lipenghe with LAPTOP-DPSC399A
     */
    public int updateStatusByEntity(XzqhDO entity) {
        buildUpdateData(entity);
        return xzqhDao.updateStatusByEntity(entity);
    }

    /**
     * <TY_XZQHB-无表注释>更改状态
     * @param xzqhVO    <无表注释>对象
     * @author lipenghe with LAPTOP-DPSC399A
     */
    public ResponseWrapper updateStatusByEntity(XzqhVO xzqhVO) {
        ResponseWrapper responseWrapperCheck = updateCheck(xzqhVO);
        if(responseWrapperCheck.isSuccess()){
            ResponseWrapper responseWrapper= uniqueCheck(xzqhVO, true);
            if(responseWrapper.isSuccess()){
                buildData(xzqhVO);
                
                //有属性操作则优先在vo处理
                XzqhDO entity= JsonUtils.parse(
                    JsonUtils.serialize(xzqhVO), XzqhDO.class);
                int num= updateStatusByEntity(entity);
                if(num> 0){
                    //修改成功后
                    saveSuccess(xzqhVO);
                    updateSuccess(xzqhVO);

                    //主键设置回去(此处实际不需要)
                    xzqhVO.setQhid(entity.getQhid());
                    return ResponseWrapper.success(buildResult(xzqhVO));
                }else{
                    return ResponseWrapper.fail();
                }
            }else{
                return responseWrapper;
            }
        }else{
            return responseWrapperCheck;
        }
    }

    /**
     * <TY_XZQHB-无表注释>根据实体批量更新全部字段
     * @param list    <无表注释>对象列表
     * @author lipenghe with LAPTOP-DPSC399A
     */
    public int updateBatchByEntityList(List<XzqhDO> list) {
        for(XzqhDO temp : list){
            buildUpdateData(temp);
        }
        return xzqhDao.updateBatchByEntityList(list);
    }

    /**
     * <TY_XZQHB-无表注释>根据实体某些属性更新全部字段
     * @param entity    <无表注释>对象
     * @author lipenghe with LAPTOP-DPSC399A
     */
    public int updateByEntity(XzqhDO entity) {
        buildUpdateData(entity);
        return xzqhDao.updateByEntity(entity);
    }

    /**
     * <TY_XZQHB-无表注释>根据实体某些属性更新全部字段
     * @param xzqhVO    <无表注释>对象
     * @author lipenghe with LAPTOP-DPSC399A
     */
    public ResponseWrapper updateByEntity(XzqhVO xzqhVO) {
        ResponseWrapper responseWrapperCheck = updateCheck(xzqhVO);
        if(responseWrapperCheck.isSuccess()){
            ResponseWrapper responseWrapper= uniqueCheck(xzqhVO, true);
            if(responseWrapper.isSuccess()){
                buildData(xzqhVO);
                //有属性操作则优先在vo处理
                XzqhDO entity= JsonUtils.parse(
                    JsonUtils.serialize(xzqhVO), XzqhDO.class);
                int num= updateByEntity(entity);
                if(num> 0){
                    //修改成功后
                    saveSuccess(xzqhVO);
                    updateSuccess(xzqhVO);

                    //主键设置回去(此处实际不需要)
                    xzqhVO.setQhid(entity.getQhid());
                    return ResponseWrapper.success(buildResult(xzqhVO));
                }
                return ResponseWrapper.fail();
            }else{
                return responseWrapper;
            }
        }else{
            return responseWrapperCheck;
        }
    }

    /**
     * <TY_XZQHB-无表注释>根据实体不为空的属性,选择性更新字段
     * @param entity    <无表注释>对象
     * @author lipenghe with LAPTOP-DPSC399A
     */
    public int updateByEntitySelective(XzqhDO entity) {
        buildUpdateData(entity);
        return xzqhDao.updateByEntitySelective(entity);
    }

    /**
     * <TY_XZQHB-无表注释>根据实体不为空的属性,选择性更新字段(存在则更新,不存在则插入,其余删除)
     * @param xzqhVO    <无表注释>对象
     * @author lipenghe with LAPTOP-DPSC399A
     */
    public ResponseWrapper updateByEntitySelective(XzqhVO xzqhVO) {
        ResponseWrapper responseWrapperCheck = updateCheck(xzqhVO);
        if(responseWrapperCheck.isSuccess()){
            ResponseWrapper responseWrapper= uniqueCheck(xzqhVO, true);
            if(responseWrapper.isSuccess()){
                buildData(xzqhVO);
                //此处是直接更新,较为繁琐,适用于子表数据有关联(被其他数据使用),缺少排序在字段会出现顺序与修改数据的顺序不一致的问题,
                //有属性操作则优先在vo处理
                XzqhDO entity= JsonUtils.parse(
                    JsonUtils.serialize(xzqhVO), XzqhDO.class);
                int num= updateByEntitySelective(entity);
                if(num> 0){
                    //修改成功后
                    saveSuccess(xzqhVO);
                    updateSuccess(xzqhVO);

                    //主键设置回去(此处实际不需要)
                    xzqhVO.setQhid(entity.getQhid());
                    return ResponseWrapper.success(buildResult(xzqhVO));
                }
                return ResponseWrapper.fail();
            }else{
                return responseWrapper;
            }
        }else{
            return responseWrapperCheck;
        }
    }

    /**
     * <TY_XZQHB-无表注释>[真删除]根据实体的某些属性进行单条或者批量删除
     * @param xzqhVO    <无表注释>对象
     * @author lipenghe with LAPTOP-DPSC399A
     */
    public ResponseWrapper deleteByEntity(XzqhVO xzqhVO) {
        ResponseWrapper responseWrapper = deleteCheck(xzqhVO);
        if(responseWrapper.isSuccess()){
            int num= xzqhDao.deleteByEntity(xzqhVO);
            return ResponseWrapper.choose(num);
        }else{
            return responseWrapper;
        }
    }

    /**
     * <TY_XZQHB-无表注释>[真删除]根据实体的某些属性进行单条或者批量删除
     * @param entity    <无表注释>对象
     * @author lipenghe with LAPTOP-DPSC399A
     */
    public int deleteByEntity(XzqhDO entity) {
        XzqhVO xzqhVO= JsonUtils.parse(
            JsonUtils.serialize(entity), XzqhVO.class);
        return xzqhDao.deleteByEntity(xzqhVO);
    }

    /**
     * <TY_XZQHB-无表注释>[假删除]根据实体的某些属性进行单条或者批量删除,根据实体属性单条或批量删除只是改变了状态不在页面显示,数据仍存在
     * @param xzqhVO    <无表注释>对象
     * @author lipenghe with LAPTOP-DPSC399A
     */
    public ResponseWrapper deleteShamByEntity(XzqhVO xzqhVO) {
        ResponseWrapper responseWrapper = deleteCheck(xzqhVO);
        if(responseWrapper.isSuccess()){
            //自行在controller设置状态,则可删除,亦可还原
            int num= xzqhDao.deleteShamByEntity(xzqhVO);
            return ResponseWrapper.choose(num);
        }else{
            return responseWrapper;
        }
    }

    /**
     * <TY_XZQHB-无表注释>[假删除]根据实体的某些属性进行单条或者批量删除,根据实体属性单条或批量删除只是改变了状态不在页面显示,数据仍存在
     * @param entity    <无表注释>对象
     * @author lipenghe with LAPTOP-DPSC399A
     */
    public int deleteShamByEntity(XzqhDO entity) {
        XzqhVO xzqhVO= JsonUtils.parse(
            JsonUtils.serialize(entity), XzqhVO.class);
        return xzqhDao.deleteShamByEntity(xzqhVO);
    }

    /**
     * <TY_XZQHB-无表注释>根据实体的某些属性查询数量
     * @param xzqhVO    <无表注释>对象
     * @author lipenghe with LAPTOP-DPSC399A
     */
    public int selectCountByEntity(XzqhVO xzqhVO) {
        int num= xzqhDao.selectCountByEntity(xzqhVO);
        return num;
    }

    /**
     * <TY_XZQHB-无表注释>根据实体的唯一属性查询数量
     * @param xzqhVO    <无表注释>对象
     * @author lipenghe with LAPTOP-DPSC399A
     */
    public int selectCountById(XzqhVO xzqhVO) {
        int num= xzqhDao.selectCountById(xzqhVO);
        return num;
    }

    /**
     * <TY_XZQHB-无表注释>根据实体的业务唯一属性(且非指定主键数据)判断是否存在
     * @param xzqhVO    <无表注释>对象
     * @author lipenghe with LAPTOP-DPSC399A
     */
    public int selectExistsByEntity(XzqhVO xzqhVO) {
        int num= xzqhDao.selectExistsByEntity(xzqhVO);
        return num;
    }

    /**
     * <TY_XZQHB-无表注释>根据实体(唯一标示)查询一条数据
     * @param xzqhVO    <无表注释>对象
     * @author lipenghe with LAPTOP-DPSC399A
     */
    public XzqhVO selectById(XzqhVO xzqhVO) {
        XzqhVO xzqhVODb= xzqhDao.selectById(xzqhVO);
        return xzqhVODb;
    }

    /**
     * <TY_XZQHB-无表注释>根据实体(唯一标示)查询一条数据
     * @param entity    <无表注释>对象
     * @author lipenghe with LAPTOP-DPSC399A
     */
    public XzqhVO selectById(XzqhDO entity) {
        XzqhVO xzqhVO= JsonUtils.parse(
            JsonUtils.serialize(entity), XzqhVO.class);
        return xzqhDao.selectById(xzqhVO);
    }

    /**
     * <TY_XZQHB-无表注释>根据实体的某些属性查询分页数据
     * @param xzqhVO    <无表注释>对象
     * @author lipenghe with LAPTOP-DPSC399A
     */
    public Page<XzqhVO> selectPageByEntity(int pageNo, int pageSize
        , XzqhVO xzqhVO, String order) {
        PageHelper.startPage(pageNo, pageSize, order);
        return xzqhDao.selectPageByEntity(xzqhVO);
    }

    /**
     * <TY_XZQHB-无表注释>根据实体的某些属性查询列表
     * @param xzqhVO    <无表注释>对象
     * @author lipenghe with LAPTOP-DPSC399A
     */
    public List<XzqhVO> selectByEntity(XzqhVO xzqhVO) {
        return xzqhDao.selectByEntity(xzqhVO);
    }

    /**
     * <TY_XZQHB-无表注释>根据实体的某些属性查询列表
     * @param entity    <无表注释>对象
     * @author lipenghe with LAPTOP-DPSC399A
     */
    public List<XzqhVO> selectByEntity(XzqhDO entity) {
        XzqhVO xzqhVO= JsonUtils.parse(
            JsonUtils.serialize(entity), XzqhVO.class);
        return xzqhDao.selectByEntity(xzqhVO);
    }

}
