page6.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  1. let appInsLogLevel = "";
  2. function setAppInstallLogLevel() {
  3. const level = logLevel.value;
  4. fetch("/api/app-install/loglevel", {
  5. method: "POST",
  6. headers: {"Content-Type": "application/json"},
  7. body: JSON.stringify({level})
  8. })
  9. .then(async r => {
  10. if (!r.ok) throw new Error(await r.text());
  11. appInsLogLevel = level;
  12. })
  13. .catch(e => {
  14. logLevel.value = appInsLogLevel;
  15. });
  16. }
  17. function getAppInstallLevel() {
  18. fetch("/api/app-install/loglevel")
  19. .then(async r => {
  20. if (!r.ok) throw new Error(await r.text());
  21. return r.json();
  22. })
  23. .then(d => {
  24. appInsLogLevel = d.log_level;
  25. logLevel.value = d.log_level;
  26. })
  27. .catch(e => {
  28. appInsLogLevel = "";
  29. logLevel.value = "";
  30. });
  31. }
  32. function downloadAppInstallLogFile(event) {
  33. const btn = event.currentTarget;
  34. btn.disabled = true;
  35. fetch("/api/app-install/logfile")
  36. .then(async r => {
  37. if (!r.ok) {
  38. throw new Error("HTTP " + r.status);
  39. }
  40. const disposition = r.headers.get("Content-Disposition");
  41. let filename = "app-install.log.tar.gz";
  42. if (disposition) {
  43. const match = disposition.match(/filename="?([^";]+)"?/);
  44. if (match) {
  45. filename = match[1];
  46. }
  47. }
  48. return {
  49. blob: await r.blob(),
  50. filename
  51. };
  52. })
  53. .then(({ blob, filename }) => {
  54. const url = URL.createObjectURL(blob);
  55. const a = document.createElement("a");
  56. a.href = url;
  57. a.download = filename;
  58. document.body.appendChild(a);
  59. a.click();
  60. a.remove();
  61. setTimeout(() => {
  62. URL.revokeObjectURL(url);
  63. }, 1000);
  64. alert("下载成功");
  65. })
  66. .catch(e => {
  67. console.error("download failed:", e);
  68. alert("下载失败: " + e.message);
  69. })
  70. .finally(() => {
  71. btn.disabled = false;
  72. btn.textContent = "下载";
  73. });
  74. }
  75. function restartAppInstallService(event) {
  76. if (!confirm("确定重启应该管理服务吗?")) {
  77. return;
  78. }
  79. const btn = event.currentTarget;
  80. btn.disabled = true;
  81. fetch("/api/app-install/restart", {
  82. method: "POST"
  83. })
  84. .then(async r => {
  85. if (!r.ok) {
  86. throw new Error(await r.text());
  87. }
  88. logLevel.value = "info";
  89. appInsLogLevel = logLevel.value;
  90. disconnectLog();
  91. connectLog("yfkj-app-install.service", "text1");
  92. alert("重启成功");
  93. })
  94. .catch(e => {
  95. console.error("restart failed:", e);
  96. alert("重启失败: " + e.message);
  97. })
  98. .finally(() => {
  99. btn.disabled = false;
  100. });
  101. }
  102. let appInsStatusTimer = null;
  103. let userAppOperating = false;
  104. function getAppInstallStatus() {
  105. if (userAppOperating || userAppUploading) {
  106. return;
  107. }
  108. fetch("/api/app-install/status")
  109. .then(async r => {
  110. if (!r.ok) {
  111. throw new Error("HTTP " + r.status);
  112. }
  113. return r.json();
  114. })
  115. .then(data => {
  116. [
  117. "avar1", "avar2", "avar3", "avar4",
  118. "bvar1", "bvar2", "bvar3", "bvar4", "bvar5",
  119. "cvar1", "cvar2", "cvar3", "cvar4", "cvar5"
  120. ].forEach(id => {
  121. setText(id, data[id], "page6");
  122. });
  123. updateAppInstallButtons(Number(data.state));
  124. })
  125. .catch(e => {
  126. console.error("getAppInstallStatus() failed:", e);
  127. [
  128. "avar1", "avar2", "avar3", "avar4",
  129. "bvar1", "bvar2", "bvar3", "bvar4", "bvar5",
  130. "cvar1", "cvar2", "cvar3", "cvar4", "cvar5"
  131. ].forEach(id => {
  132. setText(id, null, "page6");
  133. });
  134. updateAppInstallButtons(-1);
  135. });
  136. getAppInstallLevel();
  137. }
  138. function startAppInstallStatusRefresh() {
  139. if (appInsStatusTimer) {
  140. return;
  141. }
  142. getAppInstallStatus();
  143. appInsStatusTimer = setInterval(() => {
  144. getAppInstallStatus();
  145. }, 5000);
  146. }
  147. function stopAppInstallStatusRefresh() {
  148. if (appInsStatusTimer) {
  149. clearInterval(appInsStatusTimer);
  150. appInsStatusTimer = null;
  151. }
  152. }
  153. function updateAppInstallButtons(state) {
  154. switch (state) {
  155. case 0: // 无安装包, 等待上传
  156. setBtnStatus("btn1", true, "page6")
  157. setBtnStatus("btn2", false, "page6")
  158. setBtnStatus("btn3", false, "page6")
  159. setBtnStatus("btn4", false, "page6")
  160. setBtnStatus("btn5", false, "page6")
  161. setBtnStatus("btn6", false, "page6")
  162. break;
  163. case 1: // 有安装包, 未安装时
  164. setBtnStatus("btn1", false, "page6")
  165. setBtnStatus("btn2", true, "page6")
  166. setBtnStatus("btn3", true, "page6")
  167. setBtnStatus("btn4", true, "page6")
  168. setBtnStatus("btn5", false, "page6")
  169. setBtnStatus("btn6", false, "page6")
  170. break;
  171. case 2: // 有安装包, 已安装时
  172. setBtnStatus("btn1", false, "page6")
  173. setBtnStatus("btn2", true, "page6")
  174. setBtnStatus("btn3", false, "page6")
  175. setBtnStatus("btn4", false, "page6")
  176. setBtnStatus("btn5", true, "page6")
  177. setBtnStatus("btn6", true, "page6")
  178. break;
  179. case 4: // 禁用所有, 特殊操作
  180. setBtnStatus("btn1", false, "page6")
  181. setBtnStatus("btn2", false, "page6")
  182. setBtnStatus("btn3", false, "page6")
  183. setBtnStatus("btn4", false, "page6")
  184. setBtnStatus("btn5", false, "page6")
  185. setBtnStatus("btn6", false, "page6")
  186. break;
  187. default:
  188. setBtnStatus("btn1", true, "page6")
  189. setBtnStatus("btn2", true, "page6")
  190. setBtnStatus("btn3", true, "page6")
  191. setBtnStatus("btn4", true, "page6")
  192. setBtnStatus("btn5", true, "page6")
  193. setBtnStatus("btn6", true, "page6")
  194. break;
  195. }
  196. }
  197. let userAppUploading = false;
  198. function onBtn1Click() {
  199. if (userAppUploading) {
  200. return;
  201. }
  202. document.getElementById("userAppPkg").click();
  203. }
  204. function uploadUserAppPkg(input) {
  205. let file = input.files[0];
  206. if (!file) {
  207. return;
  208. }
  209. if (!file.name.toLowerCase().endsWith(".tar.gz")) {
  210. alert("只允许上传 tar.gz 类型的文件");
  211. input.value = "";
  212. return;
  213. }
  214. userAppUploading = true;
  215. setBtnStatus("btn1", false, "page6");
  216. let formData = new FormData();
  217. formData.append("file", file);
  218. let xhr = new XMLHttpRequest();
  219. xhr.open("POST", "/api/app-install/uploadUserAppPkg", true);
  220. xhr.timeout = 600000; // 10分钟
  221. xhr.upload.onprogress = function(e) {
  222. if (!e.lengthComputable) {
  223. return;
  224. }
  225. let percent = Math.floor(e.loaded * 100 / e.total);
  226. if (percent >= 100) {
  227. setText("bvar5", "上传完成,正在处理安装包,请稍候...", "page6");
  228. } else {
  229. setText("bvar5", "正在上传 " + file.name + " (" + percent + "%)", "page6");
  230. }
  231. };
  232. xhr.onload = async function() {
  233. if (xhr.status !== 200) {
  234. userAppUploading = false;
  235. input.value = "";
  236. setText("bvar5", "上传失败: " + xhr.responseText, "page6");
  237. setBtnStatus("btn1", true, "page6");
  238. return;
  239. }
  240. try {
  241. await importUserAppPkg("/tmp/" + file.name);
  242. } finally {
  243. userAppUploading = false;
  244. input.value = "";
  245. setBtnStatus("btn1", true, "page6");
  246. }
  247. };
  248. xhr.onerror = function() {
  249. userAppUploading = false;
  250. input.value = "";
  251. setText("bvar5", "上传失败,请检查网络连接", "page6");
  252. setBtnStatus("btn1", true, "page6");
  253. };
  254. xhr.ontimeout = function() {
  255. userAppUploading = false;
  256. input.value = "";
  257. setText("bvar5", "上传超时,请稍后重新尝试", "page6");
  258. setBtnStatus("btn1", true, "page6");
  259. };
  260. xhr.send(formData);
  261. }
  262. async function importUserAppPkg(file) {
  263. userAppOperating = true; stopAppInstallStatusRefresh(); updateAppInstallButtons(4);
  264. setText("bvar5", "正在导入当前上传的用户应用安装包,请稍候...", "page6");
  265. try {
  266. let res = await fetch("/api/app-install/importUserAppPkg", {
  267. method:"POST",
  268. headers:{"Content-Type":"application/json"},
  269. body:JSON.stringify({file:file})
  270. });
  271. if (!res.ok) {
  272. throw new Error(await res.text());
  273. }
  274. let data = await res.json();
  275. if (data.result !== "success") {
  276. throw new Error("返回结果异常");
  277. }
  278. return true;
  279. } catch (err) {
  280. setText("bvar5", "导入过程中发生错误: " + err.message, "page6");
  281. return false;
  282. } finally {
  283. userAppOperating = false; startAppInstallStatusRefresh();
  284. }
  285. }
  286. function onBtn2Click() {
  287. window.location.href = "/api/app-install/downloadUserAppPkg";
  288. }
  289. async function onBtn3Click() {
  290. if (!confirm("确定删除当前已上传的用户应用安装包吗?")) {
  291. return;
  292. }
  293. userAppOperating = true; stopAppInstallStatusRefresh(); updateAppInstallButtons(4);
  294. setText("bvar5", "正在删除当前已上传的用户应用安装包,请稍候...", "page6");
  295. try {
  296. let res = await fetch("/api/app-install/removeUserAppPkg", {
  297. method:"POST"
  298. });
  299. if (!res.ok) {
  300. throw new Error(await res.text());
  301. }
  302. let data = await res.json();
  303. if (data.result !== "success") {
  304. throw new Error("返回结果异常");
  305. }
  306. } catch (err) {
  307. setText("bvar5", "删除过程中发生错误: " + err.message, "page6");
  308. } finally {
  309. userAppOperating = false; startAppInstallStatusRefresh();
  310. }
  311. }
  312. async function onBtn4Click() {
  313. userAppOperating = true; stopAppInstallStatusRefresh(); updateAppInstallButtons(4);
  314. setText("bvar5", "正在使用当前安装包安装用户应用,请稍候...", "page6");
  315. try {
  316. let res = await fetch("/api/app-install/installUserApp", {
  317. method:"POST"
  318. });
  319. if (!res.ok) {
  320. throw new Error(await res.text());
  321. }
  322. let data = await res.json();
  323. if (data.result !== "success") {
  324. throw new Error("返回结果异常");
  325. }
  326. } catch (err) {
  327. setText("bvar5", "安装过程中发生错误: " + err.message, "page6");
  328. } finally {
  329. userAppOperating = false; startAppInstallStatusRefresh();
  330. }
  331. }
  332. async function onBtn5Click() {
  333. if (!confirm("确定卸载当前已经安装的用户应用吗?")) {
  334. return;
  335. }
  336. userAppOperating = true; stopAppInstallStatusRefresh(); updateAppInstallButtons(4);
  337. setText("bvar5", "正在卸载当前已经安装的用户应用,请稍候...", "page6");
  338. try {
  339. let res = await fetch("/api/app-install/uninstallUserApp", {
  340. method:"POST"
  341. });
  342. if (!res.ok) {
  343. throw new Error(await res.text());
  344. }
  345. let data = await res.json();
  346. if (data.result !== "success") {
  347. throw new Error("返回结果异常");
  348. }
  349. } catch (err) {
  350. setText("bvar5", "卸载过程中发生错误: " + err.message, "page6");
  351. } finally {
  352. userAppOperating = false; startAppInstallStatusRefresh();
  353. }
  354. }
  355. function onBtn6Click() {
  356. if (!confirm("确定重启当前已经安装的用户应用吗?")) {
  357. return;
  358. }
  359. setBtnStatus("btn6", false, "page6")
  360. fetch("/api/user-app/restart", {
  361. method: "POST"
  362. })
  363. .then(async r => {
  364. if (!r.ok) {
  365. throw new Error(await r.text());
  366. }
  367. alert("重启成功");
  368. })
  369. .catch(e => {
  370. console.error("restart failed:", e);
  371. alert("重启失败: " + e.message);
  372. })
  373. .finally(() => {
  374. setBtnStatus("btn6", true, "page6")
  375. });
  376. }
  377. function initPage6() {
  378. startAppInstallStatusRefresh()
  379. connectLog("yfkj-app-install.service", "text1");
  380. }
  381. function exitPage6() {
  382. stopAppInstallStatusRefresh()
  383. disconnectLog();
  384. }