index.html 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>游戏进程管理面板</title>
  5. <meta charset="UTF-8">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <script type="text/javascript" src="/assets/js/vue.js"></script>
  8. <script type="text/javascript" src="/assets/js/jquery.min.js"></script>
  9. <link type="text/css" rel="stylesheet" href="/assets/css/normalize.css" />
  10. <link type="text/css" rel="stylesheet" href="/assets/css/milligram.min.css" />
  11. <link type="text/css" rel="stylesheet" href="/assets/css/style.css" />
  12. </head>
  13. <body>
  14. <div class="container" id="app">
  15. <br />
  16. <div class="float-right">
  17. <a id="refresh" class="button button-primary"> 刷新 </a>
  18. <a href="/logout" class="button"> 注销 </a>
  19. </div>
  20. <h2>
  21. 欢迎进入游戏进程管理面板
  22. </h2>
  23. <br />
  24. <pre id="sysInfo"></pre>
  25. <table>
  26. <thead>
  27. <tr>
  28. <th>进程名</th>
  29. <th>序列</th>
  30. <th>进程编号</th>
  31. <th>状态</th>
  32. <th>重启次数</th>
  33. <th>启动时间</th>
  34. <th>CPU</th>
  35. <th>内存</th>
  36. <th>操作</th>
  37. </tr>
  38. </thead>
  39. <tbody>
  40. <tr>
  41. <td colspan="9" id="loader">
  42. <img src="/assets/img/loader.gif" alt="[]" />
  43. </td>
  44. </tr>
  45. <tr v-for="process in processes">
  46. <td>{{process.name}}</td>
  47. <td>{{process.pm_id}}</td>
  48. <td>{{process.pid}}</td>
  49. <td>{{process.pm2_env.status}}</td>
  50. <td>{{process.pm2_env.restart_time}}</td>
  51. <td>{{ timing(now - process.pm2_env.pm_uptime)}}</td>
  52. <td>{{process.monit.cpu}}</td>
  53. <td>{{(process.monit.memory / (1024 * 1024 )).toFixed(2)}} MB</td>
  54. <td>
  55. <a :href="'/restart?id='+process.pm_id">
  56. [ 重启 ]
  57. </a>
  58. &nbsp;
  59. <a :href="'/delete?id='+process.pm_id" class="delete">
  60. [ 关闭 ]
  61. </a>
  62. <a :href="'/stop?id='+process.pm_id" v-if="process.pm2_env.status == 'online'">
  63. [ 停止 ]
  64. </a>
  65. <a :href="'/start?id='+process.pm_id" v-else="">
  66. [ 恢复 ]
  67. </a>
  68. <a :href="'/log?id='+process.pm_id">
  69. [ 日志 ]
  70. </a>
  71. <a :href="'/pinfo?id='+process.pm_id">
  72. [ 详情 ]
  73. </a>
  74. </td>
  75. </tr>
  76. </tbody>
  77. </table>
  78. <pre id="notification"></pre>
  79. <br />
  80. <br />
  81. <div class="button button-primary" id="frmCrtl">
  82. 显示/隐藏创建进程界面
  83. </div>
  84. &nbsp;
  85. &nbsp;
  86. <a href="/dump" class="button">
  87. 保存当前进程
  88. </a>
  89. &nbsp;
  90. &nbsp;
  91. <a href="/deleteall" class="button">
  92. 关闭所有进程
  93. </a>
  94. &nbsp;
  95. &nbsp;
  96. <a href="/flush" class="button">
  97. 清空日志
  98. </a>
  99. <br />
  100. <form action="/addProccess" method="POST" class="row" id="addForm">
  101. <div class="column">
  102. <label>
  103. 文件路径:
  104. <input type="text" name="path" v-model="choosedPath" />
  105. </label>
  106. <label>
  107. 附加参数:
  108. <input type="text" name="args" />
  109. </label>
  110. <input type="submit" value="运行" class="button" />
  111. </div>
  112. <!-- <div class="column">
  113. 文件列表:
  114. <br />
  115. (当前目录:<b> {{currentDir}} </b>)
  116. <ul id="folder-list">
  117. <li v-for="dir in folders">
  118. {{dir.name}}
  119. <span v-if="dir.name !== '..'">
  120. <a class="button button-small button-outline float-right explore" :href="dir.path+'/'">
  121. explore
  122. </a>
  123. <a class="button float-right select button-small button-outline" :href="dir.path">
  124. select
  125. </a>
  126. </span>
  127. <span v-else>
  128. <a class="button float-right button-small button-outline" :href="dir.path+'/'" id="back">
  129. explore
  130. </a>
  131. </span>
  132. <div class="clearfix"></div>
  133. </li>
  134. </ul>
  135. </div> -->
  136. </form>
  137. <a href="http://git.wxqiyou.com:9527" target="_blank"> 启游 &copy; 2019 &nbsp; | &nbsp;&nbsp; 袁浩
  138. </a>
  139. <br />
  140. <br />
  141. </div>
  142. <script type="text/javascript">
  143. function GetData() {
  144. $.get('/getProccess', function (e) {
  145. var newDate = new Date();
  146. if (Array.isArray(e) !== true) {
  147. // if catch mean is session expired
  148. location.reload();
  149. return false;
  150. }
  151. vue.processes = e;
  152. // set now for calcalte uptime
  153. vue.now = Math.floor(newDate.getTime());
  154. $("#loader").slideUp(100);
  155. }).fail(function () {
  156. alert('获取数据出错:可能没有安装pm2(npm install pm2 -g),或者当前用户没有权限获取数据。'); // or whatever
  157. $("#loader").slideUp(100);
  158. });
  159. $("#addForm").slideUp(50);
  160. $.get('/folder', function (e) {
  161. vue.folders = e;
  162. });
  163. $.get('/notification', function (e) {
  164. if (e !== '-') {
  165. $("#notification").text(e).slideDown(300);
  166. }
  167. });
  168. $.get('/sysInfo', function (e) {
  169. $("#sysInfo").text(e).slideDown(300);
  170. });
  171. }
  172. var now = 0;
  173. vue = new Vue({
  174. el: '#app',
  175. data: {
  176. processes: [],
  177. folders: [],
  178. now: 0,
  179. currentDir: '/',
  180. choosedPath: '',
  181. },
  182. methods: {
  183. timing: function (sec) {
  184. var date = new Date(null);
  185. date.setSeconds(Math.floor(sec / 1000)); // specify value for SECONDS here
  186. return date.toISOString().substr(11, 8);
  187. }
  188. }
  189. });
  190. $(function () {
  191. GetData();
  192. $("#refresh").click(function () {
  193. $("#loader").slideDown(100);
  194. GetData();
  195. });
  196. $(document).on('click', ".select", function () {
  197. vue.choosedPath = $(this).attr('href');
  198. return false;
  199. });
  200. $(document).on('click', ".explore", function () {
  201. vue.currentDir = $(this).attr('href');
  202. $.get('/folder', { path: $(this).attr('href') }, function (e) {
  203. vue.folders = e;
  204. });
  205. return false;
  206. });
  207. $(document).on('click', "#back", function () {
  208. vue.currentDir = $(this).attr('href');
  209. $.get('/folder', { path: $(this).attr('href') }, function (e) {
  210. vue.folders = e;
  211. });
  212. return false;
  213. });
  214. $("#frmCrtl").click(function () {
  215. $("#addForm").slideToggle(300);
  216. });
  217. $(document).on('click', '.delete', function () {
  218. if (!confirm('确定要关闭这个进程吗?')) {
  219. return false;
  220. }
  221. });
  222. });
  223. </script>
  224. </body>
  225. </html>