index.blade.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. @extends('admin.table_layouts')
  2. @section('content')
  3. <div class="page-content container-fluid">
  4. <div class="row">
  5. <div class="col-xxl-9 col-lg-8 order-lg-1 order-2">
  6. <x-admin.table-panel :title="trans('admin.menu.customer_service.ticket')" :theads="[
  7. '#',
  8. trans('model.user.username'),
  9. ucfirst(trans('validation.attributes.title')),
  10. trans('common.status.attribute'),
  11. trans('common.action'),
  12. ]" :count="trans('admin.ticket.counts', ['num' => $ticketList->total()])" :pagination="$ticketList->links()">
  13. @can('admin.ticket.store')
  14. <x-slot:actions>
  15. <button class="btn btn-primary btn-animate btn-animate-side" data-toggle="modal" data-target="#add_ticket_modal">
  16. <span>
  17. <i class="icon wb-plus" aria-hidden="true"></i> {{ trans('user.ticket.new') }}
  18. </span>
  19. </button>
  20. </x-slot:actions>
  21. @endcan
  22. <x-slot:filters>
  23. <x-admin.filter.input class="col-lg-3 col-sm-6" name="username" :placeholder="trans('model.user.username')" />
  24. </x-slot:filters>
  25. <x-slot:tbody>
  26. @foreach ($ticketList as $ticket)
  27. <tr>
  28. <td> {{ $ticket->id }} </td>
  29. <td>
  30. @if (!$ticket->user)
  31. 【{{ trans('common.deleted_item', ['attribute' => trans('common.account')]) }}】
  32. @else
  33. @can('admin.user.index')
  34. <a href="{{ route('admin.user.index', ['id' => $ticket->user->id]) }}" target="_blank">{{ $ticket->user->username }}</a>
  35. @else
  36. {{ $ticket->user->username }}
  37. @endcan
  38. @endif
  39. </td>
  40. <td>
  41. {{ $ticket->title }}
  42. </td>
  43. <td>
  44. {!! $ticket->status_label !!}
  45. </td>
  46. <td>
  47. @can('admin.ticket.edit')
  48. <a class="btn btn-animate btn-animate-vertical btn-outline-info" href="{{ route('admin.ticket.edit', $ticket) }}">
  49. <span>
  50. @if ($ticket->status === 2)
  51. <i class="icon wb-eye" aria-hidden="true" style="left: 40%"> </i>{{ trans('common.view') }}
  52. @else
  53. <i class="icon wb-check" aria-hidden="true" style="left: 40%"> </i>{{ trans('common.open') }}
  54. @endif
  55. </span>
  56. </a>
  57. @endcan
  58. </td>
  59. </tr>
  60. @endforeach
  61. </x-slot:tbody>
  62. </x-admin.table-panel>
  63. </div>
  64. <div class="col-xxl-3 col-lg-4 order-lg-2 order-1">
  65. <div class="panel panel-bordered">
  66. <div class="panel-heading">
  67. <h3 class="panel-title cyan-600">
  68. <i class="icon wb-stats-bars"></i> {{ trans('admin.ticket.analysis_title') }}
  69. </h3>
  70. </div>
  71. <div class="panel-body pt-0">
  72. <ul class="list-group list-group-dividered list-group-full">
  73. <li class="list-group-item">
  74. <i class="icon wb-inbox"></i>
  75. {{ trans('admin.ticket.processed_30days') }}
  76. <span class="font-weight-bold float-right">
  77. {{ $responseStats['count'] }}
  78. </span>
  79. </li>
  80. @if ($responseStats['avg_time'])
  81. <li class="list-group-item">
  82. <i class="icon wb-time"></i>
  83. {{ trans('admin.ticket.first_response_30days') }}
  84. <span class="text-success font-weight-bold float-right">{{ formatTime($responseStats['avg_time']) }}</span>
  85. </li>
  86. @endif
  87. @if ($avgCloseTime > 0)
  88. <li class="list-group-item">
  89. <i class="icon wb-check"></i>
  90. {{ trans('admin.ticket.avg_processing_time_30days') }}
  91. <span class="text-success font-weight-bold float-right">
  92. {{ formatTime($avgCloseTime) }}
  93. </span>
  94. </li>
  95. @endif
  96. <li class="list-group-item">
  97. <i class="icon wb-chat-text blue-700"></i>
  98. {{ trans('admin.ticket.today_new') }}
  99. <span class="font-weight-bold float-right">
  100. <span class="text-info">{{ $todayTicketCount }}</span>
  101. </span>
  102. </li>
  103. <li class="list-group-item">
  104. <i class="icon wb-chat-working red-700"></i>
  105. {{ trans('admin.ticket.pending_tickets') }}
  106. <span class="font-weight-bold text-danger float-right">
  107. {{ $ticketStats['pending'] }}
  108. </span>
  109. </li>
  110. <li class="list-group-item">
  111. <i class="icon wb-chat green-700"></i>
  112. {{ trans('admin.ticket.total_tickets') }}
  113. <span class="font-weight-bold text-primary float-right">
  114. {{ $ticketStats['total'] }}
  115. </span>
  116. </li>
  117. </ul>
  118. </div>
  119. </div>
  120. </div>
  121. </div>
  122. </div>
  123. @can('admin.ticket.store')
  124. <x-ui.modal id="add_ticket_modal" :title="trans('user.ticket.new')" size="lg" position="center" :keyboard="false">
  125. <div class="form-group row">
  126. <label class="col-2 col-form-label" for="userId">{{ trans('model.user.attribute') }}</label>
  127. <div class="input-group col-10">
  128. <input class="form-control col-md-4" id="uid" name="uid" type="number" placeholder="{{ trans('model.user.id') }}" />
  129. <div class="input-group-prepend">
  130. <span class="input-group-text">{{ trans('common.or') }}</span>
  131. </div>
  132. <input class="form-control col-md-8" id="username" name="username" type="text" placeholder="{{ trans('model.user.username') }}" />
  133. </div>
  134. </div>
  135. <div class="form-group">
  136. <input class="form-control" id="title" name="title" type="text" placeholder="{{ ucfirst(trans('validation.attributes.title')) }}">
  137. </div>
  138. <div class="form-group">
  139. <textarea class="form-control" id="content" name="content" type="text" rows="5" placeholder="{{ ucfirst(trans('validation.attributes.content')) }}"></textarea>
  140. </div>
  141. <x-slot:actions>
  142. <button class="btn btn-success" data-dismiss="modal" type="button" onclick="createTicket()"> {{ trans('common.confirm') }} </button>
  143. </x-slot:actions>
  144. </x-ui.modal>
  145. @endcan
  146. @endsection
  147. @push('javascript')
  148. <script>
  149. @can('admin.ticket.store')
  150. // 发起工单
  151. function createTicket() {
  152. const uid = $("#uid").val();
  153. const username = $("#username").val();
  154. const title = $("#title").val();
  155. const content = $("#content").val();
  156. if (uid.trim() === "" && username.trim() === "") {
  157. showMessage({
  158. title: '{{ trans('admin.ticket.send_to') }}',
  159. icon: "warning"
  160. });
  161. return false;
  162. }
  163. if (title.trim() === "") {
  164. showMessage({
  165. title: '{{ ucfirst(trans('validation.required', ['attribute' => trans('validation.attributes.title')])) }}',
  166. icon: "warning"
  167. });
  168. return false;
  169. }
  170. if (content.trim() === "") {
  171. showMessage({
  172. title: '{{ ucfirst(trans('validation.required', ['attribute' => trans('validation.attributes.content')])) }}',
  173. icon: "warning"
  174. });
  175. return false;
  176. }
  177. showConfirm({
  178. title: '{{ trans('user.ticket.submit_tips') }}',
  179. onConfirm: function() {
  180. ajaxPost("{{ route('admin.ticket.store') }}", {
  181. uid: uid,
  182. username: username,
  183. title: title,
  184. content: content
  185. }, {
  186. success: function(ret) {
  187. $("#add_ticket_modal").modal("hide");
  188. handleResponse(ret);
  189. },
  190. error: function(xhr) {
  191. $("#add_ticket_modal").modal("hide");
  192. handleErrors(xhr);
  193. }
  194. });
  195. }
  196. });
  197. }
  198. @endcan
  199. </script>
  200. @endpush