|
@@ -8,6 +8,8 @@ import java.util.stream.Collectors;
|
|
|
|
|
|
import cn.dev33.satoken.spring.SpringMVCUtil;
|
|
|
import cn.dev33.satoken.stp.StpUtil;
|
|
|
+import cn.hutool.json.JSONUtil;
|
|
|
+import cn.hutool.log.StaticLog;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.pj.api.client.admin.AdminInterface;
|
|
|
import com.pj.api.client.level_one_server.LevelOneServerInterface;
|
|
@@ -50,155 +52,181 @@ import org.springframework.transaction.annotation.Transactional;
|
|
|
*/
|
|
|
@Service
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
-public class AppUserService extends ServiceImpl<AppUserMapper, AppUser> implements IService<AppUser>{
|
|
|
-
|
|
|
- /** 底层 Mapper 对象 */
|
|
|
- @Autowired
|
|
|
- AppUserMapper appUserMapper;
|
|
|
- /** 密码加密模式 */
|
|
|
- @Autowired
|
|
|
- private PasswordEncoder passwordEncoder;
|
|
|
- //权限字符
|
|
|
- @Autowired
|
|
|
- private ReRoleMenuMapper reRoleMenuMapper;
|
|
|
- /** 方法抽取 */
|
|
|
- @Autowired
|
|
|
- private MethodAppUserService methodAppUserService;
|
|
|
- /** 阿里云验证码 */
|
|
|
- @Autowired
|
|
|
- private SmsRetryService smsRetryService;
|
|
|
- @Autowired
|
|
|
- private LevelOneServerInterface levelOneServerInterface;
|
|
|
- @Autowired
|
|
|
- private TransportInterface transportInterface;
|
|
|
- @Autowired
|
|
|
- AppUserLoginLogService appUserLoginLogService;
|
|
|
-
|
|
|
- /** 验证码前缀 */
|
|
|
- String PREFIX = "app_user:phone:sms_code:";
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- /** 增 */
|
|
|
- void add(AppUser t){
|
|
|
- save(t);
|
|
|
- }
|
|
|
+public class AppUserService extends ServiceImpl<AppUserMapper, AppUser> implements IService<AppUser> {
|
|
|
|
|
|
- /** 删 */
|
|
|
- void delete(Long id){
|
|
|
- removeById(id);
|
|
|
- }
|
|
|
+ /**
|
|
|
+ * 底层 Mapper 对象
|
|
|
+ */
|
|
|
+ @Autowired
|
|
|
+ AppUserMapper appUserMapper;
|
|
|
+ /**
|
|
|
+ * 密码加密模式
|
|
|
+ */
|
|
|
+ @Autowired
|
|
|
+ private PasswordEncoder passwordEncoder;
|
|
|
+ //权限字符
|
|
|
+ @Autowired
|
|
|
+ private ReRoleMenuMapper reRoleMenuMapper;
|
|
|
+ /**
|
|
|
+ * 方法抽取
|
|
|
+ */
|
|
|
+ @Autowired
|
|
|
+ private MethodAppUserService methodAppUserService;
|
|
|
+ /**
|
|
|
+ * 阿里云验证码
|
|
|
+ */
|
|
|
+ @Autowired
|
|
|
+ private SmsRetryService smsRetryService;
|
|
|
+ @Autowired
|
|
|
+ private LevelOneServerInterface levelOneServerInterface;
|
|
|
+ @Autowired
|
|
|
+ private TransportInterface transportInterface;
|
|
|
+ @Autowired
|
|
|
+ AppUserLoginLogService appUserLoginLogService;
|
|
|
|
|
|
- /** 改 */
|
|
|
- void update(AppUser a){
|
|
|
- a.setUpdateTime(new Date());
|
|
|
- updateById(a);
|
|
|
+ /**
|
|
|
+ * 验证码前缀
|
|
|
+ */
|
|
|
+ String PREFIX = "app_user:phone:sms_code:";
|
|
|
|
|
|
- }
|
|
|
|
|
|
- /** 查 */
|
|
|
- AppUser getById(Long id){
|
|
|
- return super.getById(id);
|
|
|
- }
|
|
|
+ /**
|
|
|
+ * 增
|
|
|
+ */
|
|
|
+ void add(AppUser t) {
|
|
|
+ save(t);
|
|
|
+ }
|
|
|
|
|
|
- /**
|
|
|
- * 个人中心-个人详细信息
|
|
|
- * @return
|
|
|
- */
|
|
|
- AppUserVo getSelfInfo(){
|
|
|
- //查询当前人
|
|
|
- AppUser appUser = appUserMapper.selectById(StpAPPUserUtil.getAPPLoginInfo().getLoginId());
|
|
|
- if(appUser == null)throw new ServiceException("当前用户信息异常!");
|
|
|
- //获取当前组
|
|
|
- //创建返回值对象
|
|
|
- AppUserVo appUserVo = new AppUserVo();
|
|
|
- //根据身份获取不同名称
|
|
|
- appUserVo.setFk(appUser.getFkId());
|
|
|
- methodAppUserService.getRoleName(appUserVo,appUser.getUserType());
|
|
|
- //设置属性
|
|
|
- appUserVo.setPhone(appUser.getPhone());
|
|
|
- appUserVo.setName(appUser.getName());
|
|
|
-
|
|
|
- return appUserVo;
|
|
|
- }
|
|
|
+ /**
|
|
|
+ * 删
|
|
|
+ */
|
|
|
+ void delete(Long id) {
|
|
|
+ removeById(id);
|
|
|
+ }
|
|
|
|
|
|
- /** 查询单个APP有效用户 */
|
|
|
- public AppUserDto getUserById(Long id){
|
|
|
- //查单个
|
|
|
- AppUser appUser = appUserMapper.selectById(id);
|
|
|
- if (appUser == null)return null;
|
|
|
- //判断有效性
|
|
|
- if(!appUser.getStatus().equals("0") && appUser.getDeleteStatus() != 0){
|
|
|
- AppUserDto appUserDto = new AppUserDto();
|
|
|
- BeanUtils.copyProperties(appUser,appUserDto);
|
|
|
- return appUserDto;
|
|
|
- }
|
|
|
- return null;
|
|
|
- }
|
|
|
+ /**
|
|
|
+ * 改
|
|
|
+ */
|
|
|
+ void update(AppUser a) {
|
|
|
+ a.setUpdateTime(new Date());
|
|
|
+ updateById(a);
|
|
|
|
|
|
- /** 查集合 - 根据条件(参数为空时代表忽略指定条件) */
|
|
|
- List<AppUser> getList(SoMap so) {
|
|
|
- return appUserMapper.getList(so);
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
- /** 启/停边民的app账号登陆限制 */
|
|
|
- int isLock(String id, Integer type, Integer status){
|
|
|
- //查询
|
|
|
- LambdaQueryWrapper<AppUser> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
- queryWrapper.eq(AppUser::getFkId,id);
|
|
|
- queryWrapper.eq(AppUser::getUserType,type);
|
|
|
- AppUser appUser1 = appUserMapper.selectList(queryWrapper).get(0);
|
|
|
- if(appUser1 == null)throw new RuntimeException("您进行修改的用户不存在!");
|
|
|
- //设置状态
|
|
|
- appUser1.setStatus(String.valueOf(status));
|
|
|
- //保存
|
|
|
- int i = appUserMapper.updateById(appUser1);
|
|
|
- return i;
|
|
|
- }
|
|
|
+ /**
|
|
|
+ * 查
|
|
|
+ */
|
|
|
+ AppUser getById(Long id) {
|
|
|
+ return super.getById(id);
|
|
|
+ }
|
|
|
|
|
|
- /** 注册 */
|
|
|
- boolean register(RegisterDto registerDto){
|
|
|
- if(registerDto == null)return false;
|
|
|
- //手机号去重
|
|
|
- String phone = registerDto.getPhone();
|
|
|
- if(appUserMapper.selectList(new LambdaQueryWrapper<AppUser>().eq(AppUser::getPhone,phone).eq(AppUser::getDeleteStatus,DeleteStatus.DELETE_STATUS_ON.getCode())).size() != 0)
|
|
|
- throw new RuntimeException("当前手机号已被注册!");
|
|
|
- //开始进行实际注册
|
|
|
- //1. 查询数据库内是否存在逻辑删除
|
|
|
- List<Long> collect = appUserMapper.selectList(new LambdaQueryWrapper<AppUser>().eq(AppUser::getPhone, phone).eq(AppUser::getDeleteStatus, DeleteStatus.DELETE_STATUS_OFF.getCode())).stream().map(AppUser::getId).collect(Collectors.toList());
|
|
|
- //删除旧数据
|
|
|
- if(collect.size() > 0)appUserMapper.deleteBatchIds(collect);
|
|
|
- //2.校验密码
|
|
|
- if(!registerDto.getPassword().equals(registerDto.getRePassword()))throw new RuntimeException("两次密码校验不通过!");
|
|
|
- //3.校验短信验证码
|
|
|
- String smsCode = RedisUtil.get(PREFIX + registerDto.getPhone());
|
|
|
- if(smsCode == null)throw new RuntimeException("验证码已过期,请重新发送!");
|
|
|
- //比对验证码
|
|
|
- if(!registerDto.getSmsCode().toString().equals(smsCode))throw new SecurityException("验证码输入错误,请检查!");
|
|
|
- //4.开始新增
|
|
|
- AppUser appUser = new AppUser();
|
|
|
- //手机号
|
|
|
- appUser.setPhone(phone);
|
|
|
- //注册身份
|
|
|
- appUser.setUserType(registerDto.getType());
|
|
|
- //加密并设置登陆密码
|
|
|
- String password = registerDto.getPassword();
|
|
|
- String encode = passwordEncoder.encode(password);
|
|
|
- appUser.setPassword(encode);
|
|
|
- //创建单位
|
|
|
- appUser.setCreateUnit("数据分中心");
|
|
|
- //昵称
|
|
|
- appUser.setName(registerDto.getNickName());
|
|
|
- //创建时间
|
|
|
- appUser.setCreateTime(new Date());
|
|
|
- //默认可用
|
|
|
- appUser.setStatus("1");
|
|
|
- appUser.setDeleteStatus(DeleteStatus.DELETE_STATUS_ON.getCode());
|
|
|
- //保存
|
|
|
- int insert = appUserMapper.insert(appUser);
|
|
|
- return insert == 1;
|
|
|
- }
|
|
|
+ /**
|
|
|
+ * 个人中心-个人详细信息
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ AppUserVo getSelfInfo() {
|
|
|
+ //查询当前人
|
|
|
+ AppUser appUser = appUserMapper.selectById(StpAPPUserUtil.getAPPLoginInfo().getLoginId());
|
|
|
+ if (appUser == null) throw new ServiceException("当前用户信息异常!");
|
|
|
+ //获取当前组
|
|
|
+ //创建返回值对象
|
|
|
+ AppUserVo appUserVo = new AppUserVo();
|
|
|
+ //根据身份获取不同名称
|
|
|
+ appUserVo.setFk(appUser.getFkId());
|
|
|
+ methodAppUserService.getRoleName(appUserVo, appUser.getUserType());
|
|
|
+ //设置属性
|
|
|
+ appUserVo.setPhone(appUser.getPhone());
|
|
|
+ appUserVo.setName(appUser.getName());
|
|
|
+
|
|
|
+ return appUserVo;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询单个APP有效用户
|
|
|
+ */
|
|
|
+ public AppUserDto getUserById(Long id) {
|
|
|
+ //查单个
|
|
|
+ AppUser appUser = appUserMapper.selectById(id);
|
|
|
+ if (appUser == null) return null;
|
|
|
+ //判断有效性
|
|
|
+ if (!appUser.getStatus().equals("0") && appUser.getDeleteStatus() != 0) {
|
|
|
+ AppUserDto appUserDto = new AppUserDto();
|
|
|
+ BeanUtils.copyProperties(appUser, appUserDto);
|
|
|
+ return appUserDto;
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查集合 - 根据条件(参数为空时代表忽略指定条件)
|
|
|
+ */
|
|
|
+ List<AppUser> getList(SoMap so) {
|
|
|
+ return appUserMapper.getList(so);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 启/停边民的app账号登陆限制
|
|
|
+ */
|
|
|
+ int isLock(String id, Integer type, Integer status) {
|
|
|
+ //查询
|
|
|
+ LambdaQueryWrapper<AppUser> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ queryWrapper.eq(AppUser::getFkId, id);
|
|
|
+ queryWrapper.eq(AppUser::getUserType, type);
|
|
|
+ AppUser appUser1 = appUserMapper.selectList(queryWrapper).get(0);
|
|
|
+ if (appUser1 == null) throw new RuntimeException("您进行修改的用户不存在!");
|
|
|
+ //设置状态
|
|
|
+ appUser1.setStatus(String.valueOf(status));
|
|
|
+ //保存
|
|
|
+ int i = appUserMapper.updateById(appUser1);
|
|
|
+ return i;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 注册
|
|
|
+ */
|
|
|
+ boolean register(RegisterDto registerDto) {
|
|
|
+ if (registerDto == null) return false;
|
|
|
+ //手机号去重
|
|
|
+ String phone = registerDto.getPhone();
|
|
|
+ if (appUserMapper.selectList(new LambdaQueryWrapper<AppUser>().eq(AppUser::getPhone, phone).eq(AppUser::getDeleteStatus, DeleteStatus.DELETE_STATUS_ON.getCode())).size() != 0)
|
|
|
+ throw new RuntimeException("当前手机号已被注册!");
|
|
|
+ //开始进行实际注册
|
|
|
+ //1. 查询数据库内是否存在逻辑删除
|
|
|
+ List<Long> collect = appUserMapper.selectList(new LambdaQueryWrapper<AppUser>().eq(AppUser::getPhone, phone).eq(AppUser::getDeleteStatus, DeleteStatus.DELETE_STATUS_OFF.getCode())).stream().map(AppUser::getId).collect(Collectors.toList());
|
|
|
+ //删除旧数据
|
|
|
+ if (collect.size() > 0) appUserMapper.deleteBatchIds(collect);
|
|
|
+ //2.校验密码
|
|
|
+ if (!registerDto.getPassword().equals(registerDto.getRePassword()))
|
|
|
+ throw new RuntimeException("两次密码校验不通过!");
|
|
|
+ //3.校验短信验证码
|
|
|
+ String smsCode = RedisUtil.get(PREFIX + registerDto.getPhone());
|
|
|
+ if (smsCode == null) throw new RuntimeException("验证码已过期,请重新发送!");
|
|
|
+ //比对验证码
|
|
|
+ if (!registerDto.getSmsCode().toString().equals(smsCode)) throw new SecurityException("验证码输入错误,请检查!");
|
|
|
+ //4.开始新增
|
|
|
+ AppUser appUser = new AppUser();
|
|
|
+ //手机号
|
|
|
+ appUser.setPhone(phone);
|
|
|
+ //注册身份
|
|
|
+ appUser.setUserType(registerDto.getType());
|
|
|
+ //加密并设置登陆密码
|
|
|
+ String password = registerDto.getPassword();
|
|
|
+ String encode = passwordEncoder.encode(password);
|
|
|
+ appUser.setPassword(encode);
|
|
|
+ //创建单位
|
|
|
+ appUser.setCreateUnit("数据分中心");
|
|
|
+ //昵称
|
|
|
+ appUser.setName(registerDto.getNickName());
|
|
|
+ //创建时间
|
|
|
+ appUser.setCreateTime(new Date());
|
|
|
+ //默认可用
|
|
|
+ appUser.setStatus("1");
|
|
|
+ appUser.setDeleteStatus(DeleteStatus.DELETE_STATUS_ON.getCode());
|
|
|
+ //保存
|
|
|
+ int insert = appUserMapper.insert(appUser);
|
|
|
+ return insert == 1;
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* 用户登录
|
|
@@ -230,13 +258,13 @@ public class AppUserService extends ServiceImpl<AppUserMapper, AppUser> implemen
|
|
|
//比对密码
|
|
|
String userPassword = appUser.getPassword();
|
|
|
boolean matches = passwordEncoder.matches(dto.getPassword(), userPassword);
|
|
|
- if (!matches){
|
|
|
+ if (!matches) {
|
|
|
loginLog.setStatus("1");
|
|
|
appUserLoginLogService.save(loginLog);
|
|
|
return AjaxJson.getError("密码校验错误,请检查!");
|
|
|
}
|
|
|
//判断是否停用
|
|
|
- if (appUser.getStatus().equals("0")){
|
|
|
+ if (appUser.getStatus().equals("0")) {
|
|
|
loginLog.setStatus(IsLock.IS_LOCK_OFF.getCode() + "");
|
|
|
appUserLoginLogService.save(loginLog);
|
|
|
return AjaxJson.getError("该账户 " + appUser.getPhone() + " 已停用!");
|
|
@@ -248,110 +276,112 @@ public class AppUserService extends ServiceImpl<AppUserMapper, AppUser> implemen
|
|
|
//保存
|
|
|
appUserMapper.updateById(appUser);
|
|
|
|
|
|
- //开始执行登录
|
|
|
- StpAPPUserUtil.login(appUser.getId());
|
|
|
- // 组织返回参数,直接拿过来用的,然后自己改吧改吧
|
|
|
- SoMap map = new SoMap();
|
|
|
- //敏感信息置空
|
|
|
- appUser.setPassword(null);
|
|
|
- //执行
|
|
|
- map.put("appUser", appUser);
|
|
|
- //获取当前用户角色权限字符
|
|
|
- List<ReRoleMenu> reRoleMenus = reRoleMenuMapper.selectList(new LambdaQueryWrapper<ReRoleMenu>().eq(ReRoleMenu::getAppRoleId, appUser.getUserType()));
|
|
|
- //使用stream流对其reRoleMenus集合的权限字符进行过滤顺便转成String类型
|
|
|
- List<String> per_list = reRoleMenus.stream().map(ReRoleMenu::getAppMenuId).collect(Collectors.toList()).stream().map(String::valueOf).collect(Collectors.toList());
|
|
|
+ //开始执行登录
|
|
|
+ StpAPPUserUtil.login(appUser.getId());
|
|
|
+ // 组织返回参数,直接拿过来用的,然后自己改吧改吧
|
|
|
+ SoMap map = new SoMap();
|
|
|
+ //敏感信息置空
|
|
|
+ appUser.setPassword(null);
|
|
|
+ //执行
|
|
|
+ map.put("appUser", appUser);
|
|
|
+ //获取当前用户角色权限字符
|
|
|
+ List<ReRoleMenu> reRoleMenus = reRoleMenuMapper.selectList(new LambdaQueryWrapper<ReRoleMenu>().eq(ReRoleMenu::getAppRoleId, appUser.getUserType()));
|
|
|
+ //使用stream流对其reRoleMenus集合的权限字符进行过滤顺便转成String类型
|
|
|
+ List<String> per_list = reRoleMenus.stream().map(ReRoleMenu::getAppMenuId).collect(Collectors.toList()).stream().map(String::valueOf).collect(Collectors.toList());
|
|
|
// if(reRoleMenus.size() == 0)return AjaxJson.getError("当前职务暂无权限!");
|
|
|
- //过滤出权限字符
|
|
|
- map.put("per_list", per_list);
|
|
|
- map.put("tokenInfo", StpAPPUserUtil.getTokenInfo());
|
|
|
+ //过滤出权限字符
|
|
|
+ map.put("per_list", per_list);
|
|
|
+ map.put("tokenInfo", StpAPPUserUtil.getTokenInfo());
|
|
|
// StpAPPUserUtil.cachePerList(per_list);
|
|
|
- APPLoginUserInfo info=new APPLoginUserInfo();
|
|
|
- //获取区域
|
|
|
- switch (appUser.getUserType()){
|
|
|
- case 1:
|
|
|
- PeopleDto rpcById = levelOneServerInterface.getRpcById(appUser.getFkId());
|
|
|
- if(rpcById != null) {
|
|
|
- info.setTradeAreaId(rpcById.getTradeAreaId());
|
|
|
- info.setTradeAreaName(rpcById.getTradeAreaName());
|
|
|
- }
|
|
|
- break;
|
|
|
- case 2:
|
|
|
- PeopleDto leader = levelOneServerInterface.getRpcById(appUser.getFkId());
|
|
|
- if(leader != null) {
|
|
|
- info.setTradeAreaId(leader.getTradeAreaId());
|
|
|
- info.setTradeAreaName(leader.getTradeAreaName());
|
|
|
- }
|
|
|
- break;
|
|
|
- case 3:
|
|
|
- System.out.println("收购商无互市区字段");
|
|
|
- break;
|
|
|
- case 4:
|
|
|
- DriverDto driver = transportInterface.getByDriverId(appUser.getFkId());
|
|
|
- if(driver != null) {
|
|
|
- info.setTradeAreaId(driver.getTradeAreaId());
|
|
|
- info.setTradeAreaName(driver.getTradeAreaName());
|
|
|
- }
|
|
|
- break;
|
|
|
- case 5:
|
|
|
- EnterpriseDto enterprise = levelOneServerInterface.getEnterpriseById(appUser.getFkId());
|
|
|
- if(enterprise != null) {
|
|
|
- info.setTradeAreaId(enterprise.getTradeAreaId());
|
|
|
- info.setTradeAreaName(enterprise.getTradeAreaName());
|
|
|
- }
|
|
|
- break;
|
|
|
- case 6:
|
|
|
- CooperativeDto cooperative = levelOneServerInterface.getCooperativeById(appUser.getFkId());
|
|
|
- if(cooperative != null) {
|
|
|
- info.setTradeAreaId(cooperative.getTradeAreaId());
|
|
|
- info.setTradeAreaName(cooperative.getTradeAreaName());
|
|
|
- }
|
|
|
- break;
|
|
|
- default:
|
|
|
- throw new SecurityException("身份信息有误");
|
|
|
- }
|
|
|
+ APPLoginUserInfo info = new APPLoginUserInfo();
|
|
|
+ //获取区域
|
|
|
+ switch (appUser.getUserType()) {
|
|
|
+ case 1:
|
|
|
+ PeopleDto rpcById = levelOneServerInterface.getRpcById(appUser.getFkId());
|
|
|
+ if (rpcById != null) {
|
|
|
+ info.setTradeAreaId(rpcById.getTradeAreaId());
|
|
|
+ info.setTradeAreaName(rpcById.getTradeAreaName());
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ PeopleDto leader = levelOneServerInterface.getRpcById(appUser.getFkId());
|
|
|
+ if (leader != null) {
|
|
|
+ info.setTradeAreaId(leader.getTradeAreaId());
|
|
|
+ info.setTradeAreaName(leader.getTradeAreaName());
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 3:
|
|
|
+ System.out.println("收购商无互市区字段");
|
|
|
+ break;
|
|
|
+ case 4:
|
|
|
+ DriverDto driver = transportInterface.getByDriverId(appUser.getFkId());
|
|
|
+ if (driver != null) {
|
|
|
+ info.setTradeAreaId(driver.getTradeAreaId());
|
|
|
+ info.setTradeAreaName(driver.getTradeAreaName());
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 5:
|
|
|
+ EnterpriseDto enterprise = levelOneServerInterface.getEnterpriseById(appUser.getFkId());
|
|
|
+ if (enterprise != null) {
|
|
|
+ info.setTradeAreaId(enterprise.getTradeAreaId());
|
|
|
+ info.setTradeAreaName(enterprise.getTradeAreaName());
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 6:
|
|
|
+ CooperativeDto cooperative = levelOneServerInterface.getCooperativeById(appUser.getFkId());
|
|
|
+ if (cooperative != null) {
|
|
|
+ info.setTradeAreaId(cooperative.getTradeAreaId());
|
|
|
+ info.setTradeAreaName(cooperative.getTradeAreaName());
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ throw new SecurityException("身份信息有误");
|
|
|
+ }
|
|
|
|
|
|
- info.setLoginId(appUser.getId());
|
|
|
- info.setLoginName(appUser.getName());
|
|
|
- info.setFk(appUser.getFkId());
|
|
|
- info.setUserType(appUser.getUserType());
|
|
|
- StpAPPUserUtil.cacheAPPLoginInfo(info);
|
|
|
- return AjaxJson.getSuccessData(map);
|
|
|
- }
|
|
|
+ info.setLoginId(appUser.getId());
|
|
|
+ info.setLoginName(appUser.getName());
|
|
|
+ info.setFk(appUser.getFkId());
|
|
|
+ info.setUserType(appUser.getUserType());
|
|
|
+ StpAPPUserUtil.cacheAPPLoginInfo(info);
|
|
|
+ return AjaxJson.getSuccessData(map);
|
|
|
+ }
|
|
|
|
|
|
|
|
|
- /** 忘记密码 */
|
|
|
- AjaxJson forgetPassword(ForgetPasswordDto forgetPasswordDto){
|
|
|
- //进行查询
|
|
|
- List<AppUser> appUserList = appUserMapper.selectList
|
|
|
- (new LambdaQueryWrapper<AppUser>().eq(AppUser::getPhone, forgetPasswordDto.getPhone())
|
|
|
- .eq(AppUser::getDeleteStatus, DeleteStatus.DELETE_STATUS_ON.getCode())
|
|
|
- .eq(AppUser::getStatus, IsLock.IS_LOCK_ON.getCode()));
|
|
|
- //判断其手机号码可能存在的异常情况
|
|
|
- if(appUserList.size() > 1)
|
|
|
- return AjaxJson.getError("当前账户存在异常,请联系客服进行处理!");
|
|
|
- if(appUserList.size() == 0)throw new RuntimeException("您当前手机号尚未进行注册!");
|
|
|
- //获取当前手机号对象
|
|
|
- AppUser appUser = appUserList.get(0);
|
|
|
- //从缓存中获取验证码
|
|
|
- String smsCode = RedisUtil.get(PREFIX + forgetPasswordDto.getPhone());
|
|
|
- if(smsCode == null)return AjaxJson.getError("验证码已过期!");
|
|
|
- //比对用户输入的验证码
|
|
|
- boolean result = smsCode.equals(forgetPasswordDto.getSmsCode());
|
|
|
- //进行验证码校验完成后的流程
|
|
|
- if(result){
|
|
|
- //密码校验
|
|
|
- boolean equals = forgetPasswordDto.getPassword().equals(forgetPasswordDto.getRePassword());
|
|
|
- //验证码匹配成功,执行修改密码逻辑
|
|
|
- //1.判断其密码验证
|
|
|
- if(equals){
|
|
|
- //1.1 密码校验正确,设置新密码
|
|
|
- String encode = passwordEncoder.encode(forgetPasswordDto.getRePassword());
|
|
|
- appUser.setPassword(encode);
|
|
|
- //1.2 执行保存
|
|
|
- int i = appUserMapper.updateById(appUser);
|
|
|
- if(i != 1)return AjaxJson.getError("密码重置失败!");
|
|
|
- return AjaxJson.getSuccess("密码找回成功!");
|
|
|
- }else {
|
|
|
+ /**
|
|
|
+ * 忘记密码
|
|
|
+ */
|
|
|
+ AjaxJson forgetPassword(ForgetPasswordDto forgetPasswordDto) {
|
|
|
+ //进行查询
|
|
|
+ List<AppUser> appUserList = appUserMapper.selectList
|
|
|
+ (new LambdaQueryWrapper<AppUser>().eq(AppUser::getPhone, forgetPasswordDto.getPhone())
|
|
|
+ .eq(AppUser::getDeleteStatus, DeleteStatus.DELETE_STATUS_ON.getCode())
|
|
|
+ .eq(AppUser::getStatus, IsLock.IS_LOCK_ON.getCode()));
|
|
|
+ //判断其手机号码可能存在的异常情况
|
|
|
+ if (appUserList.size() > 1)
|
|
|
+ return AjaxJson.getError("当前账户存在异常,请联系客服进行处理!");
|
|
|
+ if (appUserList.size() == 0) throw new RuntimeException("您当前手机号尚未进行注册!");
|
|
|
+ //获取当前手机号对象
|
|
|
+ AppUser appUser = appUserList.get(0);
|
|
|
+ //从缓存中获取验证码
|
|
|
+ String smsCode = RedisUtil.get(PREFIX + forgetPasswordDto.getPhone());
|
|
|
+ if (smsCode == null) return AjaxJson.getError("验证码已过期!");
|
|
|
+ //比对用户输入的验证码
|
|
|
+ boolean result = smsCode.equals(forgetPasswordDto.getSmsCode());
|
|
|
+ //进行验证码校验完成后的流程
|
|
|
+ if (result) {
|
|
|
+ //密码校验
|
|
|
+ boolean equals = forgetPasswordDto.getPassword().equals(forgetPasswordDto.getRePassword());
|
|
|
+ //验证码匹配成功,执行修改密码逻辑
|
|
|
+ //1.判断其密码验证
|
|
|
+ if (equals) {
|
|
|
+ //1.1 密码校验正确,设置新密码
|
|
|
+ String encode = passwordEncoder.encode(forgetPasswordDto.getRePassword());
|
|
|
+ appUser.setPassword(encode);
|
|
|
+ //1.2 执行保存
|
|
|
+ int i = appUserMapper.updateById(appUser);
|
|
|
+ if (i != 1) return AjaxJson.getError("密码重置失败!");
|
|
|
+ return AjaxJson.getSuccess("密码找回成功!");
|
|
|
+ } else {
|
|
|
|
|
|
return AjaxJson.getError("两次密码校验不匹配,请重新尝试!");
|
|
|
|
|
@@ -363,93 +393,103 @@ public class AppUserService extends ServiceImpl<AppUserMapper, AppUser> implemen
|
|
|
return AjaxJson.getError("验证码输入错误,请检查!");
|
|
|
}
|
|
|
|
|
|
- /** 获取验证码 */
|
|
|
- boolean getPhoneSmsCode(String phone) throws Exception {
|
|
|
- //生成4位随机数
|
|
|
- Random random = new Random();
|
|
|
- int randomNumber = random.nextInt(9000) + 1000;
|
|
|
- //保存到缓存,默认1分钟 todo:届时放开手机验证码 randomNumber
|
|
|
- RedisUtil.setByMINUTES(PREFIX + phone,123 + "", 1);
|
|
|
- //发送验证码短信
|
|
|
- return true;
|
|
|
+ /**
|
|
|
+ * 获取验证码
|
|
|
+ */
|
|
|
+ boolean getPhoneSmsCode(String phone) throws Exception {
|
|
|
+ //生成4位随机数
|
|
|
+ Random random = new Random();
|
|
|
+ int randomNumber = random.nextInt(9000) + 1000;
|
|
|
+ //保存到缓存,默认1分钟 todo:届时放开手机验证码 randomNumber
|
|
|
+ RedisUtil.setByMINUTES(PREFIX + phone, 123 + "", 1);
|
|
|
+ //发送验证码短信
|
|
|
+ return true;
|
|
|
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
|
|
|
- /** 更换角色 */
|
|
|
- AjaxJson updateRole(String appRoleId){
|
|
|
- // 获取当前用户角色权限字符
|
|
|
- List<ReRoleMenu> reRoleMenus = reRoleMenuMapper.selectList(new LambdaQueryWrapper<ReRoleMenu>().eq(ReRoleMenu::getAppRoleId, appRoleId));
|
|
|
- // 使用stream流对其reRoleMenus集合的权限字符进行过滤顺便转成String类型
|
|
|
- List<String> per_list = reRoleMenus.stream().map(ReRoleMenu::getAppMenuId).collect(Collectors.toList()).stream().map(String::valueOf).collect(Collectors.toList());
|
|
|
- if(reRoleMenus.size() == 0)return AjaxJson.getError("当前用户角色暂无权限!");
|
|
|
+ /**
|
|
|
+ * 更换角色
|
|
|
+ */
|
|
|
+ AjaxJson updateRole(String appRoleId) {
|
|
|
+ // 获取当前用户角色权限字符
|
|
|
+ List<ReRoleMenu> reRoleMenus = reRoleMenuMapper.selectList(new LambdaQueryWrapper<ReRoleMenu>().eq(ReRoleMenu::getAppRoleId, appRoleId));
|
|
|
+ // 使用stream流对其reRoleMenus集合的权限字符进行过滤顺便转成String类型
|
|
|
+ List<String> per_list = reRoleMenus.stream().map(ReRoleMenu::getAppMenuId).collect(Collectors.toList()).stream().map(String::valueOf).collect(Collectors.toList());
|
|
|
+ if (reRoleMenus.size() == 0) return AjaxJson.getError("当前用户角色暂无权限!");
|
|
|
|
|
|
- SoMap map = new SoMap();
|
|
|
- map.put("per_list", per_list);
|
|
|
- StpUserUtil.cachePerList(per_list);
|
|
|
+ SoMap map = new SoMap();
|
|
|
+ map.put("per_list", per_list);
|
|
|
+ StpUserUtil.cachePerList(per_list);
|
|
|
|
|
|
- return AjaxJson.getSuccessData(map);
|
|
|
- }
|
|
|
+ return AjaxJson.getSuccessData(map);
|
|
|
+ }
|
|
|
|
|
|
- /**
|
|
|
- * 退出登录
|
|
|
- * @param appUserId appUser表主键
|
|
|
- * @return
|
|
|
- */
|
|
|
- public String logout(Object appUserId){
|
|
|
- if(appUserId == null || appUserId.toString().trim().equals(""))
|
|
|
- throw new ServiceException("退出信息异常!");
|
|
|
- StpAPPUserUtil.logout(appUserId);
|
|
|
- return "退出登录成功!";
|
|
|
- }
|
|
|
+ /**
|
|
|
+ * 退出登录
|
|
|
+ *
|
|
|
+ * @param appUserId appUser表主键
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public String logout(Object appUserId) {
|
|
|
+ if (appUserId == null || appUserId.toString().trim().equals(""))
|
|
|
+ throw new ServiceException("退出信息异常!");
|
|
|
+ StpAPPUserUtil.logout(appUserId);
|
|
|
+ return "退出登录成功!";
|
|
|
+ }
|
|
|
|
|
|
- /**
|
|
|
- * 修改密码
|
|
|
- * @param oldPassword 旧密码
|
|
|
- * @param newPassword 新密码
|
|
|
- * @param rePassword 确认密码
|
|
|
- * @return
|
|
|
- */
|
|
|
- public boolean modifyPassword(String oldPassword,String newPassword,String rePassword){
|
|
|
- //对比新密码和确认密码
|
|
|
- if(!newPassword.equals(rePassword))throw new ServiceException("新密码和确认密码不一致!");
|
|
|
-
|
|
|
- //获取user
|
|
|
- APPLoginUserInfo appLoginInfo = StpAPPUserUtil.getAPPLoginInfo();
|
|
|
- AppUser appUser = appUserMapper.selectById(appLoginInfo.getLoginId());
|
|
|
- if(appUser == null)throw new SecurityException("当前账户信息异常!");
|
|
|
- //旧密码比对
|
|
|
- boolean result = passwordEncoder.matches(oldPassword,appUser.getPassword());
|
|
|
- if(!result)throw new SecurityException("旧密码输入错误!");
|
|
|
- //新密码进行编码
|
|
|
- String password = passwordEncoder.encode(newPassword);
|
|
|
- //执行修改
|
|
|
- appUser.setPassword(password);
|
|
|
- //设置基本属性
|
|
|
- appUser.setUpdateTime(new Date());
|
|
|
- //保存
|
|
|
- return 1 == appUserMapper.updateById(appUser);
|
|
|
- }
|
|
|
+ /**
|
|
|
+ * 修改密码
|
|
|
+ *
|
|
|
+ * @param oldPassword 旧密码
|
|
|
+ * @param newPassword 新密码
|
|
|
+ * @param rePassword 确认密码
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public boolean modifyPassword(String oldPassword, String newPassword, String rePassword) {
|
|
|
+ //对比新密码和确认密码
|
|
|
+ if (!newPassword.equals(rePassword)) throw new ServiceException("新密码和确认密码不一致!");
|
|
|
+
|
|
|
+ //获取user
|
|
|
+ APPLoginUserInfo appLoginInfo = StpAPPUserUtil.getAPPLoginInfo();
|
|
|
+ AppUser appUser = appUserMapper.selectById(appLoginInfo.getLoginId());
|
|
|
+ if (appUser == null) throw new SecurityException("当前账户信息异常!");
|
|
|
+ //旧密码比对
|
|
|
+ boolean result = passwordEncoder.matches(oldPassword, appUser.getPassword());
|
|
|
+ if (!result) throw new SecurityException("旧密码输入错误!");
|
|
|
+ //新密码进行编码
|
|
|
+ String password = passwordEncoder.encode(newPassword);
|
|
|
+ //执行修改
|
|
|
+ appUser.setPassword(password);
|
|
|
+ //设置基本属性
|
|
|
+ appUser.setUpdateTime(new Date());
|
|
|
+ //保存
|
|
|
+ return 1 == appUserMapper.updateById(appUser);
|
|
|
+ }
|
|
|
|
|
|
- /** 远程调用: 收购商认证 */
|
|
|
- public AppUserDto getByPhoneAndUserType(String phone,Integer userType){
|
|
|
- List<AppUser> appUsers = appUserMapper.selectList(new LambdaQueryWrapper<AppUser>().eq(AppUser::getPhone, phone).eq(AppUser::getUserType, userType).eq(AppUser::getDeleteStatus, DeleteStatus.DELETE_STATUS_ON.getCode()).eq(AppUser::getStatus, 1));
|
|
|
- if(appUsers.size() != 1)throw new ServiceException("用户信息有误。");
|
|
|
- AppUserDto appUserDto = new AppUserDto();
|
|
|
- BeanUtils.copyProperties(appUsers.get(0),appUserDto);
|
|
|
- return appUserDto;
|
|
|
- }
|
|
|
+ /**
|
|
|
+ * 远程调用: 收购商认证
|
|
|
+ */
|
|
|
+ public AppUserDto getByPhoneAndUserType(String phone, Integer userType) {
|
|
|
+ List<AppUser> appUsers = appUserMapper.selectList(new LambdaQueryWrapper<AppUser>().eq(AppUser::getPhone, phone).eq(AppUser::getUserType, userType).eq(AppUser::getDeleteStatus, DeleteStatus.DELETE_STATUS_ON.getCode()).eq(AppUser::getStatus, 1));
|
|
|
+ if (appUsers.size() != 1) throw new ServiceException("用户信息有误。");
|
|
|
+ AppUserDto appUserDto = new AppUserDto();
|
|
|
+ BeanUtils.copyProperties(appUsers.get(0), appUserDto);
|
|
|
+ return appUserDto;
|
|
|
+ }
|
|
|
|
|
|
- /** 远程调用: 保存appUser信息 */
|
|
|
- public boolean saveAppUserInfo(AppUserDto appUser){
|
|
|
- AppUser user = new AppUser();
|
|
|
- BeanUtils.copyProperties(appUser,user);
|
|
|
- int update = appUserMapper.updateById(user);
|
|
|
- return update == 1;
|
|
|
- }
|
|
|
+ /**
|
|
|
+ * 远程调用: 保存appUser信息
|
|
|
+ */
|
|
|
+ public boolean saveAppUserInfo(AppUserDto appUser) {
|
|
|
+ AppUser user = new AppUser();
|
|
|
+ BeanUtils.copyProperties(appUser, user);
|
|
|
+ int update = appUserMapper.updateById(user);
|
|
|
+ return update == 1;
|
|
|
+ }
|
|
|
|
|
|
/** 远程调用: 当从航通导入数据时,自动给边民生成账号 */
|
|
|
- public boolean generatePeopleAccount(HtPeopleDto peopleDto) throws Exception {
|
|
|
+ public boolean generatePeopleAccount(PeopleDto peopleDto) throws Exception {
|
|
|
//检查是否重复注册
|
|
|
List<AppUser> appUsers = appUserMapper.selectList(new LambdaQueryWrapper<AppUser>().eq(AppUser::getPhone, peopleDto.getBorderTel()));
|
|
|
if(appUsers.size() != 0)throw new ServiceException("\n该用户已注册! phone = " + peopleDto.getBorderTel() + "\n");
|
|
@@ -479,53 +519,60 @@ public class AppUserService extends ServiceImpl<AppUserMapper, AppUser> implemen
|
|
|
//todo: 届时放开注释
|
|
|
// boolean msg = smsRetryService.sendSmsRegisteMsg(null, "您好,您已成功注册[边民互市]app账号。账号:" + peopleDto.getBorderTel() + ", 初始密码:" + password + "。可前往app进行修改");
|
|
|
// return msg;
|
|
|
- System.out.println("注册成功! 账户 = " + peopleDto.getBorderTel() + " password = " + password);
|
|
|
- return true;
|
|
|
- }
|
|
|
- throw new RuntimeException("同步航通信息时,边民注册app信息失败,边民手机号为: " + peopleDto.getBorderTel() + "。 时间: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
|
|
|
- }
|
|
|
+ System.out.println("注册成功! 账户 = " + peopleDto.getBorderTel() + " password = " + password);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ throw new RuntimeException("同步航通信息时,边民注册app信息失败,边民手机号为: " + peopleDto.getBorderTel() + "。 时间: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
|
|
|
+ }
|
|
|
|
|
|
- /** 远程调用: 当从航通导入数据时,自动给外籍商户生成账号 */
|
|
|
- public int generateEnterpriseAccount(EnterpriseDto enterpriseDto) throws Exception {
|
|
|
- //判断是否已被注册
|
|
|
- List<AppUser> appUsers = appUserMapper.selectList(new LambdaQueryWrapper<AppUser>().eq(AppUser::getPhone, enterpriseDto.getOwnerTel()));
|
|
|
- if(appUsers.size() != 0)throw new ServiceException("\n该用户已注册! phone = " + enterpriseDto.getOwnerTel() + "\n");
|
|
|
- //创建保存对象
|
|
|
- AppUser appUser = new AppUser();
|
|
|
- //设置基本属性
|
|
|
- appUser.setAuth(1 + ""); // 默认已认证
|
|
|
- appUser.setUserType(5); // 用户类型 1
|
|
|
- appUser.setCreateTime(new Date()); // 创建时间
|
|
|
- appUser.setPhone(enterpriseDto.getOwnerTel()); // 电话
|
|
|
- appUser.setStatus(Status.STATUS_ONE.getCode() + ""); // 可用状态
|
|
|
- appUser.setDeleteStatus(DeleteStatus.DELETE_STATUS_ON.getCode()); // 默认可用
|
|
|
- appUser.setAuthTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); // 认证时间
|
|
|
- appUser.setName(enterpriseDto.getOwnerName()); // 昵称
|
|
|
- appUser.setFkId(enterpriseDto.getId()); // 外键
|
|
|
- appUser.setCreateUnit("航通"); // 创建单位
|
|
|
- //随机生成6位数密码
|
|
|
- int password = (int) (Math.random() * (999999 - 100000 + 1) + 100000);
|
|
|
- //密码加密
|
|
|
- String encodePassword = passwordEncoder.encode(password + "");
|
|
|
- //设置密码
|
|
|
- appUser.setPassword(encodePassword);
|
|
|
- //保存
|
|
|
- int insert = appUserMapper.insert(appUser);
|
|
|
- //发送短信
|
|
|
- if(insert == 1){
|
|
|
- //查询外籍商户和商铺是否存在,不存在则删除app user信息 ownTel
|
|
|
+ /**
|
|
|
+ * 远程调用: 当从航通导入数据时,自动给外籍商户生成账号
|
|
|
+ */
|
|
|
+ public int generateEnterpriseAccount(EnterpriseDto enterpriseDto) throws Exception {
|
|
|
+ //判断是否已被注册
|
|
|
+ List<AppUser> appUsers = appUserMapper.selectList(new LambdaQueryWrapper<AppUser>().eq(AppUser::getPhone, enterpriseDto.getOwnerTel()));
|
|
|
+ if (appUsers.size() != 0) {
|
|
|
+ StaticLog.error("用户手机号已被注册:{},{}", enterpriseDto.getOwnerTel(), JSONUtil.toJsonStr(enterpriseDto));
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ //创建保存对象
|
|
|
+ AppUser appUser = new AppUser();
|
|
|
+ //设置基本属性
|
|
|
+ appUser.setAuth(1 + ""); // 默认已认证
|
|
|
+ appUser.setUserType(5); // 用户类型 1
|
|
|
+ appUser.setCreateTime(new Date()); // 创建时间
|
|
|
+ appUser.setPhone(enterpriseDto.getOwnerTel()); // 电话
|
|
|
+ appUser.setStatus(Status.STATUS_ONE.getCode() + ""); // 可用状态
|
|
|
+ appUser.setDeleteStatus(DeleteStatus.DELETE_STATUS_ON.getCode()); // 默认可用
|
|
|
+ appUser.setAuthTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); // 认证时间
|
|
|
+ appUser.setName(enterpriseDto.getOwnerName()); // 昵称
|
|
|
+ appUser.setFkId(enterpriseDto.getId()); // 外键
|
|
|
+ appUser.setCreateUnit("航通"); // 创建单位
|
|
|
+ //随机生成6位数密码
|
|
|
+ //int password = (int) (Math.random() * (999999 - 100000 + 1) + 100000);
|
|
|
+ String password = appUser.getPhone();
|
|
|
+ //密码加密
|
|
|
+ String encodePassword = passwordEncoder.encode(password + "");
|
|
|
+ //设置密码
|
|
|
+ appUser.setPassword(encodePassword);
|
|
|
+ //保存
|
|
|
+ int insert = appUserMapper.insert(appUser);
|
|
|
+ //发送短信
|
|
|
+ if (insert == 1) {
|
|
|
+ //查询外籍商户和商铺是否存在,不存在则删除app user信息 ownTel
|
|
|
// List<ShopDto> shopDtoListByPhone = levelOneServerInterface.getShopDtoListByPhone(appUser.getPhone());
|
|
|
// List<EnterpriseDto> enterpriseDtoListByPhone = levelOneServerInterface.getEnterpriseDtoListByPhone(appUser.getPhone());
|
|
|
// if(shopDtoListByPhone.size() != 1 && enterpriseDtoListByPhone.size() != 1)
|
|
|
// throw new ServiceException("当航通同步商铺信息时,商铺或者外籍商户信息入库发生异常,故在自动创建appUser时抛出异常回滚数据。");
|
|
|
- //todo: 届时放开注释
|
|
|
+ //todo: 届时放开注释
|
|
|
// boolean msg = smsRetryService.sendSmsRegisteMsg(null, "您好,您已成功注册[边民互市]app账号。账号:" + peopleDto.getBorderTel() + ", 初始密码:" + password + "。可前往app进行修改");
|
|
|
// return msg;
|
|
|
- System.out.println("\n注册成功! 账户 = " + enterpriseDto.getOwnerTel() + " password = " + password + "\n");
|
|
|
- return 1;
|
|
|
- }
|
|
|
- throw new RuntimeException("同步航通信息时,边民注册app信息失败,边民手机号为: " + enterpriseDto.getOwnerTel() + "。 时间: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
|
|
|
- }
|
|
|
+ System.out.println("\n注册成功! 账户 = " + enterpriseDto.getOwnerTel() + " password = " + password + "\n");
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ StaticLog.error("同步航通信息时,边民注册app信息失败,边民手机号为: " + enterpriseDto.getOwnerTel() + "。 时间: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
|
|
|
|
|
|
}
|