Commit 146086eb authored by 李苏's avatar 李苏 💬

zghywpc-vue项目,设备信息 设备流向 设备类型 机组编码

parent 15e7373a
export const ORIGIN_POINT = [118.00, 36.76]
import * as THREE from 'three'
import { clone } from 'three/examples/jsm/utils/SkeletonUtils'
export default class DsModel {
constructor(model, viewer) {
this.viewer = viewer
this.model = model
this.object = model.scene || model
this.clock = new THREE.Clock()
this.animalIndex = -1
}
/**
* 获取模型大小和位置
* @returns
*/
getBox() {
this.object.updateMatrixWorld() // 更新模型的世界矩阵
const box = new THREE.Box3().setFromObject(this.object) // 获取模型的包围盒
return box
}
/**
* 设置模型到原点位置
*/
setCenter() {
const box = this.getBox()
const center = box.getCenter(new THREE.Vector3)
this.object.position.x += this.object.position.x - center.x
this.object.position.y += this.object.position.y - center.y
this.object.position.z += this.object.position.z - center.z
}
/**
* 设置模型比例
* @param x 可以只填写一个参数
* @param y 纵轴缩放
* @param z 横轴缩放
*/
setScale(x, y, z) {
this.object.scale.set(x, y || x, z || x)
}
/**
* 求模型的长宽高
* @returns
*/
getLenth() {
const box = this.getBox()
return box.getSize(new THREE.Vector3())
}
/**
* 设置模型缩放
* @param x x横轴旋转
* @param y 纵轴旋转
* @param z z横轴旋转
*/
setRotation(x, y, z) {
if (x) this.object.rotation.x = x
if (y) this.object.rotation.y = y
if (z) this.object.rotation.z = z
}
/**
* 设置模型位置
* @param x x坐标
* @param y y坐标
* @param z z坐标
* @param isRotation 是否根据传入坐标进行模型旋转
*/
setPosition([x, y, z], isRotation = false) {
if (isRotation) {
const zValue = z - this.model.position.z
const xValue = x - this.model.position.x
const angle = Math.atan2(zValue, xValue)
// TODO: 有问题
this.object.rotation.y = this.rotationY - angle
}
this.object.position.set(x, y, z)
}
/**
* 克隆模型
* @param x
* @param y
* @param z
* @returns {*}
*/
cloneModel([x, y, z] = [0, 0, 0]) {
const newScene = { ...this.model }
const newModel = clone(this.object)
newModel.position.set(x, y, z)
this.viewer.scene.add(newModel)
newScene.scene = newModel
return new DsModel(newScene, this.viewer)
}
/**
* 设置模型动画
* @param {*} i 选择模型动画进行播放
* @returns
*/
startAnimal(i = 0) {
this.animalIndex = i
if (!this.mixer) {
this.mixer = new THREE.AnimationMixer(this.object) // 创建动画混合器
}
if (this.model.animations.length < 1) {
return
}
this.mixer.clipAction(this.model.animations[i]).play() // 播放动画
this.animalObject = {
fun: this.#updateAnimal,
content: this
}
this.viewer.addAnimate(this.animalObject) // 添加动画监听
}
/**
* 停止动画
* @returns
*/
stopAnimal() {
if (this.model.animations.length < 1) return
if (!this.mixer || !this.mixer.clipAction) return
this.mixer.clipAction(this.model.animations[this.animaIndex]).stop()
if (this.animaObject) this.viewer.removeAnimate(this.animaObject)
}
/**
* 更新动画混合器
* @param {*} e
*/
#updateAnimal(e) {
e.mixer.update(e.clock.getDelta()) // 更新动画混合器
}
/**
* 开启模型阴影 数组中移除阴影
*/
openCastShadow(names = []) {
this.model.scene.traverse(mesh => {
if (mesh.type === 'Mesh' && names.indexOf(mesh.name) === -1) {
mesh.frustumCulled = false // 不剔除
mesh.material.side = THREE.DoubleSide // 双面显示
mesh.castShadow = true // 阴影
}
})
}
/**
* 接收阴影
* @param names 数组中的可以接收阴影
*/
openReceiveShadow(names = []) {
this.model.scene.traverse(mesh => {
if (names.length === 0 || names.indexOf(mesh.name) !== -1) {
mesh.receiveShadow = true
}
})
}
/**
* 获取模型集合
* @param callback 返回模型集合
*/
forEach(callback) {
const temp = []
this.model.scene.traverse(mesh => {
if (mesh.isMesh) {
temp.push(mesh)
}
})
// 避免数据冲突
temp.forEach(item => {
callback?.(item)
})
}
/**
* 关闭模型阴影
*/
closeShadow() {
this.model.scene.traverse(mesh => {
mesh.castShadow = false
mesh.receiveShadow = false
})
}
/**
* 设置模型炫酷 模式
* @param option 颜色和透明度 颜色需要使用)0x 后面16进制颜色
*/
setColorCool(color = 'rgb(255,255,255)', opacity = 0.05) {
if (!this.isSaveMaterial) {
this.materials = []
}
this.model.scene.traverse(model => {
if (model.isMesh) {
if (this.isSaveMaterial) {
this.materials.push(model.material)
}
model.material = new THREE.MeshBasicMaterial({
side: THREE.DoubleSide, // 双面显示
transparent: true,
depthWrite: true, // 渲染此材质是否对深度缓冲区有任何影响
depthTest: false, // 是否在渲染此材质时启用深度测试
color: new THREE.Color(color),
opacity
})
}
})
this.isSaveMaterial = true
}
}
import { InteractiveGroup } from "three/examples/jsm/interactive/InteractiveGroup"
import { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer'
export default class Labels {
constructor(viewer) {
this.viewer = viewer
this.group = new InteractiveGroup(this.viewer.renderer, this.viewer.camera) // 创建交互对象
this.viewer.scene.add(this.group)
}
/**
* 添加2d标签
* @param {*} position
* @param {*} html html内容
*/
addCss2dLabel(position = { x: 0, y: 0, z: 0 }, html = "") {
const div = document.createElement('div')
div.style.position = 'absolute'
div.innerHTML = html
this.label = new CSS2DObject(div)
this.label.position.set(position.x, position.y, position.z)
this.viewer.scene.add(this.label)
return this.label
}
}
import * as THREE from 'three'
/**
* 灯光基类
*/
export default class AmbientLight {
/**
* 灯光基类
*/
constructor(_viewer, option = { color: 'rgb(255,255,255)' }) {
this.viewer = _viewer
this.light = new THREE.AmbientLight(0x404040) // soft white light
this.setOption(option)
this.viewer.scene.add(this.light)
}
/**
* 设置灯光参数
* @param option
*/
setOption(option = {}) {
this.light.intensity = option.intensity || 1 // 光线强度
}
}
import * as THREE from 'three'
/**
* 灯光基类
*/
export default class DirectionalLight {
/**
* 灯光基类
*/
constructor (_viewer, position = [200, 200, 200], option = { color: 'rgb(255,255,255)' }) {
this.viewer = _viewer
this.light = new THREE.DirectionalLight(new THREE.Color(option.color))
this.setPosition(position)
this.setOption(option)
this.viewer.scene.add(this.light)
}
/**
* 设置灯光参数
* @param option
*/
setOption (option = {}) {
const light = this.light
light.intensity = option.intensity || 2 // 光线强度
light.castShadow = option.castShadow || true // 是否有阴影
light.shadow.mapSize.width = option.mapSize || 2048 // 阴影像素
light.shadow.mapSize.height = option.mapSize || 2048
// 阴影范围
const d = 80
light.shadow.camera.left = -d
light.shadow.camera.right = d
light.shadow.camera.top = d
light.shadow.camera.bottom = -d
light.shadow.bias = -0.0005 // 解决条纹阴影的出现
// 最大可视距和最小可视距
light.shadow.camera.near = 0.01
light.shadow.camera.far = 2000
}
/**
* 设置灯光位置
* @param x
* @param y
* @param z
*/
setPosition ([x, y, z]) {
if (this.light) this.light.position.set(x || 0, y || 0, z || 0)
}
}
/**
* 灯光基类
*/
export default class Light {
/**
* 灯光基类
*/
constructor(_viewer) {
this.viewer = _viewer
this.light = {}
}
/**
* 设置灯光位置
* @param x
* @param y
* @param z
*/
setPosition([x, y, z]) {
if (this.light) this.light.position.set(x, y, z)
}
}
import * as THREE from 'three'
/**
* 灯光基类
*/
export default class PointLight {
/**
* 灯光基类
*/
constructor (_viewer, position = [0, 40, 0], option = { color: 'rgb(255,255,255)' }) {
this.viewer = _viewer
const color = new THREE.Color(option.color)
this.light = new THREE.PointLight(color)
this.light.castShadow = true
this.mesh = new THREE.Mesh(new THREE.SphereGeometry(1, 10, 10), new THREE.MeshBasicMaterial({ color: color }))
this.light.add(this.mesh)
this.viewer.scene.add(this.light)
this.setOption(option)
this.setPosition(position)
}
/**
* 设置灯光参数
* @param option
*/
setOption (option = {}) {
this.light.intensity = option.intensity || 20 // 光线强度
this.light.distance = option.distance || 200 // 光线距离
this.light.decay = option.decay || 1 // 光的衰减指数
}
/**
* 设置灯光位置
* @param x
* @param y
* @param z
*/
setPosition ([x, y, z]) {
if (this.light) this.light.position.set(x || 0, y || 0, z || 0)
}
}
import * as THREE from 'three'
/**
* 灯光基类
*/
export default class RectAreaLight {
/**
* 灯光基类
*/
constructor (_viewer, position = [0, 40, 0], option = { color: 'rgb(255,255,255)' }) {
this.viewer = _viewer
const color = new THREE.Color(option.color)
// 创建区域光 颜色ffffff,强度:5,宽:2,高:6
this.light = new THREE.RectAreaLight(color, option.intensity || 20, option.width || 10, option.height || 10)
this.geometry = new THREE.PlaneGeometry(option.width || 10, option.height || 10)
this.mesh = new THREE.Mesh(this.geometry, new THREE.MeshBasicMaterial({
side: THREE.DoubleSide,
color: color
}))
this.light.add(this.mesh)
this.light.rotation.x = Math.PI // 绕轴旋转
this.viewer.scene.add(this.light)
this.setPosition(position)
}
/**
* 设置灯光参数
* @param option
*/
setOption (option = {}) {
this.light.intensity = option.intensity || 20 // 光线强度
this.light.ambient = option.ambient || 1 // 光线强度
this.light.width = option.width || 10 // 光的衰减指数
this.light.height = option.height || 10 // 光的衰减指数
}
/**
* 设置灯光位置
* @param x
* @param y
* @param z
*/
setPosition ([x, y, z]) {
if (this.light) this.light.position.set(x || 0, y || 0, z || 0)
}
}
import * as THREE from 'three'
/**
* 灯光基类
*/
export default class SpotLight {
/**
* 灯光基类
*/
constructor (_viewer, position = [0, 40, 0], option = { color: 'rgb(255,255,255)' }) {
this.viewer = _viewer
const color = new THREE.Color(option.color)
this.light = new THREE.SpotLight(color)
this.light.castShadow = true
this.mesh = new THREE.Mesh(new THREE.SphereGeometry(1, 10, 10), new THREE.MeshBasicMaterial({ color: color }))
this.light.add(this.mesh)
this.viewer.scene.add(this.light)
this.setOption(option)
this.setPosition(position)
}
/**
* 设置灯光参数
* @param option
*/
setOption (option = {}) {
this.light.intensity = option.intensity || 20 // 光线强度
this.light.angle = option.angle || 1 // 光线强度
this.light.distance = option.distance || 200 // 光线距离
this.light.decay = option.decay || 1 // 光的衰减指数
this.light.castShadow = true
this.light.shadow.mapSize.width = 1024
this.light.shadow.mapSize.height = 1024
this.light.shadow.camera.near = 0.1
this.light.shadow.camera.far = 4000
this.light.shadow.camera.fov = 30
}
/**
* 设置灯光位置
* @param x
* @param y
* @param z
*/
setPosition ([x, y, z]) {
if (this.light) this.light.position.set(x || 0, y || 0, z || 0)
}
}
import { Lensflare, LensflareElement } from 'three/examples/jsm/objects/Lensflare.js'
import * as THREE from 'three'
export default class SunLensflare {
/**
* 太阳炫光
* @param _viewer 视图
*/
constructor (_viewer) {
this.scene = _viewer.scene
// lensflares
const textureLoader = new THREE.TextureLoader()
this.textureFlare0 = textureLoader.load('resources/lensflare/lensflare0.png')
this.textureFlare3 = textureLoader.load('resources/lensflare/lensflare3.png')
}
/**
* 添加炫光
* @param x
* @param y
* @param z
*/
addToScene (x = 200, y = 200, z = 200) {
this.light = new THREE.PointLight(0xffffff, 0, 0)
this.light.color.setHSL(0.995, 0.5, 0.9)
this.light.position.set(x, y, z)
this.scene.add(this.light)
// 构建炫光
const lensflare = new Lensflare()
lensflare.addElement(new LensflareElement(this.textureFlare0, 700, 0, this.light.color))
lensflare.addElement(new LensflareElement(this.textureFlare3, 60, 0.6))
lensflare.addElement(new LensflareElement(this.textureFlare3, 70, 0.7))
lensflare.addElement(new LensflareElement(this.textureFlare3, 120, 0.9))
lensflare.addElement(new LensflareElement(this.textureFlare3, 70, 1))
this.light.add(lensflare)
}
/**
* 设置炫光位置角度
* @param x
* @param y
* @param z
*/
setPosition (x = 200, y = 200, z = 200) {
if (this.light) this.light.position.set()
}
}
import SunLensflare from './SunLensflare.js'
import DirectionalLight from './DirectionalLight.js'
import AmbientLight from './AmbientLight.js'
import PointLight from './PointLight.js'
import SpotLight from './SpotLight.js'
import RectAreaLight from './RectAreaLight.js'
export default class Lights {
constructor(viewer) {
this.viewer = viewer
this.lightList = []
}
/**
* 添加平行光源
* @param option
*/
addDirectionalLight(position = [200, 200, 200], option = { color: 'rgb(255,255,255)' }) {
const directionalLight = new DirectionalLight(this.viewer, position, option)
this.lightList.push(directionalLight)
return directionalLight
}
/**
* 添加环境光源
*/
addAmbientLight() {
const ambientLight = new AmbientLight(this.viewer)
this.lightList.push(ambientLight)
return ambientLight
}
/**
* 添加点状光源
* @param option
*/
addPointLight(position = [0, 40, 0], option = { color: 'rgb(255,255,255)' }) {
const pointLight = new PointLight(this.viewer, position, option)
this.lightList.push(pointLight)
return pointLight
}
/**
* 添加锥形光源
* @param option
*/
addSpotLight(position = [0, 40, 0], option = { color: 'rgb(255,255,255)' }) {
const pointLight = new SpotLight(this.viewer, position, option)
this.lightList.push(pointLight)
return pointLight
}
/**
* 添加矩形光源
* @param option
*/
addRectAreaLight(position = [0, 40, 0], option = { color: 'rgb(255,255,255)' }) {
const rectAreaLight = new RectAreaLight(this.viewer, position, option)
this.lightList.push(rectAreaLight)
return rectAreaLight
}
/**
* 添加炫光
* @param x
* @param y
* @param z
*/
addSunLensflare(x = 200, y = 200, z = 200) {
this.sunLensflare = new SunLensflare(this.viewer)
this.sunLensflare.addToScene(x, y, z)
}
/**
* 移除灯光
* @param light 灯光
*/
removeLight(light) {
this.viewer.scene.remove(light)
}
}
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader'
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader'
import DsModel from './DsModel'
/**
* 模型加载类(只能加载GLTF及GLB格式)
*/
export default class ModelLoader {
constructor(viewer,LoadingManager) {
this.viewer = viewer
this.scene = viewer.scene
/* 创建管理器*/
this.loaderGLTF = new GLTFLoader() // 加载gltf模型
this.loaderFBX = new FBXLoader(LoadingManager) // 加载fbx模型
this.dracoLoader = new DRACOLoader() // 加载draco模型(加载基于Google Draco压缩格式的3D模型的类)
this.dracoLoader.setDecoderPath('/js/draco/') // 设置draco模型解码器路径
this.loaderGLTF.setDRACOLoader(this.dracoLoader) // 设置draco模型加载器
}
/**
* 添加模型数据
* @param url 模型的路径
* @param callback 返回模型对象,常用一些功能挂接在模型对象上
* @param progress 返回加载进度,还有问题,需要修改
*/
loadModelToScene(url, callback, progress) {
this.loadModel(url, model => {
this.scene.add(model.object) // 加载模型
callback?.(model)
}, num => {
progress?.(num) // 加载进度
})
}
/**
* 加载模型
* @param url 模型路径
* @param callback 回调模型
* @param progress 返回加载进度
*/
loadModel(url, callback, progress) {
let loader = this.loaderGLTF
if (url.indexOf('.fbx') !== -1) {
loader = this.loaderFBX
}
loader.load(url, model => {
callback?.(new DsModel(model, this.viewer))
}, xhr => {
progress?.((xhr.loaded / xhr.total).toFixed(2))
}, (error) => {
console.error('模型渲染报错:', error)
})
}
}
import * as THREE from 'three'
// 天空盒时间类型
const skyboxType = {
day: 'day',
dusk: 'dusk',
night: 'night'
}
export default class SkyBoxs {
constructor(viewer) {
this.viewer = viewer
}
/**
*
* @param {*} type 天空盒类型
*/
setSkybox(type = skyboxType.day) {
const loaderbox = new THREE.CubeTextureLoader() // 加载贴图
const cubeTexture = loaderbox.load([
`/images/skybox/${type}/posx.jpg`,
`/images/skybox/${type}/negx.jpg`,
`/images/skybox/${type}/posy.jpg`,
`/images/skybox/${type}/negy.jpg`,
`/images/skybox/${type}/posz.jpg`,
`/images/skybox/${type}/negz.jpg`
])
this.viewer.scene.background = cubeTexture
}
}
\ No newline at end of file
import * as THREE from 'three'
import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer'
export default class ThreeMouseEvent {
constructor(viewer, isSelect, callback, type = 'click') {
this.viewer = viewer
this.isSelect = isSelect
this.callback = callback
this.type = type
this.composer = new EffectComposer(this.viewer.renderer)
return this
}
startSelect() {
this.stopSelect()
this.bingEvent = this.#event.bind(this, this)
this.viewer.renderer.domElement.addEventListener(this.type, this.bingEvent)
}
stopSelect() {
this.viewer.renderer.domElement.removeEventListener(this.type, this.bingEvent)
}
#event(that, event) {
const raycaster = new THREE.Raycaster() // 创建射线
const mouse = new THREE.Vector2() // 创建鼠标坐标
mouse.x = (event.offsetX / that.viewer.renderer.domElement.clientWidth) * 2 - 1
mouse.y = -(event.offsetY / that.viewer.renderer.domElement.clientHeight) * 2 + 1
raycaster.setFromCamera(mouse, that.viewer.camera) // 设置射线的起点和终点
// TODO: 第一个参数是否需要外部传入,减小监听范围
const intersects = raycaster.intersectObject(that.viewer.scene, true) // 检测射线与模型是否相交
if (intersects.length > 0 && intersects[0]) {
that.callback(intersects[0].object, intersects[0].point)
}
}
}
import {
Cache,
WebGLRenderer,
PerspectiveCamera,
Scene,
Color,
AxesHelper
} from "three"
import {
CSS2DRenderer
} from "three/examples/jsm/renderers/CSS2DRenderer" // 二维标签渲染器
import {
CSS3DRenderer
} from "three/examples/jsm/renderers/CSS3DRenderer" // 三维标签渲染器
import {
OrbitControls
} from "three/examples/jsm/controls/OrbitControls"
import Stats from "three/examples/jsm/libs/stats.module"
import SkyBoxs from "./SkyBoxs"
import Lights from "./Lights"
import ThreeMouseEvent from "./ThreeMouseEvent"
export default class Viewer {
/**
*
* @param {*} id 场景容器id
*/
constructor(id,vdom) {
Cache.enabled = false // 开启缓存
this.vdom=vdom||null
this.id = id
this.renderer = undefined
this.scene = undefined
this.camera = undefined
this.controls = undefined
this.animateEventList = []
this.#initViewer()
}
#initViewer() {
this.#initRenderer()
this.#initCamera()
this.#initScene()
this.#initControl()
this.#initSkybox()
this.#initLight()
const animate = () => {
// console.log(this.vdom)
requestAnimationFrame(animate)
this.#updateDom()
this.#renderDom()
// 全局的公共动画函数,添加函数可同步执行
this.animateEventList.forEach(
event => {
event.fun && event.content && event.fun(event.content)
})
}
animate()
}
/**
* 添加坐标轴
*/
addAxis() {
// 显示坐标轴(x轴: 红色; y轴: 绿色; z轴: 蓝色)
// x轴水平方向(右正); y轴垂直方向(上正); z轴垂直xy平面即屏幕(外正)
this.scene.add(new AxesHelper(100))
}
/**
* 添加状态检测
*/
addStats() {
if (!this.statsControls) {
this.statsControls = new Stats()
}
this.statsControls.dom.style.position = 'absolute'
this.viewerDom.appendChild(this.statsControls.dom)
// 添加到动画
this.statsUpdateObj = {
fun: this.#statsUpdate,
content: this.statsControls
}
this.addAnimate(this.statsUpdateObj)
}
/**
* 移除状态检测
*/
removeStats() {
if (this.statsControls && this.statsUpdateObj) {
this.viewerDom.removeChild(this.statsControls.dom)
this.removeAnimate(this.statsUpdateObj)
}
}
#statsUpdate(statsControls) {
statsControls.update()
}
/**
* 更新DOM
*/
#updateDom() {
this.controls.update();
this.camera.aspect = this.viewerDom.clientWidth / this.viewerDom.clientHeight // 摄像机视锥体的长宽比,通常是使用画布的宽/画布的高
this.camera.updateProjectionMatrix() // 更新摄像机投影矩阵 在任何参数被改变以后必须被调用,来使得这些改变生效
this.renderer.setSize(this.viewerDom.clientWidth, this.viewerDom.clientHeight) // 设置渲染器的尺寸
this.renderer.setPixelRatio(window.devicePixelRatio) // 设置渲染器的像素比
this.labelRenderer.setSize(this.viewerDom.clientWidth, this.viewerDom.clientHeight) // 设置标签渲染器的尺寸
this.css3DRenderer.setSize(this.viewerDom.clientWidth, this.viewerDom.clientHeight) // 设置标签渲染器的尺寸
}
#renderDom() {
this.renderer.render(this.scene, this.camera) // 渲染场景
this.labelRenderer.render(this.scene, this.camera) // 渲染2d标签场景
this.css3DRenderer.render(this.css3dScene, this.camera) // 渲染3d标签场景
}
/**
* 创建初始化场景界面
*/
#initRenderer() {
// 获取画布dom
this.viewerDom = document.getElementById(this.id)
// 初始化渲染器
this.renderer = new WebGLRenderer({
// logarithmicDepthBuffer: true, // true/false 表示是否使用对数深度缓冲,true性能不好
antialias: true, // true/false表示是否开启反锯齿
alpha: true, // true/false 表示是否可以设置背景色透明
precision: "highp", // highp/mediump/lowp 表示着色精度选择
premultipliedAlpha: true, // true/false 表示是否可以设置像素深度(用来度量图像的分辨率)
})
this.renderer.clearDepth(); // 设置深度缓冲区
this.renderer.shadowMap.enabled = true // 场景中的阴影自动更新
this.viewerDom.appendChild(this.renderer.domElement) // 将渲染器添加到画布中
// 二维标签
this.labelRenderer = new CSS2DRenderer() // 标签渲染器
this.labelRenderer.domElement.style.zIndex = 2
this.labelRenderer.domElement.style.position = 'absolute'
this.labelRenderer.domElement.style.top = '0px'
this.labelRenderer.domElement.style.left = '0px'
this.labelRenderer.domElement.style.pointerEvents = 'none' // 避免HTML标签遮挡三维场景的鼠标事件
this.viewerDom.appendChild(this.labelRenderer.domElement)
// 三维标签
this.css3DRenderer = new CSS3DRenderer() // 标签渲染器
this.css3DRenderer.domElement.style.zIndex = 0
this.css3DRenderer.domElement.style.position = 'absolute'
this.css3DRenderer.domElement.style.top = '0px'
this.css3DRenderer.domElement.style.left = '0px'
this.css3DRenderer.domElement.style.pointerEvents = 'none' // 避免HTML标签遮挡三维场景的鼠标事件
this.viewerDom.appendChild(this.css3DRenderer.domElement)
}
/**
* 渲染相机
*/
#initCamera() {
this.camera = new PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 500000) // 透视相机
this.camera.position.set(50, 0, 50) // 相机位置
this.camera.lookAt(0, 0, 0) // 设置相机方向
}
/**
* 渲染场景
*/
#initScene() {
this.scene = new Scene()
this.css3dScene = new Scene()
this.scene.background = new Color('rgb(5,24,38)')
}
/**
* 初始化控制
*/
#initControl() {
this.controls = new OrbitControls(this.camera, this.renderer.domElement)
this.controls.enableDamping = false // 是否开启阻尼
this.controls.screenSpacePanning = false // 定义当平移的时候摄像机的位置将如何移动, 摄像机将在与摄像机向上方向垂直的平面中平移
}
/**
* 初始化天空盒
*/
#initSkybox() {
/* if (!this.skyboxs) {
this.skyboxs = new SkyBoxs(this)
}
this.skyboxs.setSkybox() */
}
/**
* 初始化灯光
*/
#initLight() {
if (!this.lights) {
this.lights = new Lights(this)
}
}
/**
* 添加全局的动画事件
* @param animate 函数加参数对象
* 传入对象 = {
fun: 函数名称,
content: 函数参数
}
*/
addAnimate(animate) {
this.animateEventList.push(animate)
}
/**
* 移除全局的动画事件
* @param animate 函数加参数对象
* 传入对象 = {
fun: 函数名称,
content: 函数参数
}
*/
removeAnimate(animate) {
this.animateEventList.map((val, i) => {
if (val === animate) this.animateEventList.splice(i, 1)
})
}
/**
* 开启鼠标事件
* @param {*} mouseType 鼠标类型
* @param {*} isSelect 是否选中
* @param {*} callback 鼠标回调
*/
startSelectEvent(mouseType, isSelect, callback) {
if (!this.mouseEvent) {
this.mouseEvent = new ThreeMouseEvent(this, isSelect, callback, mouseType)
}
this.mouseEvent.startSelect()
}
/**
* 关闭鼠标事件
*/
stopSelectEvent() {
this.mouseEvent?.stopSelect()
}
}
...@@ -86,10 +86,12 @@ export default { ...@@ -86,10 +86,12 @@ export default {
} }
}) })
// When there is only one child router, the child router is displayed by default // When there is only one child router, the child router is displayed by default
if (showingChildren.length === 1) { if (showingChildren.length === 1) {
return true // this.onlyOneChild = { ... parent, path: '', noShowingChildren: true }
} return true
}
// Show parent if there are no child router to display // Show parent if there are no child router to display
if (showingChildren.length === 0) { if (showingChildren.length === 0) {
......
...@@ -27,24 +27,121 @@ import Layout from '@/layout' ...@@ -27,24 +27,121 @@ import Layout from '@/layout'
activeMenu: '/system/user' // 当路由设置了该属性,则会高亮相对应的侧边栏。 activeMenu: '/system/user' // 当路由设置了该属性,则会高亮相对应的侧边栏。
} }
*/ */
export const powerRoutes=[ export const powerRoutes = [
/* erp 基础数据*/ /*基础数据*/
{
path: '/sbxxgl',
component: "Layout",
hidden: false,
alwaysShow: true,
redirect: 'sbxx',
meta: {
title: "设备信息管理",
icon: "fa-cog",
noCache: false,
link: null,
mkid: '920020000'
},
children: [
/* 基础数据 */
{
erpComponent: false,
component: 'sbxxgl/sbxx/index',
hidden: false,
meta: {
"title": "设备信息",
"icon": "",
"noCache": false,
"link": null,
"mkid": '920020100',
},
name: 'sbxx',
path: "sbxx",
},
{
erpComponent: false,
component: 'sbxxgl/sblxgx/index',
hidden: false,
meta: {
"title": "设备流向关系",
"icon": "",
"noCache": false,
"link": null,
"mkid": '920020200',
},
name: 'sblxgx',
path: "sblxgx",
},
{
erpComponent: false,
component: 'sbxxgl/sblx/index',
hidden: false,
meta: {
"title": "设备类型",
"icon": "",
"noCache": false,
"link": null,
"mkid": '920020300',
},
name: 'sblx',
path: "sblx",
},
{
erpComponent: false,
component: 'sbxxgl/jzbm/index',
hidden: false,
meta: {
"title": "机组编码",
"icon": "",
"noCache": false,
"link": null,
"mkid": '920020400',
},
name: 'jzbm',
path: "jzbm",
},
{
path: '/yhlywsytst',
component: "Layout",
hidden: false,
alwaysShow: true,
redirect: 'yhlywsytst',
meta: {
title: "一回路异物溯源态势图",
icon: "fa-cog",
noCache: false,
link: null,
mkid: '920050000'
},
children: [
/* 基础数据 */
{
erpComponent: false,
component: 'yhlywsytst/yhlywsytst/index',
hidden: false,
meta: {
"title": "一回路异物溯源态势图",
"icon": "",
"noCache": false,
"link": null,
"mkid": '920051000',
},
name: 'yhlywsytst',
path: "yhlywsytst",
}],
}
]
}
] ]
// 公共路由 // 公共路由
export const constantRoutes = [ export const constantRoutes = [{
{
path: '/redirect', path: '/redirect',
component: Layout, component: Layout,
hidden: true, hidden: true,
children: [ children: [{
{ path: '/redirect/:path(.*)',
path: '/redirect/:path(.*)', component: () => import('@/views/redirect')
component: () => import('@/views/redirect') }]
}
]
}, },
{ {
path: '/login', path: '/login',
...@@ -85,14 +182,15 @@ export const constantRoutes = [ ...@@ -85,14 +182,15 @@ export const constantRoutes = [
component: Layout, component: Layout,
hidden: true, hidden: true,
redirect: 'noredirect', redirect: 'noredirect',
children: [ children: [{
{ path: 'profile',
path: 'profile', component: () => import('common/src/views/user/profile/index'),
component: () => import('common/src/views/user/profile/index'), name: 'Profile',
name: 'Profile', meta: {
meta: { title: '个人中心', icon: 'user' } title: '个人中心',
icon: 'user'
} }
] }]
}, },
/* 陕钢铁预写死页面*/ /* 陕钢铁预写死页面*/
] ]
...@@ -112,6 +210,8 @@ Router.prototype.push = function push(location) { ...@@ -112,6 +210,8 @@ Router.prototype.push = function push(location) {
export default new Router({ export default new Router({
// mode: 'history', // mode: 'history',
mode: 'hash', mode: 'hash',
scrollBehavior: () => ({ y: 0 }), scrollBehavior: () => ({
y: 0
}),
routes: constantRoutes routes: constantRoutes
}) })
<template>
<RelDialog width="50%" :type='type' :editApp='editApp' :app='app' :buttonApp='buttonApp'>
<el-form slot="form" ref="form" :model="form" label-width="100px" :rules="rules">
<el-row :gutter="20" :app="this">
<EditColItem :required="item.required||false" :readonly="item.readonly?true:false " v-for="(item,index) in editColItemList " :value="item.value" :span="item.span" :label="item.label" :prop='item.prop' :key="item.prop" :type="item.type" :typeConfig='item.typeConfig' :rule="item.rule" />
</el-row>
</el-form>
</RelDialog>
</template>
<script>
import {
editMixin
} from 'common'
export default {
mixins: [editMixin],
data() {
return {
editColItemList: [
{
label: '编码',
prop: 'code',
span: 12,
type: 'input',
required:true,
},
{
label: '名称',
prop: 'name',
span: 12,
type: 'input',
required:true,
},
{
label: '备注',
prop: 'bz',
span: 24,
type: 'input'
},
]
}
}
}
</script>
<template>
<BasePage class="min_full" :config="config">
<template #dialog="ctx">
<!-- 嵌入默认页面额外弹框的插槽 ctx.pagePage来操作默认页面 -->
</template>
<template #toolbar="ctx">
<!-- 嵌入默认页面工具栏的插槽 ctx.pagePage来操作默认页面 -->
<!-- <el-button @click="demo(ctx.basePage)" size='mini' type="primary">示例按钮</el-button> -->
</template>
</BasePage>
</template>
<script>
import Edit from './edit.vue'
export default {
name: 'sblx',
data() {
return {
config: {
/* 基本配置*/
url: 'sbgl/ujzbm',
tableTitle: [{
title: "编码",
field: "code",
fieldType: "upper",
width: 140
},
{
title: "名称",
field: "name",
width: 140
},
{
title: "创建人",
field: "cjr",
width: 140
},
{
title: "创建时间",
field: "cjsj",
fieldType: 'ftDateTime'
},
{
title: "维护人",
field: "whr",
hidden: true
},
{
title: "维护时间",
field: "whsj",
fieldType: 'ftDateTime',
hidden: true
}
],
queryParams: [
[{
label: '编码',
prop: 'code',
span: 6,
type: 'input',
value: ''
},
{
label: '名称',
prop: 'name',
span: 6,
type: 'input',
value: ''
}
]
],
/* 默认启停用 */
}
}
},
methods: {
/* 示例*/
// demo(basePage){
// }
},
components: {
Edit
}
}
</script>
<style>
</style>
<template>
<RelDialog width="50%" :type='type' :editApp='editApp' :app='app' :buttonApp='buttonApp'>
<el-form slot="form" ref="form" :model="form" label-width="100px" :rules="rules">
<el-row :gutter="20" :app="this">
<EditColItem :required="item.required||false" :readonly="item.readonly?true:false " v-for="(item,index) in editColItemList " :value="item.value" :span="item.span" :label="item.label" :prop='item.prop' :key="item.prop" :type="item.type" :typeConfig='item.typeConfig' :rule="item.rule" />
</el-row>
</el-form>
</RelDialog>
</template>
<script>
import {
editMixin
} from 'common'
export default {
mixins: [editMixin],
data() {
return {
editColItemList: [
{
label: '编码',
prop: 'code',
span: 12,
type: 'input',
required:true,
},
{
label: '名称',
prop: 'name',
span: 12,
type: 'input',
required:true,
},
{
label: '备注',
prop: 'bz',
span: 24,
type: 'input'
},
]
}
}
}
</script>
<template>
<BasePage class="min_full" :config="config">
<template #dialog="ctx">
<!-- 嵌入默认页面额外弹框的插槽 ctx.pagePage来操作默认页面 -->
</template>
<template #toolbar="ctx">
<!-- 嵌入默认页面工具栏的插槽 ctx.pagePage来操作默认页面 -->
<!-- <el-button @click="demo(ctx.basePage)" size='mini' type="primary">示例按钮</el-button> -->
</template>
</BasePage>
</template>
<script>
import Edit from './edit.vue'
export default {
name: 'sblx',
data() {
return {
config: {
/* 基本配置*/
url: 'sbgl/usblx',
tableTitle: [{
title: "编码",
field: "code",
fieldType: "upper",
width: 140
},
{
title: "名称",
field: "name",
width: 140
},
{
title: "创建人",
field: "cjr",
width: 140
},
{
title: "创建时间",
field: "cjsj",
fieldType: 'ftDateTime'
},
{
title: "维护人",
field: "whr",
hidden: true
},
{
title: "维护时间",
field: "whsj",
fieldType: 'ftDateTime',
hidden: true
}
],
queryParams: [
[{
label: '编码',
prop: 'code',
span: 6,
type: 'input',
value: ''
},
{
label: '名称',
prop: 'name',
span: 6,
type: 'input',
value: ''
}
]
],
/* 默认启停用 */
}
}
},
methods: {
/* 示例*/
// demo(basePage){
// }
},
components: {
Edit
}
}
</script>
<style>
</style>
<template>
<RelDialog width="50%" :type='type' :editApp='editApp' :app='app' :buttonApp='buttonApp'>
<el-form slot="form" ref="form" :model="form" label-width="100px" :rules="rules">
<el-row :gutter="20" :app="this">
<EditColItem :required="item.required||false" :readonly="item.readonly?true:false " v-for="(item,index) in editColItemList " :value="item.value" :span="item.span" :label="item.label" :prop='item.prop' :key="item.prop" :type="item.type" :typeConfig='item.typeConfig' :rule="item.rule" />
</el-row>
</el-form>
</RelDialog>
</template>
<script>
import sbxx from './sbxx'
import {
editMixin
} from 'common'
export default {
mixins: [editMixin],
data() {
return {
editColItemList: [
{
label: '机组编码',
prop: 'jzbm',
span: 12,
"type": "RelSelect",
"typeConfig": {
"src": "sbgl/ujzbm/query",
"match": {
"value": "id",
"label": "name"
}
}
},
{
label: '路径号',
prop: 'ljh',
span: 12,
type: 'input',
required:true,
},
{
label: '上游节点',
prop: 'syjd',
span: 12,
required: true,
type: 'AuxInput',
typeConfig: {
isRequest: false,
dynamic: true,
code: true,
component: sbxx,
label: 'syjd',
transform: {
value: 'code',
label: 'code'
}
}
},
{
label: '当前节点',
prop: 'dqjd',
span: 12,
required: true,
type: 'AuxInput',
typeConfig: {
isRequest: false,
dynamic: true,
code: true,
component: sbxx,
label: 'dqjd',
transform: {
value: 'code',
label: 'code'
}
}
},
{
label: '备注',
prop: 'bz',
span: 24,
type: 'input'
}
]
}
}
}
</script>
<template>
<BasePage class="min_full" :config="config">
<template #dialog="ctx">
<!-- 嵌入默认页面额外弹框的插槽 ctx.pagePage来操作默认页面 -->
</template>
<template #toolbar="ctx">
<!-- 嵌入默认页面工具栏的插槽 ctx.pagePage来操作默认页面 -->
<!-- <el-button @click="demo(ctx.basePage)" size='mini' type="primary">示例按钮</el-button> -->
</template>
</BasePage>
</template>
<script>
import Edit from './edit.vue'
export default {
name: 'sblxgx',
data() {
return {
config: {
/* 基本配置*/
url: 'sbgl/usblxgx',
tableTitle: [{
title: "机组编码",
field: "jzbm",
width: 140,
transform: {
"url": "sbgl/ujzbm/query",
"label": "name",
"value": "id"
}
},
{
title: "路径号",
field: "ljh",
width: 100
},
{
title: "上游节点",
field: "syjd",
width: 100
},
{
title: "当前节点",
field: "dqjd",
width: 100
},
{
title: "创建人",
field: "cjr",
width: 140
},
{
title: "创建时间",
field: "cjsj",
fieldType: 'ftDateTime'
},
{
title: "维护人",
field: "whr",
hidden: true
},
{
title: "维护时间",
field: "whsj",
fieldType: 'ftDateTime',
hidden: true
}
],
queryParams: [
[{
label: '路径号',
prop: 'ljh',
span: 6,
type: 'input',
value: ''
},
{
"label": "机组编码",
"prop": "jzbm",
"span": 6,
"type": "RelSelect",
"value": "",
"typeConfig": {
"src": "sbgl/ujzbm/query",
"match": {
"value": "id",
"label": "bmmc"
}
}
}
]
],
/* 默认启停用 */
}
}
},
methods: {
/* 示例*/
// demo(basePage){
// }
},
components: {
Edit
}
}
</script>
<style>
</style>
<template>
<RelDialog ref="RelDialog" @addSuccess='addSuccess' width="70%" :type='type' :editApp='editApp' :app='app'
:buttonApp='buttonApp'>
<el-form slot="form" ref="form" :model="form" label-width="100px" :rules="rules">
<!-- 辅助编码-->
<el-row :gutter="20" :app="this">
<EditColItem :required="item.required||false" :readonly="item.readonly?true:false "
v-for="(item,index) in editColItemList " :value="item.value" :span="item.span" :label="item.label"
:prop='item.prop' :key="item.prop" :type="item.type" :typeConfig='item.typeConfig' :rule="item.rule" />
</el-row>
</el-form>
</RelDialog>
</template>
<script>
import {
editMixin
} from 'common'
export default {
mixins: [editMixin],
mounted() {
this.$nextTick(()=>{
this.form.pid=this.app.queryParams.pid
})
},
methods: {
addSuccess(obj) {
let newObj = obj.params.master
newObj.id = obj.res.data.id
newObj.pid = this.form.pid
let tree = this.app.$parent.$refs.lazyTree
tree.list.push(newObj)
this.$nextTick(() => {
tree.loadAllNode()
})
}
},
data() {
return {
editColItemList: [
{
label: '上层分类',
prop: 'pid',
span: 8,
"type": "RelSelect",
"typeConfig": {
"src": "sbgl/usbxx/queryroot",
"match": {
"value": "id",
"label": "name"
}
}
},
{
label: '设备编码',
prop: 'code',
span: 8,
type: 'input',
required: true,
},
{
label: '设备名称',
prop: 'name',
span: 8,
type: 'input',
required: true,
},
{
// required: true,
label: '设备分类',
prop: 'type',
span: 8,
"type": "RelSelect",
"typeConfig": {
"src": "sbgl/usblx/query",
"match": {
"value": "id",
"label": "name"
}
}
},
{
required: false,
label: '风险等级',
prop: 'fxdj',
span: 8,
"type": "RelSelect",
"typeConfig": {
"src": "sbgl/usbxx/init/fxlevel",
"match": {
"value": "id",
"label": "name"
}
}
},
{
label: '规格',
prop: 'gg',
span: 8,
"type": "input",
},
{
label: '管径',
prop: 'gj',
span: 8,
"type": "input",
},
{
label: '流通直径',
prop: 'ltzj',
span: 8,
"type": "input",
},
{
label: '机组编码',
prop: 'jzbm',
span: 8,
"type": "RelSelect",
"typeConfig": {
"src": "sbgl/ujzbm/query",
"match": {
"value": "id",
"label": "name"
}
}
},
{
label: '备注',
prop: 'bz',
span: 24,
type: 'input',
}
]
}
}
}
</script>
<template>
<div class="full flex">
<div class="min_full" style="width: 380px;border: 0px;height: 100%;">
<LazyTree treeTitle="设备信息树" ref="lazyTree" :props="{
label: 'name',
isLeaf: 'isLeaf'
}" cid='id' @selected='selectedTree' url='sbgl/usbxx/queryroot' />
</div>
<div style="width: calc(100% - 380px);border-top: 0px;height: 100%;">
<div class="full">
<BasePage @getRow='getRow' :power='power' class="min_full"
style="height: 100%;border: 0px;border-bottom: 5px solid #eee;" @delSuccess='delSuccess' :autoQuery='false'
ref="basePage" :config="config">
<template #dialog="ctx">
</template>
<template #toolbar="ctx">
</template>
</BasePage>
</div>
</div>
</div>
</template>
<script>
import Edit from './edit.vue'
export default {
name: 'sbxx',
data() {
return {
activeName: 'sbbg',
userid: localStorage.getItem('usercode'),
power: {
add: true,
copy: false,
/* 手动控制删除 */
delButton: true,
/* 手动控制编辑按钮权限 */
editButton: true,
/* 是否渲染右侧操作按钮 */
operateButtons: true,
/* 是否开启工作流按钮 */
workFlow: false,
/* 表格开启选择,以及记住选择 */
showSelection: false,
saveSelected: false,
},
config: {
/* 基本配置*/
url: 'sbgl/usbxx',
tableTitle: [{
title: "设备编码",
field: "code",
width: 140
},
{
title: "设备名称",
field: "name",
width: 140
},
// {
// title: "层级码",
// field: "cjid",
// width: 140
// },
{
title: "设备类型",
field: "type",
width: 140,
transform: {
"url": "sbgl/usblx/query",
"label": "name",
"value": "id"
}
},
{
title: "风险等级",
field: "fxdj",
width: 140,
transform: {
"url": "sbgl/usbxx/init/fxlevel",
"label": "name",
"value": "id"
}
},
{
title: "规格",
field: "gg",
width: 140
},
{
title: "管径",
field: "gj",
width: 140
},
{
title: "流通直径",
field: "ltzj",
width: 140
},
{
title: "机组编码",
field: "jzbm",
width: 140,
transform: {
"url": "sbgl/ujzbm/query",
"label": "name",
"value": "id"
}
},
{
title: "备注",
field: "bz",
width: 250
},
{
title: "创建人",
field: "cjr"
},
{
title: "创建时间",
field: "cjsj",
fieldType: 'ftDateTime'
},
{
title: "维护人",
field: "whr",
hidden: true
},
{
title: "维护时间",
field: "whsj",
fieldType: 'ftDateTime',
hidden: true
}
],
queryParams: [
[{
label: '设备信息',
prop: 'sbxxInfo',
span: 6,
type: 'input',
value: ''
}]
],
/* 默认启停用 */
showqt: false,
}
}
},
methods: {
getRow(row) {
},
delSuccess(obj) {
/* let id = obj.params.master.id
let tree = this.$refs.lazyTree
tree.list.forEach((item, index) => {
if (item.id == id) {
tree.list.splice(index, 1)
}
})
tree.loadAllNode() */
},
selectedTree: function(e) {
this.$refs.basePage.treeInfo = e
let pid = e.id
this.$refs.basePage.queryParams.pid = pid
this.$refs.basePage.refresh()
},
},
components: {
Edit,
}
}
</script>
<style lang="scss">
.hastree {
height: calc(100vh - 84px);
overflow: hidden;
overflow-x: auto;
}
</style>
<style lang="scss" scoped>
::v-deep .el-tabs__content {
height: calc(100% - 60px);
}
::v-deep .el-tabs__nav-scroll {
padding-left: 10px;
}
.hastree {
overflow: hidden;
overflow-x: auto;
}
</style>
<template>
<DefaultDialog :app='app'>
<div slot="form" style="display: flex;height: 70vh;">
DialogTitle:'新增',
showDialog:false,
</div>
<div slot="reFooter" class="refooter" >
<span slot="footer" class="dialog-footer" >
<el-button @click="app.showDialog=false">取 消</el-button>
<el-button type="primary" @click="save()">保 存</el-button>
</span>
</div>
</DefaultDialog>
</template>
<script>
export default {
props: {
app: {
type: Object,
default: ()=>{
return {}
}
}
},
async mounted() {
},
data() {
return {
}
},
methods: {
}
}
</script>
<style scoped>
</style>
<template>
<RelDialog ref="RelDialog" @addSuccess='addSuccess' width="70%" :type='type' :editApp='editApp' :app='app'
:buttonApp='buttonApp'>
<el-form slot="form" ref="form" :model="form" label-width="100px" :rules="rules">
<!-- 辅助编码-->
<el-row :gutter="20" :app="this">
<EditColItem :required="item.required||false" :readonly="item.readonly?true:false "
v-for="(item,index) in editColItemList " :value="item.value" :span="item.span" :label="item.label"
:prop='item.prop' :key="item.prop" :type="item.type" :typeConfig='item.typeConfig' :rule="item.rule" />
</el-row>
</el-form>
</RelDialog>
</template>
<script>
import {
editMixin
} from 'common'
export default {
mixins: [editMixin],
mounted() {
this.$nextTick(()=>{
this.form.pid=this.app.queryParams.pid
})
},
methods: {
addSuccess(obj) {
let newObj = obj.params.master
newObj.id = obj.res.data.id
newObj.pid = this.form.pid
let tree = this.app.$parent.$refs.lazyTree
tree.list.push(newObj)
this.$nextTick(() => {
tree.loadAllNode()
})
}
},
data() {
return {
editColItemList: [
{
label: '上层分类',
prop: 'pid',
span: 8,
"type": "RelSelect",
"typeConfig": {
"src": "sbgl/usbxx/queryroot",
"match": {
"value": "id",
"label": "name"
}
}
},
{
label: '设备编码',
prop: 'code',
span: 8,
type: 'input',
required: true,
},
{
label: '设备名称',
prop: 'name',
span: 8,
type: 'input',
required: true,
},
{
// required: true,
label: '设备分类',
prop: 'type',
span: 8,
"type": "RelSelect",
"typeConfig": {
"src": "sbgl/usblx/query",
"match": {
"value": "id",
"label": "name"
}
}
},
{
required: false,
label: '风险等级',
prop: 'fxdj',
span: 8,
"type": "RelSelect",
"typeConfig": {
"src": "sbgl/usbxx/init/fxlevel",
"match": {
"value": "id",
"label": "name"
}
}
},
{
label: '规格',
prop: 'gg',
span: 8,
"type": "input",
},
{
label: '管径',
prop: 'gj',
span: 8,
"type": "input",
},
{
label: '流通直径',
prop: 'ltzj',
span: 8,
"type": "input",
},
{
label: '机组编码',
prop: 'jzbm',
span: 8,
"type": "RelSelect",
"typeConfig": {
"src": "sbgl/ujzbm/query",
"match": {
"value": "id",
"label": "name"
}
}
},
{
label: '备注',
prop: 'bz',
span: 24,
type: 'input',
}
]
}
}
}
</script>
<template>
<div class="full flex hastree" style="flex-direction: row;height: 140vh;border-top: 5px solid #eee;">
<div class="min_full" style="width: 380px;border: 0px;height: 140vh;">
<LazyTree treeTitle="设备信息树" ref="lazyTree" :props="{
label: 'name',
isLeaf: 'isLeaf'
}" cid='id' @selected='selectedTree' url='sbgl/usbxx/queryroot' />
</div>
<div class="min_full" style="width: calc(100% - 380px);border-top: 0px;height: 140vh;">
<div style="height:477px;width: 100%;">
<BasePage @getRow='getRow' :power='power' class="min_full" style="height: 477px;border: 0px;border-bottom: 5px solid #eee;"
@delSuccess='delSuccess' :autoQuery='false' ref="basePage" :config="config">
<template #dialog="ctx">
</template>
<template #toolbar="ctx">
<ImportButton @success="()=>{
ctx.basePage.refresh()
}" :url="'sbgl/usbxx/import'" />
<AttachFileButton style="margin-left: 10px;" :app='ctx.basePage' />
</template>
</BasePage>
</div>
<div style="height: calc(100% - 477px);width: 100%;">
<el-tabs class="full" v-model="activeName">
<el-tab-pane class="full" label="设备标高" style="height: 100%;" name="sbbg">
<Sbbg :app='this' class="full" ref='sbbg' />
</el-tab-pane>
<!-- <el-tab-pane class="full" label="设备流向关系" style="height: 100%;" name="sblxgx">
<Sblxgx :app='this' class="full" ref='sblxgx' />
</el-tab-pane> -->
</el-tabs>
</div>
</div>
</div>
</template>
<script>
import Edit from './edit.vue'
import Sbbg from './sbbg'
import Sblxgx from './sblxgx'
export default {
name: 'sbxx',
data() {
return {
activeName: 'sbbg',
userid: localStorage.getItem('usercode'),
power: {
add: true,
copy: false,
/* 手动控制删除 */
delButton: true,
/* 手动控制编辑按钮权限 */
editButton: true,
/* 是否渲染右侧操作按钮 */
operateButtons: true,
/* 是否开启工作流按钮 */
workFlow: false,
/* 表格开启选择,以及记住选择 */
showSelection: false,
saveSelected: false,
},
config: {
/* 基本配置*/
url: 'sbgl/usbxx',
tableTitle: [
{
title: "设备编码",
field: "code",
width: 140
},
{
title: "设备名称",
field: "name",
width: 140
},
// {
// title: "层级码",
// field: "cjid",
// width: 140
// },
{
title: "设备类型",
field: "type",
width: 140,
transform: {
"url": "sbgl/usblx/query",
"label": "name",
"value": "id"
}
},
{
title: "风险等级",
field: "fxdj",
width: 140,
transform: {
"url": "sbgl/usbxx/init/fxlevel",
"label": "name",
"value": "id"
}
},
{
title: "规格",
field: "gg",
width: 140
},
{
title: "管径",
field: "gj",
width: 140
},
{
title: "流通直径",
field: "ltzj",
width: 140
},
{
title: "机组编码",
field: "jzbm",
width: 140,
transform: {
"url": "sbgl/ujzbm/query",
"label": "name",
"value": "id"
}
},
{
title: "备注",
field: "bz",
width: 250
},
{
title: "创建人",
field: "cjr"
},
{
title: "创建时间",
field: "cjsj",
fieldType: 'ftDateTime'
},
{
title: "维护人",
field: "whr",
hidden: true
},
{
title: "维护时间",
field: "whsj",
fieldType: 'ftDateTime',
hidden: true
}
],
queryParams: [
[
{
label: '设备信息',
prop: 'sbxxInfo',
span: 6,
type: 'input',
value: ''
}
]
],
/* 默认启停用 */
showqt: false,
}
}
},
methods: {
getRow(row){
this.$refs.sbbg.$refs.basePage.queryParams.mid = row.id
this.$refs.sbbg.$refs.basePage.queryParams.sbxxcode = row.code
this.$refs.sbbg.$refs.basePage.refresh()
},
delSuccess(obj) {
/* let id = obj.params.master.id
let tree = this.$refs.lazyTree
tree.list.forEach((item, index) => {
if (item.id == id) {
tree.list.splice(index, 1)
}
})
tree.loadAllNode() */
},
selectedTree: function(e) {
this.$refs.basePage.treeInfo = e
let pid = e.id
this.$refs.basePage.queryParams.pid = pid
this.$refs.basePage.refresh()
},
},
components: {
Edit,Sbbg,Sblxgx
}
}
</script>
<style lang="scss">
.hastree {
height: calc(100vh - 84px);
overflow: hidden;
overflow-x: auto;
}
</style>
<style lang="scss" scoped>
::v-deep .el-tabs__content {
height: calc(100% - 60px);
}
::v-deep .el-tabs__nav-scroll {
padding-left: 10px;
}
.hastree {
height: calc(100vh - 84px);
overflow: hidden;
overflow-x: auto;
}
</style>
<template>
<RelDialog width="50%" :type='type' :editApp='editApp' :app='app' :buttonApp='buttonApp'>
<el-form slot="form" ref="form" :model="form" label-width="100px" :rules="rules">
<el-row :gutter="20" :app="this">
<EditColItem :required="item.required||false" :readonly="item.readonly?true:false "
v-for="(item,index) in editColItemList " :value="item.value" :span="item.span" :label="item.label"
:prop='item.prop' :key="item.prop" :type="item.type" :typeConfig='item.typeConfig' :rule="item.rule" />
</el-row>
</el-form>
</RelDialog>
</template>
<script>
import {
editMixin
} from 'common'
export default {
mixins: [editMixin],
mounted() {
this.$nextTick(() => {
this.form.mid=this.app.queryParams.mid
this.form.sbxxcode=this.app.queryParams.sbxxcode
})
},
data() {
return {
editColItemList: [{
readonly: true,
label: '设备信息编码',
prop: 'sbxxcode',
span: 8,
type: 'input',
},
{
label: '名称',
"required": true,
prop: 'name',
span: 8,
type: 'input',
},
{
label: 'X坐标',
prop: 'x',
span: 8,
type: 'input',
},
{
label: 'Y坐标',
prop: 'y',
span: 8,
type: 'input',
},
{
label: 'Z坐标',
prop: 'z',
span: 8,
type: 'input',
},
{
label: '备注',
prop: 'bz',
span: 24,
type: 'input',
},
]
}
},
methods: {
}
}
</script>
<template>
<BasePage @getRow='getRow' ref="basePage" :power='power' :toolButton='false' class="min_full"
style="height: 100%;border: 0px;" :autoQuery='false' :config="config">
<template #dialog="ctx">
</template>
<template #toolbar="ctx">
<!-- 嵌入默认页面额外弹框的插槽 ctx.pagePage来操作默认页面 -->
<!-- <ImportButton @success="()=>{
ctx.basePage.refresh()
}" :url="'sbdagl/sbxx/bjqd/import'" /> -->
</template>
</BasePage>
</template>
<script>
import Edit from './edit.vue'
export default {
data() {
return {
power: {
add: true,
copy: false,
/* 手动控制删除 */
delButton: true,
/* 手动控制编辑按钮权限 */
editButton: true,
/* 是否渲染右侧操作按钮 */
operateButtons: true,
/* 是否开启工作流按钮 */
workFlow: false,
/* 表格开启选择,以及记住选择 */
showSelection: false,
saveSelected: false
},
config: {
/* 基本配置*/
url: 'sbgl/usbbg',
tableTitle: [{
title: "设备信息编码",
field: "sbxxcode",
fieldType: "upper",
width: 140
},
{
title: "名称",
field: "name",
width: 140
},
{
title: "X坐标",
field: "x",
width: 140
},
{
title: "Y坐标",
field: "y",
width: 140
},
{
title: "Z坐标",
field: "z",
width: 140
},
{
title: "备注",
field: "bz",
width: 200
},
{
title: "创建人",
field: "cjr"
},
{
title: "创建时间",
field: "cjsj",
fieldType: 'ftDateTime'
},
{
title: "维护人",
field: "whr",
hidden: true
},
{
title: "维护时间",
field: "whsj",
fieldType: 'ftDateTime',
hidden: true
}
],
queryParams: [],
}
}
},
methods: {
getRow(val) {
this.$emit('getRow', val)
},
demo(ctx) {
if (ctx.singleItem && ctx.singleItem.id) {
console.log(ctx.singleItem)
} else {
this.$warning('请选中一条数据')
}
}
},
components: {
Edit
}
}
</script>
<style>
</style>
<template>
<RelDialog width="50%" :type='type' :editApp='editApp' :app='app' :buttonApp='buttonApp'>
<el-form slot="form" ref="form" :model="form" label-width="100px" :rules="rules">
<el-row :gutter="20" :app="this">
<EditColItem :required="item.required||false" :readonly="item.readonly?true:false "
v-for="(item,index) in editColItemList " :value="item.value" :span="item.span" :label="item.label"
:prop='item.prop' :key="item.prop" :type="item.type" :typeConfig='item.typeConfig' :rule="item.rule" />
</el-row>
</el-form>
</RelDialog>
</template>
<script>
import {
editMixin
} from 'common'
export default {
mixins: [editMixin],
mounted() {
this.$nextTick(() => {
/* 把主表信息传递进去*/
})
},
data() {
return {
editColItemList: [{
readonly: true,
label: '设备信息编码',
prop: 'sbxxcode',
span: 8,
type: 'input',
},
{
label: '名称',
"required": true,
prop: 'name',
span: 8,
type: 'input',
},
{
label: 'X坐标',
prop: 'x',
span: 8,
type: 'input',
},
{
label: 'Y坐标',
prop: 'y',
span: 8,
type: 'input',
},
{
label: 'Z坐标',
prop: 'z',
span: 8,
type: 'input',
},
{
label: '备注',
prop: 'bz',
span: 24,
type: 'input',
},
]
}
},
methods: {
}
}
</script>
<template>
<BasePage @getRow='getRow' ref="basePage" :power='power' :toolButton='false' class="min_full"
style="height: 100%;border: 0px;" :autoQuery='false' :config="config">
<template #dialog="ctx">
</template>
<template #toolbar="ctx">
<!-- 嵌入默认页面额外弹框的插槽 ctx.pagePage来操作默认页面 -->
<!-- <ImportButton @success="()=>{
ctx.basePage.refresh()
}" :url="'sbdagl/sbxx/bjqd/import'" /> -->
</template>
</BasePage>
</template>
<script>
import Edit from './edit.vue'
export default {
data() {
return {
power: {
add: true,
copy: false,
/* 手动控制删除 */
delButton: true,
/* 手动控制编辑按钮权限 */
editButton: true,
/* 是否渲染右侧操作按钮 */
operateButtons: true,
/* 是否开启工作流按钮 */
workFlow: false,
/* 表格开启选择,以及记住选择 */
showSelection: false,
saveSelected: false
},
config: {
/* 基本配置*/
url: 'sbgl/usbbg',
tableTitle: [{
title: "设备信息编码",
field: "sbxxcode",
fieldType: "upper",
width: 140
},
{
title: "名称",
field: "name",
width: 140
},
{
title: "X坐标",
field: "x",
width: 140
},
{
title: "Y坐标",
field: "y",
width: 140
},
{
title: "Z坐标",
field: "z",
width: 140
},
{
title: "备注",
field: "bz",
width: 200
},
{
title: "创建人",
field: "cjr"
},
{
title: "创建时间",
field: "cjsj",
fieldType: 'ftDateTime'
},
{
title: "维护人",
field: "whr",
hidden: true
},
{
title: "维护时间",
field: "whsj",
fieldType: 'ftDateTime',
hidden: true
}
],
queryParams: [],
}
}
},
methods: {
getRow(val) {
this.$emit('getRow', val)
},
demo(ctx) {
if (ctx.singleItem && ctx.singleItem.id) {
console.log(ctx.singleItem)
} else {
this.$warning('请选中一条数据')
}
}
},
components: {
Edit
}
}
</script>
<style>
</style>
<template>
<div class="yhlywsytst">
yhlywsytst
</div>
</template>
<script>
</script>
<style>
</style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment