package com.dhcc.finance.main.service.impl;

import brave.Tracer;
import com.dhcc.common.constant.SysConstants;
import com.dhcc.common.constant.SysStatusCode;
import com.dhcc.common.model.CurrencyMeta;
import com.dhcc.common.model.SysUserInfo;
import com.dhcc.common.model.response.RestfulResponse;
import com.dhcc.common.util.CacheDataUtil;
import com.dhcc.common.util.SnowflakeIdWorker;
import com.dhcc.finance.constant.FinanceDictConsts;
import com.dhcc.finance.main.dao.CwGlVouchermaxnoMapper;
import com.dhcc.finance.main.domain.CwGlVouchermaxno;
import com.dhcc.finance.main.domain.CwGlVouchermaxnoExample;
import com.dhcc.finance.main.domain.CwGlVouchermaxnoExample.Criteria;
import com.dhcc.finance.main.service.CwGlVouchermaxnoService;
import com.dhcc.finance.util.MetaDataUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 功能描述：最大凭证号实现
 *
 * @author dml
 * @date 2019年3月28日 下午7:53:11
 * @修改日志：
 */
@Slf4j
@Service
public class CwGlVouchermaxnoServiceImpl implements CwGlVouchermaxnoService {
    @Autowired
    private Tracer tracer;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    CwGlVouchermaxnoMapper cwGlVouchermaxnoMapper;

    @Autowired
    private CuratorFramework curatorFramework;

    @Value("${curator.lockPath}")
    private String lockPath;// 锁路径

    /*
     * (非 Javadoc)
     * Title: searchCwGlVouchermaxnoAllData
     * Description:查询全部最大凭证号
     * @param pageNum
     * @param pageSize
     * @param navigatePages
     * @return
     * @see com.dhcc.finance.main.service.CwGlVouchermaxnoService#searchCwGlVouchermaxnoAllData(int, int, int)
     * @author dml
     * @date 2019年3月28日 下午7:59:15
     * @修改日志：
     */
    @Override
    public RestfulResponse<PageInfo<CwGlVouchermaxno>, CurrencyMeta> searchCwGlVouchermaxnoAllData(int pageNum,
                                                                                                   int pageSize, int navigatePages) {
        PageHelper.startPage(pageNum, pageSize);
        CwGlVouchermaxnoExample cwGlVouchermaxnoExample = new CwGlVouchermaxnoExample();
        Criteria createCriteria = cwGlVouchermaxnoExample.createCriteria();
        createCriteria.andUseStateEqualTo(FinanceDictConsts.Syzt.EFFECTIVE);
        List<CwGlVouchermaxno> listCwGlVouchermaxno = cwGlVouchermaxnoMapper.selectByExample(cwGlVouchermaxnoExample);
        PageInfo<CwGlVouchermaxno> pageInfo = new PageInfo<>(listCwGlVouchermaxno, navigatePages);
        return new RestfulResponse<PageInfo<CwGlVouchermaxno>, CurrencyMeta>(SysConstants.CODE.SUCCESS, SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS, pageInfo, MetaDataUtil.getMeta(tracer, SysStatusCode.OPERATION_SUCCESS));
    }

