新增客户

This commit is contained in:
2025-07-02 17:53:53 +08:00
parent 2a81385554
commit 5917234ca8
14 changed files with 137 additions and 355 deletions

View File

@ -157,6 +157,8 @@ public class SysLoginService {
loginUser.setUsername(user.getUserName());
loginUser.setNickname(user.getNickName());
loginUser.setUserType(user.getUserType());
// 用户级别
loginUser.setUserLevel(user.getUserLevel());
loginUser.setMenuPermission(permissionService.getMenuPermission(userId));
loginUser.setRolePermission(permissionService.getRolePermission(userId));
if (ObjectUtil.isNotNull(user.getDeptId())) {

View File

@ -1,5 +1,6 @@
package com.fuyuanshen.common.core.domain.model;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import lombok.NoArgsConstructor;
import com.fuyuanshen.common.core.domain.dto.PostDTO;
@ -132,6 +133,11 @@ public class LoginUser implements Serializable {
*/
private String deviceType;
/**
* 用户等级
*/
private Byte userLevel;
/**
* 获取登录id
*/

View File

@ -3,6 +3,8 @@ package com.fuyuanshen.fyscustomer.domain;
import com.baomidou.mybatisplus.annotation.*;
import com.fuyuanshen.common.core.constant.SystemConstants;
import com.fuyuanshen.common.tenant.core.TenantEntity;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@ -25,7 +27,7 @@ public class Customer extends TenantEntity {
* 用户ID
*/
@TableId(value = "user_id")
private Long userId;
private Long customerId;
/**
* 父id
@ -40,13 +42,18 @@ public class Customer extends TenantEntity {
/**
* 用户账号
*/
@NotNull
private String userName;
/**
* 用户昵称
*/
@NotNull
private String nickName;
@TableField(value = "user_level")
private Byte userLevel;
/**
* 用户类型sys_user系统用户
*/
@ -110,11 +117,11 @@ public class Customer extends TenantEntity {
public Customer(Long userId) {
this.userId = userId;
this.customerId = userId;
}
public boolean isSuperAdmin() {
return SystemConstants.SUPER_ADMIN_ID.equals(this.userId);
return SystemConstants.SUPER_ADMIN_ID.equals(this.customerId);
}
}

View File

@ -75,4 +75,10 @@ public class UserQueryCriteria implements Serializable {
@Schema(name = "APP/小程序账号")
private String username;
/**
* 客户名称
*/
@Schema(name = "客户名称")
private String customerName;
}

View File

@ -24,4 +24,13 @@ public interface CustomerMapper extends BaseMapper<Customer> {
List<Customer> queryAllCustomers(@Param("criteria") UserQueryCriteria criteria);
/**
* 根据条件查询客户
*
* @param criteria
* @return
*/
List<Customer> queryCustomers(@Param("criteria") UserQueryCriteria criteria);
}

View File

@ -2,6 +2,7 @@ package com.fuyuanshen.fyscustomer.service;
import com.fuyuanshen.fyscustomer.domain.Customer;
import com.fuyuanshen.fyscustomer.domain.query.UserQueryCriteria;
import io.undertow.util.BadRequestException;
import java.util.List;
import java.util.Set;
@ -25,7 +26,7 @@ public interface CustomerService {
*
* @param customer /
*/
void addCustomer(Customer customer);
void addCustomer(Customer customer) throws BadRequestException;
/**
* 修改客户

View File

@ -1,10 +1,13 @@
package com.fuyuanshen.fyscustomer.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fuyuanshen.common.core.domain.model.LoginUser;
import com.fuyuanshen.common.satoken.utils.LoginHelper;
import com.fuyuanshen.fyscustomer.domain.Customer;
import com.fuyuanshen.fyscustomer.domain.query.UserQueryCriteria;
import com.fuyuanshen.fyscustomer.mapper.CustomerMapper;
import com.fuyuanshen.fyscustomer.service.CustomerService;
import io.undertow.util.BadRequestException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -43,8 +46,20 @@ public class CustomerServiceImpl extends ServiceImpl<CustomerMapper, Customer> i
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void addCustomer(Customer customer) {
public void addCustomer(Customer customer) throws BadRequestException {
LoginUser loginUser = LoginHelper.getLoginUser();
UserQueryCriteria userQueryCriteria = new UserQueryCriteria();
userQueryCriteria.setCustomerName(customer.getUserName());
List<Customer> customers = customerMapper.queryCustomers(userQueryCriteria);
if (!customers.isEmpty()) {
throw new BadRequestException("用户名已存在!!!");
}
customer.setUserLevel((byte) (loginUser.getUserLevel() + 1));
customer.setPid(loginUser.getUserId());
save(customer);
}

View File

@ -37,7 +37,9 @@
</sql>
<sql id="Base_Column_List">
u1.user_id
u1
.
user_id
as user_user_id, u1.dept_id as user_dept_id, u1.user_name as user_user_name,
u1.nick_name as user_nick_name, u1.email as user_email, u1.phone as user_phone,
u1.gender as user_gender, u1.avatar_name as user_avatar_name, u1.avatar_path as user_avatar_path,
@ -48,12 +50,16 @@
</sql>
<sql id="Job_Column_List">
j . job_id
j
.
job_id
as job_id, j.name as job_name
</sql>
<sql id="Role_Column_List">
r . role_id
r
.
role_id
as role_id, r.name as role_name, r.level as role_level, r.data_scope as role_data_scope
</sql>
@ -84,137 +90,10 @@
</where>
</sql>
<!-- user_user_id 是您在SELECT子句中创建的别名但ORDER BY不能直接使用这个别名引用原始表 -->
<select id="findAll" resultMap="BaseResultMap">
select
u.*,
<include refid="Job_Column_List"/>,
<include refid="Role_Column_List"/>
from (
select
<include refid="Base_Column_List"/>
from sys_user u1
left join sys_dept d on u1.dept_id = d.dept_id
<include refid="Whrer_Sql"/>
order by u1.user_id desc
<if test="criteria.offset != null">
limit #{criteria.offset}, #{criteria.size}
</if>
) u
left join sys_users_jobs suj on u.user_user_id = suj.user_id
left join sys_job j on suj.job_id = j.job_id
left join sys_users_roles sur on u.user_user_id = sur.user_id
left join sys_role r on sur.role_id = r.role_id
order by u.user_user_id desc
</select>
<!-- 根据条件查询 用户 -->
<select id="selectByQuery" resultType="com.fuyuanshen.fyscustomer.domain.Customer">
SELECT u.*
FROM sys_user u
<where>
<if test="userQuery.pid != null">
AND u.pid = #{userQuery.pid}
</if>
</where>
ORDER BY u.user_id DESC
</select>
<!-- 根据条件查询一个用户 -->
<select id="selectByQueryOne" resultType="com.fuyuanshen.fyscustomer.domain.Customer">
select
u.*
from sys_user u
<where>
<if test="userQuery.pid != null">
AND u.pid = #{userQuery.pid}
</if>
<if test="userQuery.nickName != null">
AND u.nick_name = #{userQuery.nickName}
</if>
<if test="userQuery.user_name != null">
AND u.user_name = #{userQuery.user_name}
</if>
<if test="userQuery.password != null">
AND u.password = #{userQuery.password}
</if>
</where>
</select>
<!-- 根据租户ID查询用户 -->
<select id="findByTenantId" resultType="com.fuyuanshen.fyscustomer.domain.Customer">
select
u.*
from sys_user u
<where>
<if test="tenantId != null">
and u.tenant_id = #{tenantId}
</if>
</where>
</select>
<select id="countAll" resultType="java.lang.Long">
select count(*)
from sys_user u1
<include refid="Whrer_Sql"/>
</select>
<!-- 分页查询客户 -->
<select id="findCustomers" resultType="com.fuyuanshen.fyscustomer.domain.Customer">
select
u.user_id as id, u.nick_name , u.user_name, u.enabled, u.create_time
from sys_user u
<where>
<if test="criteria.ids != null and !criteria.ids.isEmpty()">
and u.pid IN
<foreach item="item" collection="criteria.ids" open="(" separator="," close=")">
#{item}
</foreach>
</if>
<if test="criteria.blurry != null and criteria.blurry.trim() != ''">
and u.nick_name like concat('%', TRIM(#{criteria.blurry}), '%')
</if>
<if test="criteria.enabled != null">
and u.enabled = #{criteria.enabled}
</if>
<if test="criteria.createTime != null and criteria.createTime.size() != 0">
and u.create_time between #{criteria.createTime[0]} and #{criteria.createTime[1]}
</if>
</where>
order by u.user_id desc
<if test="criteria.offset != null">
limit #{criteria.offset}, #{criteria.size}
</if>
</select>
<!-- 获取分页总数 -->
<select id="countCustomers" resultType="java.lang.Long">
select count(*)
from sys_user u
<where>
<if test="criteria.ids != null and !criteria.ids.isEmpty()">
and u.pid IN
<foreach item="item" collection="criteria.ids" open="(" separator="," close=")">
#{item}
</foreach>
</if>
<if test="criteria.blurry != null and criteria.blurry.trim() != ''">
and u.nick_name like concat('%', TRIM(#{criteria.blurry}), '%')
</if>
<if test="criteria.enabled != null">
and u.enabled = #{criteria.enabled}
</if>
<if test="criteria.createTime != null and criteria.createTime.size() != 0">
and u.create_time between #{criteria.createTime[0]} and #{criteria.createTime[1]}
</if>
</where>
</select>
<!-- 查询所有客户 -->
<select id="queryAllCustomers" resultType="com.fuyuanshen.fyscustomer.domain.Customer">
select u.user_id as id,
select u.user_id as customerId,
u.nick_name,
u.user_name,
u.enabled,
@ -231,207 +110,21 @@
</where>
</select>
<select id="findByuser_name" resultMap="BaseResultMap">
select
u1.password user_password, u1.is_admin user_is_admin, u1.tenant_id,
<include refid="Base_Column_List"/>
from sys_user u1
left join sys_dept d on u1.dept_id = d.dept_id
where u1.user_name = #{user_name}
</select>
<select id="findByNickName" resultMap="BaseResultMap">
select
u1.password user_password, u1.is_admin user_is_admin, u1.tenant_id,
<include refid="Base_Column_List"/>
from sys_user u1
left join sys_dept d on u1.dept_id = d.dept_id
where u1.nick_name = #{nickName}
</select>
<select id="findByEmail" resultType="com.fuyuanshen.fyscustomer.domain.Customer">
select user_id as id, user_name
from sys_user
where email = #{email}
</select>
<select id="findByPhone" resultType="com.fuyuanshen.fyscustomer.domain.Customer">
select user_id as id, user_name
from sys_user
where phone = #{phone}
</select>
<select id="findByRoleId" resultType="com.fuyuanshen.fyscustomer.domain.Customer">
SELECT u.user_id as id, u.user_name
FROM sys_user u,
sys_users_roles r
WHERE u.user_id = r.user_id
AND r.role_id = #{roleId}
group by u.user_id
</select>
<select id="findByRoleDeptId" resultType="com.fuyuanshen.fyscustomer.domain.Customer">
SELECT u.*
FROM sys_user u,
sys_users_roles r,
sys_roles_depts d
WHERE u.user_id = r.user_id
AND r.role_id = d.role_id
AND d.dept_id = #{deptId}
group by u.user_id
</select>
<select id="findByMenuId" resultType="com.fuyuanshen.fyscustomer.domain.Customer">
SELECT u.user_id as id, u.user_name
FROM sys_user u,
sys_users_roles ur,
sys_roles_menus rm
WHERE u.user_id = ur.user_id
AND ur.role_id = rm.role_id
AND rm.menu_id = #{menuId}
group by u.user_id
</select>
<select id="countByJobs" resultType="int">
SELECT count(*) FROM sys_user u, sys_users_jobs j
WHERE u.user_id = j.user_id AND j.job_id IN
<foreach collection="jobIds" item="jobId" open="(" separator="," close=")">
#{jobId}
</foreach>
</select>
<select id="countByDepts" resultType="int">
SELECT count(*) FROM sys_user u
WHERE u.dept_id IN
<foreach collection="deptIds" item="deptId" open="(" separator="," close=")">
#{deptId}
</foreach>
</select>
<select id="countByRoles" resultType="int">
SELECT count(*) FROM sys_user u, sys_users_roles r
WHERE u.user_id = r.user_id AND r.role_id in
<foreach collection="roleIds" item="roleId" open="(" separator="," close=")">
#{roleId}
</foreach>
</select>
<update id="resetPwd">
update sys_user set password = #{pwd}
where user_id in
<foreach collection="userIds" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</update>
<!-- 获取当前用户以及子用户 -->
<select id="getSubUsers" resultType="com.fuyuanshen.fyscustomer.domain.Customer">
SELECT u.user_id AS id,
<!-- 根据条件查询客户 -->
<select id="queryCustomers" resultType="com.fuyuanshen.fyscustomer.domain.Customer"
parameterType="com.fuyuanshen.fyscustomer.domain.query.UserQueryCriteria">
select u.user_id as customerId,
u.nick_name,
u.user_name,
u.enabled,
u.create_time
FROM sys_user u
WHERE u.pid = #{currentUserId}
OR u.user_id = #{currentUserId}
</select>
<!-- 获取当前用户以及子用户(递归) -->
<select id="findUserTree1" resultType="com.fuyuanshen.fyscustomer.domain.Customer">
WITH RECURSIVE UserTree AS (
-- 初始查询:查找指定用户自己
SELECT user_id AS id, user_name, pid
FROM sys_user
WHERE user_id = #{currentUserId} -- 替换为你要查询的用户ID
UNION ALL
-- 递归部分:查找所有子节点
SELECT u.user_id AS id, u.user_name, u.pid
FROM sys_user u
INNER JOIN UserTree ut ON u.pid = ut.id)
SELECT *
FROM UserTree;
</select>
<!-- 获取当前用户以及子用户(递归)不包含本身 -->
<select id="findUserTree" resultType="com.fuyuanshen.fyscustomer.domain.Customer">
WITH RECURSIVE UserTree AS (
-- 初始查询:查找当前用户的直接子节点
SELECT user_id AS id, user_name, pid
FROM sys_user
WHERE pid = #{currentUserId} -- 当前用户的子节点
UNION ALL
-- 递归部分:查找所有后代节点
SELECT u.user_id AS id, u.user_name, u.pid
FROM sys_user u
INNER JOIN UserTree ut ON u.pid = ut.id)
SELECT *
FROM UserTree;
</select>
<select id="findCustomers1" resultType="com.fuyuanshen.fyscustomer.domain.Customer">
select
u.user_id as id, u.nick_name , u.user_name, u.enabled, u.create_time,
u.pid -- 确保包含 pid 字段
from sys_user u
<where>
<if test="criteria.ids != null and !criteria.ids.isEmpty()">
and u.pid IN
<foreach item="item" collection="criteria.ids" open="(" separator="," close=")">
#{item}
</foreach>
</if>
<if test="criteria.blurry != null and criteria.blurry.trim() != ''">
and u.nick_name like concat('%', TRIM(#{criteria.blurry}), '%')
</if>
<if test="criteria.enabled != null">
and u.enabled = #{criteria.enabled}
</if>
<if test="criteria.createTime != null and criteria.createTime.size() != 0">
and u.create_time between #{criteria.createTime[0]} and #{criteria.createTime[1]}
<if test="criteria.customerName != null and criteria.customerName.trim() != ''">
and u.user_name = concat('%', TRIM(#{criteria.customerName}), '%')
</if>
</where>
order by u.user_id desc
<if test="criteria.offset != null">
limit #{criteria.offset}, #{criteria.size}
</if>
</select>
<select id="findUsersWithAncestorsByIds" resultType="com.fuyuanshen.fyscustomer.domain.Customer">
WITH RECURSIVE user_tree AS (
SELECT * FROM sys_user WHERE user_id IN
<foreach item="item" collection="ids" open="(" separator="," close=")">
#{item}
</foreach>
UNION ALL
SELECT u.* FROM sys_user u
INNER JOIN user_tree ut ON u.user_id = ut.pid
)
SELECT DISTINCT * FROM user_tree;
</select>
<!-- 获取当前用户的祖先用户 -->
<select id="findAncestorsById" resultType="com.fuyuanshen.fyscustomer.domain.Customer">
WITH RECURSIVE user_ancestors AS (SELECT user_id, pid, tenant_id
FROM sys_user
WHERE user_id = #{currentUserId}
UNION ALL
SELECT u.user_id, u.pid, u.tenant_id
FROM sys_user u
INNER JOIN user_ancestors a ON u.user_id = a.pid)
SELECT *
FROM user_ancestors
WHERE user_id != #{currentUserId}
AND user_id IS NOT NULL;
</select>

View File

@ -1,5 +1,6 @@
package com.fuyuanshen.equipment.domain.query;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.sql.Timestamp;
@ -16,19 +17,22 @@ import java.util.Set;
@Data
public class DeviceQueryCriteria {
// @Schema(value = "设备名称")
@Schema(name = "设备id")
private Long deviceId;
@Schema(name = "设备名称")
private String deviceName;
// @Schema(value = "设备类型")
private Long deviceType;
@Schema(name = "设备类型")
private Long deviceTypeId;
// @Schema(value = "设备MAC")
@Schema(name = "设备MAC")
private String deviceMac;
// @Schema(value = "设备IMEI")
@Schema(name = "设备IMEI")
private String deviceImei;
// @Schema(value = "设备SN")
@Schema(name = "设备SN")
private String deviceSn;
/**
@ -36,29 +40,29 @@ public class DeviceQueryCriteria {
* 0 失效
* 1 正常
*/
// @Schema(value = "设备状态 0 失效 1 正常 ")
@Schema(name = "设备状态 0 失效 1 正常 ")
private Integer deviceStatus;
// @Schema(value = "创建时间")
@Schema(name = "创建时间")
private List<Timestamp> createTime;
// @Schema(value = "页码", example = "1")
@Schema(name = "页码", example = "1")
private Integer page = 1;
// @Schema(value = "每页数据量", example = "10")
@Schema(name = "每页数据量", example = "10")
private Integer size = 10;
// @Schema(value = "客户id")
@Schema(name = "客户id")
private Long customerId;
private Set<Long> customerIds;
// @Schema(value = "当前所有者")
@Schema(name = "当前所有者")
private Long currentOwnerId;
// @Schema(value = "租户ID")
@Schema(name = "租户ID")
private Long tenantId;
// @Schema(value = "通讯方式", example = "0:4G;1:蓝牙")
@Schema(name = "通讯方式", example = "0:4G;1:蓝牙")
private Integer communicationMode;
}

View File

@ -27,7 +27,9 @@ import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* @Description:
@ -44,7 +46,6 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
@Value("${file.device.ip}")
private String ip;
private final DeviceMapper deviceMapper;
private final DeviceTypeMapper deviceTypeMapper;
@ -129,10 +130,22 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
@Transactional(rollbackFor = Exception.class)
public void update(DeviceForm deviceForm) throws Exception {
Device device = getById(deviceForm.getId());
if (device == null) {
DeviceTypeQueryCriteria deviceTypeQueryCriteria = new DeviceTypeQueryCriteria();
deviceTypeQueryCriteria.setDeviceTypeId(deviceForm.getId());
deviceTypeQueryCriteria.setCustomerId(LoginHelper.getUserId());
List<DeviceType> deviceTypes = deviceTypeMapper.findAll(deviceTypeQueryCriteria);
if (deviceTypes.isEmpty()) {
throw new Exception("设备类型不存在!!!");
}
DeviceQueryCriteria queryCriteria = new DeviceQueryCriteria();
queryCriteria.setDeviceId(deviceForm.getId());
queryCriteria.setCustomerId(LoginHelper.getUserId());
List<Device> devices = deviceMapper.findAll(queryCriteria);
if (devices.isEmpty()) {
throw new Exception("设备不存在!!!");
}
Device device = devices.get(0);
// 处理上传的图片
String imageUrl = saveDeviceImage(deviceForm.getFile(), device.getDeviceName());
@ -182,6 +195,18 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteAll(List<Long> ids) {
List<Long> invalidIds = new ArrayList<>();
for (Long id : ids) {
Device deviceType = deviceMapper.selectById(id);
if (deviceType == null || !Objects.equals(deviceType.getCurrentOwnerId(), LoginHelper.getUserId())) {
invalidIds.add(id);
}
}
if (!invalidIds.isEmpty()) {
throw new RuntimeException("以下设备无法删除ID 不存在或无权限): " + invalidIds);
}
deviceMapper.deleteByIds(ids);
}

View File

@ -6,8 +6,10 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fuyuanshen.common.core.domain.PageResult;
import com.fuyuanshen.common.core.utils.PageUtil;
import com.fuyuanshen.common.satoken.utils.LoginHelper;
import com.fuyuanshen.equipment.domain.Device;
import com.fuyuanshen.equipment.domain.DeviceType;
import com.fuyuanshen.equipment.domain.form.DeviceTypeForm;
import com.fuyuanshen.equipment.domain.query.DeviceQueryCriteria;
import com.fuyuanshen.equipment.domain.query.DeviceTypeQueryCriteria;
import com.fuyuanshen.equipment.mapper.DeviceMapper;
import com.fuyuanshen.equipment.mapper.DeviceTypeMapper;
@ -114,17 +116,25 @@ public class DeviceTypeServiceImpl extends ServiceImpl<DeviceTypeMapper, DeviceT
public void deleteAll(List<Long> ids) {
List<Long> invalidIds = new ArrayList<>();
List<Long> invalidId2 = new ArrayList<>();
for (Long id : ids) {
DeviceType deviceType = deviceTypeMapper.selectById(id);
if (deviceType == null || !Objects.equals(deviceType.getCustomerId(), LoginHelper.getUserId())) {
invalidIds.add(id);
}
DeviceQueryCriteria deviceQueryCriteria = new DeviceQueryCriteria();
deviceQueryCriteria.setDeviceTypeId(id);
List<Device> devices = deviceMapper.findAll(deviceQueryCriteria);
if (!devices.isEmpty()) {
invalidId2.add(id);
}
}
if (!invalidIds.isEmpty()) {
throw new RuntimeException("以下设备类型无法删除ID 不存在或无权限): " + invalidIds);
}
if (!invalidId2.isEmpty()) {
throw new RuntimeException("以下设备类型无法删除(已绑定设备): " + invalidId2);
}
deviceTypeMapper.deleteByIds(ids);
}

View File

@ -55,8 +55,8 @@
<if test="criteria.deviceImei != null">
and d.device_imei = #{criteria.deviceImei}
</if>
<if test="criteria.deviceType != null">
and d.device_type = #{criteria.deviceType}
<if test="criteria.deviceTypeId != null">
and d.device_type = #{criteria.deviceTypeId}
</if>
<if test="criteria.deviceStatus != null">
-- and da.active = #{criteria.deviceStatus}
@ -148,8 +148,8 @@
<if test="criteria.deviceMac != null">
and d.device_mac = #{criteria.deviceMac}
</if>
<if test="criteria.deviceType != null">
and d.device_type = #{criteria.deviceType}
<if test="criteria.deviceTypeId != null">
and d.device_type = #{criteria.deviceTypeId}
</if>
<if test="criteria.createTime != null and criteria.createTime.size() != 0">
and d.create_time between #{criteria.createTime[0]} and #{criteria.createTime[1]}

View File

@ -103,6 +103,8 @@ public class SysUser extends TenantEntity {
*/
private String remark;
private Byte userLevel;
public SysUser(Long userId) {
this.userId = userId;

View File

@ -139,4 +139,6 @@ public class SysUserVo implements Serializable {
*/
private Long roleId;
private Byte userLevel;
}