LogList.vue 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. <template>
  2. <div>
  3. <div class="box box-primary">
  4. <div class="box-header">
  5. <h4 class="text-primary text-center">日志列表</h4>
  6. </div>
  7. <div class="box-body">
  8. <form class="form-inline" autocomplete="off" spellcheck="false">
  9. <div class="form-group form-group-sm">
  10. <label>搜索</label>
  11. <input type="text" class="form-control" placeholder="关键字" v-model.trim="q" @keydown.enter.prevent ref="q">
  12. </div>
  13. <span class="hidden-xs">&nbsp;&nbsp;</span>
  14. <div class="form-group form-group-sm">
  15. <label>调用方式</label>
  16. <select class="form-control" v-model.trim="method">
  17. <option value="">全部</option>
  18. <option value="GET">HTTP GET</option>
  19. <option value="POST">HTTP POST</option>
  20. <option value="INVITE">SIP INVITE</option>
  21. <!-- <option value="BYE">SIP BYE</option> -->
  22. </select>
  23. </div>
  24. <span class="hidden-xs">&nbsp;&nbsp;</span>
  25. <div class="form-group">
  26. <div class="input-group input-group-sm">
  27. <DatePicker class="form-control input-group-sm" clearBtn :day.sync="starttime" ref="startDatePicker" placeholder="开始日期"></DatePicker>
  28. <div class="input-group-btn">
  29. <button type="button" class="btn btn-sm btn-default" @click.prevent="showStartDatePicker">
  30. <i class="fa fa-calendar"></i>
  31. </button>
  32. </div>
  33. </div>
  34. </div>
  35. <span class="hidden-xs">&nbsp;-&nbsp;</span>
  36. <div class="form-group">
  37. <div class="input-group input-group-sm">
  38. <DatePicker class="form-control input-group-sm" clearBtn :day.sync="endtime" ref="endDatePicker" placeholder="结束日期"></DatePicker>
  39. <div class="input-group-btn">
  40. <button type="button" class="btn btn-sm btn-default" @click.prevent="showEndDatePicker">
  41. <i class="fa fa-calendar"></i>
  42. </button>
  43. </div>
  44. </div>
  45. </div>
  46. <div class="form-group form-group-sm pull-right" v-if="hasAnyRole(serverInfo, userInfo, '管理员') && hasAllChannel(serverInfo, userInfo)">
  47. <div class="input-group input-group-sm">
  48. <button type="button" class="btn btn-sm btn-danger" @click.prevent="clearLog">
  49. <i class="fa fa-remove"></i> 清空
  50. </button>
  51. </div>
  52. </div>
  53. </form>
  54. <br>
  55. <div class="clearfix"></div>
  56. <el-table :data="logs" stripe :default-sort="{prop: 'StartAt', order: 'descending'}" @sort-change="sortChange" v-loading="loading" element-loading-text="加载中...">
  57. <el-table-column prop="Name" label="操作名称" min-width="120" show-overflow-tooltip></el-table-column>
  58. <el-table-column prop="Method" label="调用方式" min-width="120" :formatter="formatMethod"></el-table-column>
  59. <el-table-column prop="RequestURI" label="资源路径" min-width="200" show-overflow-tooltip></el-table-column>
  60. <el-table-column prop="RemoteAddr" label="远端地址" min-width="150" show-overflow-tooltip></el-table-column>
  61. <el-table-column prop="Status" label="结果" min-width="140" :formatter="formatStatus" show-overflow-tooltip></el-table-column>
  62. <el-table-column prop="Duration" label="用时(秒)" min-width="100" :formatter="formatDuration" sortable="custom" show-overflow-tooltip></el-table-column>
  63. <el-table-column prop="Username" label="操作人" min-width="120" show-overflow-tooltip></el-table-column>
  64. <el-table-column prop="StartAt" label="操作时间" min-width="160" sortable="custom"></el-table-column>
  65. </el-table>
  66. </div>
  67. <div class="box-footer" v-if="total > 0">
  68. <el-pagination layout="total,prev,pager,next" :pager-count="isMobile() ? 3 : 5" class="pull-right" :total="total" :page-size.sync="pageSize" :current-page.sync="currentPage"></el-pagination>
  69. </div>
  70. </div>
  71. </div>
  72. </template>
  73. <script>
  74. import _ from "lodash";
  75. import DatePicker from "components/DatePicker.vue";
  76. import { mapState } from "vuex";
  77. import moment from 'moment';
  78. export default {
  79. props: {
  80. },
  81. data() {
  82. return {
  83. q: "",
  84. method: "",
  85. starttime: "",
  86. endtime: "",
  87. total: 0,
  88. pageSize: 10,
  89. currentPage: 1,
  90. sort: "StartAt",
  91. order: "desc",
  92. loading: false,
  93. timer: 0,
  94. logs: [],
  95. };
  96. },
  97. computed: {
  98. ...mapState(['userInfo', 'serverInfo']),
  99. },
  100. components: {
  101. DatePicker
  102. },
  103. mounted() {
  104. // this.timer = setInterval(() => {
  105. // this.getLogs();
  106. // }, 3000);
  107. },
  108. beforeDestroy() {
  109. if (this.timer) {
  110. clearInterval(this.timer);
  111. this.timer = 0;
  112. }
  113. },
  114. methods: {
  115. ready(){
  116. this.$watch('q', function(newVal, oldVal) {
  117. this.doDelaySearch();
  118. });
  119. this.$watch('starttime', function(newVal, oldVal) {
  120. this.doSearch();
  121. });
  122. this.$watch('endtime', function(newVal, oldVal) {
  123. this.doSearch();
  124. });
  125. this.$watch('method', function(newVal, oldVal) {
  126. this.doSearch();
  127. });
  128. this.$watch('currentPage', function(newVal, oldVal) {
  129. this.doSearch(newVal);
  130. });
  131. },
  132. doSearch(page = 1) {
  133. var query = {};
  134. if (this.q) query["q"] = this.q;
  135. if (this.starttime) query["starttime"] = this.starttime;
  136. if (this.endtime) query["endtime"] = this.endtime;
  137. if (this.method) query["method"] = this.method;
  138. this.$router.replace({
  139. path: `/logs/${page}`,
  140. query: query
  141. });
  142. },
  143. doDelaySearch: _.debounce(function() {
  144. this.doSearch();
  145. }, 500),
  146. getLogs() {
  147. $.get("/api/v1/log/list", {
  148. q: this.q,
  149. start: (this.currentPage -1) * this.pageSize,
  150. limit: this.pageSize,
  151. starttime: this.starttime ? moment(this.starttime, "YYYYMMDD").startOf('day').format("YYYYMMDDHHmmss") : "",
  152. endtime: this.endtime ? moment(this.endtime, "YYYYMMDD").endOf('day').format("YYYYMMDDHHmmss") : "",
  153. method: this.method,
  154. sort: this.sort,
  155. order: this.order
  156. })
  157. .then(ret => {
  158. this.total = ret.LogCount;
  159. this.logs = ret.LogList;
  160. })
  161. .always(() => {
  162. });
  163. },
  164. sortChange(data) {
  165. this.sort = data.prop;
  166. this.order = data.order == "ascending" ? "asc" : "desc";
  167. this.getLogs();
  168. },
  169. formatMethod(row, col, cell) {
  170. return `${row.Scheme} ${row.Method}`;
  171. },
  172. formatStatus(row, col, cell) {
  173. return `${row.StatusCode} ${row.Status}`;
  174. },
  175. formatDuration(row, col, cell) {
  176. return moment.duration(row.Duration).asSeconds();
  177. },
  178. showStartDatePicker() {
  179. $(this.$refs.startDatePicker.$el).focus();
  180. },
  181. showEndDatePicker() {
  182. $(this.$refs.endDatePicker.$el).focus();
  183. },
  184. removeLog(row) {
  185. this.$confirm(`确认删除`, "提示").then(() => {
  186. $.get("/api/v1/log/remove", {
  187. id: row.ID
  188. }).always(() => {
  189. this.getLogs();
  190. });
  191. }).catch(() => {});
  192. },
  193. clearLog() {
  194. this.$confirm('确认全部删除', "提示").then(() => {
  195. $.get("/api/v1/log/clear", {}).then(() => {
  196. this.getLogs();
  197. })
  198. }).catch(() => {});
  199. }
  200. },
  201. beforeRouteEnter(to, from, next) {
  202. next(vm => {
  203. vm.q = to.query.q || "";
  204. vm.starttime = to.query.starttime || "";
  205. vm.endtime = to.query.endtime || "";
  206. vm.method = to.query.method || "";
  207. vm.currentPage = parseInt(to.params.page) || 1;
  208. vm.ready();
  209. });
  210. },
  211. beforeRouteUpdate(to, from, next) {
  212. next();
  213. this.$nextTick(() => {
  214. this.q = to.query.q || "";
  215. this.starttime = to.query.starttime || "";
  216. this.endtime = to.query.endtime || "";
  217. this.method = to.query.method || "";
  218. this.currentPage = parseInt(to.params.page) || 1;
  219. this.logs = [];
  220. this.getLogs();
  221. });
  222. }
  223. };
  224. </script>