webui-new/development/simpleadmin/www/deviceinfo.html
2025-03-24 22:39:52 +08:00

521 lines
20 KiB
HTML

<!DOCTYPE html>
<html lang="en" data-bs-theme="light">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>模块管理</title>
<!-- <link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH"
crossorigin="anonymous"
/> -->
<!-- Import all the bootstrap css files from css folder -->
<link rel="stylesheet" href="css/styles.css" />
<link rel="stylesheet" href="css/bootstrap.min.css" />
<!-- Import BootStrap Javascript -->
<script src="js/bootstrap.bundle.min.js"></script>
<script src="js/alpinejs.min.js" defer></script>
</head>
<body>
<main>
<div class="container my-4" x-data="fetchDeviceInfo()">
<nav class="navbar navbar-expand-lg mt-2">
<div class="container-fluid">
<a class="navbar-brand" href="/"
><span class="mb-0 h4 fw-bold">模块管理</span></a>
<button
class="navbar-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#navbarText"
aria-controls="navbarText"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarText">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link" href="/">首页</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/network.html">网络</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/scanner.html">扫描</a>
<li class="nav-item">
<a class="nav-link" href="/settings.html">设置</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/sms.html">短信</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/console">控制台</a>
</li>
<li class="nav-item">
<a
class="nav-link active"
href="/deviceinfo.html"
aria-current="page"
>设备信息</a
>
</li>
</ul>
<span class="navbar-text">
<button class="btn btn-link text-reset" id="darkModeToggle">
暗黑模式
</button>
</span>
</div>
</div>
</nav>
<div class="row mt-5 gap-3">
<div class="col">
<div class="card">
<div class="card-header">设备信息</div>
<div class="card-body">
<div class="card-text">
<div class="table-responsive">
<table class="table">
<style>.table th,.table td { white-space: nowrap; /* 防止换行 */}</style>
<tbody>
<tr>
<th scope="row">制造商</th>
<td x-text="manufacturer"></td>
</tr>
<tr>
<th scope="row">型号</th>
<td x-text="modelName"></td>
</tr>
<tr>
<th scope="row">固件版本</th>
<td class="col-md-2" x-text="firmwareVersion"></td>
</tr>
<tr>
<th scope="row">电话号码</th>
<td class="col-md-2" x-text="phoneNumber"></td>
</tr>
<tr>
<th scope="row">IMSI</th>
<td class="col-md-2" x-text="imsi"></td>
</tr>
<tr>
<th scope="row">ICCID</th>
<td class="col-md-2" x-text="iccid"></td>
</tr>
<tr>
<th scope="row">IMEI</th>
<td class="col-md-2">
<input
class="form-control"
type="text"
x-model="newImei"
x-bind:placeholder="imei === '-' ? '获取IMEI...' : imei"
/>
</td>
<td>
<button
type="button"
class="btn btn-primary"
@click="openModal()"
>
更新
</button>
</td>
</tr>
<tr>
<th scope="row">LAN IP</th>
<td class="col-md-2" x-text="lanIp"></td>
</tr>
<tr>
<th scope="row">WWAN IPv<sup>4</sup></th>
<td class="col-md-2" x-text="wwanIpv4"></td>
</tr>
<tr>
<th scope="row">WWAN IPv<sup>6</sup></th>
<td class="col-md-2" x-text="wwanIpv6"></td>
</tr>
<tr>
<th scope="row">版本</th>
<td class="col-md-2">SimpleAdminRev-Alpha-0.9</td>
</tr>
<tr>
<th>项目贡献者</th>
<td>
<!-- Button trigger modal -->
<p
type="button"
class="link-info link-opacity-50-hover link-offset-2"
data-bs-toggle="modal"
data-bs-target="#staticBackdrop"
>
显示贡献者
</p>
<!-- Modal -->
<div
class="modal fade"
id="staticBackdrop"
data-bs-backdrop="static"
data-bs-keyboard="false"
tabindex="-1"
aria-labelledby="staticBackdropLabel"
aria-hidden="true"
>
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h1
class="modal-title fs-5"
id="staticBackdropLabel"
>
Contributors
</h1>
<button
type="button"
class="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
></button>
</div>
<div class="modal-body">
<table>
<tbody>
<tr>
<th>
RGMII Toolkit and Documentation
</th>
<td class="col-md-2">
<a
href="https://github.com/iamromulan"
target="_blank"
>iamromulan</a
>
</td>
</tr>
<tr>
<th>Simple Admin 2.0</th>
<td class="col-md-2">
<a
href="https://github.com/dr-dolomite"
target="_blank"
>dr-dolomite</a
>
</td>
</tr>
<tr>
<th>SMS Feature</th>
<td class="col-md-2">
<a
href="https://github.com/snjzb"
target="_blank"
>snjzb</a
>
</td>
</tr>
<tr>
<th>Original Simple Admin</th>
<td class="col-md-2">
<a
href="https://github.com/aesthernr"
target="_blank"
>aesthernr</a
>
</td>
</tr>
<tr>
<th>Original Socat Bridge</th>
<td class="col-md-2">
<a
href="https://github.com/natecarlson"
target="_blank"
>natecarlson</a
>
</td>
</tr>
<tr>
<th>Original Simple Admin Fixes</th>
<td class="col-md-2">
<a
href="https://github.com/rbflurry/"
target="_blank"
>rbflurry</a
>
</td>
</tr>
<tr>
<th>SA Parsing Patch</th>
<td class="col-md-2">
<a
href="https://github.com/tarunVreddy"
target="_blank"
>tarunVreddy</a
>
</td>
</tr>
</tbody>
</table>
</div>
<div class="modal-footer">
<button
type="button"
class="btn btn-secondary"
data-bs-dismiss="modal"
>
Close
</button>
</div>
</div>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="card-footer">
Visit our
<a
href="https://github.com/iamromulan/quectel-rgmii-toolkit/tree/development"
target="_blank"
class="text-reset"
>repository</a
>
or
<a
href="https://github.com/iamromulan/quectel-rgmii-configuration-notes.git"
target="_blank"
class="text-reset"
>documentation</a
>
for more information. All rights reserved. 2024
</div>
</div>
</div>
</div>
<!-- Loading Modal for Reboot -->
<div class="modal-overlay" x-show="showModal">
<div class="loading-modal">
<div
class="loading-text"
style="display: flex; flex-direction: column"
>
<h3>This will reboot the modem.</h3>
<p style="margin-top: 0.5rem">Continue?</p>
</div>
<div class="d-grid gap-2 d-md-block">
<button
class="btn btn-primary"
type="button"
@click="updateIMEI()"
>
Reboot
</button>
<button
class="btn btn-danger"
type="button"
@click="closeModal()"
>
Cancel
</button>
</div>
</div>
</div>
<!-- Reboot Modal Countdown -->
<div class="modal-overlay" x-show="isRebooting">
<div class="loading-modal">
<div class="loader"></div>
<div
class="loading-text"
style="display: flex; flex-direction: column"
>
<h3>Rebooting...</h3>
<p style="margin-top: 0.5rem">
Please wait for
<span x-text="countdown" style="font-weight: 500"></span>
seconds.
</p>
</div>
</div>
</div>
</div>
</main>
<script src="js/dark-mode.js"></script>
<script>
function fetchDeviceInfo() {
return {
manufacturer: "-",
modelName: "-",
firmwareVersion: "-",
imsi: "-",
iccid: "-",
imei: "-",
newImei: null,
lanIp: "-",
wwanIpv4: "-",
wwanIpv6: "-",
phoneNumber: "无",
simpleAdminVersion: "-",
atcmd: null,
atCommandResponse: "",
showModal: false,
isLoading: false,
isRebooting: false,
countdown: 3,
sendATCommand() {
if (!this.atcmd) {
// Use ATI as default command
console.log(
"AT Command is empty, using ATI as default command: "
);
}
this.isLoading = true;
fetch(
"/cgi-bin/get_atcommand?" +
new URLSearchParams({
atcmd: this.atcmd,
})
)
.then((res) => {
return res.text();
})
.then((data) => {
this.atCommandResponse = data;
})
.catch((error) => {
console.error("Error: ", error);
this.showError = true;
});
},
fetchATCommand() {
this.atcmd =
'AT+CGMI;+CGMM;+QGMR;+CIMI;+ICCID;+CGSN;+QMAP="LANIP";+QMAP="WWAN";+CNUM';
this.isLoading = true;
fetch(
"/cgi-bin/get_atcommand?" +
new URLSearchParams({
atcmd: this.atcmd,
})
)
.then((res) => {
return res.text();
})
.then((data) => {
this.atCommandResponse = data;
this.parseFetchedData();
})
.catch((error) => {
console.error("Error: ", error);
this.showError = true;
});
},
parseFetchedData() {
const lines = this.atCommandResponse.split("\n");
console.log("AT Command Response: ", lines);
this.manufacturer = lines[1].trim();
this.modelName = lines[3].trim();
this.firmwareVersion = lines[5].trim();
this.imei = lines[11].trim();
this.lanIp = lines[13].trim().split(",")[3];
this.wwanIpv4 = lines[15].trim().split(",")[4].replace(/"/g, "");
this.wwanIpv6 = lines[16].trim().split(",")[4].replace(/"/g, "");
try {
this.imsi = lines[7].trim();
this.iccid = lines[9].trim().replace("+ICCID: ", "");
this.phoneNumber = lines[18]
.trim()
.split(",")[1]
.replace(/"/g, "");
if (this.phoneNumber === "") {
this.phoneNumber = "Unknown";
}
} catch (error) {
this.phoneNumber = "No SIM Card Inserted or Detected";
this.imsi = " ";
this.iccid = " ";
}
this.simpleAdminVersion = "SimpleAdminRev-Beta-1.0";
this.isLoading = false;
},
updateIMEI() {
this.atcmd = `AT+EGMR=1,7,"${this.newImei}"`;
this.sendATCommand();
this.rebootDevice();
},
rebootDevice() {
this.atcmd = "AT+CFUN=1,1";
this.sendATCommand();
this.isLoading = true;
this.showModal = false;
this.isRebooting = true;
this.countdown = 40;
const interval = setInterval(() => {
this.countdown--;
if (this.countdown === 0) {
clearInterval(interval);
this.isLoading = false;
this.showModal = false;
this.isRebooting = false;
this.init();
}
}, 1000);
},
openModal() {
if (!this.newImei) {
alert("No new IMEI provided.");
return;
}
if (this.newImei.length !== 15) {
alert("IMEI is invalid");
return;
}
if (this.newImei === this.imei) {
alert("IMEI is the same as the current IMEI");
return;
}
this.showModal = true;
},
closeModal() {
this.showModal = false;
},
init() {
this.fetchATCommand();
},
};
}
</script>
</body>
</html>