From a70b3624108487f3f4bf5fc3e3deb8b4402ed903 Mon Sep 17 00:00:00 2001 From: Gary <3489015381@qq.com> Date: Wed, 11 Dec 2024 18:14:34 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90websocket=E6=A1=86=E6=9E=B6?= =?UTF-8?q?=E6=90=AD=E5=BB=BA=EF=BC=8C=E5=B0=86excel=E8=A1=A8=E6=A0=BC?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E8=BF=9B=E8=A1=8C=E8=AF=BB=E5=85=A5=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E6=88=90=E5=8A=9F=E3=80=82=E9=9C=80=E8=A6=81=E8=BF=9B?= =?UTF-8?q?=E8=A1=8C=E5=B0=81=E8=A3=85=E5=90=8E=E8=BF=94=E5=9B=9E=E5=89=8D?= =?UTF-8?q?=E7=AB=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/compiler.xml | 6 + .idea/uiDesigner.xml | 124 ++++++++ pom.xml | 299 +++++++++++++++--- .../gary/exercise/config/WebSocketConfig.java | 18 +- .../controller/ExerciseController.java | 4 + .../exercise/controller/TestController.java | 4 + .../java/com/gary/exercise/dto/ActionDto.java | 15 + .../exception/ReadExcelException.java | 7 + .../exercise/service/ExerciseService.java | 28 ++ .../service/impl/ExerciseServiceImpl.java | 78 +++++ .../socket/ExerciseWebSocketHandler.java | 80 +++++ src/main/resources/application.yaml | 0 src/main/resources/exercise.xlsx | Bin 0 -> 9752 bytes .../exercise/ExerciseApplicationTests.java | 14 + target/classes/application.yaml | 0 .../gary/exercise/ExerciseApplication.class | Bin 0 -> 747 bytes .../exercise/config/WebSocketConfig.class | Bin 0 -> 1480 bytes .../controller/ExerciseController.class | Bin 0 -> 337 bytes .../exercise/controller/TestController.class | Bin 0 -> 325 bytes .../com/gary/exercise/dto/ActionDto.class | Bin 0 -> 2828 bytes .../exception/ReadExcelException.class | Bin 0 -> 439 bytes .../exercise/service/ExerciseService.class | Bin 0 -> 577 bytes .../service/impl/ExerciseServiceImpl$1.class | Bin 0 -> 943 bytes .../service/impl/ExerciseServiceImpl.class | Bin 0 -> 5075 bytes .../socket/ExerciseWebSocketHandler.class | Bin 0 -> 5509 bytes target/classes/exercise.xlsx | Bin 0 -> 9752 bytes .../exercise/ExerciseApplicationTests.class | Bin 0 -> 1944 bytes 27 files changed, 629 insertions(+), 48 deletions(-) create mode 100644 .idea/uiDesigner.xml create mode 100644 src/main/java/com/gary/exercise/controller/ExerciseController.java create mode 100644 src/main/java/com/gary/exercise/controller/TestController.java create mode 100644 src/main/java/com/gary/exercise/dto/ActionDto.java create mode 100644 src/main/java/com/gary/exercise/exception/ReadExcelException.java create mode 100644 src/main/java/com/gary/exercise/service/ExerciseService.java create mode 100644 src/main/java/com/gary/exercise/service/impl/ExerciseServiceImpl.java create mode 100644 src/main/java/com/gary/exercise/socket/ExerciseWebSocketHandler.java create mode 100644 src/main/resources/application.yaml create mode 100644 src/main/resources/exercise.xlsx create mode 100644 target/classes/application.yaml create mode 100644 target/classes/com/gary/exercise/ExerciseApplication.class create mode 100644 target/classes/com/gary/exercise/config/WebSocketConfig.class create mode 100644 target/classes/com/gary/exercise/controller/ExerciseController.class create mode 100644 target/classes/com/gary/exercise/controller/TestController.class create mode 100644 target/classes/com/gary/exercise/dto/ActionDto.class create mode 100644 target/classes/com/gary/exercise/exception/ReadExcelException.class create mode 100644 target/classes/com/gary/exercise/service/ExerciseService.class create mode 100644 target/classes/com/gary/exercise/service/impl/ExerciseServiceImpl$1.class create mode 100644 target/classes/com/gary/exercise/service/impl/ExerciseServiceImpl.class create mode 100644 target/classes/com/gary/exercise/socket/ExerciseWebSocketHandler.class create mode 100644 target/classes/exercise.xlsx create mode 100644 target/test-classes/com/gary/exercise/ExerciseApplicationTests.class diff --git a/.idea/compiler.xml b/.idea/compiler.xml index d7e145d..094edb7 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -2,6 +2,7 @@ + @@ -10,4 +11,9 @@ + + + \ No newline at end of file diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 0000000..2b63946 --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index a022880..1dc68e5 100644 --- a/pom.xml +++ b/pom.xml @@ -2,71 +2,276 @@ 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.1.0 + + + + + + + com.gary - exercise + exercise-vision 0.0.1-SNAPSHOT - exercise - exercise + 体育直播可视化系统 + jar + + + + - 1.8 - UTF-8 - UTF-8 - 2.6.13 + 17 + 0.11.5 + 6.0.0 + + org.springframework.boot - spring-boot-starter + spring-boot-starter-web + + + + + org.apache.poi + poi-ooxml + 5.2.3 + + + org.apache.poi + poi + 5.2.3 + + org.springframework + spring-test + ${spring.version} + test + + + + + commons-fileupload + commons-fileupload + 1.4 + + + commons-io + commons-io + 2.11.0 + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + + + org.springframework.boot + spring-boot-starter-mail + + + + + org.springframework.boot + spring-boot-starter-data-redis + + + + + com.baomidou + mybatis-plus-spring-boot3-starter + 3.5.7 + + + + + mysql + mysql-connector-java + 8.0.28 + + + + + + org.apache.pdfbox + pdfbox + 2.0.28 + + + + + io.jsonwebtoken + jjwt-api + ${jjwt.version} + + + io.jsonwebtoken + jjwt-impl + ${jjwt.version} + runtime + + + io.jsonwebtoken + jjwt-jackson + ${jjwt.version} + runtime + + + + + org.projectlombok + lombok + 1.18.34 + provided + + + org.springframework.boot spring-boot-starter-test test + + org.springframework.boot + spring-boot-testcontainers + test + + + org.springframework.restdocs + spring-restdocs-mockmvc + test + + + org.testcontainers + junit-jupiter + test + + + org.testcontainers + mssqlserver + test + + + + + org.springdoc + springdoc-openapi-starter-webmvc-ui + 2.2.0 + + + + + com.baidubce + qianfan + 0.1.0 + + + com.sun.mail + javax.mail + 1.6.2 + + + org.hibernate + hibernate-validator + 8.0.0.Final + + + org.modelmapper + modelmapper + 3.1.1 + + + com.github.chrislusf + seaweedfs-client + 3.55 + + + io.minio + minio + 8.5.5 + + + com.aliyun + dysmsapi20170525 + 3.0.0 + + + com.aliyun + aliyun-java-sdk-core + 4.5.0 + + + com.aliyun + aliyun-java-sdk-dysmsapi + 2.0.0 + + + com.aliyun + dysmsapi20170525 + 3.0.0 + + + + + + com.alibaba + fastjson + 1.2.78 + + + + com.aliyun + aliyun-java-sdk-core + 3.2.6 + + + com.aliyun + aliyun-java-sdk-dysmsapi + 1.0.0 + + + + org.apache.poi + poi + 5.2.3 + + + org.apache.poi + poi-ooxml + 5.2.3 + + + + cn.hutool + hutool-all + 5.7.17 + + + + + org.apache.tomcat.embed + tomcat-embed-core + 10.1.26 + + + org.springframework.boot + spring-boot-starter-websocket + - - - - org.springframework.boot - spring-boot-dependencies - ${spring-boot.version} - pom - import - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.1 - - 1.8 - 1.8 - UTF-8 - - - - org.springframework.boot - spring-boot-maven-plugin - ${spring-boot.version} - - com.gary.exercise.ExerciseApplication - true - - - - repackage - - repackage - - - - + + - diff --git a/src/main/java/com/gary/exercise/config/WebSocketConfig.java b/src/main/java/com/gary/exercise/config/WebSocketConfig.java index 091cf0c..5c5daa1 100644 --- a/src/main/java/com/gary/exercise/config/WebSocketConfig.java +++ b/src/main/java/com/gary/exercise/config/WebSocketConfig.java @@ -1,4 +1,20 @@ package com.gary.exercise.config; +import com.gary.exercise.socket.ExerciseWebSocketHandler; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.config.annotation.EnableWebSocket; +import org.springframework.web.socket.config.annotation.WebSocketConfigurer; +import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; +/** + *配置类 引入websocket的处理器 + */ +@Configuration +@EnableWebSocket +public class WebSocketConfig implements WebSocketConfigurer { -public class WebSocketConfig { + @Override + public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { + // 注册 WebSocket 的处理器 + registry.addHandler(new ExerciseWebSocketHandler(), "/exercise") // 定义路径 /exercise + .setAllowedOrigins("*"); // 设置允许的跨域请求 + } } diff --git a/src/main/java/com/gary/exercise/controller/ExerciseController.java b/src/main/java/com/gary/exercise/controller/ExerciseController.java new file mode 100644 index 0000000..43d1e38 --- /dev/null +++ b/src/main/java/com/gary/exercise/controller/ExerciseController.java @@ -0,0 +1,4 @@ +package com.gary.exercise.controller; + +public class ExerciseController { +} diff --git a/src/main/java/com/gary/exercise/controller/TestController.java b/src/main/java/com/gary/exercise/controller/TestController.java new file mode 100644 index 0000000..3941b5a --- /dev/null +++ b/src/main/java/com/gary/exercise/controller/TestController.java @@ -0,0 +1,4 @@ +package com.gary.exercise.controller; + +public class TestController { +} diff --git a/src/main/java/com/gary/exercise/dto/ActionDto.java b/src/main/java/com/gary/exercise/dto/ActionDto.java new file mode 100644 index 0000000..ba47590 --- /dev/null +++ b/src/main/java/com/gary/exercise/dto/ActionDto.java @@ -0,0 +1,15 @@ +package com.gary.exercise.dto; + +import lombok.Data; + +/** + *返回用户操作 + */ +@Data +public class ActionDto { + private String human; + + private String action; + + private String description; +} diff --git a/src/main/java/com/gary/exercise/exception/ReadExcelException.java b/src/main/java/com/gary/exercise/exception/ReadExcelException.java new file mode 100644 index 0000000..9a63de8 --- /dev/null +++ b/src/main/java/com/gary/exercise/exception/ReadExcelException.java @@ -0,0 +1,7 @@ +package com.gary.exercise.exception; + +public class ReadExcelException extends RuntimeException{ + public ReadExcelException(String message) { + super(message); + } +} diff --git a/src/main/java/com/gary/exercise/service/ExerciseService.java b/src/main/java/com/gary/exercise/service/ExerciseService.java new file mode 100644 index 0000000..ef11512 --- /dev/null +++ b/src/main/java/com/gary/exercise/service/ExerciseService.java @@ -0,0 +1,28 @@ +package com.gary.exercise.service; + +import java.util.List; +import java.util.Map; + +/** + * @author Gary + * @date 2024/12/11 下午4:13 + * @description: 读取和处理文件流 + */ +public interface ExerciseService { + + /** + * 读取 Excel 文件中的某一行数据,并存储在 List 中返回 + * + * @param filepath Excel 文件路径 + * @param line 要读取的行号(从 1 开始) + * @return List 包含这一行的所有数据 + */ + List readExcelByLine(String filepath, Integer line); + + + /** + *获取excel中的详细信息 + */ + Map getDetailInformation(String filepath, Integer line); + +} diff --git a/src/main/java/com/gary/exercise/service/impl/ExerciseServiceImpl.java b/src/main/java/com/gary/exercise/service/impl/ExerciseServiceImpl.java new file mode 100644 index 0000000..7f97096 --- /dev/null +++ b/src/main/java/com/gary/exercise/service/impl/ExerciseServiceImpl.java @@ -0,0 +1,78 @@ +package com.gary.exercise.service.impl; + +import com.gary.exercise.service.ExerciseService; +import org.apache.poi.ss.usermodel.*; + +import java.io.FileInputStream; +import java.io.IOException; +import java.util.*; + +public class ExerciseServiceImpl implements ExerciseService { + + @Override + public List readExcelByLine(String filepath, Integer line) { + List result = new ArrayList<>(); + try{ + FileInputStream fis = new FileInputStream(filepath); + Workbook workbook = WorkbookFactory.create(fis); + Sheet sheet = workbook.getSheetAt(0); + Row dataRow = sheet.getRow(line - 1); //获取第i行的数据 + if (dataRow == null) { + throw new IllegalArgumentException("指定的行不存在或文件为空"); + } + for (int i = 0; i < dataRow.getLastCellNum(); i++) { + Cell cell = dataRow.getCell(i); + String cellValue = getCellValue(cell); + result.add(cellValue); + } + } catch (IOException e) { + throw new RuntimeException("读取 Excel 文件失败: " + e.getMessage(), e); + } + return result; + } + + @Override + public Map getDetailInformation(String filepath, Integer line) { + + Map result =new HashMap<>(); + List readResult= readExcelByLine(filepath, line);//获取读取到的结果 + if(readResult.isEmpty()) { + throw new RuntimeException("读取到的结果为空"); + }else if(readResult.size()==1){//说明是第一第二节开始的标志 + result.put("now_class",readResult.get(0)); + }else if(Objects.equals(readResult.get(0), "时间")) { + return null; + }else{ + result.put("time",readResult.get(0));//获取当前时间 + result.put("laker_action",readResult.get(1));//获取当前湖人队的动作 + result.put("score",readResult.get(2));//获取当前比分 + result.put("wolf_action",readResult.get(3));//获取当前森林狼队的动作 + } + return result; + } + + /** + * 获取单元格的值,并转换为字符串 + */ + private String getCellValue(Cell cell) { + if (cell == null) { + return ""; + } + return switch (cell.getCellType()) { + case STRING -> cell.getStringCellValue(); + case NUMERIC -> { + if (DateUtil.isCellDateFormatted(cell)) { + yield cell.getDateCellValue().toString(); + } + yield String.valueOf(cell.getNumericCellValue()); + } + case BOOLEAN -> String.valueOf(cell.getBooleanCellValue()); + case FORMULA -> cell.getCellFormula(); + case BLANK -> ""; + default -> "UNKNOWN"; + }; + } + + + +} diff --git a/src/main/java/com/gary/exercise/socket/ExerciseWebSocketHandler.java b/src/main/java/com/gary/exercise/socket/ExerciseWebSocketHandler.java new file mode 100644 index 0000000..5c0c716 --- /dev/null +++ b/src/main/java/com/gary/exercise/socket/ExerciseWebSocketHandler.java @@ -0,0 +1,80 @@ +package com.gary.exercise.socket; +import org.jetbrains.annotations.NotNull; +import org.springframework.web.socket.*; +import java.io.IOException; +import java.util.concurrent.ConcurrentHashMap; + +public class ExerciseWebSocketHandler implements WebSocketHandler { + + // 用于存储所有的 WebSocket 会话 + private static final ConcurrentHashMap sessions = new ConcurrentHashMap<>(); + + @Override + public void afterConnectionEstablished(WebSocketSession session) throws Exception { + // 当连接建立时触发 + String sessionId = session.getId(); + sessions.put(sessionId, session); + System.out.println("WebSocket连接已建立: " + sessionId); + + // 发送欢迎消息 + session.sendMessage(new TextMessage("欢迎连接到 WebSocket 服务,您的会话 ID 是: " + sessionId)); + } + + @Override + public void handleMessage(@NotNull WebSocketSession session, @NotNull WebSocketMessage message) throws Exception { + // 处理接收到的消息 + if (message instanceof TextMessage) { + String clientMessage = ((TextMessage) message).getPayload(); + System.out.println("收到消息: " + clientMessage); + + // 回复客户端 + session.sendMessage(new TextMessage("服务器收到消息: " + clientMessage)); + } else { + System.out.println("不支持的消息类型: " + message.getClass().getName()); + } + } + + @Override + public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { + // 处理传输错误 + String sessionId = session.getId(); + System.out.println("WebSocket 传输错误,Session ID: " + sessionId + ", 错误: " + exception.getMessage()); + + // 关闭会话 + if (session.isOpen()) { + session.close(CloseStatus.SERVER_ERROR); + } + + // 从存储中移除会话 + sessions.remove(sessionId); + } + + @Override + public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception { + // 当连接关闭时触发 + String sessionId = session.getId(); + System.out.println("WebSocket连接已关闭,Session ID: " + sessionId + ", 状态: " + closeStatus); + + // 从存储中移除会话 + sessions.remove(sessionId); + } + + @Override + public boolean supportsPartialMessages() { + // 不支持部分消息 + return false; + } + + // 广播消息给所有连接的客户端 + public void broadcastMessage(String message) { + for (WebSocketSession session : sessions.values()) { + if (session.isOpen()) { + try { + session.sendMessage(new TextMessage(message)); + } catch (IOException e) { + System.out.println("广播消息失败,Session ID: " + session.getId() + ", 错误: " + e.getMessage()); + } + } + } + } +} diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/exercise.xlsx b/src/main/resources/exercise.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..f204e665a2a6f0c91cc8445b74a5ea4ae75f5266 GIT binary patch literal 9752 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.getDetailInformation(filepath,line); + /* List result = service.readExcelByLine(filepath, line);*/ + System.out.println("读取结果:"+result); + + } } diff --git a/target/classes/application.yaml b/target/classes/application.yaml new file mode 100644 index 0000000..e69de29 diff --git a/target/classes/com/gary/exercise/ExerciseApplication.class b/target/classes/com/gary/exercise/ExerciseApplication.class new file mode 100644 index 0000000000000000000000000000000000000000..0efc66021c779966c7b4c2fc4c316ed4db6af7de GIT binary patch literal 747 zcma)4O>@&Q5PeFMI!V)}O-pHk9(w4I=1|>w3C#>-;AB3AFyX*Sc2!5kmNK$j%Fp6d zhC_bxGE*OXz%$;J_T%m9?f(Ar>mI-bj=E@IEkLt}7Shvsn7|3A6?7X zF|5B(TDb|s+VFH9pv`a+n~W#Ie&_O5+F0e1zg`_)E|;l_g;Pd%(Zxo9UJsktVi*~l z@O){NPOhxTPpJwYBH~ANEPbFI7UEQ!flk{#-$_~lizW@xdOSca8@Q6Ts@_7jcvec5NgUsPej;{X5v literal 0 HcmV?d00001 diff --git a/target/classes/com/gary/exercise/config/WebSocketConfig.class b/target/classes/com/gary/exercise/config/WebSocketConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..ad45413781fc21486720edb16dabd2d731e4b06b GIT binary patch literal 1480 zcmcgsT~8B16g`&~wv@`ZD1HGd*cN5ui!W6ZM2yA)hME%M({y)O2HIUSJGJzO_(Oam zYV-&Aql|aAOHm{iiScFb-r1RR&b@Q*{r3ISR{)P-XVHh0g>(-67$A)9iFd-T3*WOh zYJ1W#gn@_3SLQJxl`m8+WC-`2pkaGLw{3YKwWC65hk>&%jlG)qTe4P(cb*I1txKJS z6|oHcLQpYU`CbMW2!mauA&g+u!dMRDm>|3ev}cEJqk}tIG-NB#`*us#jtHH=-%*|| zd_OS4sKB>RQg2F6g+{jtS>d{g9>V*4xd-$~pwgT2adJA^ONCw_XVw>sFJ*9%K*b?k z!etB7Ib6Y2!defde@8+X3#D1E*MpXHH?;DU9}?XBe+bXQbwd94>PZ6VW_%@nRSPqO zr{|BogVNMe6VfYzD+wcI<;(SEqbBuhQLFRLcsX!Hy(+Yd{A4q2b`|HOSU#)N5@A}$ zg(h`3ilo*UXuW5#o%spdr9zdE>5xTL{qmocV4I^DU6W=va9@e2*^JaIK3fTz+L6yx zl&;Bcbe-%jMJ>U>Z#I3S8nUWF#c5pbwjEK*vJF(bLSqtSEm&SPfoqq`cw0- z`q3+PHI^`kYdqixH+b4bmWLd#v+UVyiEV%J5cDDbJ;!VG8_3~iyv7G`3%A)L%wvH; zX8F6u=la+#EPjTyeTc#I7i70nQE&)FPWirCu literal 0 HcmV?d00001 diff --git a/target/classes/com/gary/exercise/controller/ExerciseController.class b/target/classes/com/gary/exercise/controller/ExerciseController.class new file mode 100644 index 0000000000000000000000000000000000000000..a483a84afce78b090df7e47152a18b1efc5cccf4 GIT binary patch literal 337 zcmb7Re&=B9iiI?7@Xm2icLz58MTBhXUzjkcY{L)hWzFGP*G|Z3<&AbT9c=Um zn6eDdpH_}<3hXMa~2$9y=8vzMQ(bxu3 S9E4fBbPts2}_~7{0Y>@ZsMTE>b2Op^~WSkX#8Xx+|o%43wvDpp6(AYSGjN Ta_or?w{Z0)FJRNF%z?7-@#gj2!zT zyier=;*A$cRYIz~NF^JmD&G{xxjj7+gQNqGByTbGn}q@&C(9{AC<&I z;n$o%l(s{!bh#Efp1T}+40^rQ1Lwuxi|0`L@Ly45L#CR+VpMno6>8!bTpi6L?32*Hs3`r=}C=I0sq& zDI0G{VnayQKyE*6Cw`6pfqRYwTQaEelZM;M8tMj0~3DW?Tz%Qhe1jHbA$Hwh6zt5RCFL{*TdlRH*=RB0Ifi2jaVR#l8S>ih8sCcr)Ymsw z*H$R6RWgt-f>uKwnf4paLYv+$9HOy8Pl-SYZ+b1iCayZNNyDmeIy&d%c_DqScwQKU zKHpP91tSL5GPsFbCf231K4T~x94*Iv;O&Z%;#Ow6N-22$BZlvjHj9CZ^g4I98zLxF zJ#V+QSLtUd8;njY^lM6Km;bpNN0OQ=vSMG&lx8EA4>gGLST{(eTt57nm*~iqfts;SJ9L1 zD0&WpoCkyAvotHwjL}n{`3>yn2sTHbMijJgj>fhE5cE9F-i=o;(38mO(ZtO=KTQMAuy(qHH(O@R3CC;eAq3YE&jdsi`qj{1s+@k;W7v7D);y z)o1vC_UZJ^fNYm?ANHpodR2Pa)DHbf5B*2|>9em&FTK*C&-KvLw~rEsU8KSXsL02~ znIEBRPm6!T`T=_SY4HzOYqK-^crBXJVEpDReU!Dizc85Bp5xdP*mHSpA1B+0iLy?R ziL#N`CB}G;+!GAt^}LY)O_ogpO_r^^DM3~YGV@j&q&=mC(h2`5BY&+D?eyp|F5(hZ zIf{qWaSyb{+siKte^iEMa zl_Iyr#w&NRGx?=YG~{b`j-CdQ-pN+xwS}lbr?Qngwa3a9pTL~kN8uY8pD1f`A+NFx3k%}EKRT=YNr3{yb&t&_Y^bFm1?3pI_^sL3}-1dyi~s`S5s+ceA2=nn4T3*`R; DZZrdq literal 0 HcmV?d00001 diff --git a/target/classes/com/gary/exercise/exception/ReadExcelException.class b/target/classes/com/gary/exercise/exception/ReadExcelException.class new file mode 100644 index 0000000000000000000000000000000000000000..2d5000dc5a89e0d9586a7f1666499d4de719478f GIT binary patch literal 439 zcmb7=PfNo<5XIldG|^aXt*GG5n}49`z1oZDDT=hx`!*TUm1HBEjnt3jN$}tY@I#5S zT2Sc8UD$nZc>HFVkI%Pv02kPe;9)I<-$o08z~O^@l5rt*9*-MsRY_Nilpd|Bv_NpK zw6Y_Cz2oFJH?c^P5YbePm--4bjZc!ysPy)P1BZ1eyC literal 0 HcmV?d00001 diff --git a/target/classes/com/gary/exercise/service/ExerciseService.class b/target/classes/com/gary/exercise/service/ExerciseService.class new file mode 100644 index 0000000000000000000000000000000000000000..fe414a354d9d9463220d17c33ed14be9c3856c13 GIT binary patch literal 577 zcmbVJO-}+b6ntHg1^fULe}r7@O%JOcjF=FYXtGx?wLD5mw@bPY0)NeeKfoVld(y-Bu^z9%#olI|Ltk##b)B_%9BKpGdr z7Zp^FgrOAB7+Hr?MPmUqw~}vW)_6s;z*bNDS>0^K*#x{}`*VZzfTXPJ`%w{cMYiw) zuKsT_P*c`>-Rt3waJ%ESvSJoAKJo`~_Fr{fRu$9*2sq%n0U~bi5b6*?%u_RhMs@LN URU{lSeGDgm(Wk7_UM+UM0qXv!00000 literal 0 HcmV?d00001 diff --git a/target/classes/com/gary/exercise/service/impl/ExerciseServiceImpl$1.class b/target/classes/com/gary/exercise/service/impl/ExerciseServiceImpl$1.class new file mode 100644 index 0000000000000000000000000000000000000000..865d1116fab9872c8b7b858fdcd043188a28002a GIT binary patch literal 943 zcmb7DT~8B16g@*rx2=m*M5*8h>RPBDj1cujB`LLFL%TIB-~&&?cG3<`cbnZ7^*nx%9*MRcgI^(w7XGW1)vKW+*S04;mNQ^D>7lau)J7F2QDa=7&Ar5zz^k zpJe2#SaQm9tbEB;udjJ+qi6hXVn>7oj9oH zsK(1Srcog0-tJD_-C`(R%(gk785>tI%V333TLnThq?XHd3)dOukHoRyS_B>LhThQc zZYrtUwI~WBleK8$hRJHVd(GNTy=t@t8#fbeqt$BEDz4FP+qjcxo2{MZUZY~PyEg6_ zZE~Ygakniv425yF*5Q%#2MpO)zE*)6tS6@S8PZki6~lBx1=1b%4rR0}4mBw=jnEf* zUqs6AkvQcIg#Up~bHwvrIE;L`smzYzIZaqG7U=i2z}I1{f=*Kox?$S_XIT6Ho>Bp> zj0bPSm};@>K_H{57I7@&!XjOm`*cZJp=hp*iAZ^X65$fDQ=}*Y_I`k!{>p!Y_0@b+ z-*F|~`i%5;Lg$E1j_Ewn%$VLHYK`e4(QHD$&~wOP7IV0UBH1VrE@2JN316UsH-t63 zgGZRcGTF!^X4X-rc!I`58Vkt3w`fK4oC#?>N|rvx6T&oBXnvX~D_AAWC-qWL$o>WQ C;@#%} literal 0 HcmV?d00001 diff --git a/target/classes/com/gary/exercise/service/impl/ExerciseServiceImpl.class b/target/classes/com/gary/exercise/service/impl/ExerciseServiceImpl.class new file mode 100644 index 0000000000000000000000000000000000000000..66070aa87f4a0228219470a32599dc700fc96e7e GIT binary patch literal 5075 zcmbVQd0Z6d8Gb%km}MCiS5em*&s9OhO^i_sYRaLJieSVeXc`@t0Y-)$GBYb`V`Cdr zO`}cQq+YdYVv}NQlW1x|q>a68)BCXZT~X7!{kMmGzS(721<{t@Z+Bl zxNDe^GTYX6R2z;PfFk+i3XJu34J)$DF!icfTimU4ZCz^(Ab?>~%y5DHg6e)j+%{rO zrG@JP$iqklK^3DgTA;|Xn<8497H!reZI%&noJic!?N+NnHzVsUyJd@IwJg)3u4V6_ zno$aIb%Di6-qavXdTC+x?XWA&#TblLFiu4X;|0REb4Vc2q`P&^y6%<{uo(qaLksgL zO9PmII}}V*F$t3eM)m_z6?63_-4^g0F?XG2#%UG7ugb+#Oj8h6FmrVOQP4Y`$4q$*WVATTve5!2M0G_%ZZinr=9cj@-1-sT!s%#T^*czOTc-dB!ZIlAZS z^ZPHIJ<$8|;of5>F7G>d`QYA5J)M`%p1bnWxd3KjST2e&M?plzow!S2(olMP$_}U2 z)tcj0=%!f{Z}qINlU(jrF%S0$C?t@Z0@H70mn0+B3$ReZTUC^xRA6q@YK=5$_Kt|Y zUALo#qemE6+l;6lFfmEm3f>&x$6zLnNNO=HOIzDqRu!h*20z{*Fz)KBJ-tsI?A>>Y z0e_|E>C4X^>x=M88R3huS%oGO+2GxUL2#N@FfsU@B-;5rZW#tY33NLWV4{0t?gaPO=*)U=W#pJj^3CZ49G~jV!lM;C%|7RIwii1SStvw&X#opDYmx76nYMTb+@VtWHni0}4K< z;zKfkhU_{08Y-6EV8k?2s`-qH56k2ZQh`LwNII`l1#k$56&z7<6d$<-^GY_*wQTFG zGKM2L$c1H=-Kx2+&ayQ9c52=RsnADNJd2MpmZ^|rl2V5{_SGCOuH+^Gcpk?Ud|br~ z(u%aAD7V=MU8^q>p1>zmbl?P4Bx^PY-8Q0W+?lYI0W{;JicjKGOyzB|f7Uk2jH^tK z{^Zmlm3>9Ut1|5+$8yUubuE_SD0!Whyk3(WHr#~685N)LG$#jnRALr4H9xwj!P=S? zHMQ$&6m$y|-aLM9XgbW93QjsKak8$_&@H;XMpj26SZzf$de=7Odvej|HXF>!dDSTFm1>Ki5ZLNH)yWr4HZ*{q?h9lwI;gxDSgvAtkkuU^K6^uHWMw=Yc-?N zjPL6!EReSD#7!!gm)Q2gTsC*|7<0YnnEXlag>Rr;l*T%V>k^(HR_AKb7FMz3vAmVK z+iW$g(rm3&cXgX^=hPWZG0lzJG-XA4iB7UfW89~6GN@CE-bDClnajGX8D>?i(JKn9 z-~t?k`uo`J384WrW<;9JiIsrt=BtzN-E;l+AW99CD=~WT|I+8S*$3*ZxEA`?aX zPQ1m}(2Xg4RYJ-I4C}$n`e0!fiq2=w_viaVN;hT;9LMyKlJD=vToUHY3gvWSeo3G> z6zImH46NVd7ai9wb|6&Z>p^9G$k&Nw=kRtQwp0KSXw(G`9?j_>0Kg!_kFm5xZPT;$4+xUv{o*QmZ4L_|i#$as}o2_%T`JWKb$75BLc`8Tcus{0u)&y7(dLn8o#z zJ-DAPuB(|;u8=SLhP6}FHsSaA7{=%6 z#B2sVKa-vT-nX5_%pZ*Cvdmt>v;*QQ@%Nw^3BPVZ;sP9 zzaUO|oFsoqFZnz#jq&^@_kNYyyU0E1uRQqvjj)0i`f19@e=;%#b-}O6g73>ItLOr$4f8|Kvxb7^0UD{F7Mu~66rIJv zBN)N=WAgNK9Vp`Si?S}f)PYHSepx=B>cA*Ie_Eai1b25JE7&Pf&GfQqF5?hX&WA;e zHVe&@Xj-hY12CqM1I#Lpk_C%y$q@fd%R=f|J%S7H|WFX5A( ABLDyZ literal 0 HcmV?d00001 diff --git a/target/classes/com/gary/exercise/socket/ExerciseWebSocketHandler.class b/target/classes/com/gary/exercise/socket/ExerciseWebSocketHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..3ad2e894877c20d36241628947d318cf916057ee GIT binary patch literal 5509 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 X*K_vuf_=SYUw>|2FWc8n``Z0qF~TDs literal 0 HcmV?d00001 diff --git a/target/classes/exercise.xlsx b/target/classes/exercise.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..f204e665a2a6f0c91cc8445b74a5ea4ae75f5266 GIT binary patch literal 9752 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 literal 0 HcmV?d00001