[add]支持其他平台通过ApiKey调用系统相关接口
| | |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-cache</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-web</artifactId> |
| | | </dependency> |
| | | <dependency> |
| | |
| | | import org.springframework.boot.builder.SpringApplicationBuilder; |
| | | import org.springframework.boot.web.servlet.ServletComponentScan; |
| | | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; |
| | | import org.springframework.cache.annotation.EnableCaching; |
| | | import org.springframework.context.ConfigurableApplicationContext; |
| | | import org.springframework.scheduling.annotation.EnableScheduling; |
| | | |
| | |
| | | @ServletComponentScan("com.genersoft.iot.vmp.conf") |
| | | @SpringBootApplication |
| | | @EnableScheduling |
| | | @EnableCaching |
| | | public class VManageBootstrap extends SpringBootServletInitializer { |
| | | |
| | | private final static Logger logger = LoggerFactory.getLogger(VManageBootstrap.class); |
| | |
| | | if (StringUtils.isBlank(jwt)) { |
| | | jwt = request.getParameter(JwtUtils.getHeader()); |
| | | if (StringUtils.isBlank(jwt)) { |
| | | chain.doFilter(request, response); |
| | | return; |
| | | jwt = request.getHeader(JwtUtils.getApiKeyHeader()); |
| | | if (StringUtils.isBlank(jwt)) { |
| | | chain.doFilter(request, response); |
| | | return; |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | package com.genersoft.iot.vmp.conf.security; |
| | | |
| | | import com.genersoft.iot.vmp.conf.security.dto.JwtUser; |
| | | import com.genersoft.iot.vmp.service.IUserApiKeyService; |
| | | import com.genersoft.iot.vmp.service.IUserService; |
| | | import com.genersoft.iot.vmp.storager.dao.dto.User; |
| | | import com.genersoft.iot.vmp.storager.dao.dto.UserApiKey; |
| | | import org.jose4j.jwk.JsonWebKey; |
| | | import org.jose4j.jwk.JsonWebKeySet; |
| | | import org.jose4j.jwk.RsaJsonWebKey; |
| | | import org.jose4j.jwk.RsaJwkGenerator; |
| | | import org.jose4j.jws.AlgorithmIdentifiers; |
| | |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.io.IOException; |
| | | import java.net.URI; |
| | | import java.net.URISyntaxException; |
| | | import java.net.URL; |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.nio.file.Files; |
| | | import java.nio.file.Path; |
| | | import java.nio.file.Paths; |
| | | import java.time.LocalDateTime; |
| | | import java.time.ZoneOffset; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | @Component |
| | | public class JwtUtils implements InitializingBean { |
| | |
| | | |
| | | public static final String HEADER = "access-token"; |
| | | |
| | | public static final String API_KEY_HEADER = "api-key"; |
| | | |
| | | private static final String AUDIENCE = "Audience"; |
| | | |
| | | private static final String keyId = "3e79646c4dbc408383a9eed09f2b85ae"; |
| | |
| | | /** |
| | | * tokenè¿ææ¶é´(åé) |
| | | */ |
| | | public static final long expirationTime = 30 * 24 * 60; |
| | | public static final long EXPIRATION_TIME = 30 * 24 * 60; |
| | | |
| | | private static RsaJsonWebKey rsaJsonWebKey; |
| | | |
| | | private static IUserService userService; |
| | | |
| | | private static IUserApiKeyService userApiKeyService; |
| | | |
| | | public static String getApiKeyHeader() { |
| | | return API_KEY_HEADER; |
| | | } |
| | | |
| | | @Resource |
| | | public void setUserService(IUserService userService) { |
| | | JwtUtils.userService = userService; |
| | | } |
| | | |
| | | @Resource |
| | | public void setUserApiKeyService(IUserApiKeyService userApiKeyService) { |
| | | JwtUtils.userApiKeyService = userApiKeyService; |
| | | } |
| | | |
| | | @Override |
| | |
| | | * @throws JoseException JoseException |
| | | */ |
| | | private RsaJsonWebKey generateRsaJsonWebKey() throws JoseException { |
| | | // çæä¸ä¸ªRSAå¯é¥å¯¹ï¼è¯¥å¯é¥å¯¹å°ç¨äºJWTçç¾ååéªè¯ï¼å
è£
å¨JWKä¸ |
| | | RsaJsonWebKey rsaJsonWebKey = RsaJwkGenerator.generateJwk(2048); |
| | | // ç»JWKä¸ä¸ªå¯é¥ID |
| | | rsaJsonWebKey.setKeyId(keyId); |
| | | RsaJsonWebKey rsaJsonWebKey = null; |
| | | try { |
| | | URL url = getClass().getClassLoader().getResource("jwk.json"); |
| | | if (url != null) { |
| | | URI uri = url.toURI(); |
| | | Path path = Paths.get(uri); |
| | | if (Files.exists(path)) { |
| | | byte[] allBytes = Files.readAllBytes(path); |
| | | String jwkJson = new String(allBytes, StandardCharsets.UTF_8); |
| | | final JsonWebKeySet jsonWebKeySet = new JsonWebKeySet(jwkJson); |
| | | List<JsonWebKey> jsonWebKeys = jsonWebKeySet.getJsonWebKeys(); |
| | | if (!jsonWebKeys.isEmpty()) { |
| | | JsonWebKey jsonWebKey = jsonWebKeys.get(0); |
| | | if (jsonWebKey instanceof RsaJsonWebKey) { |
| | | rsaJsonWebKey = (RsaJsonWebKey) jsonWebKey; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } catch (URISyntaxException | IOException e) { |
| | | // ignored |
| | | } |
| | | if (rsaJsonWebKey == null) { |
| | | // çæä¸ä¸ªRSAå¯é¥å¯¹ï¼è¯¥å¯é¥å¯¹å°ç¨äºJWTçç¾ååéªè¯ï¼å
è£
å¨JWKä¸ |
| | | rsaJsonWebKey = RsaJwkGenerator.generateJwk(2048); |
| | | // ç»JWKä¸ä¸ªå¯é¥ID |
| | | rsaJsonWebKey.setKeyId(keyId); |
| | | } |
| | | return rsaJsonWebKey; |
| | | } |
| | | |
| | | public static String createToken(String username) { |
| | | public static String createToken(String username, Long expirationTime, Map<String, Object> extra) { |
| | | try { |
| | | /* |
| | | * âissâ (issuer) åè¡äºº |
| | |
| | | claims.setGeneratedJwtId(); |
| | | claims.setIssuedAtToNow(); |
| | | // 令çå°è¿æçæ¶é´ åé |
| | | claims.setExpirationTimeMinutesInTheFuture(expirationTime); |
| | | if (expirationTime != null) { |
| | | claims.setExpirationTimeMinutesInTheFuture(expirationTime); |
| | | } |
| | | claims.setNotBeforeMinutesInThePast(0); |
| | | claims.setSubject("login"); |
| | | claims.setAudience(AUDIENCE); |
| | | //æ·»å èªå®ä¹åæ°,å¿
é¡»æ¯å符串类å |
| | | claims.setClaim("userName", username); |
| | | |
| | | if (extra != null) { |
| | | extra.forEach(claims::setClaim); |
| | | } |
| | | //jws |
| | | JsonWebSignature jws = new JsonWebSignature(); |
| | | //ç¾åç®æ³RS256 |
| | |
| | | } catch (JoseException e) { |
| | | logger.error("[Tokençæå¤±è´¥]ï¼ {}", e.getMessage()); |
| | | } |
| | | |
| | | return null; |
| | | } |
| | | |
| | | public static String createToken(String username, Long expirationTime) { |
| | | return createToken(username, expirationTime, null); |
| | | } |
| | | |
| | | public static String createToken(String username) { |
| | | return createToken(username, EXPIRATION_TIME); |
| | | } |
| | | |
| | | public static String getHeader() { |
| | |
| | | |
| | | try { |
| | | JwtConsumer consumer = new JwtConsumerBuilder() |
| | | .setRequireExpirationTime() |
| | | .setMaxFutureValidityInMinutes(5256000) |
| | | //.setRequireExpirationTime() |
| | | //.setMaxFutureValidityInMinutes(5256000) |
| | | .setAllowedClockSkewInSeconds(30) |
| | | .setRequireSubject() |
| | | //.setExpectedIssuer("") |
| | |
| | | |
| | | JwtClaims claims = consumer.processToClaims(token); |
| | | NumericDate expirationTime = claims.getExpirationTime(); |
| | | // 夿æ¯å¦å³å°è¿æ, é»è®¤å©ä½æ¶é´å°äº5åéæªå³å°è¿æ |
| | | // å©ä½æ¶é´ ï¼ç§ï¼ |
| | | long timeRemaining = LocalDateTime.now().toEpochSecond(ZoneOffset.ofHours(8)) - expirationTime.getValue(); |
| | | if (timeRemaining < 5 * 60) { |
| | | jwtUser.setStatus(JwtUser.TokenStatus.EXPIRING_SOON); |
| | | if (expirationTime != null) { |
| | | // 夿æ¯å¦å³å°è¿æ, é»è®¤å©ä½æ¶é´å°äº5åéæªå³å°è¿æ |
| | | // å©ä½æ¶é´ ï¼ç§ï¼ |
| | | long timeRemaining = LocalDateTime.now().toEpochSecond(ZoneOffset.ofHours(8)) - expirationTime.getValue(); |
| | | if (timeRemaining < 5 * 60) { |
| | | jwtUser.setStatus(JwtUser.TokenStatus.EXPIRING_SOON); |
| | | } else { |
| | | jwtUser.setStatus(JwtUser.TokenStatus.NORMAL); |
| | | } |
| | | } else { |
| | | jwtUser.setStatus(JwtUser.TokenStatus.NORMAL); |
| | | } |
| | | |
| | | Long apiKeyId = claims.getClaimValue("apiKeyId", Long.class); |
| | | if (apiKeyId != null) { |
| | | UserApiKey userApiKey = userApiKeyService.getUserApiKeyById(apiKeyId.intValue()); |
| | | if (userApiKey == null || !userApiKey.isEnable()) { |
| | | jwtUser.setStatus(JwtUser.TokenStatus.EXPIRED); |
| | | } |
| | | } |
| | | |
| | | String username = (String) claims.getClaimValue("userName"); |
| | | User user = userService.getUserByUsername(username); |
| | | |
New file |
| | |
| | | package com.genersoft.iot.vmp.service; |
| | | |
| | | import com.genersoft.iot.vmp.storager.dao.dto.UserApiKey; |
| | | import com.github.pagehelper.PageInfo; |
| | | |
| | | public interface IUserApiKeyService { |
| | | int addApiKey(UserApiKey userApiKey); |
| | | |
| | | boolean isApiKeyExists(String apiKey); |
| | | |
| | | PageInfo<UserApiKey> getUserApiKeys(int page, int count); |
| | | |
| | | int enable(Integer id); |
| | | |
| | | int disable(Integer id); |
| | | |
| | | int remark(Integer id, String remark); |
| | | |
| | | int delete(Integer id); |
| | | |
| | | UserApiKey getUserApiKeyById(Integer id); |
| | | |
| | | int reset(Integer id, String apiKey); |
| | | |
| | | } |
| | |
| | | |
| | | boolean changePassword(int id, String password); |
| | | |
| | | User getUserById(int id); |
| | | |
| | | User getUserByUsername(String username); |
| | | |
| | | int addUser(User user); |
New file |
| | |
| | | package com.genersoft.iot.vmp.service.impl; |
| | | |
| | | import com.baomidou.dynamic.datasource.annotation.DS; |
| | | import com.genersoft.iot.vmp.service.IUserApiKeyService; |
| | | import com.genersoft.iot.vmp.storager.dao.UserApiKeyMapper; |
| | | import com.genersoft.iot.vmp.storager.dao.dto.UserApiKey; |
| | | import com.github.pagehelper.PageHelper; |
| | | import com.github.pagehelper.PageInfo; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.cache.annotation.CacheEvict; |
| | | import org.springframework.cache.annotation.Cacheable; |
| | | import org.springframework.data.redis.core.RedisTemplate; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.List; |
| | | |
| | | @Service |
| | | @DS("master") |
| | | public class UserApiKeyServiceImpl implements IUserApiKeyService { |
| | | |
| | | @Autowired |
| | | UserApiKeyMapper userApiKeyMapper; |
| | | |
| | | @Autowired |
| | | private RedisTemplate<Object, Object> redisTemplate; |
| | | |
| | | @Override |
| | | public int addApiKey(UserApiKey userApiKey) { |
| | | return userApiKeyMapper.add(userApiKey); |
| | | } |
| | | |
| | | @Override |
| | | public boolean isApiKeyExists(String apiKey) { |
| | | return userApiKeyMapper.isApiKeyExists(apiKey); |
| | | } |
| | | |
| | | @Override |
| | | public PageInfo<UserApiKey> getUserApiKeys(int page, int count) { |
| | | PageHelper.startPage(page, count); |
| | | List<UserApiKey> userApiKeys = userApiKeyMapper.getUserApiKeys(); |
| | | return new PageInfo<>(userApiKeys); |
| | | } |
| | | |
| | | @Cacheable(cacheNames = "userApiKey", key = "#id", sync = true) |
| | | @Override |
| | | public UserApiKey getUserApiKeyById(Integer id) { |
| | | return userApiKeyMapper.selectById(id); |
| | | } |
| | | |
| | | @CacheEvict(cacheNames = "userApiKey", key = "#id") |
| | | @Override |
| | | public int enable(Integer id) { |
| | | return userApiKeyMapper.enable(id); |
| | | } |
| | | |
| | | @CacheEvict(cacheNames = "userApiKey", key = "#id") |
| | | @Override |
| | | public int disable(Integer id) { |
| | | return userApiKeyMapper.disable(id); |
| | | } |
| | | |
| | | @CacheEvict(cacheNames = "userApiKey", key = "#id") |
| | | @Override |
| | | public int remark(Integer id, String remark) { |
| | | return userApiKeyMapper.remark(id, remark); |
| | | } |
| | | |
| | | @CacheEvict(cacheNames = "userApiKey", key = "#id") |
| | | @Override |
| | | public int delete(Integer id) { |
| | | return userApiKeyMapper.delete(id); |
| | | } |
| | | |
| | | @CacheEvict(cacheNames = "userApiKey", key = "#id") |
| | | @Override |
| | | public int reset(Integer id, String apiKey) { |
| | | return userApiKeyMapper.apiKey(id, apiKey); |
| | | } |
| | | |
| | | } |
| | |
| | | } |
| | | |
| | | @Override |
| | | public User getUserById(int id) { |
| | | return userMapper.selectById(id); |
| | | } |
| | | |
| | | @Override |
| | | public User getUserByUsername(String username) { |
| | | return userMapper.getUserByUsername(username); |
| | | } |
New file |
| | |
| | | package com.genersoft.iot.vmp.storager.dao; |
| | | |
| | | import com.genersoft.iot.vmp.storager.dao.dto.UserApiKey; |
| | | import org.apache.ibatis.annotations.*; |
| | | import org.springframework.stereotype.Repository; |
| | | |
| | | import java.util.List; |
| | | |
| | | @Mapper |
| | | @Repository |
| | | public interface UserApiKeyMapper { |
| | | |
| | | @SelectKey(statement = "SELECT LAST_INSERT_ID() AS id", keyProperty = "id", before = false, resultType = Integer.class) |
| | | @Insert("INSERT INTO wvp_user_api_key (user_id, app, api_key, expired_at, remark, enable, create_time, update_time) VALUES" + |
| | | "(#{userId}, #{app}, #{apiKey}, #{expiredAt}, #{remark}, #{enable}, #{createTime}, #{updateTime})") |
| | | int add(UserApiKey userApiKey); |
| | | |
| | | @Update(value = {"<script>" + |
| | | "UPDATE wvp_user_api_key " + |
| | | "SET update_time = #{updateTime} " + |
| | | "<if test=\"app != null\">, app = #{app}</if>" + |
| | | "<if test=\"apiKey != null\">, api_key = #{apiKey}</if>" + |
| | | "<if test=\"expiredAt != null\">, expired_at = #{expiredAt}</if>" + |
| | | "<if test=\"remark != null\">, username = #{remark}</if>" + |
| | | "<if test=\"enable != null\">, enable = #{enable}</if>" + |
| | | "WHERE id = #{id}" + |
| | | " </script>"}) |
| | | int update(UserApiKey userApiKey); |
| | | |
| | | @Update("UPDATE wvp_user_api_key SET enable = true WHERE id = #{id}") |
| | | int enable(@Param("id") int id); |
| | | |
| | | @Update("UPDATE wvp_user_api_key SET enable = false WHERE id = #{id}") |
| | | int disable(@Param("id") int id); |
| | | |
| | | @Update("UPDATE wvp_user_api_key SET api_key = #{apiKey} WHERE id = #{id}") |
| | | int apiKey(@Param("id") int id, @Param("apiKey") String apiKey); |
| | | |
| | | @Update("UPDATE wvp_user_api_key SET remark = #{remark} WHERE id = #{id}") |
| | | int remark(@Param("id") int id, @Param("remark") String remark); |
| | | |
| | | @Delete("DELETE FROM wvp_user_api_key WHERE id = #{id}") |
| | | int delete(@Param("id") int id); |
| | | |
| | | @Select("SELECT uak.id, uak.user_id, uak.app, uak.api_key, uak.expired_at, uak.remark, uak.enable, uak.create_time, uak.update_time, u.username AS username FROM wvp_user_api_key uak LEFT JOIN wvp_user u on u.id = uak.user_id WHERE uak.id = #{id}") |
| | | UserApiKey selectById(@Param("id") int id); |
| | | |
| | | @Select("SELECT uak.id, uak.user_id, uak.app, uak.api_key, uak.expired_at, uak.remark, uak.enable, uak.create_time, uak.update_time, u.username AS username FROM wvp_user_api_key uak LEFT JOIN wvp_user u on u.id = uak.user_id WHERE uak.api_key = #{apiKey}") |
| | | UserApiKey selectByApiKey(@Param("apiKey") String apiKey); |
| | | |
| | | @Select("SELECT uak.id, uak.user_id, uak.app, uak.api_key, uak.expired_at, uak.remark, uak.enable, uak.create_time, uak.update_time, u.username AS username FROM wvp_user_api_key uak LEFT JOIN wvp_user u on u.id = uak.user_id") |
| | | List<UserApiKey> selectAll(); |
| | | |
| | | @Select("SELECT uak.id, uak.user_id, uak.app, uak.api_key, uak.expired_at, uak.remark, uak.enable, uak.create_time, uak.update_time, u.username AS username FROM wvp_user_api_key uak LEFT JOIN wvp_user u on u.id = uak.user_id") |
| | | List<UserApiKey> getUserApiKeys(); |
| | | |
| | | @Select("SELECT COUNT(0) FROM wvp_user_api_key WHERE api_key = #{apiKey}") |
| | | boolean isApiKeyExists(@Param("apiKey") String apiKey); |
| | | |
| | | } |
New file |
| | |
| | | package com.genersoft.iot.vmp.storager.dao.dto; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * ç¨æ·ä¿¡æ¯ |
| | | */ |
| | | @Schema(description = "ç¨æ·ApiKeyä¿¡æ¯") |
| | | public class UserApiKey implements Serializable { |
| | | |
| | | /** |
| | | * Id |
| | | */ |
| | | @Schema(description = "Id") |
| | | private int id; |
| | | |
| | | /** |
| | | * ç¨æ·Id |
| | | */ |
| | | @Schema(description = "ç¨æ·Id") |
| | | private int userId; |
| | | |
| | | /** |
| | | * åºç¨å |
| | | */ |
| | | @Schema(description = "åºç¨å") |
| | | private String app; |
| | | |
| | | /** |
| | | * ApiKey |
| | | */ |
| | | @Schema(description = "ApiKey") |
| | | private String apiKey; |
| | | |
| | | /** |
| | | * è¿ææ¶é´ï¼null=æ°¸ä¸è¿æï¼ |
| | | */ |
| | | @Schema(description = "è¿ææ¶é´ï¼null=æ°¸ä¸è¿æï¼") |
| | | private String expiredAt; |
| | | |
| | | /** |
| | | * 夿³¨ä¿¡æ¯ |
| | | */ |
| | | @Schema(description = "夿³¨ä¿¡æ¯") |
| | | private String remark; |
| | | |
| | | /** |
| | | * æ¯å¦å¯ç¨ |
| | | */ |
| | | @Schema(description = "æ¯å¦å¯ç¨") |
| | | private boolean enable; |
| | | |
| | | /** |
| | | * å建æ¶é´ |
| | | */ |
| | | @Schema(description = "å建æ¶é´") |
| | | private String createTime; |
| | | |
| | | /** |
| | | * æ´æ°æ¶é´ |
| | | */ |
| | | @Schema(description = "æ´æ°æ¶é´") |
| | | private String updateTime; |
| | | |
| | | /** |
| | | * ç¨æ·å |
| | | */ |
| | | private String username; |
| | | |
| | | public int getId() { |
| | | return id; |
| | | } |
| | | |
| | | public void setId(int id) { |
| | | this.id = id; |
| | | } |
| | | |
| | | public int getUserId() { |
| | | return userId; |
| | | } |
| | | |
| | | public void setUserId(int userId) { |
| | | this.userId = userId; |
| | | } |
| | | |
| | | public String getApp() { |
| | | return app; |
| | | } |
| | | |
| | | public void setApp(String app) { |
| | | this.app = app; |
| | | } |
| | | |
| | | public String getApiKey() { |
| | | return apiKey; |
| | | } |
| | | |
| | | public void setApiKey(String apiKey) { |
| | | this.apiKey = apiKey; |
| | | } |
| | | |
| | | public String getExpiredAt() { |
| | | return expiredAt; |
| | | } |
| | | |
| | | public void setExpiredAt(String expiredAt) { |
| | | this.expiredAt = expiredAt; |
| | | } |
| | | |
| | | public String getRemark() { |
| | | return remark; |
| | | } |
| | | |
| | | public void setRemark(String remark) { |
| | | this.remark = remark; |
| | | } |
| | | |
| | | public boolean isEnable() { |
| | | return enable; |
| | | } |
| | | |
| | | public void setEnable(boolean enable) { |
| | | this.enable = enable; |
| | | } |
| | | |
| | | public String getCreateTime() { |
| | | return createTime; |
| | | } |
| | | |
| | | public void setCreateTime(String createTime) { |
| | | this.createTime = createTime; |
| | | } |
| | | |
| | | public String getUpdateTime() { |
| | | return updateTime; |
| | | } |
| | | |
| | | public void setUpdateTime(String updateTime) { |
| | | this.updateTime = updateTime; |
| | | } |
| | | |
| | | public String getUsername() { |
| | | return username; |
| | | } |
| | | |
| | | public void setUsername(String username) { |
| | | this.username = username; |
| | | } |
| | | } |
New file |
| | |
| | | package com.genersoft.iot.vmp.vmanager.user; |
| | | |
| | | import com.genersoft.iot.vmp.conf.exception.ControllerException; |
| | | import com.genersoft.iot.vmp.conf.security.JwtUtils; |
| | | import com.genersoft.iot.vmp.conf.security.SecurityUtils; |
| | | import com.genersoft.iot.vmp.service.IUserApiKeyService; |
| | | import com.genersoft.iot.vmp.service.IUserService; |
| | | import com.genersoft.iot.vmp.storager.dao.dto.User; |
| | | import com.genersoft.iot.vmp.storager.dao.dto.UserApiKey; |
| | | import com.genersoft.iot.vmp.utils.DateUtil; |
| | | import com.genersoft.iot.vmp.vmanager.bean.ErrorCode; |
| | | import com.github.pagehelper.PageInfo; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.security.SecurityRequirement; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | @Tag(name = "ç¨æ·ApiKey管ç") |
| | | @RestController |
| | | @RequestMapping("/api/userApiKey") |
| | | public class UserApiKeyController { |
| | | |
| | | public static final int EXPIRATION_TIME = Integer.MAX_VALUE; |
| | | @Autowired |
| | | private IUserService userService; |
| | | |
| | | @Autowired |
| | | private IUserApiKeyService userApiKeyService; |
| | | |
| | | /** |
| | | * æ·»å ç¨æ·ApiKey |
| | | * |
| | | * @param userId |
| | | * @param app |
| | | * @param remark |
| | | * @param expiresAt |
| | | * @param enable |
| | | */ |
| | | @PostMapping("/add") |
| | | @Operation(summary = "æ·»å ç¨æ·ApiKey", security = @SecurityRequirement(name = JwtUtils.HEADER)) |
| | | @Parameter(name = "userId", description = "ç¨æ·Id", required = true) |
| | | @Parameter(name = "app", description = "åºç¨åç§°", required = false) |
| | | @Parameter(name = "remark", description = "夿³¨ä¿¡æ¯", required = false) |
| | | @Parameter(name = "expiredAt", description = "è¿ææ¶é´ï¼ä¸ä¼ 代表永ä¸è¿æï¼", required = false) |
| | | @Transactional |
| | | public synchronized void add( |
| | | @RequestParam(required = true) int userId, |
| | | @RequestParam(required = false) String app, |
| | | @RequestParam(required = false) String remark, |
| | | @RequestParam(required = false) String expiresAt, |
| | | @RequestParam(required = false) Boolean enable |
| | | ) { |
| | | User user = userService.getUserById(userId); |
| | | if (user == null) { |
| | | throw new ControllerException(ErrorCode.ERROR400.getCode(), "ç¨æ·ä¸åå¨"); |
| | | } |
| | | |
| | | Long expirationTime = null; |
| | | if (expiresAt != null) { |
| | | long timestamp = DateUtil.yyyy_MM_dd_HH_mm_ssToTimestampMs(expiresAt); |
| | | expirationTime = (timestamp - System.currentTimeMillis()) / (60 * 1000); |
| | | if (expirationTime < 0) { |
| | | throw new ControllerException(ErrorCode.ERROR400.getCode(), "è¿ææ¶é´ä¸è½æ©äºå½åæ¶é´"); |
| | | } |
| | | } |
| | | |
| | | UserApiKey userApiKey = new UserApiKey(); |
| | | userApiKey.setUserId(userId); |
| | | userApiKey.setApp(app); |
| | | userApiKey.setApiKey(null); |
| | | userApiKey.setRemark(remark); |
| | | userApiKey.setExpiredAt(expiresAt); |
| | | userApiKey.setEnable(enable != null ? enable : false); |
| | | userApiKey.setCreateTime(DateUtil.getNow()); |
| | | userApiKey.setUpdateTime(DateUtil.getNow()); |
| | | |
| | | int addResult = userApiKeyService.addApiKey(userApiKey); |
| | | |
| | | if (addResult <= 0) { |
| | | throw new ControllerException(ErrorCode.ERROR100); |
| | | } |
| | | |
| | | String apiKey; |
| | | do { |
| | | Map<String, Object> extra = new HashMap<>(1); |
| | | extra.put("apiKeyId", userApiKey.getId()); |
| | | apiKey = JwtUtils.createToken(user.getUsername(), expirationTime, extra); |
| | | } while (userApiKeyService.isApiKeyExists(apiKey)); |
| | | |
| | | int resetResult = userApiKeyService.reset(userApiKey.getId(), apiKey); |
| | | |
| | | if (resetResult <= 0) { |
| | | throw new ControllerException(ErrorCode.ERROR100); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å页æ¥è¯¢ApiKey |
| | | * |
| | | * @param page å½å页 |
| | | * @param count æ¯é¡µæ¥è¯¢æ°é |
| | | * @return å页ApiKeyå表 |
| | | */ |
| | | @GetMapping("/userApiKeys") |
| | | @Operation(summary = "å页æ¥è¯¢ç¨æ·", security = @SecurityRequirement(name = JwtUtils.HEADER)) |
| | | @Parameter(name = "page", description = "å½å页", required = true) |
| | | @Parameter(name = "count", description = "æ¯é¡µæ¥è¯¢æ°é", required = true) |
| | | @Transactional |
| | | public PageInfo<UserApiKey> userApiKeys(@RequestParam(required = true) int page, @RequestParam(required = true) int count) { |
| | | return userApiKeyService.getUserApiKeys(page, count); |
| | | } |
| | | |
| | | @PostMapping("/enable") |
| | | @Operation(summary = "å¯ç¨ç¨æ·ApiKey", security = @SecurityRequirement(name = JwtUtils.HEADER)) |
| | | @Parameter(name = "id", description = "ç¨æ·ApiKeyId", required = true) |
| | | @Transactional |
| | | public void enable(@RequestParam(required = true) Integer id) { |
| | | // è·åå½åç»å½ç¨æ·id |
| | | int currenRoleId = SecurityUtils.getUserInfo().getRole().getId(); |
| | | if (currenRoleId != 1) { |
| | | // åªç¨è§è²id为1æå¯ä»¥ç®¡çUserApiKey |
| | | throw new ControllerException(ErrorCode.ERROR403); |
| | | } |
| | | UserApiKey userApiKey = userApiKeyService.getUserApiKeyById(id); |
| | | if (userApiKey == null) { |
| | | throw new ControllerException(ErrorCode.ERROR400.getCode(), "ApiKeyä¸åå¨"); |
| | | } |
| | | |
| | | int enableResult = userApiKeyService.enable(id); |
| | | |
| | | if (enableResult <= 0) { |
| | | throw new ControllerException(ErrorCode.ERROR100); |
| | | } |
| | | } |
| | | |
| | | @PostMapping("/disable") |
| | | @Operation(summary = "åç¨ç¨æ·ApiKey", security = @SecurityRequirement(name = JwtUtils.HEADER)) |
| | | @Parameter(name = "id", description = "ç¨æ·ApiKeyId", required = true) |
| | | @Transactional |
| | | public void disable(@RequestParam(required = true) Integer id) { |
| | | // è·åå½åç»å½ç¨æ·id |
| | | int currenRoleId = SecurityUtils.getUserInfo().getRole().getId(); |
| | | if (currenRoleId != 1) { |
| | | // åªç¨è§è²id为1æå¯ä»¥ç®¡çUserApiKey |
| | | throw new ControllerException(ErrorCode.ERROR403); |
| | | } |
| | | UserApiKey userApiKey = userApiKeyService.getUserApiKeyById(id); |
| | | if (userApiKey == null) { |
| | | throw new ControllerException(ErrorCode.ERROR400.getCode(), "ApiKeyä¸åå¨"); |
| | | } |
| | | |
| | | int disableResult = userApiKeyService.disable(id); |
| | | |
| | | if (disableResult <= 0) { |
| | | throw new ControllerException(ErrorCode.ERROR100); |
| | | } |
| | | } |
| | | |
| | | @PostMapping("/reset") |
| | | @Operation(summary = "éç½®ç¨æ·ApiKey", security = @SecurityRequirement(name = JwtUtils.HEADER)) |
| | | @Parameter(name = "id", description = "ç¨æ·ApiKeyId", required = true) |
| | | @Transactional |
| | | public void reset(@RequestParam(required = true) Integer id) { |
| | | // è·åå½åç»å½ç¨æ·id |
| | | int currenRoleId = SecurityUtils.getUserInfo().getRole().getId(); |
| | | if (currenRoleId != 1) { |
| | | // åªç¨è§è²id为1æå¯ä»¥ç®¡çUserApiKey |
| | | throw new ControllerException(ErrorCode.ERROR403); |
| | | } |
| | | UserApiKey userApiKey = userApiKeyService.getUserApiKeyById(id); |
| | | if (userApiKey == null) { |
| | | throw new ControllerException(ErrorCode.ERROR400.getCode(), "ApiKeyä¸åå¨"); |
| | | } |
| | | User user = userService.getUserById(userApiKey.getUserId()); |
| | | if (user == null) { |
| | | throw new ControllerException(ErrorCode.ERROR400.getCode(), "ç¨æ·ä¸åå¨"); |
| | | } |
| | | Long expirationTime = null; |
| | | if (userApiKey.getExpiredAt() != null) { |
| | | long timestamp = DateUtil.yyyy_MM_dd_HH_mm_ssToTimestampMs(userApiKey.getExpiredAt()); |
| | | expirationTime = (timestamp - System.currentTimeMillis()) / (60 * 1000); |
| | | if (expirationTime < 0) { |
| | | throw new ControllerException(ErrorCode.ERROR400.getCode(), "ApiKey已失æ"); |
| | | } |
| | | } |
| | | String apiKey; |
| | | do { |
| | | Map<String, Object> extra = new HashMap<>(1); |
| | | extra.put("apiKeyId", userApiKey.getId()); |
| | | apiKey = JwtUtils.createToken(user.getUsername(), expirationTime, extra); |
| | | } while (userApiKeyService.isApiKeyExists(apiKey)); |
| | | |
| | | int resetResult = userApiKeyService.reset(id, apiKey); |
| | | |
| | | if (resetResult <= 0) { |
| | | throw new ControllerException(ErrorCode.ERROR100); |
| | | } |
| | | } |
| | | |
| | | @PostMapping("/remark") |
| | | @Operation(summary = "夿³¨ç¨æ·ApiKey", security = @SecurityRequirement(name = JwtUtils.HEADER)) |
| | | @Parameter(name = "id", description = "ç¨æ·ApiKeyId", required = true) |
| | | @Parameter(name = "remark", description = "ç¨æ·ApiKey夿³¨", required = false) |
| | | @Transactional |
| | | public void remark(@RequestParam(required = true) Integer id, @RequestParam(required = false) String remark) { |
| | | // è·åå½åç»å½ç¨æ·id |
| | | int currenRoleId = SecurityUtils.getUserInfo().getRole().getId(); |
| | | if (currenRoleId != 1) { |
| | | // åªç¨è§è²id为1æå¯ä»¥ç®¡çUserApiKey |
| | | throw new ControllerException(ErrorCode.ERROR403); |
| | | } |
| | | UserApiKey userApiKey = userApiKeyService.getUserApiKeyById(id); |
| | | if (userApiKey == null) { |
| | | throw new ControllerException(ErrorCode.ERROR400.getCode(), "ApiKeyä¸åå¨"); |
| | | } |
| | | int remarkResult = userApiKeyService.remark(id, remark); |
| | | |
| | | if (remarkResult <= 0) { |
| | | throw new ControllerException(ErrorCode.ERROR100); |
| | | } |
| | | } |
| | | |
| | | @DeleteMapping("/delete") |
| | | @Operation(summary = "å é¤ç¨æ·ApiKey", security = @SecurityRequirement(name = JwtUtils.HEADER)) |
| | | @Parameter(name = "id", description = "ç¨æ·ApiKeyId", required = true) |
| | | @Transactional |
| | | public void delete(@RequestParam(required = true) Integer id) { |
| | | // è·åå½åç»å½ç¨æ·id |
| | | int currenRoleId = SecurityUtils.getUserInfo().getRole().getId(); |
| | | if (currenRoleId != 1) { |
| | | // åªç¨è§è²id为1æå¯ä»¥ç®¡çUserApiKey |
| | | throw new ControllerException(ErrorCode.ERROR403); |
| | | } |
| | | UserApiKey userApiKey = userApiKeyService.getUserApiKeyById(id); |
| | | if (userApiKey == null) { |
| | | throw new ControllerException(ErrorCode.ERROR400.getCode(), "ApiKeyä¸åå¨"); |
| | | } |
| | | |
| | | int deleteResult = userApiKeyService.delete(id); |
| | | |
| | | if (deleteResult <= 0) { |
| | | throw new ControllerException(ErrorCode.ERROR100); |
| | | } |
| | | } |
| | | } |
| | |
| | | multipart: |
| | | max-file-size: 10MB |
| | | max-request-size: 100MB |
| | | cache: |
| | | type: redis |
| | | # REDISæ°æ®åºé
ç½® |
| | | redis: |
| | | # [å¿
须修æ¹] Redisæå¡å¨IP, REDISå®è£
卿¬æºç,使ç¨127.0.0.1 |
| | |
| | | multipart: |
| | | max-file-size: 10MB |
| | | max-request-size: 100MB |
| | | cache: |
| | | type: redis |
| | | # REDISæ°æ®åºé
ç½® |
| | | redis: |
| | | # [å¿
须修æ¹] Redisæå¡å¨IP, REDISå®è£
卿¬æºç,使ç¨127.0.0.1 |
| | |
| | | assetsPublicPath: '/', |
| | | proxyTable: { |
| | | '/debug': { |
| | | target: 'http://127.0.0.1:18082', |
| | | target: 'http://127.0.0.1:8080', |
| | | changeOrigin: true, |
| | | pathRewrite: { |
| | | '^/debug': '/' |
New file |
| | |
| | | <template> |
| | | <div id="app" style="width: 100%"> |
| | | <div class="page-header" style="margin-bottom: 0"> |
| | | <div class="page-title"> |
| | | <el-page-header @back="goBack" content="ApiKeyå表"></el-page-header> |
| | | </div> |
| | | <div class="page-header-btn"> |
| | | <el-button icon="el-icon-plus" size="mini" style="margin-right: 1rem;" type="primary" @click="addUserApiKey"> |
| | | æ·»å ApiKey |
| | | </el-button> |
| | | </div> |
| | | </div> |
| | | <!--ApiKeyå表--> |
| | | <el-table :data="userList" style="width: 100%;font-size: 12px;" :height="winHeight" |
| | | header-row-class-name="table-header"> |
| | | <el-table-column prop="user.username" label="ç¨æ·å" min-width="120"/> |
| | | <el-table-column prop="app" label="åºç¨å" min-width="160"/> |
| | | <el-table-column prop="apiKey" label="ApiKey" min-width="480"/> |
| | | <el-table-column prop="enable" label="å¯ç¨" width="120"> |
| | | <template #default="scope"> |
| | | <el-tag v-if="scope.row.enable"> |
| | | å¯ç¨ |
| | | </el-tag> |
| | | <el-tag v-else type="info"> |
| | | åç¨ |
| | | </el-tag> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="expiredAt" label="è¿ææ¶é´" width="160"/> |
| | | <el-table-column prop="remark" label="夿³¨ä¿¡æ¯" min-width="160"/> |
| | | <el-table-column label="æä½" min-width="160" fixed="right"> |
| | | <template #default="scope"> |
| | | <el-button v-if="scope.row.enable" |
| | | size="medium" icon="el-icon-circle-close" type="text" @click="disableUserApiKey(scope.row)"> |
| | | åç¨ |
| | | </el-button> |
| | | <el-button v-else |
| | | size="medium" icon="el-icon-circle-check" type="text" @click="enableUserApiKey(scope.row)"> |
| | | å¯ç¨ |
| | | </el-button> |
| | | <el-divider direction="vertical"></el-divider> |
| | | <el-button size="medium" icon="el-icon-refresh" type="text" @click="resetUserApiKey(scope.row)"> |
| | | éç½® |
| | | </el-button> |
| | | <el-divider direction="vertical"></el-divider> |
| | | <el-button size="medium" icon="el-icon-edit" type="text" @click="remarkUserApiKey(scope.row)"> |
| | | 夿³¨ |
| | | </el-button> |
| | | <el-divider direction="vertical"></el-divider> |
| | | <el-button size="medium" icon="el-icon-delete" type="text" @click="deleteUserApiKey(scope.row)" |
| | | style="color: #f56c6c"> |
| | | å é¤ |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <addUserApiKey ref="addUserApiKey"></addUserApiKey> |
| | | <remarkUserApiKey ref="remarkUserApiKey"></remarkUserApiKey> |
| | | <el-pagination |
| | | style="float: right" |
| | | @size-change="handleSizeChange" |
| | | @current-change="currentChange" |
| | | :current-page="currentPage" |
| | | :page-size="count" |
| | | :page-sizes="[15, 25, 35, 50]" |
| | | layout="total, sizes, prev, pager, next" |
| | | :total="total"> |
| | | </el-pagination> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import uiHeader from '../layout/UiHeader.vue' |
| | | import addUserApiKey from "./dialog/addUserApiKey.vue"; |
| | | import remarkUserApiKey from './dialog/remarkUserApiKey.vue' |
| | | |
| | | export default { |
| | | name: 'userApiKeyManager', |
| | | components: { |
| | | uiHeader, |
| | | addUserApiKey, |
| | | remarkUserApiKey |
| | | }, |
| | | data() { |
| | | return { |
| | | userList: [], //设å¤å表 |
| | | currentUser: {}, //å½åæä½è®¾å¤å¯¹è±¡ |
| | | winHeight: window.innerHeight - 200, |
| | | currentPage: 1, |
| | | count: 15, |
| | | total: 0, |
| | | getUserApiKeyListLoading: false |
| | | }; |
| | | }, |
| | | mounted() { |
| | | this.initParam(); |
| | | this.initData(); |
| | | }, |
| | | methods: { |
| | | goBack() { |
| | | this.$router.back() |
| | | }, |
| | | initParam() { |
| | | this.userId = this.$route.params.userId; |
| | | }, |
| | | initData() { |
| | | this.getUserApiKeyList(); |
| | | }, |
| | | currentChange(val) { |
| | | this.currentPage = val; |
| | | this.getUserApiKeyList(); |
| | | }, |
| | | handleSizeChange(val) { |
| | | this.count = val; |
| | | this.getUserApiKeyList(); |
| | | }, |
| | | getUserApiKeyList() { |
| | | let that = this; |
| | | this.getUserApiKeyListLoading = true; |
| | | this.$axios({ |
| | | method: 'get', |
| | | url: `/api/userApiKey/userApiKeys`, |
| | | params: { |
| | | page: that.currentPage, |
| | | count: that.count |
| | | } |
| | | }).then((res) => { |
| | | if (res.data.code === 0) { |
| | | that.total = res.data.data.total; |
| | | that.userList = res.data.data.list; |
| | | } |
| | | that.getUserApiKeyListLoading = false; |
| | | }).catch((error) => { |
| | | that.getUserApiKeyListLoading = false; |
| | | }); |
| | | }, |
| | | addUserApiKey() { |
| | | this.$refs.addUserApiKey.openDialog(this.userId, () => { |
| | | this.$refs.addUserApiKey.close(); |
| | | this.$message({ |
| | | showClose: true, |
| | | message: "ApiKeyæ·»å æå", |
| | | type: "success", |
| | | }); |
| | | setTimeout(this.getUserApiKeyList, 200) |
| | | }) |
| | | }, |
| | | remarkUserApiKey(row) { |
| | | this.$refs.remarkUserApiKey.openDialog(row.id, () => { |
| | | this.$refs.remarkUserApiKey.close(); |
| | | this.$message({ |
| | | showClose: true, |
| | | message: "夿³¨ä¿®æ¹æå", |
| | | type: "success", |
| | | }); |
| | | setTimeout(this.getUserApiKeyList, 200) |
| | | }) |
| | | }, |
| | | enableUserApiKey(row) { |
| | | let msg = "ç¡®å®å¯ç¨æ¤ApiKeyï¼" |
| | | if (row.online !== 0) { |
| | | msg = "<strong>ç¡®å®å¯ç¨æ¤ApiKeyï¼</strong>" |
| | | } |
| | | this.$confirm(msg, 'æç¤º', { |
| | | dangerouslyUseHTMLString: true, |
| | | confirmButtonText: 'ç¡®å®', |
| | | cancelButtonText: 'åæ¶', |
| | | center: true, |
| | | type: 'warning' |
| | | }).then(() => { |
| | | this.$axios({ |
| | | method: 'post', |
| | | url: `/api/userApiKey/enable?id=${row.id}` |
| | | }).then((res) => { |
| | | this.$message({ |
| | | showClose: true, |
| | | message: 'å¯ç¨æå', |
| | | type: 'success' |
| | | }); |
| | | this.getUserApiKeyList(); |
| | | }).catch((error) => { |
| | | this.$message({ |
| | | showClose: true, |
| | | message: 'å¯ç¨å¤±è´¥', |
| | | type: 'error' |
| | | }); |
| | | console.error(error); |
| | | }); |
| | | }).catch(() => { |
| | | }); |
| | | }, |
| | | disableUserApiKey(row) { |
| | | let msg = "ç¡®å®åç¨æ¤ApiKeyï¼" |
| | | if (row.online !== 0) { |
| | | msg = "<strong>ç¡®å®åç¨æ¤ApiKeyï¼</strong>" |
| | | } |
| | | this.$confirm(msg, 'æç¤º', { |
| | | dangerouslyUseHTMLString: true, |
| | | confirmButtonText: 'ç¡®å®', |
| | | cancelButtonText: 'åæ¶', |
| | | center: true, |
| | | type: 'warning' |
| | | }).then(() => { |
| | | this.$axios({ |
| | | method: 'post', |
| | | url: `/api/userApiKey/disable?id=${row.id}` |
| | | }).then((res) => { |
| | | this.$message({ |
| | | showClose: true, |
| | | message: 'åç¨æå', |
| | | type: 'success' |
| | | }); |
| | | this.getUserApiKeyList(); |
| | | }).catch((error) => { |
| | | this.$message({ |
| | | showClose: true, |
| | | message: 'åç¨å¤±è´¥', |
| | | type: 'error' |
| | | }); |
| | | console.error(error); |
| | | }); |
| | | }).catch(() => { |
| | | }); |
| | | }, |
| | | resetUserApiKey(row) { |
| | | let msg = "ç¡®å®éç½®æ¤ApiKeyï¼" |
| | | if (row.online !== 0) { |
| | | msg = "<strong>ç¡®å®éç½®æ¤ApiKeyï¼</strong>" |
| | | } |
| | | this.$confirm(msg, 'æç¤º', { |
| | | dangerouslyUseHTMLString: true, |
| | | confirmButtonText: 'ç¡®å®', |
| | | cancelButtonText: 'åæ¶', |
| | | center: true, |
| | | type: 'warning' |
| | | }).then(() => { |
| | | this.$axios({ |
| | | method: 'post', |
| | | url: `/api/userApiKey/reset?id=${row.id}` |
| | | }).then((res) => { |
| | | this.$message({ |
| | | showClose: true, |
| | | message: 'éç½®æå', |
| | | type: 'success' |
| | | }); |
| | | this.getUserApiKeyList(); |
| | | }).catch((error) => { |
| | | this.$message({ |
| | | showClose: true, |
| | | message: 'é置失败', |
| | | type: 'error' |
| | | }); |
| | | console.error(error); |
| | | }); |
| | | }).catch(() => { |
| | | }); |
| | | }, |
| | | deleteUserApiKey(row) { |
| | | let msg = "ç¡®å®å 餿¤ApiKeyï¼" |
| | | if (row.online !== 0) { |
| | | msg = "<strong>ç¡®å®å 餿¤ApiKeyï¼</strong>" |
| | | } |
| | | this.$confirm(msg, 'æç¤º', { |
| | | dangerouslyUseHTMLString: true, |
| | | confirmButtonText: 'ç¡®å®', |
| | | cancelButtonText: 'åæ¶', |
| | | center: true, |
| | | type: 'warning' |
| | | }).then(() => { |
| | | this.$axios({ |
| | | method: 'delete', |
| | | url: `/api/userApiKey/delete?id=${row.id}` |
| | | }).then((res) => { |
| | | this.$message({ |
| | | showClose: true, |
| | | message: 'å 餿å', |
| | | type: 'success' |
| | | }); |
| | | this.getUserApiKeyList(); |
| | | }).catch((error) => { |
| | | this.$message({ |
| | | showClose: true, |
| | | message: 'å é¤å¤±è´¥', |
| | | type: 'error' |
| | | }); |
| | | console.error(error); |
| | | }); |
| | | }).catch(() => { |
| | | }); |
| | | }, |
| | | } |
| | | } |
| | | </script> |
| | | <style> |
| | | |
| | | </style> |
| | |
| | | <el-divider direction="vertical"></el-divider> |
| | | <el-button size="medium" icon="el-icon-edit" type="text" @click="changePushKey(scope.row)">ä¿®æ¹pushkey</el-button> |
| | | <el-divider direction="vertical"></el-divider> |
| | | <el-button size="medium" icon="el-icon-edit" type="text" @click="showUserApiKeyManager(scope.row)">管çApiKey</el-button> |
| | | <el-divider direction="vertical"></el-divider> |
| | | <el-button size="medium" icon="el-icon-delete" type="text" @click="deleteUser(scope.row)" |
| | | style="color: #f56c6c">å é¤ |
| | | </el-button> |
| | |
| | | setTimeout(this.getUserList, 200) |
| | | |
| | | }) |
| | | } |
| | | }, |
| | | showUserApiKeyManager: function (row) { |
| | | this.$router.push(`/userApiKeyManager/${row.id}`) |
| | | }, |
| | | } |
| | | } |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <div id="addUserApiKey" v-loading="isLoading"> |
| | | <el-dialog |
| | | title="æ·»å ApiKey" |
| | | width="40%" |
| | | top="2rem" |
| | | :close-on-click-modal="false" |
| | | :visible.sync="showDialog" |
| | | :destroy-on-close="true" |
| | | @close="close()" |
| | | > |
| | | <div id="shared" style="margin-right: 20px;"> |
| | | <el-form ref="formRef" :model="form" :rules="rules" status-icon label-width="80px"> |
| | | <el-form-item label="åºç¨å" prop="app"> |
| | | <el-input |
| | | v-model="form.app" |
| | | property="app" |
| | | autocomplete="off"/> |
| | | </el-form-item> |
| | | <el-form-item label="å¯ç¨ç¶æ" prop="enable" style="text-align: left"> |
| | | <el-switch |
| | | v-model="form.enable" |
| | | property="enable" |
| | | active-text="å¯ç¨" |
| | | inactive-text="åç¨"/> |
| | | </el-form-item> |
| | | <el-form-item label="è¿ææ¶é´" prop="expiresAt" style="text-align: left"> |
| | | <el-date-picker v-model="form.expiresAt" |
| | | style="width: 100%" |
| | | property="expiresAt" |
| | | type="datetime" |
| | | value-format="yyyy-MM-dd HH:mm:ss" |
| | | format="yyyy-MM-dd HH:mm:ss" |
| | | placeholder="éæ©è¿ææ¶é´"/> |
| | | </el-form-item> |
| | | <el-form-item label="夿³¨ä¿¡æ¯" prop="remark"> |
| | | <el-input v-model="form.remark" |
| | | type="textarea" |
| | | property="remark" |
| | | autocomplete="off" |
| | | :autosize="{ minRows: 5}" |
| | | maxlength="255" |
| | | show-word-limit/> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <div style="float: right;"> |
| | | <el-button type="primary" @click="onSubmit">ä¿å</el-button> |
| | | <el-button @click="close">åæ¶</el-button> |
| | | </div> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | |
| | | export default { |
| | | name: 'addUserApiKey', |
| | | props: {}, |
| | | computed: {}, |
| | | created() { |
| | | }, |
| | | data() { |
| | | return { |
| | | userId: null, |
| | | form: { |
| | | app: null, |
| | | enable: true, |
| | | expiresAt: null, |
| | | remark: null |
| | | }, |
| | | rules: { |
| | | app: [{required: true, trigger: 'blur', message: 'åºç¨åä¸è½ä¸ºç©º'}] |
| | | }, |
| | | listChangeCallback: null, |
| | | showDialog: false, |
| | | isLoading: false |
| | | }; |
| | | }, |
| | | methods: { |
| | | resetForm() { |
| | | this.form = { |
| | | app: null, |
| | | enable: true, |
| | | expiresAt: null, |
| | | remark: null |
| | | } |
| | | }, |
| | | openDialog(userId, callback) { |
| | | this.resetForm() |
| | | this.userId = userId |
| | | this.listChangeCallback = callback |
| | | this.showDialog = true |
| | | }, |
| | | onSubmit() { |
| | | this.$refs.formRef.validate((valid) => { |
| | | if (valid) { |
| | | this.$axios({ |
| | | method: 'post', |
| | | url: '/api/userApiKey/add', |
| | | params: { |
| | | userId: this.userId, |
| | | app: this.form.app, |
| | | enable: this.form.enable, |
| | | expiresAt: this.form.expiresAt, |
| | | remark: this.form.remark, |
| | | } |
| | | }).then((res) => { |
| | | if (res.data.code === 0) { |
| | | this.$message({ |
| | | showClose: true, |
| | | message: 'æ·»å æå', |
| | | type: 'success' |
| | | }); |
| | | this.showDialog = false |
| | | if (this.listChangeCallback) { |
| | | this.listChangeCallback() |
| | | } |
| | | } else { |
| | | this.$message({ |
| | | showClose: true, |
| | | message: res.data.msg, |
| | | type: 'error' |
| | | }); |
| | | } |
| | | }).catch((error) => { |
| | | console.error(error) |
| | | }); |
| | | } |
| | | }); |
| | | }, |
| | | close() { |
| | | this.showDialog = false |
| | | } |
| | | }, |
| | | }; |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <div id="remarkUserApiKey" v-loading="isLoading"> |
| | | <el-dialog |
| | | title="ApiKey夿³¨" |
| | | width="40%" |
| | | top="2rem" |
| | | :close-on-click-modal="false" |
| | | :visible.sync="showDialog" |
| | | :destroy-on-close="true" |
| | | @close="close()" |
| | | > |
| | | <div id="shared" style="margin-right: 20px;"> |
| | | <el-form ref="form" :rules="rules" status-icon label-width="80px"> |
| | | <el-form-item label="夿³¨" prop="oldPassword"> |
| | | <el-input type="textarea" v-model="form.remark" autocomplete="off" :autosize="{ minRows: 5}" maxlength="255" show-word-limit></el-input> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <div style="float: right;"> |
| | | <el-button type="primary" @click="onSubmit">ä¿å</el-button> |
| | | <el-button @click="close">åæ¶</el-button> |
| | | </div> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | export default { |
| | | name: "remarkUserApiKey", |
| | | props: {}, |
| | | computed: {}, |
| | | created() { |
| | | }, |
| | | data() { |
| | | return { |
| | | userApiKeyId: null, |
| | | form: { |
| | | remark: null |
| | | }, |
| | | rules: {}, |
| | | listChangeCallback: null, |
| | | showDialog: false, |
| | | isLoading: false |
| | | }; |
| | | }, |
| | | methods: { |
| | | resetForm() { |
| | | this.form = { |
| | | remark: null |
| | | } |
| | | }, |
| | | openDialog(userApiKeyId, callback) { |
| | | this.resetForm() |
| | | this.userApiKeyId = userApiKeyId |
| | | this.listChangeCallback = callback |
| | | this.showDialog = true |
| | | }, |
| | | onSubmit() { |
| | | this.$axios({ |
| | | method: 'post', |
| | | url: "/api/userApiKey/remark", |
| | | params: { |
| | | id: this.userApiKeyId, |
| | | remark: this.form.remark |
| | | } |
| | | }).then((res) => { |
| | | if (res.data.code === 0) { |
| | | this.$message({ |
| | | showClose: true, |
| | | message: '夿³¨ä¿®æ¹æå!', |
| | | type: 'success' |
| | | }); |
| | | this.showDialog = false; |
| | | this.listChangeCallback() |
| | | } else { |
| | | this.$message({ |
| | | showClose: true, |
| | | message: '夿³¨ä¿®æ¹å¤±è´¥', |
| | | type: 'error' |
| | | }); |
| | | } |
| | | }).catch((error) => { |
| | | console.error(error) |
| | | }); |
| | | }, |
| | | close() { |
| | | this.showDialog = false |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | |
| | | import live from '../components/live.vue' |
| | | import deviceTree from '../components/common/DeviceTree.vue' |
| | | import userManager from '../components/UserManager.vue' |
| | | |
| | | import userApiKeyManager from '../components/UserApiKeyManager.vue' |
| | | import wasmPlayer from '../components/common/jessibuca.vue' |
| | | import rtcPlayer from '../components/dialog/rtcPlayer.vue' |
| | | |
| | |
| | | path: '/userManager', |
| | | name: 'userManager', |
| | | component: userManager, |
| | | }, |
| | | { |
| | | path: '/userApiKeyManager/:userId', |
| | | name: 'userApiKeyManager', |
| | | component: userApiKeyManager, |
| | | } |
| | | , |
| | | ] |
| | | }, |
| | | { |
| | |
| | | multipart: |
| | | max-file-size: 10MB |
| | | max-request-size: 100MB |
| | | cache: |
| | | type: redis |
| | | # REDISæ°æ®åºé
ç½® |
| | | redis: |
| | | # [å¯é] è¶
æ¶æ¶é´ |
| | |
| | | parentId integer, |
| | | path character varying(255) |
| | | ); |
| | | create table wvp_user_api_key ( |
| | | id serial primary key , |
| | | user_id bigint, |
| | | app character varying(255) , |
| | | api_key text, |
| | | expired_at bigint, |
| | | remark character varying(255), |
| | | enable bool default true, |
| | | create_time character varying(50), |
| | | update_time character varying(50) |
| | | ); |
| | | |
| | | |
| | | /*åå§æ°æ®*/ |
| | |
| | | parentId integer, |
| | | path character varying(255) |
| | | ); |
| | | |
| | | create table wvp_user_api_key ( |
| | | id serial primary key , |
| | | user_id bigint, |
| | | app character varying(255) , |
| | | api_key text, |
| | | expired_at bigint, |
| | | remark character varying(255), |
| | | enable bool default true, |
| | | create_time character varying(50), |
| | | update_time character varying(50) |
| | | ); |
| | | |
| | | /*åå§æ°æ®*/ |
| | | INSERT INTO wvp_user VALUES (1, 'admin','21232f297a57a5a743894a0e4a801fc3',1,'2021-04-13 14:14:57','2021-04-13 14:14:57','3e80d1762a324d5b0ff636e0bd16f1e3'); |
| | |
| | | parentId integer, |
| | | path character varying(255) |
| | | ); |
| | | |
| | | create table wvp_user_api_key ( |
| | | id serial primary key , |
| | | user_id bigint, |
| | | app character varying(255) , |
| | | api_key text, |
| | | expired_at bigint, |
| | | remark character varying(255), |
| | | enable bool default true, |
| | | create_time character varying(50), |
| | | update_time character varying(50) |
| | | ); |
| | | |
| | | /*åå§æ°æ®*/ |
| | | INSERT INTO wvp_user VALUES (1, 'admin','21232f297a57a5a743894a0e4a801fc3',1,'2021-04-13 14:14:57','2021-04-13 14:14:57','3e80d1762a324d5b0ff636e0bd16f1e3'); |
| | |
| | | parentId integer, |
| | | path character varying(255) |
| | | ); |
| | | |
| | | create table wvp_user_api_key ( |
| | | id serial primary key , |
| | | user_id bigint, |
| | | app character varying(255) , |
| | | api_key text, |
| | | expired_at bigint, |
| | | remark character varying(255), |
| | | enable bool default true, |
| | | create_time character varying(50), |
| | | update_time character varying(50) |
| | | ); |
| | | |
| | | /*åå§æ°æ®*/ |
| | | INSERT INTO wvp_user VALUES (1, 'admin','21232f297a57a5a743894a0e4a801fc3',1,'2021-04-13 14:14:57','2021-04-13 14:14:57','3e80d1762a324d5b0ff636e0bd16f1e3'); |