ChatVisitor.cshtml 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. @page
  2. @model Admin.Pages.Member.ChatVisitorModel
  3. @{
  4. ViewData["Title"] = "채팅 접속자";
  5. }
  6. <div class="container-fluid">
  7. <h3>@ViewData["Title"]</h3>
  8. <hr />
  9. <partial name="_StatusMessage" />
  10. <form name="f_admin_search" id="fAdminSearch" method="get" accept-charset="utf-8" autocomplete="off">
  11. <input type="hidden" name="Query.PageNum" value="1" />
  12. <div class="row g-2 mb-2">
  13. <div class="col col-lg-auto">
  14. <div class="row g-2">
  15. <div class="col-auto col-md-auto">
  16. <select name="Query.Search" class="form-select">
  17. <option value="1" selected="@(Model.Query.Search == 1)">회원 PK</option>
  18. <option value="2" selected="@(Model.Query.Search == 2)">회원 이메일</option>
  19. <option value="3" selected="@(Model.Query.Search == 3)">회원 SID</option>
  20. </select>
  21. </div>
  22. <div class="col col-md-auto">
  23. <input type="search" name="Query.Keyword" class="form-control" maxlength="100" value="@Model.Query.Keyword" />
  24. </div>
  25. <div class="col-auto col-md-auto text-center">
  26. <button type="submit" class="btn btn-primary w-100">검색</button>
  27. </div>
  28. </div>
  29. </div>
  30. <div class="col-12 col-lg text-end">
  31. <select name="Query.PerPage" class="form-select w-auto d-inline-block">
  32. <option value="10" selected="@(Model.Query.PerPage == 10)">10</option>
  33. <option value="20" selected="@(Model.Query.PerPage == 20)">20</option>
  34. <option value="50" selected="@(Model.Query.PerPage == 50)">50</option>
  35. <option value="100" selected="@(Model.Query.PerPage == 100)">100</option>
  36. </select>
  37. <button type="button" id="btnListExecute" class="btn btn-danger" data-action="/Member/ChatVisitor?handler=Kick" disabled>강제 종료</button>
  38. </div>
  39. </div>
  40. </form>
  41. <blockquote class="pt-3 pb-1">
  42. <small>※ 채팅 접속자는 채팅방(메인/종목/레거시 채널)에 입장 중인 연결을 보여줍니다. 사이트 전체는 <a href="/Member/Visitor">현재 접속자</a>에서 확인하세요.</small><br/>
  43. <small>※ 검색은 Like이 아닌 = 으로 처리됩니다.</small><br/>
  44. <small>※ 강제 종료는 해당 연결을 채팅방에서 끊습니다.</small>
  45. </blockquote>
  46. <form name="f_admin_list" id="fAdminList" method="post" accept-charset="utf-8" autocomplete="off"></form>
  47. <ul class="nav nav-tabs mt-3">
  48. <li class="nav-item">
  49. <a class="nav-link @(Model.Query.Tab == null ? "active" : null)" href="/Member/ChatVisitor">전체(@Model.TotalRows)</a>
  50. </li>
  51. <li class="nav-item">
  52. <a class="nav-link @(Model.Query.Tab == 1 ? "active" : null)" href="/Member/ChatVisitor?tab=1">정회원(@Model.TotalMember)</a>
  53. </li>
  54. <li class="nav-item">
  55. <a class="nav-link @(Model.Query.Tab == 2 ? "active" : null)" href="/Member/ChatVisitor?tab=2">비회원(@Model.TotalGuest)</a>
  56. </li>
  57. <li class="nav-item">
  58. <a class="nav-link @(Model.Query.Tab == 3 ? "active" : null)" href="/Member/ChatVisitor?tab=3">IP 목록(@Model.TotalIps)</a>
  59. </li>
  60. </ul>
  61. <div class="table-responsive">
  62. <table class="table table-bordered mt-3">
  63. @if (Model.Query.Tab != 3) {
  64. <thead>
  65. <tr>
  66. <th rowspan="2"><input type="checkbox" id="checkedAll" class="form-check-input" value="1" form="fAdminList" /></th>
  67. <th rowspan="2">ID</th>
  68. <th colspan="2">Connection ID</th>
  69. <th rowspan="2">채팅방</th>
  70. <th rowspan="2">IP</th>
  71. <th rowspan="2">Browser</th>
  72. <th rowspan="2">OS</th>
  73. <th rowspan="2">접속 기기</th>
  74. <th rowspan="2">접속 일시</th>
  75. <th rowspan="2">비고</th>
  76. </tr>
  77. <tr>
  78. <th>회원ID</th>
  79. <th>이메일</th>
  80. </tr>
  81. </thead>
  82. @if (Model.List == null || Model.List.Count <= 0)
  83. {
  84. <tbody>
  85. <tr>
  86. <td colspan="11">No Data.</td>
  87. </tr>
  88. </tbody>
  89. }
  90. else
  91. {
  92. @foreach (var row in Model.List)
  93. {
  94. <tbody class="striped">
  95. <tr>
  96. <td rowspan="2">
  97. <input type="checkbox" name="ids[]" class="form-check-input list-check-box" value="@row.ConnectionID" form="fAdminList" />
  98. </td>
  99. <td rowspan="2">@row.Num</td>
  100. <td colspan="2">@row.ConnectionID</td>
  101. <td rowspan="2"><span title="@row.RoomKey">@row.RoomName</span></td>
  102. <td rowspan="2">@row.IpAddress</td>
  103. <td rowspan="2">@row.Browser</td>
  104. <td rowspan="2">@row.OS</td>
  105. <td rowspan="2">@row.Device</td>
  106. <td rowspan="2">@row.ConnectedAt</td>
  107. <td rowspan="2">
  108. <a class="btn btn-sm btn-outline-danger btn-row-execute" href="@row.LogoutURL">강제 종료</a>
  109. </td>
  110. </tr>
  111. @if (row.IsGuest) {
  112. <tr>
  113. <td colspan="2">비회원</td>
  114. </tr>
  115. } else {
  116. <tr>
  117. <td>@row.MemberID</td>
  118. <td>@row.Email</td>
  119. </tr>
  120. }
  121. </tbody>
  122. }
  123. }
  124. } else {
  125. <thead>
  126. <tr>
  127. <th rowspan="2">No</th>
  128. <th rowspan="2">접속 일시</th>
  129. <th rowspan="2">IP</th>
  130. <th rowspan="2">Browser</th>
  131. <th rowspan="2">OS</th>
  132. <th rowspan="2">접속 기기</th>
  133. <th rowspan="2">연결 수</th>
  134. </tr>
  135. </thead>
  136. @if (Model.List == null || Model.List.Count <= 0)
  137. {
  138. <tbody>
  139. <tr>
  140. <td colspan="7">No Data.</td>
  141. </tr>
  142. </tbody>
  143. }
  144. else
  145. {
  146. @foreach (var row in Model.List)
  147. {
  148. <tbody class="striped">
  149. <tr>
  150. <td>@row.Num</td>
  151. <td>@row.ConnectedAt</td>
  152. <td>@row.IpAddress</td>
  153. <td>@row.Browser</td>
  154. <td>@row.OS</td>
  155. <td>@row.Device</td>
  156. <td>@row.Connections</td>
  157. </tr>
  158. </tbody>
  159. }
  160. }
  161. }
  162. </table>
  163. <partial name="_Pagination" model="Model.Pagination" />
  164. </div>
  165. </div>
  166. @section Scripts {
  167. <script>
  168. $(document).on("change", "[name='Query.PerPage']", function () {
  169. document.getElementById("fAdminSearch").submit();
  170. });
  171. </script>
  172. }