Commit c499165fe59f1b5d9a963ddd9892b4b372a5cd85

Authored by 芋道源码
Committed by Gitee
2 parents a53b0edf 6954150f

!353 同步 增加webSocket

Merge pull request !353 from xingyu/dev
Showing 39 changed files with 1066 additions and 221 deletions
sql/mysql/optional/vue3-menu.sql
... ... @@ -262,5 +262,6 @@ INSERT INTO `system_menu` VALUES (1266, '客户端更新', 'system:oauth2-client
262 262 INSERT INTO `system_menu` VALUES (1267, '客户端删除', 'system:oauth2-client:delete', 3, 4, 1263, '', '', '', 0, b'1', b'1', '', '2022-05-10 16:26:33', '1', '2022-05-11 00:31:33', b'0');
263 263 INSERT INTO `system_menu` VALUES (1281, '可视化报表', '', 1, 12, 0, '/visualization', 'ep:histogram', NULL, 0, b'1', b'1', '1', '2022-07-10 20:22:15', '1', '2022-07-10 20:33:30', b'0');
264 264 INSERT INTO `system_menu` VALUES (1282, '积木报表', '', 2, 1, 1281, 'jimu-report', 'ep:histogram', 'visualization/jmreport/index', 0, b'1', b'1', '1', '2022-07-10 20:26:36', '1', '2022-07-28 21:17:34', b'0');
  265 +INSERT INTO `system_menu` VALUES (1283, 'webSocket连接', '', 2, 14, 2, 'webSocket', 'ep:turn-off', 'infra/webSocket/index', 0, b'1', b'1', '1', '2023-01-01 11:43:04', '1', '2023-01-01 11:43:04', b'0');
265 266  
266 267 SET FOREIGN_KEY_CHECKS = 1;
... ...
sql/mysql/ruoyi-vue-pro.sql
... ... @@ -1710,6 +1710,8 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
1710 1710 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1267, '客户端删除', 'system:oauth2-client:delete', 3, 4, 1263, '', '', '', 0, b'1', b'1', '', '2022-05-10 16:26:33', '1', '2022-05-11 00:31:33', b'0');
1711 1711 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1281, '可视化报表', '', 1, 12, 0, '/visualization', 'chart', NULL, 0, b'1', b'1', '1', '2022-07-10 20:22:15', '1', '2022-07-10 20:33:30', b'0');
1712 1712 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1282, '积木报表', '', 2, 1, 1281, 'jimu-report', 'example', 'visualization/jmreport/index', 0, b'1', b'1', '1', '2022-07-10 20:26:36', '1', '2022-07-28 21:17:34', b'0');
  1713 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1283, 'webSocket连接', '', 2, 14, 2, 'webSocket', 'message', 'infra/webSocket/index', 0, b'1', b'1', '1', '2023-01-01 11:43:04', '1', '2023-01-01 11:43:04', b'0');
  1714 +
1713 1715 COMMIT;
1714 1716  
1715 1717 -- ----------------------------
... ...
yudao-dependencies/pom.xml
... ... @@ -23,8 +23,8 @@
23 23 <servlet.versoin>2.5</servlet.versoin>
24 24 <!-- DB 相关 -->
25 25 <druid.version>1.2.15</druid.version>
26   - <mybatis-plus.version>3.5.3</mybatis-plus.version>
27   - <mybatis-plus-generator.version>3.5.2</mybatis-plus-generator.version>
  26 + <mybatis-plus.version>3.5.3.1</mybatis-plus.version>
  27 + <mybatis-plus-generator.version>3.5.3.1</mybatis-plus-generator.version>
28 28 <dynamic-datasource.version>3.6.1</dynamic-datasource.version>
29 29 <redisson.version>3.18.0</redisson.version>
30 30 <!-- 服务保障相关 -->
... ... @@ -595,6 +595,12 @@
595 595 <artifactId>xercesImpl</artifactId>
596 596 <version>${xercesImpl.version}</version>
597 597 </dependency>
  598 + <!-- SpringBoot Websocket -->
  599 + <dependency>
  600 + <groupId>org.springframework.boot</groupId>
  601 + <artifactId>spring-boot-starter-websocket</artifactId>
  602 + <version>${spring.boot.version}</version>
  603 + </dependency>
598 604 </dependencies>
599 605 </dependencyManagement>
600 606  
... ...
yudao-framework/pom.xml
... ... @@ -40,6 +40,7 @@
40 40  
41 41 <module>yudao-spring-boot-starter-flowable</module>
42 42 <module>yudao-spring-boot-starter-captcha</module>
  43 + <module>yudao-spring-boot-starter-websocket</module>
43 44 </modules>
44 45  
45 46 <artifactId>yudao-framework</artifactId>
... ...
yudao-framework/yudao-spring-boot-starter-security/src/main/java/cn/iocoder/yudao/framework/security/config/YudaoWebSecurityConfigurerAdapter.java
... ... @@ -129,6 +129,8 @@ public class YudaoWebSecurityConfigurerAdapter {
129 129 .antMatchers(buildAppApi("/**")).permitAll()
130 130 // 1.5 验证码captcha 允许匿名访问
131 131 .antMatchers("/captcha/get", "/captcha/check").permitAll()
  132 + // 1.6 webSocket 允许匿名访问
  133 + .antMatchers("/websocket/message").permitAll()
132 134 // ②:每个项目的自定义规则
133 135 .and().authorizeRequests(registry -> // 下面,循环设置自定义规则
134 136 authorizeRequestsCustomizers.forEach(customizer -> customizer.customize(registry)))
... ...
yudao-framework/yudao-spring-boot-starter-websocket/pom.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project xmlns="http://maven.apache.org/POM/4.0.0"
  3 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5 + <parent>
  6 + <groupId>cn.iocoder.boot</groupId>
  7 + <artifactId>yudao-framework</artifactId>
  8 + <version>${revision}</version>
  9 + </parent>
  10 + <modelVersion>4.0.0</modelVersion>
  11 + <artifactId>yudao-spring-boot-starter-websocket</artifactId>
  12 + <packaging>jar</packaging>
  13 +
  14 + <name>${project.artifactId}</name>
  15 + <description>WebSocket</description>
  16 + <url>https://github.com/YunaiV/ruoyi-vue-pro</url>
  17 +
  18 +
  19 + <dependencies>
  20 +
  21 + <dependency>
  22 + <groupId>cn.iocoder.boot</groupId>
  23 + <artifactId>yudao-common</artifactId>
  24 + </dependency>
  25 +
  26 + <dependency>
  27 + <groupId>cn.iocoder.boot</groupId>
  28 + <artifactId>yudao-spring-boot-starter-security</artifactId>
  29 + </dependency>
  30 +
  31 + <dependency>
  32 + <groupId>org.springframework.boot</groupId>
  33 + <artifactId>spring-boot-starter-websocket</artifactId>
  34 + </dependency>
  35 + </dependencies>
  36 +
  37 +</project>
0 38 \ No newline at end of file
... ...
yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/config/WebSocketHandlerConfig.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.websocket.config;
  2 +
  3 +import cn.iocoder.yudao.framework.websocket.core.UserHandshakeInterceptor;
  4 +import org.springframework.boot.context.properties.EnableConfigurationProperties;
  5 +import org.springframework.context.annotation.Bean;
  6 +import org.springframework.web.socket.server.HandshakeInterceptor;
  7 +
  8 +@EnableConfigurationProperties(WebSocketProperties.class)
  9 +public class WebSocketHandlerConfig {
  10 + @Bean
  11 + public HandshakeInterceptor handshakeInterceptor() {
  12 + return new UserHandshakeInterceptor();
  13 + }
  14 +}
... ...
yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/config/WebSocketProperties.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.websocket.config;
  2 +
  3 +import lombok.Data;
  4 +import org.springframework.boot.context.properties.ConfigurationProperties;
  5 +import org.springframework.validation.annotation.Validated;
  6 +
  7 +/**
  8 + * WebSocket 配置项
  9 + *
  10 + * @author xingyu4j
  11 + */
  12 +@ConfigurationProperties("yudao.websocket")
  13 +@Data
  14 +@Validated
  15 +public class WebSocketProperties {
  16 +
  17 + /**
  18 + * 路径
  19 + */
  20 + private String path = "";
  21 + /**
  22 + * 默认最多允许同时在线用户数
  23 + */
  24 + private int maxOnlineCount = 0;
  25 + /**
  26 + * 是否保存session
  27 + */
  28 + private boolean sessionMap = true;
  29 +}
... ...
yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/config/YudaoWebSocketAutoConfiguration.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.websocket.config;
  2 +
  3 +import org.springframework.boot.autoconfigure.AutoConfiguration;
  4 +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
  5 +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
  6 +import org.springframework.boot.context.properties.EnableConfigurationProperties;
  7 +import org.springframework.context.annotation.Bean;
  8 +import org.springframework.web.socket.WebSocketHandler;
  9 +import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
  10 +import org.springframework.web.socket.server.HandshakeInterceptor;
  11 +
  12 +import java.util.List;
  13 +
  14 +/**
  15 + * WebSocket 自动配置
  16 + *
  17 + * @author xingyu4j
  18 + */
  19 +@AutoConfiguration
  20 +// 允许使用 yudao.websocket.enable=false 禁用websocket
  21 +@ConditionalOnProperty(prefix = "yudao.websocket", value = "enable", matchIfMissing = true)
  22 +@EnableConfigurationProperties(WebSocketProperties.class)
  23 +public class YudaoWebSocketAutoConfiguration {
  24 + @Bean
  25 + @ConditionalOnMissingBean
  26 + public WebSocketConfigurer webSocketConfigurer(List<HandshakeInterceptor> handshakeInterceptor,
  27 + WebSocketHandler webSocketHandler,
  28 + WebSocketProperties webSocketProperties) {
  29 +
  30 + return registry -> registry
  31 + .addHandler(webSocketHandler, webSocketProperties.getPath())
  32 + .addInterceptors(handshakeInterceptor.toArray(new HandshakeInterceptor[0]));
  33 + }
  34 +}
... ...
yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/core/UserHandshakeInterceptor.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.websocket.core;
  2 +
  3 +import cn.iocoder.yudao.framework.security.core.LoginUser;
  4 +import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
  5 +import org.springframework.http.server.ServerHttpRequest;
  6 +import org.springframework.http.server.ServerHttpResponse;
  7 +import org.springframework.web.socket.WebSocketHandler;
  8 +import org.springframework.web.socket.server.HandshakeInterceptor;
  9 +
  10 +import java.util.Map;
  11 +
  12 +public class UserHandshakeInterceptor implements HandshakeInterceptor {
  13 + @Override
  14 + public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
  15 + LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
  16 + attributes.put(WebSocketKeyDefine.LOGIN_USER, loginUser);
  17 + return true;
  18 + }
  19 +
  20 + @Override
  21 + public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {
  22 +
  23 + }
  24 +}
... ...
yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/core/WebSocketKeyDefine.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.websocket.core;
  2 +
  3 +
  4 +import lombok.Data;
  5 +
  6 +@Data
  7 +public class WebSocketKeyDefine {
  8 + public static final String LOGIN_USER ="LOGIN_USER";
  9 +}
... ...
yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/core/WebSocketMessageDO.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.websocket.core;
  2 +
  3 +import lombok.Data;
  4 +import lombok.experimental.Accessors;
  5 +
  6 +import java.util.List;
  7 +
  8 +@Data
  9 +@Accessors(chain = true)
  10 +public class WebSocketMessageDO {
  11 + /**
  12 + * 接收消息的seesion
  13 + */
  14 + private List<Object> seesionKeyList;
  15 + /**
  16 + * 发送消息
  17 + */
  18 + private String msgText;
  19 +
  20 + public static WebSocketMessageDO build(List<Object> seesionKeyList, String msgText) {
  21 + return new WebSocketMessageDO().setMsgText(msgText).setSeesionKeyList(seesionKeyList);
  22 + }
  23 +
  24 +}
... ...
yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/core/WebSocketSessionHandler.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.websocket.core;
  2 +
  3 +import org.springframework.web.socket.WebSocketSession;
  4 +
  5 +import java.util.Collection;
  6 +import java.util.Map;
  7 +import java.util.Set;
  8 +import java.util.concurrent.ConcurrentHashMap;
  9 +
  10 +public final class WebSocketSessionHandler {
  11 + private WebSocketSessionHandler() {
  12 + }
  13 +
  14 + private static final Map<String, WebSocketSession> SESSION_MAP = new ConcurrentHashMap<>();
  15 +
  16 + public static void addSession(Object sessionKey, WebSocketSession session) {
  17 + SESSION_MAP.put(sessionKey.toString(), session);
  18 + }
  19 +
  20 + public static void removeSession(Object sessionKey) {
  21 + SESSION_MAP.remove(sessionKey.toString());
  22 + }
  23 +
  24 + public static WebSocketSession getSession(Object sessionKey) {
  25 + return SESSION_MAP.get(sessionKey.toString());
  26 + }
  27 +
  28 + public static Collection<WebSocketSession> getSessions() {
  29 + return SESSION_MAP.values();
  30 + }
  31 +
  32 + public static Set<String> getSessionKeys() {
  33 + return SESSION_MAP.keySet();
  34 + }
  35 +
  36 +}
