package com.sptg.estate.biz.service.impl;

import com.baomidou.mybatisplus.enums.SqlLike;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.toolkit.IdWorker;
import com.sptg.common.core.beans.ExcelResultEnum;
import com.sptg.common.core.beans.PageBean;
import com.sptg.common.core.beans.ResultBean;
import com.sptg.common.core.beans.ResultEnum;
import com.sptg.common.core.constant.OperationConstant;
import com.sptg.common.core.constant.SymbolConstant;
import com.sptg.common.core.constant.UserFlagConstant;
import com.sptg.common.core.entity.DispatchTask;
import com.sptg.common.core.util.JsonUtils;
import com.sptg.device.api.constant.DeviceConstants;
import com.sptg.device.api.dto.AccessCardSimpleDto;
import com.sptg.device.api.dto.FaceCodeDto;
import com.sptg.device.api.dto.FaceInfoDto;
import com.sptg.device.api.entity.Device;
import com.sptg.device.api.feigns.DeviceFeign;
import com.sptg.device.api.vo.ManualPushDevicesTask;
import com.sptg.estate.api.dto.ApplyUserDto;
import com.sptg.estate.api.dto.SimpleUserDto;
import com.sptg.estate.api.dto.UserDto;
import com.sptg.estate.api.dto.UserInfoDto;
import com.sptg.estate.api.entity.*;
import com.sptg.estate.api.enums.EstateEnum;
import com.sptg.estate.api.vo.DevicesAccessPushVO;
import com.sptg.estate.biz.mapper.UserMapper;
import com.sptg.estate.biz.service.*;
import com.sptg.permissions.api.entity.CustInfoVerify;
import com.sptg.permissions.api.feigns.ConfFeign;
import com.sptg.permissions.api.feigns.SysApiLogFeign;
import com.sptg.permissions.api.utils.CustInfoVerifyUtil;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;


/**
 * title: UserServiceImpl
 * package: com.sptg.estate.biz.security.impl
 * description: 住户 服务层实现类
 *
 *
 *
 */
