Popup_Nexacro.jsp 또는 html로 만든다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
<%@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@page import="java.text.SimpleDateFormat"%>
<%@page import="java.util.*"%>
<%
    // 고유한 세션 객체의 ID를 되돌려준다.
    String id_str = session.getId();
 
    // 세션에 마지막으로 엑세스한 시간을 되돌려 준다.
    long lasttime = session.getLastAccessedTime();
   
    // 세션이 생성된 시간을 되돌려 준다.
    long createdtime = session.getCreationTime();
   
    // 세션에 마지막으로 액세스한 시간에서 세션이 생성된 시간을 빼면 웹 사이트에 머문 시간이 계산된다.
    long time_used = (lasttime - createdtime) / 60000;
   
    // 세션의 유효 시간 얻어오기
    int inactive = session.getMaxInactiveInterval() / 60;
   
    // 세션이 새로 만들어졌는지를 알려준다.
    boolean b_new = session.isNew();
%>
<!doctype html>
<html>
 
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    
    <title>결재창</title>
</head>
 
<body>
    <div >
        <h1>결제중</h1>
        <h1>이창을 닫지 마세요</h1>
        <!--
        <h1><%=id_str%></h1>
        <h1><%=b_new%></h1>
        -->
    </div>
    <script>
        let NexPopUp;
 
        if (!window.NEXACROHTML) {
            window.NEXACROHTML = {};
        }
 
        // 키와 데이터를 전달
        window.NEXACROHTML.FireUserNotify = function (sAddr,sData) {
            var arrData = new Array();
            arrData[0]= sAddr; // Key
            arrData[1]= sData; // Value
 
            if (window.NEXACROWEBBROWSER) {
                window.NEXACROWEBBROWSER.on_fire_onusernotify(window.NEXACROWEBBROWSER, arrData);
            }
        }
 
 
        // 새로운 팝업창에 올림
        function fnCallPopUp(arrInfo) {
            var hostUrl =  document.location.protocol +"//"+document.location.host;
            console.log(hostUrl);
            //alert(hostUrl);
            //var url = "http://"+hostUrl+"/kcu/pay/INIstdpay_pc_req.jsp?";
            var url = hostUrl+"/kcu/chat/lmsChat.html?";
            var name = "lmsChat";
            var option = "width = 1000, height = 800, top = 100, left = 200, location = no";
            // 파라메터 입력
            for (let index = 0; index < arrInfo.length; index++) {
                url+=arrInfo[index][0]+"="+arrInfo[index][1]+"&";
            }
            //alert(url);
            NexPopUp=window.open(url, name, option);
            setTimeout(fnIsPopupClosed, 1000);
        }
 
        // 팝업창이 떠있는지 확인해서 없으면 사용자가 팝업창을 강제로 닫은거임
        function fnIsPopupClosed() {
            if(NexPopUp.closed)
            {
                fnFromPopup("PopupClose","0");
            }
            else{
                setTimeout(fnIsPopupClosed, 1000);
            }
            
        }
        
 
        // 팝업으로 보내기
        function fnToPopup(x) {
            NexPopUp.document.getElementsByName("buyertel")[0].value=x;
        
        }
 
        // 팝업에서 받기
        function fnFromPopup(key,val) {
            window.NEXACROHTML.FireUserNotify(key,val);
        }
 
        // 팝업 닫기
        function fnFromPopupCloseMe() {
            NexPopUp.close();
        }
 
        
 
    </script>
</body>
 
</html>
cs

 

 

 

 

넥사크로에는 아래와 같이 webBrowser 컴포넌트와 이벤트 2개를 생성한다.

팝업을 띄우고 싶은 부모화면 안에 추가해야함.

 

 

 

넥사크로 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
this.divMain_btnIntoChat00_onclick = function(obj:nexacro.Button,e:nexacro.ClickEventInfo)
{
 
        if(this.dsList.rowcount==0)
        {
            return;
        }
        
        // 팝업을 실행시키기
        var objEnv = nexacro.getEnvironment();
        var sUrl = objEnv.services['exlUrl'].url;// + "/addr/postcode.jsp";
        trace("aa : "+sUrl); // http://localhost:8088/kcu/
 
        this.divMain.form.web00.set_url(sUrl+"chat/lmsChat_Nexacro.jsp");
};
 
 
 
