package com.sptg.gateway.controller.estate;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.URLUtil;
import com.baomidou.mybatisplus.plugins.Page;
import com.github.tobato.fastdfs.domain.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
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.SysLogConstant;
import com.sptg.common.core.util.Base64DecodeMultipartFileUtils;
import com.sptg.common.core.util.WebUtils;
import com.sptg.common.security.annotation.Security;
import com.sptg.common.security.enums.DataFormatEnum;
import com.sptg.common.security.service.SecurityServiceInterface;
import com.sptg.estate.api.constant.EstateSecurityToken;
import com.sptg.estate.api.dto.*;
import com.sptg.estate.api.entity.*;
import com.sptg.estate.api.feigns.*;
import com.sptg.gateway.util.DesensitizeUtils;
import com.sptg.permissions.api.entity.Account;
import com.sptg.permissions.api.entity.Dict;
import com.sptg.permissions.api.entity.Organization;
import com.sptg.permissions.api.feigns.ConfFeign;
import com.sptg.permissions.api.feigns.DictFeign;
import com.sptg.permissions.api.feigns.OrgFeign;
import com.sptg.permissions.api.feigns.SysApiLogFeign;
import com.sptg.statistics.api.constant.SysLogMenuConstant;
import com.sptg.statistics.api.entity.SysOperationLog;
import com.sptg.statistics.api.feigns.SysOperationLogFeign;
import lombok.RequiredArgsConstructor;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * title: UserController
 * package: com.sptg.gateway.controller.estate
 * description: 住户 网关控制器
 *
 *             
 *                 
 */

@RestController
@RequestMapping("/estate/user")
@RequiredArgsConstructor
public class UserController {

    private final ConfFeign confFeign;
    private final UnitFeign unitFeign;
    private final RoomFeign roomFeign;
    private final UserFeign userFeign;
    private final OrgFeign orgFeign;
    private final ResidentialFeign residentialFeign;
    private final SecurityServiceInterface<Account> securityServiceInterface;
    private final SysOperationLogFeign sysOperationLogFeign;
    private final AccessCardFeign userCardFeign;
    private final DictFeign dictFeign;
    private final FloorFeign floorFeign;
    private final ThirdUserFeign thirdUserFeign;
    private final BuildingFeign buildingFeign;
    private final SysApiLogFeign sysApiLogFeign;

    private static final String SYMBOL = "*";

    private final FastFileStorageClient fastFileStorageClient;

    /**
     * 功能描述:住户页面初始化
     * @return ModelAndView
     *             
     *                       
     */
    @GetMapping("/index")
    @Security(token = EstateSecurityToken.ESTATE_USER_MANAGE,format = DataFormatEnum.VIEW)
    public ModelAndView index(){
        return new ModelAndView("estate/user-manage");
    }

    @GetMapping("/index/{roomId}")
    @Security(token = EstateSecurityToken.ESTATE_USER_MANAGE,format = DataFormatEnum.VIEW)
    public ModelAndView index(@PathVariable(value = "roomId") Long roomId){
        Room room = roomFeign.findRoomById(roomId);
        return new ModelAndView("estate/user-table").addObject("roomId", roomId).addObject("roomName", room.getName());
    }

    /*@GetMapping("/member/{id}")
    @Security(token = EstateSecurityToken.ESTATE_USER_MEMBER,format = DataFormatEnum.VIEW)
    public ModelAndView member(@PathVariable(value = "id") Long id){
        ModelAndView modelAndView = new ModelAndView("estate/user-member");
        modelAndView.addObject("user",this.userFeign.findUserById(id));
        return modelAndView;
    }*/
    /**
     * 功能描述:人脸日志页面初始化
     * @return ModelAndView
     */
    @GetMapping("/log4face")
    @Security(token = EstateSecurityToken.ESTATE_USER_MANAGE,format = DataFormatEnum.VIEW)
    public ModelAndView log4face(Long userId){
        ModelAndView modelAndView = new ModelAndView("estate/log-face");
        modelAndView.addObject("userId", userId);
        return modelAndView;
    }

