Browse Source

feat:更换背景图, 修改单位, 集成three

sunxiao 8 months ago
parent
commit
50e933195f

+ 15 - 0
package-lock.json

@@ -24,6 +24,8 @@
         "pinia-plugin-persistedstate": "^3.2.1",
         "sass": "^1.77.1",
         "sass-loader": "^14.2.1",
+        "three": "^0.166.1",
+        "three-obj-mtl-loader": "^1.0.3",
         "vue": "^3.4.21",
         "vue-router": "^4.3.0"
       },
@@ -7299,6 +7301,19 @@
         "node": ">=0.8"
       }
     },
+    "node_modules/three": {
+      "version": "0.166.1",
+      "resolved": "https://registry.npmmirror.com/three/-/three-0.166.1.tgz",
+      "integrity": "sha512-LtuafkKHHzm61AQA1be2MAYIw1IjmhOUxhBa0prrLpEMWbV7ijvxCRHjSgHPGp2493wLBzwKV46tA9nivLEgKg=="
+    },
+    "node_modules/three-obj-mtl-loader": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/three-obj-mtl-loader/-/three-obj-mtl-loader-1.0.3.tgz",
+      "integrity": "sha512-0z7BfyG6vYPY9RvxJvL4rq8PbNrF42Kn4zxeqTfeDzJN++2oKbtCQhxHs5vLULnDuCRTEyDFf5TYvO+1vnJ7KQ==",
+      "peerDependencies": {
+        "three": ">= 0.91"
+      }
+    },
     "node_modules/to-fast-properties": {
       "version": "2.0.0",
       "resolved": "https://registry.npmmirror.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz",

+ 2 - 0
package.json

@@ -31,6 +31,8 @@
     "pinia-plugin-persistedstate": "^3.2.1",
     "sass": "^1.77.1",
     "sass-loader": "^14.2.1",
+    "three": "^0.166.1",
+    "three-obj-mtl-loader": "^1.0.3",
     "vue": "^3.4.21",
     "vue-router": "^4.3.0"
   },

BIN
src/assets/images/home/home_bg.png


BIN
src/assets/images/home/home_bg2.png


+ 1 - 1
src/components/RecodeSquareCardItem/index.vue

