Visitor.cshtml 8.0 KB

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