@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserServiceInterface {

    private final RoomServiceInterface roomServiceInterface;
    private final FloorServiceInterface floorServiceInterface;
    private final UnitServiceInterface unitServiceInterface;
    private final BuildingServiceInterface buildingServiceInterface;
    private final ResidentialServiceInterface residentialServiceInterface;
    private final MemberAndUserInterface memberAndUserInterface;
    private final RedisTemplate<String,String> redisTemplate;
    private final VideoCallAccountServiceInterface videoCallAccountServiceInterface;
    private final ConfFeign confFeign;
    private final AccessFacePushRecordsServiceInterface accessFacePushRecordsServiceInterface;
    private final AccessCardPushRecordsServiceInterface accessCardPushRecordsServiceInterface;

    /**
     * 特殊 防止循环依赖问题 MemberServiceInterface中依赖了UserServiceInterface
     */
    @Autowired
    @Lazy
    private  MemberServiceInterface memberServiceInterface;

    @Autowired
    @Lazy
    private  AccessCardServiceInterface accessCardServiceInterface;

    private final static String IMPORT_CACHE_USER_NMAE = "sptg:import:card:user:name";

    @Override
    public ResultBean<Page<User>> showUserList(UserDto userDto) {

        // 构建查询条件
        Wrapper<User> wrapper = new EntityWrapper<>();
        if (null != userDto.getCheckState()){
            wrapper.eq("i_check_state",userDto.getCheckState());
        }
        if (null != userDto.getFaceEnable()){
            wrapper.eq("i_face_enable",userDto.getFaceEnable());
        }
        //过滤删除
//        wrapper.notIn("i_status", OperationConstant.MINUS_ONE);
        if (userDto.getStatus() != null){
            wrapper.eq("i_status", userDto.getStatus());
        }else {
            wrapper.eq("i_status", OperationConstant.ZERO);
        }
        //根据机构
        if (StringUtils.isNotBlank(userDto.getOrgPosition())) {
            wrapper.like("s_org_position", userDto.getOrgPosition(), SqlLike.RIGHT);
        }
        //根据物业
        if (StringUtils.isNotBlank(userDto.getEstatePosition())) {
            wrapper.like("s_estate_position", userDto.getEstatePosition(), SqlLike.RIGHT);
        }
        //根据小区ID查询
        if(userDto.getResidentialId() != null){
            wrapper.eq("l_residential_id",userDto.getResidentialId());
        }
        //根据楼栋ID查询
        if(userDto.getBuildingId() != null){
            wrapper.eq("l_building_id",userDto.getBuildingId());
        }
        //根据单元ID查询
        if(userDto.getUnitId() != null){
            wrapper.eq("l_unit_id",userDto.getUnitId());
        }
        //根据单元ID查询
        if(userDto.getRoomId() != null){
            wrapper.eq("l_room_id",userDto.getRoomId());
        }
        //根据名称
        if (StringUtils.isNotBlank(userDto.getName())){
            wrapper.like("s_name",userDto.getName(),SqlLike.DEFAULT);
        }
        //根据时间日期
        if(null != userDto.getBeginDate()) {
            wrapper.ge("t_create_date",userDto.getBeginDate());
        }
        if(null != userDto.getEndDate()) {
            wrapper.le("t_create_date",userDto.getEndDate());
        }
        //根据人脸有效期
        if(null != userDto.getFaceBeginDate()) {
            wrapper.ge("t_face_begin_date",userDto.getFaceBeginDate());
        }
        if(null != userDto.getFaceEndDate()) {
            wrapper.le("t_face_end_date",userDto.getFaceEndDate());
        }
        //根据手机号
        if (userDto.getTel() != null){
            wrapper.like("s_tel",userDto.getTel(),SqlLike.DEFAULT);
        }
        //根据身份证号
        if (userDto.getIdCard() != null){
            wrapper.like("s_id_card",userDto.getIdCard());
        }
        //  排序字段
        if (userDto.getSortField() != null && userDto.getSortOrder() != null){
            wrapper.orderBy(userDto.getSortField(),userDto.getSortOrder().equals("asc"));
        }else {
            //  排序字段 时间降序
            wrapper.orderBy("t_create_date",false);
        }
//        Page<User> page=userDto.getPage();
//        page.setRecords(this.baseMapper.showUserList(userDto,page));
//        return new ResultBean<>(ResultEnum.SUCCESS, page);
        return new ResultBean<>(ResultEnum.SUCCESS, this.selectPage(userDto.getPage(), wrapper));
    }

    @Override
    public ResultBean<Page<User>> pagingByUserIds(UserDto userDto) {
        Wrapper<User> wrapper = new EntityWrapper<>();
        //过滤删除
        wrapper.eq("i_status", OperationConstant.ZERO);
        //用户id
        wrapper.in("l_id", userDto.getIds());
        //小区
        wrapper.eq(userDto.getResidentialId() != null,"l_residential_id",userDto.getResidentialId());
        //单元
        wrapper.eq(userDto.getUnitId() != null,"l_unit_id",userDto.getUnitId());
        //房间
        wrapper.eq(userDto.getRoomId() != null,"l_room_id",userDto.getRoomId());
        //名称
        wrapper.like(StringUtils.isNotBlank(userDto.getName()),"s_name",userDto.getName(),SqlLike.DEFAULT);
        //手机
        wrapper.like(userDto.getTel() != null,"s_tel",userDto.getTel(),SqlLike.DEFAULT);
        //身份证
        wrapper.like(userDto.getIdCard() != null,"s_id_card",userDto.getIdCard(),SqlLike.DEFAULT);
        //根据人脸有效期
        wrapper.ge(userDto.getFaceBeginDate() != null,"t_face_begin_date",userDto.getFaceBeginDate());
        wrapper.le(userDto.getFaceEndDate() != null,"t_face_end_date",userDto.getFaceEndDate());
        return new ResultBean<>(ResultEnum.SUCCESS,this.selectPage(userDto.getPage(),wrapper));
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public ResultBean<Boolean> addUser(UserDto userDto) {
        String idCard = userDto.getIdCard();
        /*在审核的接口中作身份验证
        if(StringUtils.isNotBlank(idCard)){
            CustInfoVerify custInfoVerify = new CustInfoVerify();
            custInfoVerify.setCustName(userDto.getName());
            custInfoVerify.setCertNumber(idCard);
            custInfoVerify.setCertType("1");
            Boolean result = CustInfoVerifyUtil.custInfoVerify(custInfoVerify, sysApiLogFeign);
            Assert.isTrue(result, "身份证验证失败，请填写正确的身份证信息");
        }*/
        Room room = this.roomServiceInterface.findRoomById(userDto.getRoomId());
        if (null == room) {
            return new ResultBean<>(ResultEnum.NOT_FIND);
        }
        userDto.setRoomName(room.getName());
        Floor floor = this.floorServiceInterface.findFloorById(room.getFloorId());
        if (null == floor) {
            return new ResultBean<>(ResultEnum.NOT_FIND);
        }
        userDto.setFloorId(floor.getId());
        userDto.setFloorName(floor.getName());

        Unit unit = this.unitServiceInterface.findUnitById(floor.getUnitId());
        if (null == unit) {
            return new ResultBean<>(ResultEnum.NOT_FIND);
        }
        userDto.setUnitId(unit.getId());
        userDto.setUnitName(unit.getName());

        Building building = this.buildingServiceInterface.findBuildingById(unit.getBuildingId());
        if (null == building) {
            return new ResultBean<>(ResultEnum.NOT_FIND);
        }
        userDto.setBuildingId(building.getId());
        userDto.setBuildingName(building.getName());

        Residential residential = this.residentialServiceInterface.findResidentialById(building.getResidentialId());
        if (null == residential) {
            return new ResultBean<>(ResultEnum.NOT_FIND);
        }
        userDto.setResidentialId(residential.getId());
        userDto.setResidentialName(residential.getName());

        if (null != this.findUserByCondition(userDto)) {
            if (StringUtils.isEmpty(userDto.getOldId())) {
                return new ResultBean<>(EstateEnum.USER_DATA_EXISTES);
            }
            userDto.setName(userDto.getName() + userDto.getOldId());
        }
        userDto.setRegionProvince(residential.getRegionProvince());
        userDto.setRegionCity(residential.getRegionCity());
        userDto.setRegionArea(residential.getRegionArea());
        if (null == userDto.getCheckState()) {
            if(userDto.getImageUri() == null){
                userDto.setCheckState(OperationConstant.MINUS_ONE); //待上传
            }else{
                userDto.setCheckState(OperationConstant.ZERO); //待审核
            }
        }
        userDto.setRootOrgId(room.getRootOrgId());
        userDto.setCreateDate(new Date());
        userDto.setStatus(OperationConstant.ZERO);
        userDto.setIsMember(OperationConstant.ZERO);
        userDto.setId(IdWorker.getId());
        userDto.setOrgPosition(room.getOrgPosition() + userDto.getId() + SymbolConstant.BACK_SLASH);
        //************************保存物业路径
        userDto.setEstatePosition(room.getEstatePosition() + userDto.getId() + SymbolConstant.BACK_SLASH);
        //************************保存物业路径
        //人脸待启用
        if (null == userDto.getFaceEnable()) {
            if(null == userDto.getImageUri()){
                userDto.setFaceEnable(OperationConstant.MINUS_ONE);
            }else{
                userDto.setFaceEnable(OperationConstant.ZERO);
            }
        }
        //卡待启用
        userDto.setCardEnable(OperationConstant.ZERO);
        if(this.insert(userDto)){
            //小区住户数量加+1
            residential.setUserNumber(residential.getUserNumber() + 1);
            if (this.residentialServiceInterface.updateById(residential)) {
                //单元住户数量加+1
                unit.setUserNumber(unit.getUserNumber() + 1);
                if (this.unitServiceInterface.updateById(unit)) {
                    //房间住户加+1
                    room.setUserNumber(room.getUserNumber() + 1);
                    if (this.roomServiceInterface.updateById(room)) {
                        List<User> list = new ArrayList<>();
                        list.add(userDto);
                        //  关联匹配一次会员
                        this.associatedMember(list);
                        return new ResultBean<>(ResultEnum.SUCCESS, true);
                    }
                }
            }
        }

        return new ResultBean<>(ResultEnum.ERROR);
    }

    @Override
    public User findUserById(Long id) {
        Wrapper<User> wrapper = new EntityWrapper<>();
        wrapper.eq("l_id",id);
        //过滤删除
        wrapper.notIn("i_status", OperationConstant.MINUS_ONE);
        return this.selectOne(wrapper);
    }

    @Override
    public User byTelAndName(UserDto userDto) {
        Wrapper<User> wrapper = new EntityWrapper<>();
        wrapper.eq("i_status",OperationConstant.ZERO);
        wrapper.eq(userDto.getName() != null, "s_name",userDto.getName());
        wrapper.eq(userDto.getTel() != null, "s_tel",userDto.getName());
        wrapper.eq(userDto.getResidentialId() !=null,"l_residential_id",userDto.getResidentialId());
        List<User> users = this.selectList(wrapper);
        if(users.size()>0){
            return users.get(0);
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public ResultBean<Boolean> updateUser(UserDto userDto) {
        //先通过其他字段，非ID查询的方式，查看是否已经存在住户，如果查到，说明两个以上相同的用户，但只是ID不同，不满足唯一性
        if (null != this.findUserByCondition(userDto)) {
            return new ResultBean<>(EstateEnum.USER_DATA_EXISTES);
        }
        //非海外用户 置空护照和入境照片
        /*if(userDto.getNationality() != 3){
            userDto.setPassportImgUri("");
            userDto.setEntryImgUri("");
        }*/
        if (this.updateById(userDto)){ //可以放心的通过ID进行更新
            //检测是否要生成视频账号
            User user = this.selectById(userDto.getId());
            this.matchMember(user);
            return new ResultBean<>(ResultEnum.SUCCESS, true);
        }
        return new ResultBean<>(ResultEnum.ERROR);
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public ResultBean<Boolean> deleteUser(UserDto userDto) {
        User user = this.findUserById(userDto.getId());
        if (null == user) {
            return new ResultBean<>(ResultEnum.ERROR);
        }
        Room room = this.roomServiceInterface.findRoomById(user.getRoomId());
        if (null == room) {
            return new ResultBean<>(ResultEnum.ERROR);
        }
        Unit unit = this.unitServiceInterface.findUnitById(room.getUnitId());
        if (null == unit) {
            return new ResultBean<>(ResultEnum.ERROR);
        }
        Residential residential = this.residentialServiceInterface.findResidentialById(unit.getResidentialId());
        if (null == residential) {
            return new ResultBean<>(ResultEnum.ERROR);
        }
        user.setStatus(userDto.getStatus());
        if (this.deleteById(user)) {
            //小区住户数量加-1
            residential.setUserNumber(residential.getUserNumber() - 1);
            if (this.residentialServiceInterface.updateById(residential)) {
                //单元住户数量加-1
                unit.setUserNumber(unit.getUserNumber() - 1);
                if (this.unitServiceInterface.updateById(unit)) {
                    //房间住户加-1
                    room.setUserNumber(room.getUserNumber() - 1);
                    if (this.roomServiceInterface.updateById(room)) {
                        //删除下发的人脸
                        deletePushUserFace(user);
                        this.deleteCache(user);
                        //处理删除user后，与之关联的会员状态
                        this.dealMemberState(userDto.getId());
                        //删除和住户关联的视频通话账号
//                            this.videoCallAccountServiceInterface.deleteAccountByUserId(userDto.getId());
                        return new ResultBean<>(ResultEnum.SUCCESS, true);
                    }
                }
            }
        }
        return new ResultBean<>(ResultEnum.ERROR);
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public ResultBean<Boolean> trashOrRecover(UserDto userDto) {
        User user = this.findUserById(userDto.getId());
        if (null == user) {
            return new ResultBean<>(ResultEnum.ERROR);
        }
        Room room = this.roomServiceInterface.findRoomById(user.getRoomId());
        if (null == room) {
            return new ResultBean<>(ResultEnum.ERROR);
        }
        Unit unit = this.unitServiceInterface.findUnitById(room.getUnitId());
        if (null == unit) {
            return new ResultBean<>(ResultEnum.ERROR);
        }
        Residential residential = this.residentialServiceInterface.findResidentialById(unit.getResidentialId());
        if (null == residential) {
            return new ResultBean<>(ResultEnum.ERROR);
        }
        user.setStatus(userDto.getStatus());
        if (this.updateById(user)) {
            //删除关联卡及下发的卡号
            if(this.accessCardServiceInterface.deleteAccessCardByUserIdAndType(String.valueOf(user.getId()),OperationConstant.ZERO)){
                //删除下发的人脸
                deletePushUserFace(user);
                this.deleteCache(user);
                //处理删除user后，与之关联的会员状态
                this.dealMemberState(userDto.getId());
                //删除和住户关联的视频通话账号
                this.videoCallAccountServiceInterface.deleteAccountByUserId(userDto.getId());
                return new ResultBean<>(ResultEnum.SUCCESS, true);
            }
        }
        return new ResultBean<>(ResultEnum.ERROR);
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public ResultBean<Boolean> deleteUserList(UserDto userDto) throws Exception {
        List<String> ids = userDto.getIds();
        String msg ;
        for(String id : ids){
            User user = this.findUserById(Long.valueOf(id));
            if (null == user) {
                msg = "住户不存在，请核实后重新操作";
                throw new Exception(msg);
            }
            Room room = this.roomServiceInterface.findRoomById(user.getRoomId());
            if (null == room) {
                msg = user.getName()+"所属房间不存在，请核实后重新操作";
                throw new Exception(msg);
            }
            Unit unit = this.unitServiceInterface.findUnitById(room.getUnitId());
            if (null == unit) {
                msg = user.getName()+"所属单元不存在，请核实后重新操作";
                throw new Exception(msg);
            }
            Residential residential = this.residentialServiceInterface.findResidentialById(unit.getResidentialId());
            if (null == residential) {
                msg = user.getName()+"所属小区不存在，请核实后重新操作";
                throw new Exception(msg);
            }
            user.setStatus(OperationConstant.MINUS_ONE);
            if (this.updateById(user)) {
                //小区住户数量加-1
                residential.setUserNumber(residential.getUserNumber() - 1);
                if (this.residentialServiceInterface.updateById(residential)) {
                    //单元住户数量加-1
                    unit.setUserNumber(unit.getUserNumber() - 1);
                    if (this.unitServiceInterface.updateById(unit)) {
                        //房间住户加-1
                        room.setUserNumber(room.getUserNumber() - 1);
                        if(this.roomServiceInterface.updateById(room)){
                            //删除关联卡及下发的卡号
                           if(this.accessCardServiceInterface.deleteAccessCardByUserIdAndType(String.valueOf(user.getId()),OperationConstant.ZERO)){
                               //删除下发的人脸
                               this.deletePushUserFace(user);
                               this.deleteCache(user);
                               //处理删除user后，与之关联的会员状态
                               this.dealMemberState(Long.valueOf(id));
                               //删除与住户关联的视频账号
                               this.videoCallAccountServiceInterface.deleteAccountByUserId(Long.valueOf(id));
                           }else{
                               msg = user.getName()+"关联卡删除失败，请核实后重新操作";
                               throw new Exception(msg);
                           }
                        }
                    }
                }
            }
        }
        return new ResultBean<>(ResultEnum.SUCCESS,true);
    }

    @Override
    public ResultBean<User> findListByPosition(UserDto userDto) {
        Wrapper<User> wrapper = new EntityWrapper<>();
        //过滤删除
        wrapper.notIn("i_status", OperationConstant.MINUS_ONE);
        //根据机构
        if (StringUtils.isNotBlank(userDto.getOrgPosition())) {
            wrapper.like("s_org_position", userDto.getOrgPosition(), SqlLike.RIGHT);
        }
        //根据物业
        if (StringUtils.isNotBlank(userDto.getEstatePosition())) {
            wrapper.like("s_estate_position", userDto.getEstatePosition(), SqlLike.RIGHT);
        }
        return new ResultBean<>(ResultEnum.SUCCESS, this.selectList(wrapper));
    }

    @Override
    public ResultBean<Boolean> updateUserCheckState(UserDto userDto) {
        User user = this.findUserById(userDto.getId());
        if (null == user) {
            return new ResultBean<>(ResultEnum.ERROR);
        }
        user.setCheckState(userDto.getCheckState());
        if(StringUtils.isNotBlank(userDto.getCheckOpinion())){
            user.setCheckOpinion(userDto.getCheckOpinion());
        }
        if (this.updateById(user)) {
            return new ResultBean<>(ResultEnum.SUCCESS, true);
        }
        return new ResultBean<>(ResultEnum.ERROR);
    }

    @Override
    public String getUserNameById(Serializable id) {
        Wrapper<User> wrapper = new EntityWrapper<>();
        wrapper.setSqlSelect("s_name");
        //过滤删除
        wrapper.notIn("i_status", OperationConstant.MINUS_ONE);
        //id查询
        wrapper.eq("l_id", id);
        String userName = (String) this.selectObj(wrapper);
        return userName;
    }

    @Override
    public Map<String, Object> statisticsUserCount(UserDto userDto) {
        //当前时间的上个月
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.MONTH, -1);
        Date statisticsDate = calendar.getTime();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
        String statisticsDateStr = sdf.format(statisticsDate);
        Wrapper<User> wrapper = new EntityWrapper<>();
        String sqlSelect = "SUM(1) AS userTotalCount,SUM(CASE WHEN DATE_FORMAT(t_create_date,'%Y%m')='" + statisticsDateStr + "' THEN 1 ELSE 0 END) AS lastMonthNewUserCount," +
                "SUM(CASE WHEN i_type=2 THEN 1 ELSE 0 END) AS tenantUserCount,SUM(CASE WHEN i_create_type=0 THEN 1 ELSE 0 END) AS weiXinUserCount";
        wrapper.setSqlSelect(sqlSelect);
        //过滤删除
        wrapper.notIn("i_status", OperationConstant.MINUS_ONE);
        //机构位置
        String orgPosition = userDto.getOrgPosition();
        if (StringUtils.isNotBlank(orgPosition)) {
            wrapper.like("s_org_position", orgPosition, SqlLike.RIGHT);
        }
        Map<String, Object> map = this.selectMap(wrapper);
        return map;
    }

    @Override
    public List<User> getUserByTelAndName(Member member) {
        Wrapper<User> wrapper = new EntityWrapper<>();
        if (!StringUtils.isEmpty(member.getName())){
            //名字
            wrapper.eq("s_name", member.getName());
        }
        //电话
        wrapper.eq("s_tel", member.getTel());
        //过滤删除
        wrapper.eq("i_status", OperationConstant.ZERO);
        //机构
        wrapper.like("s_org_position", member.getOrgPosition());
        return this.selectList(wrapper);
    }

    @Override
    public User getUserByNameAndRoomId(String name, Long roomId) {
        Wrapper<User> wrapper = new EntityWrapper<>();
        //名字
        wrapper.eq("s_name", name);
        //房间号
        wrapper.eq("l_room_id", roomId);
        //过滤删除
        wrapper.eq("i_status", OperationConstant.ZERO);
        return this.selectOne(wrapper);
    }

    @Override
    public ResultBean<Boolean> checkByNameAndRoomId(UserDto userDto) {
        Wrapper<User> wrapper = new EntityWrapper<>();
        //名字
        wrapper.eq("s_name", userDto.getName());
        //房间号
        wrapper.eq("l_room_id", userDto.getRoomId());
        //过滤删除
        wrapper.eq("i_status", OperationConstant.ZERO);
        int count = this.selectCount(wrapper);
        if(count>0){
            return new ResultBean<>(ResultEnum.SUCCESS,true);
        }
        return new ResultBean<>(ResultEnum.SUCCESS,false);
    }

    @Override
    public List<User> getListByRoomId(List<Long> roomIds) {
        Wrapper<User> wrapper = new EntityWrapper<>();
        //过滤删除
        wrapper.eq("i_status", OperationConstant.ZERO);
        //房间id
        wrapper.in("l_room_id", roomIds);
        return this.selectList(wrapper);
    }

    @Override
    public Page<User> pagingByRoomId(UserDto userDto) {
        Wrapper<User> wrapper = new EntityWrapper<>();
        //过滤删除
        wrapper.eq("i_status", OperationConstant.ZERO);
        //房间id
        wrapper.in(userDto.getRoomIds() != null ,"l_room_id", userDto.getRoomIds());
        return this.selectPage(userDto.getPage(),wrapper);
    }

    @Override
    public List<User> getListByUserId(List<Long> userIds) {
        Wrapper<User> wrapper = new EntityWrapper<>();
        //过滤删除
        wrapper.eq("i_status", OperationConstant.ZERO);
        //用户id
        wrapper.in("l_id", userIds);
        return this.selectList(wrapper);
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public ResultBean<Boolean> deleteUserAndRelationship(UserDto userDto){
        User user = new User();
        user.setId(userDto.getId());
        //状态删除
        user.setStatus(OperationConstant.MINUS_ONE);
        User dbUser = this.selectById(userDto.getId());
        Boolean result = this.deleteById(user);
        if(result){
            //修改住户数量
//            user = this.selectById(userDto.getId());
//            if (null == user) {
//                return new ResultBean<>(ResultEnum.ERROR);
//            }
            Room room = this.roomServiceInterface.findRoomById(dbUser.getRoomId());
            if (null == room) {
                return new ResultBean<>(ResultEnum.ERROR);
            }
            Unit unit = this.unitServiceInterface.findUnitById(room.getUnitId());
            if (null == unit) {
                return new ResultBean<>(ResultEnum.ERROR);
            }
            Residential residential = this.residentialServiceInterface.findResidentialById(unit.getResidentialId());
            if (null == residential) {
                return new ResultBean<>(ResultEnum.ERROR);
            }
            //小区住户数量加-1
            residential.setUserNumber(residential.getUserNumber() - 1);
            if (this.residentialServiceInterface.updateById(residential)) {
                //单元住户数量加-1
                unit.setUserNumber(unit.getUserNumber() - 1);
                if (this.unitServiceInterface.updateById(unit)) {
                    //房间住户加-1
                    room.setUserNumber(room.getUserNumber() - 1);
                    this.roomServiceInterface.updateById(room);
                }
            }
            //处理删除user后，与之关联的会员状态
            result = this.dealMemberState(userDto.getId());
        }
        return  new ResultBean<>(ResultEnum.SUCCESS,result);
    }

    /**
     * 处理删除user后，与之关联的会员状态
     *
     */
    private boolean dealMemberState(Long userId){
        boolean result = false;
        //查询和user有关系的会员
        MemberAndUser condition = new MemberAndUser();
        condition.setUserId(userId);
        List<MemberAndUser> list = this.memberAndUserInterface.getByCondition(condition);
        if(list!=null && list.size()>0){
            Wrapper<MemberAndUser> wrapper = new EntityWrapper<>();
            wrapper.eq("l_user_id", userId);
            //删除和user有关系的
            result = this.memberAndUserInterface.delete(wrapper);
            if(result){
                //修改与之关联的会员状态
                for (MemberAndUser mau:list){
                    //重新拼凑查询条件，查询与member关联的user个数
                    condition.setUserId(null);
                    condition.setMemberId(mau.getMemberId());
                    //统计
                    int count = this.memberAndUserInterface.countByCondition(condition);
                    //会员已经没有了关联的住户，会员状态改为未认证
                    if(count==0){
                        ApplyUserDto applyUserDto = new ApplyUserDto();
                        applyUserDto.setUserId(userId);

//                        Member update = new Member();
//                        update.setId(mau.getMemberId());
//                        //修改会员状态 ----未认证
//                        update.setState(OperationConstant.ZERO);
                        result = this.memberServiceInterface.deleteById(mau.getMemberId());
                    }
                }
            }
        }else {
            result = true;
        }
        return result;
    }


    @Override
    public int getUserAccount(UserDto userDto) {
        Wrapper<User> wrapper = new EntityWrapper<>();
        wrapper.like("s_org_position",userDto.getOrgPosition(),SqlLike.RIGHT);
        //当月新增
        if(OperationConstant.TWO == userDto.getIsAllType()){
            wrapper.and("DATE_FORMAT(t_create_date,'%Y%m')=DATE_FORMAT(NOW(),'%Y%m')");
        }
        //过滤删除
        wrapper.notIn("i_status", OperationConstant.MINUS_ONE);
        return this.selectCount(wrapper);
    }

    private final DeviceFeign deviceFeign;

    @Override
    public ResultBean<Boolean> addOrUpdateUserFaceImage(UserDto userDto) {
        User user = this.findUserById(userDto.getId());
        if (null == user) {
            return new ResultBean<>(ResultEnum.ERROR);
        }
        Residential residential = this.residentialServiceInterface.findResidentialById(user.getResidentialId());
        if (null == residential) {
            return new ResultBean<>(ResultEnum.ERROR);
        }
        boolean isDelete = false;
        boolean isUpdateOrAdd = false;
        boolean isUpdate = false;
        if(StringUtils.isBlank(user.getImageUri())){
            if(StringUtils.isNotBlank(userDto.getImageUri())){
                //新增
                user.setFaceBeginDate(userDto.getFaceBeginDate());
                user.setFaceEndDate(userDto.getFaceEndDate());
                user.setImageUri(userDto.getImageUri());
                user.setFaceCode(userDto.getFaceCode());
                user.setCreateFaceImageType(OperationConstant.ONE);
                user.setFaceEnable(OperationConstant.ONE);
                if (this.updateById(user)) {
                    residential.setUserFaceNumber(residential.getUserNumber()+1);
                    if(this.residentialServiceInterface.updateById(residential)){
                        isUpdateOrAdd = true;
                        isUpdate = false;
                    }else {
                        return new ResultBean<>(ResultEnum.ERROR);
                    }
                }else{
                    return new ResultBean<>(ResultEnum.ERROR);
                }
            }else{
                return new ResultBean<>(ResultEnum.SUCCESS, true);
            }
        }else {
            if(StringUtils.isNotBlank(userDto.getImageUri())){
                if(!userDto.getImageUri().equals(user.getImageUri())){
                    //修改
                    user.setFaceBeginDate(userDto.getFaceBeginDate());
                    user.setFaceEndDate(userDto.getFaceEndDate());
                    user.setImageUri(userDto.getImageUri());
                    user.setFaceCode(userDto.getFaceCode());
                    user.setCreateFaceImageType(OperationConstant.ONE);
                    if (this.updateById(user)) {
                        isUpdateOrAdd = true;
                        isUpdate = true;
                    }else{
                        return new ResultBean<>(ResultEnum.ERROR);
                    }
                }else{
                    user.setFaceBeginDate(userDto.getFaceBeginDate());
                    user.setFaceEndDate(userDto.getFaceEndDate());
                    if (this.updateById(user)) {
                        isUpdateOrAdd = true;
                        isUpdate = true;
                    }else{
                        return new ResultBean<>(ResultEnum.ERROR);
                    }
                }
            }else{
                //删除
                user.setImageUri(null);
                user.setFaceCode(null);
                user.setCreateFaceImageType(null);
                if (this.baseMapper.deleteUserFaceImage(user) > 0) {
                    residential.setUserFaceNumber(residential.getUserNumber()-1);
                    if(this.residentialServiceInterface.updateById(residential)){
                        isDelete = true;
                    }else {
                        return new ResultBean<>(ResultEnum.ERROR);
                    }
                }else{
                    return new ResultBean<>(ResultEnum.ERROR);
                }
            }
        }

        Map<String,String> logMap = new HashMap<>();
        //小区
        if (!StringUtils.isEmpty(user.getResidentialName())){
            logMap.put("xqName",user.getResidentialName());
        }else {
            logMap.put("xqName",null);
        }
        //单元
        if (!StringUtils.isEmpty(user.getUnitName())){
            logMap.put("unitName",user.getUnitName());
        }else {
            logMap.put("unitName",null);
        }
        //房间
        if (!StringUtils.isEmpty(user.getRoomName())){
            logMap.put("roomName",user.getRoomName());
        }else {
            logMap.put("roomName",null);
        }
        //用户名
        if (!StringUtils.isEmpty(user.getName())){
            logMap.put("userName",user.getName());
        }else {
            logMap.put("userName",null);
        }

        if(isDelete){
            //  下发人脸
            UserInfoDto dto = new UserInfoDto();
            dto.setId(UserFlagConstant.USER_NUMBER_FLAG + user.getId());
            DispatchTask task = new DispatchTask();
            task.setXqId(user.getResidentialId());
            task.setUnitId(user.getUnitId());
            task.setData(dto);
            Integer deviceAccessType = userDto.getDeviceAccessType();
            if(deviceAccessType != null && deviceAccessType.equals(DeviceConstants.DEVICE_ACCESS_TYPE_UNIVERSAL)){
                this.deviceFeign.deleteUserFaceToUniversalDevices(task, logMap);
            }else{
                this.deviceFeign.pushUserFace(task,logMap);
            }
        }
        if(isUpdateOrAdd){
            String imgHost = this.confFeign.getFileServerHost();
            List<Map<String,Object>> userFaceList = new ArrayList<>(1);
            Map<String,Object> map = new HashMap<>(3);
            map.put("imgMd5",user.getFaceCode());
            map.put("imgSrc",imgHost + user.getImageUri());
            userFaceList.add(map);
            //  下发人脸
            UserInfoDto dto = new UserInfoDto();
            dto.setId(UserFlagConstant.USER_NUMBER_FLAG + user.getId());
            dto.setName(user.getName());
            dto.setFaceCodeList(userFaceList);
            dto.setBeginDate(user.getFaceBeginDate());
            dto.setEndDate(user.getFaceEndDate());
            DispatchTask task = new DispatchTask();
            task.setUnitId(user.getUnitId());
            task.setXqId(user.getResidentialId());
            task.setData(dto);
            Integer deviceAccessType = userDto.getDeviceAccessType();
            if(deviceAccessType != null && deviceAccessType.equals(DeviceConstants.DEVICE_ACCESS_TYPE_UNIVERSAL)){
                this.deviceFeign.pushUserFaceToUniversalDevices(task, !isUpdate ? OperationConstant.ONE : OperationConstant.TWO,logMap);
            }else{
                this.deviceFeign.pushUserFace(task,logMap);
            }
        }
        //人脸审核状态改为通过
        if(user.getCheckState() != null && user.getCheckState() == -1 || user.getCheckState() == 0){
            user.setCheckState(OperationConstant.ONE);
//            user.setFaceEnable(OperationConstant.ONE);
            boolean isUpDateCheckState=this.updateById(user);
            if(!isUpDateCheckState){
                return new ResultBean<>(ResultEnum.ERROR);
            }
        }
        return new ResultBean<>(ResultEnum.SUCCESS, true);
    }

    /**
     * 仅添加或修改住户人脸图片（但不下发人脸）
     * @param userDto 住户业务传输对象
     * @return
     */
    @Override
    public ResultBean<Boolean> simpleAddOrUpdateUserFaceImage(UserDto userDto) {
        User user = this.findUserById(userDto.getId());
        if (null == user) {
            return new ResultBean<>(ResultEnum.ERROR, false);
        }
        Residential residential = this.residentialServiceInterface.findResidentialById(user.getResidentialId());
        if (null == residential) {
            return new ResultBean<>(ResultEnum.ERROR, false);
        }
        if(StringUtils.isBlank(user.getImageUri())){
            if(StringUtils.isNotBlank(userDto.getImageUri())){
                //新增
                user.setImageUri(userDto.getImageUri());
                user.setFaceCode(userDto.getFaceCode());
                user.setCreateFaceImageType(OperationConstant.ONE);
                user.setFaceBeginDate(userDto.getFaceBeginDate());
                user.setFaceEndDate(userDto.getFaceEndDate());
                if (this.updateById(user)) {
                    residential.setUserFaceNumber(residential.getUserNumber()+1);
                    if(this.residentialServiceInterface.updateById(residential)){

                    }else {
                        return new ResultBean<>(ResultEnum.ERROR, false);
                    }
                }else{
                    return new ResultBean<>(ResultEnum.ERROR, false);
                }
            }else{
                return new ResultBean<>(ResultEnum.SUCCESS, true);
            }
        }else {
            if(StringUtils.isNotBlank(userDto.getImageUri())){
                if(!userDto.getImageUri().equals(user.getImageUri())){
                    //修改
                    user.setImageUri(userDto.getImageUri());
                    user.setFaceCode(userDto.getFaceCode());
                    user.setCreateFaceImageType(OperationConstant.ONE);
                    user.setFaceBeginDate(userDto.getFaceBeginDate());
                    user.setFaceEndDate(userDto.getFaceEndDate());
                    if (this.updateById(user)) {

                    }else{
                        return new ResultBean<>(ResultEnum.ERROR, false);
                    }
                }else{
                    user.setFaceBeginDate(userDto.getFaceBeginDate());
                    user.setFaceEndDate(userDto.getFaceEndDate());
                    return new ResultBean<>(ResultEnum.SUCCESS, this.updateById(user));
                }
            }else{
                //删除
                user.setImageUri(null);
                user.setFaceCode(null);
                user.setCreateFaceImageType(null);
                if (this.baseMapper.deleteUserFaceImage(user) > 0) {
                    residential.setUserFaceNumber(residential.getUserNumber()-1);
                    if(this.residentialServiceInterface.updateById(residential)){

                    }else {
                        return new ResultBean<>(ResultEnum.ERROR, false);
                    }
                }else{
                    return new ResultBean<>(ResultEnum.ERROR, false);
                }
            }
        }
        //人脸审核状态改为通过
        if(user.getCheckState()!=null&&user.getCheckState()==0){
            user.setCheckState(OperationConstant.ONE);
            boolean isUpDateCheckState=this.updateById(user);
            if(!isUpDateCheckState){
                return new ResultBean<>(ResultEnum.ERROR, false);
            }
        }
        return new ResultBean<>(ResultEnum.SUCCESS, true);
    }

    /**
     * 文祥添加：下发人脸操作
     * @param userDto 住户业务传输对象
     * @return
     */
    @Override
    public ResultBean<Boolean> sendUserFaceImage(UserDto userDto) {
        User user = this.findUserById(userDto.getId());
        if (null == user) return new ResultBean<>(ResultEnum.ERROR, false);
        DevicesAccessPushVO devicesAccessPushVO = userDto.getDevicesAccessPushVO();
        //人脸下发操作类型：1，特殊授权下发，2：禁用，3：启用或重新启用
        Integer operType = devicesAccessPushVO.getOperType();
        if(operType.equals(OperationConstant.ONE)){
            if(StringUtils.isBlank(user.getImageUri())){ //特殊人脸授权下发到设备
                return new ResultBean<>(EstateEnum.IS_NOT_FACE);
            }else{
                String imgHost = this.confFeign.getFileServerHost();
                List<Map<String,Object>> userFaceList = new ArrayList<>(1);
                Map<String,Object> map = new HashMap<>(3);
                map.put("imgMd5",user.getFaceCode());
                map.put("imgSrc",imgHost + user.getImageUri());
                userFaceList.add(map);
                if(devicesAccessPushVO.getDeviceIdList() == null || devicesAccessPushVO.getDeviceIdList().size() <= 0){
                    return new ResultBean<>(ResultEnum.PARAMETER_ANOMALY, true);
                }
                List<Long> deviceIdList = devicesAccessPushVO.getDeviceIdList();
                //  下发人脸（添加或更新设备上的人脸）
                UserInfoDto dto = new UserInfoDto();
                dto.setId(UserFlagConstant.USER_FLAG + user.getId());
                dto.setFaceCodeList(userFaceList);
                dto.setBeginDate(user.getFaceBeginDate());
                dto.setEndDate(user.getFaceEndDate());
                ManualPushDevicesTask task = new ManualPushDevicesTask();
                task.setDeviceIdList(deviceIdList);
                task.setData(dto);
                this.deviceFeign.manualPushUserFaceToDevices(task);
            }
            if(user.getFaceEnable()!=null&&(user.getFaceEnable()==0 || user.getFaceEnable() == 2)){
                user.setFaceEnable(OperationConstant.ONE);
                boolean isUpDateFaceEnable=this.updateById(user);
                if(!isUpDateFaceEnable){
                    return new ResultBean<>(ResultEnum.ERROR);
                }
            }
        }else if(operType.equals(OperationConstant.TWO)){
            //  下发人脸(删除设备上人脸)
            UserInfoDto dto = new UserInfoDto();
            dto.setId(UserFlagConstant.USER_FLAG + user.getId());
            dto.setFaceCodeList(new ArrayList<>(0));
            DispatchTask task = new DispatchTask();
            task.setXqId(user.getResidentialId());
            task.setUnitId(user.getUnitId());
            task.setData(dto);
            Map<String,String> logMap = new HashMap<>();
            //小区
            if (!StringUtils.isEmpty(user.getResidentialName())){
                logMap.put("xqName",user.getResidentialName());
            }else {
                logMap.put("xqName",null);
            }
            //单元
            if (!StringUtils.isEmpty(user.getUnitName())){
                logMap.put("unitName",user.getUnitName());
            }else {
                logMap.put("unitName",null);
            }
            //房间
            if (!StringUtils.isEmpty(user.getRoomName())){
                logMap.put("roomName",user.getRoomName());
            }else {
                logMap.put("roomName",null);
            }
            //用户名
            if (!StringUtils.isEmpty(user.getName())){
                logMap.put("userName",user.getName());
            }else {
                logMap.put("userName",null);
            }
            //有效期开始时间
            SimpleDateFormat format = new SimpleDateFormat();
            if (null != dto.getBeginDate()){
                logMap.put("beginTime",format.format(dto.getBeginDate()));
            }else {
                logMap.put("beginTime",null);
            }
            //有效期结束时间
            if (null != dto.getEndDate()){
                logMap.put("endTime",format.format(dto.getEndDate()));
            }else {
                logMap.put("endTime",null);
            }
            //人脸
            if (dto.getFaceCodeList().size() > 0){
                List<String> list = new ArrayList<>();
                for (Map m : dto.getFaceCodeList()) {
                    if (m.containsKey("imgSrc")){
                        list.add(m.get("imgSrc").toString());
                    }
                }
                logMap.put("imgSrc", JsonUtils.listToString(list));
            }else {
                logMap.put("imgSrc",null);
            }
            this.deviceFeign.pushUserFace(task,logMap);
            if(user.getFaceEnable()!=null&&user.getFaceEnable()==1){
                user.setFaceEnable(OperationConstant.TWO);
                boolean isUpDateFaceEnable=this.updateById(user);
                if(!isUpDateFaceEnable){
                    return new ResultBean<>(ResultEnum.ERROR);
                }
            }
        }
        return new ResultBean<>(ResultEnum.SUCCESS, true);
    }

    @Override
    public ResultBean<Boolean> deleteUserFaceImageBatch(List<Long> ids) {
        //  下发人脸(删除设备上人脸)
        List<User> users = this.selectBatchIds(ids);
        List<FaceInfoDto> faceInfoDtoList = new ArrayList<>();
        for(int i = 0; i < users.size(); i++){
            User user = users.get(i);
            if (user.getFaceEnable() != OperationConstant.ONE){
                continue;
            }
            user.setFaceEnable(OperationConstant.TWO); //禁用人脸
            FaceInfoDto faceInfoDto = new FaceInfoDto();
            faceInfoDto.setId(UserFlagConstant.USER_FLAG + user.getId());
            faceInfoDto.setResidentialId(user.getResidentialId());
            faceInfoDto.setUnitId(user.getUnitId());
            faceInfoDtoList.add(faceInfoDto);
        }
        Assert.isTrue(faceInfoDtoList.size() != 0,"没有需要禁用的人脸");
        if(this.updateBatchById(users, 1000)){
            this.deviceFeign.deleteUserFaceBatch(faceInfoDtoList);
            return new ResultBean<>(ResultEnum.SUCCESS, true);
        }else{
            return new ResultBean<>(ResultEnum.ERROR, false);
        }
    }

    @Override
    public ResultBean<Boolean> issueUserFaceImageBatch(List<SimpleUserDto> simpleUserDtoList) {
        //先保存好批量用户信息
        List<FaceInfoDto> faceInfoDtoList = this.editUserFace(simpleUserDtoList);
        //再下发用户信息到设备
        ResultBean<Boolean> resultBean = this.deviceFeign.issueUserFaceBatch(faceInfoDtoList);
        return resultBean;
    }

    private List<FaceInfoDto> editUserFace(List<SimpleUserDto> simpleUserDtoList){
        List<User> users = new ArrayList<>();
        for(int i = 0; i < simpleUserDtoList.size(); i++){
            SimpleUserDto simpleUserDto = simpleUserDtoList.get(i);
            User user = this.findUserById(simpleUserDto.getId());
            if(user != null){
                Residential residential = this.residentialServiceInterface.findResidentialById(user.getResidentialId());
                if (residential != null) {
                    if(StringUtils.isBlank(user.getImageUri())){
                        if(StringUtils.isNotBlank(simpleUserDto.getImageUri())){
                            //新增
                            user.setImageUri(confFeign.getFileServerHost() + simpleUserDto.getImageUri());
                            user.setFaceCode(simpleUserDto.getFaceCode());
                            user.setCreateFaceImageType(OperationConstant.ONE);
                            user.setFaceBeginDate(simpleUserDto.getFaceBeginDate());
                            user.setFaceEndDate(simpleUserDto.getFaceEndDate());
                            user.setFaceEnable(OperationConstant.ONE);
                            residential.setUserFaceNumber(residential.getUserNumber()+1);
                            users.add(user);
                        }
                    }else{
                        if(StringUtils.isNotBlank(simpleUserDto.getImageUri())){
                            if(!user.getImageUri().equals(simpleUserDto.getImageUri())){
                                //修改
                                user.setImageUri(simpleUserDto.getImageUri());
                                user.setFaceCode(simpleUserDto.getFaceCode());
                                user.setCreateFaceImageType(OperationConstant.ONE);
                                user.setFaceBeginDate(simpleUserDto.getFaceBeginDate());
                                user.setFaceEndDate(simpleUserDto.getFaceEndDate());
                                user.setFaceEnable(OperationConstant.ONE);
                            }else{
                                //只修改有效期
                                user.setFaceBeginDate(simpleUserDto.getFaceBeginDate());
                                user.setFaceEndDate(simpleUserDto.getFaceEndDate());
                                user.setFaceEnable(OperationConstant.ONE);
                            }
                            users.add(user);
                        }
                    }
                }else{
                    continue;
                }
            }else{
                continue;
            }
        }
        if(this.updateBatchById(users, 100)){
            List<FaceInfoDto> faceInfoDtoList = new ArrayList<>();
            for (User user : users){
                FaceInfoDto faceInfoDto = new FaceInfoDto();
                faceInfoDto.setId(UserFlagConstant.USER_FLAG + user.getId());
                faceInfoDto.setName(user.getName());
                faceInfoDto.setUnitId(user.getUnitId());
                faceInfoDto.setResidentialId(user.getResidentialId());
                faceInfoDto.setBeginDate(user.getFaceBeginDate());
                faceInfoDto.setEndDate(user.getFaceEndDate());
                List<FaceCodeDto> faceCodeDtos = new ArrayList<>();
                FaceCodeDto faceCodeDto = new FaceCodeDto();
                faceCodeDto.setImgSrc(confFeign.getFileServerHost() + user.getImageUri());
                faceCodeDto.setImgMd5(user.getFaceCode());
                faceCodeDtos.add(faceCodeDto);
                faceInfoDto.setFaceCodeList(faceCodeDtos);
                faceInfoDtoList.add(faceInfoDto);
            }
            return faceInfoDtoList;
        }
        return null;
    }

    @Override
    public ResultBean<Boolean> deleteUserCardBatch(List<Long> cardIds) {
        //  下发删除门禁卡指令

        List<AccessCard> cardsList = this.accessCardServiceInterface.selectBatchIds(cardIds);
                List<AccessCard> list = new ArrayList<>();
        for(int i = 0; i < cardsList.size(); i++){
            AccessCard card = cardsList.get(i);
            if (card.getCardEnable() != OperationConstant.ONE){
                continue;
            }
                    card.setCardEnable(OperationConstant.TWO);
                    list.add(card);
                }
        Assert.isTrue(list.size() != 0,"没有需要禁用的门禁卡");
                ResultBean<Boolean> bean = accessCardServiceInterface.updateAccessCardList(list);
                Assert.isTrue(bean.getData(),"修改门禁卡状态异常");
        List<AccessCardSimpleDto> accessCardSimpleDtoList = new ArrayList<>();
        list.forEach(card ->{
                AccessCardSimpleDto accessCardSimpleDto = new AccessCardSimpleDto();
            accessCardSimpleDto.setId(card.getId());
            accessCardSimpleDto.setResidentialId(card.getResidentialId());
            accessCardSimpleDto.setUnitId(card.getUnitId());
                accessCardSimpleDtoList.add(accessCardSimpleDto);
        });
        Assert.notEmpty(accessCardSimpleDtoList, "没有需要禁用的门禁卡");
        this.deviceFeign.removePushCardBatch(accessCardSimpleDtoList);
        return new ResultBean<>(ResultEnum.SUCCESS, true);
    }

    /**
     * 手动下发人脸到指定设备上
     * @param devicesAccessPushVO
     * @return
     */
    @Override
    @Transactional(rollbackFor = {Exception.class} )
    public ResultBean<Boolean> accessDevicesManualPush(DevicesAccessPushVO devicesAccessPushVO){
        ResultBean<Boolean> resultBean = null;
        Integer operType = devicesAccessPushVO.getOperType();
        Integer pushMaterial = devicesAccessPushVO.getPushMaterial();
        Long userId = devicesAccessPushVO.getUserId();
        User user = findUserById(userId);
        if(null == user ){
            return new ResultBean<>(ResultEnum.ERROR,false);
        }
        //特殊授权下发
        if(operType.equals(OperationConstant.ONE)){
            List<Long> deviceIdList = devicesAccessPushVO.getDeviceIdList();
            Assert.notEmpty(deviceIdList, "请选择需要下发人脸的设备");
            switch (pushMaterial){
                case 0: //人脸和门禁卡同时下发到设备
                    if(StringUtils.isBlank(user.getImageUri())){ //人脸下发是基于用户已存在人脸
                        return new ResultBean<>(EstateEnum.IS_NOT_FACE);
                    }
                    List<AccessCard> list0 = accessCardServiceInterface.getAccessCardByUserIdAndType(String.valueOf(userId), OperationConstant.ZERO);
                    Assert.notEmpty(list0, "该用户未设置任何门禁卡");
                    AccessCard accessCard0 = list0.get(0);
                    Boolean checkPass0 = this.checkXqUnitDevicePermission(user, deviceIdList);
                    if(checkPass0){
                        //--------------下发人脸---------------------//
                        resultBean = this.handleSendUserFace(user, deviceIdList, true, devicesAccessPushVO.getBeginDate(), devicesAccessPushVO.getEndDate());
                        //----------------下发门禁卡-------------------//
                        resultBean = this.handleSendUserCard(accessCard0, OperationConstant.ONE, deviceIdList, true,devicesAccessPushVO.getBeginDate(), devicesAccessPushVO.getEndDate());
                    }
                    break;
                case 1: //仅人脸下发到设备
                    if(StringUtils.isBlank(user.getImageUri())){ //人脸下发是基于用户已存在人脸
                        return new ResultBean<>(EstateEnum.IS_NOT_FACE);
                    }
                    Boolean checkPass1 = this.checkXqUnitDevicePermission(user, deviceIdList);
                    if(checkPass1){
                        //--------------下发人脸---------------------//
                        resultBean = this.handleSendUserFace(user, deviceIdList, true,devicesAccessPushVO.getBeginDate(),devicesAccessPushVO.getEndDate());
                    }
                    break;
                case 2: //仅门禁卡下发到设备
                    List<AccessCard> list2 = accessCardServiceInterface.getAccessCardByUserIdAndType(String.valueOf(userId), OperationConstant.ZERO);
                    Assert.notEmpty(list2, "该用户未设置任何门禁卡");
                    AccessCard accessCard2 = list2.get(0);
                    Boolean checkPass2 = this.checkXqUnitDevicePermission(user, deviceIdList);
                    if(checkPass2){
                        //--------------下发门禁卡---------------------//
                        resultBean = this.handleSendUserCard(accessCard2, OperationConstant.ONE, deviceIdList, true,devicesAccessPushVO.getBeginDate(),devicesAccessPushVO.getEndDate());
                    }
                    break;
                default:
                    break;
            }
        }
        //同时删除设备上的人脸和门禁卡
        else if(operType.equals(OperationConstant.TWO)){
            //删除人脸，有则删除
            List<Long> disFaceDeviceIdList = new ArrayList<>();
            List<Device> faceDeviceList = this.deviceFeign.getDeviceByPathUseAndType(user.getResidentialId(), user.getUnitId(), DeviceConstants.DEVICE_ACCESS_TYPE_UNIVERSAL, OperationConstant.TWO);
            if(faceDeviceList != null && faceDeviceList.size() > 0){
                faceDeviceList.forEach(device -> disFaceDeviceIdList.add(device.getId()));
            }
            ResultBean<AccessFacePushRecords> faceResult = this.accessFacePushRecordsServiceInterface.getListByUserId(userId, OperationConstant.ZERO, null);
            List<AccessFacePushRecords> faceRecords = faceResult.getList();
            if(faceRecords != null && faceRecords.size() > 0){
                faceRecords.forEach(records -> {
                    disFaceDeviceIdList.add(records.getDeviceId());
                });
            }
            if(disFaceDeviceIdList.size() > 0){
                this.handleSendUserFace(user, disFaceDeviceIdList, false, null, null);
            }
            //删除卡片，有则删除
            List<AccessCard> cardList = this.accessCardServiceInterface.getAccessCardByUserIdAndType(String.valueOf(userId), OperationConstant.ZERO);
            if(cardList == null || cardList.size() <= 0){
                return new ResultBean<>(ResultEnum.SUCCESS,true);
            }
            List<Long> disCardDeviceIdList = new ArrayList<>();
            List<Device> cardDeviceList = this.deviceFeign.getDeviceByPathUseAndType(user.getResidentialId(), user.getUnitId(), DeviceConstants.DEVICE_ACCESS_TYPE_UNIVERSAL, OperationConstant.ONE);
            if(cardDeviceList != null && cardDeviceList.size() > 0){
                cardDeviceList.forEach(device -> disCardDeviceIdList.add(device.getId()));
            }
            if(disCardDeviceIdList.size() > 0){
                ResultBean<AccessCardPushRecords> cardResult = this.accessCardPushRecordsServiceInterface.getListByUserId(userId, OperationConstant.ZERO, OperationConstant.TWO);
                List<AccessCardPushRecords> cardRecords = cardResult.getList();
                if(cardRecords != null && cardRecords.size() > 0){
                    List<Long> disDeviceIdList = new ArrayList<>();
                    cardRecords.forEach(records -> {
                        disDeviceIdList.add(records.getDeviceId());
                    });
                    AccessCard accessCard = cardList.get(0);
                    this.handleSendUserCard(accessCard, OperationConstant.TWO, disDeviceIdList, false,null,null);
                    accessCard.setCardEnable(OperationConstant.TWO);
                    boolean b = this.accessCardServiceInterface.updateById(accessCard);
                    if(b){
                        return new ResultBean<>(ResultEnum.SUCCESS,true);
                    }else{
                        return new ResultBean<>(ResultEnum.ERROR);
                    }
                }
            }
            resultBean = new ResultBean<>(ResultEnum.SUCCESS, true);
        }
        //人脸启动
        else if(operType.equals(OperationConstant.THREE)){
            if(StringUtils.isBlank(user.getImageUri())){ //人脸下发是基于用户已存在人脸
                return new ResultBean<>(EstateEnum.IS_NOT_FACE);
            }
            //获取通用人脸机
            List<Device> deviceList = this.deviceFeign.getDeviceByPathUseAndType(user.getResidentialId(), user.getUnitId(), DeviceConstants.DEVICE_ACCESS_TYPE_UNIVERSAL, OperationConstant.TWO);
            //获取已下发的特殊人脸机
            ResultBean<AccessFacePushRecords> facePushResult = this.accessFacePushRecordsServiceInterface.getListByUserId(userId, OperationConstant.ZERO, OperationConstant.TWO);
            List<AccessFacePushRecords> faceRecords = facePushResult.getList();
            List<Long> enableDeviceIdList = new ArrayList<>();
            //添加普通设备位置的设备
            if (deviceList != null && deviceList.size() > 0){
                deviceList.forEach(device -> enableDeviceIdList.add(device.getId()));
            }
            //添加特殊设备位置的设备
            if(faceRecords != null && faceRecords.size() > 0){
                faceRecords.forEach(records -> enableDeviceIdList.add(records.getDeviceId()));
            }
            if (enableDeviceIdList.size() > 0){
                    resultBean = this.handleSendUserFace(user, enableDeviceIdList, true,null,null); //启用下发
            } else{ //新增启用设备
//                user.setFaceEnable(OperationConstant.ONE);
//                String imgHost = this.confFeign.getFileServerHost();
//                List<Map<String,Object>> userFaceList = new ArrayList<>(1);
//                Map<String,Object> map = new HashMap<>(3);
//                map.put("imgMd5",user.getFaceCode());
//                map.put("imgSrc",imgHost + user.getImageUri());
//                map.put("beginDate", user.getFaceBeginDate());
//                map.put("endDate", user.getFaceEndDate());
//                userFaceList.add(map);
//                //  下发人脸
//                UserInfoDto dto = new UserInfoDto();
//                dto.setId(UserFlagConstant.USER_FLAG + user.getId());
//                dto.setFaceCodeList(userFaceList);
//                DispatchTask task = new DispatchTask();
//                task.setUnitId(user.getUnitId());
//                task.setXqId(user.getResidentialId());
//                task.setData(dto);
//                this.deviceFeign.pushUserFaceToUniversalDevices(task, OperationConstant.ONE);
//                user.setFaceEnable(OperationConstant.ONE);
//                if(this.updateById(user)){
//                    resultBean = new ResultBean<>(ResultEnum.SUCCESS, true);
//                }else{
//                    resultBean = new ResultBean<>(ResultEnum.ERROR, false);
//                }
                user.setFaceEnable(OperationConstant.ONE);
                if(this.updateById(user)){
                    resultBean = new ResultBean<>(ResultEnum.SUCCESS, true);
                }else{
                    resultBean = new ResultBean<>(ResultEnum.ERROR, false);
                }
            }
        }
        //门禁卡启用
        else if(operType.equals(OperationConstant.FOUR)){
            List<AccessCard> cardList = this.accessCardServiceInterface.getAccessCardByUserIdAndType(String.valueOf(userId), OperationConstant.ZERO);
            Assert.notEmpty(cardList, "该用户没有门禁卡信息，无需禁用");
            ResultBean<AccessCardPushRecords> cardPushRecordsResult = this.accessCardPushRecordsServiceInterface.getListByUserId(userId, OperationConstant.ZERO, OperationConstant.TWO);
            List<AccessCardPushRecords> cardPushRecords = cardPushRecordsResult.getList();
            AccessCard accessCard = cardList.get(0);
            accessCard.setCardEnable(OperationConstant.ONE);
            if(this.accessCardServiceInterface.updateById(accessCard)){
                List<Long> enableDeviceIdList = new ArrayList<>();
                //获取通用门禁卡设备
                List<Device> deviceList = this.deviceFeign.getDeviceByPathUseAndType(user.getResidentialId(), user.getUnitId(), DeviceConstants.DEVICE_ACCESS_TYPE_UNIVERSAL, OperationConstant.ONE);
                //添加普通设备位置的设备
                if (deviceList != null && deviceList.size() > 0){
                    deviceList.forEach(device -> enableDeviceIdList.add(device.getId()));
                }
                //添加特殊设备位置的设备
                if(cardPushRecords != null && cardPushRecords.size() > 0){ //如果有下发记录，则增加下发过的设备
                    cardPushRecords.forEach(records -> enableDeviceIdList.add(records.getDeviceId()));
                }
                if(enableDeviceIdList.size() > 0){
                    resultBean = this.handleSendUserCard(accessCard, OperationConstant.TWO, enableDeviceIdList, true,devicesAccessPushVO.getBeginDate(),devicesAccessPushVO.getEndDate());
                }else{ //否则下发到一般授权设备
                    resultBean = accessCardServiceInterface.sendPushCard(cardList.get(0), DeviceConstants.DEVICE_ACCESS_TYPE_UNIVERSAL, OperationConstant.ONE);
                }
            }else{
                return new ResultBean<>(ResultEnum.ERROR);
            }

        }
        //人脸禁用
        else if(operType.equals(OperationConstant.FIVE)){
            //获取通用人脸设备
            List<Device> deviceList = this.deviceFeign.getDeviceByPathUseAndType(user.getResidentialId(), user.getUnitId(), DeviceConstants.DEVICE_ACCESS_TYPE_UNIVERSAL, OperationConstant.TWO);
            ResultBean<AccessFacePushRecords> faceResult = this.accessFacePushRecordsServiceInterface.getListByUserId(userId, OperationConstant.ZERO, null);
            List<AccessFacePushRecords> faceRecords = faceResult.getList();

            List<Long> disDeviceIdList = new ArrayList<>();
            //添加普通设备位置的设备
            if (deviceList !=null && deviceList.size() > 0){
                deviceList.forEach(device -> disDeviceIdList.add(device.getId()));
            }
            //添加特殊设备位置的设备
            if(faceRecords != null && faceRecords.size() > 0){
                faceRecords.forEach(records -> disDeviceIdList.add(records.getDeviceId()));
            }
            if(disDeviceIdList.size() > 0){
                resultBean = this.handleSendUserFace(user, disDeviceIdList, false, null, null);
            }else{
                user.setFaceEnable(OperationConstant.TWO);
                if(this.updateById(user)){
                    resultBean = new ResultBean<>(ResultEnum.SUCCESS, true);
                }else{
                    resultBean = new ResultBean<>(ResultEnum.SUCCESS, false);
                }
            }
        }
        //卡禁用
        else if(operType.equals(6)){

            List<AccessCard> cardList = this.accessCardServiceInterface.getAccessCardByUserIdAndType(String.valueOf(userId), OperationConstant.ZERO);
            if(cardList == null || cardList.size() <= 0){
                return new ResultBean<>(ResultEnum.SUCCESS,true);
            }
            AccessCard accessCard = cardList.get(0);
            accessCard.setCardEnable(OperationConstant.TWO);
            if(this.accessCardServiceInterface.updateById(accessCard)){
                ResultBean<AccessCardPushRecords> cardResult = this.accessCardPushRecordsServiceInterface.getListByUserId(userId, OperationConstant.ZERO, null);
                List<AccessCardPushRecords> cardRecords = cardResult.getList();
                List<Long> disDeviceIdList = new ArrayList<>();
                List<Device> deviceList = this.deviceFeign.getDeviceByPathUseAndType(user.getResidentialId(), user.getUnitId(), DeviceConstants.DEVICE_ACCESS_TYPE_UNIVERSAL, OperationConstant.ONE);
                //添加普通设备位置的设备
                if (deviceList !=null && deviceList.size() > 0){
                    deviceList.forEach(device -> disDeviceIdList.add(device.getId()));
                }
                //添加特殊设备位置的设备
                if(cardRecords != null && cardRecords.size() > 0){
                    cardRecords.forEach(records -> disDeviceIdList.add(records.getDeviceId()));
                }
                if (disDeviceIdList.size() > 0){
                    resultBean = this.handleSendUserCard(accessCard, OperationConstant.TWO, disDeviceIdList, false, null, null);
                }else {
                    return new ResultBean<>(ResultEnum.SUCCESS,true);
                }
            } else{
                return new ResultBean<>(ResultEnum.ERROR);
            }
        }
        return resultBean;
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public ResultBean<Boolean> importUserList(UserDto dto){
        List<User> list = dto.getList();
        if(this.insertOrUpdateBatch(list,500)){
            Map<Long,Integer> residentialMap = dto.getResidentialMap();
            for (Map.Entry<Long, Integer> entry : residentialMap.entrySet()) {
                Residential residential = this.residentialServiceInterface.findResidentialById(entry.getKey());
                residential.setUserNumber(residential.getUserNumber() + entry.getValue());
                this.residentialServiceInterface.updateById(residential);
            }
            Map<Long,Integer> unitMap = dto.getUnitMap();
            for (Map.Entry<Long, Integer> entry : unitMap.entrySet()) {
                Unit unit = this.unitServiceInterface.findUnitById(entry.getKey());
                unit.setUserNumber(unit.getUserNumber() + entry.getValue());
                this.unitServiceInterface.updateById(unit);
            }
            Map<Long,Integer> roomMap = dto.getRoomMap();
            for (Map.Entry<Long, Integer> entry : roomMap.entrySet()) {
                Room room = this.roomServiceInterface.findRoomById(entry.getKey());
                room.setUserNumber(room.getUserNumber() + entry.getValue());
                this.roomServiceInterface.updateById(room);
            }
        }
        List<User> addList = dto.getAddList();
        if(addList!=null){
            this.associatedMember(addList);
        }
        return  new ResultBean<>(ExcelResultEnum.SUCCESS,true);
    }

    @Override
    public Map<String,Object> userCountForType(UserDto dto){
        EntityWrapper<User> wrapper=new EntityWrapper<User>();
        //0-业主 1-成员 2-租户 人数
        String sqlSelect="sum(case  when i_type=0 then 1 ELSE 0 end) proprietorUserCount," +
                "sum(case  when i_type=1 then 1 ELSE 0 end) memberUserCount," +
                "sum(case  when i_type=2 then 1 ELSE 0 end) lesseeCount";
        wrapper.setSqlSelect(sqlSelect);
        //机构位置
        String orgPosition=dto.getOrgPosition();
        //根据机构
        if(StringUtils.isNotBlank(orgPosition)) {
            wrapper.like("s_org_position", orgPosition, SqlLike.RIGHT);
        }
        wrapper.eq("i_status",OperationConstant.ZERO);
        return this.selectMap(wrapper);
    }

    @Override
    public Map<String,Object> userCountForCreateType(UserDto dto){
        EntityWrapper<User> wrapper=new EntityWrapper<User>();
        //0-小程序添加 1-后台添加  2-后台导入 3-app添加 人数
        String sqlSelect="sum(case  when i_create_type=0 then 1 ELSE 0 end) wxAppletCount," +
                "sum(case  when i_create_type=1 then 1 ELSE 0 end) backgroundCount," +
                "sum(case  when i_create_type=2 then 1 ELSE 0 end) backgroundImportCount," +
                "sum(case  when i_create_type=3 then 1 ELSE 0 end) appCount";
        wrapper.setSqlSelect(sqlSelect);
        //机构位置
        String orgPosition=dto.getOrgPosition();
        //根据机构
        if(StringUtils.isNotBlank(orgPosition)) {
            wrapper.like("s_org_position", orgPosition, SqlLike.RIGHT);
        }
        wrapper.eq("i_status",OperationConstant.ZERO);
        return this.selectMap(wrapper);
    }

    @Override
    public User findUserByCondition(UserDto userDto) {
        Wrapper<User> wrapper = new EntityWrapper<>();
        //过滤删除
        wrapper.notIn("i_status", OperationConstant.MINUS_ONE);
        if (null != userDto.getId()) {
            wrapper.notIn("l_id", userDto.getId());
        }
        if (userDto.getRoomId() != null){
            wrapper.eq("l_room_id", userDto.getRoomId());
        }
        if (StringUtils.isNotBlank(userDto.getRoomName())){
            wrapper.eq("s_room_name", userDto.getRoomName());
        }
        if (userDto.getCheckState() != null){
            wrapper.eq("i_check_state", userDto.getCheckState());
        }
        if (StringUtils.isNotBlank(userDto.getCheckOpinion())){
            wrapper.like("", userDto.getCheckOpinion(), SqlLike.DEFAULT);
        }
        if (userDto.getUnitId() != null){
            wrapper.eq("l_unit_id", userDto.getUnitId());
        }
        if (StringUtils.isNotBlank(userDto.getUnitName())){
            wrapper.eq("s_unit_name", userDto.getUnitName());
        }
        if (userDto.getResidentialId() != null){
            wrapper.eq("l_residential_id", userDto.getResidentialId());
        }
        if (StringUtils.isNotBlank(userDto.getResidentialName())){
            wrapper.eq("s_residential_name", userDto.getResidentialName());
        }
        if (userDto.getCreateType() != null){
            wrapper.eq("i_create_type", userDto.getCreateType());
        }
        //
        if (userDto.getNationality() != null){
            wrapper.eq("i_nationality", userDto.getNationality());
        }
        if (StringUtils.isNotBlank(userDto.getIdCard())){
            wrapper.eq("s_id_card", userDto.getIdCard());
        }
        if (StringUtils.isNotBlank(userDto.getBirthPlace())){
            wrapper.eq("s_birth_place", userDto.getBirthPlace());
        }
        if (StringUtils.isNotBlank(userDto.getEstatePosition())){
            wrapper.like("s_estate_position", userDto.getEstatePosition());
        }
        if (userDto.getFaceEnable() != null){
            wrapper.eq("i_face_enable", userDto.getFaceEnable());
        }
        if(userDto.getOldId() != null){
            wrapper.eq("old_id",userDto.getOldId());
        }
        return this.baseMapper.findUserByCondition(userDto, wrapper);
    }

    @Override
    public int findUserTotalCount(UserDto userDto) {
        EntityWrapper<User> wrapper=new EntityWrapper<>();
        //小区
        wrapper.eq("l_residential_id",  userDto.getResidentialId());
        //过滤删除
        wrapper.eq("i_status", OperationConstant.ZERO);
        return this.selectCount(wrapper);
    }

    @Override
    public ResultBean<Page> getUserPage(PageBean<User, UserDto> pageBean) {
        UserDto dto = pageBean.getDto();
        pageBean.setRecords(this.baseMapper.getUserPage(dto,pageBean));
        String serverHost = this.confFeign.getFileServerHost();
        pageBean.getRecords().forEach(user -> {
            if (!StringUtils.isEmpty(user.getImageUri())){
                user.setImageUri(serverHost + user.getImageUri());
            }
        });
        return new ResultBean<>(ResultEnum.SUCCESS,pageBean);
    }

    @Override
    public ResultBean<Boolean> enableUserCardBatch(List<Long> cardIds) {
        List<AccessCard> cardsList = this.accessCardServiceInterface.selectBatchIds(cardIds);
        List<AccessCard> list = new ArrayList<>();
        for(int i = 0; i < cardsList.size(); i++){
            AccessCard card = cardsList.get(i);
            if (card.getCardEnable() != OperationConstant.TWO){
                continue;
            }
            card.setCardEnable(OperationConstant.ONE);
            list.add(card);
        }
        Assert.isTrue(list.size() != 0,"没有需要启用的门禁卡");
        ResultBean<Boolean> bean = accessCardServiceInterface.updateAccessCardList(list);
        Assert.isTrue(bean.getData(),"修改门禁卡状态异常");
        List<AccessCardSimpleDto> accessCardSimpleDtoList = new ArrayList<>();
        list.forEach(card ->{
            AccessCardSimpleDto accessCardSimpleDto = new AccessCardSimpleDto();
            accessCardSimpleDto.setId(card.getId());
            accessCardSimpleDto.setResidentialId(card.getResidentialId());
            accessCardSimpleDto.setUnitId(card.getUnitId());
            accessCardSimpleDto.setCardNo(card.getCardNo());
            accessCardSimpleDto.setBeginDate(card.getBeginDate());
            accessCardSimpleDto.setEndDate(card.getEndDate());
            accessCardSimpleDtoList.add(accessCardSimpleDto);
        });
        Assert.notEmpty(accessCardSimpleDtoList, "没有需要启用的门禁卡");
        this.deviceFeign.pushCardToUniversalDevicesBatch(accessCardSimpleDtoList);
        return new ResultBean<>(ResultEnum.SUCCESS, true);
    }

    @Override
    public List<User> getListByCondition(UserDto userDto) {
        Wrapper<User> wrapper = new EntityWrapper<>();
        //过滤删除
        wrapper.notIn("i_status", OperationConstant.MINUS_ONE);
        if (null != userDto.getRoomId()){
            wrapper.eq("l_room_id", userDto.getRoomId());
        }
        if (StringUtils.isNotBlank(userDto.getImageUri())){
            wrapper.eq("s_image_uri", userDto.getImageUri());
        }

        if (null != userDto.getId()) {
            wrapper.notIn("l_id", userDto.getId());
        }
        if (userDto.getRoomId() != null){
            wrapper.eq("l_room_id", userDto.getRoomId());
        }
        if (StringUtils.isNotBlank(userDto.getRoomName())){
            wrapper.eq("s_room_name", userDto.getRoomName());
        }
        if (userDto.getCheckState() != null){
            wrapper.eq("i_check_state", userDto.getCheckState());
        }
        if (StringUtils.isNotBlank(userDto.getCheckOpinion())){
            wrapper.like("", userDto.getCheckOpinion(), SqlLike.DEFAULT);
        }
        if (userDto.getUnitId() != null){
            wrapper.eq("l_unit_id", userDto.getUnitId());
        }
        if (StringUtils.isNotBlank(userDto.getUnitName())){
            wrapper.eq("s_unit_name", userDto.getUnitName());
        }
        if (userDto.getResidentialId() != null){
            wrapper.eq("l_residential_id", userDto.getResidentialId());
        }
        if (StringUtils.isNotBlank(userDto.getResidentialName())){
            wrapper.eq("s_residential_name", userDto.getResidentialName());
        }
        if (userDto.getCreateType() != null){
            wrapper.eq("i_create_type", userDto.getCreateType());
        }
        //
        if (userDto.getNationality() != null){
            wrapper.eq("i_nationality", userDto.getNationality());
        }
        if (StringUtils.isNotBlank(userDto.getIdCard())){
            wrapper.eq("s_id_card", userDto.getIdCard());
        }
        if (StringUtils.isNotBlank(userDto.getBirthPlace())){
            wrapper.eq("s_birth_place", userDto.getBirthPlace());
        }
        if (StringUtils.isNotBlank(userDto.getEstatePosition())){
            wrapper.like("s_estate_position", userDto.getEstatePosition());
        }
        if (userDto.getFaceEnable() != null){
            wrapper.eq("i_face_enable", userDto.getFaceEnable());
        }
        if(userDto.getOldId() != null){
            wrapper.eq("old_id",userDto.getOldId());
        }
        if (userDto.getUserIds() != null && userDto.getUserIds().length > 0){
            wrapper.in("l_id", userDto.getUserIds());
        }

        return this.selectList(wrapper);
    }
    /* -------------------------------------------------- 内部方法 -------------------------------------------------- */
    /* -------------------------------------------------------------------------------------------------------------- */
    /**
     * 功能描述:删除下发的人脸
     * @param user
     *
     *
     */
    private void deletePushUserFace(User user){
        //删除人脸下发
        if(StringUtils.isNotBlank(user.getImageUri())){
            UserInfoDto dto = new UserInfoDto();
            dto.setId(UserFlagConstant.USER_NUMBER_FLAG + user.getId());
            dto.setFaceCodeList(new ArrayList<>(0));
            DispatchTask task = new DispatchTask();
            task.setUnitId(user.getUnitId());
            task.setXqId(user.getResidentialId());
            task.setData(dto);
            Map<String,String> logMap = new HashMap<>();
            //小区
            if (!StringUtils.isEmpty(user.getResidentialName())){
                logMap.put("xqName",user.getResidentialName());
            }else {
                logMap.put("xqName",null);
            }
            //单元
            if (!StringUtils.isEmpty(user.getUnitName())){
                logMap.put("unitName",user.getUnitName());
            }else {
                logMap.put("unitName",null);
            }
            //房间
            if (!StringUtils.isEmpty(user.getRoomName())){
                logMap.put("roomName",user.getRoomName());
            }else {
                logMap.put("roomName",null);
            }
            //用户名
            if (!StringUtils.isEmpty(user.getName())){
                logMap.put("userName",user.getName());
            }else {
                logMap.put("userName",null);
            }
            //有效期开始时间
            SimpleDateFormat format = new SimpleDateFormat();
            if (null != dto.getBeginDate()){
                logMap.put("beginTime",format.format(dto.getBeginDate()));
            }else {
                logMap.put("beginTime",null);
            }
            //有效期结束时间
            if (null != dto.getEndDate()){
                logMap.put("endTime",format.format(dto.getEndDate()));
            }else {
                logMap.put("endTime",null);
            }
            //人脸
            if (dto.getFaceCodeList().size() > 0){
                List<String> list = new ArrayList<>();
                for (Map m : dto.getFaceCodeList()) {
                    if (m.containsKey("imgSrc")){
                        list.add(m.get("imgSrc").toString());
                    }
                }
                logMap.put("imgSrc", JsonUtils.listToString(list));
            }else {
                logMap.put("imgSrc",null);
            }
            logMap.put("deleteUser", "true");
            this.deviceFeign.pushUserFace(task,logMap);
        }
    }

    /**
     * 功能描述:删除缓存
     * @param user
     *
     *
     */
    private void deleteCache(User user){
        HashOperations<String, String, String> hashOperations = this.redisTemplate.opsForHash();
        StringBuffer sb = new StringBuffer(user.getRoomId()+""+user.getName());
        String hashKey = sb.toString();
        String json = hashOperations.get(IMPORT_CACHE_USER_NMAE,hashKey);
        if (!StringUtils.isEmpty(json)) {
            hashOperations.delete(IMPORT_CACHE_USER_NMAE,hashKey);
        }
    }
    /**
     * 功能描述:后台新增住户的时候-去匹配一次会员--住户新增时候调用
     * @param list 手机号和名字
     *
     *
     */
    private void associatedMember(List<User> list) {
        for(User u :list){
            if(StringUtils.isNotBlank(u.getName()) && StringUtils.isNotBlank(u.getTel())){
                List<Member> members = this.memberServiceInterface.findMemberByNameAndTel(u.getName(),u.getTel());
                //匹配到了会员
                insertMemberAndUser(u, members);
            }
        }
    }
    /**
     * 功能描述:后台修改住户的时候-去匹配一次会员--住户修改时调用
     * @param u
     *
     *
     */
    private void matchMember(User u){
        MemberAndUser condition = new MemberAndUser();
        condition.setUserId(u.getId());
        List<MemberAndUser> list  = this.memberAndUserInterface.getByCondition(condition);
        //住户没有关联会员--则去匹配一次会员
        if(list==null || list.size()==0){
            List<Member> members = this.memberServiceInterface.findMemberByNameAndTel(u.getName(),u.getTel());
            //匹配到了会员
            insertMemberAndUser(u, members);
        }
    }

    private void insertMemberAndUser(User u, List<Member> members) {
        if(members!=null){
            for(Member m:members){
                MemberAndUser memberAndUser = new MemberAndUser();
                memberAndUser.setMemberId(m.getId());
                memberAndUser.setRoomId(u.getRoomId());
                memberAndUser.setUserId(u.getId());
                this.memberAndUserInterface.insert(memberAndUser);
                //  生成视频对讲账号
                VideoCallAccount account = new VideoCallAccount();
                account.setMember(m);
                List<User> userList = new ArrayList<>();
                userList.add(u);
                account.setUserList(userList);
                this.videoCallAccountServiceInterface.createAccountByUser(account);
            }
        }
    }

    /**
     * 根据小区ID，获取小区下的所有设备
     * @param xqIdList
     * @return
     */
    private List<Long> getDeviceIdByXqs(List<Long> xqIdList){
        List<Long> deviceIdList = new ArrayList<>();
        xqIdList.forEach(xqId -> {
            List<Device> deviceList = this.deviceFeign.getListByXqId(xqId);
            deviceList.forEach(device -> deviceIdList.add(device.getId()));
        });
        return deviceIdList;
    }

    /**
     * 根据单元ID，获取单元下的所有设备
     * @param unitIdList
     * @return
     */
    private List<Long> getDeviceIdByUnits(List<Long> unitIdList){
        List<Device> deviceList = this.deviceFeign.getListByUnitIds(unitIdList);
        return deviceList.stream().map(Device::getId).collect(Collectors.toList());
    }

    /**
     * 处理用户人脸下发
     * @param user
     * @param deviceIdList
     * @param isPush true表示下发，false表示禁用
     */
    private ResultBean<Boolean> handleSendUserFace(User user, List<Long> deviceIdList, Boolean isPush, Date beginDate, Date endDate){
        UserInfoDto dto = new UserInfoDto();
        dto.setId(UserFlagConstant.USER_NUMBER_FLAG + user.getId());
        dto.setName(user.getName());
        if(isPush){
            String imgHost = this.confFeign.getFileServerHost();
            List<Map<String,Object>> userFaceList = new ArrayList<>(1);
            Map<String,Object> map = new HashMap<>(3);
            map.put("imgMd5", user.getFaceCode());
            map.put("imgSrc", imgHost + user.getImageUri());
            userFaceList.add(map);
            dto.setFaceCodeList(userFaceList);
            dto.setBeginDate(user.getFaceBeginDate());
            dto.setEndDate(user.getFaceEndDate());
            ManualPushDevicesTask task = new ManualPushDevicesTask();
            task.setDeviceIdList(deviceIdList);
            task.setData(dto);
            task.setBeginDate(beginDate);
            task.setEndDate(endDate);
            task.setOperType(OperationConstant.TWO);
           /* ResultBean<AccessFacePushRecords> facePushRecordsResult = this.accessFacePushRecordsServiceInterface.getListByUserId(user.getId(), OperationConstant.ZERO);
            List<AccessFacePushRecords> faceRecords = facePushRecordsResult.getList();
            if(faceRecords != null && faceRecords.size() > 0){
                task.setOperType(OperationConstant.TWO);
            }else{
                task.setOperType(OperationConstant.ONE);
            }*/
            this.deviceFeign.manualPushUserFaceToDevices(task);
            user.setFaceEnable(OperationConstant.ONE);
            if(this.updateById(user)){
                return new ResultBean<>(ResultEnum.SUCCESS,true);
            }else{
                return new ResultBean<>(ResultEnum.ERROR, false);
            }
        }
        else{
            ManualPushDevicesTask task = new ManualPushDevicesTask();
            task.setDeviceIdList(deviceIdList);
            task.setData(dto);
            task.setOperType(OperationConstant.THREE); //删除人脸下发
            user.setFaceEnable(OperationConstant.TWO);
            if(this.updateById(user)){
                this.deviceFeign.manualPushUserFaceToDevices(task);
                return new ResultBean<>(ResultEnum.SUCCESS,true);
            }else{
                return new ResultBean<>(ResultEnum.ERROR, false);
            }
        }
    }

    /**
     * 处理用户门禁卡下发&禁用
     * @param accessCard
     * @param operType
     * @param deviceIdList
     * @param isPush true表示下发，false表示禁用
     */
    private ResultBean<Boolean> handleSendUserCard(AccessCard accessCard, Integer operType, List<Long> deviceIdList, Boolean isPush,Date beginDate, Date endDate){
        ManualPushDevicesTask task = new ManualPushDevicesTask();
        task.setDeviceIdList(deviceIdList);
        task.setData(accessCard);
        task.setBeginDate(beginDate);
        task.setEndDate(endDate);
        task.setEnable(isPush);
        task.setOperType(operType);
        if(!isPush){
            task.setOperType(OperationConstant.THREE);
        }
        return this.deviceFeign.manualPushUserCardToDevices(task);
    }

    /**
     * 检查用户是否在所选设备区域
     * @param user
     * @param deviceIdList
     * @return
     */
    private Boolean checkXqUnitDevicePermission(User user, List<Long> deviceIdList){
        Boolean check = false;
        for(int i = 0; i < deviceIdList.size(); i++){
            Long deviceId = deviceIdList.get(i);
            Device device = deviceFeign.getEntityById(deviceId);
            Long deviceUnitId = device.getUnitId();
            Long deviceXqId = device.getXqId();
            Long userUnitId = user.getUnitId();
            Long userXqId = user.getResidentialId();
            if(deviceUnitId != null){
                if(userUnitId.equals(deviceUnitId)){
                    check = true;
                }else{
                    check = false;
                }
                if(!check) {
                    Assert.isTrue(check, "该用户不在部分设备所在的单元");
                    break;
                }
            }else{
                if(!userXqId.equals(deviceXqId)){
                    check = false;
                    Assert.isTrue(check, "该用户不在设备所在的小区");
                }else{
                    check = true;
                }
            }
        }
        return check;
    }
}