@@ -72,7 +72,7 @@ const dataSources = computed(() => {
   if (item.type == 1) {
     return [
       { label: '报警时间', value: item.time },
-      { label: '报警值', value: Number(item?.warningVal?.toFixed(2)), type: 'wraning', unit: 'mg/L' },
+      { label: '报警值', value: item.warningValStr, type: 'wraning' },
       { label: '报警次数', value: item.counts },
     ]
   }

+ 8 - 0
src/router/index.js

@@ -9,6 +9,14 @@ const constantRouterMap = [
       title: "智慧总控"
     }
   },
+  // {
+  //   path: '/test',
+  //   name: 'TempTest',
+  //   component: () => import('@/views/test/index.vue'),
+  //   meta: {
+  //     title: "测试建模文件"
+  //   }
+  // },
   {
     path: '/count1',
     name: 'count1',

+ 3 - 5
src/utils/format.js

@@ -1,7 +1,7 @@
 import { ORDER_OPTION_ENUM } from "./enum";
 
 
-export const formatToData = (dataSource, warnKey) => {
+export const formatToData = (dataSource, warnKey, isNoUnit) => {
   const reuslt = {
     title: dataSource?.title,
     list: []
@@ -9,7 +9,7 @@ export const formatToData = (dataSource, warnKey) => {
   delete dataSource.title;
   reuslt.list = Object.entries(dataSource).map(([key, value]) => {
     if ( Number.isFinite(value) ) value = Number(value.toFixed(2));
-    if ( key.includes("值") ) value = value? value + 'mg/L' : '';
+    if ( key.includes("值") && !isNoUnit) value = value? value + 'mg/L' : '';
     return { label: key, value, isWarning: warnKey === key };
   });
   return reuslt;
@@ -66,8 +66,6 @@ export const colorToRgba = (color, alpha) => {
   return `rgba(${r}, ${g}, ${b}, ${alpha})`
 }
 
-
-// 判断是不是数字
 export const isNumberComprehensive = (value) => {
   return isFinite(value) && !isNaN(parseFloat(value));
-}
+}

+ 24 - 13
src/utils/tools.ts → src/utils/tools.js

@@ -1,12 +1,9 @@
 const baseUrl = import.meta.env.VITE_BASE_URL;
 const basePrefix = import.meta.env.VITE_BASE_PREFIX;
 import { screenApi } from "@/api/screen"
-interface IUrlParams {
-  [propsName: string]: any
-}
 
 /** 统一 - get和post请求书写方式 */
-export function tansParams(params: any): string {
+export function tansParams(params) {
   let result = ''
   for (const propName of Object.keys(params)) {
     const value = params[propName];
@@ -30,14 +27,14 @@ export function tansParams(params: any): string {
 
 /** localhost - methods */
 export class LocalCache {
-  static setCath(key: string, value: any) {
+  static setCath(key, value) {
     window.localStorage.setItem(key, JSON.stringify(value));
   }
-  static getCache(key: string) {
+  static getCache(key) {
     const value = window.localStorage.getItem(key);
     return value ? JSON.parse(value) : {};
   }
-  static deleteCatch(key: string) {
+  static deleteCatch(key) {
     window.localStorage.removeItem(key);
   }
   static clearCache() {
@@ -50,7 +47,7 @@ export const getPreviewPath = (fileObjectKey = '') => {
   return baseUrl + basePrefix + "/auth/t/queryFiles?fileName=" + new Date().getTime() + ".pdf&fileObjectKey=" + fileObjectKey;
 }
 
-export const getQueryParamsAsObject = (url?: string) => {
+export const getQueryParamsAsObject = (url) => {
   url = url || window.location.href;
 
   const queryString = url.split('?')[1];
@@ -61,7 +58,7 @@ export const getQueryParamsAsObject = (url?: string) => {
 
   const queryParams = queryString.split('&');
 
-  const paramsObj:IUrlParams = {};
+  const paramsObj = {};
 
   queryParams.forEach(function(param) {
     const parts = param.split('=');
@@ -77,10 +74,10 @@ export const getQueryParamsAsObject = (url?: string) => {
  * 复制文本
 * @param options
  */
-export function copyText(options: { text: string; origin?: boolean }) {
+export function copyText(options) {
   const props = { origin: true, ...options }
 
-  let input: HTMLInputElement | HTMLTextAreaElement
+  let input;
 
   if (props.origin) {
     input = document.createElement('textarea')
@@ -97,7 +94,7 @@ export function copyText(options: { text: string; origin?: boolean }) {
 }
 
 
-export const upLoadImageFun = async (targe:any) => {
+export const upLoadImageFun = async (targe) => {
   const file = targe.files[0]; // 获取上传的文件
   const allowedTypes = [
     "image/png",
@@ -130,4 +127,18 @@ export const upLoadImageFun = async (targe:any) => {
   } catch (error) {
     return "";
   }
-};
+};
+
+// 简易版防抖
+export const debounce = (func, wait) => {
+  let timeout = null;
+
+  return function() {
+    const context = this;
+    const args = arguments;
+    clearTimeout(timeout);
+    timeout = setTimeout(function() {
+      func.apply(context, args);
+    }, wait);
+  };
+}

+ 1 - 1
src/views/analyse/PymolView.vue

@@ -42,7 +42,7 @@ const handleOpenContent = async ({ id, reason:title }) => {
   answerResult.value = data.answer;
 
   basic.title = title
-  textDataSources.value = formatToData(basic, '报警值');
+  textDataSources.value = formatToData(basic, '报警值', true);
 
   jsTableData.value = [jsData];
   csTableData.value = [csData];

File diff suppressed because it is too large
+ 97282 - 0
src/views/test/factory.obj


+ 71 - 0
src/views/test/index.vue

@@ -0,0 +1,71 @@
+<script setup>
+import { ref, onMounted, onUnmounted } from 'vue';
+import * as THREE from 'three';
+import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader'
+import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
+import motor3d from './renderModel';
+
+
+
+onMounted(() => {
+  new motor3d('#scene') 
+
+//   const scene = new THREE.Scene();
+
+//   const fov = 75;
+//   const aspect = 2;  // 相机默认值
+//   const near = 0.1;
+//   const far = 5;
+
+//   const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 201, 2000);
+
+//   // camera.up.set(0, 0, 1);
+//   // camera.lookAt(0, 1000, 0);
+
+//   const renderer = new THREE.WebGLRenderer();
+//   renderer.setSize(window.innerWidth, window.innerHeight);
+//   document.getElementById('three').appendChild(renderer.domElement);
+
+//   const loader = new OBJLoader();
+//   loader.load('factor.obj', (object) => {
+//     console.log(object);
+//     // 这里可以对加载进来的模型做一些处理,比如旋转、缩放等
+//     scene.add(object);
+//   });
+
+
+//   const ambientLight = new THREE.AmbientLight(0x404040); // soft white light
+// scene.add(ambientLight);
+
+// const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
+// directionalLight.position.set(1, 1, 1);
+// scene.add(directionalLight);
+//   // camera.position.z = 2;
+
+//   const controls = new OrbitControls(camera, renderer.domElement);
+//   controls.enableDamping = true;
+
+//   function animate() {
+//     requestAnimationFrame(animate);
+//     renderer.render(scene, camera);
+//     controls.update();
+//   }
+
+//   animate();
+
+})
+
+</script>
+
+
+
+<template>
+  <div id="scene">    
+  </div>
+  <!-- <div id="three"></div> -->
+  <!-- <section id="model" class="w-[600vw] h-[600vh]">
+
+  </section> -->
+</template>
+
+<style lang="scss" scoped></style>

+ 111 - 0
src/views/test/renderModel.js

@@ -0,0 +1,111 @@
+import * as THREE from 'three'//导入three.js核心库
+import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls' //导入轨道控制器
+import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader'
+import { debounce } from '@/utils/tools';
+
+class motor3d {
+  constructor(selector) {
+    this.container = document.querySelector(selector)
+    this.scene
+    this.camera
+    this.renderer
+    this.controls
+    this.init()
+    this.animate()
+  }
+
+  init() {
+    // 初始化场景
+    this.initScene()
+    // 初始化辅助轴
+    this.initAxesHelper()
+    // 初始化灯光
+    this.initLight()
+    // 初始化Mesh
+    this.initMesh()
+    // 初始化相机
+    this.initCamera()
+    // 初始化渲染器
+    this.initRender()
+    // 初始化轨道控制器
+    this.initControls()
+    // 监听场景大小改变,重新渲染尺寸
+    window.addEventListener('resize', this.onWindowResize.bind(this))
+  }
+
+  initScene() {
+    this.scene = new THREE.Scene()
+    // this.scene.background = new THREE.Color(0xa0a0a0)
+    this.scene.background = null;
+  }
+
+  initAxesHelper() {
+    const axesHelper = new THREE.AxesHelper(5)
+    this.scene.add(axesHelper)
+  }
+
+  initLight() {
+    const hesLight = new THREE.HemisphereLight(0xffffff, 0x333333)
+    hesLight.intensity = 0.6
+    this.scene.add(hesLight)
+
+    const dirLight = new THREE.DirectionalLight()
+    dirLight.position.set(1, 1, 1)
+    this.scene.add(dirLight)
+  }
+  recordCameraChanges () {
+    // 记录位置
+    const position = this.camera.position;
+    console.log(`Position: (${position.x}, ${position.y}, ${position.z})`);
+  };
+  initMesh() {
+    this.addOBJFModel('motor03.gltf')
+  }
+  initCamera() {
+    this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 100)
+    // this.camera.position.set(3.5, 5.5, 1.5)
+    // this.camera.position.set(28.07, 22.32, -12.92)
+    this.camera.position.set(37.3642, 24.8315, -22.6927)
+  }
+
+  initRender() {
+    this.renderer = new THREE.WebGLRenderer({ antialias: true,  alpha: true })//设置抗锯齿
+    //设置屏幕像素比
+    this.renderer.setPixelRatio(window.devicePixelRatio)
+    //渲染的尺寸大小
+    this.renderer.setSize(window.innerWidth, window.innerHeight)
+    // 添加到容器
+    this.container.appendChild(this.renderer.domElement)
+    // 设置清除颜色的 Alpha 为 0
+    this.renderer.setClearColor(0xffffff, 0)
+  }
+
+  animate() {
+    this.renderer.setAnimationLoop(this.render.bind(this))
+  }
+  render() {
+    this.renderer.render(this.scene, this.camera)
+  }
+  initControls() {
+    this.controls = new OrbitControls(this.camera, this.renderer.domElement)
+  }
+  // 加载模型
+  addOBJFModel(modelName) {
+    return new Promise((resolve, reject) => {
+      const loader = new OBJLoader()
+      loader.load('./factory.obj', (obj) => {
+        console.log(obj);
+        this.scene.add(obj)
+        resolve(this.modelName + '模型添加成功')
+      })
+    })
+  }
+
+  onWindowResize() {
+    this.recordCameraChanges();
+    this.camera.aspect = window.innerWidth / window.innerHeight
+    this.camera.updateProjectionMatrix()//更新矩阵,将3d内容投射到2d画面上转换
+    this.renderer.setSize(window.innerWidth, window.innerHeight)
+  }
+}
+export default motor3d

+ 0 - 19
xxx.md

@@ -1,19 +0,0 @@
-### 解决方案
-1. **紧急响应与预案启动**
-   - 当出水总磷指标超过管控值时,应立即进行水质复测确认。   - 若确认超标且超过标准值,则立即启动应急预案,并向行业主管部门报备。2. **加强水质监测与数据分析**
-   - 建议增加水质监测频次,特别是针对总磷指标的实时监测。   - 对历史数据进行深入分析,找出总磷超标的原因和规律。3. **优化除磷工艺**
-   - 调整除磷药剂的投加量,由原先的0.56提升至0.74,以提高除磷效率。   - 对除磷药剂投加点位进行优化,确保药剂与污水的充分混合。4. **工艺调整与优化**
-   - 针对AAO+MBBR工艺,优化生化系统的运行,特别是厌氧段、缺氧段和好氧段的运行参数。   - 调整多点进水和回流分配,提高厌氧释磷的底物浓度和反应速率。5. **污泥管理与处置**
-   - 增加干污泥的排放量,由当前的13.15调整至22.8,以降低污泥龄,提高磷的去除率。   - 定期检查污泥的性质,确保污泥的活性。6. **溶解氧与污泥浓度的控制**
-   - 调整好氧池1的溶解氧,由2.83降至2.80,以保持适宜的微生物活性。   - 好氧池2的溶解氧建议大幅调整至20.00,以促进有机物的降解和磷的吸收。(注:此值较高,需根据实际情况和工艺要求进行验证)
-   - 调整生化池的污泥浓度,池1由5342.00mg/L降至4746.00mg/L,池2由5827.00mg/L降至5375.00mg/L,以优化污泥的活性。### 解决策略表格
-| 指标项 | 当前值 | 建议调整值 | 是否要调整 | 调整说明 | 如何调整 |
-| --- | --- | --- | --- | --- | --- |
-| 进水水量 | 3619.0 | 3619.0 | 否 | 保持稳定 | 无需调整 || 除磷药剂投加量 | 0.56 | 0.74 | 是 | 提高除磷效率 | 增加药剂投加泵的频率或时间 |
-| 干污泥量 | 13.15 | 22.8 | 是 | 降低污泥龄,提高磷去除率 | 增加污泥排放频次或量 |
-| 好氧池1溶解氧 | 2.83 | 2.80 | 是 | 保持微生物活性 | 调整曝气装置的运行参数 |
-| 好氧池2溶解氧 | 2.46 | 20.00 | 是 | 促进有机物降解和磷吸收 | 大幅增加曝气量,需验证和调整 |
-| 池1生化池污泥浓度(MLSS) | 5342.00mg/L | 4746.00mg/L | 是 | 优化污泥活性 | 调整污泥回流和排放比例 |
-| 池2生化池污泥浓度(MLSS) | 5827.00mg/L | 5375.00mg/L | 是 | 优化污泥活性 | 调整污泥回流和排放比例 |
-### 总结概述
-针对污水处理厂出水总磷超标的问题,我们提出了一系列综合解决方案。

Some files were not shown because too many files changed in this diff