// 웹이 성공적으로 열렸을때 html에 아래 파라미터를 넣고 호출할수 있다. 
this.web00_onloadcompleted = function(obj:nexacro.WebBrowser,e:nexacro.WebLoadCompEventInfo)
{
    trace("web00_onloadcompleted :"+e.url);
    
    // url에 파라메터로 넘길값
    var arrList = new Array();
    
    // 참가자명
    var arrKeyVal = new Array("NAME",this.dsSearch.getColumn(0,"USER_NAME"));
    arrList.push(arrKeyVal);
    
    // 학년도 학기명 EX)2023학년도 1학기
    arrKeyVal = new Array("SMST_NM",this.dsList.getColumn(0,"SHYR")+"학년도 "+this.dsList.getColumn(0,"SMST_NM"));
    arrList.push(arrKeyVal);
    
    
    // 과목명
    arrKeyVal = new Array("DERT_NM",this.dsList.getColumn(this.divMain.form.cboSubj.index,"SUBJ_KORN_NM"));
    arrList.push(arrKeyVal);
    
    
    
    // 과목코드 (방번호지정됨)
    arrKeyVal = new Array("DERT_CD",this.dsList.getColumn(this.divMain.form.cboSubj.index,"COSE_CD"));
    arrList.push(arrKeyVal);
    
    
    // 과목기본정보명
    var sInfoString = "";
    sInfoString += this.dsList.getColumn(this.divMain.form.cboSubj.index,"COPL_SE_NM")+" / ";
    sInfoString += this.dsList.getColumn(this.divMain.form.cboSubj.index,"BAN")+"반 / ";
    sInfoString += this.dsList.getColumn(this.divMain.form.cboSubj.index,"PROFINSTR_NM")+"교수님 / ";
    sInfoString += this.dsList.getColumn(this.divMain.form.cboSubj.index,"PNT_SCOR")+"학점";
    
    arrKeyVal = new Array("DERT_INFO",sInfoString);
    arrList.push(arrKeyVal);
    
    
    trace(arrList);
    
    
        
    // web에 결재정보 보내기
    // OID  년월일시분초학년도학기학번 2023061314353920221022134061
    var _doc = this.divMain.form.web00.getProperty("window");
    _doc.callMethod("fnCallPopUp", arrList);
    
    
    if(_doc){
        _doc.destroy();
        _doc = null;
    }
};
 
 
 
 
// html에서 받아올수도 있다.
this.web00_onusernotify = function(obj:nexacro.WebBrowser,e:nexacro.WebUserNotifyEventInfo)
{
    switch(e.userdata[0]) {
    case "visibilityState"// visible, hidden
        if(e.userdata[1]=="visible")
        {
            // 작업
        }
        else
        {
            // 작업    
        }
        break;
    case "videoState":
        if(e.userdata[1]=="pause")
        {
            // 작업
        }
        else
        {
            // 작업    
        }
        
        break;
    default:
        break;
    }
};
 
 
this.fnPopClose = function ()
{
    // 여기서 팝업을 닫을수도 있다.
    var _doc = this.divMain.form.web00.getProperty("window");
    _doc.callMethod("fnFromPopupCloseMe");
    
    
    if(_doc){
        _doc.destroy();
        _doc = null;
    }
};
 
 
 
cs

 

이렇게 해야 넥사크로의 팝업을 제어할수 있고 데이터도 받을수 있음

 

 

 

 

 

 

 

 

websocket으로 채팅방 만드는 방법

 

채팅방 번호로 방을 구분하고

일반적인 문자 채팅을 구현한다.

 

 

pom.xml 에 아래 라이브러리를 추가

1
2
3
4
5
6
<dependency>
              <groupId>javax.websocket</groupId>
              <artifactId>javax.websocket-api</artifactId>
              <version>1.1</version>
</dependency>
 
cs

 

 

컨트롤러단

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Array;
import java.net.InetAddress;
import java.net.Socket;
import java.net.URLEncoder;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
 
 
 
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import org.springframework.stereotype.Controller;
 
 
 
 
@Controller
@ServerEndpoint("/lms/chat")
public class lmsChatController extends Socket {
    private static final List<Session> session = new ArrayList<Session>();
    private static final HashMap<StringString[]> chatIdMap = new HashMap<StringString[]>(); // 접속자의 정보를 저장
    
    @OnOpen
    public void open(Session newUser) {
        System.out.println("connected");
        
        session.add(newUser);
        System.out.println("현재 접속중인 유저 수 : " + session.size() + " : "+newUser.getId());
        
        
    }
 