    /**
     * 功能描述:卡日志页面初始化
     * @return ModelAndView
     */
    @GetMapping("/log4card")
    @Security(token = EstateSecurityToken.ESTATE_USER_MANAGE,format = DataFormatEnum.VIEW)
    public ModelAndView log4card(String cardNo){
        ModelAndView modelAndView = new ModelAndView("estate/log-card");
        modelAndView.addObject("cardNo", cardNo);
        return modelAndView;
    }

    /**
     * 功能描述:住户列表查询
     * @param userDto 住户业务对象（含查询条件）
     * @param page 分页条件
     * @return ResultBean<Page<User>>
     *             
     *                       
     */
    @GetMapping(value = "/showUserList")
    @Security(token = EstateSecurityToken.ESTATE_USER_MANAGE,format = DataFormatEnum.JSON)
    public ResultBean<Page<User>> showUserList(UserDto userDto, Page<User> page) {
        //根据树形选择加载数据；如果没有选中ID，则根据当前账号查询
        Account onLineUser = this.securityServiceInterface.getOnLineUser();
        Organization userOrg = this.orgFeign.getOrgById(onLineUser.getOrgId());
        if(userDto.getSelectTreeId() == null ||  null == userDto.getSelectTreeType()){
            if (userOrg.getOrgType() == OperationConstant.THREE){
                //物业
                userDto.setEstatePosition(onLineUser.getOrgPosition());
            }else{
                //机构
                userDto.setOrgPosition(onLineUser.getOrgPosition());
            }
        }else{
            //1 机构 2 小区 3社区机构
            /*Organization organization = this.orgFeign.getOrgById(userDto.getSelectTreeId());
            if(userDto.getSelectTreeType() <= OperationConstant.THREE){
                if (userDto.getSelectTreeType() == OperationConstant.ONE){
                    if (organization.getOrgType() == OperationConstant.THREE){
                        //物业
                        userDto.setEstatePosition(organization.getPosition());
                    }else{
                        //机构
                        userDto.setOrgPosition(organization.getPosition());
                    }
                }
                if (userDto.getSelectTreeType() == OperationConstant.TWO){
                    //小区
                    if (userOrg.getOrgType() == OperationConstant.THREE){
                        //物业账号
                        userDto.setEstatePosition(this.residentialFeign.findResidentialById(organization.getId()).getEstatePosition());
                    }else{
                        //机构账号
                        userDto.setOrgPosition(organization.getPosition());
                    }
                }
            }
            //4 单元
            if(userDto.getSelectTreeType() == OperationConstant.FOUR){
                if (userOrg.getOrgType() == OperationConstant.THREE){
                    userDto.setEstatePosition(this.unitFeign.findUnitById(userDto.getSelectTreeId()).getEstatePosition());
                }else{
                    userDto.setOrgPosition(this.unitFeign.findUnitById(userDto.getSelectTreeId()).getOrgPosition());
                }
            }
            //5 房间
            if(userDto.getSelectTreeType() == OperationConstant.FIVE){
                if (userOrg.getOrgType() == OperationConstant.THREE){
                    userDto.setEstatePosition(this.roomFeign.findRoomById(userDto.getSelectTreeId()).getEstatePosition());
                }else{
                    userDto.setOrgPosition(this.roomFeign.findRoomById(userDto.getSelectTreeId()).getOrgPosition());
                }
            }*/
        }
        userDto.setPage(page);
        ResultBean<Page<User>> pageResultBean = this.userFeign.showUserList(userDto);
        String fastDfsServer = this.confFeign.getFileServerHost();
        if(pageResultBean!=null&&pageResultBean.getData()!=null){
            Page<User> resultPage=pageResultBean.getData();
            if(null!=resultPage){
                List<User> records = resultPage.getRecords();
                records.forEach(user -> {
                    user.setFastDfsServer(fastDfsServer);
                });
                //数据脱敏
                if (!userDto.getDesensitize()){
                    DesensitizeUtils.desensitizeList(records);
                }
            }
        }

        /*//查询卡信息
        if(pageResultBean!=null&&pageResultBean.getData()!=null){
            Page<User> resultPage=pageResultBean.getData();
            if(null!=resultPage){
                List<User> records = resultPage.getRecords();
                if(null!=records&&!records.isEmpty()){
                    records.forEach(u->{
                        u.setFastDfsServer(fastDfsServer);
                        AccessCardDto accessCardDto = new AccessCardDto();
                        accessCardDto.setType(OperationConstant.ZERO);
                        accessCardDto.setUserId(String.valueOf(u.getId()));
                        List<AccessCard> accessCardList = userCardFeign.getAccessCardByUserIdAndType(accessCardDto);
                        if(null != accessCardList && !accessCardList.isEmpty()){
                            u.setAccessCard(accessCardList.get(0));
                        }


                        //处理user数据没有floorID的问题
                        String orgPosition = u.getOrgPosition();
                        String[] split = orgPosition.split("/");
                        String residentialIdStr = split[3];
                        String buildingIdStr = split[4];
                        String unitIdStr = split[5];
                        String floorIdStr = split[6];

                        FloorDto dto = new FloorDto();
                        dto.setResidentialId(Long.parseLong(residentialIdStr));
                        dto.setBuildingId(Long.parseLong(buildingIdStr));
                        dto.setUnitId(Long.parseLong(unitIdStr));
                        List<Floor> listByCondition = floorFeign.getListByCondition(dto);
                        if (listByCondition.size() > 0){
                            Floor f = listByCondition.get(0);
                            u.setFloorId(f.getId());
                            u.setFloorName(f.getName());
                            boolean b = userFeign.updateEntity(u);
                            System.out.println("******处理用户数据floor成功！！！*******");
                        }

                    });
                }
            }
        }*/

        return pageResultBean;
    }

