From e5e76412f1a20e8aed95614cbd7bf2b638cda2cc Mon Sep 17 00:00:00 2001
From: zhang <zc857179121@qq.com>
Date: 星期三, 11 三月 2026 13:30:31 +0800
Subject: [PATCH] 1
---
zy-acs-hex/src/main/resources/application.yml | 9
/dev/null | 354 -----------------
zy-acs-hex/dashboard.html | 392 +++++++++++++++++++
zy-acs-hex/pom.xml | 2
zy-acs-hex/src/main/java/com/zy/acs/hex/config/WebMvcConfig.java | 69 +++
zy-acs-hex/src/main/java/com/zy/acs/hex/controller/RouterController.java | 37 +
zy-acs-hex/src/main/webapp/views/index.html | 165 ++++++++
zy-acs-hex/src/main/java/com/zy/acs/hex/HexApplication.java | 5
zy-acs-hex/src/main/java/com/zy/acs/hex/controller/DeviceLogController.java | 37 +
zy-acs-cv/src/main/webapp/views/pipeline.html | 7
zy-acs-hex/src/main/webapp/views/login.html | 104 +++++
11 files changed, 822 insertions(+), 359 deletions(-)
diff --git a/zy-acs-cv/src/main/webapp/views/pipeline.html b/zy-acs-cv/src/main/webapp/views/pipeline.html
index 4c6f970..65846fd 100644
--- a/zy-acs-cv/src/main/webapp/views/pipeline.html
+++ b/zy-acs-cv/src/main/webapp/views/pipeline.html
@@ -841,6 +841,7 @@
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" id="save">淇濆瓨</button>
+ <button type="button" class="btn btn-secondary" id="clear">娓呴櫎</button>
<button type="button" class="btn btn-secondary" id="cancel">鍙栨秷</button>
</div>
</div>
@@ -1090,6 +1091,12 @@
});
});
+ // 娓呴櫎浠诲姟鍙峰拰鐩爣绔欑偣
+ $(document).on('click', '#clear', function () {
+ $('#workNo').val(0);
+ $('#staNo').val(0);
+ });
+
// 鍙栨秷绔欑偣淇℃伅淇敼
$(document).on('click', '#cancel', function () {
closeModal();
diff --git a/zy-acs-hex/dashboard.html b/zy-acs-hex/dashboard.html
new file mode 100644
index 0000000..378c261
--- /dev/null
+++ b/zy-acs-hex/dashboard.html
@@ -0,0 +1,392 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>鏈哄櫒浜烘暟鎹洃鎺�</title>
+ <!-- 寮曞叆 layui-vue 鏍峰紡 -->
+ <link href="https://cdn.jsdelivr.net/npm/layui-vue@2.1.0/dist/index.css" rel="stylesheet">
+ <!-- 寮曞叆 Vue 3 -->
+ <script src="https://cdn.jsdelivr.net/npm/vue@3.3.4/dist/vue.global.min.js"></script>
+ <!-- 寮曞叆 layui-vue -->
+ <script src="https://cdn.jsdelivr.net/npm/layui-vue@2.1.0/dist/index.js"></script>
+ <!-- 寮曞叆 Chart.js -->
+ <script src="/static/js/chart.umd.min.js"></script>
+ <!-- 寮曞叆 Font Awesome -->
+ <link href="/static/css/font-awesome.min.css" rel="stylesheet">
+ <style>
+ body {
+ font-family: 'Inter', sans-serif;
+ background-color: #f5f7fa;
+ }
+ .layui-card {
+ margin-bottom: 16px;
+ }
+ .layui-card-header {
+ font-weight: 600;
+ }
+ .status-online {
+ color: #10b981;
+ }
+ .status-offline {
+ color: #ef4444;
+ }
+ .chart-container {
+ height: 300px;
+ }
+ .realtime-container {
+ height: 160px;
+ overflow-y: auto;
+ }
+ </style>
+</head>
+<body>
+ <div id="app">
+ <!-- 椤堕儴瀵艰埅鏍� -->
+ <lay-header height="60px" bg-color="#fff" shadow>
+ <template #left>
+ <div class="flex items-center space-x-2">
+ <i class="fa fa-android text-2xl" style="color: #3b82f6"></i>
+ <h1 class="text-xl font-bold" style="color: #1e293b">鏈哄櫒浜烘暟鎹洃鎺�</h1>
+ </div>
+ </template>
+ <template #right>
+ <div class="flex items-center space-x-4">
+ <lay-input placeholder="鎼滅储鏈哄櫒浜�..." prefix-icon="search" style="width: 200px"></lay-input>
+ <lay-button type="primary" @click="refreshData">
+ <i class="fa fa-refresh mr-1"></i> 鍒锋柊
+ </lay-button>
+ </div>
+ </template>
+ </lay-header>
+
+ <!-- 涓诲唴瀹瑰尯 -->
+ <lay-container style="padding: 20px">
+ <!-- 鐘舵�佹瑙� -->
+ <lay-row :gutter="16">
+ <lay-col :span="6">
+ <lay-card shadow>
+ <div class="flex items-center justify-between">
+ <div>
+ <p style="color: #64748b; font-size: 14px">鎬绘満鍣ㄤ汉鏁�</p>
+ <h3 style="font-size: 24px; font-weight: bold; color: #1e293b">24</h3>
+ </div>
+ <div style="width: 48px; height: 48px; border-radius: 50%; background-color: #dbeafe; display: flex; align-items: center; justify-content: center">
+ <i class="fa fa-microchip text-xl" style="color: #3b82f6"></i>
+ </div>
+ </div>
+ </lay-card>
+ </lay-col>
+ <lay-col :span="6">
+ <lay-card shadow>
+ <div class="flex items-center justify-between">
+ <div>
+ <p style="color: #64748b; font-size: 14px">鍦ㄧ嚎鏈哄櫒浜�</p>
+ <h3 style="font-size: 24px; font-weight: bold; color: #10b981">18</h3>
+ </div>
+ <div style="width: 48px; height: 48px; border-radius: 50%; background-color: #d1fae5; display: flex; align-items: center; justify-content: center">
+ <i class="fa fa-check-circle text-xl" style="color: #10b981"></i>
+ </div>
+ </div>
+ </lay-card>
+ </lay-col>
+ <lay-col :span="6">
+ <lay-card shadow>
+ <div class="flex items-center justify-between">
+ <div>
+ <p style="color: #64748b; font-size: 14px">绂荤嚎鏈哄櫒浜�</p>
+ <h3 style="font-size: 24px; font-weight: bold; color: #ef4444">6</h3>
+ </div>
+ <div style="width: 48px; height: 48px; border-radius: 50%; background-color: #fee2e2; display: flex; align-items: center; justify-content: center">
+ <i class="fa fa-exclamation-circle text-xl" style="color: #ef4444"></i>
+ </div>
+ </div>
+ </lay-card>
+ </lay-col>
+ <lay-col :span="6">
+ <lay-card shadow>
+ <div class="flex items-center justify-between">
+ <div>
+ <p style="color: #64748b; font-size: 14px">浠婃棩鏁版嵁閲�</p>
+ <h3 style="font-size: 24px; font-weight: bold; color: #f59e0b">1.2k</h3>
+ </div>
+ <div style="width: 48px; height: 48px; border-radius: 50%; background-color: #fef3c7; display: flex; align-items: center; justify-content: center">
+ <i class="fa fa-database text-xl" style="color: #f59e0b"></i>
+ </div>
+ </div>
+ </lay-card>
+ </lay-col>
+ </lay-row>
+
+ <!-- 鏁版嵁鍥捐〃 -->
+ <lay-row :gutter="16" style="margin-top: 16px">
+ <lay-col :span="12">
+ <lay-card shadow>
+ <template #header>
+ <div class="flex justify-between items-center">
+ <h2 style="font-size: 16px; font-weight: 600; color: #1e293b">涓婅鏁版嵁瓒嬪娍</h2>
+ <div class="flex space-x-2">
+ <lay-button size="sm" type="primary">灏忔椂</lay-button>
+ <lay-button size="sm">澶�</lay-button>
+ <lay-button size="sm">鍛�</lay-button>
+ </div>
+ </div>
+ </template>
+ <div class="chart-container">
+ <canvas ref="upDataChart"></canvas>
+ </div>
+ </lay-card>
+ </lay-col>
+ <lay-col :span="12">
+ <lay-card shadow>
+ <template #header>
+ <div class="flex justify-between items-center">
+ <h2 style="font-size: 16px; font-weight: 600; color: #1e293b">涓嬭鏁版嵁瓒嬪娍</h2>
+ <div class="flex space-x-2">
+ <lay-button size="sm" type="primary">灏忔椂</lay-button>
+ <lay-button size="sm">澶�</lay-button>
+ <lay-button size="sm">鍛�</lay-button>
+ </div>
+ </div>
+ </template>
+ <div class="chart-container">
+ <canvas ref="downDataChart"></canvas>
+ </div>
+ </lay-card>
+ </lay-col>
+ </lay-row>
+
+ <!-- 璁惧鏁版嵁琛ㄦ牸 -->
+ <lay-card shadow style="margin-top: 16px">
+ <template #header>
+ <div class="flex justify-between items-center">
+ <h2 style="font-size: 16px; font-weight: 600; color: #1e293b">鏈哄櫒浜烘暟鎹垪琛�</h2>
+ <div class="flex space-x-2">
+ <lay-button size="sm">
+ <i class="fa fa-filter mr-1"></i> 绛涢��
+ </lay-button>
+ <lay-button size="sm">
+ <i class="fa fa-download mr-1"></i> 瀵煎嚭
+ </lay-button>
+ </div>
+ </div>
+ </template>
+ <lay-table :data="devices" :height="400">
+ <lay-table-column prop="id" label="璁惧ID" width="120"></lay-table-column>
+ <lay-table-column prop="name" label="璁惧鍚嶇О" width="150"></lay-table-column>
+ <lay-table-column prop="status" label="鐘舵��" width="100">
+ <template #default="{ row }">
+ <lay-badge v-if="row.status === 'online'" type="success">鍦ㄧ嚎</lay-badge>
+ <lay-badge v-else type="danger">绂荤嚎</lay-badge>
+ </template>
+ </lay-table-column>
+ <lay-table-column prop="upData" label="涓婅鏁版嵁" width="120"></lay-table-column>
+ <lay-table-column prop="downData" label="涓嬭鏁版嵁" width="120"></lay-table-column>
+ <lay-table-column prop="lastComm" label="鏈�鍚庨�氫俊" width="150"></lay-table-column>
+ <lay-table-column label="鎿嶄綔" width="150">
+ <template #default="{ row }">
+ <lay-button size="sm" type="primary" style="margin-right: 8px">
+ <i class="fa fa-eye"></i>
+ </lay-button>
+ <lay-button size="sm" type="warning" style="margin-right: 8px">
+ <i class="fa fa-edit"></i>
+ </lay-button>
+ <lay-button size="sm" type="danger">
+ <i class="fa fa-trash"></i>
+ </lay-button>
+ </template>
+ </lay-table-column>
+ </lay-table>
+ <div class="flex justify-between items-center mt-4">
+ <p style="color: #64748b; font-size: 14px">鏄剧ず 1-10 鏉★紝鍏� 24 鏉�</p>
+ <lay-pagination
+ v-model:current="currentPage"
+ v-model:limit="pageSize"
+ :total="total"
+ :limits="[10, 20, 50, 100]"
+ layout="prev, pager, next, jumper, sizes, total"
+ ></lay-pagination>
+ </div>
+ </lay-card>
+
+ <!-- 瀹炴椂鏁版嵁鏇存柊 -->
+ <lay-card shadow style="margin-top: 16px">
+ <template #header>
+ <h2 style="font-size: 16px; font-weight: 600; color: #1e293b">瀹炴椂鏁版嵁鏇存柊</h2>
+ </template>
+ <div class="realtime-container p-2 border border-gray-200 rounded-lg">
+ <div v-for="(item, index) in realtimeData" :key="index" class="py-1 border-b border-gray-100">
+ <span style="color: #64748b; font-size: 12px">{{ item.timestamp }}</span>
+ <span style="color: #1e293b; margin-left: 10px">{{ item.message }}</span>
+ </div>
+ </div>
+ </lay-card>
+ </lay-container>
+
+ <!-- 椤佃剼 -->
+ <lay-footer height="60px" bg-color="#fff" shadow>
+ <div class="text-center" style="color: #64748b; font-size: 14px">
+ 漏 2026 鏈哄櫒浜烘暟鎹洃鎺х郴缁� | 鐗堟湰 1.0.0
+ </div>
+ </lay-footer>
+ </div>
+
+ <script>
+ const { createApp, ref, onMounted } = Vue;
+ const app = createApp({
+ components: {
+ LayHeader: layui.LayHeader,
+ LayContainer: layui.LayContainer,
+ LayRow: layui.LayRow,
+ LayCol: layui.LayCol,
+ LayCard: layui.LayCard,
+ LayInput: layui.LayInput,
+ LayButton: layui.LayButton,
+ LayTable: layui.LayTable,
+ LayTableColumn: layui.LayTableColumn,
+ LayBadge: layui.LayBadge,
+ LayPagination: layui.LayPagination,
+ LayFooter: layui.LayFooter
+ },
+ setup() {
+ // 妯℃嫙鏈哄櫒浜烘暟鎹�
+ const devices = ref([
+ { id: 'ROB-001', name: '閰嶉�佹満鍣ㄤ汉1鍙�', status: 'online', upData: '2.4KB', downData: '0.8KB', lastComm: '2鍒嗛挓鍓�' },
+ { id: 'ROB-002', name: '閰嶉�佹満鍣ㄤ汉2鍙�', status: 'online', upData: '1.8KB', downData: '0.5KB', lastComm: '5鍒嗛挓鍓�' },
+ { id: 'ROB-003', name: '宸℃鏈哄櫒浜�1鍙�', status: 'offline', upData: '0KB', downData: '0KB', lastComm: '2灏忔椂鍓�' },
+ { id: 'ROB-004', name: '閰嶉�佹満鍣ㄤ汉3鍙�', status: 'online', upData: '3.2KB', downData: '1.2KB', lastComm: '1鍒嗛挓鍓�' },
+ { id: 'ROB-005', name: '宸℃鏈哄櫒浜�2鍙�', status: 'online', upData: '1.5KB', downData: '0.6KB', lastComm: '3鍒嗛挓鍓�' },
+ { id: 'ROB-006', name: '閰嶉�佹満鍣ㄤ汉4鍙�', status: 'offline', upData: '0KB', downData: '0KB', lastComm: '5灏忔椂鍓�' },
+ { id: 'ROB-007', name: '宸℃鏈哄櫒浜�3鍙�', status: 'online', upData: '2.1KB', downData: '0.9KB', lastComm: '4鍒嗛挓鍓�' },
+ { id: 'ROB-008', name: '閰嶉�佹満鍣ㄤ汉5鍙�', status: 'online', upData: '2.8KB', downData: '1.1KB', lastComm: '2鍒嗛挓鍓�' },
+ { id: 'ROB-009', name: '宸℃鏈哄櫒浜�4鍙�', status: 'offline', upData: '0KB', downData: '0KB', lastComm: '1澶╁墠' },
+ { id: 'ROB-010', name: '閰嶉�佹満鍣ㄤ汉6鍙�', status: 'online', upData: '1.9KB', downData: '0.7KB', lastComm: '6鍒嗛挓鍓�' }
+ ]);
+
+ // 鍒嗛〉鏁版嵁
+ const currentPage = ref(1);
+ const pageSize = ref(10);
+ const total = ref(24);
+
+ // 瀹炴椂鏁版嵁
+ const realtimeData = ref([]);
+
+ // 鍥捐〃寮曠敤
+ const upDataChart = ref(null);
+ const downDataChart = ref(null);
+
+ // 鍒锋柊鏁版嵁
+ const refreshData = () => {
+ console.log('鍒锋柊鏁版嵁');
+ // 杩欓噷鍙互娣诲姞瀹為檯鐨勫埛鏂伴�昏緫
+ };
+
+ // 鍒濆鍖栧浘琛�
+ const initCharts = () => {
+ // 涓婅鏁版嵁鍥捐〃
+ const upCtx = upDataChart.value.getContext('2d');
+ new Chart(upCtx, {
+ type: 'line',
+ data: {
+ labels: ['00:00', '03:00', '06:00', '09:00', '12:00', '15:00', '18:00', '21:00'],
+ datasets: [{
+ label: '涓婅鏁版嵁 (KB)',
+ data: [12, 19, 15, 25, 22, 30, 28, 35],
+ borderColor: '#3b82f6',
+ backgroundColor: 'rgba(59, 130, 246, 0.1)',
+ tension: 0.4,
+ fill: true
+ }]
+ },
+ options: {
+ responsive: true,
+ maintainAspectRatio: false,
+ plugins: {
+ legend: {
+ display: false
+ }
+ },
+ scales: {
+ y: {
+ beginAtZero: true
+ }
+ }
+ }
+ });
+
+ // 涓嬭鏁版嵁鍥捐〃
+ const downCtx = downDataChart.value.getContext('2d');
+ new Chart(downCtx, {
+ type: 'line',
+ data: {
+ labels: ['00:00', '03:00', '06:00', '09:00', '12:00', '15:00', '18:00', '21:00'],
+ datasets: [{
+ label: '涓嬭鏁版嵁 (KB)',
+ data: [5, 8, 6, 12, 10, 15, 13, 18],
+ borderColor: '#10b981',
+ backgroundColor: 'rgba(16, 185, 129, 0.1)',
+ tension: 0.4,
+ fill: true
+ }]
+ },
+ options: {
+ responsive: true,
+ maintainAspectRatio: false,
+ plugins: {
+ legend: {
+ display: false
+ }
+ },
+ scales: {
+ y: {
+ beginAtZero: true
+ }
+ }
+ }
+ });
+ };
+
+ // 妯℃嫙瀹炴椂鏁版嵁鏇存柊
+ const simulateRealtimeData = () => {
+ const messages = [
+ 'ROB-001 閰嶉�佹満鍣ㄤ汉1鍙�: 杩愯涓紝浣嶇疆: A1鍖�',
+ 'ROB-002 閰嶉�佹満鍣ㄤ汉2鍙�: 寰呮満涓紝浣嶇疆: B2鍖�',
+ 'ROB-004 閰嶉�佹満鍣ㄤ汉3鍙�: 鍏呯數涓紝鐢甸噺: 85%',
+ 'ROB-005 宸℃鏈哄櫒浜�2鍙�: 宸℃涓紝宸插畬鎴�3/5浠诲姟',
+ 'ROB-007 宸℃鏈哄櫒浜�3鍙�: 寰呮満涓紝浣嶇疆: C3鍖�',
+ 'ROB-008 閰嶉�佹満鍣ㄤ汉5鍙�: 杩愯涓紝浣嶇疆: D4鍖�'
+ ];
+
+ setInterval(() => {
+ const message = messages[Math.floor(Math.random() * messages.length)];
+ const timestamp = new Date().toLocaleTimeString();
+ realtimeData.value.unshift({ timestamp, message });
+ // 闄愬埗鏄剧ず鏉℃暟
+ if (realtimeData.value.length > 20) {
+ realtimeData.value.pop();
+ }
+ }, 2000);
+ };
+
+ // 椤甸潰鍔犺浇瀹屾垚鍚庡垵濮嬪寲
+ onMounted(() => {
+ initCharts();
+ simulateRealtimeData();
+ });
+
+ return {
+ devices,
+ currentPage,
+ pageSize,
+ total,
+ realtimeData,
+ upDataChart,
+ downDataChart,
+ refreshData
+ };
+ }
+ });
+ app.mount('#app');
+ </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/zy-acs-hex/pom.xml b/zy-acs-hex/pom.xml
index 0a39584..eddbcf8 100644
--- a/zy-acs-hex/pom.xml
+++ b/zy-acs-hex/pom.xml
@@ -10,6 +10,8 @@
</parent>
<artifactId>zy-acs-hex</artifactId>
+ <version>1.0.0</version>
+ <packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
diff --git a/zy-acs-hex/src/main/java/com/zy/acs/hex/HexApplication.java b/zy-acs-hex/src/main/java/com/zy/acs/hex/HexApplication.java
index d779c50..571d86c 100644
--- a/zy-acs-hex/src/main/java/com/zy/acs/hex/HexApplication.java
+++ b/zy-acs-hex/src/main/java/com/zy/acs/hex/HexApplication.java
@@ -3,16 +3,19 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling;
@EnableScheduling
@ComponentScan(basePackages = {"com.zy.component", "com.zy.acs"})
@SpringBootApplication
-public class HexApplication {
+public class HexApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(HexApplication.class, args);
}
+
}
+
diff --git a/zy-acs-hex/src/main/java/com/zy/acs/hex/config/WebMvcConfig.java b/zy-acs-hex/src/main/java/com/zy/acs/hex/config/WebMvcConfig.java
new file mode 100644
index 0000000..5cb4541
--- /dev/null
+++ b/zy-acs-hex/src/main/java/com/zy/acs/hex/config/WebMvcConfig.java
@@ -0,0 +1,69 @@
+package com.zy.acs.hex.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.AsyncHandlerInterceptor;
+import org.springframework.web.servlet.config.annotation.CorsRegistry;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * WebMvc閰嶇疆, 鎷︽埅鍣ㄣ�佽祫婧愭槧灏勭瓑閮藉湪姝ら厤缃�
+ *
+ * @author vincent
+ * @since 2019-06-12 10:11:16
+ */
+@Configuration
+public class WebMvcConfig implements WebMvcConfigurer {
+
+ /**
+ * token閫氳繃header浼犻�掔殑鍚嶇О
+ */
+ public static final String TOKEN_HEADER_NAME = "Authorization";
+
+
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ registry.addInterceptor(getAsyncHandlerInterceptor())
+ .addPathPatterns("/**")
+ ;
+ }
+
+
+ @Bean
+ public AsyncHandlerInterceptor getAsyncHandlerInterceptor() {
+ return new AsyncHandlerInterceptor(){
+ @Override
+ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+ cors(response);
+ return true;
+ }
+ };
+ }
+
+
+
+ @Override
+ public void addResourceHandlers(ResourceHandlerRegistry registry) {
+ // 閰嶇疆闈欐�佽祫婧愬鐞嗗櫒
+ registry.addResourceHandler("/static/**")
+ .addResourceLocations("/static/");
+ // 閰嶇疆瑙嗗浘鏂囦欢澶勭悊鍣�
+ registry.addResourceHandler("/views/**")
+ .addResourceLocations("/views/");
+ }
+
+ public static void cors(HttpServletResponse response){
+ // 璺ㄥ煙璁剧疆
+ response.setHeader("Access-Control-Max-Age", "3600");
+ response.setHeader("Access-Control-Allow-Origin", "*");
+ response.setHeader("Access-Control-Allow-Methods", "*");
+ response.setHeader("Access-Control-Allow-Headers", "*");
+ response.setHeader("Access-Control-Expose-Headers", TOKEN_HEADER_NAME);
+ }
+
+}
diff --git a/zy-acs-hex/src/main/java/com/zy/acs/hex/controller/DeviceLogController.java b/zy-acs-hex/src/main/java/com/zy/acs/hex/controller/DeviceLogController.java
new file mode 100644
index 0000000..047b845
--- /dev/null
+++ b/zy-acs-hex/src/main/java/com/zy/acs/hex/controller/DeviceLogController.java
@@ -0,0 +1,37 @@
+package com.zy.acs.hex.controller;
+
+import com.zy.acs.common.domain.mq.DeviceMessage;
+import com.zy.acs.framework.common.R;
+import com.zy.component.influxdb.service.InfluxDBService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@RestController
+@Slf4j
+@RequestMapping(value = "/deviceLog")
+public class DeviceLogController {
+
+ @Autowired
+ private InfluxDBService influxDBService;
+
+
+ /**
+ * 鏌ヨ鏈�鏂扮殑鍗佹潯鏁版嵁
+ *
+ * @return
+ */
+ @GetMapping(value = "/query")
+ @ResponseBody
+ public R query() {
+ List<DeviceMessage> deviceMessages = influxDBService.queryPoints("select * from device order by time desc limit 10", DeviceMessage.class);
+ return R.ok(deviceMessages);
+ }
+
+
+}
diff --git a/zy-acs-hex/src/main/java/com/zy/acs/hex/controller/RouterController.java b/zy-acs-hex/src/main/java/com/zy/acs/hex/controller/RouterController.java
new file mode 100644
index 0000000..9fcbbc2
--- /dev/null
+++ b/zy-acs-hex/src/main/java/com/zy/acs/hex/controller/RouterController.java
@@ -0,0 +1,37 @@
+package com.zy.acs.hex.controller;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Created by vincent on 2019-07-30
+ */
+@Controller
+public class RouterController {
+
+
+
+
+ @RequestMapping("/")
+ public void index(HttpServletResponse response) {
+ try {
+ response.sendRedirect( "/views/index.html");
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ @RequestMapping("/login")
+ public void login(HttpServletResponse response) {
+ try {
+ response.sendRedirect( "/views/login.html");
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+
+
+}
diff --git a/zy-acs-hex/src/main/resources/application.yml b/zy-acs-hex/src/main/resources/application.yml
index 0a41bf9..6901000 100644
--- a/zy-acs-hex/src/main/resources/application.yml
+++ b/zy-acs-hex/src/main/resources/application.yml
@@ -5,7 +5,7 @@
name: rcs-hex
# RabbitMQ閰嶇疆
rabbitmq:
- host: 192.168.133.173
+ host: localhost
port: 5672
username: root
password: xltys1995
@@ -26,9 +26,10 @@
# --add-opens java.base/java.nio=ALL-UNNAMED
influxdb3:
enabled: true
- url: http://192.168.133.173:8181
- #token: apiv3_Jx1SvmBMV_kikGhc4eZJQbeGmNYN7KX1GdpoR9MClkKzMxSJ0MPKM_O2Xt3o1hVyRikMmlxZ_h9zfy6ybC5Idg
+ url: http://localhost:8181
+ token: apiv3_Jx1SvmBMV_kikGhc4eZJQbeGmNYN7KX1GdpoR9MClkKzMxSJ0MPKM_O2Xt3o1hVyRikMmlxZ_h9zfy6ybC5Idg
database: rcs
- token: apiv3_116RKycNhxbf62Nys4zthC05aRD-aidzhEpEpLtsFuedhJTaCtVklNrzHs9LHxBWMuzDclBHVgToGoQuWGiIIA
+ # 铏氭嫙鏈虹殑token
+ #token: apiv3_116RKycNhxbf62Nys4zthC05aRD-aidzhEpEpLtsFuedhJTaCtVklNrzHs9LHxBWMuzDclBHVgToGoQuWGiIIA
retention-period: 30d
createDatabaseUrl: ${influxdb3.url}/api/v3/configure/database
diff --git a/zy-acs-hex/src/main/webapp/views/dashboard.html b/zy-acs-hex/src/main/webapp/views/dashboard.html
deleted file mode 100644
index ac20308..0000000
--- a/zy-acs-hex/src/main/webapp/views/dashboard.html
+++ /dev/null
@@ -1,354 +0,0 @@
-<!DOCTYPE html>
-<html lang="zh-CN">
-<head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>CTU灏忚溅鏁版嵁鐩戞帶</title>
- <script src="https://cdn.tailwindcss.com"></script>
- <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
- <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.8/dist/chart.umd.min.js"></script>
- <script>
- tailwind.config = {
- theme: {
- extend: {
- colors: {
- primary: '#3b82f6',
- secondary: '#10b981',
- warning: '#f59e0b',
- danger: '#ef4444',
- dark: '#1e293b',
- },
- fontFamily: {
- inter: ['Inter', 'sans-serif'],
- },
- }
- }
- }
- </script>
- <style type="text/tailwindcss">
- @layer utilities {
- .content-auto {
- content-visibility: auto;
- }
- .card-shadow {
- box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
- }
- .animate-pulse-slow {
- animation: pulse 3s cubic-bezier(0.4, 0, 0.6, 1) infinite;
- }
- }
- </style>
-</head>
-<body class="bg-gray-50 font-inter">
- <div class="min-h-screen">
- <!-- 椤堕儴瀵艰埅鏍� -->
- <header class="bg-white card-shadow sticky top-0 z-10">
- <div class="container mx-auto px-4 py-3 flex justify-between items-center">
- <div class="flex items-center space-x-2">
- <i class="fa fa-car text-primary text-2xl"></i>
- <h1 class="text-xl font-bold text-dark">CTU灏忚溅鏁版嵁鐩戞帶</h1>
- </div>
- <div class="flex items-center space-x-4">
- <div class="relative">
- <span class="absolute inset-y-0 left-0 flex items-center pl-3">
- <i class="fa fa-search text-gray-400"></i>
- </span>
- <input type="text" placeholder="鎼滅储璁惧..." class="pl-10 pr-4 py-2 rounded-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent">
- </div>
- <button class="bg-primary text-white px-4 py-2 rounded-lg hover:bg-blue-600 transition-colors">
- <i class="fa fa-refresh mr-1"></i> 鍒锋柊
- </button>
- </div>
- </div>
- </header>
-
- <!-- 涓诲唴瀹瑰尯 -->
- <main class="container mx-auto px-4 py-6">
- <!-- 鐘舵�佹瑙� -->
- <section class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-6">
- <div class="bg-white rounded-lg p-4 card-shadow">
- <div class="flex items-center justify-between">
- <div>
- <p class="text-gray-500 text-sm">鎬昏澶囨暟</p>
- <h3 class="text-2xl font-bold text-dark">24</h3>
- </div>
- <div class="w-12 h-12 rounded-full bg-blue-100 flex items-center justify-center">
- <i class="fa fa-microchip text-primary text-xl"></i>
- </div>
- </div>
- </div>
- <div class="bg-white rounded-lg p-4 card-shadow">
- <div class="flex items-center justify-between">
- <div>
- <p class="text-gray-500 text-sm">鍦ㄧ嚎璁惧</p>
- <h3 class="text-2xl font-bold text-secondary">18</h3>
- </div>
- <div class="w-12 h-12 rounded-full bg-green-100 flex items-center justify-center">
- <i class="fa fa-check-circle text-secondary text-xl"></i>
- </div>
- </div>
- </div>
- <div class="bg-white rounded-lg p-4 card-shadow">
- <div class="flex items-center justify-between">
- <div>
- <p class="text-gray-500 text-sm">绂荤嚎璁惧</p>
- <h3 class="text-2xl font-bold text-danger">6</h3>
- </div>
- <div class="w-12 h-12 rounded-full bg-red-100 flex items-center justify-center">
- <i class="fa fa-exclamation-circle text-danger text-xl"></i>
- </div>
- </div>
- </div>
- <div class="bg-white rounded-lg p-4 card-shadow">
- <div class="flex items-center justify-between">
- <div>
- <p class="text-gray-500 text-sm">浠婃棩鏁版嵁閲�</p>
- <h3 class="text-2xl font-bold text-warning">1.2k</h3>
- </div>
- <div class="w-12 h-12 rounded-full bg-yellow-100 flex items-center justify-center">
- <i class="fa fa-database text-warning text-xl"></i>
- </div>
- </div>
- </div>
- </section>
-
- <!-- 鏁版嵁鍥捐〃 -->
- <section class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6">
- <!-- 涓婅鏁版嵁鍥捐〃 -->
- <div class="bg-white rounded-lg p-4 card-shadow">
- <div class="flex justify-between items-center mb-4">
- <h2 class="text-lg font-semibold text-dark">涓婅鏁版嵁瓒嬪娍</h2>
- <div class="flex space-x-2">
- <button class="px-3 py-1 text-sm bg-blue-100 text-primary rounded-md">灏忔椂</button>
- <button class="px-3 py-1 text-sm bg-gray-100 text-gray-600 rounded-md">澶�</button>
- <button class="px-3 py-1 text-sm bg-gray-100 text-gray-600 rounded-md">鍛�</button>
- </div>
- </div>
- <div class="h-64">
- <canvas id="upDataChart"></canvas>
- </div>
- </div>
- <!-- 涓嬭鏁版嵁鍥捐〃 -->
- <div class="bg-white rounded-lg p-4 card-shadow">
- <div class="flex justify-between items-center mb-4">
- <h2 class="text-lg font-semibold text-dark">涓嬭鏁版嵁瓒嬪娍</h2>
- <div class="flex space-x-2">
- <button class="px-3 py-1 text-sm bg-blue-100 text-primary rounded-md">灏忔椂</button>
- <button class="px-3 py-1 text-sm bg-gray-100 text-gray-600 rounded-md">澶�</button>
- <button class="px-3 py-1 text-sm bg-gray-100 text-gray-600 rounded-md">鍛�</button>
- </div>
- </div>
- <div class="h-64">
- <canvas id="downDataChart"></canvas>
- </div>
- </div>
- </section>
-
- <!-- 璁惧鏁版嵁琛ㄦ牸 -->
- <section class="bg-white rounded-lg p-4 card-shadow">
- <div class="flex justify-between items-center mb-4">
- <h2 class="text-lg font-semibold text-dark">CTU灏忚溅鏁版嵁鍒楄〃</h2>
- <div class="flex space-x-2">
- <button class="px-3 py-1 text-sm bg-gray-100 text-gray-600 rounded-md">
- <i class="fa fa-filter mr-1"></i> 绛涢��
- </button>
- <button class="px-3 py-1 text-sm bg-gray-100 text-gray-600 rounded-md">
- <i class="fa fa-download mr-1"></i> 瀵煎嚭
- </button>
- </div>
- </div>
- <div class="overflow-x-auto">
- <table class="min-w-full divide-y divide-gray-200">
- <thead>
- <tr>
- <th class="px-6 py-3 bg-gray-50 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">璁惧ID</th>
- <th class="px-6 py-3 bg-gray-50 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">璁惧鍚嶇О</th>
- <th class="px-6 py-3 bg-gray-50 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">鐘舵��</th>
- <th class="px-6 py-3 bg-gray-50 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">涓婅鏁版嵁</th>
- <th class="px-6 py-3 bg-gray-50 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">涓嬭鏁版嵁</th>
- <th class="px-6 py-3 bg-gray-50 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">鏈�鍚庨�氫俊</th>
- <th class="px-6 py-3 bg-gray-50 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">鎿嶄綔</th>
- </tr>
- </thead>
- <tbody class="bg-white divide-y divide-gray-200" id="deviceTableBody">
- <!-- 琛ㄦ牸鏁版嵁灏嗛�氳繃JavaScript鍔ㄦ�佺敓鎴� -->
- </tbody>
- </table>
- </div>
- <div class="flex justify-between items-center mt-4">
- <p class="text-sm text-gray-500">鏄剧ず 1-10 鏉★紝鍏� 24 鏉�</p>
- <div class="flex space-x-1">
- <button class="px-3 py-1 text-sm bg-gray-100 text-gray-600 rounded-md disabled:opacity-50" disabled>涓婁竴椤�</button>
- <button class="px-3 py-1 text-sm bg-primary text-white rounded-md">1</button>
- <button class="px-3 py-1 text-sm bg-gray-100 text-gray-600 rounded-md">2</button>
- <button class="px-3 py-1 text-sm bg-gray-100 text-gray-600 rounded-md">3</button>
- <button class="px-3 py-1 text-sm bg-gray-100 text-gray-600 rounded-md">涓嬩竴椤�</button>
- </div>
- </div>
- </section>
-
- <!-- 瀹炴椂鏁版嵁鏇存柊 -->
- <section class="bg-white rounded-lg p-4 card-shadow mt-6">
- <h2 class="text-lg font-semibold text-dark mb-4">瀹炴椂鏁版嵁鏇存柊</h2>
- <div class="h-40 overflow-y-auto p-2 border border-gray-200 rounded-lg" id="realtimeData">
- <!-- 瀹炴椂鏁版嵁灏嗛�氳繃JavaScript鍔ㄦ�佺敓鎴� -->
- </div>
- </section>
- </main>
-
- <!-- 椤佃剼 -->
- <footer class="bg-white card-shadow mt-6 py-4">
- <div class="container mx-auto px-4 text-center text-gray-500 text-sm">
- <p>漏 2026 鐗╄仈缃戣澶囨暟鎹洃鎺х郴缁� | 鐗堟湰 1.0.0</p>
- </div>
- </footer>
- </div>
-
- <script>
- // 妯℃嫙CTU灏忚溅鏁版嵁
- const devices = [
- { id: 'CTU-001', name: '閰嶉�佸皬杞�1鍙�', status: 'online', upData: '2.4KB', downData: '0.8KB', lastComm: '2鍒嗛挓鍓�' },
- { id: 'CTU-002', name: '閰嶉�佸皬杞�2鍙�', status: 'online', upData: '1.8KB', downData: '0.5KB', lastComm: '5鍒嗛挓鍓�' },
- { id: 'CTU-003', name: '宸℃灏忚溅1鍙�', status: 'offline', upData: '0KB', downData: '0KB', lastComm: '2灏忔椂鍓�' },
- { id: 'CTU-004', name: '閰嶉�佸皬杞�3鍙�', status: 'online', upData: '3.2KB', downData: '1.2KB', lastComm: '1鍒嗛挓鍓�' },
- { id: 'CTU-005', name: '宸℃灏忚溅2鍙�', status: 'online', upData: '1.5KB', downData: '0.6KB', lastComm: '3鍒嗛挓鍓�' },
- { id: 'CTU-006', name: '閰嶉�佸皬杞�4鍙�', status: 'offline', upData: '0KB', downData: '0KB', lastComm: '5灏忔椂鍓�' },
- { id: 'CTU-007', name: '宸℃灏忚溅3鍙�', status: 'online', upData: '2.1KB', downData: '0.9KB', lastComm: '4鍒嗛挓鍓�' },
- { id: 'CTU-008', name: '閰嶉�佸皬杞�5鍙�', status: 'online', upData: '2.8KB', downData: '1.1KB', lastComm: '2鍒嗛挓鍓�' },
- { id: 'CTU-009', name: '宸℃灏忚溅4鍙�', status: 'offline', upData: '0KB', downData: '0KB', lastComm: '1澶╁墠' },
- { id: 'CTU-010', name: '閰嶉�佸皬杞�6鍙�', status: 'online', upData: '1.9KB', downData: '0.7KB', lastComm: '6鍒嗛挓鍓�' }
- ];
-
- // 鐢熸垚琛ㄦ牸鏁版嵁
- function generateTableData() {
- const tbody = document.getElementById('deviceTableBody');
- tbody.innerHTML = '';
- devices.forEach(device => {
- const row = document.createElement('tr');
- row.innerHTML = `
- <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">${device.id}</td>
- <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${device.name}</td>
- <td class="px-6 py-4 whitespace-nowrap">
- <span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full ${device.status === 'online' ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-800'}">
- ${device.status === 'online' ? '鍦ㄧ嚎' : '绂荤嚎'}
- </span>
- </td>
- <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${device.upData}</td>
- <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${device.downData}</td>
- <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">${device.lastComm}</td>
- <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
- <button class="text-primary hover:text-blue-700 mr-3">
- <i class="fa fa-eye"></i>
- </button>
- <button class="text-warning hover:text-yellow-700 mr-3">
- <i class="fa fa-edit"></i>
- </button>
- <button class="text-danger hover:text-red-700">
- <i class="fa fa-trash"></i>
- </button>
- </td>
- `;
- tbody.appendChild(row);
- });
- }
-
- // 鍒濆鍖栧浘琛�
- function initCharts() {
- // 涓婅鏁版嵁鍥捐〃
- const upCtx = document.getElementById('upDataChart').getContext('2d');
- const upDataChart = new Chart(upCtx, {
- type: 'line',
- data: {
- labels: ['00:00', '03:00', '06:00', '09:00', '12:00', '15:00', '18:00', '21:00'],
- datasets: [{
- label: '涓婅鏁版嵁 (KB)',
- data: [12, 19, 15, 25, 22, 30, 28, 35],
- borderColor: '#3b82f6',
- backgroundColor: 'rgba(59, 130, 246, 0.1)',
- tension: 0.4,
- fill: true
- }]
- },
- options: {
- responsive: true,
- maintainAspectRatio: false,
- plugins: {
- legend: {
- display: false
- }
- },
- scales: {
- y: {
- beginAtZero: true
- }
- }
- }
- });
-
- // 涓嬭鏁版嵁鍥捐〃
- const downCtx = document.getElementById('downDataChart').getContext('2d');
- const downDataChart = new Chart(downCtx, {
- type: 'line',
- data: {
- labels: ['00:00', '03:00', '06:00', '09:00', '12:00', '15:00', '18:00', '21:00'],
- datasets: [{
- label: '涓嬭鏁版嵁 (KB)',
- data: [5, 8, 6, 12, 10, 15, 13, 18],
- borderColor: '#10b981',
- backgroundColor: 'rgba(16, 185, 129, 0.1)',
- tension: 0.4,
- fill: true
- }]
- },
- options: {
- responsive: true,
- maintainAspectRatio: false,
- plugins: {
- legend: {
- display: false
- }
- },
- scales: {
- y: {
- beginAtZero: true
- }
- }
- }
- });
- }
-
- // 妯℃嫙瀹炴椂鏁版嵁鏇存柊
- function simulateRealtimeData() {
- const realtimeContainer = document.getElementById('realtimeData');
- const messages = [
- 'CTU-001 閰嶉�佸皬杞�1鍙�: 杩愯涓紝浣嶇疆: A1鍖�',
- 'CTU-002 閰嶉�佸皬杞�2鍙�: 寰呮満涓紝浣嶇疆: B2鍖�',
- 'CTU-004 閰嶉�佸皬杞�3鍙�: 鍏呯數涓紝鐢甸噺: 85%',
- 'CTU-005 宸℃灏忚溅2鍙�: 宸℃涓紝宸插畬鎴�3/5浠诲姟',
- 'CTU-007 宸℃灏忚溅3鍙�: 寰呮満涓紝浣嶇疆: C3鍖�',
- 'CTU-008 閰嶉�佸皬杞�5鍙�: 杩愯涓紝浣嶇疆: D4鍖�'
- ];
-
- setInterval(() => {
- const message = messages[Math.floor(Math.random() * messages.length)];
- const timestamp = new Date().toLocaleTimeString();
- const div = document.createElement('div');
- div.className = 'py-1 border-b border-gray-100';
- div.innerHTML = `<span class="text-gray-500 text-xs">${timestamp}</span> <span class="text-gray-900">${message}</span>`;
- realtimeContainer.prepend(div);
- // 闄愬埗鏄剧ず鏉℃暟
- if (realtimeContainer.children.length > 20) {
- realtimeContainer.removeChild(realtimeContainer.lastChild);
- }
- }, 2000);
- }
-
- // 椤甸潰鍔犺浇瀹屾垚鍚庡垵濮嬪寲
- document.addEventListener('DOMContentLoaded', function() {
- generateTableData();
- initCharts();
- simulateRealtimeData();
- });
- </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/zy-acs-hex/src/main/webapp/views/index.html b/zy-acs-hex/src/main/webapp/views/index.html
new file mode 100644
index 0000000..63acba4
--- /dev/null
+++ b/zy-acs-hex/src/main/webapp/views/index.html
@@ -0,0 +1,165 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>鏈哄櫒浜烘棩蹇楃郴缁�</title>
+ <style>
+ * {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ }
+ body {
+ font-family: Arial, sans-serif;
+ background-color: #f0f2f5;
+ }
+ .header {
+ background-color: #1890ff;
+ color: white;
+ padding: 15px 20px;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ }
+ .header h1 {
+ font-size: 20px;
+ }
+ .header button {
+ background-color: transparent;
+ color: white;
+ border: 1px solid white;
+ padding: 5px 15px;
+ border-radius: 4px;
+ cursor: pointer;
+ }
+ .header button:hover {
+ background-color: rgba(255,255,255,0.1);
+ }
+ .container {
+ padding: 20px;
+ }
+ .refresh-btn {
+ background-color: #1890ff;
+ color: white;
+ border: none;
+ padding: 8px 16px;
+ border-radius: 4px;
+ cursor: pointer;
+ margin-bottom: 20px;
+ }
+ .refresh-btn:hover {
+ background-color: #40a9ff;
+ }
+ table {
+ width: 100%;
+ border-collapse: collapse;
+ background-color: white;
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
+ }
+ th, td {
+ padding: 12px;
+ text-align: left;
+ border-bottom: 1px solid #ddd;
+ }
+ th {
+ background-color: #f5f5f5;
+ font-weight: bold;
+ }
+ tr:hover {
+ background-color: #f5f5f5;
+ }
+ .loading {
+ text-align: center;
+ padding: 20px;
+ color: #666;
+ }
+ .error {
+ text-align: center;
+ padding: 20px;
+ color: red;
+ }
+ </style>
+</head>
+<body>
+ <div class="header">
+ <h1>鏈哄櫒浜轰笂涓嬭鏃ュ織</h1>
+ <button id="logoutBtn">鐧诲嚭</button>
+ </div>
+ <div class="container">
+ <button class="refresh-btn" id="refreshBtn">鍒锋柊鏁版嵁</button>
+ <div id="loading" class="loading">鍔犺浇涓�...</div>
+ <div id="error" class="error" style="display: none;"></div>
+ <table id="logTable" style="display: none;">
+ <thead>
+ <tr>
+ <th>鏃堕棿</th>
+ <th>璁惧ID</th>
+ <th>娑堟伅绫诲瀷</th>
+ <th>娑堟伅鍐呭</th>
+ </tr>
+ </thead>
+ <tbody id="logTableBody">
+ </tbody>
+ </table>
+ </div>
+ <script>
+ // 妫�鏌ョ櫥褰曠姸鎬�
+ function checkLogin() {
+ if (!localStorage.getItem('loggedIn')) {
+ window.location.href = '/login';
+ }
+ }
+
+ // 鐧诲嚭鍔熻兘
+ document.getElementById('logoutBtn').addEventListener('click', function() {
+ localStorage.removeItem('loggedIn');
+ window.location.href = '/login';
+ });
+
+ // 鍔犺浇鏃ュ織鏁版嵁
+ function loadLogData() {
+ document.getElementById('loading').style.display = 'block';
+ document.getElementById('error').style.display = 'none';
+ document.getElementById('logTable').style.display = 'none';
+
+ fetch('/deviceLog/query')
+ .then(response => response.json())
+ .then(data => {
+ document.getElementById('loading').style.display = 'none';
+ if (data && data.length > 0) {
+ document.getElementById('logTable').style.display = 'table';
+ const tbody = document.getElementById('logTableBody');
+ tbody.innerHTML = '';
+
+ data.forEach(item => {
+ const row = document.createElement('tr');
+ row.innerHTML = `
+ <td>${item.time || '-'}</td>
+ <td>${item.deviceId || '-'}</td>
+ <td>${item.messageType || '-'}</td>
+ <td>${item.messageContent || '-'}</td>
+ `;
+ tbody.appendChild(row);
+ });
+ } else {
+ document.getElementById('error').textContent = '鏆傛棤鏃ュ織鏁版嵁';
+ document.getElementById('error').style.display = 'block';
+ }
+ })
+ .catch(error => {
+ document.getElementById('loading').style.display = 'none';
+ document.getElementById('error').textContent = '鍔犺浇鏁版嵁澶辫触: ' + error.message;
+ document.getElementById('error').style.display = 'block';
+ });
+ }
+
+ // 鍒锋柊鎸夐挳鐐瑰嚮浜嬩欢
+ document.getElementById('refreshBtn').addEventListener('click', loadLogData);
+
+ // 椤甸潰鍔犺浇鏃舵鏌ョ櫥褰曠姸鎬佸苟鍔犺浇鏁版嵁
+ checkLogin();
+ loadLogData();
+ </script>
+</body>
+</html>
\ No newline at end of file
diff --git a/zy-acs-hex/src/main/webapp/views/login.html b/zy-acs-hex/src/main/webapp/views/login.html
new file mode 100644
index 0000000..f39e7b1
--- /dev/null
+++ b/zy-acs-hex/src/main/webapp/views/login.html
@@ -0,0 +1,104 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>鐧诲綍 - 鏈哄櫒浜烘棩蹇楃郴缁�</title>
+ <style>
+ * {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ }
+ body {
+ font-family: Arial, sans-serif;
+ background-color: #f0f2f5;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 100vh;
+ }
+ .login-container {
+ background-color: white;
+ padding: 40px;
+ border-radius: 8px;
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
+ width: 100%;
+ max-width: 400px;
+ }
+ h2 {
+ text-align: center;
+ margin-bottom: 30px;
+ color: #333;
+ }
+ .form-group {
+ margin-bottom: 20px;
+ }
+ label {
+ display: block;
+ margin-bottom: 8px;
+ color: #666;
+ }
+ input {
+ width: 100%;
+ padding: 10px;
+ border: 1px solid #ddd;
+ border-radius: 4px;
+ font-size: 16px;
+ }
+ button {
+ width: 100%;
+ padding: 12px;
+ background-color: #1890ff;
+ color: white;
+ border: none;
+ border-radius: 4px;
+ font-size: 16px;
+ cursor: pointer;
+ margin-top: 10px;
+ }
+ button:hover {
+ background-color: #40a9ff;
+ }
+ .error-message {
+ color: red;
+ margin-top: 10px;
+ text-align: center;
+ }
+ </style>
+</head>
+<body>
+ <div class="login-container">
+ <h2>鏈哄櫒浜烘棩蹇楃郴缁�</h2>
+ <form id="loginForm">
+ <div class="form-group">
+ <label for="username">鐢ㄦ埛鍚�</label>
+ <input type="text" id="username" name="username" required>
+ </div>
+ <div class="form-group">
+ <label for="password">瀵嗙爜</label>
+ <input type="password" id="password" name="password" required>
+ </div>
+ <button type="submit">鐧诲綍</button>
+ <div id="errorMessage" class="error-message"></div>
+ </form>
+ </div>
+ <script>
+ document.getElementById('loginForm').addEventListener('submit', function(e) {
+ e.preventDefault();
+ const username = document.getElementById('username').value;
+ const password = document.getElementById('password').value;
+
+ // 绠�鍗曠殑鐧诲綍楠岃瘉锛堝疄闄呴」鐩腑搴旇璋冪敤鍚庣API锛�
+ if (username === 'admin' && password === 'admin123') {
+ // 瀛樺偍鐧诲綍鐘舵��
+ localStorage.setItem('loggedIn', 'true');
+ // 璺宠浆鍒颁富椤甸潰
+ window.location.href = '/';
+ } else {
+ document.getElementById('errorMessage').textContent = '鐢ㄦ埛鍚嶆垨瀵嗙爜閿欒';
+ }
+ });
+ </script>
+</body>
+</html>
\ No newline at end of file
--
Gitblit v1.9.1