Explorar el Código

feat: 新增功能+优化

jinx hace 1 día
padre
commit
2dd3ee6791
Se han modificado 12 ficheros con 3454 adiciones y 1479 borrados
  1. 2 1
      package.json
  2. 12 5
      public/index.html
  3. 1480 0
      src/App copy.vue
  4. 5 1470
      src/App.vue
  5. 12 1
      src/api.js
  6. 6 0
      src/main.js
  7. 16 0
      src/router/index.js
  8. 1534 0
      src/views/Home/index.vue
  9. 216 0
      src/views/Report/index.vue
  10. 145 0
      src/views/Report/tagCoordinateList.json
  11. 14 2
      vue.config.js
  12. 12 0
      yarn.lock

+ 2 - 1
package.json

@@ -13,7 +13,8 @@
     "core-js": "^3.6.5",
     "d3": "^7.3.0",
     "element-plus": "^1.3.0-beta.5",
-    "vue": "^3.0.0"
+    "vue": "^3.0.0",
+    "vue-router": "4.0.16"
   },
   "devDependencies": {
     "@vue/cli-plugin-babel": "~4.5.0",

+ 12 - 5
public/index.html

@@ -1,15 +1,22 @@
 <!DOCTYPE html>
 <html lang="">
   <head>
-    <meta charset="utf-8">
-    <meta http-equiv="X-UA-Compatible" content="IE=edge">
-    <meta name="viewport" content="width=device-width,initial-scale=1.0">
-    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
+    <meta charset="utf-8" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+    <meta
+      name="viewport"
+      content="width=device-width, initial-scale=1, viewport-fit=cover"
+    />
+    <link rel="icon" href="<%= BASE_URL %>favicon.ico" />
     <title>点位数据可视化 v2.0.1</title>
   </head>
   <body>
     <noscript>
-      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
+      <strong
+        >We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work
+        properly without JavaScript enabled. Please enable it to
+        continue.</strong
+      >
     </noscript>
     <div id="app"></div>
     <!-- built files will be auto injected -->

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1480 - 0
src/App copy.vue


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 5 - 1470
src/App.vue


+ 12 - 1
src/api.js

@@ -38,4 +38,15 @@ export function resetWholeData(sceneCode) {
         throw(res?.data?.msg || '操作失败')
       }
     })
-}
+}
+export function reportTagInfo(data) {
+  const url = `https://uat-laser.4dkankan.com/location/ingest`
+
+  return axios.post(url, data).then((res) => {
+    if (res?.data?.code === 200 || res?.status === 200) {
+      return res?.data?.msg || 'report success'
+    } else {
+      throw(res?.data?.msg || 'report failed')
+    }
+  })
+}

+ 6 - 0
src/main.js

@@ -1,8 +1,14 @@
 import { createApp } from 'vue'
 import App from './App.vue'
+import router from './router'
 import ElementPlus from 'element-plus'
 import 'element-plus/dist/index.css'
 
 const app = createApp(App)
 app.use(ElementPlus)
+app.use(router)
 app.mount('#app')
+
+
+
+

+ 16 - 0
src/router/index.js

@@ -0,0 +1,16 @@
+import { createRouter, createWebHistory ,createWebHashHistory } from "vue-router";
+import Home from "../views/Home/index.vue";
+import Report from "../views/Report/index.vue";
+
+const routes = [
+  { path: "/", component: Home },
+  { path: "/report", component: Report },
+];
+
+const router = createRouter({
+  // history: createWebHistory(process.env.BASE_URL),
+  history: createWebHashHistory(),
+  routes,
+});
+
+export default router;

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1534 - 0
src/views/Home/index.vue


+ 216 - 0
src/views/Report/index.vue