    /*
     * (非 Javadoc)
     * Title: addCwGlVouchermaxno
     * Description:新增最大凭证号
     * @param cwGlVouchermaxno
     * @return
     * @see com.dhcc.finance.main.service.CwGlVouchermaxnoService#addCwGlVouchermaxno(com.dhcc.finance.main.domain.CwGlVouchermaxno)
     * @author dml
     * @date 2019年3月28日 下午7:59:18
     * @修改日志：
     */
    @Override
    public RestfulResponse<Object, CurrencyMeta> addCwGlVouchermaxno(CwGlVouchermaxno cwGlVouchermaxno) {
        SysUserInfo sysUserInfo = CacheDataUtil.<SysUserInfo>getCacheBean(stringRedisTemplate, SysConstants.REDIS_KEY_PREFIX.SYS_USER_INFO, SysUserInfo.class);
        if (sysUserInfo != null) {
            cwGlVouchermaxno.setCreateUser(sysUserInfo.getUserId());
        }
        cwGlVouchermaxno.setCreateTime(new Date());
        cwGlVouchermaxno.setUseState(FinanceDictConsts.Syzt.EFFECTIVE);
        cwGlVouchermaxno.setPkVouchermaxno(SnowflakeIdWorker.getInstance().nextIdString());
        cwGlVouchermaxnoMapper.insert(cwGlVouchermaxno);
        return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.SUCCESS, SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS, MetaDataUtil.getMeta(tracer, SysStatusCode.OPERATION_SUCCESS));
    }

    /*
     * (非 Javadoc)
     * Title: updateCwGlVouchermaxnoByPk
     * Description:修改最大凭证号
     * @param cwGlVouchermaxno
     * @return
     * @see com.dhcc.finance.main.service.CwGlVouchermaxnoService#updateCwGlVouchermaxnoByPk(com.dhcc.finance.main.domain.CwGlVouchermaxno)
     * @author dml
     * @date 2019年3月28日 下午7:59:21
     * @修改日志：
     */
    @Override
    public RestfulResponse<Object, CurrencyMeta> updateCwGlVouchermaxnoByPk(CwGlVouchermaxno cwGlVouchermaxno) {
        SysUserInfo sysUserInfo = CacheDataUtil.<SysUserInfo>getCacheBean(stringRedisTemplate, SysConstants.REDIS_KEY_PREFIX.SYS_USER_INFO, SysUserInfo.class);
        if (sysUserInfo != null) {
            cwGlVouchermaxno.setUpdateUser(sysUserInfo.getUserId());
        }
        cwGlVouchermaxno.setUpdateTime(new Date());
        cwGlVouchermaxnoMapper.updateByPrimaryKeySelective(cwGlVouchermaxno);
        return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.SUCCESS, SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS, MetaDataUtil.getMeta(tracer, SysStatusCode.OPERATION_SUCCESS));
    }

    /*
     * (非 Javadoc)
     * Title: deleteCwGlVouchermaxnoByPk
     * Description:逻辑删除最大凭证号
     * @param pkVouchermaxno
     * @return
     * @see com.dhcc.finance.main.service.CwGlVouchermaxnoService#deleteCwGlVouchermaxnoByPk(java.lang.String)
     * @author dml
     * @date 2019年3月28日 下午7:59:25
     * @修改日志：
     */
    @Override
    public RestfulResponse<Object, CurrencyMeta> deleteCwGlVouchermaxnoByPk(String pkVouchermaxno) {
        CwGlVouchermaxno cwGlVouchermaxno = new CwGlVouchermaxno();
        SysUserInfo sysUserInfo = CacheDataUtil.<SysUserInfo>getCacheBean(stringRedisTemplate, SysConstants.REDIS_KEY_PREFIX.SYS_USER_INFO, SysUserInfo.class);
        if (sysUserInfo != null) {
            cwGlVouchermaxno.setUpdateUser(sysUserInfo.getUserId());
        }
        cwGlVouchermaxno.setUpdateTime(new Date());
        cwGlVouchermaxno.setUseState(FinanceDictConsts.Syzt.INVALID);
        cwGlVouchermaxno.setPkVouchermaxno(pkVouchermaxno);
        cwGlVouchermaxnoMapper.updateByPrimaryKeySelective(cwGlVouchermaxno);
        return new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.SUCCESS, SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS, MetaDataUtil.getMeta(tracer, SysStatusCode.OPERATION_SUCCESS));
    }

    /* (非 Javadoc)
     * <p>Title: searchCwGlVouchermaxnoMaxNo</p>
     * <p>Description:获取最大凭证号 </p>
     * @param pkGlorgbook
     * @param period
     * @param pkVouchertype
     * @return
     * @see com.dhcc.finance.main.service.CwGlVouchermaxnoService#searchCwGlVouchermaxnoMaxNo(java.lang.String, java.lang.String, java.lang.String)
     * @author huangpeng
     * @date 2019年4月12日 下午4:02:41
     * @修改日志：
     */

    @Override
    public RestfulResponse<CwGlVouchermaxno, CurrencyMeta> searchCwGlVouchermaxnoMaxNo(String pkGlorgbook,
                                                                                       String period) {
        CwGlVouchermaxno list = cwGlVouchermaxnoMapper.selectGetMaxNo(pkGlorgbook, period);
        return new RestfulResponse<CwGlVouchermaxno, CurrencyMeta>(SysConstants.CODE.SUCCESS, SysConstants.DEFAULT_MESSAGE.OPERATION_SUCCESS, list, MetaDataUtil.getMeta(tracer, SysStatusCode.OPERATION_SUCCESS));
    }

    /**
     * @param [pkGlorgbook, period]
     * @return com.dhcc.finance.main.domain.CwGlVouchermaxno
     * @description: 获取最大凭证号
     * @author liuxianjv
     * @date 2020-06-13 16:16
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public CwGlVouchermaxno getVoucherMaxNo(String pkGlorgbook, String period) {
        String path = lockPath + "/" + pkGlorgbook + "/" + period;
        InterProcessMutex lock = new InterProcessMutex(curatorFramework, path);
        CwGlVouchermaxno cwGlVouchermaxno = new CwGlVouchermaxno();
        try {
            if (lock.acquire(5, TimeUnit.MINUTES)) {
                log.info("已锁住>>>>>>>" + path);

                cwGlVouchermaxno = cwGlVouchermaxnoMapper.getVoucherMaxNo(pkGlorgbook, period);
            }
            if (lock.isOwnedByCurrentThread()) {
                lock.release();
                log.info("释放锁成功>>>>>>>>>" + path);
            }
        } catch (Exception e) {
            log.error("更新最大凭证号异常>>>>>>>>>", e);
            cwGlVouchermaxno = null;
        }
        return cwGlVouchermaxno;
    }

}