... ...
yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/core/WebSocketUtils.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.websocket.core;
  2 +
  3 +import lombok.extern.slf4j.Slf4j;
  4 +import org.springframework.web.socket.TextMessage;
  5 +import org.springframework.web.socket.WebSocketSession;
  6 +
  7 +import java.io.IOException;
  8 +
  9 +@Slf4j
  10 +public class WebSocketUtils {
  11 + public static boolean sendMessage(WebSocketSession seesion, String message) {
  12 + if (seesion == null) {
  13 + log.error("seesion 不存在");
  14 + return false;
  15 + }
  16 + if (seesion.isOpen()) {
  17 + try {
  18 + seesion.sendMessage(new TextMessage(message));
  19 + } catch (IOException e) {
  20 + log.error("WebSocket 消息发送异常 Session={} | msg= {} | exception={}", seesion, message, e);
  21 + return false;
  22 + }
  23 + }
  24 + return true;
  25 + }
  26 +
  27 + public static boolean sendMessage(Object sessionKey, String message) {
  28 + WebSocketSession session = WebSocketSessionHandler.getSession(sessionKey);
  29 + return sendMessage(session, message);
  30 + }
  31 +}
... ...
yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/core/YudaoWebSocketHandlerDecorator.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.websocket.core;
  2 +
  3 +import cn.iocoder.yudao.framework.security.core.LoginUser;
  4 +import org.springframework.web.socket.CloseStatus;
  5 +import org.springframework.web.socket.WebSocketHandler;
  6 +import org.springframework.web.socket.WebSocketSession;
  7 +import org.springframework.web.socket.handler.WebSocketHandlerDecorator;
  8 +
  9 +public class YudaoWebSocketHandlerDecorator extends WebSocketHandlerDecorator {
  10 + public YudaoWebSocketHandlerDecorator(WebSocketHandler delegate) {
  11 + super(delegate);
  12 + }
  13 +
  14 + /**
  15 + * websocket 连接时执行的动作
  16 + * @param session websocket session 对象
  17 + * @throws Exception 异常对象
  18 + */
  19 + @Override
  20 + public void afterConnectionEstablished(final WebSocketSession session) throws Exception {
  21 + Object sessionKey = sessionKeyGen(session);
  22 + WebSocketSessionHandler.addSession(sessionKey, session);
  23 + }
  24 +
  25 + /**
  26 + * websocket 关闭连接时执行的动作
  27 + * @param session websocket session 对象
  28 + * @param closeStatus 关闭状态对象
  29 + * @throws Exception 异常对象
  30 + */
  31 + @Override
  32 + public void afterConnectionClosed(final WebSocketSession session, CloseStatus closeStatus) throws Exception {
  33 + Object sessionKey = sessionKeyGen(session);
  34 + WebSocketSessionHandler.removeSession(sessionKey);
  35 + }
  36 +
  37 + public Object sessionKeyGen(WebSocketSession webSocketSession) {
  38 +
  39 + Object obj = webSocketSession.getAttributes().get(WebSocketKeyDefine.LOGIN_USER);
  40 +
  41 + if (obj instanceof LoginUser) {
  42 + LoginUser loginUser = (LoginUser) obj;
  43 + // userId 作为唯一区分
  44 + return String.valueOf(loginUser.getId());
  45 + }
  46 +
  47 + return null;
  48 + }
  49 +}
... ...
yudao-framework/yudao-spring-boot-starter-websocket/src/main/java/cn/iocoder/yudao/framework/websocket/package-info.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.websocket;
... ...
yudao-framework/yudao-spring-boot-starter-websocket/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 0 → 100644
  1 +cn.iocoder.yudao.framework.websocket.config.YudaoWebSocketAutoConfiguration
0 2 \ No newline at end of file
... ...
yudao-module-infra/yudao-module-infra-biz/pom.xml
... ... @@ -111,6 +111,12 @@
111 111 <groupId>cn.iocoder.boot</groupId>
112 112 <artifactId>yudao-spring-boot-starter-file</artifactId>
113 113 </dependency>
  114 +
  115 + <!-- WebSocket -->
  116 + <dependency>
  117 + <groupId>org.springframework.boot</groupId>
  118 + <artifactId>spring-boot-starter-websocket</artifactId>
  119 + </dependency>
114 120 </dependencies>
115 121  
116 122 </project>
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/websocket/SemaphoreUtils.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.websocket;
  2 +
  3 +import lombok.extern.slf4j.Slf4j;
  4 +
  5 +import java.util.concurrent.Semaphore;
  6 +
  7 +/**
  8 + * 信号量相关处理
  9 + *
  10 + */
  11 +@Slf4j
  12 +public class SemaphoreUtils {
  13 +
  14 + /**
  15 + * 获取信号量
  16 + *
  17 + * @param semaphore
  18 + * @return
  19 + */
  20 + public static boolean tryAcquire(Semaphore semaphore) {
  21 + boolean flag = false;
  22 +
  23 + try {
  24 + flag = semaphore.tryAcquire();
  25 + } catch (Exception e) {
  26 + log.error("获取信号量异常", e);
  27 + }
  28 +
  29 + return flag;
  30 + }
  31 +
  32 + /**
  33 + * 释放信号量
  34 + *
  35 + * @param semaphore
  36 + */
  37 + public static void release(Semaphore semaphore) {
  38 +
  39 + try {
  40 + semaphore.release();
  41 + } catch (Exception e) {
  42 + log.error("释放信号量异常", e);
  43 + }
  44 + }
  45 +}
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/websocket/WebSocketConfig.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.websocket;
  2 +
  3 +import org.springframework.context.annotation.Bean;
  4 +import org.springframework.context.annotation.Configuration;
  5 +import org.springframework.web.socket.server.standard.ServerEndpointExporter;
  6 +
  7 +/**
  8 + * websocket 配置
  9 + */
  10 +@Configuration
  11 +public class WebSocketConfig {
  12 + @Bean
  13 + public ServerEndpointExporter serverEndpointExporter() {
  14 + return new ServerEndpointExporter();
  15 + }
  16 +}
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/websocket/WebSocketServer.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.websocket;
  2 +
  3 +import lombok.extern.slf4j.Slf4j;
  4 +import org.springframework.stereotype.Component;
  5 +
  6 +import javax.websocket.*;
  7 +import javax.websocket.server.ServerEndpoint;
  8 +import java.util.concurrent.Semaphore;
  9 +
  10 +/**
  11 + * websocket 消息处理
  12 + */
  13 +@Component
  14 +@ServerEndpoint("/websocket/message")
  15 +@Slf4j
  16 +public class WebSocketServer {
  17 +
  18 + /**
  19 + * 默认最多允许同时在线用户数100
  20 + */
  21 + public static int socketMaxOnlineCount = 100;
  22 +
  23 + private static final Semaphore SOCKET_SEMAPHORE = new Semaphore(socketMaxOnlineCount);
  24 +
  25 + /**
  26 + * 连接建立成功调用的方法
  27 + */
  28 + @OnOpen
  29 + public void onOpen(Session session) throws Exception {
  30 + // 尝试获取信号量
  31 + boolean semaphoreFlag = SemaphoreUtils.tryAcquire(SOCKET_SEMAPHORE);
  32 + if (!semaphoreFlag) {
  33 + // 未获取到信号量
  34 + log.error("当前在线人数超过限制数:{}", socketMaxOnlineCount);
  35 + WebSocketUsers.sendMessage(session, "当前在线人数超过限制数:" + socketMaxOnlineCount);
  36 + session.close();
  37 + } else {
  38 + String userId = WebSocketUsers.getParam("userId", session);
  39 + if (userId != null) {
  40 + // 添加用户
  41 + WebSocketUsers.addSession(userId, session);
  42 + log.info("用户【userId={}】建立连接,当前连接用户总数:{}", userId, WebSocketUsers.getUsers().size());
  43 + WebSocketUsers.sendMessage(session, "接收内容:连接成功");
  44 + } else {
  45 + WebSocketUsers.sendMessage(session, "接收内容:连接失败");
  46 + }
  47 + }
  48 + }
  49 +
  50 + /**
  51 + * 连接关闭时处理
  52 + */
  53 + @OnClose
  54 + public void onClose(Session session) {
  55 + log.info("用户【sessionId={}】关闭连接!", session.getId());
  56 + // 移除用户
  57 + WebSocketUsers.removeSession(session);
  58 + // 获取到信号量则需释放
  59 + SemaphoreUtils.release(SOCKET_SEMAPHORE);
  60 + }
  61 +
  62 + /**
  63 + * 抛出异常时处理
  64 + */
  65 + @OnError
  66 + public void onError(Session session, Throwable exception) throws Exception {
  67 + if (session.isOpen()) {
  68 + // 关闭连接
  69 + session.close();
  70 + }
  71 + String sessionId = session.getId();
  72 + log.info("用户【sessionId={}】连接异常!异常信息:{}", sessionId, exception);
  73 + // 移出用户
  74 + WebSocketUsers.removeSession(session);
  75 + // 获取到信号量则需释放
  76 + SemaphoreUtils.release(SOCKET_SEMAPHORE);
  77 + }
  78 +
  79 + /**
  80 + * 收到客户端消息时调用的方法
  81 + */
  82 + @OnMessage
  83 + public void onMessage(Session session, String message) {
  84 + WebSocketUsers.sendMessage(session, "接收内容:" + message);
  85 + }
  86 +}
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/websocket/WebSocketUsers.java 0 → 100644
  1 +package cn.iocoder.yudao.module.infra.websocket;
  2 +
  3 +import cn.hutool.core.map.MapUtil;
  4 +import cn.hutool.core.util.StrUtil;
  5 +import lombok.extern.slf4j.Slf4j;
  6 +import org.bouncycastle.util.Strings;
  7 +
  8 +import javax.validation.constraints.NotNull;
  9 +import javax.websocket.Session;
  10 +import java.io.IOException;
  11 +import java.util.List;
  12 +import java.util.Map;
  13 +import java.util.Set;
  14 +import java.util.concurrent.ConcurrentHashMap;
  15 +
  16 +/**
  17 + * websocket 客户端用户
  18 + */
  19 +@Slf4j
  20 +public class WebSocketUsers {
  21 +
  22 + /**
  23 + * 用户集
  24 + * TODO 需要登录用户的session?
  25 + */
  26 + private static final Map<String, Session> SESSION_MAP = new ConcurrentHashMap<>();
  27 +
  28 + /**
  29 + * 存储用户
  30 + *
  31 + * @param userId 唯一键
  32 + * @param session 用户信息
  33 + */
  34 + public static void addSession(String userId, Session session) {
  35 + SESSION_MAP.put(userId, session);
  36 + }
  37 +
  38 + /**
  39 + * 移除用户
  40 + *
  41 + * @param session 用户信息
  42 + * @return 移除结果
  43 + */
  44 + public static boolean removeSession(Session session) {
  45 + String key = null;
  46 + boolean flag = SESSION_MAP.containsValue(session);
  47 + if (flag) {
  48 + Set<Map.Entry<String, Session>> entries = SESSION_MAP.entrySet();
  49 + for (Map.Entry<String, Session> entry : entries) {
  50 + Session value = entry.getValue();
  51 + if (value.equals(session)) {
  52 + key = entry.getKey();
  53 + break;
  54 + }
  55 + }
  56 + } else {
  57 + return true;
  58 + }
  59 + return removeSession(key);
  60 + }
  61 +
  62 + /**
  63 + * 移出用户
  64 + *
  65 + * @param userId 用户id
  66 + */
  67 + public static boolean removeSession(String userId) {
  68 + log.info("用户【userId={}】退出", userId);
  69 + Session remove = SESSION_MAP.remove(userId);
  70 + if (remove != null) {
  71 + boolean containsValue = SESSION_MAP.containsValue(remove);
  72 + log.info("用户【userId={}】退出{},当前连接用户总数:{}", userId, containsValue ? "失败" : "成功", SESSION_MAP.size());
  73 + return containsValue;
  74 + } else {
  75 + return true;
  76 + }
  77 + }
  78 +
  79 + /**
  80 + * 获取在线用户列表
  81 + *
  82 + * @return 返回用户集合
  83 + */
  84 + public static Map<String, Session> getUsers() {
  85 + return SESSION_MAP;
  86 + }
  87 +
  88 + /**
  89 + * 向所有在线人发送消息
  90 + *
  91 + * @param message 消息内容
  92 + */
  93 + public static void sendMessageToAll(String message) {
  94 + SESSION_MAP.forEach((userId, session) -> {
  95 + if (session.isOpen()) {
  96 + sendMessage(session, message);
  97 + }
  98 + });
  99 + }
  100 +
  101 + /**
  102 + * 异步发送文本消息
  103 + *
  104 + * @param session 用户session
  105 + * @param message 消息内容
  106 + */
  107 + public static void sendMessageAsync(Session session, String message) {
  108 + if (session.isOpen()) {
  109 + // TODO 需要加synchronized锁(synchronized(session))?单个session创建线程?
  110 + session.getAsyncRemote().sendText(message);
  111 + } else {
  112 + log.warn("用户【session={}】不在线", session.getId());
  113 + }
  114 + }
  115 +
  116 + /**
  117 + * 同步发送文本消息
  118 + *
  119 + * @param session 用户session
  120 + * @param message 消息内容
  121 + */
  122 + public static void sendMessage(Session session, String message) {
  123 + try {
  124 + if (session.isOpen()) {
  125 + // TODO 需要加synchronized锁(synchronized(session))?单个session创建线程?
  126 + session.getBasicRemote().sendText(message);
  127 + } else {
  128 + log.warn("用户【session={}】不在线", session.getId());
  129 + }
  130 + } catch (IOException e) {
  131 + log.error("发送消息异常", e);
  132 + }
  133 +
  134 + }
  135 +
  136 + /**
  137 + * 根据用户id发送消息
  138 + *
  139 + * @param userId 用户id
  140 + * @param message 消息内容
  141 + */
  142 + public static void sendMessage(String userId, String message) {
  143 + Session session = SESSION_MAP.get(userId);
  144 + //判断是否存在该用户的session,并且是否在线
  145 + if (session == null || !session.isOpen()) {
  146 + return;
  147 + }
  148 + sendMessage(session, message);
  149 + }
  150 +
  151 +
  152 + /**
  153 + * 获取session中的指定参数值
  154 + *
  155 + * @param key 参数key
  156 + * @param session 用户session
  157 + */
  158 + public static String getParam(@NotNull String key, Session session) {
  159 + //TODO 目前只针对获取一个key的值,后期根据情况拓展多个 或者直接在onClose onOpen上获取参数?
  160 + String value = null;
  161 + Map<String, List<String>> parameters = session.getRequestParameterMap();
  162 + if (MapUtil.isNotEmpty(parameters)) {
  163 + value = parameters.get(key).get(0);
  164 + } else {
  165 + String queryString = session.getQueryString();
  166 + if (!StrUtil.isEmpty(queryString)) {
  167 + String[] params = Strings.split(queryString, '&');
  168 + for (String paramPair : params) {
  169 + String[] nameValues = Strings.split(paramPair, '=');
  170 + if (key.equals(nameValues[0])) {
  171 + value = nameValues[1];
  172 + }
  173 + }
  174 + }
  175 + }
  176 + return value;
  177 + }
  178 +}