    public void dealWithData(){
        Long residentialId = 36719L;
        String orgPosition = "0/1/17782/18117/";
        Long buildingId = 1344456912929551921L;

        List<User> updateList = new ArrayList<>();

        UserDto userDto = new UserDto();
        userDto.setResidentialId(residentialId);
        userDto.setOrgPosition(orgPosition);
        Long[] ld = new Long[]{10976L,10966L,10996L,10969L,10978L,10985L,10994L,11084L,10950L,10958L,10959L,10963L,10980L,10999L,10997L,10998L,10977L,10982L,10993L};
        userDto.setUserIds(ld);
        List<User> userList = this.userFeign.getListByCondition(userDto);
        userList.forEach(user -> {
            String unitName = user.getUnitName();
//            String floorName = user.getFloorName();
            String roomName = user.getRoomName();
            String floorName = roomName.substring(0, roomName.length() - 2) + "层";

            UnitDto unitDto = new UnitDto();
            unitDto.setResidentialId(residentialId);
            unitDto.setOrgPosition(orgPosition);
            unitDto.setBuildingId(buildingId);
            unitDto.setName(unitName);
            List<Unit> units = this.unitFeign.getListByCondition(unitDto);
            if (units.size() > 0){
                Unit unit = units.get(0);
                FloorDto floorDto = new FloorDto();
                floorDto.setResidentialId(residentialId);
                floorDto.setOrgPosition(orgPosition);
                floorDto.setBuildingId(buildingId);
                floorDto.setUnitId(unit.getId());
                floorDto.setName(floorName);
                List<Floor> floors = this.floorFeign.getListByCondition(floorDto);
                if (floors.size() > 0){
                    Floor floor = floors.get(0);
                    RoomDto roomDto = new RoomDto();
                    roomDto.setResidentialId(residentialId);
                    roomDto.setOrgPosition(orgPosition);
                    roomDto.setBuildingId(buildingId);
                    roomDto.setUnitId(unit.getId());
                    roomDto.setFloorId(floor.getId());
                    roomDto.setName(roomName);

                    List<Room> rooms = this.roomFeign.getListByCondition(roomDto);
                    if (rooms.size() > 0){
                        Room room = rooms.get(0);

                        user.setBuildingId(buildingId);
                        user.setBuildingName("印刷1栋");
                        user.setUnitId(unit.getId());
                        user.setUnitName(unit.getName());
                        user.setFloorId(floor.getId());
                        user.setFloorName(floor.getName());
                        user.setRoomId(room.getId());
                        user.setRoomName(room.getName());
                        user.setOrgPosition(room.getOrgPosition());
                        updateList.add(user);

                    }
                }
            }

        });


        boolean b = this.userFeign.updateUserList(updateList);

    }

