1个文件已删除
12个文件已添加
30个文件已修改
| New file |
| | |
| | | package com.ruoyi.web.controller.api; |
| | | |
| | | |
| | | import com.ruoyi.common.core.controller.BaseController; |
| | | import com.ruoyi.common.core.domain.AjaxResult; |
| | | import com.ruoyi.system.dto.CardVerifyRequest; |
| | | import com.ruoyi.system.service.EmployeeVerifyService; |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import org.springframework.web.bind.annotation.PostMapping; |
| | | import org.springframework.web.bind.annotation.RequestBody; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import javax.annotation.Resource; |
| | | import javax.validation.Valid; |
| | | |
| | | /** |
| | | * 接待人(被访者)刷卡验证接口。 |
| | | * 数据源:t_employee 员工管理表(含内部员工及已授权的外部人员)。 |
| | | */ |
| | | @Api(tags = "接待人验证接口") |
| | | @RestController |
| | | @RequestMapping("/api/employee/verify") |
| | | public class EmployeeVerifyController extends BaseController { |
| | | |
| | | @Resource |
| | | private EmployeeVerifyService employeeVerifyService; |
| | | |
| | | /** |
| | | * 刷卡验证:现场读卡器读取卡号后调用本接口,与接待人绑定的卡号比对。 |
| | | */ |
| | | @PostMapping("/card") |
| | | @ApiOperation(value = "接待人刷卡验证", notes = "根据传入的卡号与接待人(employeeId)绑定的卡号进行比对," |
| | | + "仅对启用且未删除的接待人生效") |
| | | public AjaxResult verifyByCard(@RequestBody @Valid CardVerifyRequest request) { |
| | | return employeeVerifyService.verifyByCard(request); |
| | | } |
| | | } |
| New file |
| | |
| | | package com.ruoyi.web.controller.api; |
| | | |
| | | import com.ruoyi.common.annotation.Log; |
| | | import com.ruoyi.common.core.controller.BaseController; |
| | | import com.ruoyi.common.core.domain.AjaxResult; |
| | | import com.ruoyi.common.enums.BusinessType; |
| | | import com.ruoyi.system.dto.*; |
| | | import com.ruoyi.system.service.ISysVisitorMachineService; |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.PostMapping; |
| | | import org.springframework.web.bind.annotation.RequestBody; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import javax.validation.Valid; |
| | | |
| | | /** |
| | | * 访客机设备激活/注销 |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/api/visitmachine") |
| | | @Api(tags = "访客机设备激活、注销" , value = "访客机设备激活、注销") |
| | | public class SysApiDoorMachineController extends BaseController |
| | | { |
| | | @Autowired |
| | | private ISysVisitorMachineService visitorMachineService; |
| | | |
| | | /** |
| | | * 激活设备 |
| | | */ |
| | | @Log(title = "访客机设备", businessType = BusinessType.UPDATE) |
| | | @PostMapping("/activate") |
| | | @ApiOperation(value = "激活访客机设备") |
| | | public AjaxResult activate(@Valid @RequestBody SysVisitorMachineDetailRequest request) { |
| | | int result = visitorMachineService.activateDevice(request.getMachineId()); |
| | | return result > 0 ? success("设备激活成功") : error("设备激活失败"); |
| | | } |
| | | |
| | | /** |
| | | * 注销设备 |
| | | */ |
| | | @Log(title = "访客机设备", businessType = BusinessType.UPDATE) |
| | | @PostMapping("/deactivate") |
| | | @ApiOperation(value = "注销访客机设备") |
| | | public AjaxResult deactivate(@Valid @RequestBody SysVisitorMachineDetailRequest request) { |
| | | int result = visitorMachineService.deactivateDevice(request.getMachineId()); |
| | | return result > 0 ? success("设备注销成功") : error("设备注销失败"); |
| | | } |
| | | |
| | | } |
| New file |
| | |
| | | package com.ruoyi.web.controller.api; |
| | | |
| | | import com.ruoyi.common.annotation.Log; |
| | | import com.ruoyi.common.core.controller.BaseController; |
| | | import com.ruoyi.common.core.domain.AjaxResult; |
| | | import com.ruoyi.common.enums.BusinessType; |
| | | import com.ruoyi.system.dto.*; |
| | | import com.ruoyi.system.service.ISysVisitAreaService; |
| | | import com.ruoyi.system.vo.SysVisitAreaVO; |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import io.swagger.annotations.ApiResponse; |
| | | import io.swagger.annotations.ApiResponses; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.PostMapping; |
| | | import org.springframework.web.bind.annotation.RequestBody; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 访问区域管理接口 |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/api/visitArea") |
| | | @Api(tags = "访问区域管理") |
| | | public class SysApiVisitAreaController extends BaseController |
| | | { |
| | | @Autowired |
| | | private ISysVisitAreaService visitAreaService; |
| | | |
| | | /** |
| | | * 查询访问区域树 |
| | | */ |
| | | @ApiOperation( |
| | | value = "查询访问区域树", |
| | | notes = "返回所有访问区域树形结构", |
| | | response = SysVisitAreaVO.class, |
| | | responseContainer = "List" |
| | | ) |
| | | @ApiResponses({ |
| | | @ApiResponse( |
| | | code = 200, |
| | | message = "成功", |
| | | response = AjaxResult.class, |
| | | responseContainer = "List" |
| | | ) |
| | | }) |
| | | @PostMapping("/tree") |
| | | public AjaxResult<List<SysVisitAreaVO>> tree() { |
| | | return success(visitAreaService.tree(null)); |
| | | } |
| | | } |
| New file |
| | |
| | | package com.ruoyi.web.controller.api; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.ruoyi.common.core.controller.BaseController; |
| | | import com.ruoyi.common.core.domain.AjaxResult; |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import com.ruoyi.common.utils.bean.BeanUtils; |
| | | import com.ruoyi.system.domain.SysVisitorRecord; |
| | | import com.ruoyi.system.dto.SysVisitorRecordAddRequest; |
| | | import com.ruoyi.system.dto.SysVisitorRecordPageRequest; |
| | | import com.ruoyi.system.mapper.SysVisitorRecordMapper; |
| | | import com.ruoyi.system.service.ISysVisitorRecordService; |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import io.swagger.annotations.ApiParam; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.web.bind.annotation.PostMapping; |
| | | import org.springframework.web.bind.annotation.RequestBody; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import java.util.Date; |
| | | |
| | | @RestController |
| | | @RequestMapping("/api/visitorRecord") |
| | | @Api(tags = "访客登记") |
| | | public class SysApiVisitorRecordController extends BaseController { |
| | | |
| | | @Autowired |
| | | private SysVisitorRecordMapper visitorRecordMapper; |
| | | |
| | | @PostMapping("/add") |
| | | @ApiOperation(value = "访客登记", notes = "现场访客登记") |
| | | public AjaxResult add( |
| | | @RequestBody |
| | | @ApiParam(value = "访客登记信息", required = true) |
| | | SysVisitorRecordAddRequest request) { |
| | | |
| | | // ================= 参数校验 ================= |
| | | if (StringUtils.isBlank(request.getVisitorName())) { |
| | | return AjaxResult.error("访客姓名不能为空"); |
| | | } |
| | | |
| | | if (StringUtils.isBlank(request.getIntervieweeName())) { |
| | | return AjaxResult.error("被访人不能为空"); |
| | | } |
| | | |
| | | if (StringUtils.isNotBlank(request.getIdCard())) { |
| | | |
| | | LambdaQueryWrapper<SysVisitorRecord> wrapper = Wrappers.lambdaQuery(); |
| | | |
| | | wrapper.eq(SysVisitorRecord::getIdCard, request.getIdCard()) |
| | | .eq(SysVisitorRecord::getDelFlag, "0") |
| | | .in(SysVisitorRecord::getStatus, |
| | | "VISITING", |
| | | "PENDING_CONFIRM") |
| | | .last("limit 1"); |
| | | |
| | | SysVisitorRecord oldRecord = visitorRecordMapper.selectOne(wrapper); |
| | | |
| | | if (oldRecord != null) { |
| | | return AjaxResult.error("该访客当前已有未结束的登记,请勿重复登记"); |
| | | } |
| | | } |
| | | |
| | | // ================= 保存 ================= |
| | | SysVisitorRecord record = new SysVisitorRecord(); |
| | | BeanUtils.copyProperties(request, record); |
| | | |
| | | record.setRegisterNo(generateRegisterNo()); |
| | | record.setRegisterType("ONSITE"); |
| | | record.setRegisterSource("访客机"); |
| | | record.setStatus("VISITING"); |
| | | record.setRegisterTime(new Date()); |
| | | record.setDelFlag("0"); |
| | | |
| | | int rows = visitorRecordMapper.insert(record); |
| | | |
| | | if (rows > 0) { |
| | | return AjaxResult.success(record.getRegisterNo()); |
| | | } |
| | | |
| | | return AjaxResult.error("登记失败"); |
| | | } |
| | | |
| | | /** |
| | | * 生成登记编号 |
| | | * 格式: |
| | | * VIS + 年月日 + 6位随机数 |
| | | * 例如: |
| | | * VIS20260707123456 |
| | | */ |
| | | private String generateRegisterNo() { |
| | | |
| | | String date = |
| | | new java.text.SimpleDateFormat("yyyyMMddHHmmss") |
| | | .format(new Date()); |
| | | |
| | | String random = |
| | | String.valueOf((int)((Math.random() * 900000) + 100000)); |
| | | |
| | | return "VIS" + date + random; |
| | | } |
| | | } |
| | |
| | | import com.ruoyi.common.enums.BusinessType; |
| | | import com.ruoyi.system.dto.SysVisitorConfigSaveRequest; |
| | | import com.ruoyi.system.service.ISysVisitorConfigService; |
| | | import com.ruoyi.system.vo.SysVisitorConfigVO; |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import io.swagger.annotations.ApiResponse; |
| | | import io.swagger.annotations.ApiResponses; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.web.bind.annotation.PostMapping; |
| | |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/system/visitor/config") |
| | | @Api(tags = "访客系统配置接口") |
| | | public class SysVisitorConfigController extends BaseController |
| | | { |
| | | @Autowired |
| | |
| | | @Log(title = "访客系统配置", businessType = BusinessType.SELECT) |
| | | @PreAuthorize("@ss.hasPermi('visitor:config:view')") |
| | | @PostMapping("/detail") |
| | | public AjaxResult detail() |
| | | @ApiOperation(value = "查询访客系统配置") |
| | | @ApiResponses({ |
| | | @ApiResponse( |
| | | code = 200, message = "查询成功", response = SysVisitorConfigVO.class, responseContainer = "Data" // 指定数据在 data 字段中 |
| | | ) |
| | | }) |
| | | public AjaxResult<SysVisitorConfigVO> detail() |
| | | { |
| | | return success(visitorConfigService.selectConfig()); |
| | | return AjaxResult.success(visitorConfigService.selectConfig()); |
| | | } |
| | | |
| | | /** |
| | |
| | | @Log(title = "访客系统配置", businessType = BusinessType.UPDATE) |
| | | @PreAuthorize("@ss.hasPermi('visitor:config:edit')") |
| | | @PostMapping("/save") |
| | | @ApiOperation( |
| | | value = "设置访客系统配置", |
| | | response = AjaxResult.class |
| | | ) |
| | | public AjaxResult save(@RequestBody SysVisitorConfigSaveRequest request) |
| | | { |
| | | return success(visitorConfigService.saveConfig(request, getUsername())); |
| | | visitorConfigService.saveConfig(request, getUsername()); |
| | | return success(); |
| | | } |
| | | } |
| | |
| | | import java.util.List; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/common") |
| | | @Api(tags = "图片上传接口") |
| | | public class CommonController |
| | | { |
| | | private static final Logger log = LoggerFactory.getLogger(CommonController.class); |
| | |
| | | * 通用上传请求(单个) |
| | | */ |
| | | @PostMapping("/upload") |
| | | @ApiOperation(value = "上传图片 MultipartFile file") |
| | | public AjaxResult uploadFile(MultipartFile file) throws Exception |
| | | { |
| | | try |
| | |
| | | import com.ruoyi.common.basic.PageInfo; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.core.domain.entity.SysMenu; |
| | | import com.ruoyi.system.dto.SysRoleDTO; |
| | | import com.ruoyi.system.query.SysRoleQuery; |
| | | import com.ruoyi.system.service.ISysMenuService; |
| | | import com.ruoyi.system.vo.RoleInfoVO; |
| | |
| | | public AjaxResult roleInfoFromUserId(@RequestParam Long userId) |
| | | { |
| | | return AjaxResult.success(roleService.roleInfoFromUserId(userId)); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 新增角色 |
| | | */ |
| | | // @PreAuthorize("@ss.hasPermi('system:role:add')") |
| | | @ApiOperation(value = "新增角色") |
| | | @Log(title = "角色信息-新增角色", businessType = BusinessType.INSERT) |
| | | @PostMapping("/system/role/add") |
| | | public AjaxResult add(@Validated @RequestBody SysRoleDTO dto) |
| | | { |
| | | Boolean flag= roleService.isExit(dto.getRoleId(),dto.getRoleName()); |
| | | if(flag){ |
| | | return error("新增角色'" + dto.getRoleName() + "'失败,角色名称已存在"); |
| | | } |
| | | roleService.saveRole(dto); |
| | | return AjaxResult.success(); |
| | | |
| | | } |
| | | |
| | | /** |
| | | * 修改保存角色 |
| | | */ |
| | | // @PreAuthorize("@ss.hasPermi('system:role:edit')") |
| | | @ApiOperation(value = "编辑角色",response = SysRoleDTO.class) |
| | | @Log(title = "角色信息-编辑角色", businessType = BusinessType.UPDATE) |
| | | @PostMapping("/api/system/role/edit") |
| | | public R<String> edit(@RequestBody String param) |
| | | { |
| | | SysRoleDTO dto = JSON.parseObject(param, SysRoleDTO.class); |
| | | Boolean flag= roleService.isExit(dto.getRoleId(),dto.getRoleName()); |
| | | if (flag){ |
| | | return R.fail("修改角色'" + dto.getRoleName() + "'失败,角色名称已存在"); |
| | | } |
| | | if (roleService.editRole(dto) > 0) |
| | | { |
| | | // 更新缓存用户权限 |
| | | LoginUser loginUser = getLoginUser(); |
| | | if (StringUtils.isNotNull(loginUser.getUser()) && !loginUser.getUser().isAdmin()) |
| | | { |
| | | loginUser.setPermissions(permissionService.getMenuPermission(loginUser.getUser())); |
| | | loginUser.setUser(userService.selectUserByUserName(loginUser.getUser().getUserName())); |
| | | tokenService.setLoginUser(loginUser); |
| | | } |
| | | return R.ok(); |
| | | } |
| | | return R.fail("修改角色'" + dto.getRoleName() + "'失败,请联系管理员"); |
| | | } |
| | | |
| | | /** |
| | |
| | | import com.ruoyi.common.constant.Constants; |
| | | import com.ruoyi.common.core.domain.model.LoginUserApplet; |
| | | import com.ruoyi.common.core.redis.RedisCache; |
| | | import com.ruoyi.system.model.TAppUser; |
| | | import com.ruoyi.system.service.TAppUserService; |
| | | import io.jsonwebtoken.Claims; |
| | | import io.jsonwebtoken.Jwts; |
| | | import lombok.extern.slf4j.Slf4j; |
| | |
| | | @Slf4j |
| | | public class WebSocketAuthHandler { |
| | | |
| | | @Autowired |
| | | private TAppUserService appUserService; |
| | | |
| | | |
| | | @Autowired |
| | | private RedisCache redisCache; |
| | | |
| | |
| | | @Value("${token.secret}") |
| | | private String secret; |
| | | |
| | | /** |
| | | * 验证用户认证信息 |
| | | * @param appUserId 用户ID |
| | | * @param token 认证令牌(可选) |
| | | * @return 认证结果 |
| | | */ |
| | | public AuthResult authenticateUser(String appUserId, String token) { |
| | | try { |
| | | if (appUserId == null || appUserId.trim().isEmpty()) { |
| | | return AuthResult.failure("用户ID不能为空"); |
| | | } |
| | | |
| | | // 查询用户信息 |
| | | TAppUser appUser = appUserService.getById(appUserId); |
| | | if (appUser == null) { |
| | | return AuthResult.failure("用户不存在"); |
| | | } |
| | | |
| | | // 检查用户状态 |
| | | if (appUser.getStatus() == null || appUser.getStatus() != 1) { |
| | | return AuthResult.failure("用户已被禁用"); |
| | | } |
| | | |
| | | // 检查用户审核状态 |
| | | if (appUser.getState() == null || appUser.getState() != 1) { |
| | | return AuthResult.failure("用户未通过审核"); |
| | | } |
| | | |
| | | // 这里可以添加token验证逻辑 |
| | | if (token != null && !token.trim().isEmpty()) { |
| | | // 验证token的有效性 |
| | | if (!validateToken(appUserId, token)) { |
| | | return AuthResult.failure("认证令牌无效"); |
| | | } |
| | | } |
| | | |
| | | return AuthResult.success(appUser); |
| | | } catch (Exception e) { |
| | | log.error("用户认证失败,用户ID: {}, 错误: {}", appUserId, e.getMessage(), e); |
| | | return AuthResult.failure("认证过程中发生错误: " + e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 验证token |
| | |
| | | return com.ruoyi.common.constant.CacheConstants.LOGIN_TOKEN_KEY + uuid; |
| | | } |
| | | |
| | | /** |
| | | * 认证结果类 |
| | | */ |
| | | public static class AuthResult { |
| | | private final boolean success; |
| | | private final String message; |
| | | private final TAppUser appUser; |
| | | |
| | | private AuthResult(boolean success, String message, TAppUser appUser) { |
| | | this.success = success; |
| | | this.message = message; |
| | | this.appUser = appUser; |
| | | } |
| | | |
| | | public static AuthResult success(TAppUser appUser) { |
| | | return new AuthResult(true, "认证成功", appUser); |
| | | } |
| | | |
| | | public static AuthResult failure(String message) { |
| | | return new AuthResult(false, message, null); |
| | | } |
| | | |
| | | public boolean isSuccess() { |
| | | return success; |
| | | } |
| | | |
| | | public String getMessage() { |
| | | return message; |
| | | } |
| | | |
| | | public TAppUser getAppUser() { |
| | | return appUser; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 从认证消息中提取用户信息 |
| | |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.ruoyi.common.core.controller.BaseController; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.system.model.TMissionReassign; |
| | | |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import lombok.extern.slf4j.Slf4j; |
| | |
| | | * @return 操作结果 |
| | | */ |
| | | @PostMapping("/user/send/{appUserId}") |
| | | @ApiOperation(value = "发送信息", response = TMissionReassign.class) |
| | | @ApiOperation(value = "发送信息") |
| | | public R<String> sendMessageToUser(@PathVariable String appUserId, @RequestBody Map<String, String> request) { |
| | | try { |
| | | String message = JSONObject.toJSONString(request); |
| | |
| | | } |
| | | |
| | | @GetMapping("/user/send1/{appUserId}") |
| | | @ApiOperation(value = "发送信息", response = TMissionReassign.class) |
| | | @ApiOperation(value = "发送信息") |
| | | public R<String> sendMessageToUser1(@PathVariable String appUserId) { |
| | | try { |
| | | String message = "{\"type\":\"mission_push\",\"content\":\"{\\\"missionId\\\":\\\"1983875114637811713\\\"}\",\"timestamp\":\"2025-10-27T09:22:45.681\"}"; |
| | |
| | | .authorizeRequests() |
| | | // 对于登录login 注册register 验证码captchaImage 允许匿名访问 |
| | | .antMatchers("/getPrivacyAgreement/{agreementType}", |
| | | "/applet/queryProtocolConfigByType","/api/loginApp", |
| | | "/applet/queryProtocolConfigByType","/api/loginApp","/common/upload", |
| | | "/api/login","/api/middle-platform/login","/open/login","/applet/queryProtocolConfigByType", |
| | | "/register","/applet/getCode","/applet/loginCode", |
| | | "/applet/changepwd", "/captchaImage","/getCode","/loginCode", |
| | | "/operations/getBySingleNum/**", |
| | | "/operations/getBySingleNum/**","/api/**","/system/visitor/config/**", |
| | | "/user/getUserInfoByNumber/**","/open/t-app-user/test", |
| | | "/wxLogin/**","/cos/get/**","/t-mission/**","/api/t-app-user/**","/open/file/**","/open/t-data-statistics/**","/open/pushMessageSolo/**", |
| | | "/open/t-mission/sendMission","/open/websocket/**" |
| | |
| | | import com.ruoyi.framework.manager.AsyncManager; |
| | | import com.ruoyi.framework.manager.factory.AsyncFactory; |
| | | import com.ruoyi.framework.security.context.AuthenticationContextHolder; |
| | | import com.ruoyi.system.model.TAppUser; |
| | | import com.ruoyi.system.service.ISysConfigService; |
| | | import com.ruoyi.system.service.ISysUserService; |
| | | import com.ruoyi.system.service.TAppUserService; |
| | | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.security.authentication.AuthenticationManager; |
| | |
| | | private ISysConfigService configService; |
| | | @Autowired |
| | | private SysPermissionService permissionService; |
| | | @Autowired |
| | | private TAppUserService appUserService; |
| | | |
| | | public LoginUser loginByTrustedUsername(String username, String loginSource, String middlePlatformToken) |
| | | { |
| | |
| | | } |
| | | // 用户验证 |
| | | Authentication authentication = null; |
| | | // 用户验证 |
| | | TAppUser appUser = appUserService.getOne(Wrappers.<TAppUser>lambdaQuery().eq(TAppUser::getAccount,account)); |
| | | if (StringUtils.isNull(appUser)){ |
| | | log.info("登录用户:{} 不存在.", account); |
| | | throw new ServiceException(MessageUtils.message("user.not.exists")); |
| | | } else if (appUser.getDisabled()) { |
| | | log.info("登录用户:{} 已被删除.", account); |
| | | throw new ServiceException(MessageUtils.message("user.password.delete")); |
| | | } else if (2 == appUser.getStatus()) { |
| | | log.info("登录用户:{} 已被停用.", account); |
| | | throw new ServiceException(MessageUtils.message("user.blocked")); |
| | | } |
| | | |
| | | try |
| | | { |
| | | String userName = account + "_2"; |
| | |
| | | */ |
| | | public void recordAppLoginInfo(String userId) |
| | | { |
| | | TAppUser appUser = new TAppUser(); |
| | | appUser.setId(userId); |
| | | // sysUser.setLoginIp(IpUtils.getIpAddr()); |
| | | // sysUser.setLoginDate(DateUtils.getNowDate()); |
| | | // userService.updateUserProfile(sysUser); |
| | |
| | | import com.ruoyi.framework.manager.AsyncManager; |
| | | import com.ruoyi.framework.manager.factory.AsyncFactory; |
| | | import com.ruoyi.framework.security.context.AuthenticationContextHolder; |
| | | import com.ruoyi.system.model.TAppUser; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.security.core.Authentication; |
| | |
| | | clearLoginRecordCache(username); |
| | | } |
| | | } |
| | | public void validateApp(TAppUser user) |
| | | { |
| | | Authentication usernamePasswordAuthenticationToken = AuthenticationContextHolder.getContext(); |
| | | String username = usernamePasswordAuthenticationToken.getName(); |
| | | String password = usernamePasswordAuthenticationToken.getCredentials().toString(); |
| | | |
| | | Integer retryCount = redisCache.getCacheObject(getCacheKey(username)); |
| | | |
| | | if (retryCount == null) |
| | | { |
| | | retryCount = 0; |
| | | } |
| | | |
| | | if (retryCount >= Integer.valueOf(maxRetryCount).intValue()) |
| | | { |
| | | AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, |
| | | MessageUtils.message("user.password.retry.limit.exceed", maxRetryCount, lockTime))); |
| | | throw new UserPasswordRetryLimitExceedException(maxRetryCount, lockTime); |
| | | } |
| | | |
| | | if (!matchesApp(user, password)) |
| | | { |
| | | retryCount = retryCount + 1; |
| | | AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, |
| | | MessageUtils.message("user.password.retry.limit.count", retryCount))); |
| | | redisCache.setCacheObject(getCacheKey(username), retryCount, lockTime, TimeUnit.MINUTES); |
| | | throw new UserPasswordNotMatchException(); |
| | | } |
| | | else |
| | | { |
| | | clearLoginRecordCache(username); |
| | | } |
| | | } |
| | | |
| | | public boolean matches(SysUser user, String rawPassword) |
| | | { |
| | | return SecurityUtils.matchesPassword(rawPassword, user.getPassword()); |
| | | } |
| | | public boolean matchesApp(TAppUser user, String rawPassword) |
| | | { |
| | | return SecurityUtils.matchesPassword(rawPassword, user.getPassword()); |
| | | } |
| | |
| | | import com.ruoyi.common.exception.ServiceException; |
| | | import com.ruoyi.common.utils.MessageUtils; |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import com.ruoyi.system.model.TAppUser; |
| | | import com.ruoyi.system.service.ISysUserService; |
| | | import com.ruoyi.system.service.TAppUserService; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.BeanUtils; |
| | |
| | | @Autowired |
| | | private ISysUserService userService; |
| | | @Autowired |
| | | private TAppUserService appUserService; |
| | | |
| | | @Autowired |
| | | private SysPasswordService passwordService; |
| | | |
| | | @Autowired |
| | |
| | | { |
| | | String[] split = username.split("_"); |
| | | username = split[0]; |
| | | String type = split[1]; |
| | | if("1".equals(type)){ |
| | | SysUser user = userService.selectUserByUserName(username); |
| | | if (StringUtils.isNull(user)) |
| | | { |
| | | log.info("登录用户:{} 不存在.", username); |
| | | throw new ServiceException(MessageUtils.message("user.not.exists")); |
| | | } |
| | | else if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) |
| | | { |
| | | log.info("登录用户:{} 已被删除.", username); |
| | | throw new ServiceException(MessageUtils.message("user.password.delete")); |
| | | } |
| | | else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) |
| | | { |
| | | log.info("登录用户:{} 已被停用.", username); |
| | | throw new ServiceException(MessageUtils.message("user.blocked")); |
| | | } |
| | | |
| | | passwordService.validate(user); |
| | | |
| | | return createLoginUser(user); |
| | | }else { |
| | | TAppUser user = appUserService.getOne(Wrappers.<TAppUser>lambdaQuery().eq(TAppUser::getAccount,username)); |
| | | if (StringUtils.isNull(user)) |
| | | { |
| | | log.info("登录用户:{} 不存在.", username); |
| | | throw new ServiceException(MessageUtils.message("user.not.exists")); |
| | | } |
| | | else if (user.getDisabled()) |
| | | { |
| | | log.info("登录用户:{} 已被删除.", username); |
| | | throw new ServiceException(MessageUtils.message("user.password.delete")); |
| | | } |
| | | else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) |
| | | { |
| | | log.info("登录用户:{} 已被停用.", username); |
| | | throw new ServiceException(MessageUtils.message("user.blocked")); |
| | | } |
| | | passwordService.validateApp(user); |
| | | |
| | | TAppUserResp appUserResp = new TAppUserResp(); |
| | | BeanUtils.copyProperties(user,appUserResp); |
| | | |
| | | return createLoginUserApp(appUserResp); |
| | | SysUser user = userService.selectUserByUserName(username); |
| | | if (StringUtils.isNull(user)) |
| | | { |
| | | log.info("登录用户:{} 不存在.", username); |
| | | throw new ServiceException(MessageUtils.message("user.not.exists")); |
| | | } |
| | | else if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) |
| | | { |
| | | log.info("登录用户:{} 已被删除.", username); |
| | | throw new ServiceException(MessageUtils.message("user.password.delete")); |
| | | } |
| | | else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) |
| | | { |
| | | log.info("登录用户:{} 已被停用.", username); |
| | | throw new ServiceException(MessageUtils.message("user.blocked")); |
| | | } |
| | | |
| | | passwordService.validate(user); |
| | | |
| | | return createLoginUser(user); |
| | | } |
| | | |
| | | public UserDetails createLoginUser(SysUser user) |
| New file |
| | |
| | | package com.ruoyi.system.domain; |
| | | |
| | | |
| | | import java.time.LocalDateTime; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 员工实体(对应 t_employee 表) |
| | | */ |
| | | @Data |
| | | public class Employee { |
| | | |
| | | private Long employeeId; |
| | | |
| | | private Long deptId; |
| | | |
| | | private String employeeName; |
| | | |
| | | private String employeeNo; |
| | | |
| | | private String contactPhoneCipher; |
| | | |
| | | private String contactPhoneHash; |
| | | |
| | | /** EMPLOYEE员工 / DEPT_MANAGER部门负责人 */ |
| | | private String position; |
| | | |
| | | /** 绑定卡号,可能为空 */ |
| | | private String cardNo; |
| | | |
| | | private String faceImage; |
| | | |
| | | private Boolean enabled; |
| | | |
| | | /** 0正常 1删除 */ |
| | | private String delFlag; |
| | | |
| | | private String createBy; |
| | | |
| | | private LocalDateTime createTime; |
| | | |
| | | private String updateBy; |
| | | |
| | | private LocalDateTime updateTime; |
| | | } |
| New file |
| | |
| | | package com.ruoyi.system.dto; |
| | | |
| | | |
| | | import javax.validation.constraints.NotBlank; |
| | | import javax.validation.constraints.NotNull; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 刷卡验证请求: |
| | | * employeeId 为业务上下文中已确定的"接待人"(如访客预约单/登记时选定的被访者); |
| | | * cardNo 为现场读卡器读取到的卡号原文。 |
| | | */ |
| | | @Data |
| | | @ApiModel(value = "CardVerifyRequest", description = "接待人刷卡验证请求") |
| | | public class CardVerifyRequest { |
| | | @ApiModelProperty(value = "现场读卡器读取到的卡号原文", required = true, example = "0123456789") |
| | | @NotBlank(message = "卡号不能为空") |
| | | private String cardNo; |
| | | } |
| | |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | import javax.validation.constraints.NotBlank; |
| | | |
| | | /** |
| | | * 门禁设备详情请求 |
| | | * |
| | |
| | | @Data |
| | | public class SysDoorDeviceDetailRequest |
| | | { |
| | | /** 门禁设备主键 */ |
| | | /** |
| | | * 门禁设备主键 |
| | | */ |
| | | @ApiModelProperty("门禁设备主键") |
| | | @NotBlank(message = "设备ID不能为空") |
| | | private Long doorId; |
| | | } |
| | |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | import javax.validation.constraints.NotNull; |
| | | |
| | | /** |
| | | * 访客机详情请求 |
| | | * |
| | |
| | | { |
| | | /** 访客机主键 */ |
| | | @ApiModelProperty("访客机主键") |
| | | @NotNull(message = "设备ID不能为空") |
| | | private Long machineId; |
| | | } |
| New file |
| | |
| | | package com.ruoyi.system.dto; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | import com.ruoyi.common.core.domain.BasePage; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | import javax.validation.constraints.NotBlank; |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * 访客登记 |
| | | * |
| | | * @author ruoyi |
| | | */ |
| | | @Data |
| | | @ApiModel(value = "SysVisitorRecordAddRequest", description = "访客登记") |
| | | public class SysVisitorRecordAddRequest |
| | | { |
| | | /** |
| | | * 访客姓名 |
| | | */ |
| | | @NotBlank(message = "访客姓名不能为空") |
| | | @ApiModelProperty(value = "访客姓名") |
| | | private String visitorName; |
| | | |
| | | /** |
| | | * 访客身份证号 |
| | | */ |
| | | @NotBlank(message = "访客身份证号不能为空") |
| | | @ApiModelProperty(value = "访客身份证号") |
| | | private String idCard; |
| | | |
| | | /** |
| | | * 被访人 |
| | | */ |
| | | @NotBlank(message = "被访人不能为空") |
| | | @ApiModelProperty(value = "被访人") |
| | | private String intervieweeName; |
| | | |
| | | /** |
| | | * 接待人验证方式 |
| | | */ |
| | | @ApiModelProperty(value = "接待人验证方式") |
| | | private String receiverVerifyMethod; |
| | | |
| | | /** |
| | | * 访问区域ID,英文逗号分隔 |
| | | */ |
| | | @ApiModelProperty(value = "访问区域ID,英文逗号分隔") |
| | | private String visitAreaIds; |
| | | |
| | | /** |
| | | * 车牌号 |
| | | */ |
| | | @ApiModelProperty(value = "车牌号") |
| | | private String plateNo; |
| | | |
| | | /** |
| | | * 来访事由 |
| | | */ |
| | | @ApiModelProperty(value = "来访事由") |
| | | private String visitReason; |
| | | |
| | | /** |
| | | * 有效期开始时间 |
| | | */ |
| | | @ApiModelProperty(value = "有效期开始时间") |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private Date validStartTime; |
| | | |
| | | /** |
| | | * 有效期结束时间 |
| | | */ |
| | | @ApiModelProperty(value = "有效期结束时间") |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private Date validEndTime; |
| | | |
| | | /** |
| | | * 访客人像地址 |
| | | */ |
| | | @ApiModelProperty(value = "访客人像地址") |
| | | private String faceImageUrl; |
| | | } |
| New file |
| | |
| | | package com.ruoyi.system.enums; |
| | | |
| | | |
| | | /** |
| | | * 接待人刷卡验证结果码 |
| | | */ |
| | | public enum VerifyResultEnum { |
| | | |
| | | SUCCESS( "验证通过"), |
| | | |
| | | PARAM_INVALID( "请求参数不合法"), |
| | | |
| | | /** 不存在 / 已停用 / 已删除统一走这个码,避免向前端泄露具体是哪种情况 */ |
| | | RECEPTIONIST_UNAVAILABLE( "接待人不存在或已停用"), |
| | | |
| | | CARD_NOT_BOUND( "该接待人尚未绑定卡号,请联系管理员"), |
| | | CARD_NOT_MATCH( "卡号与接待人不匹配,请核实后重试"), |
| | | |
| | | VERIFY_LOCKED( "验证失败次数过多,请稍后重试或联系前台"), |
| | | |
| | | SYSTEM_ERROR( "系统繁忙,请稍后重试"); |
| | | |
| | | private final String message; |
| | | |
| | | VerifyResultEnum(String message) { |
| | | this.message = message; |
| | | } |
| | | |
| | | public String getMessage() { |
| | | return message; |
| | | } |
| | | } |
| New file |
| | |
| | | package com.ruoyi.system.mapper; |
| | | |
| | | |
| | | import com.ruoyi.system.domain.Employee; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | import org.apache.ibatis.annotations.Param; |
| | | |
| | | @Mapper |
| | | public interface EmployeeMapper { |
| | | |
| | | /** |
| | | * 按主键查询启用且未删除的接待人。 |
| | | * 若返回 null,说明该员工不存在 / 已停用 / 已删除中的某一种情况(SQL 层已合并过滤)。 |
| | | */ |
| | | Employee selectEnabledByCardNo(@Param("cardNo") String cardNo); |
| | | } |
| | |
| | | package com.ruoyi.system.mapper; |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.ruoyi.common.basic.PageInfo; |
| | | import com.ruoyi.system.domain.SysVisitorRecord; |
| | | import com.ruoyi.system.dto.SysVisitorRecordPageRequest; |
| | | import com.ruoyi.system.vo.SysVisitorPassRecordVO; |
| | | import com.ruoyi.system.vo.SysVisitorRecordDetailVO; |
| | |
| | | * @author ruoyi |
| | | */ |
| | | @Mapper |
| | | public interface SysVisitorRecordMapper |
| | | public interface SysVisitorRecordMapper extends BaseMapper<SysVisitorRecord> |
| | | { |
| | | public List<SysVisitorRecordVO> pageList(@Param("query") SysVisitorRecordPageRequest query, |
| | | @Param("pageInfo") PageInfo<SysVisitorRecordVO> pageInfo); |
| | |
| | | public List<SysVisitorPassRecordVO> selectPassRecordsByRecordId(Long recordId); |
| | | |
| | | public int deleteByIds(@Param("recordIds") List<Long> recordIds, @Param("updateBy") String updateBy); |
| | | |
| | | public int insert(SysVisitorRecord record); |
| | | } |
| New file |
| | |
| | | package com.ruoyi.system.service; |
| | | |
| | | |
| | | import com.ruoyi.common.core.domain.AjaxResult; |
| | | import com.ruoyi.system.dto.CardVerifyRequest; |
| | | |
| | | public interface EmployeeVerifyService { |
| | | |
| | | /** |
| | | * 刷卡验证:比对现场读到的卡号与该接待人绑定的卡号是否一致。 |
| | | */ |
| | | AjaxResult verifyByCard(CardVerifyRequest request); |
| | | } |
| | |
| | | public int logout(SysDoorDeviceLogoutRequest request, String username); |
| | | |
| | | public int delete(SysDoorDeviceDeleteRequest request, String username); |
| | | |
| | | } |
| | |
| | | import com.ruoyi.common.core.domain.entity.SysMenu; |
| | | import com.ruoyi.common.core.domain.entity.SysRole; |
| | | import com.ruoyi.system.domain.SysUserRole; |
| | | import com.ruoyi.system.dto.SysRoleDTO; |
| | | import com.ruoyi.system.query.SysRoleQuery; |
| | | |
| | | /** |
| | |
| | | |
| | | String selectByUserId(Long user_id); |
| | | |
| | | void saveRole(SysRoleDTO dto); |
| | | |
| | | PageInfo<SysRole> selectPageList(SysRoleQuery query); |
| | | |
| | | /** |
| | | * 修改保存角色信息 |
| | | * |
| | | * @param dto 角色信息 |
| | | * @return 结果 |
| | | */ |
| | | public int editRole(SysRoleDTO dto); |
| | | |
| | | List<SysRole> selectRoleByUserIds(List<String> roleIds); |
| | | } |
| | |
| | | public int edit(SysVisitAreaEditRequest request, String username); |
| | | |
| | | public int delete(SysVisitAreaDeleteRequest request, String username); |
| | | |
| | | } |
| | |
| | | public int logout(SysVisitorMachineLogoutRequest request, String username); |
| | | |
| | | public int delete(SysVisitorMachineDeleteRequest request, String username); |
| | | |
| | | /** |
| | | * 激活设备 |
| | | * |
| | | * @param deviceId 设备ID |
| | | * @return 影响行数 |
| | | */ |
| | | int activateDevice(Long deviceId); |
| | | |
| | | /** |
| | | * 注销设备 |
| | | * |
| | | * @param deviceId 设备ID |
| | | * @return 影响行数 |
| | | */ |
| | | int deactivateDevice(Long deviceId); |
| | | } |
| New file |
| | |
| | | package com.ruoyi.system.service.impl; |
| | | |
| | | import com.ruoyi.common.core.domain.AjaxResult; |
| | | import com.ruoyi.system.domain.Employee; |
| | | import com.ruoyi.system.dto.CardVerifyRequest; |
| | | import com.ruoyi.system.enums.VerifyResultEnum; |
| | | import com.ruoyi.system.mapper.EmployeeMapper; |
| | | import com.ruoyi.system.service.EmployeeVerifyService; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import javax.annotation.Resource; |
| | | |
| | | @Service |
| | | public class EmployeeVerifyServiceImpl implements EmployeeVerifyService { |
| | | |
| | | private static final Logger log = LoggerFactory.getLogger(EmployeeVerifyServiceImpl.class); |
| | | |
| | | @Resource |
| | | private EmployeeMapper employeeMapper; |
| | | |
| | | // TODO: 注入验证日志Mapper / Redis,用于失败次数统计与锁定(见 recordAndReturn 方法说明) |
| | | |
| | | @Override |
| | | public AjaxResult verifyByCard(CardVerifyRequest request) { |
| | | Employee employee = employeeMapper.selectEnabledByCardNo(request.getCardNo()); |
| | | |
| | | if (employee == null) { |
| | | return recordAndReturn(VerifyResultEnum.RECEPTIONIST_UNAVAILABLE); |
| | | } |
| | | |
| | | String boundCardNo = employee.getCardNo(); |
| | | if (boundCardNo == null || boundCardNo.trim().isEmpty()) { |
| | | return recordAndReturn(VerifyResultEnum.CARD_NOT_BOUND); |
| | | } |
| | | |
| | | String inputCardNo = request.getCardNo() == null ? "" : request.getCardNo().trim(); |
| | | if (!boundCardNo.trim().equalsIgnoreCase(inputCardNo)) { |
| | | return recordAndReturn(VerifyResultEnum.CARD_NOT_MATCH); |
| | | } |
| | | |
| | | return recordAndReturn(VerifyResultEnum.SUCCESS); |
| | | } |
| | | |
| | | /** |
| | | * 统一出口:记录验证流水(成功/失败均记录)并返回结果。 |
| | | * TODO: 落库到 t_employee_verify_log(建表脚本见 sql/verify_log.sql),字段建议包含: |
| | | * employee_id, result_code, client_ip, device_no, create_time。 |
| | | * TODO: 结合 Redis 按 employeeId + 来源IP/设备号 做滑动窗口计数,连续失败N次后返回 |
| | | * VERIFY_LOCKED 并锁定一段时间,防止对某个接待人反复试卡的暴力破解/撞库。 |
| | | */ |
| | | private AjaxResult recordAndReturn(VerifyResultEnum result) { |
| | | if (VerifyResultEnum.SUCCESS.equals(result)) { |
| | | log.info("接待人刷卡验证成功"); |
| | | return AjaxResult.success(); |
| | | } |
| | | log.warn("接待人刷卡验证失败, result={}", result.getMessage()); |
| | | return AjaxResult.error(result.getMessage()); |
| | | } |
| | | } |
| | | |
| | |
| | | import com.ruoyi.system.vo.SysDoorDeviceVO; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.util.CollectionUtils; |
| | | |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | /** |
| | |
| | | import com.ruoyi.system.domain.SysRoleDept; |
| | | import com.ruoyi.system.domain.SysRoleMenu; |
| | | import com.ruoyi.system.domain.SysUserRole; |
| | | import com.ruoyi.system.dto.SysRoleDTO; |
| | | import com.ruoyi.system.mapper.*; |
| | | import com.ruoyi.system.query.SysRoleQuery; |
| | | import com.ruoyi.system.service.ISysRoleService; |
| | |
| | | } |
| | | |
| | | @Override |
| | | public void saveRole(SysRoleDTO dto) { |
| | | // 添加角色 |
| | | SysRole sysRole = new SysRole(); |
| | | sysRole.setRoleName(dto.getRoleName()); |
| | | sysRole.setPostType(dto.getPostType()); |
| | | sysRole.setRemark(dto.getRemark()); |
| | | roleMapper.insertRole(sysRole); |
| | | |
| | | // 添加角色权限中间表 |
| | | List<Long> menuIds = dto.getMenuIds(); |
| | | List<SysRoleMenu> sysRoleMenus = new ArrayList<>(); |
| | | for (Long menuId : menuIds) { |
| | | SysRoleMenu sysRoleMenu = new SysRoleMenu(); |
| | | sysRoleMenu.setRoleId(sysRole.getRoleId()); |
| | | sysRoleMenu.setMenuId(menuId); |
| | | sysRoleMenus.add(sysRoleMenu); |
| | | } |
| | | roleMenuMapper.batchRoleMenu(sysRoleMenus); |
| | | } |
| | | |
| | | @Override |
| | | public PageInfo<SysRole> selectPageList(SysRoleQuery query) { |
| | | PageInfo<SysRole> pageInfo = new PageInfo<>(query.getPageNum(), query.getPageSize()); |
| | | List<SysRole> list = roleMapper.selectPageList(query,pageInfo); |
| | | pageInfo.setRecords(list); |
| | | return pageInfo; |
| | | } |
| | | |
| | | @Override |
| | | public int editRole(SysRoleDTO dto) { |
| | | // 修改角色信息 |
| | | SysRole sysRole = new SysRole(); |
| | | sysRole.setRoleId(dto.getRoleId()); |
| | | sysRole.setRoleName(dto.getRoleName()); |
| | | sysRole.setPostType(dto.getPostType()); |
| | | sysRole.setRemark(dto.getRemark()); |
| | | roleMapper.updateRole(sysRole); |
| | | // 删除角色与菜单关联 |
| | | roleMenuMapper.deleteRoleMenuByRoleId(dto.getRoleId()); |
| | | |
| | | // 添加角色权限中间表 |
| | | List<Long> menuIds = dto.getMenuIds(); |
| | | List<SysRoleMenu> sysRoleMenus = new ArrayList<>(); |
| | | for (Long menuId : menuIds) { |
| | | SysRoleMenu sysRoleMenu = new SysRoleMenu(); |
| | | sysRoleMenu.setRoleId(dto.getRoleId()); |
| | | sysRoleMenu.setMenuId(menuId); |
| | | sysRoleMenus.add(sysRoleMenu); |
| | | } |
| | | |
| | | return roleMenuMapper.batchRoleMenu(sysRoleMenus); |
| | | } |
| | | |
| | | @Override |
| | |
| | | import com.ruoyi.system.vo.SysVisitAreaVO; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.util.CollectionUtils; |
| | | |
| | | import java.util.ArrayList; |
| | |
| | | import com.ruoyi.common.basic.PageInfo; |
| | | import com.ruoyi.common.exception.ServiceException; |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import com.ruoyi.system.domain.SysDoorDevice; |
| | | import com.ruoyi.system.domain.SysVisitArea; |
| | | import com.ruoyi.system.domain.SysVisitorMachine; |
| | | import com.ruoyi.system.dto.SysVisitorMachineAddRequest; |
| | |
| | | import com.ruoyi.system.vo.SysVisitorMachineVO; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.util.CollectionUtils; |
| | | |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | /** |
| | |
| | | return machine; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public int activateDevice(Long deviceId) { |
| | | // 1. 根据deviceId查询设备 |
| | | SysVisitorMachine device = visitorMachineMapper.selectById(deviceId); |
| | | if (device == null || device.getDelFlag().equals("1")) { |
| | | throw new ServiceException("设备不存在,请先添加设备"); |
| | | } |
| | | |
| | | // 2. 检查是否已激活 |
| | | if ("ONLINE".equals(device.getOnlineStatus()) || "ACTIVATED".equals(device.getOnlineStatus())) { |
| | | throw new ServiceException("设备已激活,无需重复操作"); |
| | | } |
| | | |
| | | // 3. 检查设备是否启用 |
| | | if (device.getEnabled() == null || !device.getEnabled()) { |
| | | throw new ServiceException("设备未启用,请先在后台启用设备"); |
| | | } |
| | | |
| | | // 4. 更新状态为激活/在线 |
| | | SysVisitorMachine update = new SysVisitorMachine(); |
| | | update.setMachineId(device.getMachineId()); |
| | | update.setOnlineStatus("ONLINE"); // 或 "ACTIVATED",根据你的枚举定义 |
| | | update.setUpdateTime(new Date()); |
| | | |
| | | return visitorMachineMapper.updateMachine(update); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public int deactivateDevice(Long deviceId) { |
| | | // 1. 根据deviceId查询设备 |
| | | SysVisitorMachine device = visitorMachineMapper.selectById(deviceId); |
| | | if (device == null || device.getDelFlag().equals("1")) { |
| | | throw new ServiceException("设备不存在"); |
| | | } |
| | | |
| | | // 2. 检查是否已注销 |
| | | if ("OFFLINE".equals(device.getOnlineStatus()) || "UNACTIVATED".equals(device.getOnlineStatus())) { |
| | | throw new ServiceException("设备已注销,无需重复操作"); |
| | | } |
| | | |
| | | // 3. 更新状态为离线/未激活 |
| | | SysVisitorMachine update = new SysVisitorMachine(); |
| | | update.setMachineId(deviceId); |
| | | update.setOnlineStatus("OFFLINE"); // 或 "UNACTIVATED" |
| | | update.setUpdateTime(new Date()); |
| | | |
| | | return visitorMachineMapper.updateMachine(update); |
| | | } |
| | | |
| | | private Long getRequiredAreaId(Long areaId) |
| | | { |
| | | if (areaId == null || areaId <= 0) |
| | |
| | | package com.ruoyi.system.vo; |
| | | |
| | | import com.ruoyi.system.model.TMission; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | |
| | | |
| | | @ApiModelProperty("一般任务数") |
| | | private Integer regularMissionNum=0; |
| | | |
| | | |
| | | @ApiModelProperty("带指派任务") |
| | | private List<TMission> missions; |
| | | |
| | | @ApiModelProperty("用户信息") |
| | | private List<IndexLookDataUserVo> userInfos; |
| | |
| | | package com.ruoyi.system.vo; |
| | | |
| | | import com.ruoyi.system.model.TAppUser; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | @Data |
| | | @ApiModel(value = "人员分布轨迹详情PositioningDetailVO") |
| | | public class PositioningDetailVO extends TAppUser { |
| | | public class PositioningDetailVO { |
| | | |
| | | @ApiModelProperty(value = "轨迹") |
| | | private String realTimePositioning; |
| | |
| | | package com.ruoyi.system.vo; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | |
| | | * @author ruoyi |
| | | */ |
| | | @Data |
| | | @ApiModel(value = "SysVisitAreaVO", description = "访问区域") |
| | | public class SysVisitAreaVO |
| | | { |
| | | /** 区域主键 */ |
| | |
| | | package com.ruoyi.system.vo; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | import java.util.List; |
| | |
| | | * @author ruoyi |
| | | */ |
| | | @Data |
| | | @ApiModel(value = "访客系统配置返回对象", description = "访客系统的全部配置信息") |
| | | public class SysVisitorConfigVO |
| | | { |
| | | @ApiModelProperty(value = "配置主键ID", example = "1") |
| | | private Long configId; |
| | | |
| | | @ApiModelProperty(value = "现场登记开关", example = "true", allowableValues = "true,false") |
| | | private Boolean onsiteRegistrationEnabled; |
| | | |
| | | @ApiModelProperty(value = "预约登记开关", example = "true", allowableValues = "true,false") |
| | | private Boolean appointmentRegistrationEnabled; |
| | | |
| | | @ApiModelProperty(value = "登记需接待人确认", example = "true", allowableValues = "true,false") |
| | | private Boolean registerReceiverConfirmEnabled; |
| | | |
| | | @ApiModelProperty(value = "签离需接待人确认", example = "true", allowableValues = "true,false") |
| | | private Boolean signReceiverConfirmEnabled; |
| | | |
| | | @ApiModelProperty(value = "人像对比开关", example = "true", allowableValues = "true,false") |
| | | private Boolean faceCompareEnabled; |
| | | |
| | | @ApiModelProperty(value = "全方位人脸采集开关", example = "true", allowableValues = "true,false") |
| | | private Boolean faceCaptureEnabled; |
| | | |
| | | @ApiModelProperty(value = "允许手动输入身份证", example = "true", allowableValues = "true,false") |
| | | private Boolean manualIdCardEnabled; |
| | | |
| | | @ApiModelProperty(value = "凭条打印字段列表(按顺序打印)", |
| | | example = "visitorName,idCard,appointmentTimeRange,interviewee '凭条打印字段,英文逗号分隔并按顺序打印‘ ") |
| | | private List<String> printFields; |
| | | |
| | | @ApiModelProperty(value = "打印字段选项列表(前端展示用)") |
| | | private List<PrintFieldOptionVO> printFieldOptions; |
| | | |
| | | @ApiModelProperty(value = "系统名称", example = "自主访客登记管理平台") |
| | | private String systemName; |
| | | |
| | | @ApiModelProperty(value = "Logo图片地址", example = "https://example.com/logo.png") |
| | | private String logoUrl; |
| | | |
| | | @ApiModelProperty(value = "服务厂家", example = "科世达科技有限公司") |
| | | private String serviceProvider; |
| | | |
| | | @ApiModelProperty(value = "技术支持电话", example = "400-888-9999") |
| | | private String supportPhone; |
| | | |
| | | @ApiModelProperty(value = "访客机管理入口开关", example = "true", allowableValues = "true,false") |
| | | private Boolean visitorMachineEntryEnabled; |
| | | } |
| | |
| | | package com.ruoyi.system.vo; |
| | | |
| | | import com.ruoyi.system.model.TAppUser; |
| | | import com.ruoyi.system.model.TAppUserSkill; |
| | | import com.ruoyi.system.model.TUserMajor; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | |
| | | |
| | | @Data |
| | | @ApiModel("人员管理详情TAppUserDetailVO") |
| | | public class TAppUserDetailVO extends TAppUser { |
| | | |
| | | @ApiModelProperty(value = "用户专业") |
| | | private List<TUserMajor> userMajors; |
| | | |
| | | @ApiModelProperty(value = "用户职业技能") |
| | | private TAppUserSkill appUserSkill; |
| | | public class TAppUserDetailVO { |
| | | |
| | | } |
| | |
| | | package com.ruoyi.system.vo; |
| | | |
| | | import com.ruoyi.system.model.TAppUser; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | @Data |
| | | @ApiModel("人员管理Vo") |
| | | public class TAppUserPageVo extends TAppUser { |
| | | public class TAppUserPageVo { |
| | | @ApiModelProperty(value = "分队名称") |
| | | private String teamName; |
| | | } |
| | |
| | | package com.ruoyi.system.vo; |
| | | |
| | | import com.ruoyi.system.model.TMissionAssignRule; |
| | | import com.ruoyi.system.model.TMissionAssignRuleIndicator; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | |
| | | |
| | | @Data |
| | | @ApiModel(value = "TMissionAssignRuleVO对象", description = "任务指派规则视图对象") |
| | | public class TMissionAssignRuleVO extends TMissionAssignRule { |
| | | |
| | | @ApiModelProperty(value = "任务指派指标列表") |
| | | private List<TMissionAssignRuleIndicator> missionAssignRuleIndicators; |
| | | public class TMissionAssignRuleVO { |
| | | |
| | | } |
| | |
| | | package com.ruoyi.system.vo; |
| | | |
| | | import com.ruoyi.system.model.TMissionReassign; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | @Data |
| | | @ApiModel(value = "任务支援、改派TMissionReassignVO") |
| | | public class TMissionReassignVO extends TMissionReassign { |
| | | public class TMissionReassignVO { |
| | | |
| | | @ApiModelProperty(value = "负责人") |
| | | private String chargePerson; |
| | |
| | | package com.ruoyi.system.vo; |
| | | |
| | | |
| | | import com.ruoyi.system.model.TAppUser; |
| | | import com.ruoyi.system.model.TMission; |
| | | import com.ruoyi.system.model.TMissionOperation; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | |
| | | |
| | | @Data |
| | | @ApiModel(value = "任务管理对象TMissionVO") |
| | | public class TMissionVO extends TMission { |
| | | public class TMissionVO { |
| | | |
| | | @ApiModelProperty(value = "负责人") |
| | | private String chargePerson; |
| | |
| | | @ApiModelProperty(value = "完成时间差") |
| | | private Double finishTimePoor; |
| | | |
| | | @ApiModelProperty(value = "任务人员") |
| | | private List<TAppUser> appUsers; |
| | | |
| | | @ApiModelProperty(value = "任务操作记录") |
| | | private List<TMissionOperation> missionOperations; |
| | | |
| | | } |
| New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="com.ruoyi.system.mapper.EmployeeMapper"> |
| | | |
| | | <resultMap id="BaseResultMap" type="com.ruoyi.system.domain.Employee"> |
| | | <id column="employee_id" property="employeeId"/> |
| | | <result column="dept_id" property="deptId"/> |
| | | <result column="employee_name" property="employeeName"/> |
| | | <result column="employee_no" property="employeeNo"/> |
| | | <result column="contact_phone_cipher" property="contactPhoneCipher"/> |
| | | <result column="contact_phone_hash" property="contactPhoneHash"/> |
| | | <result column="position" property="position"/> |
| | | <result column="card_no" property="cardNo"/> |
| | | <result column="face_image" property="faceImage"/> |
| | | <result column="enabled" property="enabled"/> |
| | | <result column="del_flag" property="delFlag"/> |
| | | <result column="create_by" property="createBy"/> |
| | | <result column="create_time" property="createTime"/> |
| | | <result column="update_by" property="updateBy"/> |
| | | <result column="update_time" property="updateTime"/> |
| | | </resultMap> |
| | | |
| | | <!-- 人脸图片不参与本接口逻辑,且 longtext 体积较大,列表中排除,减少不必要的数据传输 --> |
| | | <sql id="Base_Column_List"> |
| | | employee_id, dept_id, employee_name, employee_no, contact_phone_cipher, |
| | | contact_phone_hash, `position`, card_no, enabled, del_flag, |
| | | create_by, create_time, update_by, update_time |
| | | </sql> |
| | | |
| | | <select id="selectEnabledByCardNo" resultMap="BaseResultMap"> |
| | | SELECT |
| | | <include refid="Base_Column_List"/> |
| | | FROM t_employee |
| | | WHERE card_no = #{cardNo} |
| | | AND enabled = 1 |
| | | AND del_flag = '0' |
| | | </select> |
| | | |
| | | </mapper> |
| | |
| | | #{recordId} |
| | | </foreach> |
| | | </update> |
| | | |
| | | <insert id="insert" |
| | | parameterType="com.ruoyi.system.domain.SysVisitorRecord" |
| | | useGeneratedKeys="true" |
| | | keyProperty="recordId"> |
| | | insert into t_visitor_record |
| | | <trim prefix="(" suffix=")" suffixOverrides=","> |
| | | <if test="registerNo != null">register_no,</if> |
| | | <if test="visitorName != null">visitor_name,</if> |
| | | <if test="idCard != null">id_card,</if> |
| | | <if test="registerType != null">register_type,</if> |
| | | <if test="intervieweeName != null">interviewee_name,</if> |
| | | <if test="receiverVerifyMethod != null">receiver_verify_method,</if> |
| | | <if test="visitAreaIds != null">visit_area_ids,</if> |
| | | <if test="plateNo != null">plate_no,</if> |
| | | <if test="visitReason != null">visit_reason,</if> |
| | | <if test="validStartTime != null">valid_start_time,</if> |
| | | <if test="validEndTime != null">valid_end_time,</if> |
| | | <if test="status != null">status,</if> |
| | | <if test="registerTime != null">register_time,</if> |
| | | <if test="faceImageUrl != null">face_image_url,</if> |
| | | <if test="delFlag != null">del_flag,</if> |
| | | create_time |
| | | </trim> |
| | | values |
| | | <trim prefix="(" suffix=")" suffixOverrides=","> |
| | | <if test="registerNo != null">#{registerNo},</if> |
| | | <if test="visitorName != null">#{visitorName},</if> |
| | | <if test="idCard != null">#{idCard},</if> |
| | | <if test="registerType != null">#{registerType},</if> |
| | | <if test="intervieweeName != null">#{intervieweeName},</if> |
| | | <if test="receiverVerifyMethod != null">#{receiverVerifyMethod},</if> |
| | | <if test="visitAreaIds != null">#{visitAreaIds},</if> |
| | | <if test="plateNo != null">#{plateNo},</if> |
| | | <if test="visitReason != null">#{visitReason},</if> |
| | | <if test="validStartTime != null">#{validStartTime},</if> |
| | | <if test="validEndTime != null">#{validEndTime},</if> |
| | | <if test="status != null">#{status},</if> |
| | | <if test="registerTime != null">#{registerTime},</if> |
| | | <if test="faceImageUrl != null">#{faceImageUrl},</if> |
| | | <if test="delFlag != null">#{delFlag},</if> |
| | | now() |
| | | </trim> |
| | | |
| | | </insert> |
| | | </mapper> |