spring boot工程集成jwt 鉴权步骤

#spring boot工程集成jwt 鉴权步骤

1、pom.xml依赖

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency>

2、JwtUtils.java

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;import java.util.Date;public class JwtUtils {private static final String SECRET_KEY = "rBSnM5GAB0T7M6mZ8Yg";//your_secret_keyprivate static final long EXPIRATION_TIME = 86400000; // 1 day//    private static final long EXPIRATION_TIME = 3000;public static String generateToken(String username) {return Jwts.builder().setSubject(username).setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME)).signWith(SignatureAlgorithm.HS512, SECRET_KEY).compact();}/** 设置token失效*/public static void setTokenExpired(String token) {getClaimsFromToken(token).setExpiration(new Date(System.currentTimeMillis()));
//        getClaimsFromToken(token).clear();}public static Claims getClaimsFromToken(String token) {return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();}public static boolean isTokenExpired(String token) {return getClaimsFromToken(token).getExpiration().before(new Date());}
}

3、JwtAuthenticationFilter.java

import com.ewaycloud.jw.common.core.util.JwtUtils;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;public class JwtAuthenticationFilter extends BasicAuthenticationFilter {public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {super(authenticationManager);}@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)throws IOException, ServletException {String header = request.getHeader("Authorization");if (header == null || !header.startsWith("Bearer ")) {chain.doFilter(request, response);return;}String token = header.substring(7);UsernamePasswordAuthenticationToken authentication = getAuthentication(token);SecurityContextHolder.getContext().setAuthentication(authentication);chain.doFilter(request, response);}private UsernamePasswordAuthenticationToken getAuthentication(String token) {if (token != null && !JwtUtils.isTokenExpired(token)) {String user = JwtUtils.getClaimsFromToken(token).getSubject();if (user != null) {return new UsernamePasswordAuthenticationToken(user, null, new ArrayList<>());}}return null;}
}

4、WebGlobalInterceptor.java

import com.ewaycloud.jw.common.core.config.CoreCommonProperties;
import com.ewaycloud.jw.common.core.config.MyCacheManager;
import com.ewaycloud.jw.common.core.util.JwtUtils;
import com.ewaycloud.jw.common.core.util.SpringContextHolder;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.CacheManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;/*** WEB全局拦截器*** @date 2022/8/25*/
@Slf4j
@RequiredArgsConstructor
public class WebGlobalInterceptor implements HandlerInterceptor {private final ObjectMapper objectMapper;private final CoreCommonProperties coreCommonProperties;private final CacheManager cacheManager = SpringContextHolder.getBean(CacheManager.class);@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String header = request.getHeader("Authorization");if (header == null || !header.startsWith("Bearer ")) {return false;}String token = header.substring(7);if(token == null || JwtUtils.isTokenExpired(token)){return false;}/**从缓存中获取token, 用户主动退出后清除*/if(null ==MyCacheManager.get(token)){return false;}UsernamePasswordAuthenticationToken authentication = getAuthentication(token);SecurityContextHolder.getContext().setAuthentication(authentication);return true;}private UsernamePasswordAuthenticationToken getAuthentication(String token) {if (token != null && !JwtUtils.isTokenExpired(token)) {String user = JwtUtils.getClaimsFromToken(token).getSubject();if (user != null) {return new UsernamePasswordAuthenticationToken(user, null, new ArrayList<>());}}return null;}}

5、WebGlobalInterceptorConfigurer.java

import com.ewaycloud.jw.common.core.config.CoreCommonProperties;
import com.ewaycloud.jw.common.data.resolver.SqlFilterArgumentResolver;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import java.util.List;/*** 拦截器配置* @author gwh* @date 2024/10/26*/
@Configuration
@RequiredArgsConstructor
public class WebGlobalInterceptorConfigurer  implements WebMvcConfigurer {private final ObjectMapper objectMapper;private final CoreCommonProperties coreCommonProperties;/*** 增加请求参数解析器,对请求中的参数注入SQL 检查* @param resolverList 参数解析器*/@Overridepublic void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolverList) {resolverList.add(new SqlFilterArgumentResolver());}@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(webGlobalInterceptor()).addPathPatterns("/**").excludePathPatterns("/user/login","/user/logout");}@Beanpublic WebGlobalInterceptor webGlobalInterceptor(){return new WebGlobalInterceptor(objectMapper, coreCommonProperties);}}

6、SecurityUtils.java

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.ewaycloud.jw.common.core.config.MyCacheManager;
import com.ewaycloud.jw.common.core.user.SysUser;
import com.ewaycloud.jw.common.core.user.UserInfo;
import com.ewaycloud.jw.common.core.constant.CommonConstants;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
//import org.springframework.data.redis.core.RedisTemplate;import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;/*** 安全工具类** @author gwh*/
@Slf4j
@UtilityClass
public class SecurityUtils {private final CacheManager cacheManager = SpringContextHolder.getBean(CacheManager.class);//	@Resource
//	private  RedisTemplate redisTemplate;/*** 获取用户登录信息*/public UserInfo getUserInfo() {// 获取传递的tokenString token = WebUtils.getRequest().getHeader(CommonConstants.AUTHORIZATION);if (StrUtil.isBlank(token)) token = WebUtils.getRequest().getParameter(CommonConstants.AUTHORIZATION.toLowerCase());log.debug("获取header用户token为:{}", token);// 验证登录信息if (StrUtil.isNotBlank(token)) {UserInfo userInfo = (UserInfo)MyCacheManager.get(token.substring(7));if (userInfo != null ) {if ( userInfo.getSysUser() == null) {return null;}return userInfo;} else {return null;}} else {return null;}}/*** 获取用户*/public SysUser getUser() {if (Objects.isNull(getUserInfo())) return null;return getUserInfo().getSysUser();}/*** 获取用户角色信息* @return 角色集合*/public List<Long> getRoleIds() {if (Objects.isNull(getUserInfo())) return null;return CollUtil.newArrayList(getUserInfo().getRoles());}}

7、SecurityConfig.java

import com.ewaycloud.jw.common.data.interceptor.JwtAuthenticationFilter;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.csrf().disable().authorizeRequests().antMatchers("/user/login","/user/logout").permitAll().anyRequest().authenticated().and().addFilter(new JwtAuthenticationFilter(authenticationManager()));}
}