    /**
     * 功能描述:新增页面初始化
     * @return ModelAndView
     *             
     *                       
     */
    @GetMapping(value = "/add")
    @Security(token = EstateSecurityToken.ESTATE_USER_ADD,format = DataFormatEnum.VIEW)
    public ModelAndView add(String selectTreeId){
        ModelAndView modelAndView = new ModelAndView("estate/user-add");
        modelAndView.addObject("selectTreeId",selectTreeId);
        modelAndView.addObject("fastDfsServer",this.confFeign.getFileServerHost());
        return modelAndView;
    }


    @GetMapping(value = "/thirdUserSync")
    @Security(token = EstateSecurityToken.ESTATE_USER_ADD,format = DataFormatEnum.VIEW)
    public ResultBean<String> thirdUserSync(){
        ThirdUserDto thirdUserDto = new ThirdUserDto();
//        thirdUserDto.set
        List<ThirdUser> thirdUserList = this.thirdUserFeign.getListByCondition(thirdUserDto);

        // 遍历同步住户数据到住户表
        thirdUserList.forEach(thirdUser -> {

            if (thirdUser.getSign() == null || !thirdUser.getSign().equals(1)){
                Boolean flag = true;
                StringBuffer syncErrorMsg = new StringBuffer();

                ResidentialDto residentialDto = new ResidentialDto();
                BuildingDto buildingDto = new BuildingDto();
                UnitDto unitDto = new UnitDto();
                FloorDto floorDto = new FloorDto();
                RoomDto roomDto = new RoomDto();
                UserDto userDto = new UserDto();

                userDto.setName(thirdUser.getName());
                userDto.setIdCard(thirdUser.getIdcard());
                userDto.setTel(thirdUser.getTel());

                User user = null;
                List<User> userlist = this.userFeign.getListByCondition(userDto);
                if (userlist != null && userlist.size() > 0){
                    user = userlist.get(0);
                    userDto = BeanUtil.toBean(user, UserDto.class);
                }

                residentialDto.setAgencyName(thirdUser.getAgencyName());
                residentialDto.setName(thirdUser.getResidentialname());
                ResultBean<Residential> residentialResultBean = this.residentialFeign.getListByCondition(residentialDto);
                List<Residential> residentialList = residentialResultBean.getList();
                Residential residential = null;
                if (residentialList.size() > 0) {
                    residential = residentialList.get(0);
                    String houseInfo = thirdUser.getHouseInfo();
                    String[] houseMsg = houseInfo.split("-");
                    String buildingName = houseMsg[houseMsg.length - 3];
                    String unitName = houseMsg[houseMsg.length - 2];
                    String roomName = houseMsg[houseMsg.length - 1];
                    String floorName = roomName.substring(0, roomName.length() - 2);

                    try{
                        if (!isContainChinese(floorName)){
                            floorName += "层";
                        }
                        if (!isContainChinese(buildingName)){
                            buildingName = Integer.valueOf(buildingName).toString();
                            buildingName += "栋";
                        }
                        if (!isContainChinese(unitName)){
                            unitName += "单元";
                        }
                    }catch (Exception e){
                    }

                    buildingDto.setResidentialId(residential.getId());
                    buildingDto.setName(buildingName);
                    List<Building> buildingList = this.buildingFeign.getListByCondition(buildingDto);

                    if (buildingList.size() > 0) {
                        Building building = buildingList.get(0);
                        unitDto.setResidentialId(residential.getId());
                        unitDto.setBuildingId(building.getId());
                        unitDto.setName(unitName);
                        List<Unit> unitList = this.unitFeign.getListByCondition(unitDto);
                        if (unitList.size() > 0) {
                            Unit unit = unitList.get(0);
                            floorDto.setResidentialId(residential.getId());
                            floorDto.setBuildingId(building.getId());
                            floorDto.setUnitId(unit.getId());
                            floorDto.setName(floorName);
                            List<Floor> floorList = this.floorFeign.getListByCondition(floorDto);
                            if (floorList.size() > 0) {
                                Floor floor = floorList.get(0);
                                roomDto.setResidentialId(residential.getId());
                                roomDto.setBuildingId(building.getId());
                                roomDto.setFloorId(floor.getId());
                                roomDto.setName(roomName);
                                List<Room> roomList = this.roomFeign.getListByCondition(roomDto);
                                if (roomList.size() > 0) {
                                    Room room = roomList.get(0);

//                                if (user != null){
//                                    userDto = BeanUtil.toBean(user, UserDto.class);
//                                }

                                    if (thirdUser.getImageName() != null && (thirdUser.getImageName().contains("http://") || thirdUser.getImageName().contains("https://"))){
                                        URL faceUrl = URLUtil.toUrlForHttp(thirdUser.getImageName());
                                        try{
                                            InputStream stream = URLUtil.getStream(faceUrl);
                                            byte[] bytes = IoUtil.readBytes(stream);
                                            String base64 = Base64.getEncoder().encodeToString(bytes);
                                            //图片上传
                                            String groupUrl = uploadFace(base64, fastFileStorageClient);
                                            userDto.setImageUri(groupUrl);
                                        }catch (Exception e){
                                            userDto.setImageUri(thirdUser.getImageName());
                                            e.printStackTrace();
                                        }
                                    }

                                    userDto.setResidentialId(residential.getId());
                                    userDto.setResidentialName(residential.getName());
                                    userDto.setBuildingId(building.getId());
                                    userDto.setBuildingName(building.getName());
                                    userDto.setUnitId(unit.getId());
                                    userDto.setUnitName(unit.getName());
                                    userDto.setFloorId(floor.getId());
                                    userDto.setFloorName(floor.getName());
                                    userDto.setRoomId(room.getId());
                                    userDto.setRoomName(room.getName());
//                                    userDto.setImageUri(thirdUser.getImageUrl());
                                    userDto.setSex(this.getSexBySexName(thirdUser.getSex()));
                                    userDto.setType(this.getTypeByName(thirdUser.getType()));
                                    userDto.setSign(0);
                                    userDto.setCreateType(1);//后台导入
                                    userDto.setCheckState(1);//审核通过

                                    try{
                                        ResultBean<Boolean> resultBean;
                                        if (userDto.getId() == null){
                                            resultBean = this.userFeign.addUser(userDto);
                                        }else{
                                            resultBean = this.userFeign.updateUser(userDto);
                                        }
                                        if (resultBean != null && resultBean.getData()){
                                            // 单条数据同步成功
                                        }else{
                                            // 单条数据同步失败
                                            flag = false;
                                            syncErrorMsg.append("单条数据同步失败;");
                                        }

                                    }catch (Exception e){
                                        String message = e.getMessage();
                                        flag = false;
                                        syncErrorMsg.append(message);
                                    }


                                } else {
                                    flag = false;
                                    syncErrorMsg.append("找不到相应房屋；");
                                }
                            } else {
                                flag = false;
                                syncErrorMsg.append("找不到相应楼层；");
                            }

                        } else {
                            flag = false;
                            syncErrorMsg.append("找不到相应单元；");
                        }

                    } else {
                        flag = false;
                        syncErrorMsg.append("找不到相应楼栋；");
                    }

                } else {
                    flag = false;
                    syncErrorMsg.append("该社区下找不到该小区;");
                }

                if (flag){
                    thirdUser.setSign(1);
                    thirdUser.setErrorMsg("已同步到住户表");
                }else{
                    thirdUser.setSign(0);
                    thirdUser.setErrorMsg(syncErrorMsg.toString());
                }
                boolean b = this.thirdUserFeign.updateEntity(thirdUser);
            }else{
                // 已同步过此条第三方住户信息，直接跳过
            }
        });


        /*thirdUserList.forEach(user -> {
            CustInfoVerify custInfoVerify = new CustInfoVerify();
            custInfoVerify.setCustName(user.getName());
            custInfoVerify.setCertNumber(user.getIdcard());
            custInfoVerify.setCertType("1");
            Boolean result = CustInfoVerifyUtil.custInfoVerify(custInfoVerify, sysApiLogFeign);

            if (!result){
                user.setCheckMsg("身份证验证失败，请填写正确的身份证信息！");
            }else{
                user.setCheckMsg("身份证验证成功！");
            }

            this.thirdUserFeign.updateEntity(user);
        });
        return "身份证验证完毕！";*/

        return new ResultBean<>(ResultEnum.SUCCESS, "同步完成，详细信息请查看第三方用户数据！");

//        return "同步完成，详细信息请查看第三方用户数据！";
    }


    /**
     * 功能描述:根据性别名称获取性别状态
     *
     * @param sexName 性别名称
     * @return int
     */
    private int getSexBySexName(String sexName) {
        if(null == sexName){
            return -1;
        }
        switch (sexName) {
            case "未定义":
                return 0;
            case "男":
                return 1;
            case "女":
                return 2;
            default:
                return -1;
        }
    }
    /**
     * 功能描述:根据性别名称获取住户类型
     *
     * @param type 住户类型名称
     * @return int
     */
    private int getTypeByName(String type) {
        if(null == type){
            return -1;
        }
        switch (type) {
            case "业主":
                return 0;
            case "家属":
                return 1;
            case "租客":
                return 2;
            default:
                return -1;
        }
    }


    /**
     * 功能描述:新增页面初始化
     * @return ModelAndView
     *
     *
     */
    @GetMapping(value = "/addView/{roomId}")
    @Security(token = EstateSecurityToken.ESTATE_USER_ADD,format = DataFormatEnum.VIEW)
    public ModelAndView addView(@PathVariable(value = "roomId") Long roomId){
        Room room = roomFeign.findRoomById(roomId);
        ModelAndView modelAndView = new ModelAndView("estate/user-add-view");
        modelAndView.addObject("roomId", roomId);
        modelAndView.addObject("roomName", room.getName());
        modelAndView.addObject("fastDfsServer",this.confFeign.getFileServerHost());
        return modelAndView;
    }

    /**
     * 功能描述:新增页面初始化-带参数
     * @return ModelAndView
     *
     *
     */
    @GetMapping(value = "/add/{parentId}/{flag}")
    @Security(token = EstateSecurityToken.ESTATE_USER_ADD,format = DataFormatEnum.VIEW)
    public ModelAndView add(@PathVariable(value = "parentId")Long parentId,@PathVariable(value = "flag") Integer flag){
        ModelAndView modelAndView = new ModelAndView("estate/user-add");
        modelAndView.addObject("parentId",parentId);
        modelAndView.addObject("flag",flag);
        modelAndView.addObject("fastDfsServer",this.confFeign.getFileServerHost());
        return modelAndView;
    }

    /**
     * 功能描述:新增住户
     * @param userDto 住户业务对象
     * @return ResultBean<Boolean>
     *             
     *                       
     */
    @PostMapping(value = "/addUser")
    @Security(token = EstateSecurityToken.ESTATE_USER_ADD,format = DataFormatEnum.JSON)
    public ResultBean<Boolean> addUser(UserDto userDto){
        Account onLineUser = this.securityServiceInterface.getOnLineUser();
        userDto.setCreateId(onLineUser.getId());
        //后台录入
        userDto.setCreateType(OperationConstant.ONE);
        ResultBean<Boolean> resultBean=this.userFeign.addUser(userDto);
        if( null != resultBean.getData() && resultBean.getData()){
            /*---------------------------------------------------记录日志--------------------------------------------------------*/
            SysOperationLog sysOperationLog=new SysOperationLog(SysLogMenuConstant.ESTATE_USER_MANAGE, SysLogConstant.ADD_EVENT,
                    WebUtils.getIp(),userDto,onLineUser,userDto);
            sysOperationLogFeign.info(sysOperationLog);
            /*------------------------------------------------------------------------------------------------------------------*/
        }
        return resultBean;
    }

    /**
     * 功能描述: 编辑页面初始化
     * @param id 必填
     * @return ModelAndView
     *             
     *                       
     */
    @GetMapping(value = "/edit/{id}")
    @Security(token = EstateSecurityToken.ESTATE_USER_UPDATE,format = DataFormatEnum.VIEW)
    public ModelAndView edit(@PathVariable(value = "id")Long id){
        User user =  this.userFeign.findUserById(id);
        if (null == user){
            //  没有找到要修改的住户
            return new ModelAndView("common/404");
        }
        ModelAndView  modelAndView = new ModelAndView("estate/user-edit");
        modelAndView.addObject("user",user);
        modelAndView.addObject("fastDfsServer",this.confFeign.getFileServerHost());
        return modelAndView;
    }