@@ -0,0 +1,216 @@
+<template>
+  <div class="report-page">
+    <h2 class="title">Report</h2>
+
+    <div class="button-list">
+      <el-button
+        v-for="item in tagList"
+        :key="item.id"
+        :class="['report-btn', { 'is-active': activeReportItem && activeReportItem.id === item.id }]"
+        type="primary"
+        plain
+        :loading="reportingId === item.id"
+        @click="onReport(item)"
+      >
+        <span class="btn-content">
+          <span class="btn-name">{{ item.name }}</span>
+          <span class="btn-id">#{{ item.id }}</span>
+        </span>
+      </el-button>
+
+      <el-button
+        class="report-btn stop-btn"
+        type="danger"
+        plain
+        :disabled="!activeReportItem"
+        @click="onStopReport()"
+      >
+        <span class="btn-content">
+          <span class="btn-name">结束上报</span>
+        </span>
+      </el-button>
+    </div>
+
+    <p v-if="activeReportItem" class="status-text">
+      Reporting: {{ activeReportItem.name }} #{{ activeReportItem.id }} (every 1s)
+    </p>
+
+    <div v-if="lastReportedItem" class="report-result">
+      <h3>Last Report Payload</h3>
+      <pre>{{ JSON.stringify(lastReportedItem, null, 2) }}</pre>
+    </div>
+  </div>
+</template>
+
+<script>
+import { ElMessage } from 'element-plus'
+import { reportTagInfo } from '@/api.js'
+import tagCoordinateList from './tagCoordinateList.json'
+
+export default {
+  name: 'ReportPage',
+  data() {
+    return {
+      tagList: tagCoordinateList,
+      reportingId: null,
+      activeReportItem: null,
+      lastReportedItem: null,
+      reportTimer: null,
+      isRequesting: false,
+    }
+  },
+  beforeUnmount() {
+    this.clearReportTimer()
+  },
+  methods: {
+    clearReportTimer() {
+      if (this.reportTimer) {
+        clearInterval(this.reportTimer)
+        this.reportTimer = null
+      }
+    },
+    sendReportOnce() {
+      if (!this.activeReportItem || this.isRequesting) {
+        return
+      }
+
+      const item = this.activeReportItem
+      this.reportingId = item.id
+      this.isRequesting = true
+
+      reportTagInfo(item).then(() => {
+        this.lastReportedItem = item
+      }).catch((err) => {
+        ElMessage({
+          message: err?.message || err || 'report failed',
+          type: 'error',
+        })
+      }).finally(() => {
+        this.isRequesting = false
+        this.reportingId = null
+      })
+    },
+    onReport(item) {
+      const switched = !this.activeReportItem || this.activeReportItem.id !== item.id
+      this.activeReportItem = item
+
+      this.clearReportTimer()
+      this.sendReportOnce()
+      this.reportTimer = setInterval(() => {
+        this.sendReportOnce()
+      }, 1000)
+
+      if (switched) {
+        // ElMessage({
+        //   message: `start reporting ${item.name} #${item.id}`,
+        //   type: 'success',
+        // })
+      }
+    },
+    onStopReport() {
+      this.clearReportTimer()
+      this.activeReportItem = null
+      this.reportingId = null
+      this.isRequesting = false
+      ElMessage({
+        message: 'report stopped',
+        type: 'info',
+      })
+    },
+  },
+}
+</script>
+
+<style scoped>
+.report-page {
+  padding: calc(12px + env(safe-area-inset-top)) 12px calc(16px + env(safe-area-inset-bottom));
+  max-width: 920px;
+  margin: 0 auto;
+}
+
+.title {
+  margin: 0 0 12px;
+  font-size: 20px;
+  line-height: 1.2;
+}
+
+.button-list {
+  display: grid;
+  grid-template-columns: 1fr;
+  gap: 8px;
+}
+
+.report-btn {
+  width: 100%;
+  min-height: 42px;
+  margin: 0;
+  padding: 8px 10px;
+  margin-left: 0 !important;
+}
+
+.report-btn .btn-content {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  width: 100%;
+  text-align: left;
+}
+
+.report-btn .btn-name {
+  font-size: 13px;
+  line-height: 1.1;
+  padding-right: 8px;
+}
+
+.report-btn .btn-id {
+  margin-left: 0;
+  opacity: 0.8;
+  font-size: 12px;
+  min-width: 34px;
+  text-align: right;
+}
+
+.report-btn.is-active {
+  border-color: #409eff;
+  background-color: #ecf5ff;
+}
+
+.stop-btn :deep(span) {
+  justify-content: center;
+}
+
+.status-text {
+  margin: 10px 0 0;
+  color: #606266;
+  font-size: 12px;
+}
+
+.report-result {
+  margin-top: 20px;
+}
+
+.report-result pre {
+  background: #f5f7fa;
+  padding: 12px;
+  border-radius: 6px;
+  overflow-x: auto;
+  font-size: 12px;
+  line-height: 1.5;
+}
+
+@media (min-width: 640px) {
+  .report-page {
+    padding: 20px;
+  }
+
+  .button-list {
+    grid-template-columns: repeat(2, minmax(0, 1fr));
+    gap: 10px;
+  }
+
+  .report-btn {
+    min-height: 40px;
+    padding: 7px 10px;
+  }
+}
+</style>

+ 145 - 0
src/views/Report/tagCoordinateList.json

