forked from gzzfw/backEnd/gz-dyh

xusd
2024-10-14 3721eea476d9dad0a5838b3aa89a30a8b4640f7d
网格登录对接
4 files renamed
11 files modified
259 ■■■■ changed files
dyh-service/dyh-base/src/main/java/cn/huge/module/sys/dto/GridRoleMenuDTO.java 5 ●●●● patch | view | raw | blame | history
dyh-service/dyh-base/src/main/java/cn/huge/module/sys/dto/GridUserRoleDTO.java 4 ●●● patch | view | raw | blame | history
dyh-service/dyh-base/src/main/java/cn/huge/module/sys/vo/GridRoleMenuVo.java 2 ●●● patch | view | raw | blame | history
dyh-service/dyh-base/src/main/java/cn/huge/module/sys/vo/GridUserRoleVo.java 2 ●●● patch | view | raw | blame | history
dyh-service/dyh-cust/src/main/java/cn/huge/module/client/api/SysClient.java 15 ●●●●● patch | view | raw | blame | history
dyh-service/dyh-cust/src/main/java/cn/huge/module/client/api/impl/SysClientImpl.java 53 ●●●●● patch | view | raw | blame | history
dyh-service/dyh-cust/src/main/java/cn/huge/module/ctuser/dao/mapper/CtUnitMapper.java 2 ●●●●● patch | view | raw | blame | history
dyh-service/dyh-cust/src/main/java/cn/huge/module/ctuser/dao/mapper/xml/CtUnitMapper.xml 8 ●●●●● patch | view | raw | blame | history
dyh-service/dyh-cust/src/main/java/cn/huge/module/ctuser/service/CtAccountService.java 126 ●●●● patch | view | raw | blame | history
dyh-service/dyh-cust/src/main/java/cn/huge/module/ctuser/service/CtUnitService.java 5 ●●●●● patch | view | raw | blame | history
dyh-service/dyh-sys/src/main/java/cn/huge/module/grid/controller/GridUserInfoController.java 12 ●●●● patch | view | raw | blame | history
dyh-service/dyh-sys/src/main/java/cn/huge/module/grid/domain/dto/GridSysRoleDTO.java 2 ●●● patch | view | raw | blame | history
dyh-service/dyh-sys/src/main/java/cn/huge/module/grid/domain/vo/GridRoleMenuRequestVo.java 1 ●●●● patch | view | raw | blame | history
dyh-service/dyh-sys/src/main/java/cn/huge/module/grid/domain/vo/GridUserRoleRequestVo.java 1 ●●●● patch | view | raw | blame | history
dyh-service/dyh-sys/src/main/java/cn/huge/module/grid/service/GridUserService.java 21 ●●●● patch | view | raw | blame | history
dyh-service/dyh-base/src/main/java/cn/huge/module/sys/dto/GridRoleMenuDTO.java
File was renamed from dyh-service/dyh-sys/src/main/java/cn/huge/module/grid/domain/dto/GridRoleMenuDTO.java
@@ -1,6 +1,8 @@
package cn.huge.module.grid.domain.dto;
package cn.huge.module.sys.dto;
import lombok.Data;
import java.util.List;
@Data
public class GridRoleMenuDTO {
@@ -33,5 +35,6 @@
     */
    private String parentId;
    private String orderBy;
    private List<GridRoleMenuDTO> children;
}
dyh-service/dyh-base/src/main/java/cn/huge/module/sys/dto/GridUserRoleDTO.java
File was renamed from dyh-service/dyh-sys/src/main/java/cn/huge/module/grid/domain/dto/GridUserRoleDTO.java
@@ -1,8 +1,6 @@
package cn.huge.module.grid.domain.dto;
package cn.huge.module.sys.dto;
import lombok.Data;
import java.util.List;
@Data
public class GridUserRoleDTO {
dyh-service/dyh-base/src/main/java/cn/huge/module/sys/vo/GridRoleMenuVo.java
File was renamed from dyh-service/dyh-sys/src/main/java/cn/huge/module/grid/domain/vo/GridRoleMenuVo.java
@@ -1,4 +1,4 @@
package cn.huge.module.grid.domain.vo;
package cn.huge.module.sys.vo;
import lombok.Data;
dyh-service/dyh-base/src/main/java/cn/huge/module/sys/vo/GridUserRoleVo.java
File was renamed from dyh-service/dyh-sys/src/main/java/cn/huge/module/grid/domain/vo/GridUserRoleVo.java
@@ -1,4 +1,4 @@
package cn.huge.module.grid.domain.vo;
package cn.huge.module.sys.vo;
import lombok.Data;
dyh-service/dyh-cust/src/main/java/cn/huge/module/client/api/SysClient.java
@@ -2,11 +2,17 @@
import cn.huge.base.common.bo.R;
import cn.huge.base.common.bo.ReturnBO;
import cn.huge.module.sys.dto.GridRoleMenuDTO;
import cn.huge.module.sys.dto.GridTokenBaseDTO;
import cn.huge.module.sys.dto.GridUserRoleDTO;
import cn.huge.module.sys.vo.GridRoleMenuVo;
import cn.huge.module.sys.vo.GridUserRoleVo;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.List;
/**
 * @title: 系统服务微服务调用接口
@@ -28,10 +34,17 @@
    /**
     * 根据用户token获取用户信息
     * @url {ctx}/api/thrid/grid/user/get-userinfo
     *
     * @param gridTokenBaseDTO
     * @return
     * @url {ctx}/api/thrid/grid/user/get-userinfo
     */
    @PostMapping("/api/thrid/grid/user/get-userinfo")
    ReturnBO getUserInfo(@RequestBody GridTokenBaseDTO gridTokenBaseDTO);
    @PostMapping("/api/thrid/grid/user/get-user-role")
    R<List<GridUserRoleDTO>> getUserRoleList(@RequestBody GridUserRoleVo gridUserRoleVo);
    @PostMapping("/api/thrid/grid/user/get-role-menu")
    R<List<GridRoleMenuDTO>> getRoleMenu(@RequestBody GridRoleMenuVo gridRoleMenuVo);
}
dyh-service/dyh-cust/src/main/java/cn/huge/module/client/api/impl/SysClientImpl.java
@@ -1,18 +1,29 @@
package cn.huge.module.client.api.impl;
import cn.huge.base.common.bo.R;
import cn.huge.base.common.bo.ReturnBO;
import cn.huge.base.common.constant.ReturnConsts;
import cn.huge.base.common.exception.ClientException;
import cn.huge.base.common.exception.ServiceException;
import cn.huge.module.client.api.SysClient;
import cn.huge.module.client.api.UtilsClient;
import cn.huge.module.ctuser.domain.po.CtUserole;
import cn.huge.module.cust.dto.CtUnitDTO;
import cn.huge.module.sys.dto.GridRoleMenuDTO;
import cn.huge.module.sys.dto.GridTokenBaseDTO;
import cn.huge.module.sys.dto.GridUserBaseDTO;
import cn.huge.module.sys.dto.GridUserRoleDTO;
import cn.huge.module.sys.vo.GridRoleMenuVo;
import cn.huge.module.sys.vo.GridUserRoleVo;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.List;
/**
@@ -41,9 +52,10 @@
    /**
     * 根据用户token获取用户信息
     * @url {ctx}/api/thrid/grid/user/get-userinfo
     *
     * @param gridTokenBaseDTO
     * @return
     * @url {ctx}/api/thrid/grid/user/get-userinfo
     */
    public GridUserBaseDTO getUserInfo(GridTokenBaseDTO gridTokenBaseDTO){
        GridUserBaseDTO gridUserBaseDTO = null;
@@ -61,4 +73,43 @@
        return gridUserBaseDTO;
    }
    /**
     * @param gridUserRoleVo
     * @return 返回当前登录使用的机构角色
     */
    public GridUserRoleDTO getUserRoleList(GridUserRoleVo gridUserRoleVo) {
        GridUserRoleDTO roleDTO = new GridUserRoleDTO();
        R<List<GridUserRoleDTO>> userRoleList = sysClient.getUserRoleList(gridUserRoleVo);
        if (userRoleList.getCode() == R.SUCCESS) {
            List<GridUserRoleDTO> data = userRoleList.getData();
            for (GridUserRoleDTO item : data) {
                if (item.isLastOrgRole()) {
                    BeanUtils.copyProperties(item, roleDTO);
                    break;
                }
            }
        }
        return roleDTO;
    }
    /**
     * @param gridRoleMenuVo
     * @return true管理员,全部权限;false,纠纷调解员,部分权限    //如果全部菜单权限,分配管理员角色;如果部分菜单权限,分配纠纷化解员角色
     */
    public CtUserole getRoleMenu(GridRoleMenuVo gridRoleMenuVo) {
        CtUserole ctUserole = new CtUserole();
        ctUserole.setRoleId("22_00024-4");
        ctUserole.setRoleName("纠纷化解人员");
        R<List<GridRoleMenuDTO>> roleMenu = sysClient.getRoleMenu(gridRoleMenuVo);
        if (roleMenu.getCode() == R.SUCCESS) {
            List<GridRoleMenuDTO> data = roleMenu.getData();
            String name = data.get(0).getName();
            if("矛盾纠纷化解子系统".equals(name)){
                List<GridRoleMenuDTO> children = data.get(0).getChildren();
            }
        }
        return ctUserole;
    }
}
dyh-service/dyh-cust/src/main/java/cn/huge/module/ctuser/dao/mapper/CtUnitMapper.java
@@ -80,4 +80,6 @@
     * @return String
     */
    List<CtUnit> listAllChild(@Param("unitId") String unitId);
    CtUnit selectUnitByGridId(@Param("gridUnitId") String gridUnitId);
}
dyh-service/dyh-cust/src/main/java/cn/huge/module/ctuser/dao/mapper/xml/CtUnitMapper.xml
@@ -384,4 +384,12 @@
        FROM
        unit_hierarchy;
    </select>
    <!--  根据条件分页查询  -->
    <select id="selectUnitByGridId" resultMap="dataResult">
        SELECT
            t1.*
        FROM dyh_ct_unit t1 left join dyh_ct_unit_grid t2 on t1.id = t2.dyh_unit_id
        where t2.third_unit_id = #{gridUnitId} limit 1
    </select>
</mapper> 
dyh-service/dyh-cust/src/main/java/cn/huge/module/ctuser/service/CtAccountService.java
@@ -1,5 +1,6 @@
package cn.huge.module.ctuser.service;
import cn.huge.base.common.bo.R;
import cn.huge.base.common.bo.ReturnBO;
import cn.huge.base.common.exception.ServiceException;
import cn.huge.base.common.utils.*;
@@ -7,15 +8,16 @@
import cn.huge.module.client.api.impl.UtilsClientImpl;
import cn.huge.module.ctuser.dao.mapper.CtAccountMapper;
import cn.huge.module.ctuser.domain.po.CtAccount;
import cn.huge.module.ctuser.domain.po.CtUnit;
import cn.huge.module.ctuser.domain.po.CtUser;
import cn.huge.module.ctuser.domain.po.CtUserole;
import cn.huge.module.ctuser.dto.CtAccountLoginDTO;
import cn.huge.module.ctuser.dto.CtCipherDTO;
import cn.huge.module.ctuser.dto.CtUserAddrDTO;
import cn.huge.module.ctuser.dto.UserLoginDTO;
import cn.huge.module.ctuser.dto.*;
import cn.huge.module.cust.constant.UserBaseConsts;
import cn.huge.module.sys.dto.GridTokenBaseDTO;
import cn.huge.module.sys.dto.GridUserBaseDTO;
import cn.huge.module.sys.dto.GridUserRoleDTO;
import cn.huge.module.sys.vo.GridRoleMenuVo;
import cn.huge.module.sys.vo.GridUserRoleVo;
import cn.huge.module.utils.JwtUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
@@ -31,6 +33,7 @@
import org.springframework.util.DigestUtils;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
@@ -59,6 +62,8 @@
    private CtUseroleService ctUseroleService;
    @Autowired
    private SysClientImpl sysClient;
    @Autowired
    private CtUnitService ctUnitService;
    /**
     * 更新对象
@@ -347,23 +352,55 @@
                return ReturnFailUtils.getRepInfo("gridToken已失效,请重新登录!");
            }
            // 判断账号是否存在
            CtAccount ctAccount = this.getByAccAndType(gridUserBaseDTO.getAccount(), UserBaseConsts.ACC_TYPE_1);
            if (ObjectUtils.isEmpty(ctAccount)) {
                ctAccount = this.getByAccAndType(gridUserBaseDTO.getMobile(), UserBaseConsts.ACC_TYPE_1);
            }
            CtAccount ctAccount = null;
            CtUser ctUser = null;
            if (ObjectUtils.isNotEmpty(ctAccount)) {
                //返回结果
                ctUser = ctUserService.getById(ctAccount.getUserId());
                if (ObjectUtils.isEmpty(ctUser)) {
                    return ReturnFailUtils.getRepInfo("用户不存在!");
                }
            } else {
                //如果和亿迅系统的手机号对不上,在用身份证号去查询用户,如果查询得到,就对得上,如果查询不到,就说明用户不存在
                ctUser = ctUserService.getByIdCard(gridUserBaseDTO.getIdNumber());
            }
            if (ObjectUtils.isNotEmpty(ctUser)) {
                //返回结果
                ctAccount = this.getByUserIdAndType(ctUser.getId(), UserBaseConsts.ACC_TYPE_1);
            }
//            CtAccount ctAccount = this.getByAccAndType(gridUserBaseDTO.getAccount(), UserBaseConsts.ACC_TYPE_1);
//            if (ObjectUtils.isEmpty(ctAccount)) {
//                ctAccount = this.getByAccAndType(gridUserBaseDTO.getMobile(), UserBaseConsts.ACC_TYPE_1);
//            }
//            if (ObjectUtils.isNotEmpty(ctAccount)) {
//                //返回结果
//                ctUser = ctUserService.getById(ctAccount.getUserId());
//                if (ObjectUtils.isEmpty(ctUser)) {
//                    return ReturnFailUtils.getRepInfo("用户不存在!");
//                }
//            } else {
//
//            }
            if (ObjectUtils.isNotEmpty(ctUser)) {
                //有对应用户,则模拟登录,返回对应信息
                UserLoginDTO userLoginDTO = login(ctAccount, ctUser);
                return ReturnSucUtils.getRepInfo(userLoginDTO);
            } else {
                //没有对应用户,创建用户,根据用户id获取用户信息
                ReturnBO repInfo = initNewUser(gridUserBaseDTO);
                if (repInfo.getCode() == 0) {
                    //创建用户成功,模拟登录
                    ctUser = ctUserService.getByIdCard(gridUserBaseDTO.getIdNumber());
                    if (ObjectUtils.isNotEmpty(ctUser)) {
                        ctAccount = this.getByUserIdAndType(ctUser.getId(), UserBaseConsts.ACC_TYPE_1);
                    }
                    UserLoginDTO userLoginDTO = login(ctAccount, ctUser);
                    return ReturnSucUtils.getRepInfo(userLoginDTO);
                } else {
                    //创建用户失败,返回失败信息
                    return repInfo;
                }
            }
        } catch (Exception e) {
            log.error("service方法[AccountService.webGridLogin]调用失败,异常信息:" + e, e);
            throw new ServiceException("CtAccountService.webGridLogin", e);
        }
    }
    private UserLoginDTO login(CtAccount ctAccount, CtUser ctUser) {
                UserLoginDTO userLoginDTO = new UserLoginDTO();
                // 封装用户信息
                userLoginDTO.setToken(JwtUtils.buildJWT(ctUser.getId()));
@@ -389,36 +426,51 @@
                ctUserAddrDTO.setVillageName(ctUser.getVillageName());
                userLoginDTO.setCtUserAddrDTO(ctUserAddrDTO);
                // 最后登录时间
                Date loginTime = ctAccount.getLoginTime();
                if (ObjectUtils.isEmpty(ctAccount.getLoginTime())) {
                    loginTime = DateUtils.getNowDate();
                }
        Date loginTime = new Date();
                userLoginDTO.setLastLoginTime(loginTime);
                // 更新最新登录时间
                UpdateWrapper<CtAccount> accountUpdateWrapper = new UpdateWrapper<>();
                accountUpdateWrapper.set("login_time", loginTime).eq("id", ctAccount.getId());
                this.update(accountUpdateWrapper);
                return ReturnSucUtils.getRepInfo(userLoginDTO);
            } else {
        return userLoginDTO;
    }
    private ReturnBO initNewUser(GridUserBaseDTO gridUserBaseDTO) {
                String userId = gridUserBaseDTO.getId();
                //根据用户id获取用户信息
                //拿到用户机构信息
                //拿到用户角色菜单权限信息
                //如果全部菜单权限,分配管理员角色;如果部分菜单权限,分配纠纷化解员角色
                //初始化完成用户信息,返回给前端登录
        GridUserRoleVo gridUserRoleVo = new GridUserRoleVo();
        gridUserRoleVo.setUserId(userId);
        GridUserRoleDTO userRoleDTO = sysClient.getUserRoleList(gridUserRoleVo);
        if (StringUtils.isEmpty(userRoleDTO.getOrgName())) {
                return ReturnFailUtils.getRepInfo("用户不存在!,请确认后重试!");
            }
        } catch (Exception e) {
            log.error("service方法[AccountService.webGridLogin]调用失败,异常信息:" + e, e);
            throw new ServiceException("CtAccountService.webGridLogin", e);
        if (StringUtils.isNotEmpty(userRoleDTO.getOrgName()) && userRoleDTO.getOrgName().endsWith("网格")) {
            return ReturnFailUtils.getRepInfo("该用户所在机构禁止登录矛调系统,请切换该用户机构为区、镇街、社区机构");
        }
        //拿到用户角色菜单权限信息
        GridRoleMenuVo gridRoleMenuVo = new GridRoleMenuVo();
        gridRoleMenuVo.setOrgRoleId(userRoleDTO.getRoleId());
        gridRoleMenuVo.setMenuSys("sub-mdjfhj");
        CtUserole roleMenu = sysClient.getRoleMenu(gridRoleMenuVo);
        List<CtUserole> ctUseroles = new ArrayList<>();
        ctUseroles.add(roleMenu);
        CtUnit ctUnit = ctUnitService.selectUnitByGridId(userRoleDTO.getOrgId());
        if (ctUnit != null && StringUtils.isNotEmpty(ctUnit.getId())) {
            CtUserSaveDTO ctUserSaveDTO = new CtUserSaveDTO();
            ctUserSaveDTO.setUnitId(ctUnit.getId());
            ctUserSaveDTO.setUnitName(ctUnit.getUnitName());
            ctUserSaveDTO.setCipher("byzfw2023!");
            ctUserSaveDTO.setAcc(gridUserBaseDTO.getMobile());
            ctUserSaveDTO.setTrueName(gridUserBaseDTO.getName());
            ctUserSaveDTO.setMobile(gridUserBaseDTO.getMobile());
            ctUserSaveDTO.setIdcard(gridUserBaseDTO.getIdNumber());
            ctUserSaveDTO.setCtUseroleList(ctUseroles);
            ctUserService.webSaveCtUser(ctUserSaveDTO, "-1");
        } else {
            return ReturnFailUtils.getRepInfo("用户不存在!,请确认后重试!");
        }
        return ReturnSucUtils.getRepInfo("创建账号成功");
    }
}
dyh-service/dyh-cust/src/main/java/cn/huge/module/ctuser/service/CtUnitService.java
@@ -23,6 +23,7 @@
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -670,4 +671,8 @@
            throw new ServiceException("CtUnitService.getParentZzzx", e);
        }
    }
    public CtUnit selectUnitByGridId(String gridUnitId){
        return mapper.selectUnitByGridId(gridUnitId);
    }
}
dyh-service/dyh-sys/src/main/java/cn/huge/module/grid/controller/GridUserInfoController.java
@@ -1,12 +1,13 @@
package cn.huge.module.grid.controller;
import cn.huge.base.common.bo.R;
import cn.huge.base.common.utils.ReturnSucUtils;
import cn.huge.module.grid.domain.dto.GridRoleMenuDTO;
import cn.huge.module.grid.domain.dto.GridSysRoleDTO;
import cn.huge.module.grid.domain.dto.GridUserRoleDTO;
import cn.huge.module.grid.domain.vo.*;
import cn.huge.module.grid.service.GridUserService;
import cn.huge.module.sys.dto.GridRoleMenuDTO;
import cn.huge.module.sys.dto.GridUserRoleDTO;
import cn.huge.module.sys.vo.GridRoleMenuVo;
import cn.huge.module.sys.vo.GridUserRoleVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@@ -48,4 +49,9 @@
    public R<List<GridRoleMenuDTO>> getRoleMenu(@RequestBody GridRoleMenuVo gridRoleMenuVo) {
        return gridUserService.getRoleMenu(gridRoleMenuVo);
    }
    public R<String> initNewUsers(@RequestBody GridUserRoleVo gridUserRoleVo){
        return gridUserService.initNewUsers(gridUserRoleVo);
    }
}
dyh-service/dyh-sys/src/main/java/cn/huge/module/grid/domain/dto/GridSysRoleDTO.java
@@ -26,7 +26,7 @@
    /**
     * 数据记录
     */
    private List<SySRoleDTO> records;
    private List<SySRoleDTO> list;
    @Data
    public static class SySRoleDTO {
dyh-service/dyh-sys/src/main/java/cn/huge/module/grid/domain/vo/GridRoleMenuRequestVo.java
@@ -1,5 +1,6 @@
package cn.huge.module.grid.domain.vo;
import cn.huge.module.sys.vo.GridRoleMenuVo;
import lombok.Data;
@Data
dyh-service/dyh-sys/src/main/java/cn/huge/module/grid/domain/vo/GridUserRoleRequestVo.java
@@ -1,5 +1,6 @@
package cn.huge.module.grid.domain.vo;
import cn.huge.module.sys.vo.GridUserRoleVo;
import lombok.Data;
@Data
dyh-service/dyh-sys/src/main/java/cn/huge/module/grid/service/GridUserService.java
@@ -3,11 +3,12 @@
import cn.huge.base.common.bo.R;
import cn.huge.base.common.utils.HttpClientUtils;
import cn.huge.base.common.utils.SpringContextUtil;
import cn.huge.module.grid.domain.dto.GridOrgDTO;
import cn.huge.module.grid.domain.dto.GridRoleMenuDTO;
import cn.huge.module.grid.domain.dto.GridSysRoleDTO;
import cn.huge.module.grid.domain.dto.GridUserRoleDTO;
import cn.huge.module.grid.domain.vo.*;
import cn.huge.module.sys.dto.GridRoleMenuDTO;
import cn.huge.module.sys.dto.GridUserRoleDTO;
import cn.huge.module.sys.vo.GridRoleMenuVo;
import cn.huge.module.sys.vo.GridUserRoleVo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
@@ -131,4 +132,18 @@
        List<GridRoleMenuDTO> gridRoleMenuDTOList = data.toJavaList(GridRoleMenuDTO.class);
        return R.ok(gridRoleMenuDTOList);
    }
    public R<String> initNewUsers(GridUserRoleVo gridUserRoleVo) {
        //根据用户id获取用户信息
        //拿到用户机构信息
        //拿到用户角色菜单权限信息
        //如果全部菜单权限,分配管理员角色;如果部分菜单权限,分配纠纷化解员角色
        //初始化完成用户信息,返回给前端登录
        return R.fail();
    }
}