    @GetMapping(value = "/getUserById/{id}")
    public User getUserById(@PathVariable(value = "id")Long id){
        User user =  this.userFeign.findUserById(id);
        return user;
    }

    /**
     * 功能描述:编辑住户
     * @param userDto 住户业务对象
     * @return ResultBean<Boolean>
     *             
     *                       
     */
    @PostMapping(value = "/updateUser")
    @Security(token = EstateSecurityToken.ESTATE_USER_UPDATE,format = DataFormatEnum.JSON)
    public ResultBean<Boolean> updateUser(UserDto userDto){
        if ( null == userDto || null == userDto.getId()){
            //  参数异常
            return new ResultBean<>(ResultEnum.PARAMETER_ANOMALY);
        }
        User oldObj = this.userFeign.findUserById(userDto.getId());
        ResultBean<Boolean> resultBean=this.userFeign.updateUser(userDto);
        if(null != resultBean.getData() && resultBean.getData()){
            Account onLineUser = this.securityServiceInterface.getOnLineUser();
            /*---------------------------------------------------记录日志--------------------------------------------------------*/
            User newObj = this.userFeign.findUserById(userDto.getId());
            SysOperationLog sysOperationLog=new SysOperationLog(SysLogMenuConstant.ESTATE_USER_MANAGE, SysLogConstant.ALTER_EVENT,
                    WebUtils.getIp(),userDto,onLineUser,oldObj,newObj);
            sysOperationLogFeign.info(sysOperationLog);
            /*------------------------------------------------------------------------------------------------------------------*/
        }
        return resultBean;
    }

    /**
     * 功能描述:删除住户
     * @param userDto 住户业务对象
     * @return ResultBean<Boolean>
     *             
     *                       
     */
    @PostMapping(value = "/deleteUser")
    @Security(token = EstateSecurityToken.ESTATE_USER_DELETE,format = DataFormatEnum.JSON)
    public ResultBean<Boolean> deleteUser(UserDto userDto){
        if ( null == userDto || null == userDto.getId()){
            //  参数异常
            return new ResultBean<>(ResultEnum.PARAMETER_ANOMALY);
        }
        User oldObj = this.userFeign.findUserById(userDto.getId());
        userDto.setStatus(OperationConstant.MINUS_ONE);
        ResultBean<Boolean> resultBean=this.userFeign.deleteUser(userDto);
        if( null != resultBean.getData() && resultBean.getData()){
            Account onLineUser = this.securityServiceInterface.getOnLineUser();
            /*---------------------------------------------------记录日志--------------------------------------------------------*/
            SysOperationLog sysOperationLog=new SysOperationLog(SysLogMenuConstant.ESTATE_USER_MANAGE, SysLogConstant.DELETE_EVENT,
                    WebUtils.getIp(),userDto,onLineUser,oldObj);
            sysOperationLogFeign.info(sysOperationLog);
            /*------------------------------------------------------------------------------------------------------------------*/
        }
        return resultBean;
    }
    
    /**
     * 功能描述:批量删除住户
     * @param ids id集合
     * @return ResultBean<Boolean>
     *             
     *                     
     */
    @PostMapping(value = "/deleteUserList")
    @Security(token = EstateSecurityToken.ESTATE_USER_DELETE,format = DataFormatEnum.JSON)
    public ResultBean<Boolean> deleteUserList(@RequestBody List<String> ids){
        if (null == ids || ids.size() <=0){
            //  参数异常
            return new ResultBean<>(ResultEnum.PARAMETER_ANOMALY);
        }
        UserDto userDto = new UserDto();
        userDto.setIds(ids);
        ResultBean<Boolean> resultBean = this.userFeign.deleteUserList(userDto);
        if( null != resultBean.getData() && resultBean.getData()){
            Account onLineUser = this.securityServiceInterface.getOnLineUser();
            /*---------------------------------------------------记录日志--------------------------------------------------------*/
            SysOperationLog sysOperationLog=new SysOperationLog(SysLogMenuConstant.ESTATE_USER_MANAGE, SysLogConstant.DELETE_EVENT,
                    WebUtils.getIp(),userDto,onLineUser);
            sysOperationLogFeign.info(sysOperationLog);
            /*------------------------------------------------------------------------------------------------------------------*/
        }
        return resultBean;
    }