... ...
yudao-server/pom.xml
... ... @@ -104,7 +104,7 @@
104 104 <plugin>
105 105 <groupId>org.springframework.boot</groupId>
106 106 <artifactId>spring-boot-maven-plugin</artifactId>
107   - <version>2.7.6</version> <!-- 如果 spring.boot.version 版本修改,则这里也要跟着修改 -->
  107 + <version>2.7.7</version> <!-- 如果 spring.boot.version 版本修改,则这里也要跟着修改 -->
108 108 <configuration>
109 109 <fork>true</fork>
110 110 </configuration>
... ...
yudao-server/src/main/resources/application.yaml
... ... @@ -92,6 +92,11 @@ yudao:
92 92 security:
93 93 permit-all_urls:
94 94 - /admin-ui/** # /resources/admin-ui 目录下的静态资源
  95 + websocket:
  96 + enable: true # websocket的开关
  97 + path: /websocket/message # 路径
  98 + maxOnlineCount: 0 # 最大连接人数
  99 + sessionMap: true # 保存sessionMap
95 100 swagger:
96 101 title: 管理后台
97 102 description: 提供管理员管理的所有功能
... ...
yudao-ui-admin-vue3/package.json
... ... @@ -104,7 +104,7 @@
104 104 "vite-plugin-svg-icons": "^2.0.1",
105 105 "vite-plugin-vue-setup-extend": "^0.4.0",
106 106 "vite-plugin-windicss": "^1.8.10",
107   - "vue-tsc": "^1.0.20",
  107 + "vue-tsc": "^1.0.22",
108 108 "windicss": "^3.5.6"
109 109 },
110 110 "engines": {
... ...
yudao-ui-admin-vue3/pnpm-lock.yaml
... ... @@ -75,7 +75,7 @@ specifiers:
75 75 vue: 3.2.45
76 76 vue-i18n: 9.2.2
77 77 vue-router: ^4.1.6
78   - vue-tsc: ^1.0.20
  78 + vue-tsc: ^1.0.22
79 79 vue-types: ^5.0.2
80 80 vxe-table: ^4.3.7
81 81 web-storage-cache: ^1.1.1
... ... @@ -163,13 +163,13 @@ devDependencies:
163 163 vite-plugin-svg-icons: 2.0.1_vite@4.0.4
164 164 vite-plugin-vue-setup-extend: 0.4.0_vite@4.0.4
165 165 vite-plugin-windicss: 1.8.10_vite@4.0.4
166   - vue-tsc: 1.0.20_typescript@4.9.4
  166 + vue-tsc: 1.0.22_typescript@4.9.4
167 167 windicss: 3.5.6
168 168  
169 169 packages:
170 170  
171 171 /@ampproject/remapping/2.2.0:
172   - resolution: {integrity: sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==, registry: https://registry.npm.taobao.org/}
  172 + resolution: {integrity: sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@ampproject/remapping/-/remapping-2.2.0.tgz}
173 173 engines: {node: '>=6.0.0'}
174 174 dependencies:
175 175 '@jridgewell/gen-mapping': 0.1.1
... ... @@ -177,23 +177,23 @@ packages:
177 177 dev: true
178 178  
179 179 /@antfu/utils/0.7.2:
180   - resolution: {integrity: sha512-vy9fM3pIxZmX07dL+VX1aZe7ynZ+YyB0jY+jE6r3hOK6GNY2t6W8rzpFC4tgpbXUYABkFQwgJq2XYXlxbXAI0g==, registry: https://registry.npm.taobao.org/}
  180 + resolution: {integrity: sha512-vy9fM3pIxZmX07dL+VX1aZe7ynZ+YyB0jY+jE6r3hOK6GNY2t6W8rzpFC4tgpbXUYABkFQwgJq2XYXlxbXAI0g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@antfu/utils/-/utils-0.7.2.tgz}
181 181 dev: true
182 182  
183 183 /@babel/code-frame/7.18.6:
184   - resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==, registry: https://registry.npm.taobao.org/}
  184 + resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@babel/code-frame/-/code-frame-7.18.6.tgz}
185 185 engines: {node: '>=6.9.0'}
186 186 dependencies:
187 187 '@babel/highlight': 7.18.6
188 188 dev: true
189 189  
190 190 /@babel/compat-data/7.20.1:
191   - resolution: {integrity: sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ==, registry: https://registry.npm.taobao.org/}
  191 + resolution: {integrity: sha512-EWZ4mE2diW3QALKvDMiXnbZpRvlj+nayZ112nK93SnhqOtpdsbVD4W+2tEoT3YNBAG9RBR0ISY758ZkOgsn6pQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@babel/compat-data/-/compat-data-7.20.1.tgz}
192 192 engines: {node: '>=6.9.0'}
193 193 dev: true
194 194  
195 195 /@babel/core/7.20.5:
196   - resolution: {integrity: sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==, registry: https://registry.npm.taobao.org/}
  196 + resolution: {integrity: sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@babel/core/-/core-7.20.5.tgz}
197 197 engines: {node: '>=6.9.0'}
198 198 dependencies:
199 199 '@ampproject/remapping': 2.2.0
... ... @@ -216,7 +216,7 @@ packages:
216 216 dev: true
217 217  
218 218 /@babel/generator/7.20.5:
219   - resolution: {integrity: sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==, registry: https://registry.npm.taobao.org/}
  219 + resolution: {integrity: sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@babel/generator/-/generator-7.20.5.tgz}
220 220 engines: {node: '>=6.9.0'}
221 221 dependencies:
222 222 '@babel/types': 7.20.5
... ... @@ -225,14 +225,14 @@ packages:
225 225 dev: true
226 226  
227 227 /@babel/helper-annotate-as-pure/7.18.6:
228   - resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==, registry: https://registry.npm.taobao.org/}
  228 + resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz}
229 229 engines: {node: '>=6.9.0'}
230 230 dependencies:
231 231 '@babel/types': 7.20.5
232 232 dev: true
233 233  
234 234 /@babel/helper-compilation-targets/7.20.0_@babel+core@7.20.5:
235   - resolution: {integrity: sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==, registry: https://registry.npm.taobao.org/}
  235 + resolution: {integrity: sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz}
236 236 engines: {node: '>=6.9.0'}
237 237 peerDependencies:
238 238 '@babel/core': ^7.0.0
... ... @@ -245,7 +245,7 @@ packages:
245 245 dev: true
246 246  
247 247 /@babel/helper-create-class-features-plugin/7.20.2_@babel+core@7.20.5:
248   - resolution: {integrity: sha512-k22GoYRAHPYr9I+Gvy2ZQlAe5mGy8BqWst2wRt8cwIufWTxrsVshhIBvYNqC80N0GSFWTsqRVexOtfzlgOEDvA==, registry: https://registry.npm.taobao.org/}
  248 + resolution: {integrity: sha512-k22GoYRAHPYr9I+Gvy2ZQlAe5mGy8BqWst2wRt8cwIufWTxrsVshhIBvYNqC80N0GSFWTsqRVexOtfzlgOEDvA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.2.tgz}
249 249 engines: {node: '>=6.9.0'}
250 250 peerDependencies:
251 251 '@babel/core': ^7.0.0
... ... @@ -263,12 +263,12 @@ packages:
263 263 dev: true
264 264  
265 265 /@babel/helper-environment-visitor/7.18.9:
266   - resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==, registry: https://registry.npm.taobao.org/}
  266 + resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz}
267 267 engines: {node: '>=6.9.0'}
268 268 dev: true
269 269  
270 270 /@babel/helper-function-name/7.19.0:
271   - resolution: {integrity: sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==, registry: https://registry.npm.taobao.org/}
  271 + resolution: {integrity: sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz}
272 272 engines: {node: '>=6.9.0'}
273 273 dependencies:
274 274 '@babel/template': 7.18.10
... ... @@ -276,28 +276,28 @@ packages:
276 276 dev: true
277 277  
278 278 /@babel/helper-hoist-variables/7.18.6:
279   - resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==, registry: https://registry.npm.taobao.org/}
  279 + resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz}
280 280 engines: {node: '>=6.9.0'}
281 281 dependencies:
282 282 '@babel/types': 7.20.5
283 283 dev: true
284 284  
285 285 /@babel/helper-member-expression-to-functions/7.18.9:
286   - resolution: {integrity: sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==, registry: https://registry.npm.taobao.org/}
  286 + resolution: {integrity: sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz}
287 287 engines: {node: '>=6.9.0'}
288 288 dependencies:
289 289 '@babel/types': 7.20.5
290 290 dev: true
291 291  
292 292 /@babel/helper-module-imports/7.18.6:
293   - resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==, registry: https://registry.npm.taobao.org/}
  293 + resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz}
294 294 engines: {node: '>=6.9.0'}
295 295 dependencies:
296 296 '@babel/types': 7.20.5
297 297 dev: true
298 298  
299 299 /@babel/helper-module-transforms/7.20.2:
300   - resolution: {integrity: sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==, registry: https://registry.npm.taobao.org/}
  300 + resolution: {integrity: sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz}
301 301 engines: {node: '>=6.9.0'}
302 302 dependencies:
303 303 '@babel/helper-environment-visitor': 7.18.9
... ... @@ -313,19 +313,19 @@ packages:
313 313 dev: true
314 314  
315 315 /@babel/helper-optimise-call-expression/7.18.6:
316   - resolution: {integrity: sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==, registry: https://registry.npm.taobao.org/}
  316 + resolution: {integrity: sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz}
317 317 engines: {node: '>=6.9.0'}
318 318 dependencies:
319 319 '@babel/types': 7.20.5
320 320 dev: true
321 321  
322 322 /@babel/helper-plugin-utils/7.20.2:
323   - resolution: {integrity: sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==, registry: https://registry.npm.taobao.org/}
  323 + resolution: {integrity: sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz}
324 324 engines: {node: '>=6.9.0'}
325 325 dev: true
326 326  
327 327 /@babel/helper-replace-supers/7.19.1:
328   - resolution: {integrity: sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==, registry: https://registry.npm.taobao.org/}
  328 + resolution: {integrity: sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz}
329 329 engines: {node: '>=6.9.0'}
330 330 dependencies:
331 331 '@babel/helper-environment-visitor': 7.18.9
... ... @@ -338,34 +338,34 @@ packages:
338 338 dev: true
339 339  
340 340 /@babel/helper-simple-access/7.20.2:
341   - resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==, registry: https://registry.npm.taobao.org/}
  341 + resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz}
342 342 engines: {node: '>=6.9.0'}
343 343 dependencies:
344 344 '@babel/types': 7.20.5
345 345 dev: true
346 346  
347 347 /@babel/helper-split-export-declaration/7.18.6:
348   - resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==, registry: https://registry.npm.taobao.org/}
  348 + resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz}
349 349 engines: {node: '>=6.9.0'}
350 350 dependencies:
351 351 '@babel/types': 7.20.5
352 352 dev: true
353 353  
354 354 /@babel/helper-string-parser/7.19.4:
355   - resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==, registry: https://registry.npm.taobao.org/}
  355 + resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz}
356 356 engines: {node: '>=6.9.0'}
357 357  
358 358 /@babel/helper-validator-identifier/7.19.1:
359   - resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==, registry: https://registry.npm.taobao.org/}
  359 + resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz}
360 360 engines: {node: '>=6.9.0'}
361 361  
362 362 /@babel/helper-validator-option/7.18.6:
363   - resolution: {integrity: sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==, registry: https://registry.npm.taobao.org/}
  363 + resolution: {integrity: sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz}
364 364 engines: {node: '>=6.9.0'}
365 365 dev: true
366 366  
367 367 /@babel/helpers/7.20.6:
368   - resolution: {integrity: sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==, registry: https://registry.npm.taobao.org/}
  368 + resolution: {integrity: sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@babel/helpers/-/helpers-7.20.6.tgz}
369 369 engines: {node: '>=6.9.0'}
370 370 dependencies:
371 371 '@babel/template': 7.18.10
... ... @@ -376,7 +376,7 @@ packages:
376 376 dev: true
377 377  
378 378 /@babel/highlight/7.18.6:
379   - resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==, registry: https://registry.npm.taobao.org/}
  379 + resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@babel/highlight/-/highlight-7.18.6.tgz}
380 380 engines: {node: '>=6.9.0'}
381 381 dependencies:
382 382 '@babel/helper-validator-identifier': 7.19.1
... ... @@ -392,14 +392,14 @@ packages:
392 392 '@babel/types': 7.20.5
393 393  
394 394 /@babel/parser/7.20.5:
395   - resolution: {integrity: sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==, registry: https://registry.npm.taobao.org/}
  395 + resolution: {integrity: sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@babel/parser/-/parser-7.20.5.tgz}
396 396 engines: {node: '>=6.0.0'}
397 397 hasBin: true
398 398 dependencies:
399 399 '@babel/types': 7.20.5
400 400  
401 401 /@babel/plugin-syntax-jsx/7.18.6_@babel+core@7.20.5:
402   - resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==, registry: https://registry.npm.taobao.org/}
  402 + resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz}
403 403 engines: {node: '>=6.9.0'}
404 404 peerDependencies:
405 405 '@babel/core': ^7.0.0-0
... ... @@ -409,7 +409,7 @@ packages:
409 409 dev: true
410 410  
411 411 /@babel/plugin-syntax-typescript/7.20.0_@babel+core@7.20.5:
412   - resolution: {integrity: sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==, registry: https://registry.npm.taobao.org/}
  412 + resolution: {integrity: sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz}
413 413 engines: {node: '>=6.9.0'}
414 414 peerDependencies:
415 415 '@babel/core': ^7.0.0-0
... ... @@ -419,7 +419,7 @@ packages:
419 419 dev: true
420 420  
421 421 /@babel/plugin-transform-typescript/7.20.2_@babel+core@7.20.5:
422   - resolution: {integrity: sha512-jvS+ngBfrnTUBfOQq8NfGnSbF9BrqlR6hjJ2yVxMkmO5nL/cdifNbI30EfjRlN4g5wYWNnMPyj5Sa6R1pbLeag==, registry: https://registry.npm.taobao.org/}
  422 + resolution: {integrity: sha512-jvS+ngBfrnTUBfOQq8NfGnSbF9BrqlR6hjJ2yVxMkmO5nL/cdifNbI30EfjRlN4g5wYWNnMPyj5Sa6R1pbLeag==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.20.2.tgz}
423 423 engines: {node: '>=6.9.0'}
424 424 peerDependencies:
425 425 '@babel/core': ^7.0.0-0
... ... @@ -440,12 +440,12 @@ packages:
440 440 dev: false
441 441  
442 442 /@babel/standalone/7.20.6:
443   - resolution: {integrity: sha512-u5at/CbBLETf7kx2LOY4XdhseD79Y099WZKAOMXeT8qvd9OSR515my2UNBBLY4qIht/Qi9KySeQHQwQwxJN4Sw==, registry: https://registry.npm.taobao.org/}
  443 + resolution: {integrity: sha512-u5at/CbBLETf7kx2LOY4XdhseD79Y099WZKAOMXeT8qvd9OSR515my2UNBBLY4qIht/Qi9KySeQHQwQwxJN4Sw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@babel/standalone/-/standalone-7.20.6.tgz}
444 444 engines: {node: '>=6.9.0'}
445 445 dev: true
446 446  
447 447 /@babel/template/7.18.10:
448   - resolution: {integrity: sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==, registry: https://registry.npm.taobao.org/}
  448 + resolution: {integrity: sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@babel/template/-/template-7.18.10.tgz}
449 449 engines: {node: '>=6.9.0'}
450 450 dependencies:
451 451 '@babel/code-frame': 7.18.6
... ... @@ -454,7 +454,7 @@ packages:
454 454 dev: true
455 455  
456 456 /@babel/traverse/7.20.1:
457   - resolution: {integrity: sha512-d3tN8fkVJwFLkHkBN479SOsw4DMZnz8cdbL/gvuDuzy3TS6Nfw80HuQqhw1pITbIruHyh7d1fMA47kWzmcUEGA==, registry: https://registry.npm.taobao.org/}
  457 + resolution: {integrity: sha512-d3tN8fkVJwFLkHkBN479SOsw4DMZnz8cdbL/gvuDuzy3TS6Nfw80HuQqhw1pITbIruHyh7d1fMA47kWzmcUEGA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@babel/traverse/-/traverse-7.20.1.tgz}
458 458 engines: {node: '>=6.9.0'}
459 459 dependencies:
460 460 '@babel/code-frame': 7.18.6
... ... @@ -472,7 +472,7 @@ packages:
472 472 dev: true
473 473  
474 474 /@babel/traverse/7.20.5:
475   - resolution: {integrity: sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==, registry: https://registry.npm.taobao.org/}
  475 + resolution: {integrity: sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@babel/traverse/-/traverse-7.20.5.tgz}
476 476 engines: {node: '>=6.9.0'}
477 477 dependencies:
478 478 '@babel/code-frame': 7.18.6
... ... @@ -490,7 +490,7 @@ packages:
490 490 dev: true
491 491  
492 492 /@babel/types/7.20.2:
493   - resolution: {integrity: sha512-FnnvsNWgZCr232sqtXggapvlkk/tuwR/qhGzcmxI0GXLCjmPYQPzio2FbdlWuY6y1sHFfQKk+rRbUZ9VStQMog==, registry: https://registry.npm.taobao.org/}
  493 + resolution: {integrity: sha512-FnnvsNWgZCr232sqtXggapvlkk/tuwR/qhGzcmxI0GXLCjmPYQPzio2FbdlWuY6y1sHFfQKk+rRbUZ9VStQMog==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@babel/types/-/types-7.20.2.tgz}
494 494 engines: {node: '>=6.9.0'}
495 495 dependencies:
496 496 '@babel/helper-string-parser': 7.19.4
... ... @@ -499,7 +499,7 @@ packages:
499 499 dev: true
500 500  
501 501 /@babel/types/7.20.5:
502   - resolution: {integrity: sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==, registry: https://registry.npm.taobao.org/}
  502 + resolution: {integrity: sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@babel/types/-/types-7.20.5.tgz}
503 503 engines: {node: '>=6.9.0'}
504 504 dependencies:
505 505 '@babel/helper-string-parser': 7.19.4
... ... @@ -952,7 +952,7 @@ packages:
952 952 dev: true
953 953  
954 954 /@iconify/iconify/2.1.2:
955   - resolution: {integrity: sha512-QcUzFeEWkE/mW+BVtEGmcWATClcCOIJFiYUD/PiCWuTcdEA297o8D4oN6Ra44WrNOHu1wqNW4J0ioaDIiqaFOQ==, registry: https://registry.npm.taobao.org/}
  955 + resolution: {integrity: sha512-QcUzFeEWkE/mW+BVtEGmcWATClcCOIJFiYUD/PiCWuTcdEA297o8D4oN6Ra44WrNOHu1wqNW4J0ioaDIiqaFOQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@iconify/iconify/-/iconify-2.1.2.tgz}
956 956 dependencies:
957 957 cross-fetch: 3.1.5
958 958 transitivePeerDependencies:
... ... @@ -1078,7 +1078,7 @@ packages:
1078 1078 '@intlify/shared': 9.2.2
1079 1079  
1080 1080 /@jridgewell/gen-mapping/0.1.1:
1081   - resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==, registry: https://registry.npm.taobao.org/}
  1081 + resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz}
1082 1082 engines: {node: '>=6.0.0'}
1083 1083 dependencies:
1084 1084 '@jridgewell/set-array': 1.1.2
... ... @@ -1100,7 +1100,7 @@ packages:
1100 1100 dev: true
1101 1101  
1102 1102 /@jridgewell/set-array/1.1.2:
1103   - resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==, registry: https://registry.npm.taobao.org/}
  1103 + resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@jridgewell/set-array/-/set-array-1.1.2.tgz}
1104 1104 engines: {node: '>=6.0.0'}
1105 1105 dev: true
1106 1106  
... ... @@ -1151,7 +1151,7 @@ packages:
1151 1151 dev: true
1152 1152  
1153 1153 /@purge-icons/core/0.9.1:
1154   - resolution: {integrity: sha512-sx8/a30MbbqQVEqhuMPE1wJpdVRRbEmwEPZpFzVkcDixzX4p+R2A0WVxqkb0xfHUBAVQwrSE2SeAyniIQLqbLw==, registry: https://registry.npm.taobao.org/}
  1154 + resolution: {integrity: sha512-sx8/a30MbbqQVEqhuMPE1wJpdVRRbEmwEPZpFzVkcDixzX4p+R2A0WVxqkb0xfHUBAVQwrSE2SeAyniIQLqbLw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@purge-icons/core/-/core-0.9.1.tgz}
1155 1155 dependencies:
1156 1156 '@iconify/iconify': 2.1.2
1157 1157 axios: 0.26.1_debug@4.3.4
... ... @@ -1456,7 +1456,7 @@ packages:
1456 1456 dev: false
1457 1457  
1458 1458 /@vitejs/plugin-legacy/3.0.1_terser@5.16.1+vite@4.0.4:
1459   - resolution: {integrity: sha512-XCtEjxoR3rmy000ujYRBp5kggWqzHz9+F20/yIMUWOzbvu0+KW1e14Fvb8h7SpNn+bfjGW1RiAs1Vrgb7Js+iQ==, registry: https://registry.npm.taobao.org/}
  1459 + resolution: {integrity: sha512-XCtEjxoR3rmy000ujYRBp5kggWqzHz9+F20/yIMUWOzbvu0+KW1e14Fvb8h7SpNn+bfjGW1RiAs1Vrgb7Js+iQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@vitejs/plugin-legacy/-/plugin-legacy-3.0.1.tgz}
1460 1460 engines: {node: ^14.18.0 || >=16.0.0}
1461 1461 peerDependencies:
1462 1462 terser: ^5.4.0
... ... @@ -1472,7 +1472,7 @@ packages:
1472 1472 dev: true
1473 1473  
1474 1474 /@vitejs/plugin-vue-jsx/3.0.0_vite@4.0.4+vue@3.2.45:
1475   - resolution: {integrity: sha512-vurkuzgac5SYuxd2HUZqAFAWGTF10diKBwJNbCvnWijNZfXd+7jMtqjPFbGt7idOJUn584fP1Ar9j/GN2jQ3Ew==, registry: https://registry.npm.taobao.org/}
  1475 + resolution: {integrity: sha512-vurkuzgac5SYuxd2HUZqAFAWGTF10diKBwJNbCvnWijNZfXd+7jMtqjPFbGt7idOJUn584fP1Ar9j/GN2jQ3Ew==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@vitejs/plugin-vue-jsx/-/plugin-vue-jsx-3.0.0.tgz}
1476 1476 engines: {node: ^14.18.0 || >=16.0.0}
1477 1477 peerDependencies:
1478 1478 vite: ^4.0.0
... ... @@ -1488,7 +1488,7 @@ packages:
1488 1488 dev: true
1489 1489  
1490 1490 /@vitejs/plugin-vue/4.0.0_vite@4.0.4+vue@3.2.45:
1491   - resolution: {integrity: sha512-e0X4jErIxAB5oLtDqbHvHpJe/uWNkdpYV83AOG2xo2tEVSzCzewgJMtREZM30wXnM5ls90hxiOtAuVU6H5JgbA==, registry: https://registry.npm.taobao.org/}
  1491 + resolution: {integrity: sha512-e0X4jErIxAB5oLtDqbHvHpJe/uWNkdpYV83AOG2xo2tEVSzCzewgJMtREZM30wXnM5ls90hxiOtAuVU6H5JgbA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@vitejs/plugin-vue/-/plugin-vue-4.0.0.tgz}
1492 1492 engines: {node: ^14.18.0 || >=16.0.0}
1493 1493 peerDependencies:
1494 1494 vite: ^4.0.0
... ... @@ -1498,30 +1498,30 @@ packages:
1498 1498 vue: 3.2.45
1499 1499 dev: true
1500 1500  
1501   - /@volar/language-core/1.0.20:
1502   - resolution: {integrity: sha512-FU6TC+xQDLkBmp226NTeZ454MTb8VFLga6CIzWP+TsxuxGwB9Exvzof9TKpilIhTdF4IGVJJ4X1aCP6ycnLMbg==}
  1501 + /@volar/language-core/1.0.22:
  1502 + resolution: {integrity: sha512-hiJeCOqxNdtG/04FRGLGI9H9DVz2l6cTqPDBzwqplHXAWfMxjzUaGUrn9sfTG7YMFNZUgK4EYxJnRfhqdtbSFQ==}
1503 1503 dependencies:
1504   - '@volar/source-map': 1.0.20
  1504 + '@volar/source-map': 1.0.22
1505 1505 muggle-string: 0.1.0
1506 1506 dev: true
1507 1507  
1508   - /@volar/source-map/1.0.20:
1509   - resolution: {integrity: sha512-6wwrvAjuy7HepvHW7CqCw5b57YIFrj9mcfJvjic1WCX9TqjnXAcuHFqiUPid7EdZ4SCRKCYQbWmWreThYbHaZw==}
  1508 + /@volar/source-map/1.0.22:
  1509 + resolution: {integrity: sha512-cv4gypHSP4MWVR82ed/+1IpI6794qAl0Q0+KJ+VGMVF8rVugsiF9QbyMCgjel9wNRsssQsazzsf6txOR9vHQiw==}
1510 1510 dependencies:
1511 1511 muggle-string: 0.1.0
1512 1512 dev: true
1513 1513  
1514   - /@volar/typescript/1.0.20:
1515   - resolution: {integrity: sha512-98D2+rC4igqPL7emqIf0NtIx3UYXZ8xqILiP/ihwP7G2T4oyoGr2vKEOwo49sUzvgUvQl2AI5p8ZQ71mFJfP7w==}
  1514 + /@volar/typescript/1.0.22:
  1515 + resolution: {integrity: sha512-VPyEicealSD4gqlE5/UQ1j3ietsO6Hfat40KtUEh/K+XEZ7h02b1KgFV64YEuBkBOaZ5hgvRW/WXKtQgXCl7Iw==}
1516 1516 dependencies:
1517   - '@volar/language-core': 1.0.20
  1517 + '@volar/language-core': 1.0.22
1518 1518 dev: true
1519 1519  
1520   - /@volar/vue-language-core/1.0.20:
1521   - resolution: {integrity: sha512-Zz6yuxtA6BG6YU8KPwV4qhO5kh3e2Et6+YOu0QC43SiDgjIw2Vzzi+qAqm8UYofg9UBn82OArO1L+VrZPCCK8A==}
  1520 + /@volar/vue-language-core/1.0.22:
  1521 + resolution: {integrity: sha512-Ki0G/ZdBj2/GLw+/VVH3n9XR/JL6krMIth02EekFn6JV4PGN3mNxbvoh6lOPSDZLR6biOU5nJPnnjpKy8nuXhw==}
1522 1522 dependencies:
1523   - '@volar/language-core': 1.0.20
1524   - '@volar/source-map': 1.0.20
  1523 + '@volar/language-core': 1.0.22
  1524 + '@volar/source-map': 1.0.22
1525 1525 '@vue/compiler-dom': 3.2.45
1526 1526 '@vue/compiler-sfc': 3.2.45
1527 1527 '@vue/reactivity': 3.2.45
... ... @@ -1530,19 +1530,19 @@ packages:
1530 1530 vue-template-compiler: 2.7.14
1531 1531 dev: true
1532 1532  
1533   - /@volar/vue-typescript/1.0.20:
1534   - resolution: {integrity: sha512-FxucnAIZc503CfkdEGmUSw8EQfT31gi0DST7YmCNBK3cWOqJTF7UaHaBDpejnYGbsB568KZQbWTLNSpid5S/lA==}
  1533 + /@volar/vue-typescript/1.0.22:
  1534 + resolution: {integrity: sha512-2T1o5z86PAev31OMtVOv/qp4P3ZVl9ln/2KTmykQE8Fh4A5F+868MW4nf5J7XQ6RNyx7RH9LhzgjvbqJpAfiYw==}
1535 1535 dependencies:
1536   - '@volar/typescript': 1.0.20
1537   - '@volar/vue-language-core': 1.0.20
  1536 + '@volar/typescript': 1.0.22
  1537 + '@volar/vue-language-core': 1.0.22
1538 1538 dev: true
1539 1539  
1540 1540 /@vue/babel-helper-vue-transform-on/1.0.2:
1541   - resolution: {integrity: sha512-hz4R8tS5jMn8lDq6iD+yWL6XNB699pGIVLk7WSJnn1dbpjaazsjZQkieJoRX6gW5zpYSCFqQ7jUquPNY65tQYA==, registry: https://registry.npm.taobao.org/}
  1541 + resolution: {integrity: sha512-hz4R8tS5jMn8lDq6iD+yWL6XNB699pGIVLk7WSJnn1dbpjaazsjZQkieJoRX6gW5zpYSCFqQ7jUquPNY65tQYA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.0.2.tgz}
1542 1542 dev: true
1543 1543  
1544 1544 /@vue/babel-plugin-jsx/1.1.1_@babel+core@7.20.5:
1545   - resolution: {integrity: sha512-j2uVfZjnB5+zkcbc/zsOc0fSNGCMMjaEXP52wdwdIfn0qjFfEYpYZBFKFg+HHnQeJCVrjOeO0YxgaL7DMrym9w==, registry: https://registry.npm.taobao.org/}
  1545 + resolution: {integrity: sha512-j2uVfZjnB5+zkcbc/zsOc0fSNGCMMjaEXP52wdwdIfn0qjFfEYpYZBFKFg+HHnQeJCVrjOeO0YxgaL7DMrym9w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.1.1.tgz}
1546 1546 dependencies:
1547 1547 '@babel/helper-module-imports': 7.18.6
1548 1548 '@babel/plugin-syntax-jsx': 7.18.6_@babel+core@7.20.5
... ... @@ -1593,7 +1593,7 @@ packages:
1593 1593 '@vue/shared': 3.2.45
1594 1594  
1595 1595 /@vue/devtools-api/6.4.5:
1596   - resolution: {integrity: sha512-JD5fcdIuFxU4fQyXUu3w2KpAJHzTVdN+p4iOX2lMWSHMOoQdMAcpFLZzm9Z/2nmsoZ1a96QEhZ26e50xLBsgOQ==, registry: https://registry.npm.taobao.org/}
  1596 + resolution: {integrity: sha512-JD5fcdIuFxU4fQyXUu3w2KpAJHzTVdN+p4iOX2lMWSHMOoQdMAcpFLZzm9Z/2nmsoZ1a96QEhZ26e50xLBsgOQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@vue/devtools-api/-/devtools-api-6.4.5.tgz}
1597 1597  
1598 1598 /@vue/reactivity-transform/3.2.45:
1599 1599 resolution: {integrity: sha512-BHVmzYAvM7vcU5WmuYqXpwaBHjsS8T63jlKGWVtHxAHIoMIlmaMyurUSEs1Zcg46M4AYT5MtB1U274/2aNzjJQ==}
... ... @@ -1846,7 +1846,7 @@ packages:
1846 1846 dev: false
1847 1847  
1848 1848 /@windicss/config/1.8.10:
1849   - resolution: {integrity: sha512-O9SsC110b1Ik3YYa4Ck/0TWuCo7YFfA9KDrwD5sAeqscT5COIGK1HszdCT3oh0MJFej2wNrvpfyW9h6yQaW6PA==, registry: https://registry.npm.taobao.org/}
  1849 + resolution: {integrity: sha512-O9SsC110b1Ik3YYa4Ck/0TWuCo7YFfA9KDrwD5sAeqscT5COIGK1HszdCT3oh0MJFej2wNrvpfyW9h6yQaW6PA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@windicss/config/-/config-1.8.10.tgz}
1850 1850 dependencies:
1851 1851 debug: 4.3.4
1852 1852 jiti: 1.16.0
... ... @@ -1856,7 +1856,7 @@ packages:
1856 1856 dev: true
1857 1857  
1858 1858 /@windicss/plugin-utils/1.8.10:
1859   - resolution: {integrity: sha512-Phqk5OW1w+Mv+ry6t7BzAeDq3aMhbI94gR49j9vQCufFfDGCHndhhjtMK0sBv+NPJUsIAIh6qayb1iwBCXUGrw==, registry: https://registry.npm.taobao.org/}
  1859 + resolution: {integrity: sha512-Phqk5OW1w+Mv+ry6t7BzAeDq3aMhbI94gR49j9vQCufFfDGCHndhhjtMK0sBv+NPJUsIAIh6qayb1iwBCXUGrw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/@windicss/plugin-utils/-/plugin-utils-1.8.10.tgz}
1860 1860 dependencies:
1861 1861 '@antfu/utils': 0.7.2
1862 1862 '@windicss/config': 1.8.10
... ... @@ -2152,7 +2152,7 @@ packages:
2152 2152 dev: true
2153 2153  
2154 2154 /braces/2.3.2:
2155   - resolution: {integrity: sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==, registry: https://registry.npm.taobao.org/}
  2155 + resolution: {integrity: sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/braces/-/braces-2.3.2.tgz}
2156 2156 engines: {node: '>=0.10.0'}
2157 2157 dependencies:
2158 2158 arr-flatten: 1.1.0
... ... @@ -2239,7 +2239,7 @@ packages:
2239 2239 engines: {node: '>=6'}
2240 2240  
2241 2241 /camelcase/6.3.0:
2242   - resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==, registry: https://registry.npm.taobao.org/}
  2242 + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/camelcase/-/camelcase-6.3.0.tgz}
2243 2243 engines: {node: '>=10'}
2244 2244 dev: true
2245 2245  
... ... @@ -2497,7 +2497,7 @@ packages:
2497 2497 dev: true
2498 2498  
2499 2499 /convert-source-map/1.9.0:
2500   - resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==, registry: https://registry.npm.taobao.org/}
  2500 + resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/convert-source-map/-/convert-source-map-1.9.0.tgz}
2501 2501 dev: true
2502 2502  
2503 2503 /copy-descriptor/0.1.1:
... ... @@ -2506,7 +2506,7 @@ packages:
2506 2506 dev: true
2507 2507  
2508 2508 /core-js/3.26.1:
2509   - resolution: {integrity: sha512-21491RRQVzUn0GGM9Z1Jrpr6PNPxPi+Za8OM9q4tksTSnlbXXGKK1nXNg/QvwFYettXvSX6zWKCtHHfjN4puyA==, registry: https://registry.npm.taobao.org/}
  2509 + resolution: {integrity: sha512-21491RRQVzUn0GGM9Z1Jrpr6PNPxPi+Za8OM9q4tksTSnlbXXGKK1nXNg/QvwFYettXvSX6zWKCtHHfjN4puyA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/core-js/-/core-js-3.26.1.tgz}
2510 2510 requiresBuild: true
2511 2511 dev: true
2512 2512  
... ... @@ -2563,7 +2563,7 @@ packages:
2563 2563 dev: false
2564 2564  
2565 2565 /cross-fetch/3.1.5:
2566   - resolution: {integrity: sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==, registry: https://registry.npm.taobao.org/}
  2566 + resolution: {integrity: sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/cross-fetch/-/cross-fetch-3.1.5.tgz}
2567 2567 dependencies:
2568 2568 node-fetch: 2.6.7
2569 2569 transitivePeerDependencies:
... ... @@ -2848,7 +2848,7 @@ packages:
2848 2848 dev: false
2849 2849  
2850 2850 /echarts/5.4.1:
2851   - resolution: {integrity: sha512-9ltS3M2JB0w2EhcYjCdmtrJ+6haZcW6acBolMGIuf01Hql1yrIV01L1aRj7jsaaIULJslEP9Z3vKlEmnJaWJVQ==, registry: https://registry.npm.taobao.org/}
  2851 + resolution: {integrity: sha512-9ltS3M2JB0w2EhcYjCdmtrJ+6haZcW6acBolMGIuf01Hql1yrIV01L1aRj7jsaaIULJslEP9Z3vKlEmnJaWJVQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/echarts/-/echarts-5.4.1.tgz}
2852 2852 dependencies:
2853 2853 tslib: 2.3.0
2854 2854 zrender: 5.4.1
... ... @@ -3345,7 +3345,7 @@ packages:
3345 3345 dev: true
3346 3346  
3347 3347 /fill-range/4.0.0:
3348   - resolution: {integrity: sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==, registry: https://registry.npm.taobao.org/}
  3348 + resolution: {integrity: sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/fill-range/-/fill-range-4.0.0.tgz}
3349 3349 engines: {node: '>=0.10.0'}
3350 3350 dependencies:
3351 3351 extend-shallow: 2.0.1
... ... @@ -3355,7 +3355,7 @@ packages:
3355 3355 dev: true
3356 3356  
3357 3357 /fill-range/7.0.1:
3358   - resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==, registry: https://registry.npm.taobao.org/}
  3358 + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/fill-range/-/fill-range-7.0.1.tgz}
3359 3359 engines: {node: '>=8'}
3360 3360 dependencies:
3361 3361 to-regex-range: 5.0.1
... ... @@ -3456,7 +3456,7 @@ packages:
3456 3456 resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
3457 3457  
3458 3458 /gensync/1.0.0-beta.2:
3459   - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==, registry: https://registry.npm.taobao.org/}
  3459 + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/gensync/-/gensync-1.0.0-beta.2.tgz}
3460 3460 engines: {node: '>=6.9.0'}
3461 3461 dev: true
3462 3462  
... ... @@ -3881,14 +3881,14 @@ packages:
3881 3881 dev: false
3882 3882  
3883 3883 /is-number/3.0.0:
3884   - resolution: {integrity: sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==, registry: https://registry.npm.taobao.org/}
  3884 + resolution: {integrity: sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/is-number/-/is-number-3.0.0.tgz}
3885 3885 engines: {node: '>=0.10.0'}
3886 3886 dependencies:
3887 3887 kind-of: 3.2.2
3888 3888 dev: true
3889 3889  
3890 3890 /is-number/7.0.0:
3891   - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==, registry: https://registry.npm.taobao.org/}
  3891 + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/is-number/-/is-number-7.0.0.tgz}
3892 3892 engines: {node: '>=0.12.0'}
3893 3893 dev: true
3894 3894  
... ... @@ -3976,7 +3976,7 @@ packages:
3976 3976 dev: true
3977 3977  
3978 3978 /jiti/1.16.0:
3979   - resolution: {integrity: sha512-L3BJStEf5NAqNuzrpfbN71dp43mYIcBUlCRea/vdyv5dW/AYa1d4bpelko4SHdY3I6eN9Wzyasxirj1/vv5kmg==, registry: https://registry.npm.taobao.org/}
  3979 + resolution: {integrity: sha512-L3BJStEf5NAqNuzrpfbN71dp43mYIcBUlCRea/vdyv5dW/AYa1d4bpelko4SHdY3I6eN9Wzyasxirj1/vv5kmg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/jiti/-/jiti-1.16.0.tgz}
3980 3980 hasBin: true
3981 3981 dev: true
3982 3982  
... ... @@ -3989,7 +3989,7 @@ packages:
3989 3989 dev: true
3990 3990  
3991 3991 /js-tokens/4.0.0:
3992   - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==, registry: https://registry.npm.taobao.org/}
  3992 + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/js-tokens/-/js-tokens-4.0.0.tgz}
3993 3993 dev: true
3994 3994  
3995 3995 /js-tokens/8.0.0:
... ... @@ -4008,7 +4008,7 @@ packages:
4008 4008 dev: false
4009 4009  
4010 4010 /jsesc/2.5.2:
4011   - resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==, registry: https://registry.npm.taobao.org/}
  4011 + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/jsesc/-/jsesc-2.5.2.tgz}
4012 4012 engines: {node: '>=4'}
4013 4013 hasBin: true
4014 4014 dev: true
... ... @@ -4095,7 +4095,7 @@ packages:
4095 4095 dev: true
4096 4096  
4097 4097 /kolorist/1.6.0:
4098   - resolution: {integrity: sha512-dLkz37Ab97HWMx9KTes3Tbi3D1ln9fCAy2zr2YVExJasDRPGRaKcoE4fycWNtnCAJfjFqe0cnY+f8KT2JePEXQ==, registry: https://registry.npm.taobao.org/}
  4098 + resolution: {integrity: sha512-dLkz37Ab97HWMx9KTes3Tbi3D1ln9fCAy2zr2YVExJasDRPGRaKcoE4fycWNtnCAJfjFqe0cnY+f8KT2JePEXQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/kolorist/-/kolorist-1.6.0.tgz}
4099 4099 dev: true
4100 4100  
4101 4101 /levn/0.4.1:
... ... @@ -4294,7 +4294,7 @@ packages:
4294 4294 sourcemap-codec: 1.4.8
4295 4295  
4296 4296 /magic-string/0.27.0:
4297   - resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==, registry: https://registry.npm.taobao.org/}
  4297 + resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/magic-string/-/magic-string-0.27.0.tgz}
4298 4298 engines: {node: '>=12'}
4299 4299 dependencies:
4300 4300 '@jridgewell/sourcemap-codec': 1.4.14
... ... @@ -4506,7 +4506,7 @@ packages:
4506 4506 dev: false
4507 4507  
4508 4508 /nanoid/3.3.4:
4509   - resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==, registry: https://registry.npm.taobao.org/}
  4509 + resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/nanoid/-/nanoid-3.3.4.tgz}
4510 4510 engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
4511 4511 hasBin: true
4512 4512  
... ... @@ -4549,7 +4549,7 @@ packages:
4549 4549 dev: true
4550 4550  
4551 4551 /node-fetch/2.6.7:
4552   - resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==, registry: https://registry.npm.taobao.org/}
  4552 + resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/node-fetch/-/node-fetch-2.6.7.tgz}
4553 4553 engines: {node: 4.x || >=6.0.0}
4554 4554 peerDependencies:
4555 4555 encoding: ^0.1.0
... ... @@ -4815,7 +4815,7 @@ packages:
4815 4815 dev: true
4816 4816  
4817 4817 /pinia/2.0.28_prq2uz4lho2pwp6irk4cfkrxwu:
4818   - resolution: {integrity: sha512-YClq9DkqCblq9rlyUual7ezMu/iICWdBtfJrDt4oWU9Zxpijyz7xB2xTwx57DaBQ96UGvvTMORzALr+iO5PVMw==, registry: https://registry.npm.taobao.org/}
  4818 + resolution: {integrity: sha512-YClq9DkqCblq9rlyUual7ezMu/iICWdBtfJrDt4oWU9Zxpijyz7xB2xTwx57DaBQ96UGvvTMORzALr+iO5PVMw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/pinia/-/pinia-2.0.28.tgz}
4819 4819 peerDependencies:
4820 4820 '@vue/composition-api': ^1.4.0
4821 4821 typescript: '>=4.4.4'
... ... @@ -4925,7 +4925,7 @@ packages:
4925 4925 dev: true
4926 4926  
4927 4927 /postcss/8.4.20:
4928   - resolution: {integrity: sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==, registry: https://registry.npm.taobao.org/}
  4928 + resolution: {integrity: sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/postcss/-/postcss-8.4.20.tgz}
4929 4929 engines: {node: ^10 || ^12 || >=14}
4930 4930 dependencies:
4931 4931 nanoid: 3.3.4
... ... @@ -5108,7 +5108,7 @@ packages:
5108 5108 dev: true
5109 5109  
5110 5110 /regenerator-runtime/0.13.11:
5111   - resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==, registry: https://registry.npm.taobao.org/}
  5111 + resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz}
5112 5112  
5113 5113 /regex-not/1.0.2:
5114 5114 resolution: {integrity: sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==}
... ... @@ -5207,7 +5207,7 @@ packages:
5207 5207 dev: true
5208 5208  
5209 5209 /rollup-plugin-purge-icons/0.9.1:
5210   - resolution: {integrity: sha512-hRDKBsPUz47UMdBufki2feTmBF2ClEJlYqL7N6vpVAHSLd7V2BJUaNKOF7YYbLMofVVF+9hm44YSkYO6k9hUgg==, registry: https://registry.npm.taobao.org/}
  5210 + resolution: {integrity: sha512-hRDKBsPUz47UMdBufki2feTmBF2ClEJlYqL7N6vpVAHSLd7V2BJUaNKOF7YYbLMofVVF+9hm44YSkYO6k9hUgg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/rollup-plugin-purge-icons/-/rollup-plugin-purge-icons-0.9.1.tgz}
5211 5211 engines: {node: '>= 12'}
5212 5212 dependencies:
5213 5213 '@purge-icons/core': 0.9.1
... ... @@ -5428,7 +5428,7 @@ packages:
5428 5428 dev: true
5429 5429  
5430 5430 /source-map-js/1.0.2:
5431   - resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==, registry: https://registry.npm.taobao.org/}
  5431 + resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/source-map-js/-/source-map-js-1.0.2.tgz}
5432 5432 engines: {node: '>=0.10.0'}
5433 5433  
5434 5434 /source-map-resolve/0.5.3:
... ... @@ -5771,7 +5771,7 @@ packages:
5771 5771 dev: true
5772 5772  
5773 5773 /systemjs/6.13.0:
5774   - resolution: {integrity: sha512-P3cgh2bpaPvAO2NE3uRp/n6hmk4xPX4DQf+UzTlCAycssKdqhp6hjw+ENWe+aUS7TogKRFtptMosTSFeC6R55g==, registry: https://registry.npm.taobao.org/}
  5774 + resolution: {integrity: sha512-P3cgh2bpaPvAO2NE3uRp/n6hmk4xPX4DQf+UzTlCAycssKdqhp6hjw+ENWe+aUS7TogKRFtptMosTSFeC6R55g==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/systemjs/-/systemjs-6.13.0.tgz}
5775 5775 dev: true
5776 5776  
5777 5777 /table/6.8.1:
... ... @@ -5820,7 +5820,7 @@ packages:
5820 5820 dev: false
5821 5821  
5822 5822 /to-fast-properties/2.0.0:
5823   - resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==, registry: https://registry.npm.taobao.org/}
  5823 + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz}
5824 5824 engines: {node: '>=4'}
5825 5825  
5826 5826 /to-object-path/0.3.0:
... ... @@ -5831,7 +5831,7 @@ packages:
5831 5831 dev: true
5832 5832  
5833 5833 /to-regex-range/2.1.1:
5834   - resolution: {integrity: sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==, registry: https://registry.npm.taobao.org/}
  5834 + resolution: {integrity: sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/to-regex-range/-/to-regex-range-2.1.1.tgz}
5835 5835 engines: {node: '>=0.10.0'}
5836 5836 dependencies:
5837 5837 is-number: 3.0.0
... ... @@ -5839,7 +5839,7 @@ packages:
5839 5839 dev: true
5840 5840  
5841 5841 /to-regex-range/5.0.1:
5842   - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==, registry: https://registry.npm.taobao.org/}
  5842 + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/to-regex-range/-/to-regex-range-5.0.1.tgz}
5843 5843 engines: {node: '>=8.0'}
5844 5844 dependencies:
5845 5845 is-number: 7.0.0
... ... @@ -5856,7 +5856,7 @@ packages:
5856 5856 dev: true
5857 5857  
5858 5858 /tr46/0.0.3:
5859   - resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==, registry: https://registry.npm.taobao.org/}
  5859 + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/tr46/-/tr46-0.0.3.tgz}
5860 5860 dev: true
5861 5861  
5862 5862 /traverse/0.6.7:
... ... @@ -5904,7 +5904,7 @@ packages:
5904 5904 dev: true
5905 5905  
5906 5906 /tslib/2.3.0:
5907   - resolution: {integrity: sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==, registry: https://registry.npm.taobao.org/}
  5907 + resolution: {integrity: sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/tslib/-/tslib-2.3.0.tgz}
5908 5908 dev: false
5909 5909  
5910 5910 /tslib/2.4.1:
... ... @@ -6113,7 +6113,7 @@ packages:
6113 6113 dev: true
6114 6114  
6115 6115 /vite-plugin-purge-icons/0.9.2_vite@4.0.4:
6116   - resolution: {integrity: sha512-vxJEMyNyckqLr/4HPsW9P6BMLUvOVMvjjFz3jLl4Wke1KWE8ITJUxIUwodxaOmEp9L2lxVk5an3TYeycZCfqFw==, registry: https://registry.npm.taobao.org/}
  6116 + resolution: {integrity: sha512-vxJEMyNyckqLr/4HPsW9P6BMLUvOVMvjjFz3jLl4Wke1KWE8ITJUxIUwodxaOmEp9L2lxVk5an3TYeycZCfqFw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/vite-plugin-purge-icons/-/vite-plugin-purge-icons-0.9.2.tgz}
6117 6117 engines: {node: '>= 12'}
6118 6118 peerDependencies:
6119 6119 vite: ^2.0.0 || ^3.0.0 || ^4.0.0
... ... @@ -6171,7 +6171,7 @@ packages:
6171 6171 dev: true
6172 6172  
6173 6173 /vite-plugin-windicss/1.8.10_vite@4.0.4:
6174   - resolution: {integrity: sha512-scywsuzo46lcTBohspmF0WiwhWEte6p+OUVrX4yr7VMRvLHMHVfLtJReyD5pppjijG7YOwVsZn7XBWWZtF658Q==, registry: https://registry.npm.taobao.org/}
  6174 + resolution: {integrity: sha512-scywsuzo46lcTBohspmF0WiwhWEte6p+OUVrX4yr7VMRvLHMHVfLtJReyD5pppjijG7YOwVsZn7XBWWZtF658Q==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/vite-plugin-windicss/-/vite-plugin-windicss-1.8.10.tgz}
6175 6175 peerDependencies:
6176 6176 vite: ^2.0.1 || ^3.0.0 || ^4.0.0
6177 6177 dependencies:
... ... @@ -6281,14 +6281,14 @@ packages:
6281 6281 he: 1.2.0
6282 6282 dev: true
6283 6283  
6284   - /vue-tsc/1.0.20_typescript@4.9.4:
6285   - resolution: {integrity: sha512-AApewYXozAD7v4Iz9I0QzQebSVgvlUvpfbGe2e9TwtBdcw5gBsGiX8Oj5BdxRRiGnOdDG3BHPK8msl7Qhmy/1A==}
  6284 + /vue-tsc/1.0.22_typescript@4.9.4:
  6285 + resolution: {integrity: sha512-xSxwgWR3czhv7sLKHWu6lzj9Xq6AtsCURVL45AY4TLGFszv2L2YlMgygXvqslyCM5bz9cyoIKSaZnzHqHTHjzA==}
6286 6286 hasBin: true
6287 6287 peerDependencies:
6288 6288 typescript: '*'
6289 6289 dependencies:
6290   - '@volar/vue-language-core': 1.0.20
6291   - '@volar/vue-typescript': 1.0.20
  6290 + '@volar/vue-language-core': 1.0.22
  6291 + '@volar/vue-typescript': 1.0.22
6292 6292 typescript: 4.9.4
6293 6293 dev: true
6294 6294  
... ... @@ -6315,7 +6315,7 @@ packages:
6315 6315 '@vue/shared': 3.2.45
6316 6316  
6317 6317 /vxe-table/4.3.7_vue@3.2.45+xe-utils@3.5.7:
6318   - resolution: {integrity: sha512-v+d7eEQ5uqtVTQCts4xkW0S15LZcIuEukYHGXI53SdoUj2gLFggPYAxQr1y659CM/ESRWPz9LNVHpd97KkjGHw==, registry: https://registry.npm.taobao.org/}
  6318 + resolution: {integrity: sha512-v+d7eEQ5uqtVTQCts4xkW0S15LZcIuEukYHGXI53SdoUj2gLFggPYAxQr1y659CM/ESRWPz9LNVHpd97KkjGHw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/vxe-table/-/vxe-table-4.3.7.tgz}
6319 6319 peerDependencies:
6320 6320 vue: ^3.2.28
6321 6321 xe-utils: ^3.5.0
... ... @@ -6329,7 +6329,7 @@ packages:
6329 6329 dev: false
6330 6330  
6331 6331 /webidl-conversions/3.0.1:
6332   - resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==, registry: https://registry.npm.taobao.org/}
  6332 + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz}
6333 6333 dev: true
6334 6334  
6335 6335 /webpack-sources/3.2.3:
... ... @@ -6342,7 +6342,7 @@ packages:
6342 6342 dev: true
6343 6343  
6344 6344 /whatwg-url/5.0.0:
6345   - resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==, registry: https://registry.npm.taobao.org/}
  6345 + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/whatwg-url/-/whatwg-url-5.0.0.tgz}
6346 6346 dependencies:
6347 6347 tr46: 0.0.3
6348 6348 webidl-conversions: 3.0.1
... ... @@ -6510,7 +6510,7 @@ packages:
6510 6510 dev: true
6511 6511  
6512 6512 /zrender/5.4.1:
6513   - resolution: {integrity: sha512-M4Z05BHWtajY2241EmMPHglDQAJ1UyHQcYsxDNzD9XLSkPDqMq4bB28v9Pb4mvHnVQ0GxyTklZ/69xCFP6RXBA==, registry: https://registry.npm.taobao.org/}
  6513 + resolution: {integrity: sha512-M4Z05BHWtajY2241EmMPHglDQAJ1UyHQcYsxDNzD9XLSkPDqMq4bB28v9Pb4mvHnVQ0GxyTklZ/69xCFP6RXBA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npm.taobao.org/zrender/-/zrender-5.4.1.tgz}
6514 6514 dependencies:
6515 6515 tslib: 2.3.0
6516 6516 dev: false
... ...
yudao-ui-admin-vue3/src/components/Crontab/src/Crontab.vue
... ... @@ -353,7 +353,6 @@ const select = ref()
353 353 watch(
354 354 () => select.value,
355 355 () => {
356   - console.info(select.value)
357 356 if (select.value == 'custom') {
358 357 open()
359 358 } else {
... ...
yudao-ui-admin-vue3/src/hooks/web/useVxeCrudSchemas.ts
... ... @@ -165,7 +165,7 @@ const filterSearchSchema = (crudSchema: VxeCrudSchema): VxeFormItemProps[] =&gt; {
165 165 // 添加搜索按钮
166 166 const buttons: VxeFormItemProps = {
167 167 span: 24,
168   - align: 'center',
  168 + align: 'right',
169 169 collapseNode: searchSchema.length > spanLength,
170 170 itemRender: {
171 171 name: '$buttons',
... ...
yudao-ui-admin-vue3/src/main.ts
... ... @@ -26,10 +26,10 @@ import &#39;@/styles/index.scss&#39;
26 26 import '@/plugins/animate.css'
27 27  
28 28 // 路由
29   -import { setupRouter } from './router'
  29 +import router, { setupRouter } from '@/router'
30 30  
31 31 // 权限
32   -import { setupAuth } from './directives'
  32 +import { setupAuth } from '@/directives'
33 33  
34 34 import { createApp } from 'vue'
35 35  
... ... @@ -53,6 +53,8 @@ const setupAll = async () =&gt; {
53 53  
54 54 setupAuth(app)
55 55  
  56 + await router.isReady()
  57 +
56 58 app.mount('#app')
57 59 }
58 60  
... ...
yudao-ui-admin-vue3/src/plugins/vxeTable/renderer/index.tsx
... ... @@ -4,3 +4,4 @@ import &#39;./dict&#39;
4 4 import './html'
5 5 import './link'
6 6 import './img'
  7 +import './preview'
... ...
yudao-ui-admin-vue3/src/plugins/vxeTable/renderer/preview.tsx 0 → 100644
  1 +import { VXETable } from 'vxe-table'
  2 +import { ElImage, ElLink } from 'element-plus'
  3 +
  4 +// 图片渲染
  5 +VXETable.renderer.add('XPreview', {
  6 + // 默认显示模板
  7 + renderDefault(_renderOpts, params) {
  8 + const { row, column } = params
  9 + if (row.type.indexOf('image/') === 0) {
  10 + return (
  11 + <ElImage
  12 + style="width: 80px; height: 50px"
  13 + src={row[column.field]}
  14 + key={row[column.field]}
  15 + preview-src-list={[row[column.field]]}
  16 + fit="contain"
  17 + lazy
  18 + ></ElImage>
  19 + )
  20 + } else if (row.type.indexOf('video/') === 0) {
  21 + return (
  22 + <video>
  23 + <source src={row[column.field]}></source>
  24 + </video>
  25 + )
  26 + } else {
  27 + return (
  28 + <ElLink href={row[column.field]} target="_blank">
  29 + {row[column.field]}
  30 + </ElLink>
  31 + )
  32 + }
  33 + }
  34 +})
... ...
yudao-ui-admin-vue3/src/router/index.ts
... ... @@ -6,15 +6,11 @@ import { isRelogin } from &#39;@/config/axios/service&#39;
6 6 import { getAccessToken } from '@/utils/auth'
7 7 import { useTitle } from '@/hooks/web/useTitle'
8 8 import { useNProgress } from '@/hooks/web/useNProgress'
9   -import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
10 9 import { usePageLoading } from '@/hooks/web/usePageLoading'
11 10 import { useDictStoreWithOut } from '@/store/modules/dict'
12 11 import { useUserStoreWithOut } from '@/store/modules/user'
13 12 import { usePermissionStoreWithOut } from '@/store/modules/permission'
14 13 import { getInfoApi } from '@/api/login'
15   -import { listSimpleDictDataApi } from '@/api/system/dict/dict.data'
16   -
17   -const { wsCache } = useCache()
18 14  
19 15 const { start, done } = useNProgress()
20 16  
... ... @@ -50,10 +46,8 @@ router.beforeEach(async (to, from, next) =&gt; {
50 46 const dictStore = useDictStoreWithOut()
51 47 const userStore = useUserStoreWithOut()
52 48 const permissionStore = usePermissionStoreWithOut()
53   - const dictMap = wsCache.get(CACHE_KEY.DICT_CACHE)
54   - if (!dictMap) {
55   - const res = await listSimpleDictDataApi()
56   - dictStore.setDictMap(res)
  49 + if (!dictStore.getIsSetDict) {
  50 + dictStore.setDictMap()
57 51 }
58 52 if (!userStore.getIsSetUser) {
59 53 isRelogin.show = true
... ...
yudao-ui-admin-vue3/src/store/modules/dict.ts
... ... @@ -3,6 +3,7 @@ import { store } from &#39;../index&#39;
3 3 import { DictDataVO } from '@/api/system/dict/types'
4 4 import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
5 5 const { wsCache } = useCache('sessionStorage')
  6 +import { listSimpleDictDataApi } from '@/api/system/dict/dict.data'
6 7  
7 8 export interface DictValueType {
8 9 value: any
... ... @@ -16,45 +17,54 @@ export interface DictTypeType {
16 17 }
17 18 export interface DictState {
18 19 dictMap: Map<string, any>
  20 + isSetDict: boolean
19 21 }
20 22  
21 23 export const useDictStore = defineStore('dict', {
22 24 state: (): DictState => ({
23   - dictMap: new Map<string, any>()
  25 + dictMap: new Map<string, any>(),
  26 + isSetDict: false
24 27 }),
25 28 getters: {
26 29 getDictMap(): Recordable {
27 30 const dictMap = wsCache.get(CACHE_KEY.DICT_CACHE)
28   - return dictMap ? dictMap : this.dictMap
29   - },
30   - getHasDictData(): boolean {
31   - if (this.dictMap.size > 0) {
32   - return true
33   - } else {
34   - return false
  31 + if (dictMap) {
  32 + this.dictMap = dictMap
35 33 }
  34 + return this.dictMap
  35 + },
  36 + getIsSetDict(): boolean {
  37 + return this.isSetDict
36 38 }
37 39 },
38 40 actions: {
39   - setDictMap(dictMap: Recordable) {
40   - // 设置数据
41   - const dictDataMap = new Map<string, any>()
42   - dictMap.forEach((dictData: DictDataVO) => {
43   - // 获得 dictType 层级
44   - const enumValueObj = dictDataMap[dictData.dictType]
45   - if (!enumValueObj) {
46   - dictDataMap[dictData.dictType] = []
47   - }
48   - // 处理 dictValue 层级
49   - dictDataMap[dictData.dictType].push({
50   - value: dictData.value,
51   - label: dictData.label,
52   - colorType: dictData.colorType,
53   - cssClass: dictData.cssClass
  41 + async setDictMap() {
  42 + const dictMap = wsCache.get(CACHE_KEY.DICT_CACHE)
  43 + if (dictMap) {
  44 + this.dictMap = dictMap
  45 + this.isSetDict = true
  46 + } else {
  47 + const res = await listSimpleDictDataApi()
  48 + // 设置数据
  49 + const dictDataMap = new Map<string, any>()
  50 + res.forEach((dictData: DictDataVO) => {
  51 + // 获得 dictType 层级
  52 + const enumValueObj = dictDataMap[dictData.dictType]
  53 + if (!enumValueObj) {
  54 + dictDataMap[dictData.dictType] = []
  55 + }
  56 + // 处理 dictValue 层级
  57 + dictDataMap[dictData.dictType].push({
  58 + value: dictData.value,
  59 + label: dictData.label,
  60 + colorType: dictData.colorType,
  61 + cssClass: dictData.cssClass
  62 + })
54 63 })
55   - })
56   - this.dictMap = dictDataMap
57   - wsCache.set(CACHE_KEY.DICT_CACHE, dictDataMap, { exp: 60 }) // 60 秒 过期
  64 + this.dictMap = dictDataMap
  65 + this.isSetDict = true
  66 + wsCache.set(CACHE_KEY.DICT_CACHE, dictDataMap, { exp: 60 }) // 60 秒 过期
  67 + }
58 68 }
59 69 }
60 70 })
... ...
yudao-ui-admin-vue3/src/utils/auth.ts
... ... @@ -36,45 +36,30 @@ export const formatToken = (token: string): string =&gt; {
36 36 }
37 37 // ========== 账号相关 ==========
38 38  
39   -const UsernameKey = 'USERNAME'
40   -const PasswordKey = 'PASSWORD'
41   -const RememberMeKey = 'REMEMBER_ME'
  39 +const LoginFormKey = 'LOGINFORM'
42 40  
43   -export const getUsername = () => {
44   - return wsCache.get(UsernameKey)
  41 +export type LoginFormType = {
  42 + tenantName: string
  43 + username: string
  44 + password: string
  45 + rememberMe: boolean
45 46 }
46 47  
47   -export const setUsername = (username: string) => {
48   - wsCache.set(UsernameKey, username, { exp: 30 * 24 * 60 * 60 })
  48 +export const getLoginForm = () => {
  49 + const loginForm: LoginFormType = wsCache.get(LoginFormKey)
  50 + if (loginForm) {
  51 + loginForm.password = decrypt(loginForm.password) as string
  52 + }
  53 + return loginForm
49 54 }
50 55  
51   -export const removeUsername = () => {
52   - wsCache.delete(UsernameKey)
  56 +export const setLoginForm = (loginForm: LoginFormType) => {
  57 + loginForm.password = encrypt(loginForm.password) as string
  58 + wsCache.set(LoginFormKey, loginForm, { exp: 30 * 24 * 60 * 60 })
53 59 }
54 60  
55   -export const getPassword = () => {
56   - const password = wsCache.get(PasswordKey)
57   - return password ? decrypt(password) : undefined
58   -}
59   -
60   -export const setPassword = (password: string) => {
61   - wsCache.set(PasswordKey, encrypt(password), { exp: 30 * 24 * 60 * 60 })
62   -}
63   -
64   -export const removePassword = () => {
65   - wsCache.delete(PasswordKey)
66   -}
67   -
68   -export const getRememberMe = () => {
69   - return wsCache.get(RememberMeKey) === true
70   -}
71   -
72   -export const setRememberMe = (rememberMe: boolean) => {
73   - wsCache.set(RememberMeKey, rememberMe, { exp: 30 * 24 * 60 * 60 })
74   -}
75   -
76   -export const removeRememberMe = () => {
77   - wsCache.delete(RememberMeKey)
  61 +export const removeLoginForm = () => {
  62 + wsCache.delete(LoginFormKey)
78 63 }
79 64  
80 65 // ========== 租户相关 ==========
... ...
yudao-ui-admin-vue3/src/views/Login/components/LoginForm.vue
... ... @@ -148,7 +148,6 @@ import { useIcon } from &#39;@/hooks/web/useIcon&#39;
148 148 import { useMessage } from '@/hooks/web/useMessage'
149 149 import { required } from '@/utils/formRules'
150 150 import * as authUtil from '@/utils/auth'
151   -import { decrypt } from '@/utils/jsencrypt'
152 151 import { Verify } from '@/components/Verifition'
153 152 import { usePermissionStore } from '@/store/modules/permission'
154 153 import * as LoginApi from '@/api/login'
... ... @@ -180,10 +179,6 @@ const loginData = reactive({
180 179 isShowPassword: false,
181 180 captchaEnable: import.meta.env.VITE_APP_CAPTCHA_ENABLE,
182 181 tenantEnable: import.meta.env.VITE_APP_TENANT_ENABLE,
183   - token: '',
184   - loading: {
185   - signIn: false
186   - },
187 182 loginForm: {
188 183 tenantName: '芋道源码',
189 184 username: 'admin',
... ... @@ -194,22 +189,10 @@ const loginData = reactive({
194 189 })
195 190  
196 191 const socialList = [
197   - {
198   - icon: 'ant-design:github-filled',
199   - type: 0
200   - },
201   - {
202   - icon: 'ant-design:wechat-filled',
203   - type: 30
204   - },
205   - {
206   - icon: 'ant-design:alipay-circle-filled',
207   - type: 0
208   - },
209   - {
210   - icon: 'ant-design:dingtalk-circle-filled',
211   - type: 20
212   - }
  192 + { icon: 'ant-design:github-filled', type: 0 },
  193 + { icon: 'ant-design:wechat-filled', type: 30 },
  194 + { icon: 'ant-design:alipay-circle-filled', type: 0 },
  195 + { icon: 'ant-design:dingtalk-circle-filled', type: 20 }
213 196 ]
214 197  
215 198 // 获取验证码
... ... @@ -232,18 +215,15 @@ const getTenantId = async () =&gt; {
232 215 }
233 216 // 记住我
234 217 const getCookie = () => {
235   - const username = authUtil.getUsername()
236   - const password = authUtil.getPassword()
237   - ? decrypt(authUtil.getPassword() as unknown as string)
238   - : undefined
239   - const rememberMe = authUtil.getRememberMe()
240   - const tenantName = authUtil.getTenantName()
241   - loginData.loginForm = {
242   - ...loginData.loginForm,
243   - username: username ? username : loginData.loginForm.username,
244   - password: password ? password : loginData.loginForm.password,
245   - rememberMe: rememberMe ? true : false,
246   - tenantName: tenantName ? tenantName : loginData.loginForm.tenantName
  218 + const loginForm = authUtil.getLoginForm()
  219 + if (loginForm) {
  220 + loginData.loginForm = {
  221 + ...loginData.loginForm,
  222 + username: loginForm.username ? loginForm.username : loginData.loginForm.username,
  223 + password: loginForm.password ? loginForm.password : loginData.loginForm.password,
  224 + rememberMe: loginForm.rememberMe ? true : false,
  225 + tenantName: loginForm.tenantName ? loginForm.tenantName : loginData.loginForm.tenantName
  226 + }
247 227 }
248 228 }
249 229 // 登录
... ... @@ -266,15 +246,9 @@ const handleLogin = async (params) =&gt; {
266 246 background: 'rgba(0, 0, 0, 0.7)'
267 247 })
268 248 if (loginData.loginForm.rememberMe) {
269   - authUtil.setUsername(loginData.loginForm.username)
270   - authUtil.setPassword(loginData.loginForm.password)
271   - authUtil.setRememberMe(loginData.loginForm.rememberMe)
272   - authUtil.setTenantName(loginData.loginForm.tenantName)
  249 + authUtil.setLoginForm(loginData.loginForm)
273 250 } else {
274   - authUtil.removeUsername()
275   - authUtil.removePassword()
276   - authUtil.removeRememberMe()
277   - authUtil.removeTenantName()
  251 + authUtil.removeLoginForm()
278 252 }
279 253 authUtil.setToken(res)
280 254 if (!redirect.value) {
... ...
yudao-ui-admin-vue3/src/views/infra/fileList/fileList.data.ts
... ... @@ -23,7 +23,7 @@ const crudSchemas = reactive&lt;VxeCrudSchema&gt;({
23 23 field: 'url',
24 24 table: {
25 25 cellRender: {
26   - name: 'XImg'
  26 + name: 'XPreview'
27 27 }
28 28 }
29 29 },
... ...
yudao-ui-admin-vue3/src/views/infra/webSocket/index.vue 0 → 100644
  1 +<template>
  2 + <div class="flex">
  3 + <el-card class="w-1/2" :gutter="12" shadow="always">
  4 + <template #header>
  5 + <div class="card-header">
  6 + <span>连接</span>
  7 + </div>
  8 + </template>
  9 + <div class="flex items-center">
  10 + <span class="text-lg font-medium mr-4"> 连接状态: </span>
  11 + <el-tag :color="getTagColor">{{ status }}</el-tag>
  12 + </div>
  13 + <hr class="my-4" />
  14 +
  15 + <div class="flex">
  16 + <el-input v-model="server" disabled>
  17 + <template #prepend> 服务地址 </template>
  18 + </el-input>
  19 + <el-button :type="getIsOpen ? 'danger' : 'primary'" @click="toggle">
  20 + {{ getIsOpen ? '关闭连接' : '开启连接' }}
  21 + </el-button>
  22 + </div>
  23 + <p class="text-lg font-medium mt-4">设置</p>
  24 + <hr class="my-4" />
  25 + <el-input
  26 + v-model="sendValue"
  27 + :autosize="{ minRows: 2, maxRows: 4 }"
  28 + type="textarea"
  29 + :disabled="!getIsOpen"
  30 + clearable
  31 + />
  32 + <el-button type="primary" block class="mt-4" :disabled="!getIsOpen" @click="handlerSend">
  33 + 发送
  34 + </el-button>
  35 + </el-card>
  36 + <el-card class="w-1/2" :gutter="12" shadow="always">
  37 + <template #header>
  38 + <div class="card-header">
  39 + <span>消息记录</span>
  40 + </div>
  41 + </template>
  42 + <div class="max-h-80 overflow-auto">
  43 + <ul>
  44 + <li v-for="item in getList" class="mt-2" :key="item.time">
  45 + <div class="flex items-center">
  46 + <span class="mr-2 text-primary font-medium">收到消息:</span>
  47 + <span>{{ dayjs(item.time).format('YYYY-MM-DD HH:mm:ss') }}</span>
  48 + </div>
  49 + <div>
  50 + {{ item.res }}
  51 + </div>
  52 + </li>
  53 + </ul>
  54 + </div>
  55 + </el-card>
  56 + </div>
  57 +</template>
  58 +<script setup lang="ts">
  59 +import { computed, reactive, ref, watchEffect } from 'vue'
  60 +import { ElCard, ElInput, ElTag } from 'element-plus'
  61 +import { useWebSocket } from '@vueuse/core'
  62 +import dayjs from 'dayjs'
  63 +import { useUserStore } from '@/store/modules/user'
  64 +
  65 +const userStore = useUserStore()
  66 +
  67 +const sendValue = ref('')
  68 +
  69 +const server = ref(
  70 + (import.meta.env.VITE_BASE_URL + '/websocket/message').replace('http', 'ws') +
  71 + '?userId=' +
  72 + userStore.getUser.id
  73 +)
  74 +
  75 +const state = reactive({
  76 + recordList: [] as { id: number; time: number; res: string }[]
  77 +})
  78 +
  79 +const { status, data, send, close, open } = useWebSocket(server.value, {
  80 + autoReconnect: false,
  81 + heartbeat: true
  82 +})
  83 +
  84 +watchEffect(() => {
  85 + if (data.value) {
  86 + try {
  87 + const res = JSON.parse(data.value)
  88 + state.recordList.push(res)
  89 + } catch (error) {
  90 + state.recordList.push({
  91 + res: data.value,
  92 + id: Math.ceil(Math.random() * 1000),
  93 + time: new Date().getTime()
  94 + })
  95 + }
  96 + }
  97 +})
  98 +
  99 +const getIsOpen = computed(() => status.value === 'OPEN')
  100 +const getTagColor = computed(() => (getIsOpen.value ? 'success' : 'red'))
  101 +
  102 +const getList = computed(() => {
  103 + return [...state.recordList].reverse()
  104 +})
  105 +
  106 +function handlerSend() {
  107 + send(sendValue.value)
  108 + sendValue.value = ''
  109 +}
  110 +
  111 +function toggle() {
  112 + if (getIsOpen.value) {
  113 + close()
  114 + } else {
  115 + open()
  116 + }
  117 +}
  118 +</script>
... ...
yudao-ui-admin-vue3/src/views/system/tenantPackage/index.vue
... ... @@ -146,7 +146,6 @@ const submitForm = async () =&gt; {
146 146 ...(treeRef.value!.getCheckedKeys(false) as unknown as Array<number>),
147 147 ...(treeRef.value!.getHalfCheckedKeys() as unknown as Array<number>)
148 148 ]
149   - console.info(data.menuIds)
150 149 if (actionType.value === 'create') {
151 150 await TenantPackageApi.createTenantPackageTypeApi(data)
152 151 message.success(t('common.createSuccess'))
... ...
yudao-ui-admin/src/views/infra/webSocket/index.vue 0 → 100644
  1 +<template>
  2 + <div class="app-container">
  3 + <el-form label-width="120px">
  4 + <el-row type="flex" :gutter="0">
  5 + <el-col :sm="12">
  6 + <el-form-item label="WebSocket地址" size="small">
  7 + <el-input v-model="url" type="text"/>
  8 + </el-form-item>
  9 + </el-col>
  10 + <el-col :offset="1">
  11 + <el-form-item label="" label-width="0px" size="small">
  12 + <el-button @click="connect" type="primary" :disabled="ws&&ws.readyState===1">
  13 + {{ ws && ws.readyState === 1 ? "已连接" : "连接" }}
  14 + </el-button>
  15 + <el-button @click="exit" type="danger">断开</el-button>
  16 + </el-form-item>
  17 + </el-col>
  18 + </el-row>
  19 + <el-form-item label="发送内容" size="small">
  20 + <el-input type="textarea" v-model="message" :rows="5"/>
  21 + </el-form-item>
  22 + <el-form-item label="" size="small">
  23 + <el-button type="success" @click="send">发送消息</el-button>
  24 + </el-form-item>
  25 + <el-form-item label="接收内容" size="small">
  26 + <el-input type="textarea" v-model="content" :rows="12" disabled/>
  27 + </el-form-item>
  28 + <el-form-item label="" size="small">
  29 + <el-button type="info" @click="content=''">清空消息</el-button>
  30 + </el-form-item>
  31 + </el-form>
  32 + </div>
  33 +</template>
  34 +
  35 +<script>
  36 +import store from "@/store";
  37 +import {getNowDateTime} from "@/utils/ruoyi";
  38 +
  39 +export default {
  40 + data() {
  41 + return {
  42 + url: process.env.VUE_APP_BASE_API + "/websocket/message",
  43 + message: "",
  44 + content: "",
  45 + ws: null,
  46 + };
  47 + },
  48 + created() {
  49 + this.url = this.url.replace("http", "ws")
  50 + },
  51 + methods: {
  52 + connect() {
  53 + if (!'WebSocket' in window) {
  54 + this.$modal.msgError("您的浏览器不支持WebSocket");
  55 + return;
  56 + }
  57 + const userId = store.getters.userId;
  58 + this.ws = new WebSocket(this.url + "?userId=" + userId);
  59 + const self = this;
  60 + this.ws.onopen = function (event) {
  61 + self.content = self.content + "\n**********************连接开始**********************\n";
  62 + };
  63 + this.ws.onmessage = function (event) {
  64 + self.content = self.content + "接收时间:" + getNowDateTime() + "\n" + event.data + "\n";
  65 + };
  66 + this.ws.onclose = function (event) {
  67 + self.content = self.content + "**********************连接关闭**********************\n";
  68 + };
  69 + this.ws.error = function (event) {
  70 + self.content = self.content + "**********************连接异常**********************\n";
  71 + };
  72 + },
  73 + exit() {
  74 + if (this.ws) {
  75 + this.ws.close();
  76 + this.ws = null;
  77 + }
  78 + },
  79 + send() {
  80 + if (!this.ws || this.ws.readyState !== 1) {
  81 + this.$modal.msgError("未连接到服务器");
  82 + return;
  83 + }
  84 + if (!this.message) {
  85 + this.$modal.msgError("请输入发送内容");
  86 + return;
  87 + }
  88 + this.ws.send(this.message);
  89 + }
  90 + },
  91 +};
  92 +</script>
... ...