    @OnMessage
    public void getMsg(Session recieveSession, String msg) {
        System.out.println("getMsg : " + msg +" : "+recieveSession.getId());
        String[] arrChatIdMap;
        
        // 0 명령
        // 1 이름
        // 2 학과명
        // 3 학과코드
        String[] arrMsg = msg.split(":,:");
        
        System.out.println("정보 : " + arrMsg[0+" : "+ arrMsg.length);
        switch(arrMsg[0]) {
        
        case "CONNECT":
            
            chatIdMap.put(recieveSession.getId(), arrMsg);
            arrChatIdMap = chatIdMap.get(recieveSession.getId());
            System.out.println("첫 접속정보 : " + session.size() + " : "+chatIdMap.size() + " : "+recieveSession.getId());
            connectlog(chatIdMap);
             String sConnUserName ="";
              for (Entry<StringString[]> entrySet : chatIdMap.entrySet()) {
                 String[] arrChatIdInfo= entrySet.getValue();
                 if(arrChatIdInfo[3].equals(arrChatIdMap[3])) {
                     sConnUserName+=arrChatIdInfo[1]+"+,+";
                 }
                 //System.out.println("AA : "+entrySet.getKey() + " : " + sConnUserName);
             }
             sConnUserName=sConnUserName.substring(0, sConnUserName.length()-3);
            
             for (int i = 0; i < session.size(); i++) {
                  try {
                            if(session.get(i).isOpen()) {
                                System.out.println("접속자 정보 : " + i);
                                System.out.println("CON:,:"+sConnUserName+":,:"+arrChatIdMap[1]+"님이 접속하였습니다"+":,:"+arrChatIdMap[3]);
                                session.get(i).getBasicRemote().sendText("CON:,:"+sConnUserName+":,:"+arrChatIdMap[1]+"님이 접속하였습니다"+":,:"+arrChatIdMap[1]+":,:"+arrChatIdMap[2]+":,:"+arrChatIdMap[3]);
                            }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            
            break;
            
        case "MESSAGE":
        default:
             arrChatIdMap = chatIdMap.get(recieveSession.getId());
             for (int i = 0; i < session.size(); i++) {
                    if (! recieveSession.getId().equals(session.get(i).getId())) {
                        try {
                            if(session.get(i).isOpen()) {
                                session.get(i).getBasicRemote().sendText("U:,:"+arrChatIdMap[1]+":,:"+ msg+":,:"+arrChatIdMap[1]+":,:"+arrChatIdMap[2]+":,:"+arrChatIdMap[3] ); // 너가 보낸거
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    } else {
                        try {
                            if(session.get(i).isOpen()) {
                                session.get(i).getBasicRemote().sendText("I:,:"+arrChatIdMap[1]+":,:"+ msg+":,:"+arrChatIdMap[1]+":,:"+arrChatIdMap[2]+":,:"+arrChatIdMap[3] ); // 내가 보낸거
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            break;
        }     
       
    }
    
    @OnClose
    public void close(Session recieveSession) {
        int sessionSize = session.size();
        if (sessionSize != 0) {
            try {
                 for (int i = 0; i < sessionSize; i++) {
                    // System.out.println("get : "+i+":"+recieveSession.getId() + " : "+session.size());
                     if (session.get(i).isOpen()) {
                         String[] arrChatIdMap = chatIdMap.get(recieveSession.getId());
                         //0 구분
                         //1 참여자 정보
                         //2 메시지
                         //3 학과번호
                         //4 학과명
                          String sConnUserName ="";
                          for (Entry<StringString[]> entrySet : chatIdMap.entrySet()) {
                             String[] arrChatIdInfo= entrySet.getValue();
                             System.out.println("AA : "+arrChatIdInfo[3+ " : " + arrChatIdMap[3]);
                             if(arrChatIdInfo[3].equals(arrChatIdMap[3])) {
                                     sConnUserName+=arrChatIdInfo[1]+"+,+";                                
                             }
                         }
                         sConnUserName=sConnUserName.substring(0, sConnUserName.length()-3);
                         
                         
                         System.out.println("DCON:,:"+sConnUserName+":,:"+arrChatIdMap[1]+"님이 접속을 종료하였습니다"+":,:"+arrChatIdMap[3]+":,:"+arrChatIdMap[1]);
                         session.get(i).getBasicRemote().sendText("DCON:,:"+sConnUserName+":,:"+arrChatIdMap[1]+"님이 접속을 종료하였습니다"+":,:"+arrChatIdMap[1]+":,:"+arrChatIdMap[2]+":,:"+arrChatIdMap[3]);
                     }
                 }
                List<Integer> nRemoveNum=new ArrayList<Integer>();
                for (int i = 0; i < sessionSize; i++) {
                    System.out.println("close : "+i+":"+recieveSession.getId() + " : "+session.size());
                    if (! session.get(i).isOpen()) {
                        nRemoveNum.add(i);
                        chatIdMap.remove(recieveSession.getId());
                    }
                }
                for(int forInt:nRemoveNum) {
                    session.remove(forInt);
                }
                
                
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }    
    
    @OnError
    public void error(Session recieveSession, Throwable error) {
        System.out.println("error : "+error.toString()+" : "+recieveSession.getId());
        if(chatIdMap.containsKey(recieveSession.getId()))
        {
            chatIdMap.remove(recieveSession.getId());
        }
    }
    
    private void connectlog(HashMap<StringString[]> log) {
        
         for (Entry<StringString[]> entrySet : log.entrySet()) {
             String[] logtest= entrySet.getValue();
             String bb = entrySet.getKey()+" = ";
             for(String a:logtest) {
                 bb+=a+" : ";
             }
             System.out.println("AA : "+entrySet.getKey() + " : " + bb);
         }
        
    }
    
}
 
cs

 

 

 

HTML 단

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Chat</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</head>
<style>
    * {
    padding: 0;
    margin: 0;
    box-sizing: border-box;
}
 
{
    text-decoration: none;
}
 
.wrap {
    padding: 40px 0;
    background-color: #A8C0D6;
}
 
.wrap .chat {
    display: flex;
    align-items: flex-start;
    padding: 20px;
}
 
.wrap .chat .icon {
    position: relative;
    overflow: hidden;
    width: 50px;
    height: 50px;
    border-radius: 50%;
    background-color: #eee;
}
 
.wrap .chat .icon i {
    position: absolute;
    top: 10px;
    left: 50%;
    font-size: 2.5rem;
    color: #aaa;
    transform: translateX(-50%);
}
 
.wrap .chat .textbox {
    position: relative;
    display: inline-block;
    max-width: calc(100% - 70px);
    padding: 10px;
    margin-top: 7px;
    font-size: 13px;
    border-radius: 10px;
}
 
.wrap .chat .textbox::before {
    position: absolute;
    display: block;
    top: 0;
    font-size: 1.5rem;
}
 
.wrap .ch1 .textbox {
    margin-left: 20px;
    background-color: #ddd;
}
 
.wrap .ch1 .textbox::before {
    left: -15px;
    content: "◀";
    color: #ddd;
}
 
.wrap .ch2 {
    flex-direction: row-reverse;
}
 
.wrap .ch2 .textbox {
    margin-right: 20px;
    background-color: #F9EB54;
}
 
.wrap .ch2 .textbox::before {
    right: -15px;
    content: "▶";
    color: #F9EB54;
}
 
.wrap .ch3 {
    flex-direction: row-reverse;
}
 
.wrap .ch3 .textbox {
    margin-left: 50%;
    /* background-color: #9d5830; */
}
/* 
.wrap .ch3 .textbox::before {
    right: -15px;
    color: #9d5830;
} */
 
 
</style>
<body onload="HtmlOnload();">
 
 
<div class="chatTitle">
    <h1>[과목채팅]</h1>
    <h3 id="SmstNm_h1"></h1>
    <h3 id="DertNm_h1"></h1>
    <h5 id="DertInfo_h1"></h1>
</div>
<!-- 채팅 입력창 -->
<div style="width: 70%; float: left; overflow-y: scroll; height:90%;">
    <div class="wrap"></div>
    <div id="chatFocus">
    </div>
</div>
 
<div style="float: right; width: 30%; top: 0;">
    참여자
<div class="container mt-3" id="nameTable" style="width: 100%; height: 90%; overflow-y: scroll;">
    
    <table class="table table-striped" style="width: 100%;">
        <!-- 현재 접속자 -->
        <tbody class="connecterName"> 
          <tr>
            <td>John</td>
          </tr>
        </tbody>
      </table>
</div>
</div>
 
<div class="msgArea" style="position: fixed; bottom: 0%; width: 100%;">
    <div class="input-group input-group-lg mb-3">
    <input type="text" placeholder="보낼 메세지를 입력하세요." onkeyup="if(window.event.keyCode==13){sendMsg()}" class="chatMsgText form-control">
    <span class="input-group-text"  onclick="sendMsg()">전송</span>
    <!-- <button type="button" class="btn btn-primary" value="전송" class="sendBtn" onclick="sendMsg()">전송</button> -->
    </div>
    
</div>
 
 
 
 
 
</body>
<script>
        var hostUrl = document.location.protocol +"//"+ document.location.host;
        console.log(hostUrl)
        let ws;//      var ws = new WebSocket('ws://localhost:8080');
        
        function getParameter(name) {
            name = name.replace(/[\[]/"\\[").replace(/[\]]/"\\]");
            var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
                results = regex.exec(location.search);
            return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
            
        }
 
 
 
 
        let sName    =  getParameter("NAME");
        let sDertNm    =  getParameter("DERT_NM"); // 과목명
        let sDertCd    =  getParameter("DERT_CD"); // 과목코드 (방번호)
        let sSmstNm    =  getParameter("SMST_NM"); // 학년도학기
        let sDertInfo    =  getParameter("DERT_INFO"); // 과목기본정보
        
 
        function connect() {
            let sHost = document.location.host;
            ws = new WebSocket("ws://"+sHost+"/kcu/lms/chat");
 
            console.log('connect');
            ws.onopen = function() {
                // subscribe to some channels
                
                let sChatVistor = "CONNECT"+":,:"+sName+":,:"+sDertNm+":,:"+sDertCd;
                console.log(sChatVistor);
                ws.send(sChatVistor);
            };
 
            // 메시지 수신
            ws.onmessage = function(e) {
                console.log('Message:', e.data);
                // 0 U,I,CON,DCON
                // 1 이름
                // 2 메시지
                // 3 학과명
                // 4 학과코드
                let arrMsg = e.data.split(":,:");
                console.log('a : '+sDertCd +" : "+arrMsg[5]);
                
                if(sDertCd!=arrMsg[5]){
                        return;
                }
 
                let sChatMsgDiv="";
                if(arrMsg[0]=="U"// 너가 보낸 메시지
                {
                    
                    sChatMsgDiv='<div class="chat ch1">';
                    sChatMsgDiv+='<div class="icon" style="text-align: center;">'+arrMsg[1]+'<i class="fa-solid fa-user"></i></div>';
                    sChatMsgDiv+='<div class="textbox">'+arrMsg[2]+'</div>';
                    sChatMsgDiv+='</div>';
 
                }else if(arrMsg[0]=="I"){ // 내가 보낸 메시지
                    sChatMsgDiv='<div class="chat ch2">';
                    sChatMsgDiv+='<div class="icon" style="text-align: center;">'+arrMsg[1]+'<i class="fa-solid fa-user"></i></div>';
                    sChatMsgDiv+='<div class="textbox">'+arrMsg[2]+'</div>';
                    sChatMsgDiv+='</div>';
                }
                else  if(arrMsg[0]=="CON"){ // 접속
                    sChatMsgDiv='<div class="chat ch3">';
                    sChatMsgDiv+='<div class="textbox">'+arrMsg[2]+'</div>';
                    sChatMsgDiv+='</div>';
 
                    let sChatVistorNames="";
                    sChatVistorNames+='<table class="table table-striped" style="width: 100%;">';
                    sChatVistorNames+='<tbody class="connecterName">';
                    let arrNames = arrMsg[1].split("+,+"); // 참여자들이 String에 묶에서 들어오는것 품
                    for(let i=0;i<arrNames.length;i++){ // 참여자 목록을 넣기 위함
                        sChatVistorNames+="<tr>";
                        sChatVistorNames+="<td>"+arrNames[i]+"</td>";
                        sChatVistorNames+="</tr>";
                    }
                    sChatVistorNames+='</tbody></table>';
                    document.getElementById('nameTable').innerHTML=sChatVistorNames;
 
                }
                else  if(arrMsg[0]=="DCON"){ // 접속 종료
                    console.log('DCON : ');
                    sChatMsgDiv='<div class="chat ch3">';
                    sChatMsgDiv+='<div class="textbox">'+arrMsg[2]+'</div>';
                    sChatMsgDiv+='</div>';
 
                    let sChatVistorNames="";
                    sChatVistorNames+='<table class="table table-striped" style="width: 100%;">';
                    sChatVistorNames+='<tbody class="connecterName">';
                    let arrNames = arrMsg[1].split("+,+");// 참여자들이 String에 묶에서 들어오는것 품
                    let bOutNameFlag=false// 접속 종료시 동명이인일 경우를 대비하여 한개의 이름만 빼게 함
                    for(let i=0;i<arrNames.length;i++){
 
                        console.log('CCC : '+arrNames[i] +" : "+arrMsg[3]);// 접속 종료자의 이름을 하나만 없앤다.
                        if(bOutNameFlag){
                            arrMsg[3]="";
                        }
 
                        if((arrMsg[3]!=arrNames[i])){ // 종료자를 제외한 모든 참여자 추가
                            sChatVistorNames+="<tr>";
                            sChatVistorNames+="<td>"+arrNames[i]+"</td>";
                            sChatVistorNames+="</tr>";
                        }
                        else{
                            bOutNameFlag=true;
                        }
                    }
                    sChatVistorNames+='</tbody></table>';
                    document.getElementById('nameTable').innerHTML=sChatVistorNames;
 
                }
                else{
                    return;
                }
                document.querySelector('.wrap').insertAdjacentHTML("beforeend",sChatMsgDiv);
                document.getElementById("chatFocus").scrollIntoView();
 
            };
 
            
            ws.onclose = function(e) {
                console.log('Socket is closed. Reconnect will be attempted in 1 second.', e.reason);
                setTimeout(function() {
                connect();
                }, 1000);
            };
 
            ws.onerror = function(err) {
                console.error('Socket encountered error: ', err.message, 'Closing socket');
                ws.close();
            };
        }
 
        function HtmlOnload() {
            connect();
            document.getElementById("DertNm_h1").innerHTML =sDertNm;
            document.getElementById("SmstNm_h1").innerHTML =sSmstNm;
            document.getElementById("DertInfo_h1").innerHTML =sDertInfo;
        }
        
 
 
        function sendMsg() {
            let chatMsgText=document.querySelector('.chatMsgText').value;
            document.querySelector('.chatMsgText').value="";
            console.log("SENd : "+chatMsgText);
            if(chatMsgText!="")
            {
                ws.send(chatMsgText);
            }
        }
       
</script>
</html>
cs

 

 

 

session값 저장과 함께 사용자를 구분할 chatIdMap 을 생성한다.

들어오는 내용은 (:,:)로 split하여 보낸사람의 정보를 받는다.

 

.../lmsChat.html?NAME=황재철&DERT_NM=위험물질론&DERT_CD=FD201701 

처음 접속할때 HTML에서 @OnMessage를 한번 보낸다.

예) CONNECT:,:황재철:,:위험물질론:,:FD201701 

1 접속할때 접속했다는걸 보내기 위한 구분

2 접속자 이름

3 채팅방 이름

4. 채팅방 구분번호

 

 

그뒤 참여자 목록을 (+,+)로 구분하여 같이 묶어서 보낸다.

참여했습니다., 종료했습니다. 들어올때 참여자를 삭제 추가 하여 참여자 정보를 유지한다.

 

메시지는 이름하고 내가 보낸건지 상대가 보낸건지 구분하여 전달하고 좌우 표시한다.

 

위 파라미터에서 DERT_CD가 동일해야 같은 방에 들어있는걸로 동작됨

 

졸작 수준의 채팅 완료

 

 

 

 

 

 

네비에 글 보이기 설정

 

색상 설정

 

 

 

'업무관련 > DB' 카테고리의 다른 글

Toad Data Modeler7.2 엑셀 출력  (0) 2024.02.08
DBeaver 테이블 목록에 설명 보이기  (0) 2023.04.20
 
우선 페이징 관련 클래스를 만든다.
 

 

 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package com.goodshoes.ssm.board.domain;
 
public class PagingInfo {
    private int postPerPage; // 1페이지 당 보여줄 글의 갯수
    private int totalPagingBlock; // 전체 페이징 블럭 수
    private int totalPostCnt; // 전체 글의 갯수
    private int currentPagingBlock; // 현재 페이지가 속한 페이징 블럭 번호
 
    private int totalPage; // 전체 페이지 수
 
    private String pageWrite = "n1y2n3n4n5"// 현재 페이지를 글자로 표현
 
    // 초기 페이지 세팅
 
    /**
     * @methodName : settingPage
     * @author : son
     * @date : 2022. 10. 6.
     * @입력 param : int totalPostCnt 총 게시글 수 ,int postPerPage 한페이지에 표시할 게시글수 
     *                 int totalPagingBlock 페이지 숫자 표시할 최대 수, int currentPagingBlock 현재 페이지
     * @returnType : String y1n2n3n4n5 y가 앞에있으면 현재 선택, n은 비선택
     */
    public String settingPage(int totalPostCnt, int postPerPage, int totalPagingBlock, int currentPagingBlock) {
        if(totalPostCnt==0) {
            totalPostCnt=1;
        }
 
        this.totalPostCnt = totalPostCnt;
 
        this.postPerPage = postPerPage
        this.totalPagingBlock = totalPagingBlock;
        this.totalPage = this.totalPostCnt / this.postPerPage; // 꽉차는 게시물
        System.out.println(this.totalPage);
 
 
        int pageLeftOver = this.totalPostCnt % this.postPerPage; // 남은 게시물
 
        if (pageLeftOver > 0) {
            this.totalPage++;
        }
        
        
        if (currentPagingBlock <= 0)
            currentPagingBlock = 1// 오동작 방지
        if (currentPagingBlock > this.totalPage)
            currentPagingBlock = this.totalPage;
        this.currentPagingBlock = currentPagingBlock; // 현재 페이지
 
        
        this.pageWrite = "";
        int startPage = ((this.currentPagingBlock / this.totalPagingBlock) * this.totalPagingBlock) + 1;
 
        if ((this.currentPagingBlock % this.totalPagingBlock) == 0) {
            startPage -= this.totalPagingBlock;
        }
        int endPage = startPage + this.totalPagingBlock - 1;
 
        this.pageWrite = "s" + startPage + "s";
        int i = 0;
        for (i = startPage; i <= endPage; i++) {
 
            if (i > this.totalPage) {
 
                break;
            }
            if (currentPagingBlock == i) {
                this.pageWrite += "y" + i + "y";
            } else {
                this.pageWrite += "n" + i + "n";
            }
        }
        this.pageWrite += "e" + (i - 1+ "e";
        // y1n2n3
        return this.pageWrite;
    }
 
    public int getStartPos() {
        return Integer
                .parseInt(this.pageWrite.substring(this.pageWrite.indexOf("s"+ 1this.pageWrite.lastIndexOf("s")));
 
    }
 
    public int getCurrentPos() {
        return Integer
                .parseInt(this.pageWrite.substring(this.pageWrite.indexOf("y"+ 1this.pageWrite.lastIndexOf("y")));
 
    }
 
    public int getEndPos() {
        return Integer
                .parseInt(this.pageWrite.substring(this.pageWrite.indexOf("e"+ 1this.pageWrite.lastIndexOf("e")));
 
    }
 
}
cs


 
 
 
 
사용법
 
 
1
2
3
4
5
6
7
8
9
10
11
        PagingInfo testpage = new PagingInfo();
        System.out.println("pageNo : "+pageNo);
        String testp = testpage.settingPage(total, postSize, 5, pageNo); // 한페이지에 8개 게시물, 최대 5(<<12345>>)개 페이징갯수
        System.out.println(testp);
        map.put("startPage", testpage.getStartPos());
        map.put("currentPage", testpage.getCurrentPos());
        map.put("endPage", testpage.getEndPos());        
        
        // 보드 list 가져오기
        List<PointEventBoardListVo> pointlisttable=dao.SelectPointEventBoardList((testpage.getCurrentPos()-1)*postSize,postSize);
        
cs
 
 
우선 페이징 부터 받아오기 
testpage.getCurrentPos() 을 가지고 DB에 페이지를 가져오면 편함
위 함수가 전체 페이지 기준으로 적거나 오버될때 보정까지 해줌
 
 
 
 
 
 
testp 콘솔로 찍어보면
 
s1sy1yn2ne2e
 
이런식으로 보기 편하게 나오게함
 

이거라고 보면됨
 
또는

s1sn1ny2ye2e 이거임
 
s1s start 의미
n1n 선택되지 않음
y2y 현재 2페이지
e2e end 의미
 
 
 
각 값은 int 로 받고 싶으면 testpage.getStartPos() 로 받아오면됨
그냥 s와s 사이 값 찾아서 리턴하는 것임
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
<c:forEach var="i" begin="${startPage}" end="${endPage}" step="1">
    <c:choose>
        <c:when test="${currentPage == i}">
            <li class="page-item active"><a href="${contextPath }/board/pointevent/pointevent?pageNo=${i}&postSize=${postSize}" " class="page-link">${i}</a></li>
        </c:when>
        <c:otherwise>
            <li class="page-item"><a href="${contextPath }/board/pointevent/pointevent?pageNo=${i}&postSize=${postSize}" class="page-link">${i}</a></li>
        </c:otherwise>
    </c:choose>
</c:forEach>
 
cs
 
jstl 사용시 위와 같이 사용하면 됨
 
 

 

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
MANIFEST.MF
#.xml
/.metadata/*
*.class
Servers/
 
# Mobile Tools for Java (J2ME)
.mtj.tmp/
 
# Package Files #
*.jar
*.war
*.ear
 
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
 
# netbeans
nbproject/private/
build/
nbbuild/
 
# the dist file could make some problems
# dist/
nbdist/
nbactions.xml
nb-configuration.xml
.nb-gradle/
 
# Eclipse
#.classpath
#.project
#.settings/
 
# Intellij
.idea/
*.iml
*.iws
 
# Mac
.DS_Store
 
# Maven
log/
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
 
 
cs
 
Spring 프로젝트 깃허브 공유시 잘 사용했던 
.gitignore 
 

 

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 
$(document).ready(function() {
 
    $(".selectalartpopupCloseBtn").on("click"function() {
            $("#selectalartpopup").hide();
    });
 
    $(".selectalartpopupYesBtn").on("click"function(data) {
            console.log("selectalartpopupYesBtn");
            console.log(data);
            switch ($("#hidden_func").val()) {
            case "delJuso":
                delJuso($("#hidden_param").val());
                break;
            case "buySummit":
                buySummit();
                break;
            default:
                break;
            }
            
            $("#hidden_func").val("");
            $("#hidden_param").val("");
            $("#selectalartpopup").hide();
        });
 
});
 
 
cs

 

위 코드를 설명하자면

팝업을 띄웠을때 '예' 버튼을 클릭하면 해당  switch 문을 통해 함수로 들어갈수 있다.

닫기 버튼 눌렀을때 팝업 닫는것도 있음

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!-- The Modal -->
    <div class="modal" id="selectalartpopup">
        <div class="modal-dialog">
            <div class="modal-content">
 
                <!-- Modal Header -->
                <div class="modal-header">
                    <h4 class="modal-title">알림</h4>
                    <button type="button" class="btn-close selectalartpopupCloseBtn" data-bs-dismiss="modal"></button>
                </div>
 
                <!-- Modal body -->
                <div class="modal-body" id="selectpopupMsg">Modal body..</div>
 
                <!-- Modal footer -->
                <div class="modal-footer">
                    <input type="hidden" id="hidden_func" value=""> <input type="hidden" id="hidden_param" value="">
                    <button type="button" class="btn btn-danger selectalartpopupYesBtn" data-bs-dismiss="modal"></button>
                    <button type="button" class="btn btn-danger selectalartpopupCloseBtn" data-bs-dismiss="modal">아니오</button>
                </div>
 
            </div>
        </div>
    </div>
cs

 

위와같이 모달창에 만들기

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    
    function selectalartpopup(str,func,param) {
        $("#selectpopupMsg").html(str);
        $("#hidden_func").val(func);
        $("#hidden_param").val(param);
        $("#selectalartpopup").show();
    }
 
 
    function selectbuySummit() {
        selectalartpopup("정말 구매하겠습니까?","buySummit","");
    }
 
    function selectdeljuso(addrNo) {
        selectalartpopup("정말 삭제하겠습니까?","delJuso",addrNo);
    }
 
cs

 

위와 같이 함수를 만들어 파라메터 넘기면됨

1. 중간에 메모를 띄어줄 문자열 입력

2. switch 문에 들어갈 문자열

3. 파라메터 한개 넘기기

 

 

 

1
2
3
4
5
6
7
    
    <class="primary-btn" href="#;" onclick="selectbuySummit();">구매하기</a>
 
 
    output+='<a href="#;" class="btn btn-secondary" onclick="selectdeljuso('+elt.addrNo+');">삭제</a>';
 
 
cs

 

html에서 버튼 넣어서 사용

 

 



 

 

 



 

 

 

 

위와 같이 DB를 받았을때 테이블 모양을 위 처럼 나오게 하고 싶었다.
 

 

 
우선 DB에서 Vo로 담아서 View단 까지 가져와 console.log에 찍어봤을때 아래와 같이 나옴
 
 
 


이제 OrderNo를 기준으로 같은 이름이 반복되면 ++ 시켜서 넣은 값을 기준으로 rowspan을 하겠다.
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
    function drawOrderTable(data) {
 
        $("#orderlist").empty();
 
        if (data == "") {
            return;
        } else {
        }
 
        let oldOrderNo = 0;
        let oldOrderNum = 0;
        let SizeIndex = -1;
        let OrderNoSize = [];
        
        // 같은 번호를 묶는거 우선 실행
        $.each(data.OrderManageViewVo, function(i, elt) {
            if (oldOrderNo != elt.orderNo) {
                oldOrderNo = elt.orderNo;
                oldOrderNum = 1;
                SizeIndex++;
                OrderNoSize[SizeIndex] = oldOrderNum;
 
            } else {
                oldOrderNum++;
                OrderNoSize[SizeIndex] = oldOrderNum;
            }
        });
 
        console.log(OrderNoSize);
        oldOrderNo=0;
        SizeIndex = -1;
        
        // 묶였으면 출력하자.
        $
                .each(
                        data.OrderManageViewVo,
                        function(i, elt) {
                            console.log(i + " : " + elt);
                            let output = '<tr>';
 
                            if (oldOrderNo != elt.orderNo) { // 처음 한줄은 rowspen을 입력
                                oldOrderNo = elt.orderNo;
                                SizeIndex++;
 
                                output += '<td class="boardRightGray" rowspan="'+OrderNoSize[SizeIndex]+'"><input type="checkbox" name="productCheck" /></td>';
                                output += '<td class="boardRightGray" rowspan="'+OrderNoSize[SizeIndex]+'">'
                                        + elt.orderTime + '</td>';
                                output += '<td class="boardRightGray" rowspan="'+OrderNoSize[SizeIndex]+'">'
                                        + elt.orderNo + '</td>';
 
                                output += '<td class="boardRightGray" rowspan="'+OrderNoSize[SizeIndex]+'">'
                                        + elt.name;
                                if (elt.sessionId != null) {
                                    output += '<br/>[비회원]</td>';
                                } else {
                                    output += '<br/>[회원]</td>';
                                }
 
                                output += '<td class="boardRightGray">'
                                        + elt.productName + '</td>';
                                output += '<td class="boardRightGray">'
                                        + elt.qty + '</td>';
                                output += '<td class="boardRightGray">'
                                        + elt.price + '</td>';
                                output += '<td class="boardRightGray">'
                                        + elt.transAddress + '<br/>'
                                        + elt.transHome + ' '
                                        + elt.transDetailedHome + '<br/>'
                                        + elt.userName + ' ' + elt.phoneNum
                                        + '</td>';
                                output += '<td class="boardRightGray">'
                                        + elt.state + '</td>';
                                output += '<td class="boardRightGray"><button type="button" class="saveBtn btn btn-block bg-gradient-secondary btn-sm" onclick="showSearchBox()">상세보기</button></td>';
 
                            } else { // 나머지는 그냥 입력
 
                                output += '<td class="boardRightGray">'
                                        + elt.productName + '</td>';
                                output += '<td class="boardRightGray">'
                                        + elt.qty + '</td>';
                                output += '<td class="boardRightGray">'
                                        + elt.price + '</td>';
                                output += '<td class="boardRightGray">'
                                        + elt.transAddress + '<br/>'
                                        + elt.transHome + ' '
                                        + elt.transDetailedHome + '<br/>'
                                        + elt.userName + ' ' + elt.phoneNum
                                        + '</td>';
                                output += '<td class="boardRightGray">'
                                        + elt.state + '</td>';
                                output += '<td class="boardRightGray"><button type="button" class="saveBtn btn btn-block bg-gradient-secondary btn-sm" onclick="showSearchBox()">상세보기</button></td>';
 
                            }
                            output += '</tr>';
 
                            $("#orderlist").append(output);
 
                        });
 
    }
 
cs
 
 
 
 
 
위와 같이 작성하여 테이블 위치에 출력함
 


 
콘솔로 출력해보면 위와 같이 연속된 숫자 횟수를 볼수 있다.
 
 
 


    출력 결과