    /**
     * 功能描述:用户人脸审核详情
     * @param id 必填
     * @return ModelAndView
     *             
     *                       
     */
    @GetMapping(value = "/indexUserFaceDetail/{id}/{desensitize}")
    @Security(token = EstateSecurityToken.ESTATE_USER_MANAGE,format = DataFormatEnum.JSON)
    public ModelAndView indexUserFaceDetail(@PathVariable(value = "id")Long id, @PathVariable(value = "desensitize") Boolean desensitize){
        User user =  this.userFeign.findUserById(id);
        if (null == id || null == user){
            //  没有找到要绑定的住户
            return new ModelAndView("common/404");
        }
        List<Dict> sexDict = this.dictFeign.getByCode("sex").getList();
        List<Dict> userTypeDict = this.dictFeign.getByCode("userType").getList();
        List<Dict> nationalityDict = this.dictFeign.getByCode("nationality").getList();
        ModelAndView modelAndView = new ModelAndView("estate/user-face-detail");
        //数据脱敏
        if (!desensitize){
            DesensitizeUtils.desensitize(user);
        }
        modelAndView.addObject("user",user);
        modelAndView.addObject("fastDfsServer",this.confFeign.getFileServerHost());
        modelAndView.addObject("sexDict",sexDict);
        modelAndView.addObject("userTypeDict",userTypeDict);
        modelAndView.addObject("nationalityDict",nationalityDict);
        return modelAndView;
    }

    /**
     * 功能描述:导入住户
     * @param flag 4 住户
     * @return ModelAndView
     *             
     *                      
     */
    @RequestMapping(value = "/indexImportExcel/{flag}")
    @Security(token = EstateSecurityToken.ESTATE_USER_IMPORT,format = DataFormatEnum.VIEW)
    public ModelAndView indexImportExcel(@PathVariable(value = "flag")String flag) {
        ModelAndView modelAndView = new ModelAndView("common/import-excel");
        modelAndView.addObject("flag",flag);
        return modelAndView;
    }

    @RequestMapping(value = "/indexImportFaceZip")
    @Security(token = EstateSecurityToken.ESTATE_USER_IMPORT,format = DataFormatEnum.VIEW)
    public ModelAndView indexImportFaceZip() {
        ModelAndView modelAndView = new ModelAndView("common/import-face-zip");
        return modelAndView;
    }

    /**
     * 功能描述:导出住户
     * @param response
     *             
     *                      
     */
    @RequestMapping(value = "/exportUser")
    @Security(token = EstateSecurityToken.ESTATE_USER_EXPORT)
    public void exportUser(HttpServletResponse response) {
        try {
            response.sendRedirect("/common/excel/exportExcel/4");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //上传人脸
    public static String uploadFace(String face_image_base64, FastFileStorageClient fastFileStorageClient){
        if(StringUtils.isNotBlank(face_image_base64)){
            MultipartFile multipartFile  = Base64DecodeMultipartFileUtils.base64ToMultipart(Base64DecodeMultipartFileUtils.imageFormatToPng("data:image/png;base64," + face_image_base64));
            //图片上传
            StorePath storePath = null;
            try {
                storePath = fastFileStorageClient.uploadFile(
                        multipartFile.getInputStream(),multipartFile.getSize(),
                        FilenameUtils.getExtension(multipartFile.getOriginalFilename()),null);
            } catch (IOException e) {
                return null;
            }
            return storePath.getFullPath();
        }else{
            return null;
        }
    }

    /**
     * 判断字符串中是否包含中文
     * @param str
     * 待校验字符串
     * @return 是否为中文
     * @warn 不能校验是否为中文标点符号
     */
    public static boolean isContainChinese(String str) {
        Pattern p = Pattern.compile("[\u4e00-\u9fa5]");
        Matcher m = p.matcher(str);
        if (m.find()) {
            return true;
        }
        return false;
    }
}
