diff options
Diffstat (limited to 'web/html/index.html')
| -rw-r--r-- | web/html/index.html | 114 |
1 files changed, 112 insertions, 2 deletions
diff --git a/web/html/index.html b/web/html/index.html index db678cd6..4089e6a6 100644 --- a/web/html/index.html +++ b/web/html/index.html @@ -167,7 +167,10 @@ <span>{{ i18n "pages.index.xrayErrorPopoverTitle" }}</span> </a-col> <a-col> - <a-icon type="bars" :style="{ cursor: 'pointer', float: 'right' }" @click="openLogs()"></a-tag> + <a-icon type="bars" :style="{ cursor: 'pointer', float: 'right' }" @click="openLogs()"></a-icon> + </a-col> + <a-col> + <a-icon type="bars" :style="{ cursor: 'pointer', float: 'right' }" @click="openXrayLogs()"></a-icon> </a-col> </a-row> </span> @@ -179,6 +182,10 @@ </template> </template> <template #actions> + <a-space v-if="app.ipLimitEnable" direction="horizontal" @click="openXrayLogs()" :style="{ justifyContent: 'center' }"> + <a-icon type="bars"></a-icon> + <span v-if="!isMobile">{{ i18n "pages.index.logs" }}</span> + </a-space> <a-space direction="horizontal" @click="stopXrayService" :style="{ justifyContent: 'center' }"> <a-icon type="poweroff"></a-icon> <span v-if="!isMobile">{{ i18n "pages.index.stopXray" }}</span> @@ -422,6 +429,40 @@ </a-form> <div class="ant-input" :style="{ height: 'auto', maxHeight: '500px', overflow: 'auto', marginTop: '0.5rem' }" v-html="logModal.formattedLogs"></div> </a-modal> + <a-modal id="xraylog-modal" + v-model="xraylogModal.visible" + :closable="true" @cancel="() => xraylogModal.visible = false" + :class="themeSwitcher.currentTheme" + width="80vw" + footer=""> + <template slot="title"> + {{ i18n "pages.index.logs" }} + <a-icon :spin="xraylogModal.loading" + type="sync" + :style="{ verticalAlign: 'middle', marginLeft: '10px' }" + :disabled="xraylogModal.loading" + @click="openXrayLogs()"> + </a-icon> + </template> + <a-form layout="inline"> + <a-form-item :style="{ marginRight: '0.5rem' }"> + <a-input-group compact> + <a-select size="small" v-model="xraylogModal.rows" :style="{ width: '70px' }" + @change="openXrayLogs()" :dropdown-class-name="themeSwitcher.currentTheme"> + <a-select-option value="10">10</a-select-option> + <a-select-option value="20">20</a-select-option> + <a-select-option value="50">50</a-select-option> + <a-select-option value="100">100</a-select-option> + <a-select-option value="500">500</a-select-option> + </a-select> + </a-input-group> + </a-form-item> + <a-form-item :style="{ float: 'right' }"> + <a-button type="primary" icon="download" @click="FileManager.downloadTextFile(xraylogModal.logs?.join('\n'), 'x-ui.log')"></a-button> + </a-form-item> + </a-form> + <div class="ant-input" :style="{ height: 'auto', maxHeight: '500px', overflow: 'auto', marginTop: '0.5rem' }" v-html="xraylogModal.formattedLogs"></div> + </a-modal> <a-modal id="backup-modal" v-model="backupModal.visible" title='{{ i18n "pages.index.backupTitle" }}' @@ -606,6 +647,57 @@ }, }; + const xraylogModal = { + visible: false, + logs: [], + rows: 20, + loading: false, + show(logs) { + this.visible = true; + this.logs = logs; + this.formattedLogs = this.logs?.length > 0 ? this.formatLogs(this.logs) : "No Record..."; + }, + formatLogs(logs) { + let formattedLogs = ''; + + logs.forEach((log, index) => { + if(index > 0) formattedLogs += '<br>'; + + const parts = log.split(' '); + + if(parts.length === 9) { + const dateTime = `<b>${parts[0]} ${parts[1]}</b>`; + const from = `<b>${parts[3]}</b>`; + const to = `<b>${parts[5].replace(/^\/+/, "")}</b>`; + + let outboundColor = ''; + if (parts[8].startsWith('blocked')) { + outboundColor = ' style="color: #e04141;"'; + } + else if (!parts[8].startsWith('direct')) { + outboundColor = ' style="color: #3c89e8;"'; + } + + formattedLogs += `<span${outboundColor}> +${dateTime} + ${parts[2]} + ${from} + ${parts[4]} + ${to} + ${parts.slice(6).join(' ')} +</span>`; + } else { + formattedLogs += `<span>${parts.join(' ')}</span>`; + } + }); + + return formattedLogs; + }, + hide() { + this.visible = false; + }, + }; + const backupModal = { visible: false, show() { @@ -629,10 +721,12 @@ status: new Status(), versionModal, logModal, + xraylogModal, backupModal, loadingTip: '{{ i18n "loading"}}', showAlert: false, - showIp: false + showIp: false, + ipLimitEnable: false, }, methods: { loading(spinning, tip = '{{ i18n "loading"}}') { @@ -721,6 +815,16 @@ await PromiseUtil.sleep(500); logModal.loading = false; }, + async openXrayLogs(){ + xraylogModal.loading = true; + const msg = await HttpUtil.post('server/xraylogs/'+xraylogModal.rows); + if (!msg.success) { + return; + } + xraylogModal.show(msg.obj); + await PromiseUtil.sleep(500); + xraylogModal.loading = false; + }, async openConfig() { this.loading(true); const msg = await HttpUtil.post('server/getConfigJson'); @@ -773,6 +877,12 @@ if (window.location.protocol !== "https:") { this.showAlert = true; } + + const msg = await HttpUtil.post('/panel/setting/defaultSettings'); + if (msg.success) { + this.ipLimitEnable = msg.obj.ipLimitEnable; + } + while (true) { try { await this.getStatus(); |