8、SysUserController.java

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ewaycloud.jw.admin.api.dto.UserDTO;
import com.ewaycloud.jw.admin.api.vo.UserVO;
import com.ewaycloud.jw.admin.mapper.SysUserMapper;
import com.ewaycloud.jw.admin.service.SysUserService;
import com.ewaycloud.jw.channel.model.SysLogInfo;
import com.ewaycloud.jw.channel.service.SysLogInfoService;
import com.ewaycloud.jw.common.core.config.MyCacheManager;
import com.ewaycloud.jw.common.core.constant.CommonConstants;
import com.ewaycloud.jw.common.core.exception.ErrorCodes;
import com.ewaycloud.jw.common.core.user.SysUser;
import com.ewaycloud.jw.common.core.user.UserInfo;
import com.ewaycloud.jw.common.core.util.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.cache.CacheManager;
import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.List;
import java.util.Objects;/*** * @date 2018/12/16*/
@RestController
@AllArgsConstructor
@RequestMapping("/user")
@Api(value = "user", tags = "用户管理模块")
public class SysUserController {private final SysUserService userService;private final CacheManager cacheManager;
//	private final RedisTemplate redisTemplate;@Resourceprivate SysLogInfoService sysLogInfoService;@Resourceprivate SysUserMapper sysUserMapper;public static String getIpAddr(HttpServletRequest request) {String ipAddress = null;try {ipAddress = request.getHeader("x-forwarded-for");if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getHeader("Proxy-Client-IP");}if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getHeader("WL-Proxy-Client-IP");}if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getRemoteAddr();if (ipAddress.equals("127.0.0.1")) {// 根据网卡取本机配置的IPInetAddress inet = null;try {inet = InetAddress.getLocalHost();} catch (UnknownHostException e) {e.printStackTrace();}ipAddress = inet.getHostAddress();}}// 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割if (ipAddress != null && ipAddress.length() > 15) { // "***.***.***.***".length()if (ipAddress.indexOf(",") > 0) {ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));}}} catch (Exception e) {ipAddress = "";}return ipAddress;}/*** 用户登录* @return 用户信息*/@GetMapping("/login")public R login(@RequestParam String username, @RequestParam String password, HttpServletRequest request) {UserInfo userInfo = userService.login(username, password);if (null != userInfo && userInfo.getLoginCount()==0) {return R.ok(userInfo);}if (null == userInfo ) {return R.failed("用户名或密码错误");}if(null != userInfo && userInfo.getLoginCount()>0 && userInfo.getLoginCount()<5) {return R.failed("用户名或密码错误");}if(null != userInfo && userInfo.getLoginCount()>5 ) {return R.failed("密码错误次数过多,账户已被锁定");}/** 记录日志 */SysLogInfo vo = new SysLogInfo();vo.setOperate("Get登录系统/user/login");if(null != userInfo && null!= userInfo.getSysUser()){vo.setCreateBy(userInfo.getSysUser().getName());}if(null != userInfo && null!= userInfo.getAreaName()){vo.setArea(userInfo.getAreaName());}vo.setCreateTime(new Date());//查询角色if(null != userInfo && null != userInfo.getSysUser()){UserVO userVO = sysUserMapper.getUserVoById(userInfo.getSysUser().getUserId());vo.setRole(userVO.getRoleList().get(0).getRoleName());}vo.setIp(getIpAddr(request));sysLogInfoService.addSysLogInfo(vo);return R.ok();}/*** 获取指定用户全部信息* @return 用户信息*/@GetMapping("/info/{username}")public R info(@PathVariable String username, HttpServletRequest request) {SysUser user = userService.getOne(Wrappers.<SysUser>query().lambda().eq(SysUser::getUsername, username));if (user == null) {return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_USER_USERINFO_EMPTY, username));}SysLogInfo vo = new SysLogInfo();vo.setOperate("Get获取指定用户全部信息/user/"+username);vo.setIp(getIpAddr(request));sysLogInfoService.addSysLogInfo(vo);return R.ok(userService.findUserInfo(user));}/*** 获取当前用户登出* @return 用户信息*/@DeleteMapping(value = { "/logout" })public R logout( HttpServletRequest request) {if (Objects.isNull(SecurityUtils.getUser())) return R.ok();String token = WebUtils.getRequest().getHeader(CommonConstants.AUTHORIZATION).substring(7);/** 设置token失效*/if(null != token){JwtUtils.setTokenExpired(token);MyCacheManager.set(token, null);}SysLogInfo vo = new SysLogInfo();vo.setOperate("Delete退出系统/user/logout"+ token);vo.setIp(getIpAddr(request));sysLogInfoService.addSysLogInfo(vo);return R.ok();}/*** 获取当前用户全部信息* @return 用户信息*/@GetMapping(value = { "/info" })public R info() {String username = SecurityUtils.getUser().getUsername();SysUser user = userService.getOne(Wrappers.<SysUser>query().lambda().eq(SysUser::getUsername, username));if (user == null) {return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_USER_QUERY_ERROR));}return R.ok(userService.findUserInfo(user));}/*** 通过ID查询用户信息* @param id ID* @return 用户信息*/@GetMapping("/{id}")public R user(@PathVariable Long id) {return R.ok(userService.selectUserVoById(id));}/*** 根据用户名查询用户信息* @param username 用户名* @return*/@GetMapping("/details/{username}")public R user(@PathVariable String username) {SysUser condition = new SysUser();condition.setUsername(username);return R.ok(userService.getOne(new QueryWrapper<>(condition)));}/*** 删除用户信息* @param id ID* @return R*/@DeleteMapping("/{id}")@ApiOperation(value = "删除用户", notes = "根据ID删除用户")@ApiImplicitParam(name = "id", value = "用户ID", required = true, dataType = "int", paramType = "path")public R userDel(@PathVariable Long id, HttpServletRequest request) {SysUser sysUser = userService.getById(id);SysLogInfo vo = new SysLogInfo();vo.setOperate("Delete删除用户信息/id"+id);vo.setIp(getIpAddr(request));sysLogInfoService.addSysLogInfo(vo);return R.ok(userService.deleteUserById(sysUser));}/*** 添加用户* @param userDto 用户信息* @return success/false*/@PostMappingpublic R user(@RequestBody UserDTO userDto, HttpServletRequest request) {SysLogInfo vo = new SysLogInfo();vo.setOperate("Post添加用户/name"+userDto.getName());vo.setIp(getIpAddr(request));sysLogInfoService.addSysLogInfo(vo);return R.ok(userService.saveUser(userDto));}/*** 更新用户信息* @param userDto 用户信息* @return R*/@PutMappingpublic R updateUser(@Valid @RequestBody UserDTO userDto) {return R.ok(userService.updateUser(userDto));}/*** 分页查询用户* @param page 参数集* @param userDTO 查询参数列表* @return 用户集合*/@GetMapping("/page")public R getUserPage(Page page, UserDTO userDTO) {//根据当前登录人所在的区县 areaId 做权限控制, 市级用户看全部Long userId = SecurityUtils.getUser().getUserId();UserVO userVO = sysUserMapper.getUserVoById(userId);if(userVO.getAreaId() == 370300 || userVO.getUsername().equals("admin")){return R.ok(userService.getUsersWithRolePage(page, userDTO));}else {userDTO.setUserId(userId);return R.ok(userService.getUsersWithRolePage(page, userDTO));}}/*** 修改个人信息* @param userDto userDto* @return success/false*/@PutMapping("/edit")public R updateUserInfo(@Valid @RequestBody UserDTO userDto, HttpServletRequest request) {SysLogInfo vo = new SysLogInfo();vo.setOperate("Put修改个人信息/edit/"+userDto.getUserId());vo.setIp(getIpAddr(request));sysLogInfoService.addSysLogInfo(vo);return userService.updateUserInfo(userDto);}/*** @param username 用户名称* @return 上级部门用户列表*/@GetMapping("/ancestor/{username}")public R listAncestorUsers(@PathVariable String username) {return R.ok(userService.listAncestorUsers(username));}/*** 锁定指定用户* @param username 用户名* @return R*/@PutMapping("/lock/{username}")public R lockUser(@PathVariable String username) {SysLogInfo vo = new SysLogInfo();vo.setOperate("Put锁定指定用户/lock/username/"+username);sysLogInfoService.addSysLogInfo(vo);return userService.lockUser(username);}/*** 通过ID查询用户** @param id ID* @return 用户信息*/@GetMapping("/id/{id}")public R getByUserId(@PathVariable Long id) {return R.ok(userService.getById(id));}/*** 查询租户所有用户携带部门名称*/@GetMapping("/list/dept-name")public R listUsersWithDeptName(){return R.ok(userService.listUsersWithDeptName());}/*** 查询选择办理人/角色分页** @param userVO 查询参数列表* @return 用户及角色集合*/@GetMapping("/user-role/page")public R getUserRolePage(Page page, UserVO userVO) {return R.ok(userService.getUserRolePage(page, userVO));}/*** 查询租户所有用户*/@GetMapping("/list")public R listUsers(){if(null == SecurityUtils.getUser().getUserId()){return null;}//根据当前登录人所在的区县 areaId 做权限控制, 市级用户看全部Long userId = SecurityUtils.getUser().getUserId();UserVO userVO = sysUserMapper.getUserVoById(userId);if(userVO.getAreaId() == 370300){return R.ok(userService.list());}else {UserDTO userDTO = new UserDTO();userDTO.setUserId(userId);List<UserVO> userList =  sysUserMapper.selectVoListByScope(userDTO);return R.ok(userList);}}}

9、SysUserServiceImpl.java

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.symmetric.AES;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ewaycloud.jw.admin.api.dto.UserDTO;
import com.ewaycloud.jw.admin.api.entity.SysDept;
import com.ewaycloud.jw.admin.api.entity.SysMenu;
import com.ewaycloud.jw.admin.api.entity.SysRole;
import com.ewaycloud.jw.admin.api.entity.SysUserRole;
import com.ewaycloud.jw.admin.api.vo.RoleVO;
import com.ewaycloud.jw.admin.api.vo.UserVO;
import com.ewaycloud.jw.admin.config.LoginConfigProperties;
import com.ewaycloud.jw.admin.mapper.SysUserMapper;
import com.ewaycloud.jw.admin.service.*;
import com.ewaycloud.jw.common.core.config.MyCacheManager;
import com.ewaycloud.jw.common.core.constant.CommonConstants;
import com.ewaycloud.jw.common.core.exception.ErrorCodes;
import com.ewaycloud.jw.common.core.user.SysUser;
import com.ewaycloud.jw.common.core.user.UserInfo;
import com.ewaycloud.jw.common.core.util.JwtUtils;
import com.ewaycloud.jw.common.core.util.MsgUtils;
import com.ewaycloud.jw.common.core.util.R;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.validation.ValidationException;
import java.util.*;
import java.util.stream.Collectors;/**** @date 2017/10/31*/
@Slf4j
@Service
@AllArgsConstructor
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();private final SysMenuService sysMenuService;private final SysRoleService sysRoleService;private final SysDeptService sysDeptService;private final SysUserRoleService sysUserRoleService;private final LoginConfigProperties loginConfigProperties;private final CacheManager cacheManager;private final SysUserMapper sysUserMapper;//	private final RedisTemplate redisTemplate;private static final String KEY_ALGORITHM = "AES";private static int loginCount = 0;private static final int MAX_LOGIN_COUNT = 5;private static boolean isLocked = false;/*** 保存用户信息* @param userDto DTO 对象* @return success/fail*/@Override@Transactional(rollbackFor = Exception.class)public Boolean saveUser(UserDTO userDto) {SysUser sysUser = new SysUser();BeanUtils.copyProperties(userDto, sysUser);sysUser.setDelFlag(CommonConstants.STATUS_NORMAL);sysUser.setPassword(ENCODER.encode(userDto.getPassword()));baseMapper.insert(sysUser);// 如果角色为空,赋默认角色if (CollUtil.isEmpty(userDto.getRole())) {// 默认角色SysRole sysRole = sysRoleService.getOne(Wrappers.<SysRole>lambdaQuery().eq(SysRole::getRoleCode, 1));userDto.setRole(Collections.singletonList(sysRole.getRoleId()));}List<SysUserRole> userRoleList = userDto.getRole().stream().map(roleId -> {SysUserRole userRole = new SysUserRole();userRole.setUserId(sysUser.getUserId());userRole.setRoleId(roleId);return userRole;}).collect(Collectors.toList());return sysUserRoleService.saveBatch(userRoleList);}@Overridepublic UserInfo login(String username, String password) {if (isLocked) {System.out.println(username+ " 账户已锁定,请稍后再试");return null;}SysUser user = this.getOne(Wrappers.<SysUser>query().lambda().eq(SysUser::getUsername, username));if (user == null) {throw new ValidationException("用户名或密码错误");}if (CommonConstants.STATUS_LOCK.equals(user.getLockFlag())) {return null;}if (!ENCODER.matches(this.decryptAES(password), user.getPassword())) {loginCount++;System.out.println(username+ "密码错误,还剩余" + (MAX_LOGIN_COUNT - loginCount) + "次机会");if (loginCount < MAX_LOGIN_COUNT) {UserInfo userInfo = new UserInfo();userInfo.setLoginCount(loginCount);return userInfo;}if (loginCount >= MAX_LOGIN_COUNT) {System.out.println(username+ "密码错误次数过多,账户已被锁定");
//				isLocked = true;/** 锁定用户 */this.lockUser(username);UserInfo userInfo = new UserInfo();userInfo.setLoginCount(loginCount);return userInfo;}} else {System.out.println(username+ "登录成功!");loginCount = 0;// 放入缓存UserInfo userInfo = this.findUserInfo(user);UserInfo userInfoCache = new UserInfo();BeanUtil.copyProperties(userInfo, userInfoCache);//通userId查询用户的areaIdUserVO userVO = sysUserMapper.getUserVoById(user.getUserId());userInfo.setAreaId(userVO.getAreaId());userInfo.setAreaName(userVO.getAreaName());userInfo.setLoginCount(0);userInfoCache.setToken(JwtUtils.generateToken(username));/** 设置token */String token = JwtUtils.generateToken(username);userInfo.setToken(token);/** 本地缓存 1天 */
//			MyCacheManager.set(userInfo.getSysUser().getUserId().toString(), userInfoCache, 24*60*60*1000); //缓存用户信息1天,即 24*60*60*1000MyCacheManager.set(token, userInfoCache, 24*60*60*1000); //缓存用户信息1天,即 24*60*60*1000//			redisTemplate.opsForValue().set(token, userInfoCache, 86400000);
//			redisTemplate.opsForValue().set(username, token, 86400000);log.info("登录用户{}",userInfo.getSysUser().getUsername());
//			isLocked = false;return userInfo;}return null;}/*** 原文解密*/private String decryptAES(String password) {// 构建前端对应解密AES 因子AES aes = new AES(Mode.CFB, Padding.NoPadding,new SecretKeySpec(loginConfigProperties.getEncodeKey().getBytes(), KEY_ALGORITHM),new IvParameterSpec(loginConfigProperties.getEncodeKey().getBytes()));return aes.decryptStr(password);}/*** 通过查用户的全部信息* @param sysUser 用户* @return*/@Overridepublic UserInfo findUserInfo(SysUser sysUser) {UserInfo userInfo = new UserInfo();userInfo.setSysUser(sysUser);// 设置角色列表 (ID)List<Long> roleIds = sysRoleService.findRolesByUserId(sysUser.getUserId()).stream().map(RoleVO::getRoleId).collect(Collectors.toList());userInfo.setRoles(ArrayUtil.toArray(roleIds, Long.class));// 设置权限列表(menu.permission)Set<String> permissions = new HashSet<>();roleIds.forEach(roleId -> {List<String> permissionList = sysMenuService.findMenuByRoleId(roleId).stream().map(SysMenu::getPermission).filter(StrUtil::isNotEmpty).collect(Collectors.toList());permissions.addAll(permissionList);});userInfo.setPermissions(ArrayUtil.toArray(permissions, String.class));return userInfo;}/*** 分页查询用户信息(含有角色信息)* @param page 分页对象* @param userDTO 参数列表* @return*/@Overridepublic IPage getUsersWithRolePage(Page page, UserDTO userDTO) {return baseMapper.getUserVosPage(page, userDTO);}/*** 通过ID查询用户信息* @param id 用户ID* @return 用户信息*/@Overridepublic UserVO selectUserVoById(Long id) {return baseMapper.getUserVoById(id);}/*** 删除用户* @param sysUser 用户* @return Boolean*/@Override@CacheEvict(value = CommonConstants.USER_DETAILS, key = "#sysUser.username")public Boolean deleteUserById(SysUser sysUser) {sysUserRoleService.deleteByUserId(sysUser.getUserId());this.removeById(sysUser.getUserId());return Boolean.TRUE;}@Override@CacheEvict(value = CommonConstants.USER_DETAILS, key = "#userDto.username")public R<Boolean> updateUserInfo(UserDTO userDto) {UserVO userVO = baseMapper.getUserVoByUsername(userDto.getUsername());if (!ENCODER.matches(userDto.getPassword(), userVO.getPassword())) {log.info("原密码错误,修改个人信息失败:{}", userDto.getUsername());return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_USER_UPDATE_PASSWORDERROR));}SysUser sysUser = new SysUser();if (StrUtil.isNotBlank(userDto.getNewpassword1())) {sysUser.setPassword(ENCODER.encode(userDto.getNewpassword1()));}sysUser.setPhone(userDto.getPhone());sysUser.setUserId(userVO.getUserId());sysUser.setAvatar(userDto.getAvatar());sysUser.setNickname(userDto.getNickname());sysUser.setName(userDto.getName());sysUser.setEmail(userDto.getEmail());return R.ok(this.updateById(sysUser));}@Override@Transactional(rollbackFor = Exception.class)@CacheEvict(value = CommonConstants.USER_DETAILS, key = "#userDto.username")public Boolean updateUser(UserDTO userDto) {SysUser sysUser = new SysUser();BeanUtils.copyProperties(userDto, sysUser);
//		sysUser.setUpdateTime(new Date());sysUser.setUpdateTime(new Date());if (StrUtil.isNotBlank(userDto.getPassword())) {sysUser.setPassword(ENCODER.encode(userDto.getPassword()));}this.updateById(sysUser);sysUserRoleService.remove(Wrappers.<SysUserRole>update().lambda().eq(SysUserRole::getUserId, userDto.getUserId()));userDto.getRole().forEach(roleId -> {SysUserRole userRole = new SysUserRole();userRole.setUserId(sysUser.getUserId());userRole.setRoleId(roleId);userRole.insert();});return Boolean.TRUE;}/*** 查询上级部门的用户信息* @param username 用户名* @return R*/@Overridepublic List<SysUser> listAncestorUsers(String username) {SysUser sysUser = this.getOne(Wrappers.<SysUser>query().lambda().eq(SysUser::getUsername, username));SysDept sysDept = sysDeptService.getById(sysUser.getDeptId());if (sysDept == null) {return null;}Long parentId = sysDept.getParentId();return this.list(Wrappers.<SysUser>query().lambda().eq(SysUser::getDeptId, parentId));}/*** 锁定用户* @param username 用户名* @return*/@Override
//	@CacheEvict(value = CommonConstants.USER_DETAILS, key = "#username")public R<Boolean> lockUser(String username) {SysUser sysUser = baseMapper.selectOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, username));sysUser.setLockFlag(CommonConstants.STATUS_LOCK);baseMapper.updateById(sysUser);return R.ok();}@Overridepublic List<SysUser> listUsersWithDeptName() {List<SysUser> sysUsers = this.list(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getLockFlag, CommonConstants.STATUS_NORMAL));// 拼接部门信息if (CollUtil.isEmpty(sysUsers)) {return sysUsers;}List<SysDept> sysDepts = sysDeptService.list();sysUsers.forEach(user -> {SysDept sysDept = sysDepts.stream().filter(f -> f.getDeptId().equals(user.getDeptId())).findAny().get();user.setName(user.getName() + "-" + sysDept.getName());});return sysUsers;}@Overridepublic IPage getUserRolePage(Page page, UserVO userVO) {return baseMapper.getUserRolePage(page, userVO);}@Overridepublic List<UserVO> listUsersByRoleIds(List<Long> roleIds) {List<SysUserRole> userRoles = sysUserRoleService.list(Wrappers.<SysUserRole>lambdaQuery().in(SysUserRole::getRoleId,roleIds));List<Long> list = userRoles.stream().map(SysUserRole::getUserId).collect(Collectors.toList());if (CollUtil.isEmpty(list)) return Collections.emptyList();return this.listByIds(list).stream().map(m->{UserVO userVO = new UserVO();BeanUtil.copyProperties(m,userVO);List<Long> userRoleIds = userRoles.stream().filter(f -> f.getUserId().equals(m.getUserId())).map(SysUserRole::getRoleId).collect(Collectors.toList());List<SysRole> sysRoles = sysRoleService.listByIds(userRoleIds);userVO.setRoleList(sysRoles);return userVO;}).collect(Collectors.toList());}@Overridepublic List<SysUser> listUsersByRoleId(Long roleId) {List<Long> list = sysUserRoleService.list(Wrappers.<SysUserRole>lambdaQuery().eq(SysUserRole::getRoleId, roleId)).stream().map(SysUserRole::getUserId).collect(Collectors.toList());return CollUtil.isEmpty(list) ? Collections.emptyList() : this.list(Wrappers.<SysUser>lambdaQuery().in(SysUser::getUserId, list).eq(SysUser::getLockFlag, CommonConstants.STATUS_NORMAL));}}

10、SysUserService.java

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ewaycloud.jw.admin.api.dto.UserDTO;
import com.ewaycloud.jw.common.core.user.UserInfo;
import com.ewaycloud.jw.common.core.user.SysUser;
import com.ewaycloud.jw.admin.api.vo.UserVO;
import com.ewaycloud.jw.common.core.util.R;import java.util.List;/*** * @date 2017/10/31*/
public interface SysUserService extends IService<SysUser> {/*** 用户登录* @param username 用户名* @param password 密码* @return UserInfo*/UserInfo login(String username, String password);/*** 查询用户信息* @param sysUser 用户* @return userInfo*/UserInfo findUserInfo(SysUser sysUser);/*** 分页查询用户信息(含有角色信息)* @param page 分页对象* @param userDTO 参数列表* @return*/IPage getUsersWithRolePage(Page page, UserDTO userDTO);/*** 删除用户* @param sysUser 用户* @return boolean*/Boolean deleteUserById(SysUser sysUser);/*** 更新当前用户基本信息* @param userDto 用户信息* @return Boolean*/R<Boolean> updateUserInfo(UserDTO userDto);/*** 更新指定用户信息* @param userDto 用户信息* @return*/Boolean updateUser(UserDTO userDto);/*** 通过ID查询用户信息* @param id 用户ID* @return 用户信息*/UserVO selectUserVoById(Long id);/*** 查询上级部门的用户信息* @param username 用户名* @return R*/List<SysUser> listAncestorUsers(String username);/*** 保存用户信息* @param userDto DTO 对象* @return success/fail*/Boolean saveUser(UserDTO userDto);/*** 锁定用户* @param username* @return*/R<Boolean> lockUser(String username);/*** 查询租户所有用户携带部门名称*/List<SysUser> listUsersWithDeptName();/*** 查询选择办理人/角色分页** @param userVO 参数列表*/IPage getUserRolePage(Page page, UserVO userVO);/*** 通过角色ID查询用户集合** @param roleIds 角色ID* @return 用户信息*/List<UserVO> listUsersByRoleIds(List<Long> roleIds);/*** 通过角色ID查询用户集合** @param roleId 角色ID* @return 用户信息*/List<SysUser> listUsersByRoleId(Long roleId);}

11、前端:user.js

import {getStore, setStore} from '@/util/store'
import {isURL, validatenull} from '@/util/validate'
import {loginByUsername, getUserInfo, logout} from '@/api/login'
import {deepClone, encryption} from '@/util'
import webiste from '@/const/website'
import {getMenu, getTopMenu} from '@/api/admin/menu'function addPath(ele, first) {const menu = webiste.menuconst propsConfig = menu.propsconst propsDefault = {label: propsConfig.label || 'name',path: propsConfig.path || 'path',icon: propsConfig.icon || 'icon',children: propsConfig.children || 'children'}const icon = ele[propsDefault.icon]ele[propsDefault.icon] = validatenull(icon) ? menu.iconDefault : iconconst isChild = ele[propsDefault.children] && ele[propsDefault.children].length !== 0if (!isChild) ele[propsDefault.children] = []if (!isChild && first && !isURL(ele[propsDefault.path])) {ele[propsDefault.path] = ele[propsDefault.path] + '/index'} else {ele[propsDefault.children].forEach(child => {addPath(child)})}
}const user = {state: {userInfo: getStore({name: 'userInfo'}) || {},permissions: getStore({name: 'permissions'}) || [],roles: [],menu: getStore({name: 'menu'}) || [],menuAll: [],userId: getStore({name: 'userId'}) || ''},actions: {// 根据用户名登录LoginByUsername({commit}, userInfo) {let user = {}if (webiste.passwordEnc) {user = encryption({data: userInfo,key: '1234567887654321',param: ['password']})} else {user = userInfo}return new Promise((resolve, reject) => {loginByUsername(user.username, user.password).then(response => {const data = response.data.data || {}commit('SET_USER_INFO', data.sysUser)commit('SET_ROLES', data.roles || [])commit('SET_PERMISSIONS', data.permissions || [])commit('SET_USERID', data.sysUser.userId)commit('CLEAR_LOCK')commit('token', data.token)localStorage.setItem('areaName', data.areaName);localStorage.setItem('areaId', data.areaId);localStorage.setItem('token', data.token);resolve()}).catch(error => {reject(error)})})},// 查询用户信息GetUserInfo({commit}) {return new Promise((resolve, reject) => {getUserInfo().then((res) => {const data = res.data.data || {}commit('SET_USER_INFO', data.sysUser)commit('SET_ROLES', data.roles || [])commit('SET_PERMISSIONS', data.permissions || [])localStorage.setItem('areaName', data.areaName);resolve(data)}).catch(() => {reject()})})},// 登出LogOut({commit}) {return new Promise((resolve, reject) => {logout().then(() => {commit('SET_MENU', [])commit('SET_PERMISSIONS', [])commit('SET_USER_INFO', {})commit('SET_USERID', '')commit('SET_ROLES', [])commit('DEL_ALL_TAG')commit('CLEAR_LOCK')resolve()}).catch(error => {reject(error)})})},// 获取系统菜单GetMenu({commit}, obj) {// 记录用户点击顶部信息,保证刷新的时候不丢失commit('LIKE_TOP_MENUID', obj)return new Promise(resolve => {getMenu(obj.id).then((res) => {const data = res.data.dataconst menu = deepClone(data)menu.forEach(ele => {addPath(ele)})let type = obj.typecommit('SET_MENU', {type, menu})resolve(menu)}).catch(error => {reject(error)})})},//顶部菜单GetTopMenu() {return new Promise(resolve => {getTopMenu().then((res) => {const data = res.data.data || []resolve(data)}).catch(error => {reject(error)})})}},mutations: {SET_USERID: (state, userId) => {state.userId = userIdsetStore({name: 'userId',content: state.userId,type: 'session'})},SET_USER_INFO: (state, userInfo) => {state.userInfo = userInfosetStore({name: 'userInfo',content: userInfo,type: 'session'})},SET_MENU: (state, params = {}) => {let {menu, type} = params;if (type !== false) state.menu = menusetStore({name: 'menu',content: menu,type: 'session'})},SET_MENU_ALL: (state, menuAll) => {state.menuAll = menuAll},SET_ROLES: (state, roles) => {state.roles = roles},SET_PERMISSIONS: (state, permissions) => {const list = {}for (let i = 0; i < permissions.length; i++) {list[permissions[i]] = true}state.permissions = listsetStore({name: 'permissions',content: list,type: 'session'})}}}
export default user

12、前端:axios.js

import axios from 'axios'
import {paramsFilter,serialize
} from '@/util'
import NProgress from 'nprogress' // progress bar
import errorCode from '@/const/errorCode'
import {Message,MessageBox
} from 'element-ui'
import 'nprogress/nprogress.css'
import qs from 'qs'
import store from '@/store' // progress bar style
import * as aesSecure from "./aes/CryptoJS";
import {dataFilter
} from "@/const/flow";
import BigNumber from 'bignumber.js';axios.defaults.timeout = 300000
// 返回其他状态吗
axios.defaults.validateStatus = function(status) {return status >= 200 && status <= 500 // 默认的
}
// 跨域请求,允许保存cookie
axios.defaults.withCredentials = true
// NProgress Configuration
NProgress.configure({showSpinner: false
})// HTTPrequest拦截
axios.interceptors.request.use(config => {NProgress.start() // start progress barconst userId = store.getters.userIdif (userId) {// config.headers['USER-ID'] = userId // 用户IDconfig.headers['authorization'] = 'Bearer ' + localStorage.getItem('token') // token}if (aesSecure.dataAesEnabled === true) config.headers['Content-Type'] = "application/json;charset=UTF-8";// 校验参数、加密if (typeof config.data === 'object' && config.responseType !== "arraybuffer") {for (const dataKey in config.data) {if (typeof config.data[dataKey] === 'number' && !isNaN(config.data[dataKey])) {// console.log(dataKey)// console.log(config.data[dataKey])// console.log(new BigNumber(config.data[dataKey] + '').toString())config.data[dataKey] = new BigNumber(config.data[dataKey] + '');}}// 这里给后端传参的时候会删除是空的字段,导致只能修改字段,不能删除字段// if (aesSecure.dataAesEnabled === false) config.data = dataFilter(config.headers, config.data)// else config.data = aesSecure.Encrypt(JSON.stringify(dataFilter(config.headers, config.data)))}if (typeof config.params === 'object' && config.responseType !== "arraybuffer") config.params = dataFilter(config.headers, config.params)// serialize为true开启序列化if (config.method === 'post' && config.headers.serialize) {config.data = serialize(config.data)delete config.data.serialize}if (config.method === 'get') {config.paramsSerializer = function(params) {return qs.stringify(paramsFilter(params), {arrayFormat: 'repeat'})}}return config
}, error => {return Promise.reject(error)
})// HTTPresponse拦截
axios.interceptors.response.use(res => {NProgress.done()// 返回值解密if (aesSecure.dataAesEnabled === true && res.config.responseType !== "arraybuffer") res.data = JSON.parse(aesSecure.Decrypt(res.data));const status = Number(res.status) || 200const message = res.data.msg || errorCode[status] || errorCode['default']// 后台定义 424if (status === 424) {MessageBox.confirm('令牌状态已过期,请点击重新登录', '系统提示', {confirmButtonText: '重新登录',cancelButtonText: '取消',type: 'warning'}).then(() => {store.dispatch('LogOut').then(() => {// 刷新登录页面,避免多次弹框window.location.reload()})}).catch(() => {});return}if (status !== 200 || res.data.code === 1) {Message({message: message,type: 'error'})return Promise.reject(new Error(message))}return res
}, error => {// 处理 503 网络异常let response = error.response;if (response && response.status === 503) {Message({message: response.data.msg,type: 'error'})}NProgress.done()return Promise.reject(new Error(error))
})export default axios

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/461967.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数字IC后端实现之Innovus Place跑完density爆涨案例分析

下图所示为咱们社区a7core后端训练营学员的floorplan。 数字IC后端实现 | Innovus各个阶段常用命令汇总 该学员跑placement前density是59.467%&#xff0c;但跑完place后density飙升到87.68%。 仔细查看place过程中的log就可以发现Density一路飙升&#xff01; 数字IC后端物…

大数据新视界 -- 大数据大厂之大数据环境下的网络安全态势感知

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

如何解决mingw64安装后配置完环境变量仍然执行不了gcc命令以及Vscode中的环境路径配置中找不到gcc

配置环境变量教程很多&#xff0c;就不多说&#xff0c;说下耗费一小时解决的问题&#xff1a;mingw64安装后配置完环境变量仍然执行不了gcc命令 配置 了N次了&#xff0c;都还是在终端找不到指令&#xff0c;然后&#xff0c;将路径放到第一个&#xff0c;然后再看下&#xf…

【AI日记】24.11.01 LangChain、openai api和github copilot

【AI论文解读】【AI知识点】【AI小项目】【AI战略思考】【AI日记】 工作 工作1 内容&#xff1a;学习deeplearning.ai的免费课程地址&#xff1a;LangChain Chat with Your DataB站地址&#xff1a;https://www.bilibili.com/video/BV148411D7d2时间&#xff1a;2小时评估&am…

位运算算法及习题 ,丢弃的数字 , 两整数之和 ,只出现一次的数字II

文章目录 位运算基础1.基础位运算2. 给一个数n,确定他的二进制位中的第x为是0还是13.将一个数n的二进制表示的第x位修改为14.将一个数n的二进制表示的第x位修改为05.位图的思想6. 提取一个数n二进制表示中最右侧的17. 去掉一个数n二进制表示中最右侧的18. 异或运算的运算律 丢弃…

使用form表单的action提交并接收后端返回的消息

使用form表单的action提交表单是同步提交的方式&#xff0c;会跳转页面&#xff0c;所以无法获取后端返回来到消息。这样描述或许没有太大感觉&#xff0c;如果我要通过表单的方式上传文件&#xff0c;并接收后台返回来的响应数据&#xff1b;这样说是不是就感同深受了呢。 1.…

曹操出行借助 ApsaraMQ for Kafka Serverless 提升效率,成本节省超 20%

本文整理于 2024 年云栖大会主题演讲《云消息队列 ApsaraMQ Serverless 演进》&#xff0c;杭州优行科技有限公司消息中间件负责人王智洋分享 ApsaraMQ for Kafka Serverless 助力曹操出行实现成本优化和效率提升的实践经验。 曹操出行&#xff1a;科技驱动共享出行未来 曹操…

2024年10月文章一览

2024年10月编程人总共更新了21篇文章&#xff1a; 1.2024年9月文章一览 2.《Programming from the Ground Up》阅读笔记&#xff1a;p147-p180 3.《Programming from the Ground Up》阅读笔记&#xff1a;p181-p216 4.《Programming from the Ground Up》阅读笔记&#xff…

【果蔬识别】Python+卷积神经网络算法+深度学习+人工智能+机器学习+TensorFlow+计算机课设项目+算法模型

一、介绍 果蔬识别系统&#xff0c;本系统使用Python作为主要开发语言&#xff0c;通过收集了12种常见的水果和蔬菜&#xff08;‘土豆’, ‘圣女果’, ‘大白菜’, ‘大葱’, ‘梨’, ‘胡萝卜’, ‘芒果’, ‘苹果’, ‘西红柿’, ‘韭菜’, ‘香蕉’, ‘黄瓜’&#xff09;…

Partition架构

优质博文&#xff1a;IT-BLOG-CN Partition架构 【1】结构&#xff1a; Region至少3个Zone&#xff0c;Zone内至少两个Partition&#xff0c;Partition内至少1个K8S Member Cluster&#xff1b; 【2】故障域&#xff1a; 故障域及核心链路至少Zone内收敛&#xff0c;甚至Part…

xlrd.biffh.XLRDError: Excel xlsx file; not supported

文章目录 一、问题报错二、报错原因三、解决思路四、解决方法 一、问题报错 在处理Excel文件时&#xff0c;特别是当我们使用Python的xlrd库来读取.xlsx格式的文件&#xff0c;偶尔会遇到这样一个错误&#xff1a;“xlrd.biffh.XLRDError: Excel xlsx file; not supported”。…

Java XML一口气讲完!(p≧w≦q)

Java XML API Java XML教程 - Java XML API SAX API 下面是关键的SAX API的摘要: 类用法SAXParserFactory创建由系统属性javax.xml.parsers.SAXParserFactory确定的解析器的实例。SAXParserSAXParser接口定义了几个重载的parse()方法。SAXReaderSAXParser包装一个SAXReader…

CTF顶级工具与资源

《Web安全》http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247484238&idx1&snca66551c31e37b8d726f151265fc9211&chksmc0e47a12f793f3049fefde6e9ebe9ec4e2c7626b8594511bd314783719c216bd9929962a71e6&scene21#wechat_redirect 《网安面试指南》h…

腾讯云视频文件上传云存储时自动将mp4格式转码成m3u8

针对问题&#xff1a; 弱网环境下或手机网络播放mp4格式视频卡顿。 存储环境&#xff1a;腾讯云对象存储。 处理流程&#xff1a; 1&#xff1a;登录腾讯云控制台&#xff0c;进入对象存储服务&#xff0c;找到对应的存储桶&#xff0c;点击进入。 在任务与工作流选项卡中找…

【AIGC】逆向拆解OpenAI官方提示词Prompt技巧:高效提升ChatGPT输出质量

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AIGC | ChatGPT 文章目录 &#x1f4af;前言&#x1f4af;OpenAI官方提示词的介绍OpenAI官方提示词的结构与组成如何通过分析提示词找到其核心组件 &#x1f4af;OpenAI官方提示词分析案例一&#xff1a;制定教学计划案例二&…

Linux之nfs服务器和dns服务器

NFS服务器 NFS&#xff08;Network File System&#xff0c;网络文件系统)&#xff0c;NFS服务器可以让PC将网络中的NFS服务器共享的目录挂载到本地端的文件系统中&#xff0c;而在本地端的系统 中看来&#xff0c;那个远程主机的目录就好像是自己的一个磁盘分区一样。 注&am…

【机器学习】25. 聚类-DBSCAN(density base)

聚类-DBSCAN-density base 1. 介绍2. 实现案例计算 3. K-dist4. 变化密度5. 优缺点 1. 介绍 DBSCAN – Density-Based Spatial Clustering of Applications with Noise 与K-Means查找圆形簇相比&#xff0c;DBSCAN可以查找任意形状和复杂形状的簇&#xff0c;如S形、椭圆、半圆…

计组-层次化存储结构

这里主要看存储的整体结构&#xff0c;cache&#xff0c;内存 这里看存储结构是按什么样的层次来划分存储结构&#xff0c;速度由慢到快&#xff0c;容量由大到小&#xff0c;这是基于性价比的考虑&#xff0c;所以分为多级多层次&#xff0c;可以做到提高速度的同时没有增加多…

奇瑞不客气智驾 晚不晚?

文/孔文清 一直很好奇&#xff1a; 尹同跃董事长的金句“智驾不客气”&#xff0c;应该怎么翻译成英语&#xff1f; 谷俊丽的演讲PPT给了我答案&#xff1a; All in Ai Cars ——全力以赴、全情投入智能化汽车。 谷俊丽是奇瑞全球创新大会上最兴奋的人之一&#xff0c;有一种闭…

【万兴科技-注册_登录安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…