@@ -0,0 +1,145 @@
+[
+  {
+    "id": 1,
+    "name": "二楼电梯口",
+    "locationDesc": "二楼电梯口",
+    "tagNo": "0C2105777700000022015F00",
+    "pos": {
+      "x": 17.55922624158694,
+      "y": -0.070636670561876,
+      "z": 1.4465
+    }
+  },
+  {
+    "id": 2,
+    "name": "供应链",
+    "locationDesc": "碧兰座位",
+    "tagNo": "E28011B0A50500768C9628AB",
+    "pos": {
+      "x": 15.41374989638694,
+      "y": 6.680792536895755,
+      "z": 1.1792
+    }
+  },
+  {
+    "id": 3,
+    "name": "入口走廊",
+    "locationDesc": "生产间和会议室中间",
+    "tagNo": "E28011B0A50500768C96289B",
+    "pos": {
+      "x": 11.120055278274682,
+      "y": -0.22127844330303995,
+      "z": 1.5889
+    }
+  },
+  {
+    "id": 4,
+    "name": "生产间",
+    "locationDesc": "生产间",
+    "tagNo": "E28011B0A50500768C9602FB",
+    "pos": {
+      "x": 11.212734225075176,
+      "y": -4.318222351176363,
+      "z": 1.5946
+    }
+  },
+  {
+    "id": 5,
+    "name": "二楼会议室",
+    "locationDesc": "二楼会议室",
+    "tagNo": "E28011B0A50500768C96288B",
+    "pos": {
+      "x": 9.064077095867487,
+      "y": 3.2887987760751094,
+      "z": 1.3429
+    }
+  },
+  {
+    "id": 6,
+    "name": "二楼生产部标定区",
+    "locationDesc": "王灏宇座位",
+    "tagNo": "E28011B0A50500768C96287B",
+    "pos": {
+      "x": 4.993024468492701,
+      "y": 1.4946738731602902,
+      "z": 1.5364
+    }
+  },
+  {
+    "id": 7,
+    "name": "硬件部",
+    "locationDesc": "张慧博座位",
+    "tagNo": "E28011B0A50500768C96286B",
+    "pos": {
+      "x": -0.8586087211942526,
+      "y": 0.6235740583771266,
+      "z": 1.5423
+    }
+  },
+  {
+    "id": 8,
+    "name": "测试部",
+    "locationDesc": "朱海华座位",
+    "tagNo": "E28011B0A50500768C96285B",
+    "pos": {
+      "x": -0.737473591282138,
+      "y": -6.57596525940062,
+      "z": 1.6142
+    }
+  },
+  {
+    "id": 9,
+    "name": "技术研发部",
+    "locationDesc": "钟汉明座位",
+    "tagNo": "E28011B0A50500768C96283B",
+    "pos": {
+      "x": -6.851451898324801,
+      "y": 1.8587779405564784,
+      "z": 1.527
+    }
+  },
+  {
+    "id": 10,
+    "name": "测试部2",
+    "locationDesc": "赖学荣座位",
+    "tagNo": "E28011B0A50500768C96284B",
+    "pos": {
+      "x": -6.693255923285772,
+      "y": -4.738682386752513,
+      "z": 1.6093
+    }
+  },
+  {
+    "id": 11,
+    "name": "APP",
+    "locationDesc": "刘敏座位",
+    "tagNo": "E28011B0A50500768C96282B",
+    "pos": {
+      "x": -12.848009364926108,
+      "y": 1.7548362165470666,
+      "z": 1.5243
+    }
+  },
+  {
+    "id": 12,
+    "name": "算法部",
+    "locationDesc": "谷庆座位",
+    "tagNo": "E28011B0A50500768C96281B",
+    "pos": {
+      "x": -12.720718258490592,
+      "y": -5.265756389811795,
+      "z": 1.5949
+    }
+  },
+  {
+    "id": 13,
+    "name": "开发部",
+    "locationDesc": "马瑞座位",
+    "tagNo": "E28011B0A50500768C96280B",
+    "pos": {
+      "x": -18.875211031796464,
+      "y": 3.088940566764247,
+      "z": 1.4797
+    }
+  }
+]

+ 14 - 2
vue.config.js

@@ -1,3 +1,15 @@
 module.exports = {
-  publicPath: './'
-}
+  publicPath: "./",
+  devServer: {
+    headers: {
+      "Cache-Control": "no-store",
+    },
+    https: false,
+    proxy: {
+      "ingest": {
+        target: "http://192.168.0.17:8080",
+        changeOrigin: true,
+      },
+    },
+  },
+};

+ 12 - 0
yarn.lock

@@ -1469,6 +1469,11 @@
   optionalDependencies:
     prettier "^1.18.2 || ^2.0.0"
 
+"@vue/devtools-api@^6.0.0":
+  version "6.6.4"
+  resolved "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz#cbe97fe0162b365edc1dba80e173f90492535343"
+  integrity sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==
+
 "@vue/preload-webpack-plugin@^1.1.0":
   version "1.1.2"
   resolved "https://registry.npm.taobao.org/@vue/preload-webpack-plugin/download/@vue/preload-webpack-plugin-1.1.2.tgz"
@@ -8668,6 +8673,13 @@ vue-loader@^15.9.2:
     vue-hot-reload-api "^2.3.0"
     vue-style-loader "^4.1.0"
 
+vue-router@4.0.16:
+  version "4.0.16"
+  resolved "https://registry.npmmirror.com/vue-router/-/vue-router-4.0.16.tgz#9477beeeef36e80e04d041a1738801a55e6e862e"
+  integrity sha512-JcO7cb8QJLBWE+DfxGUL3xUDOae/8nhM1KVdnudadTAORbuxIC/xAydC5Zr/VLHUDQi1ppuTF5/rjBGzgzrJNA==
+  dependencies:
+    "@vue/devtools-api" "^6.0.0"
+
 vue-style-loader@^4.1.0, vue-style-loader@^4.1.2:
   version "4.1.3"
   resolved "https://registry.npmmirror.com/vue-style-loader/download/vue-style-loader-4.1.3.tgz"