Commit 05c7a730 authored by xioln's avatar xioln

已办任务界面,缺少“已办”的标识,缺少实际处理结果。

已办任务界面,“审签历史”,没有任何信息。
parent 8db38893
/*
* @Descripttion:
* @version:
* @Author: zp
* @Date: 2019-10-22 09:22:12
* @LastEditors: zp
* @LastEditTime: 2020-03-09 20:32:14
*/
// import * as BIM from "./BIM3DViewer"; // react里的用法
// import "./BIM3DViewer.js";
/**
* @description:
* @param {type} dom
* @param {number} BMcubeSize 罗盘大小,默认35
* @param {array} cubeImageUrl 罗盘图片路,数组,例["../../img/home.png", "../../img/up.png", "../../img/down.png"];(不传时则不创建罗盘)
* @param {string} manUrl 漫游人物模型路径
* @param {object} options json对象。相关系统配置,参数见下面。
* @param {number} options.near 近平面值,当该值不传时默认为0.01
* @param {number} options.far 远平面值,当该值不传时默认为100000
* @return:
*/
var BIM3DInterface = function (dom, BMcubeSize, cubeImageUrl, manUrl, options) {
this.viewer = new BIM.BimViewer(dom, BMcubeSize, cubeImageUrl, manUrl, options);
this.domElement = this.viewer.container;
};
BIM3DInterface.prototype = {
/**
* 销毁BIMViewer。
*/
dispose: function () {
this.viewer.dispose();
},
/**
* 获取BIMViewer的dom对象。用来添加进浏览器展示。
*/
getViewerDomElement: function () {
return this.viewer.container;
},
/**
* 重置窗口大小,调用getViewerDomElement()方法添加进对象里后调用此方法,浏览器窗口大小改变时应调用此方法。
* @param {number} height 窗口高度,当为undefined时使用100%;
* @param {number} width 窗口宽度,当为undefined时使用100%;
*/
resize: function (height, width) {
this.viewer.onWindowResize(height, width);
},
/**
* 加载模型文件。支持glb和gltf格式。
* @param {*} filenames 文件的url地址。支持数组对象,例如["url1","url2"]。
* @param {*} isHide 是否隐藏,true隐藏加载的模型,false不隐藏。
* @param {*} requestHeader {name:"",value:token};
*/
appendFile: function (filenames, isHide, requestHeader) {
this.viewer.appendFile(filenames, isHide, requestHeader);
},
/**
* 移除模型。
* @param {*} filenames 需要移除场景里模型的url地址。支持数组对象,例如["url1","url2"]。
*/
removeFile: function (filenames) {
this.viewer.removeFile(filenames);
},
/**
* 清空场景。
* @param {*} callback
*/
clearScene: function () {
this.viewer.removeScene();
},
/**
* 添加模型加载完毕回调。当调用appendFile接口加载的模型文件加载完毕则调用改回调。。
* @param {*} callback 文件加载成功后调用的回调方法,第一个参数为当前加载的文件url,第二个参数整数值,0失败,1成功。
*/
addAppendFileCallBack: function (callback) {
this.viewer.AddAppendFileCallBack(callback);
},
/**
* 添加选中模型回调方法。
* @param {*} callback 选中模型调用的方法。该方法需要定义一个函数参数。返回为object对象,
* 可用该对象调用接口来控制颜色,透明度等模型操作。可以使用该对象的name属性,该属性为字符串。为模型的名字id。
*/
addSelectObjectCallBack: function (callback) {
this.viewer.AddSelectObjectCallBack(callback);
},
/**
* 设置场景裁剪。
* @param {number} value 裁剪值,系统默认为10。
*/
setOptionCullingThreshold: function (value) {
this.viewer.setOptionCullingThreshold(value);
},
/**
* 设置透明度模式。
* @param {number} type 为0时,默认透明模式。为1时仅开启透明优化效果。为2时开启透明优化效果,效果虽好,但是会导致一些透明模型渲染失败。
* type传1,场景渲染已经够用。
*/
SetOptionTransparent: function (type) {
this.viewer.setOptionTransparent(type);
},
/**
* 设置模型高亮。
* @param {*} id string类型 需要高亮的模型id,多个则传数组。
* @param {*} whetherAdd 是否增加到当前高亮对象。true则将传入id追加到当前高亮对象,false则取消当前场景高亮的对象,高亮当前传入对象。
* 当id为"",whetherAdd为false时候,清除场景里的所有选中。
*/
setModelSelection: function (id, whetherAdd) {
this.viewer.setModelSelection(id, whetherAdd);
},
/**
* 设置模型显示隐藏。
* @param {*} id 需要显示隐藏的模型id。
* @param {*} visible 是否可见,true显示,false隐藏。
* @param {*} option 操作类型,传入0表示对传入的对象进行操作。传入1表示对传入的对象之外的对象进行操作。
*/
setModelVisible: function (id, visible, option) {
this.viewer.setModelVisible(id, visible, option);
},
/**
* 设置标准视图。
* @param {*} type 视图的类型。0-主视图,1-前视图,2-后视图,3-左视图,4-右视图,5-顶视图,6-底视图。
*/
setStandardView: function (type) {
this.viewer.setStandardView(type);
},
/**
* 根据RGB值设置模型颜色。
* @param {*} ids 需要修改颜色的模型id。支持传入数组。
* @param {*} red 红色值,取值范围0-255。
* @param {*} green 绿色值,取值范围0-255。
* @param {*} blue 蓝色值,取值范围0-255。
* @param {*} option 操作类型,传入0表示对传入的对象进行操作。传入1表示对传入的对象之外的对象进行操作。
*/
setModelColorByRGB: function (ids, red, green, blue, option) {
this.viewer.setModelColorByRGB(ids, red, green, blue, option);
},
/**
* 根据十六进制值设置模型颜色。
* @param {*} ids 需要修改颜色的模型id。支持传入数组。
* @param {*} hexColor 十六进制颜色值,例如红色0xff0000。
* @param {*} option 操作类型,传入0表示对传入的对象进行操作。传入1表示对传入的对象之外的对象进行操作。
*/
setModelColorByHex: function (ids, hexColor, option) {
this.viewer.setModelColorByHex(ids, hexColor, option);
},
/**
* 恢复模型颜色。
* @param {*} ids 需要恢复颜色的模型id。支持传入数组。
* @param {*} option 操作类型,传入0表示对传入的对象进行操作。传入1表示对传入的对象之外的对象进行操作。
*/
restoreModelColor: function (ids, option) {
this.viewer.restoreModelColor(ids, option);
},
/**
* 设置模型透明度。
* @param {*} id 需要设置透明度的模型id。
* @param {*} alpha 透明度值。取值范围0到1。0-不透明,1透明。
* @param {*} option 操作类型,传入0表示对传入的对象进行操作。传入1表示对传入的对象之外的对象进行操作。
*/
setModelAlpha: function (id, alpha, option) {
this.viewer.setModelAlpha(id, alpha, option);
},
/**
* 恢复模型透明度。
* @param {*} id 需要恢复透明度的模型id。
*/
restoreModelAlpha: function (id) {
this.viewer.restoreModelAlpha(id);
},
/**
* 根据id创建文字标签。
* @param {*} ids 需要创建文字标签的id。支持传入数组。
* @param {*} height 文字线的高度。
* @param {*} isWorldHeight 是否是世界坐标高度。
* @param {*} text 文字标签内容。
* @returns 返回数组对象,每个元素为html的a元素对象。可用来设置自定义风格以及添加事件。切记在调用dispose接口之前将返回的数组清空,否则回造成内存泄露。
*/
setModelTextLabel: function (ids, height, isWorldHeight, text) {
return this.viewer.setModelTextLabel(ids, height, isWorldHeight, text);
},
/**
* 移除文本标签。
* @param {Array?} ids 需要移除文字标签关联的id数组,当不传值时清除所有标签。
*/
removeModelTextLabelByIDs: function (ids) {
this.viewer.removeModelTextLabelByIDs(ids);
},
/**
* 移除文本标签。
* @param {Array?} divs 该参数由setModelTextLabel接口返回,当不传值时清除所有标签。
*/
removeModelTextLabelByDivs: function (divs) {
this.viewer.removeModelTextLabelByDivs(divs);
},
/**
* 根据id创建图像标签。
* @param {*} ids 需要创建图像标签的id。支持传入数组。
* @param {*} image_url 图像url地址。
* @param {*} image_width 图像标签宽度。
* @param {*} image_height 图像标签高度。
* @returns 返回数组对象,每个元素为html的img元素对象。可用来设置自定义风格以及添加事件。切记在调用dispose接口之前将返回的数组清空,否则回造成内存泄露。
*/
setModelImageLabel: function (ids, image_url, image_width, image_height) {
return this.viewer.setModelImageLabel(
ids,
image_url,
image_width,
image_height
);
},
/**
* 移除图像标签。
* @param {Array?} ids 需要移除图像标签关联的id数组,当不传值时清除所有标签。
*/
removeModelImageLabelByIDs: function (ids) {
this.viewer.removeModelImageLabelByIDs(ids);
},
/**
* 移除图像标签。
* @param {Array?} divs 该参数由setModelImageLabel接口返回,当不传值时清除所有标签。
*/
removeModelImageLabelByDivs: function (divs) {
this.viewer.removeModelImageLabelByDivs(divs);
},
/**
* 根据id创建任意html标签。
* @param {*} ids 需要创建图像标签的id。支持传入数组。
* @param {*} htmlValues html的字符串。
* @returns 返回数组对象,每个元素为html的根元素对象。可用来设置自定义风格以及添加事件。切记在调用dispose接口之前将返回的数组清空,否则回造成内存泄露。
*/
setModelAnyLabel: function (ids, htmlValues) {
return this.viewer.setModelAnyLabel(ids, htmlValues);
},
/**
* 移除html标签。
* @param {Array?} ids 需要移除html标签关联的id数组,当不传值时清除所有标签。
*/
removeModelAnyLabelByIDs: function (ids) {
this.viewer.removeModelAnyLabelByIDs(ids);
},
/**
* 移除html标签。
* @param {Array?} divs 该参数由setModelAnyLabel接口返回,当不传值时清除所有标签。
*/
removeModelAnyLabelByDivs: function (divs) {
this.viewer.removeModelAnyLabelByDivs(divs);
},
/**
* 设置轮廓线显示隐藏。
* @param {bool} visible true为显示,false为隐藏。默认为false。在场景过大时建议关闭该效果。
*/
setOutlineVisible: function (visible) {
this.viewer.setOutlineVisible(visible);
},
/**
* 设置轮廓线颜色
* @param {*} hexColor 十六进制颜色值,例如红色0xff0000。
*/
setOutlineColor: function (hexColor) {
this.viewer.setOutlineColor(hexColor);
},
/**
* 开始拾取顶点,传入回调,且回调带一个参数,该参数返回json对象,格式为{x:拾取点x的坐标,y:拾取点y的坐标,z:拾取点z的坐标}。
* 该json对象可用来使用在setImageLabelFromCoordinate接口参数里。
* @param {*} callback 鼠标左键确认点以后调用的方法。参数为坐标的json对象。
*/
startPickupPoint: function (callback) {
this.viewer.startPickupPoint(callback);
},
/**
* 结束拾取顶点操作。
*/
endPickupPoint: function () {
this.viewer.endPickupPoint();
},
/**
* 清除所有根据坐标点创建的图标。
*/
clearPickupPointImageLabel: function () {
this.viewer.clearPickupPoint();
},
/**
* 根据坐标点创建图标。
* @param {*} coordinate 坐标。startPickupPoint返回的json对象。
* @param {*} image_url 图像url地址。
* @param {*} image_width 图像宽度。
* @param {*} image_height 图像高度。
* @returns 返回图像标签对象,dom对象。可用来自定义点击事件。
*/
setImageLabelFromCoordinate: function (
coordinate,
image_url,
image_width,
image_height
) {
return this.viewer.setImageLabelFromCoordinate(
coordinate,
image_url,
image_width,
image_height
);
},
/**
* 移除单个拾取点创建的图标。
* @param {*} imagelabel 图像标签对象,传入setImageLabelFromCoordinate返回的对象。
*/
removePickupPointImageLabel: function (imagelabel) {
this.viewer.removePickupPointImageLabel(imagelabel);
},
/**
* 获取摄像机信息。
* @returns 返回当前摄像机信息,格式为json对象。例如
* {
cmPosition:{x:0.0,y:0.0,z:0.0},cmTarget:{x:10.0,y:10.0,z:10.0},cmUp:{x:0.0,y:0.0,z:1.0}
};
*/
getCamera: function () {
return this.viewer.getCamera();
},
/**
* 设置摄像机信息。
* @param {*} cameraInfo 摄像机信息的json格式对象。
*/
setCamera: function (cameraInfo) {
this.viewer.setCamera(cameraInfo);
},
/**
* 添加模型id进选择过滤管理器。在过滤管理器里的模型不能被选中。
* @param {*} ids 不被选中的对象id,支持传入数组。
*/
addSelectFilter: function (ids) {
this.viewer.addSelectFilter(ids);
},
/**
* 移除过滤管理器里的模型。使得对应的模型可以被选中。
* @param {*} ids 模型对象id,支持传入数组。
*/
removeSelectFilter: function (ids) {
this.viewer.removeSelectFilter(ids);
},
/**
* 清空过滤管理器里的模型。使得模型都可以被选中。
*/
clearSelectFiler: function () {
this.viewer.clearSelectFiler();
},
/**
*指定的模型是否在过滤管理器里。
* @param {*} id 需要查询的模型id。
* @returns 返回bool类型变量,true表示在过滤管理器里,false表示没有在过滤管理器里。
*/
isInSelectFilter: function (id) {
return this.viewer.isInSelectFilter(id);
},
/**
* 设置控件背景。
* @param {*} topColor 顶部颜色值。十六进制的字符串。例如"#FF0000"红色。
* @param {*} bottomColor 底部颜色值。十六进制的字符串。例如"#00FF00"绿色。
*/
setBackground: function (topColor, bottomColor) {
this.viewer.setBackground(1, topColor, bottomColor);
},
/**
* 设置模型隔离。
* @param {*} ids 需要隔离对象的id,支持数组。
* @param {*} bQuarantine 是否隔离对象,true隔离,false取消隔离。
* @param {*} option 操作类型,传入0表示对传入的对象进行操作。传入1表示对传入的对象之外的对象进行操作。
* 注:当ids传入""时,bQuarantine传入false,option传入1时取消所有隔离。
*/
setModelQuarantine: function (ids, bQuarantine, option) {
this.viewer.setModelQuarantine(ids, bQuarantine, option);
},
/**
* 根据字符串矩阵设置模型矩阵。
* @param {*} ids 需要修改模型矩阵的模型id数组。
* @param {*} strMatrix 字符串矩阵。
*/
setModelMatrixByString: function (ids, strMatrix) {
this.viewer.setModelMatrixByString(ids, strMatrix);
},
/**
* 获取视点。
* @param {*} moveSpeed
* @param {*} rotateSpeed
* @returns 返回json对象。
*/
getViewpoint: function () {
return this.viewer.getViewpoint();
},
/**
* 恢复视点。
* @param {*} viewpoint 视点信息,json对象。
* @param {*} needsUpdate 是否需要恢复后可更改视点信息(标注的修改等)
*/
setViewpoint: function (viewpoint, needsUpdate) {
this.viewer.setViewpoint(viewpoint, needsUpdate);
},
/**
* 开始漫游。
* @param {*} moveSpeed 移动速度 默认0.1。
* @param {*} rotateSpeed 旋转速度 默认0.1。
*/
startFPRoaming: function (moveSpeed, rotateSpeed) {
this.viewer.startFPRoaming(moveSpeed, rotateSpeed);
},
/**
* @description: 设置漫游速度
* @param {number} moveSpeed 移动速度
* @param {number} rotateSpeed 旋转速度
* @return:
*/
setFPRoamingSpeed: function (moveSpeed, rotateSpeed) {
this.viewer.setFPRoamingSpeed(moveSpeed, rotateSpeed);
},
/**
* 结束漫游。
*/
endFPRoaming: function () {
this.viewer.endFPRoaming();
},
/**
* 箭头标注(有弹窗)
* @param {function} con 用于获取返回值的回调函数。如 const con = a => {console.log(a)} a为返回值
*
*/
arrowMarkWithPanel: function (con) {
this.viewer.arrowMark(con);
},
/**
* 箭头标注(无弹窗)。
* @param {*} color 颜色 #ffffff(str)
* @param {*} width 线宽 线的粗细(单位像素)
*/
arrowMark: function (color, width) {
this.viewer._arrowMark(color, width);
},
/**
* 圆形标注(有弹窗)
* @param {function} con 用于获取返回值的回调函数。如 const con = a => {console.log(a)} a为返回值
*
*/
circleMarkWithPanel: function (con) {
this.viewer.circleMark(con);
},
/**
* 圆形标注(无弹窗)
* @param {*} color 颜色 #ffffff(str)
* @param {*} width 线宽 线的粗细(单位像素)
*/
circleMark: function (color, width) {
this.viewer._circleMark(color, width);
},
/**
* 椭圆形标注(有弹窗)
* @param {function} con 用于获取返回值的回调函数。如 const con = a => {console.log(a)} a为返回值
*
*/
ellipseMarkWithPanel: function (con) {
this.viewer.ellipseMark(con);
},
/**
* 椭圆形标注(无弹窗)
* @param {*} color 颜色 #ffffff(str)
* @param {*} width 线宽 线的粗细(单位像素)
*/
ellipseMark: function (color, width) {
this.viewer._ellipseMark(color, width);
},
/**
* 矩形标注(有弹窗)
* @param {function} con 用于获取返回值的回调函数。如 const con = a => {console.log(a)} a为返回值
*
*/
rectMarkWithPanel: function (con) {
this.viewer.rectMark(con);
},
/**
* 矩形标注(无弹窗)
* @param {*} color 颜色 #ffffff(str)
* @param {*} width 线宽 线的粗细(单位像素)
*/
rectMark: function (color, width) {
this.viewer._rectMark(color, width);
},
/**
* 简单箭头标注(有弹窗)
* @param {function} con 用于获取返回值的回调函数。如 const con = a => {console.log(a)} a为返回值
*
*/
simpleArrowMarkWithPanel: function (con) {
this.viewer.simpleArrowMark(con);
},
/**
* 简单箭头标注(无弹窗)
* @param {*} color 颜色 #ffffff(str)
* @param {*} width 线宽 线的粗细(单位像素)
*/
simpleArrowMark: function (color, width) {
this.viewer._simpleArrowMark(color, width);
},
/**
* @description: 正多边形标注(有弹窗)
* @param {type} con 用于获取返回值的回调函数。如 const con = a => {console.log(a)} a为返回值
* @return:
*/
regularPolygonMarkWithPanel: function (con) {
this.viewer.regularPolygonMark(con);
},
/**
* @description: 正多边形标注(无弹窗)
* @param {*} color 颜色 #ffffff(str)
* @param {*} width 线宽 线的粗细(单位像素)
* @param {*} segments 边数 线的粗细(单位像素)
* @return:
*/
regularPolygonMark: function (color, width, segments) {
this.viewer._regularPolygonMark(color, width, segments);
},
/**
* @description: 任意多边形标注(有弹窗)
* @param {type} con 用于获取返回值的回调函数。如 const con = a => {console.log(a)} a为返回值
* @return:
*/
polygonMarkWithPanel: function (con) {
this.viewer.polygonMark(con);
},
/**
* @description: 任意多边形标注(无弹窗)
* @param {*} color 颜色 #ffffff(str)
* @param {*} width 线宽 线的粗细(单位像素)
* @return:
*/
polygonMark: function (color, width) {
this.viewer._polygonMark(color, width);
},
/**
* 文字标注
* @param {*} text 文字内容 str
* @param {*} color 文字颜色 例如:#ffffff(str)
* @param {*} bgColor 背景颜色 例如:#ffffff(str)
* @param {*} fontSize 字体大小 int
* @param {*} lineWidth 标注宽度(行宽)int
*/
textMark: function (text, color, bgColor, fontSize, lineWidth) {
this.viewer.textMark(text, color, bgColor, fontSize, lineWidth);
},
/**
* 退出标注
*/
endMark: function () {
this.viewer.endMark();
},
/**
* 获取选中标注信息
*/
getSelectMarkInfo: function () {
return this.viewer.bimMark.getSelectMarkInfo();
},
// ToDO
/**
* 设置标注 除文字标注外的其他所有标注
* @param {*} color 颜色 #ffffff(str)
* @param {*} width 线宽 线的粗细(单位像素)
*/
setSelectMark: function (color, width) {
this.viewer.bimMark.setSelectMark(color, width);
},
/**
* 设置文字标注
* @param {*} text 文字内容 str
* @param {*} color 文字颜色 例如:#ffffff(str)
* @param {*} bgColor 背景颜色 例如:#ffffff(str)
* @param {*} fontSize 字体大小 number
* @param {*} lineWidth 标注宽度(行宽) number
*/
setSelectText: function (text, color, bgColor, fontSize, lineWidth) {
this.viewer.bimMark.setSelectText(
text,
color,
bgColor,
fontSize,
lineWidth
);
},
/**
* 获取面片
*/
getModelInfo: function () {
return this.viewer.getModelInfo();
},
/**
* 炸开
* @param {*} offset 偏移倍数 number 一般设为1
* @param {*} time 时间 number 毫秒计 1000为1秒
* @param {number} 系数取0-1的值。当time为0时候,该值有效。
*/
explodeModels: function (offset, time, factor) {
this.viewer.explodeModels(offset, time, factor);
},
/**
* 炸开归位
*/
backHomeModels: function () {
this.viewer.backHomeModels();
},
/**
* 剖切模型
*/
sliceModel: function () {
this.viewer.sliceModel();
},
/**
* 沿着X方向加1
*/
addCapX: function () {
this.viewer.addCapX();
},
/**
* 沿着X方向减1
*/
subCapX: function () {
this.viewer.subCapX();
},
/**
* 沿着Y方向加1
*/
addCapY: function () {
this.viewer.addCapY();
},
/**
* 沿着Y方向减1
*/
subCapY: function () {
this.viewer.subCapY();
},
/**
* 沿着Z方向加1
*/
addCapZ: function () {
this.viewer.addCapZ();
},
/**
* 沿着Z方向减1
*/
subCapZ: function () {
this.viewer.subCapZ();
},
/**
* 退出剖切
*/
cancleSliceModel: function () {
this.viewer.cancleSliceModel();
},
/**
* 设置模型的纹理
* @param {*} object 需操作的模型对象
* @param {*} path 纹理路径
*/
setModelTexture: function (object, path) {
this.viewer.setModelTexture(object, path);
},
/**
* @param {*} object 需操作的模型对象
* 恢复模型之前的纹理状态
*/
resetModelTexture: function (object) {
this.viewer.resetModelTexture(object);
},
/**
* 设置模型是否闪烁
* @param {*} object 需操作的模型对象,支持传入数组。
* @param {*} color 颜色 0xffffff 十六进制
* @param {*} time 间隔时间 number
*/
setModelFlicker: function (object, color, time) {
this.viewer.setModelFlicker(object, color, time);
},
/**
* 取消闪烁
* @param {*} object 需操作的模型对象,支持传入数组。传入''表示清除所有闪烁。
* 注意:当调用removeFile文件时,请先调用stopModelFlicker接口,移除闪烁,否则会造成内存泄漏。
*/
stopModelFlicker: function (object) {
this.viewer.stopModelFlicker(object);
},
/**
* 点测量 激活点测量状态 传入isOnlyZ true 为高程测量 undefined为点测量
*/
measurePoint: function (isOnlyZ) {
this.viewer.measurePoint(isOnlyZ);
},
/**
* 点点测量 激活点点测量状态
*/
measurePtop: function () {
this.viewer.measurePtop();
},
/**
* 边点测量 激活边点测量状态
*/
measureLtop: function () {
this.viewer.measureLtop();
},
/**
* @description: 面点测量 激活面点测量状态
* @param {type}
* @return:
*/
measureFtop: function () {
this.viewer.measureFtop();
},
/**
* @description: 边边测量 激活面点测量状态
* @param {type}
* @return:
*/
measureLtol: function () {
this.viewer.measureLtol();
},
/**
* @description: 三点角度测量 激活三点角度测量
* @param {type}
* @return:
*/
measureAngleByPoints: function () {
this.viewer.measureAngleByPoints();
},
/**
* @description: 体积测量。调用endMeasure结束。
* @return: 无。
*/
measureVolume: function () {
this.viewer.measureVolume();
},
/**
* @description: 面积测量 。调用endMeasure结束。
* @return: 无。
*/
measureArea: function () {
this.viewer.measureArea();
},
/**
* 计算体积。
* @param {string} id 需要计算体积的模型id。
*/
computeVolume: function (id) {
return this.viewer.computeVolume(id);
},
/**
* 退出测量状态
*/
endMeasure: function () {
this.viewer.endMeasure();
},
/**
* @description: 配置测量
* @param {type} Object类型
* {boardFill:[177,201,237],数值面板填充色
boardStroke:[221,221,221],数值面板描边色
textStroke:[255,255,255],数值颜色
hoverPointColor:[255,0,0],测量时顶点选中颜色
selectPointColor:[255,255,0],测量点确认后、测量时顶点未选中颜色
hoverLineColor:[255,0,0],测量边未选择颜色
selectLineColor:[255,255,0],测量边确认后颜色
lineColor:[255,255,255],虚线颜色
boardFont:'宋体',数值面板字体
可传undefined,默认如上
* @return:
*/
setMeasureColor: function (object) {
this.viewer.setMeasureColor(object);
},
/**
* 删除视点
*/
deleteViewPoint: function () {
this.viewer.deleteViewPoint();
},
/**
* 删除选中标注
*/
deleteSelectMark: function () {
this.viewer.bimMark.deleteSelectMark();
},
/**
* 设置背景及描边颜色(弹窗)
* @param {function} con 用于获取返回值的回调函数。如 const con = a => {console.log(a)} a为返回值
* @param {String} backgroundColorA 背景色上
* @param {String} backgroundColorB 背景色下
* @param {String} lineColor 描边高亮颜色
* @param {String} faceColor 面高亮颜色
* @param {Boolean} switchFace 是否高亮面
* @param {Boolean} switchLight 是否有描边
*/
setBackgroundAndOutLine: function (con) {
this.viewer.setBackgroundAndOutLine(con);
},
/**
* 初始化背景及描边颜色的弹窗
* @param {Object} obj {backgroundColorA: "#ffc000", backgroundColorB: "#123456", lineColor: "#009789", faceColor: "#ffffff", switchFace:true, switchLight: false, switchAO : false, switchShadow : false}
*
*/
setInitBackAndOutlineColor: function (obj) {
this.viewer.setInitBackAndOutlineColor(obj);
},
//清空标注
disposeMark: function () {
this.viewer.disposeMark();
},
/**
* 设置环境光、色
* @param {*} color 默认颜色0xffffff(不设置颜色传undefined)
* @param {*} intensity 默认强度0.5
*/
setAmbientLight: function (color, intensity) {
this.viewer.setAmbientLight(color, intensity);
},
/**
* 设置相机光、色
* @param {*} color 默认颜色0xffffff(不设置颜色传undefined)
* @param {*} intensity 默认强度0.25
*/
setCameraLight: function (color, intensity) {
this.viewer.setDirectionalLight(color, intensity);
},
/**
* 根据时间设置光,该光照影响阴影。
* @param {boolean} visible 根据开启太阳光
* @param {number} time 时间值,取值范围为0-24。
* @param {number} color 默认颜色0xffffff(不设置颜色传undefined)
* @param {number} intensity 光照强度,默认强度为0.25
*/
setSunLightByTime: function (visible, time, color, intensity) {
this.viewer.setSunLightByTime(visible, time, color, intensity);
},
/**
* 设置阴影,当enbale传true时会开启SunLight。
* @param {*} enable 是否开启阴影,true为开启,false为关闭。当不传值时候关闭阴影。
* @param {*} ignoreSetCast 是否忽略setModelCastShadow接口配置的值,true为忽略,false为不忽略。当不传该值时,setModelCastShadow接口配置有效。
* @param {*} ingorSetReceive 是否忽略setModelReceiveShadow接口配置的值,true为忽略,false为不忽略。当不传该值时,setModelReceiveShadow接口配置有效。
*/
setShadow: function (enable, ignoreSetCast, ingorSetReceive) {
this.viewer.setShadow(enable, ignoreSetCast, ingorSetReceive);
},
/**
* 设置模型是否能投射出阴影。显示模型阴影在别的模型上。
* @param {*} ids 需要设置的模型id。支持传入数组。
* @param {*} enable 是否开启,true为开启,false为不开启。
* @param {*} option 操作类型,传入0表示对传入的对象进行操作。传入1表示对传入的对象之外的对象进行操作。
*/
setModelCastShadow: function (ids, enable, option) {
this.viewer.setModelCastShadow(ids, enable, option);
},
/**
* 设置模型是否能接受别的模型阴影。在模型上显示别的模型的阴影。
* @param {*} ids 需要设置的模型id。支持传入数组。
* @param {*} enable 是否开启,true为开启,false为不开启。
* @param {*} option 操作类型,传入0表示对传入的对象进行操作。传入1表示对传入的对象之外的对象进行操作。
*/
setModelReceiveShadow: function (ids, enable, option) {
this.viewer.setModelReceiveShadow(ids, enable, option);
},
/**
* 是否使用遮蔽效果,该效果会使模型更有层次感,但是会对渲染效率有影响。
* @param {boolean} enable true开启,false关闭。默认关闭。
*/
setEffectOcclusion: function (enable) {
this.viewer.setEffectOcclusion(enable);
},
/**
* 根据id来zoomfit 不传参数就是重置视口
* @param {*} id 模型对象id 可是string数组
* @param {*} factor 距离因子
*/
zoomFit: function (id, factor) {
this.viewer.zoomFit(id, factor);
},
/**
* 设置选中高光颜色和强度
* @param {*} color 默认0x0000ff
* @param {*} intensity 默认1
*/
setSelectColorIntensity: function (color, intensity) {
this.viewer.setSelectColorIntensity(color, intensity);
},
//更改描边颜色
setOutLineColor: function (color) {
this.viewer.setOutLineColor(color);
},
/**
* 高亮边开关
* @param {*} bool bool变量 true打开,false关闭
*/
setHighlightedLine: function (bool) {
this.viewer.setHighlightedLine(bool);
},
/**
* 高亮面开关
* @param {*} bool bool变量 true打开,false关闭
*/
setHighlightedFace: function (bool) {
this.viewer.setHighlightedFace(bool);
},
/**
* 设置剖切面移动步长 绝对
* @param {*} unit number 默认为1 单位为m
*/
setCapMoveStepByUnit: function (unit) {
this.viewer.setCapMoveStepByUnit(unit);
},
/**
* @description: 设置点测量偏移点 默认为[0,0,0] 顺序对应xyz
* @param {type} Array
* @return:
*/
setOffsetPoint: function (arr) {
this.viewer.setOffsetPoint(arr);
},
/**
* @description: 反转剖切方向
* @param {type}
* @return:
*/
inverseCap: function () {
this.viewer.inverseCap();
},
/**
* @description: 是否隐藏剖切参考面 (参考面默认是显示状态)
* @param {type} bool true隐藏 false显示 必须处于剖切状态才可调用
* @return:
*/
hiddenCap: function (bool) {
this.viewer.hiddenCap(bool);
},
/**
* @description: 打开剖切盒
* @param {type}
* @return:
*/
startBoxClip: function () {
this.viewer.startBoxClip();
},
/**
* @description: 关闭剖切盒
* @param {type}
* @return:
*/
endBoxClip: function () {
this.viewer.endBoxClip();
},
/**
* @description: 是否隐藏剖切参考面操作轴 (参考面操作轴默认是显示状态)
* @param {type} bool true隐藏 false显示 必须处于剖切状态才可调用
* @return:
*/
hiddenCapGizmo: function (bool) {
this.viewer.hiddenCapGizmo(bool);
},
/**
* 根据传入数据实例化模型。
* @param {*} modelValue 模型参数。
* 参数格式为json对象
{
"asset":[
{"file":"文件路径","id":"实例id","matrix":[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]},
{...}
]
}
* @param {*} callback 回调方法,在加载完该次所有加载的模型后调用该回调,回调方法参数为callbackValue传入的值,如果没值则返回undefined。
* @param {*} callbackValue 回调方法参数。在处理完改次所有数据后,如果传入回调方法,则在回调方法参数里传入该值。
*/
instanceModel: function (modelValue, callback, callbackValue) {
this.viewer.instanceModel(modelValue, callback, callbackValue);
},
/**
* 移除实例化的模型。
* @param {*} ids 需要移除的模型id,根据instanceModel第一参数传入的id值。可传单个字符串以及字符串数组。
*/
removeInstanceModel: function (ids) {
this.viewer.removeInstanceModel(ids);
},
/**
* @description: 碰撞检测
* @param {type} Array id数组 collisionDetectionByIds(['idString',...],['idString',...]) 如果idArr2为undefined 则在idArr1内互相检测
* @return: Array 相互碰撞的对象数组[{id1:idString,id2:idString},...]
*/
collisionDetectionByIds: function (idArr1, idArr2) {
return this.viewer.collisionDetectionByIds(idArr1, idArr2);
},
/**
* @description: 碰撞检测异步执行
* @param {type} Array id数组 collisionDetectionByIds(['idString',...],['idString',...]) 如果idArr2为undefined 则在idArr1内互相检测 callback 回调
* @return:
*/
collisionDetectionByIdsAsync: function (idArr1, idArr2, callback) {
this.viewer.collisionDetectionByIdsAsync(idArr1, idArr2, callback);
},
/**
* @description: 设置碰撞显示效果 即颜色(注:全选)
* @param {type} color 0xffffff 十六进制 number
* @return:
*/
setCollisionDetectionColor: function (color1, color2) {
this.viewer.setCollisionDetectionColor(color1, color2);
},
/**
* @description: 设置碰撞显示效果 即颜色(注:根据id) 如果是全部设置 使用setCollisionDetectionColor以节约开销
* @param {type} ids 可以是单个id字符串 也可以是多个id字符串数组 color 0xffffff 十六进制 number
* @return:
*/
setCollisionDetectionColorByIds: function (ids, color) {
this.viewer.setCollisionDetectionColorByIds(ids, color);
},
/**
* @description: 清除碰撞显示效果 即颜色
* @param {type}
* @return:
*/
clearCollisionDetectionColor: function () {
this.viewer.clearCollisionDetectionColor();
},
/**
* @description: 开始漫游 返回1开始漫游成功 返回2已处于漫游状态 返回0不成功(下方50m内未检测到模型) 如果传入cm_pos则根据指定视点进入否则根据当前视点
* @param {String} cm_pos 视点的cm_pos 例如viewer.startRoaming(viewpoint.cameras.cm_pos)
* @return:
*/
startRoaming: function (cm_pos) {
return this.viewer.startRoaming(cm_pos);
},
/**
* @description: 开始漫游
* @param {type}
* @return:
*/
endRoaming: function () {
this.viewer.endRoaming();
},
/**
* @description: 设置漫游移动速度 倍数
* @param {type}
* @return:
*/
setRoamingMoveSpeed: function (times) {
this.viewer.setRoamingMoveSpeed(times);
},
/**
* @description: 设置漫游旋转速度 倍数
* @param {type}
* @return:
*/
setRoamingRotateSpeed: function (times) {
this.viewer.setRoamingRotateSpeed(times);
},
/**
* @description: 设置漫游跳跃速度 倍数
* @param {type}
* @return:
*/
setRoamingJumpSpeed: function (times) {
this.viewer.setRoamingJumpSpeed(times);
},
/**
* @description: 切换第一/三人称
* @param {type}
* @return:
*/
switchRoamingMode: function () {
this.viewer.switchRoamingMode();
},
/**
* @description: 使用worker 进行一组碰撞检测
* @param {type} idArr id数组
* @param {type} callback(result) 回调 碰撞检测结束后执行 返回[{id1:id1,id2:id2},...]互相碰撞的id对
* @param {type} progress(progress) 回调 碰撞检测进行时执行 进度回调
* @return:
*/
collisionDetectionByIdsWorker: function (idArr, callback, progress) {
this.viewer.collisionDetectionByIdsWorker(idArr, callback, progress);
},
/**
* @description: 使用worker 进行两组碰撞检测
* @param {type} idArr id数组
* @param {type} callback(result) 回调 碰撞检测结束后执行 返回[{id1:id1,id2:id2},...]互相碰撞的id对
* @param {type} progress(progress) 回调 碰撞检测进行时执行 进度回调
* @return:
*/
collisionDetectionByIdsWorker2: function (
idArr1,
idArr2,
callback,
progress
) {
this.viewer.collisionDetectionByIdsWorker2(
idArr1,
idArr2,
callback,
progress
);
},
/**
* @description: 传入bool值来控制是否更新
* @param {type} 布尔
* @return:
*/
enableRender: function (bool) {
this.viewer.enableRender(bool);
},
/**
* 设置摄像机进入模型内部的最短距离。
* @param {number} distance 穿入模型的最短距离。大场景建议0.5,小场景建议0.005即可。根据用户自定义适配。
*/
setMinEnterDistance: function (distance) {
this.viewer.setMinEnterDistance(distance);
}
};
// export {BIM3DInterface};
\ No newline at end of file
// 开发环境
const VUE_APP_BASE_API = 'http://119.91.70.186:9002' // eslint-disable-line
// const VUE_APP_BASE_API = 'http://119.91.70.186:9002' // eslint-disable-line
// 测试环境
const VUE_APP_BASE_API = 'http://218.75.209.68:9002' // eslint-disable-line
// 生产环境
// const VUE_APP_BASE_API = 'http://218.75.209.68:9351' // eslint-disable-line
// 本地
......
......@@ -19,9 +19,6 @@
</noscript>
<div id="app"></div>
<script src="apiUrl.js"></script>
<script src="newVisualizing/visualizing/BIM3DInterface.js"></script>
<script src="newVisualizing/visualizing/BIM3DViewer.js"></script>
<script src="newVisualizing/visualizing/lic.js"></script>
<!-- built files will be auto injected -->
</body>
......
// store.js
const state = {
// 需要隐藏的
TODOTITLE: [
// '数据发放任务',
// '更改贯彻监控任务',
// 'ICD签审任务',
// '资源库数据签审任务',
// '基线签审任务',
// // '技术文件传阅任务',
// '试验签审任务',
// '管理文件传阅任务'
],
// 需要展示的
TODOLIST: [
'实物部件',
'技术文件',
'技术协调单',
'设计技术文件更改通告',
'设计图档文件更改通告',
'装配方案',
'MBOM顶层更改包',
'A类工作包',
'B类工作包',
'PBOM顶层件',
'设计更改请求',
'设计更改通告',
'供应商更改单',
'管理体系文件'
]
}
export default {
namespaced: true,
state
}
/**
* @Description: 受影响数据
* @author xioln
* @date 2022-06-10
* @FilePath: src/views/BomTreeDetail/components/affectedData.vue
*/
<template>
<div class="affected-data">
<van-row>
<van-col
v-if="
Object.keys(affectedData).length !== 0 ||
Object.keys(affectedAIData).length !== 0
"
span="24"
class="van-col-class"
>
<van-cell
v-show="affectedData.length !== 0"
is-link
v-for="(item, i) in affectedData"
:key="i"
@click="cellClick(item)"
>
<template #title>
<van-col span="24">
<span class="van-col-span">编号</span>
<b>
{{ item.changeable.number }}
</b>
<div style="float: right">
<van-tag color="#1989fa" class="van-col-span-right">{{
item.state
}}</van-tag>
</div>
</van-col>
<van-col span="24">
<span class="van-col-span">名称</span>
<b>{{ item.changeable.name }}</b>
</van-col>
<van-col span="24">
<span class="van-col-span">版本</span>
<b
><van-tag color="#1989fa" class="van-col-span-right">{{
item.version
}}</van-tag></b
>
</van-col>
<van-col span="24">
<span class="van-col-span">修改时间</span>
<b>{{ item.modifyTime }}</b>
</van-col>
<van-col span="24">
<span class="van-col-span">修改者</span>
<b>{{ item.modifier }}</b>
</van-col>
<van-col span="24">
<span class="van-col-span">备注</span>
<b>{{ item.comment }}</b>
</van-col>
</template>
<template #right-icon>
<van-icon name="arrow" class="search-icon center" />
</template>
</van-cell>
<van-cell
v-show="affectedAIData.length !== 0"
is-link
v-for="(item, i) in affectedAIData"
:key="i"
@click="cellClick(item)"
>
<template #title>
<van-col span="24">
<span class="van-col-span">编号</span>
<b>{{ item.label ? item.label : item.number.label }}</b>
</van-col>
<van-col span="24">
<span class="van-col-span">名称</span>
<b>{{ item.name }}</b>
</van-col>
<van-col span="24">
<span class="van-col-span">版本</span>
<b
><van-tag color="#1989fa" class="van-col-span-right">{{
item.version
}}</van-tag></b
>
</van-col>
<van-col span="24">
<span class="van-col-span">设计者</span>
<b>{{ item.creator }}</b>
</van-col>
</template>
<template #right-icon>
<van-icon name="arrow" class="search-icon center" />
</template>
</van-cell>
</van-col>
<van-col v-else span="24" class="van-col-class">
<van-empty description="受影响数据为空" />
</van-col>
</van-row>
</div>
</template>
<script>
import moment from 'moment'
export default {
name: 'affectedData', // name写在组件的最前方,自定义组件为必填
props: {
affectedData: {
type: [Array, Object],
default: () => {
return {}
}
},
affectedAIData: {
type: [Array, Object],
default: () => {
return {}
}
}
},
data () {
return {}
},
watch: {
affectedAIData (v) {
console.log(v)
}
},
computed: {},
created () {},
methods: {
cellClick (item) {
const id = item?.number?.oid ?? item.changeable.id
const dxClassName = item?.changeable?.dxClassname
const subTypeName = item?.changeable?.subTypeName
this.$router.push({
path: `/bomTreeDetail-${id}`,
query: {
oid: id,
title: 'EBOM',
subTypeName: subTypeName,
dxClassName: dxClassName,
time: moment().valueOf()
}
})
}
}
}
</script>
<style lang='scss' scoped>
.van-icon-arrow:before {
position: absolute;
transform: translate(-50%, 50%);
}
.van-cell:active {
background: rgb(161, 47, 47);
}
</style>
/**
* @Description: 相关文档
* @author xioln
* @date 2022-07-01
* @FilePath: src/views/BomTreeDetail/components/bindArticle.vue
*/
<template>
<div class="bind-article">
<van-collapse v-model="active" accordion @change="collapseChange">
<van-collapse-item title="交付规范书" name="getDeliverySpecDocRows">
<van-row>
<van-col
v-if="deliveryTableData.length !== 0"
span="24"
class="van-col-class"
>
<van-cell
is-link
v-for="item in deliveryTableData"
:key="item.name"
>
<template #title>
<van-col span="24">
<van-tag type="primary"
>编号:{{ item.number.label }}
</van-tag>
</van-col>
<van-col span="24">
<van-tag type="primary">名称:{{ item.name }} </van-tag>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">版本</van-col>
<van-col span="14" offset="1">{{ item.version }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">供应商</van-col>
<van-col span="14" offset="1">{{ item.supplier }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">工艺有效性</van-col>
<van-col span="14" offset="1">{{
item.effectiveness
}}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">状态</van-col>
<van-col span="14" offset="1">{{ item.state }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">修改者</van-col>
<van-col span="14" offset="1">{{ item.modifier }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">上次修改时间</van-col>
<van-col span="14" offset="1">{{
item.lastModifyTime
}}</van-col>
</van-col>
</template>
<template #right-icon>
<!-- <van-icon name="arrow"/> -->
</template>
</van-cell>
</van-col>
<van-col span="24" v-else>
<van-empty description="数据为空" />
</van-col>
</van-row>
</van-collapse-item>
<van-collapse-item title="SPSPOM" name="getSPSBOMRows">
<van-row>
<van-col
v-if="spsbomTableData.length !== 0"
span="24"
class="van-col-class"
>
<van-cell is-link v-for="item in spsbomTableData" :key="item.name">
<template #title>
<van-col span="24">
<van-tag type="primary"
>编号:{{ item.number.label }}
</van-tag>
</van-col>
<van-col span="24">
<van-tag type="primary">名称:{{ item.name }} </van-tag>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">版本</van-col>
<van-col span="14" offset="1">{{ item.version }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">工艺有效性</van-col>
<van-col span="14" offset="1">{{
item.effectiveness
}}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">状态</van-col>
<van-col span="14" offset="1">{{ item.state }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">修改者</van-col>
<van-col span="14" offset="1">{{ item.modifier }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">上次修改时间</van-col>
<van-col span="14" offset="1">{{
item.lastModifyTime
}}</van-col>
</van-col>
</template>
<template #right-icon>
<!-- <van-icon name="arrow"/> -->
</template>
</van-cell>
</van-col>
<van-col span="24" v-else>
<van-empty description="数据为空" />
</van-col>
</van-row>
</van-collapse-item>
<van-collapse-item
title="工作包SPSBOM历史记录"
name="getWorkPackageSpsbomHistory"
>
<van-row>
<van-col
v-if="spsbomHistoryTableData.length !== 0"
span="24"
class="van-col-class"
>
<van-cell
is-link
v-for="item in spsbomHistoryTableData"
:key="item.name"
>
<template #title>
<van-col span="24">
<van-col class="van-col-span" span="10">工作包编号</van-col>
<van-col span="14" offset="1">{{
item.workPackageNumber.label
}}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">工作包名称</van-col>
<van-col span="14" offset="1">{{
item.workPackageName
}}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">工作包版本</van-col>
<van-col span="14" offset="1">{{
item.workPackageVer
}}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">编号</van-col>
<van-col span="14" offset="1">{{
item.spsboms.length > 0 ? item.spsboms[0].number.label : ""
}}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">名称</van-col>
<van-col span="14" offset="1">{{
item.workPackageName
}}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">版本</van-col>
<van-col span="14" offset="1">{{
item.spsboms.length > 0
? item.spsboms[0].version
: ""
}}</van-col>
</van-col>
</template>
<template #right-icon>
<!-- <van-icon name="arrow"/> -->
</template>
</van-cell>
</van-col>
<van-col span="24" v-else>
<van-empty description="数据为空" />
</van-col>
</van-row>
</van-collapse-item>
</van-collapse>
</div>
</template>
<script>
import {
getDeliverySpecDocRows,
getSPSBOMRows,
getWorkPackageSpsbomHistory
} from '@/api/taskDetail'
export default {
name: 'AindArticle', // name写在组件的最前方,自定义组件为必填
components: {},
props: {
oid: {
type: String,
require: true
}
},
data () {
return {
active: 'getDeliverySpecDocRows',
cellData: [],
parmas: {},
deliveryTableData: [],
spsbomTableData: [],
spsbomHistoryTableData: []
}
},
computed: {},
created () {},
mounted () {
this.parmas = this.$utils.formDataParams({
oid: this.oid
})
this.getDeliverySpecDocRows()
},
methods: {
collapseChange (v) {
if (v) {
this[v]()
}
},
getDeliverySpecDocRows () {
getDeliverySpecDocRows(this.parmas).then((res) => {
this.deliveryTableData = res.items
})
},
getSPSBOMRows () {
getSPSBOMRows(this.parmas).then((res) => {
this.spsbomTableData = res.items
})
},
getWorkPackageSpsbomHistory () {
getWorkPackageSpsbomHistory(this.parmas).then((res) => {
console.log('res', res)
this.spsbomHistoryTableData = res.items
})
}
}
}
</script>
<style lang='scss'>
.bind-article {
padding: 0 10px;
.van-collapse-item__content {
padding: 0;
}
.van-col-span {
width: 120px;
font-weight: bold;
}
.van-cell {
margin-right: 0;
}
}
</style>
/**
* @Description: 自制件相关文档
* @author xioln
* @date 2022-07-02
* @FilePath: src/views/BomTreeDetail/components/bindArticleCreatedSelf.vue
*/
<template>
<div class="bindArticle-createdSelf">
<van-collapse v-model="active" accordion @change="collapseChange">
<van-collapse-item title="CAD文档" name="picDocInformation">
<van-row>
<van-col v-if="picsData.length !== 0" span="24" class="van-col-class">
<van-cell is-link v-for="item in picsData" :key="item.key">
<template #title>
<van-col span="24">
<van-col class="van-col-span" span="10">编号</van-col>
<van-col span="14" offset="1">{{
item.serialNumber
}}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">文件名称</van-col>
<van-col span="14" offset="1">{{ item.docName }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">版本</van-col>
<van-col span="14" offset="1">{{ item.version }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">状态</van-col>
<van-col span="14" offset="1">{{ item.status }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">上次修改时间</van-col>
<van-col span="14" offset="1">{{ item.modifyTime }}</van-col>
</van-col>
</template>
<template #right-icon>
<!-- <van-icon name="arrow"/> -->
</template>
</van-cell>
</van-col>
<van-col span="24" v-else>
<van-empty description="数据为空" />
</van-col>
</van-row>
</van-collapse-item>
<van-collapse-item title="技术文件" name="getDocumentation">
<van-row>
<van-col v-if="docsData.length !== 0" span="24" class="van-col-class">
<van-cell is-link v-for="item in docsData" :key="item.key">
<template #title>
<van-col span="24">
<van-col class="van-col-span" span="10">编号:</van-col>
<van-col span="14" offset="1">{{ item.number }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">名称:</van-col>
<van-col span="14" offset="1">{{ item.name }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">版本</van-col>
<van-col span="14" offset="1">{{ item.version }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">状态</van-col>
<van-col span="14" offset="1">{{ item.state }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">上次修改时间</van-col>
<van-col span="14" offset="1">{{ item.modifyTime }}</van-col>
</van-col>
</template>
<template #right-icon>
<!-- <van-icon name="arrow"/> -->
</template>
</van-cell>
</van-col>
<van-col span="24" v-else>
<van-empty description="数据为空" />
</van-col>
</van-row>
</van-collapse-item>
</van-collapse>
</div>
</template>
<script>
import { getPictureDocument } from '@/api/taskDetail'
import { adddoc } from '@/api/design'
import moment from 'moment'
export default {
name: 'BindArticleCreatedSelf', // name写在组件的最前方,自定义组件为必填
props: {
oid: {
type: String,
require: true
}
},
components: {},
data () {
return {
active: 'picDocInformation',
picsData: [],
docsData: []
}
},
computed: {},
created () {
// 初始化数据
this.picDocInformation()
},
methods: {
collapseChange (v) {
if (v) {
this[v]()
}
},
// 获取CAD图档
picDocInformation () {
this.docLoading = true
getPictureDocument(this.oid).then((res) => {
this.picsData = []
if (res.code === 0 && res.items.length > 0) {
this.partDataStructure(res.items)
}
})
},
partDataStructure (res) {
res.forEach((doc) => {
this.picsData.push({
partId: this.oid,
dxClassname: doc.dxClassname,
subTypeName: doc.subTypeName,
cadId: doc.id,
serialNumber: doc.number,
name: doc.name,
docName: doc.cadName,
version: doc.versionId + '.' + doc.iterationId,
status: doc.state.display,
modifyTime: moment(doc.modifyTime).format('YYYY-MM-DD HH:mm:ss'),
show: true
})
})
},
getDocumentation () {
this.cadLoading = true
adddoc(this.oid).then((docs) => {
this.docsData = []
this.docsDataStructure(docs.items.docList)
})
},
docsDataStructure (res) {
res.forEach((doc) => {
this.docsData.push({
oid: doc.id,
number: doc.number,
name: doc.name,
docName: doc.cadName,
version: doc.versionId + '.' + doc.iterationId,
state: doc.state.display,
modifyTime: moment(doc.modifyTime).format('YYYY-MM-DD HH:mm:ss'),
show: true,
link: true
})
})
}
}
}
</script>
<style lang='scss'>
.bindArticle-createdSelf {
padding: 0 10px;
.van-collapse-item__content {
padding: 0;
}
.van-col-span {
width: 120px;
font-weight: bold;
}
.van-cell {
margin-right: 0;
}
}
</style>
/**
* @Description: 可视化
* @author xioln
* @date 2022-11-29
* @FilePath: src/views/BomTreeDetail/components/ebomTree.vue
*/
<template>
<div ref="tabPanel" class="ebom-tree">
<float-button @onFloatBtnClicked="onFloatBtnClicked" />
<color-picker
ref="colorPicker"
v-model="color1"
style="display: none"
color-format="rgb"
@change="getColor"
/>
<div id="webglcontain" ref="webglcontain" class="ThreeDViewer">
<div class="three_head">
<div
v-for="(item, index) in mainUrl"
:key="index"
class="out-wrap"
@click="showSubmenu(item)"
>
<!-- <el-tooltip class="item" effect="dark" :content="item.name" placement="top-start"> -->
<img class="title" :src="item.url" style="cursor: pointer" />
<p>{{ item.name }}</p>
<!-- </el-tooltip> -->
</div>
</div>
<div
v-if="submenuData && submenuData.eveUrl && submenuData.eveUrl.length"
class="main_function"
>
<div class="submenu-box">
<div
v-for="(item1, index1) in submenuData.eveUrl"
:key="index1"
@click="mainView(item1.func)"
>
<img
class="function_each child_img"
:src="item1.url"
style="cursor: pointer"
/>
<p>{{ item1.name }}</p>
</div>
</div>
</div>
</div>
<van-action-sheet v-model="treeOrDxpart3d" @opened="init" title="模型树">
<div v-if="treeData.length === 0">
<van-loading v-if="showLoading" type="spinner" size="24px" vertical />
<van-empty v-else description="模型树数据为空" />
</div>
<tree
id="tree"
ref="tree"
v-else
:empty-text="text"
show-checkbox
:data="treeData"
:props="defaultProps"
node-key="targetId"
:highlight-current="true"
:default-expand-all="true"
:expand-on-click-node="false"
@node-click="handleNodeClick"
@check="checkNode"
>
<span slot-scope="{ node, data }">
<span>{{ data.label }}</span>
<van-switch
v-if="data.data.hasOwnProperty('hasPMI') && data.data.hasPMI"
v-model="data.checked"
@change="changeSwitch(node, data)"
/>
<!-- <img
v-if="transformState(node)"
class="tree-icon"
src="../../../../public/icons/3DViewer/成功.svg"
style="cursor: pointer"
/> -->
<van-icon v-if="transformState(node)" color="#07c160" size="16" name="certificate" style="vertical-align: bottom;margin-left 5px;"/>
</span>
</tree>
</van-action-sheet>
</div>
</template>
<script>
// import Tree from '@/components/tree/index.vue'
import { Tree, ColorPicker } from 'element-ui'
import { getCadTree, getPmiInfo } from '@/api/taskDetail'
import { downloadFile } from '@/utils/http'
import { Notify } from 'vant'
import floatButton from './float_button'
import { mainUrl } from '@/utils/enum'
export default {
name: 'EbomTree', // name写在组件的最前方,自定义组件为必填
components: { Tree, floatButton, ColorPicker },
modelRelationObjs: ['DxPart'],
directives: {
// 使用局部注册指令的方式
resize: {
// 指令的名称
bind (el, binding) {
// el为绑定的元素,binding为绑定给指令的对象
let width = ''
let height = ''
function isReize () {
const style = document.defaultView.getComputedStyle(el)
if (width !== style.width || height !== style.height) {
binding.value() // 关键
}
width = style.width
height = style.height
}
el.__vueSetInterval__ = setInterval(isReize, 300)
},
unbind (el) {
clearInterval(el.__vueSetInterval__)
}
}
},
props: {
id: {
type: String,
required: true
}
},
data () {
return {
mainUrl,
showPopover: false,
showLoading: false,
webglcontainDom: null,
treeOrDxpart3d: false,
text: '',
treeData: [],
defaultProps: {
children: 'children',
label: 'label'
},
checkedNode: [],
showWebglcontain: false,
submenuData: null,
viewer: null,
disabled: false,
color1: null,
currentModelIds: [],
explode: false,
showOutline: false,
pmiArr: [],
matrixArr: [],
bankSwitch: false,
loadedMatrixArr: []
}
},
computed: {},
mounted () {
// this.initPanel()
this.getCadTree()
this.treeOrDxpart3d = true
},
beforeDestroy () {
if (this.viewer) {
this.viewer.dispose()
this.viewer = null
}
},
methods: {
transformState (node) {
if (node.level === 1) {
return false
} else if (node.isLeaf === true) {
if (node.data.data.visFile && node.data.data.transform) {
return true
}
return false
} else {
return false
}
},
bodyCloseMenus (e) {
const self = this
if (self.bankSwitch === true) {
self.bankSwitch = false
}
},
onFloatBtnClicked () {
this.treeOrDxpart3d = true
},
init () {
// this.initCad()
// this.getCadTree()
},
changeSwitch (node, data) {
if (!node.checked) {
data.checked = false
Notify({ type: 'warning', message: '请先加载模型' })
return
}
if (data.checked) {
this.append(node, data)
} else {
this.remove(data)
}
},
// 添加节点
append (node, data) {
this.loadPMI(data)
const targetId = data.targetId
getPmiInfo(data.data.cadId).then((res) => {
const obj = []
res.items.annotationsRoot.forEach((item) => {
obj.push({
label: item.name,
targetId: item.name + item.index,
data: item,
disabled: true,
children: item.annotationSets
? item.annotationSets.map((anno, index) => {
return {
label: anno.name,
targetId: anno.id,
data: anno,
subTypeName: 'DxAnnotation',
disabled: true
}
})
: []
})
if (item.viewSets) {
obj.push({
label: item.viewSets.name,
targetId: item.viewSets.name + item.viewSets.id,
data: item.viewSets,
disabled: true,
children: item.viewSets.view
? item.viewSets.view.map((view, index) => {
return {
label: view.name,
targetId: view.id,
data: view,
subTypeName: 'DxCapture',
disabled: true
}
})
: []
})
}
})
this.$refs.tree.updateKeyChildren(targetId, obj)
})
},
resize () {
this.viewer && this.resizeCanves()
},
initPanel () {
let tabPane = this.$refs.tabPanel
let i = 0
while (tabPane.className !== 'el-tab-pane' && i < 10) {
tabPane = tabPane.parentElement
i++
}
if (i < 10) {
tabPane.className += ' full-pane'
}
},
initCad () {
if (!this.webglcontainDom) {
this.webglcontainDom = this.$refs.webglcontain
}
// const dom = this.$refs.webglcontain
// const dom = document.getElementById('webglcontain')
// eslint-disable-next-line no-undef
try {
// eslint-disable-next-line no-undef
this.viewer = new BIM3DInterface(this.webglcontainDom, 35, '', {
licenseContent,
wasmURL: '/newVisualizing/visualizing/tools.wasm',
pmiFont: '/newVisualizing/visualizing/PMIFont.ttf'
})
} catch (error) {
console.log(
'ERROR: chrome 浏览器访问 chrome://gpu/ 查看当前环境是否支持 WebGL'
)
}
this.$nextTick(() => {
this.viewer.clearScene() // 先清除当前场景
})
},
getCadTree () {
if (!this.id) {
return
}
this.showLoading = true
getCadTree(this.id)
.then((res) => {
this.showLoading = false
this.treeData = this.filterData([res.items])
this.$nextTick(() => {
this.initCad()
})
// this.getTreeNode(res.items[0].target.id)
})
.catch((e) => {
this.showLoading = false
})
},
filterData (tree) {
const treeData = []
if (tree instanceof Array) {
tree.forEach((item) => {
const obj = {
label: item.number + ' ' + item.name + ' ' + item.displayVersion,
objFileLinks: item.visFile ? item.visFile : '',
transform: item.transform ? item.transform : '',
targetId: this.$utils.GenNonDuplicateID(10) + '_' + (item.cadId ? item.cadId : item.id),
// targetId: (item.cadId ? item.cadId : item.id) + '_' + this.$utils.GenNonDuplicateID(10),
// disabled: !item.sourceCADUsageLinkParents,
disabled: item.children.length !== 0 ? !item.transform : !(item.transform && item.visFile),
data: item
}
// if (treeData.find((x) => x.targetId === obj.targetId)) {
// return true
// }
obj.children = this.filterData(item.children)
treeData.push(obj)
})
}
return treeData
},
checkNode (nodeData, checkedNodes) {
const Node = this.$refs.tree.getNode(nodeData.targetId)
if (!checkedNodes.checkedKeys.includes(nodeData.targetId) && !checkedNodes.halfCheckedKeys.includes(nodeData.targetId)) {
if (nodeData.data.hasPMI) {
this.remove(nodeData)
}
if (Node.isLeaf) {
this.matrixArr = this.matrixArr.filter(x => x.id !== nodeData.targetId)
this.viewer.removeInstanceModel([nodeData.targetId])
} else {
this.removeChildren([nodeData])
}
this.afterInstanceModel()
this.resizeCanves()
} else {
this.loadModel(checkedNodes)
}
},
removeChildren (data) {
data.forEach(item => {
this.matrixArr = this.matrixArr.filter(x => x.id !== item.targetId)
this.viewer.removeInstanceModel([item.targetId])
if (item.children) {
this.removeChildren(item.children)
}
})
},
// 移除节点
remove (data) {
this.$set(data, 'checked', false)
this.$set(data, 'children', [])
this.pmiArr = this.pmiArr.filter(
(x) => x.id !== data.objFileLinks.fileId + '_PMI'
)
this.viewer.removeInstanceModel([data.objFileLinks.fileId + '_PMI'])
},
/** 实例化后做的事情 */
afterInstanceModel () {
// 设置边框
this.getBorder()
// 设置精度
// this.viewer.setMeasureTextDecimalPlaces(6)
// 监听点击事件
this.listenModelClick()
},
/** 监听模型点击事件 */
listenModelClick () {
this.viewer.addSelectObjectCallBack((res) => {
if (res) {
// 点击
this.currentModelIds.push(res.name)
} else {
// 取消点击
this.currentModelIds = []
}
})
},
/** 重置可视化窗口 */
resizeCanves () {
this.$nextTick(() => {
this.viewer.resize()
})
},
/** 模型边框 */
getBorder () {
if (this.viewer) {
this.viewer.setOutlineVisible(true)
}
},
// 加载模型
loadModel (Nodes) {
// if (!this.transformState(Nodes) && Node.checked && Node.level !== 1) {
// this.$refs.tree.setChecked(nodeData.targetId, false)
// this.$utils.showMessageWarning('模型未转换成功!')
// return
// }
const attachments = []
const nodes = Nodes.checkedNodes
this.viewer.clearScene()
this.matrixArr = []
let temp = false
// const fildNames = []
nodes.forEach((currentChecked, cIndex) => {
const Node = this.$refs.tree.getNode(currentChecked.targetId)
if (!this.transformState(Node) && Node.checked && Node.level !== 1) {
return
}
if (this.loadedMatrixArr.find(load => load.id === currentChecked.targetId)) {
this.matrixArr.push(this.loadedMatrixArr.find(load => load.id === currentChecked.targetId))
this.viewer.instanceModel({ asset: this.matrixArr.filter(x => x.file) })
this.afterInstanceModel()
this.resizeCanves()
temp = true
} else {
temp = false
if (currentChecked.objFileLinks && currentChecked.objFileLinks.fileUri) {
attachments.push({
fileUri: currentChecked.objFileLinks.fileUri,
fileName: currentChecked.objFileLinks.fileName
})
if (currentChecked.data.hasPMI) {
attachments.push({
fileUri: currentChecked.data.pmiFile.fileUri,
fileName: currentChecked.data.pmiFile.fileName
})
this.pmiArr.push({
id: currentChecked.targetId + '_PMI',
fileName: currentChecked.data.pmiFile.fileName,
matrix: JSON.parse(currentChecked.transform)
})
}
if (nodes.length === 1 && !currentChecked.transform.length) {
this.matrixArr.push({
id: currentChecked.targetId,
// id: currentChecked.objFileLinks.fileId,
fileName: currentChecked.objFileLinks.fileName,
matrix: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, -28.9471786008458, 1.38537169396519, 0]
})
} else {
if (currentChecked.transform.length > 0) {
this.matrixArr.push({
// id: currentChecked.objFileLinks.fileId,
id: currentChecked.targetId,
fileName: currentChecked.objFileLinks.fileName,
matrix: JSON.parse(currentChecked.transform)
})
}
}
}
}
})
if (temp) return
Notify({ type: 'success', message: '模型加载中,请稍候' })
if (attachments.length > 0) {
attachments.forEach((m) => {
m && downloadFile(`api/documents/attachments/download?fileName='${encodeURIComponent(m.fileName)}'&url=${encodeURIComponent(m.fileUri)}`).then(res => {
const reader = new FileReader()
reader.readAsDataURL(res.data)
const load_file = reader.addEventListener('loadend', () => {
const filedName = this.getFileName(res)
for (let i = 0; i < this.matrixArr.length; i++) {
if (filedName.includes(this.matrixArr[i].fileName)) {
this.matrixArr[i].file = reader.result
}
// matrixArr[i].file = reader.result
}
this.loadedMatrixArr = Array.from(new Set([...this.loadedMatrixArr, ...this.matrixArr]))
this.viewer.instanceModel({ asset: this.matrixArr.filter(x => x.file) })
// this.viewer.appendFile(reader.result, false)
this.afterInstanceModel()
this.resizeCanves()
reader.removeEventListener('loadend', load_file)
})
})
})
}
},
// 加载PMI
loadPMI (data) {
const pmiFile = {
fileName: data.data.pmiFile.fileName,
fileUri: data.data.pmiFile.fileUri
}
downloadFile(
`api/documents/attachments/download?fileName='${encodeURIComponent(
pmiFile.fileName
)}'&url=${encodeURIComponent(pmiFile.fileUri)}`
).then((res) => {
const reader = new FileReader()
reader.readAsDataURL(res.data)
const load_file = reader.addEventListener('loadend', () => {
const filedName = this.getFileName(res)
for (let i = 0; i < this.pmiArr.length; i++) {
if (filedName.includes(this.pmiArr[i].fileName)) {
this.pmiArr[i].file = reader.result
}
}
this.viewer.instanceModel({
asset: this.pmiArr.filter((x) => x.file)
})
this.afterInstanceModel()
})
})
},
getFileName (res) {
let fileName = ''
if (res.headers['content-disposition']) {
fileName = decodeURIComponent(
res.headers['content-disposition'].substring(
res.headers['content-disposition'].indexOf('=') + 1,
res.headers['content-disposition'].indexOf(";filename*=UTF-8''")
)
)
}
return fileName
},
/** 树结构节点选中状态发生改变时 */
handleCheckChanges (nodeData, addOrDelete) {
// console.log('nodeData', nodeData)
},
handleNodeClick (data, node) {
// 高亮PMI #实例化PMI传入的id#pmi自身的id
if (data.targetId && data.subTypeName === 'DxAnnotation') {
Notify({ type: 'success', message: `【${data.label}】正在加载...` })
const pmiId = `#${node.parent.parent.data.targetId}_PMI#${data.targetId}`
this.viewer.setModelSelection([pmiId], false)
}
if (data.subTypeName === 'DxCapture') {
Notify({ type: 'success', message: `【${data.label}】视图已切换` })
// 恢复初始状态
this.viewer.setModelVisible('', true, 1)
// 恢复捕获(带动画)
const _id = this.viewer.createView(
{
Position: data.data.camera.position,
Target: data.data.camera.target,
Up: data.data.camera.up
},
data.data.pmiIds,
data.data.modelIds,
JSON.parse(node.parent.parent.data.transform)
)
this.viewer.restoreView(_id, true, 600) // true:带动画效果
this.viewer.removeView(_id)
}
},
/** 可视化二级菜单 */
showSubmenu (item, spceil) {
if ((item.eveUrl && item.eveUrl.length > 1) || spceil) {
this.submenuData = item
} else {
this.submenuData = null
}
},
/** 鼠标离开,隐藏二级菜单 */
hideSubmenu () {
this.submenuData = null
},
/** 菜单栏比盟视图接口 */
mainView (funcMethods) {
if (!this.viewer) {
Notify({ type: 'warning', message: '请先加载模型' })
return
}
if (funcMethods && this[funcMethods]) {
this[funcMethods]()
}
},
/** 是否选中模型 */
isChekcedModel () {
// 监听点击事件
this.listenModelClick()
if (this.currentModelIds.length === 0) {
Notify({ type: 'warning', message: '请点击选择一个模型' })
return false
}
return true
},
/**
* 视图管理
**/
/** 主视图 */
showMain () {
this.viewer.setStandardView(0)
},
/** 上 */
showTop () {
this.viewer.setStandardView(5)
},
/** 下 */
showBottom () {
this.viewer.setStandardView(6)
},
/** 前 */
showFront () {
this.viewer.setStandardView(1)
},
/** 后 */
showBack () {
this.viewer.setStandardView(2)
},
/** 左 */
showLeft () {
this.viewer.setStandardView(3)
},
/** 右 */
showRight () {
this.viewer.setStandardView(4)
},
/**
* 模型操作
**/
getColor (val) {
if (val) {
const colorArr = val.substring(4, val.length - 1).split(',')
const [red, green, blue] = colorArr
this.viewer.setModelColorByRGB(
this.currentModelIds,
red,
green,
blue,
0
)
}
},
/** 设置模型颜色 */
setModelColorByRGB () {
if (this.isChekcedModel()) {
// 弹出模型颜色选择器
this.$refs.colorPicker.$el.children[0].click()
}
},
/** 恢复模型颜色 */
restoreModelColor () {
if (this.isChekcedModel()) {
this.viewer.restoreModelColor(this.currentModelIds, 0)
}
},
/** 设置透明 */
setModelAlpha () {
if (this.isChekcedModel()) {
this.viewer.setModelAlpha(this.currentModelIds, '0.5', 0)
}
},
/** 取消透明 */
restoreModelAlpha () {
if (this.isChekcedModel()) {
this.viewer.restoreModelAlpha(this.currentModelIds, 0)
}
},
/** 设置模型闪烁 */
setModelFlicker () {
if (this.isChekcedModel()) {
this.viewer.setModelFlicker(this.currentModelIds, 0xffffff, 100)
}
},
/** 取消模型闪烁 */
stopModelFlicker () {
if (this.isChekcedModel()) {
this.viewer.stopModelFlicker(this.currentModelIds)
}
},
/** 居中 */
zoomFit () {
this.viewer.zoomFit()
},
/** 爆炸视图 */
explodeModels () {
if (this.explode) {
this.viewer.backHomeModels()
} else {
this.viewer.explodeModels(2, 500, 0)
}
this.explode = !this.explode
},
/**
* 模型测量
**/
/** 三点线角度 */
measureAngleByPoints () {
this.viewer.measureAngleByPoints()
},
/** 半径测量 */
measureRadius () {
this.viewer.measureRadius()
},
/** 体积测量 */
measureVolume () {
this.viewer.measureVolume()
},
/** 面积测量 */
measureArea () {
this.viewer.measureArea()
},
/** 坐标测量 */
measurePoint () {
this.viewer.measurePoint()
},
/**
* 模型测量
**/
/** 最短距离测量 */
pointToPoint () {
this.viewer.measurePtop()
},
/** 点线测量 */
lineToLine () {
this.viewer.measureLtop()
},
/** 点面测量 */
faceToFace () {
this.viewer.measureFtop()
},
/** 线线测量 */
volumeToVolume () {
this.viewer.measureLtol()
},
/** 取消测量 */
diameterSurveying () {
this.viewer.endMeasure()
},
/**
* 标注
**/
/** 方形标注 */
rectMarkWithPanel () {
this.viewer.rectMarkWithPanel()
},
/** 圆形标注 */
circleMarkWithPanel () {
this.viewer.circleMarkWithPanel()
},
/** 自由圈注 */
polygonMarkWithPanel () {
this.viewer.polygonMarkWithPanel()
},
/** 文字标注 */
textMark () {
this.viewer.textMark('测试文字标注', '#000000', '#eeeeee', 12, 50)
},
/** 箭头标注 */
arrowMarkWithPanel () {
this.viewer.arrowMarkWithPanel()
},
/** 椭圆标注 */
ellipseMarkWithPanel () {
this.viewer.ellipseMarkWithPanel()
},
/** 正多边形标注 */
regularPolygonMarkWithPanel () {
this.viewer.regularPolygonMarkWithPanel()
},
/** 退出标注 */
endMark () {
this.viewer.endMark()
},
/** 删除标注 */
deleteSelectMark () {
this.viewer.deleteSelectMark()
},
/**
*系统配置
**/
setOptionCullingThreshold () {
this.viewer.setOptionCullingThreshold(30)
},
/** 显示/隐藏轮廓 */
setOutlineVisible () {
this.viewer.setOutlineVisible(this.showOutline)
this.showOutline = !this.showOutline
},
/** 设置轮廓颜色 */
setOutlineColor () {
this.viewer.setOutlineColor('#e11313')
},
/** 设置轮廓宽度 */
setOutlineWidth () {
this.viewer.setOutlineWidth(6)
},
/** 设置背景颜色 */
setBackground () {
this.viewer.setBackground('red', 'green')
},
/** 光照设置 */
setAmbientLight () {
this.viewer.setAmbientLight('FFFFFF', 5)
},
/** 标签 */
/** 文字标签 */
setModelTextLabel () {
if (this.isChekcedModel()) {
this.viewer.setModelTextLabel(
this.currentModelIds,
10,
true,
'测试文字标签'
)
}
},
/** 移除文字标签 */
removeModelTextLabelByIDs () {
if (this.isChekcedModel()) {
this.viewer.removeModelTextLabelByIDs(this.currentModelIds)
}
},
/** 图像标签 */
setModelImageLabel () {
if (this.isChekcedModel()) {
this.viewer.setModelImageLabel(
this.currentModelIds,
'http://icons.iconarchive.com/icons/hopstarter/square-flags/32/China-Flag-icon.png',
30,
30
)
}
},
/** 移除图像标签 */
removeModelImageLabelByIDs () {
if (this.isChekcedModel()) {
this.viewer.removeModelImageLabelByIDs(this.currentModelIds)
}
},
/** HTML标签 */
setModelAnyLabel () {
if (this.isChekcedModel()) {
this.viewer.setModelAnyLabel(
this.currentModelIds,
'<p>测试html文字</p>'
)
}
},
/** 移除HTML标签 */
removeModelAnyLabelByIDs () {
if (this.isChekcedModel()) {
this.viewer.removeModelAnyLabelByIDs(this.currentModelIds)
}
},
/**
* 剖切
**/
/** XY剖切 */
clipXY () {
this.viewer.setAxisClip(2)
},
/** YZ剖切 */
clipYZ () {
this.viewer.setAxisClip(0)
},
/** XZ剖切 */
clipXZ () {
this.viewer.setAxisClip(1)
},
/** 平面法线剖切 */
planeNormal () {
this.viewer.startClip(2)
},
/** 直线中点剖切 */
midpointOfLine () {
this.viewer.startClip(1)
},
/** 剖切盒 */
startBoxClip () {
this.viewer.startBoxClip()
},
/** 取消剖切 */
endClip () {
this.viewer.clearClip()
this.viewer.endBoxClip()
}
}
}
</script>
<style lang='scss' scoped>
// @import "../../../styles/webgl.scss";
@import "/newVisualizing/visualizing/index.css";
.ebom-tree {
height: calc(100vh - 190px);
width: 100%;
/deep/.van-switch {
font-size: 12px;
vertical-align: sub;
margin-left: 5px;
}
/deep/.van-action-sheet__content {
min-height: 200px;
padding: 10px 0;
}
/deep/.el-checkbox__input.is-disabled {
display: none;
}
/deep/.el-tree {
font-size: 12px;
}
.ThreeDViewer {
height: 100%;
width: 100%;
background: linear-gradient(rgb(18, 52, 86) 0%, rgb(238, 238, 238) 100%);
#container {
height: 100%;
}
#webglParent {
height: 100%;
background: transparent !important;
}
canvas {
height: 100%;
width: 100%;
}
.three_head {
// background: transparent;
width: 60%;
background: rgba(245, 245, 245, 0.5);
height: 65px;
box-shadow: 0px 4px 8px 0px rgba(0, 0, 0, 0.06);
border: 1px solid rgba(0, 0, 0, 0.06);
padding: 5px 3%;
box-sizing: border-box;
//justify-content: flex-start;
position: absolute;
left: 0;
right: 0;
bottom: 15px;
margin: 0 auto;
z-index: 10;
display: flex;
justify-content: center;
.out-wrap {
width: 50px;
display: flex;
justify-content: center;
flex-wrap: wrap;
img {
display: block;
width: 35px;
height: 35px;
margin: 0 auto;
}
p {
white-space: nowrap;
font-size: 10px;
text-align: center;
-webkit-margin-before: 0;
-webkit-margin-after: 0;
}
}
}
.main_function {
width: 70%;
position: absolute;
left: 0;
right: 0;
bottom: 85px;
margin: 0 auto;
z-index: 10;
background: transparent;
display: flex;
justify-content: center;
.submenu-box {
width: 100%;
// overflow-x: auto;
display: flex;
flex-wrap: wrap;
// justify-content: flex-start;
background: rgba(245, 245, 245, 0.5);
box-shadow: 0px 4px 8px 0px rgba(0, 0, 0, 0.06);
border: 1px solid rgba(0, 0, 0, 0.06);
padding: 6px 5px;
div {
// display: flex;
// justify-content: flex-start;
// flex-direction: column;
width: 33%;
display: inline-block;
margin: 8% 0;
img {
display: block;
width: 35px;
height: 35px;
margin: 0 auto;
}
p {
white-space: nowrap;
font-size: 10px;
text-align: center;
-webkit-margin-before: 0;
-webkit-margin-after: 0;
}
}
div:last-child {
margin-right: 0;
}
}
}
.tree-icon {
height: 16px;
line-height: 16px;
vertical-align: sub;
}
}
}
</style>
/**
* @Description: 可视化
* @author xioln
* @date 2022-06-29
* @FilePath: src/views/BomTreeDetail/components/dxPart3DViewer.vue
*/
<template>
<div ref="tabPanel" class="dx-part3D-viewer">
<div id="webglcontain" ref="viewer" class="ThreeDViewer"></div>
</div>
</template>
<script>
import { downloadFile } from '@/utils/http'
import { Notify } from 'vant'
let viewer = null
export default {
name: 'DxPart3DViewer', // name写在组件的最前方,自定义组件为必填
components: {},
props: {
checkedNode: {
type: Array,
default: () => {
return []
}
}
},
data () {
return {
// viewer: null
}
},
computed: {},
created () {
// 初始化数据
},
mounted () {
if (this.checkedNode.length === 0) {
Notify({ type: 'warning', message: '请勾选模型树节点' })
} else {
this.initCad()
this.clickFun()
this.$parent.checkedNode = []
}
},
methods: {
clickFun () {
const nodes = this.checkedNode
viewer.clearScene()
const matrixArr = []
const attachments = []
nodes.forEach((currentChecked, cIndex) => {
if (
currentChecked.objFileLinks &&
currentChecked.objFileLinks.fileUri
) {
attachments.push({
fileUri: currentChecked.objFileLinks.fileUri,
fileName: currentChecked.objFileLinks.fileName
})
if (nodes.length === 1 && !currentChecked.transform.length) {
matrixArr.push({
id: currentChecked.data.memberLinkId + cIndex,
fileName: currentChecked.objFileLinks.fileName,
matrix: [
1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, -28.9471786008458,
1.38537169396519, 0
]
})
} else {
if (currentChecked.transform.length > 0) {
matrixArr.push({
id: currentChecked.data.memberLinkId + cIndex,
fileName: currentChecked.objFileLinks.fileName,
matrix: JSON.parse(currentChecked.transform)
})
}
}
}
})
attachments.forEach((m) => {
m &&
downloadFile(
`api/documents/attachments/download?fileName='${encodeURIComponent(
m.fileName
)}'&url=${encodeURIComponent(m.fileUri)}`
).then((res) => {
const reader = new FileReader()
reader.readAsDataURL(res.data)
const loadFile = reader.addEventListener('loadend', () => {
const filedName = this.getFileName(res)
for (let i = 0; i < matrixArr.length; i++) {
if (filedName.includes(matrixArr[i].fileName)) {
matrixArr[i].file = reader.result
}
// matrixArr[i].file = reader.result
}
viewer.instanceModel({ asset: matrixArr.filter((x) => x.file) })
// this.viewer.appendFile(reader.result, false )
// this.afterInstanceModel()
this.resizeCanves()
reader.removeEventListener('loadend', loadFile)
})
})
})
},
initCad () {
const dom = this.$refs.viewer
// const dom = document.getElementById('webglcontain')
// eslint-disable-next-line no-undef
viewer = new BIM3DInterface(
dom,
35,
'',
// eslint-disable-next-line no-undef
{ licenseContent, wasmURL: '/visualizing/visualizing65/tools.wasm' },
{ near: 0.001, far: 1000 }
)
this.$nextTick(() => {
viewer.clearScene() // 先清除当前场景
})
window.addEventListener('resize', this.resizeCanves(), false)
this.resizeCanves()
},
/** 重置可视化窗口 */
resizeCanves () {
this.$nextTick(() => {
viewer.resize()
})
},
getFileName (res) {
let fileName = ''
if (res.headers['content-disposition']) {
fileName = decodeURIComponent(
res.headers['content-disposition'].substring(
res.headers['content-disposition'].indexOf('=') + 1,
res.headers['content-disposition'].indexOf(";filename*=UTF-8''")
)
)
}
return fileName
}
}
}
</script>
<style lang='scss' scoped>
@import "../../../styles/bim3Dview.css";
@import "../../../styles/webgl.scss";
.ThreeDViewer {
height: 85vh;
width: 100vw;
background-color: aliceblue;
}
</style>
/**
* @Description: EBOM结构树
* @author xioln
* @date 2022-11-29
* @FilePath: src/views/BomTreeDetail/components/ebomTree.vue
*/
<template>
<div ref="tabPanel" class="ebom-tree">
<float-button @onFloatBtnClicked="onFloatBtnClicked" />
<div id="webglcontain" ref="webglcontain" class="ThreeDViewer"></div>
<van-action-sheet v-model="treeOrDxpart3d" @opened="init" title="模型树">
<van-loading v-if="showLoading" type="spinner" size="24px" vertical />
<tree
id="tree"
ref="tree"
:empty-text="text"
show-checkbox
:data="treeData"
:props="defaultProps"
node-key="targetId"
:highlight-current="true"
:default-expand-all="true"
:expand-on-click-node="false"
@node-click="handleNodeClick"
@check="checkNode"
>
<span slot-scope="{ node, data }">
<span>{{ data.label }}</span>
<van-switch
v-if="data.data.hasOwnProperty('hasPMI') && data.data.hasPMI"
v-model="data.checked"
@change="changeSwitch(node, data)"
/>
</span>
</tree>
</van-action-sheet>
</div>
</template>
<script>
// import Tree from '@/components/tree/index.vue'
import { Tree } from 'element-ui'
import { getCadTree, getPmiInfo } from '@/api/taskDetail'
import { downloadFile } from '@/utils/http'
import { Notify } from 'vant'
import floatButton from './float_button'
export default {
name: 'EbomTree', // name写在组件的最前方,自定义组件为必填
components: { Tree, floatButton },
modelRelationObjs: ['DxPart'],
directives: {
// 使用局部注册指令的方式
resize: {
// 指令的名称
bind (el, binding) {
// el为绑定的元素,binding为绑定给指令的对象
let width = ''
let height = ''
function isReize () {
const style = document.defaultView.getComputedStyle(el)
if (width !== style.width || height !== style.height) {
binding.value() // 关键
}
width = style.width
height = style.height
}
el.__vueSetInterval__ = setInterval(isReize, 300)
},
unbind (el) {
clearInterval(el.__vueSetInterval__)
}
}
},
props: {
id: {
type: String,
required: true
}
},
data () {
return {
showLoading: false,
webglcontainDom: null,
treeOrDxpart3d: false,
text: '',
treeData: [],
defaultProps: {
children: 'children',
label: 'label'
},
checkedNode: [],
showWebglcontain: false,
submenuData: null,
viewer: null,
disabled: false,
color1: null,
currentModelIds: [],
explode: false,
showOutline: false,
pmiArr: [],
matrixArr: []
}
},
computed: {},
mounted () {
// this.initPanel()
this.getCadTree()
this.initCad()
this.treeOrDxpart3d = true
},
beforeDestroy () {
if (this.viewer) {
this.viewer.dispose()
this.viewer = null
}
},
methods: {
onFloatBtnClicked () {
this.treeOrDxpart3d = true
},
init () {
// this.initCad()
// this.getCadTree()
},
changeSwitch (node, data) {
if (!node.checked) {
data.checked = false
Notify({ type: 'warning', message: '请先加载模型' })
return
}
if (data.checked) {
this.append(node, data)
} else {
this.remove(data)
}
},
// 添加节点
append (node, data) {
this.loadPMI(data)
const targetId = data.targetId
getPmiInfo(data.data.cadId).then((res) => {
const obj = []
res.items.annotationsRoot.forEach((item) => {
obj.push({
label: item.name,
targetId: item.name + item.index,
data: item,
disabled: true,
children: item.annotationSets
? item.annotationSets.map((anno, index) => {
return {
label: anno.name,
targetId: anno.id,
data: anno,
subTypeName: 'DxAnnotation',
disabled: true
}
})
: []
})
if (item.viewSets) {
obj.push({
label: item.viewSets.name,
targetId: item.viewSets.name + item.viewSets.id,
data: item.viewSets,
disabled: true,
children: item.viewSets.view
? item.viewSets.view.map((view, index) => {
return {
label: view.name,
targetId: view.id,
data: view,
subTypeName: 'DxCapture',
disabled: true
}
})
: []
})
}
})
this.$refs.tree.updateKeyChildren(targetId, obj)
})
},
resize () {
this.viewer && this.resizeCanves()
},
initPanel () {
let tabPane = this.$refs.tabPanel
let i = 0
while (tabPane.className !== 'el-tab-pane' && i < 10) {
tabPane = tabPane.parentElement
i++
}
if (i < 10) {
tabPane.className += ' full-pane'
}
},
initCad () {
if (!this.webglcontainDom) {
this.webglcontainDom = this.$refs.webglcontain
}
// const dom = this.$refs.webglcontain
// const dom = document.getElementById('webglcontain')
// eslint-disable-next-line no-undef
try {
// eslint-disable-next-line no-undef
this.viewer = new BIM3DInterface(this.webglcontainDom, 35, '', {
licenseContent,
wasmURL: '/newVisualizing/visualizing/tools.wasm',
pmiFont: '/newVisualizing/visualizing/PMIFont.ttf',
near: 0.045,
far: 10000
})
} catch (error) {
console.log(
'ERROR: chrome 浏览器访问 chrome://gpu/ 查看当前环境是否支持 WebGL'
)
}
this.$nextTick(() => {
this.viewer.clearScene() // 先清除当前场景
})
},
getCadTree () {
if (!this.id) {
return
}
this.showLoading = true
getCadTree(this.id)
.then((res) => {
this.showLoading = false
this.treeData = this.filterData([res.items])
// this.getTreeNode(res.items[0].target.id)
})
.catch((e) => {
this.showLoading = false
})
},
filterData (tree) {
const treeData = []
if (tree instanceof Array) {
tree.forEach((item) => {
const obj = {
label: item.number + ' ' + item.name + ' ' + item.displayVersion,
objFileLinks: item.visFile ? item.visFile : '',
transform: item.transform ? item.transform : '',
targetId: item.cadId ? item.cadId : item.id,
// targetId: (item.cadId ? item.cadId : item.id) + '_' + this.$utils.GenNonDuplicateID(10),
// disabled: !item.sourceCADUsageLinkParents,
disabled: false,
data: item
}
if (treeData.find((x) => x.targetId === obj.targetId)) {
return true
}
obj.children = this.filterData(item.children)
treeData.push(obj)
})
}
return treeData
},
checkNode (nodeData, node) {
if (!this.$refs.tree.getNode(nodeData.targetId).checked) {
this.matrixArr = this.matrixArr.filter(
(x) => x.id !== nodeData.objFileLinks.fileId
)
this.viewer.removeInstanceModel([nodeData.objFileLinks.fileId])
if (nodeData.data.hasPMI) {
this.remove(nodeData)
}
if (nodeData.targetId === this.$refs.tree.root.data[0].targetId) {
this.$refs.tree.root.data[0].children.map((child) => {
this.remove(child)
})
}
this.afterInstanceModel()
} else {
this.loadModel()
}
},
// 移除节点
remove (data) {
this.$set(data, 'checked', false)
this.$set(data, 'children', [])
this.pmiArr = this.pmiArr.filter(
(x) => x.id !== data.objFileLinks.fileId + '_PMI'
)
this.viewer.removeInstanceModel([data.objFileLinks.fileId + '_PMI'])
},
/** 实例化后做的事情 */
afterInstanceModel () {
// 设置边框
this.getBorder()
// 设置精度
// this.viewer.setMeasureTextDecimalPlaces(6)
// 监听点击事件
this.listenModelClick()
},
/** 监听模型点击事件 */
listenModelClick () {
this.viewer.addSelectObjectCallBack((res) => {
if (res && res.length) {
// 点击
this.currentModelIds = res.map((eve) => eve.name)
} else {
// 取消点击
this.currentModelIds = []
}
})
},
/** 重置可视化窗口 */
resizeCanves () {
this.$nextTick(() => {
this.viewer.resize()
})
},
/** 模型边框 */
getBorder () {
if (this.viewer) {
this.viewer.setOutlineVisible(true)
}
},
// 加载模型
loadModel (data) {
Notify({ type: 'success', message: '模型加载中,请稍候' })
const attachments = []
if (data) {
data.forEach((file) => {
attachments.push({
fileUri: data.fileUri,
fileName: data.name
})
})
}
const nodes = this.$refs.tree.getCheckedNodes()
this.viewer.clearScene()
this.matrixArr = []
// const fildNames = []
nodes.forEach((currentChecked, cIndex) => {
if (
currentChecked.objFileLinks &&
currentChecked.objFileLinks.fileUri
) {
attachments.push({
fileUri: currentChecked.objFileLinks.fileUri,
fileName: currentChecked.objFileLinks.fileName
})
if (currentChecked.data.hasPMI) {
attachments.push({
fileUri: currentChecked.data.pmiFile.fileUri,
fileName: currentChecked.data.pmiFile.fileName
})
this.pmiArr.push({
id: currentChecked.objFileLinks.fileId + '_PMI',
fileName: currentChecked.data.pmiFile.fileName,
matrix: JSON.parse(currentChecked.transform)
})
}
if (nodes.length === 1 && !currentChecked.transform.length) {
this.matrixArr.push({
id: currentChecked.objFileLinks.fileId,
fileName: currentChecked.objFileLinks.fileName,
matrix: [
1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, -28.9471786008458,
1.38537169396519, 0
]
})
} else {
if (currentChecked.transform.length > 0) {
this.matrixArr.push({
id: currentChecked.objFileLinks.fileId,
fileName: currentChecked.objFileLinks.fileName,
matrix: JSON.parse(currentChecked.transform)
})
}
}
}
})
if (attachments.length > 0) {
attachments.forEach((m) => {
m &&
downloadFile(
`api/documents/attachments/download?fileName='${encodeURIComponent(
m.fileName
)}'&url=${encodeURIComponent(m.fileUri)}`
).then((res) => {
const reader = new FileReader()
reader.readAsDataURL(res.data)
const load_file = reader.addEventListener('loadend', () => {
const filedName = this.getFileName(res)
for (let i = 0; i < this.matrixArr.length; i++) {
if (filedName.includes(this.matrixArr[i].fileName)) {
this.matrixArr[i].file = reader.result
}
// matrixArr[i].file = reader.result
}
this.viewer.instanceModel({
asset: this.matrixArr.filter((x) => x.file)
})
// this.viewer.appendFile(reader.result, false )
this.afterInstanceModel()
this.resizeCanves()
reader.removeEventListener('loadend', load_file)
})
})
})
}
},
// 加载PMI
loadPMI (data) {
const pmiFile = {
fileName: data.data.pmiFile.fileName,
fileUri: data.data.pmiFile.fileUri
}
downloadFile(
`api/documents/attachments/download?fileName='${encodeURIComponent(
pmiFile.fileName
)}'&url=${encodeURIComponent(pmiFile.fileUri)}`
).then((res) => {
const reader = new FileReader()
reader.readAsDataURL(res.data)
const load_file = reader.addEventListener('loadend', () => {
const filedName = this.getFileName(res)
for (let i = 0; i < this.pmiArr.length; i++) {
if (filedName.includes(this.pmiArr[i].fileName)) {
this.pmiArr[i].file = reader.result
}
}
this.viewer.instanceModel({
asset: this.pmiArr.filter((x) => x.file)
})
this.afterInstanceModel()
})
})
},
getFileName (res) {
let fileName = ''
if (res.headers['content-disposition']) {
fileName = decodeURIComponent(
res.headers['content-disposition'].substring(
res.headers['content-disposition'].indexOf('=') + 1,
res.headers['content-disposition'].indexOf(";filename*=UTF-8''")
)
)
}
return fileName
},
/** 树结构节点选中状态发生改变时 */
handleCheckChanges (nodeData, addOrDelete) {
// console.log('nodeData', nodeData)
},
handleNodeClick (data, node) {
// 高亮PMI #实例化PMI传入的id#pmi自身的id
if (data.targetId && data.subTypeName === 'DxAnnotation') {
Notify({ type: 'success', message: `【${data.label}】正在加载...` })
const pmiId = `#${node.parent.parent.data.objFileLinks.fileId}_PMI#${data.targetId}`
this.viewer.setModelSelection([pmiId], false)
}
if (data.subTypeName === 'DxCapture') {
Notify({ type: 'success', message: `【${data.label}】视图已切换` })
// 恢复初始状态
this.viewer.setModelVisible('', true, 1)
// 恢复捕获(带动画)
const _id = this.viewer.createView(
{
Position: data.data.camera.position,
Target: data.data.camera.target,
Up: data.data.camera.up
},
data.data.pmiIds,
data.data.modelIds,
JSON.parse(node.parent.parent.data.transform)
)
this.viewer.restoreView(_id, true, 600) // true:带动画效果
this.viewer.removeView(_id)
}
},
/** 可视化二级菜单 */
showSubmenu (item, spceil) {
if ((item.eveUrl && item.eveUrl.length > 1) || spceil) {
this.submenuData = item
} else {
this.submenuData = null
}
},
/** 鼠标离开,隐藏二级菜单 */
hideSubmenu () {
this.submenuData = null
},
/** 菜单栏比盟视图接口 */
mainView (funcMethods) {
if (!this.viewer) {
Notify({ type: 'warning', message: '请先加载模型' })
return
}
if (funcMethods && this[funcMethods]) {
this[funcMethods]()
}
},
/** 是否选中模型 */
isChekcedModel () {
// 监听点击事件
this.listenModelClick()
if (this.currentModelIds.length === 0) {
Notify({ type: 'warning', message: '请点击选择一个模型' })
return false
}
return true
},
/**
* 视图管理
**/
/** 主视图 */
showMain () {
this.viewer.setStandardView(0)
},
/** 上 */
showTop () {
this.viewer.setStandardView(5)
},
/** 下 */
showBottom () {
this.viewer.setStandardView(6)
},
/** 前 */
showFront () {
this.viewer.setStandardView(1)
},
/** 后 */
showBack () {
this.viewer.setStandardView(2)
},
/** 左 */
showLeft () {
this.viewer.setStandardView(3)
},
/** 右 */
showRight () {
this.viewer.setStandardView(4)
},
/**
* 模型操作
**/
getColor (val) {
if (val) {
const colorArr = val.substring(4, val.length - 1).split(',')
const [red, green, blue] = colorArr
this.viewer.setModelColorByRGB(
this.currentModelIds,
red,
green,
blue,
0
)
}
},
/** 设置模型颜色 */
setModelColorByRGB () {
if (this.isChekcedModel()) {
// 弹出模型颜色选择器
this.$refs.colorPicker.$el.children[0].click()
}
},
/** 恢复模型颜色 */
restoreModelColor () {
if (this.isChekcedModel()) {
this.viewer.restoreModelColor(this.currentModelIds, 0)
}
},
/** 设置透明 */
setModelAlpha () {
if (this.isChekcedModel()) {
this.viewer.setModelAlpha(this.currentModelIds, '0.5', 0)
}
},
/** 取消透明 */
restoreModelAlpha () {
if (this.isChekcedModel()) {
this.viewer.restoreModelAlpha(this.currentModelIds, 0)
}
},
/** 设置模型闪烁 */
setModelFlicker () {
if (this.isChekcedModel()) {
this.viewer.setModelFlicker(this.currentModelIds, 0xffffff, 100)
}
},
/** 取消模型闪烁 */
stopModelFlicker () {
if (this.isChekcedModel()) {
this.viewer.stopModelFlicker(this.currentModelIds)
}
},
/** 居中 */
zoomFit () {
this.viewer.zoomFit()
},
/** 爆炸视图 */
explodeModels () {
if (this.explode) {
this.viewer.backHomeModels()
} else {
this.viewer.explodeModels(2, 500, 0)
}
this.explode = !this.explode
},
/**
* 模型测量
**/
/** 三点线角度 */
measureAngleByPoints () {
this.viewer.measureAngleByPoints()
},
/** 半径测量 */
measureRadius () {
this.viewer.measureRadius()
},
/** 体积测量 */
measureVolume () {
this.viewer.measureVolume()
},
/** 面积测量 */
measureArea () {
this.viewer.measureArea()
},
/** 坐标测量 */
measurePoint () {
this.viewer.measurePoint()
},
/**
* 模型测量
**/
/** 最短距离测量 */
pointToPoint () {
this.viewer.measurePtop()
},
/** 点线测量 */
lineToLine () {
this.viewer.measureLtop()
},
/** 点面测量 */
faceToFace () {
this.viewer.measureFtop()
},
/** 线线测量 */
volumeToVolume () {
this.viewer.measureLtol()
},
/** 取消测量 */
diameterSurveying () {
this.viewer.endMeasure()
},
/**
* 标注
**/
/** 方形标注 */
rectMarkWithPanel () {
this.viewer.rectMarkWithPanel()
},
/** 圆形标注 */
circleMarkWithPanel () {
this.viewer.circleMarkWithPanel()
},
/** 自由圈注 */
polygonMarkWithPanel () {
this.viewer.polygonMarkWithPanel()
},
/** 文字标注 */
textMark () {
this.viewer.textMark('测试文字标注', '#000000', '#eeeeee', 12, 50)
},
/** 箭头标注 */
arrowMarkWithPanel () {
this.viewer.arrowMarkWithPanel()
},
/** 椭圆标注 */
ellipseMarkWithPanel () {
this.viewer.ellipseMarkWithPanel()
},
/** 正多边形标注 */
regularPolygonMarkWithPanel () {
this.viewer.regularPolygonMarkWithPanel()
},
/** 退出标注 */
endMark () {
this.viewer.endMark()
},
/** 删除标注 */
deleteSelectMark () {
this.viewer.deleteSelectMark()
},
/**
*系统配置
**/
setOptionCullingThreshold () {
this.viewer.setOptionCullingThreshold(30)
},
/** 显示/隐藏轮廓 */
setOutlineVisible () {
this.viewer.setOutlineVisible(this.showOutline)
this.showOutline = !this.showOutline
},
/** 设置轮廓颜色 */
setOutlineColor () {
this.viewer.setOutlineColor('#e11313')
},
/** 设置轮廓宽度 */
setOutlineWidth () {
this.viewer.setOutlineWidth(6)
},
/** 设置背景颜色 */
setBackground () {
this.viewer.setBackground('red', 'green')
},
/** 光照设置 */
setAmbientLight () {
this.viewer.setAmbientLight('FFFFFF', 5)
},
/** 标签 */
/** 文字标签 */
setModelTextLabel () {
if (this.isChekcedModel()) {
this.viewer.setModelTextLabel(
this.currentModelIds,
10,
true,
'测试文字标签'
)
}
},
/** 移除文字标签 */
removeModelTextLabelByIDs () {
if (this.isChekcedModel()) {
this.viewer.removeModelTextLabelByIDs(this.currentModelIds)
}
},
/** 图像标签 */
setModelImageLabel () {
if (this.isChekcedModel()) {
this.viewer.setModelImageLabel(
this.currentModelIds,
'http://icons.iconarchive.com/icons/hopstarter/square-flags/32/China-Flag-icon.png',
30,
30
)
}
},
/** 移除图像标签 */
removeModelImageLabelByIDs () {
if (this.isChekcedModel()) {
this.viewer.removeModelImageLabelByIDs(this.currentModelIds)
}
},
/** HTML标签 */
setModelAnyLabel () {
if (this.isChekcedModel()) {
this.viewer.setModelAnyLabel(
this.currentModelIds,
'<p>测试html文字</p>'
)
}
},
/** 移除HTML标签 */
removeModelAnyLabelByIDs () {
if (this.isChekcedModel()) {
this.viewer.removeModelAnyLabelByIDs(this.currentModelIds)
}
},
/**
* 剖切
**/
/** XY剖切 */
clipXY () {
this.viewer.setAxisClip(2)
},
/** YZ剖切 */
clipYZ () {
this.viewer.setAxisClip(0)
},
/** XZ剖切 */
clipXZ () {
this.viewer.setAxisClip(1)
},
/** 平面法线剖切 */
planeNormal () {
this.viewer.startClip(2)
},
/** 直线中点剖切 */
midpointOfLine () {
this.viewer.startClip(1)
},
/** 剖切盒 */
startBoxClip () {
this.viewer.startBoxClip()
},
/** 取消剖切 */
endClip () {
this.viewer.clearClip()
this.viewer.endBoxClip()
}
}
}
</script>
<style lang='scss' scoped>
.ebom-tree {
height: calc(100vh - 190px);
width: 100%;
/deep/.van-switch {
font-size: 12px;
vertical-align: sub;
margin-left: 5px;
}
/deep/.van-action-sheet__content {
min-height: 200px;
padding: 10px 0;
}
/deep/.el-checkbox__input.is-disabled {
display: none;
}
/deep/.el-tree {
font-size: 12px;
}
.ThreeDViewer {
height: 100%;
width: 100%;
background-color: aliceblue;
#container {
height: 100%;
}
canvas {
height: 100%;
width: 100%;
}
}
}
</style>
<template>
<div class="float_button">
<div
@click="onBtnClicked"
ref="floatButton"
class="float_info"
:style="{'width': itemWidth + '%', 'height': itemHeight + '%', 'left': left + 'px', 'top': top + 'px'}"
>
<img src="../../../assets/document/treeIcon.svg" alt="" srcset="">
<span class="text">{{ text }}</span>
</div>
</div>
</template>
<script>
export default {
data () {
return {
clientWidth: 0,
clientHeight: 0,
timer: null,
currentTop: 0,
left: 0,
top: 0
}
},
props: {
text: { // 按钮文本内容
type: String,
default: '模型树'
},
itemWidth: { // 悬浮按钮宽度
type: Number,
default: 15
},
itemHeight: { // 悬浮按钮高度
type: Number,
default: 10
},
gapWidth: { // 距离左右两边距离
type: Number,
default: 0
},
coefficientHeight: { // 从上到下距离比例
type: Number,
default: 0.55
}
},
created () {
this.clientWidth = document.documentElement.clientWidth
this.clientHeight = document.documentElement.clientHeight
this.left = this.clientWidth - this.itemWidth - this.gapWidth
this.top = this.clientHeight * this.coefficientHeight
},
methods: {
onBtnClicked () {
this.$emit('onFloatBtnClicked')
},
handleScrollStart () {
this.timer && clearTimeout(this.timer)
this.timer = setTimeout(() => {
this.handleScrollEnd()
}, 300)
this.currentTop = document.documentElement.scrollTop || document.body.scrollTop
if (this.left > this.clientWidth / 2) {
this.left = this.clientWidth - this.itemWidth / 2
} else {
this.left = -this.itemWidth / 2
}
},
handleScrollEnd () {
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop
if (scrollTop === this.currentTop) {
if (this.left > this.clientWidth / 2) {
this.left = this.clientWidth - this.itemWidth - this.gapWidth
} else {
this.left = this.gapWidth
}
clearTimeout(this.timer)
}
}
},
mounted () {
this.$nextTick(() => {
const floatButton = this.$refs.floatButton
floatButton.addEventListener('touchstart', () => {
floatButton.style.transition = 'none'
})
// 在拖拽的过程中,组件应该跟随手指的移动而移动。
floatButton.addEventListener('touchmove', (e) => {
if (e.targetTouches.length === 1) { // 一根手指
const touch = e.targetTouches[0]
this.left = touch.clientX - 20
this.top = touch.clientY - 25
}
})
// 拖拽结束以后,重新调整组件的位置并重新设置过度动画。
floatButton.addEventListener('touchend', () => {
floatButton.style.transition = 'all 0.3s'
if (this.left > document.documentElement.clientWidth / 2) {
this.left = document.documentElement.clientWidth - 40
} else {
this.left = 0
}
})
})
},
beforeDestroy () {
// 添加监听页面滚动
window.removeEventListener('scroll', this.handleScrollStart)
},
destroyed () {}
}
</script>
<style lang="scss" scoped>
.float_button {
.float_info{
box-shadow: 0 2px 10px 0 rgba(0, 0, 0, 0.1);
color: #666666;
transition: all 0.3s;
position: fixed;
bottom: 436px;
right: 0;
width: 80px;
height: 100px;
display: flex;
flex-flow: column;
justify-content: center;
align-items: center;
z-index: 999;
background: rgba(206, 209, 212, 0.5);
border-radius: 14px;
cursor: pointer;
.text{
font-size: 10px;
color: #1b77ea;
}
img{
width: 65%;
height: 50%;
}
}
}
</style>
/**
* @Description: 更改记录
* @author xioln
* @date 2022-07-02
* @FilePath: src/views/BomTreeDetail/components/modifieRecord.vue
*/
<template>
<div class="modifie-record">
<van-collapse v-model="active" accordion>
<van-collapse-item title="更改请求" name="requestTableData">
<van-row>
<van-col
v-if="requestTableData.length !== 0"
span="24"
class="van-col-class"
>
<van-cell is-link v-for="item in requestTableData" :key="item.key">
<van-col span="24">
<van-col class="van-col-span" span="10">编号</van-col>
<van-col span="14" offset="1">{{ item.number }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">名称</van-col>
<van-col span="14" offset="1">{{ item.name }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">状态</van-col>
<van-col span="14" offset="1">{{ item.state.display}}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">创建者</van-col>
<van-col span="14" offset="1">{{ item.creator.fullName }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">创建时间</van-col>
<van-col span="14" offset="1">{{ item.createTime }}</van-col>
</van-col>
<template #right-icon>
<!-- <van-icon name="arrow"/> -->
</template>
</van-cell>
</van-col>
<van-col span="24" v-else>
<van-empty description="数据为空"/>
</van-col>
</van-row>
</van-collapse-item>
<van-collapse-item
title="更改通告(受更改通告影响)"
name="circularTableData"
>
<van-row>
<van-col
v-if="circularTableData.length !== 0"
span="24"
class="van-col-class"
>
<van-cell is-link v-for="item in circularTableData" :key="item.key">
<van-col span="24">
<van-col class="van-col-span" span="10">编号</van-col>
<van-col span="14" offset="1">{{ item.number }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">文件名称</van-col>
<van-col span="14" offset="1">{{ item.name }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">状态</van-col>
<van-col span="14" offset="1">{{ item.state.display }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">创建者</van-col>
<van-col span="14" offset="1">{{ item.creator.fullName }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">创建时间</van-col>
<van-col span="14" offset="1">{{ item.createTime }}</van-col>
</van-col>
<template #right-icon>
<!-- <van-icon name="arrow"/> -->
</template>
</van-cell>
</van-col>
<van-col span="24" v-else>
<van-empty description="数据为空"/>
</van-col>
</van-row> </van-collapse-item
><van-collapse-item
title="更改通告(自更改通告产生)"
name="noticeGeneratedData"
>
<van-row>
<van-col
v-if="noticeGeneratedData.length !== 0"
span="24"
class="van-col-class"
>
<van-cell
is-link
v-for="item in noticeGeneratedData"
:key="item.key"
>
<van-col span="24">
<van-col class="van-col-span" span="10">编号</van-col>
<van-col span="14" offset="1">{{ item.number }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">文件名称</van-col>
<van-col span="14" offset="1">{{ item.name }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">状态</van-col>
<van-col span="14" offset="1">{{ item.state.display }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">创建者</van-col>
<van-col span="14" offset="1">{{ item.creator.fullName }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">创建时间</van-col>
<van-col span="14" offset="1">{{ item.createTime }}</van-col>
</van-col>
<template #right-icon>
<!-- <van-icon name="arrow"/> -->
</template>
</van-cell>
</van-col>
<van-col span="24" v-else>
<van-empty description="数据为空"/>
</van-col>
</van-row>
</van-collapse-item>
</van-collapse>
</div>
</template>
<script>
import { getChangeData } from '@/api/taskDetail'
import { getPartById } from '@/api/design.js'
export default {
name: 'ModifieRecord', // name写在组件的最前方,自定义组件为必填
props: {
oid: {
type: String,
require: true
}
},
components: {},
data () {
return {
active: '',
requestTableData: [],
circularTableData: [],
noticeGeneratedData: []
}
},
computed: {},
created () {
// 初始化数据
this.initData()
},
methods: {
async initData () {
if (this.documentId !== '') {
let basicData = {}
this.loading = true
await getPartById(this.oid).then(async (res) => {
if (res.items) {
basicData = res.items
}
})
await getChangeData(
basicData.dxClassname,
basicData.id,
basicData.subTypeName
).then((res) => {
if (res.code === 0 && res.items) {
if (
// eslint-disable-next-line no-prototype-builtins
res.items.hasOwnProperty('changeRequests') &&
res.items.changeRequests.length
) {
// 变更请求
this.requestTableData = res.items.changeRequests
}
if (
// eslint-disable-next-line no-prototype-builtins
res.items.hasOwnProperty('acceptChangeNotices') &&
res.items.acceptChangeNotices.length
) {
// 受变更通告影响
this.circularTableData = res.items.acceptChangeNotices
}
if (
// eslint-disable-next-line no-prototype-builtins
res.items.hasOwnProperty('selfChangeNotice') &&
res.items.selfChangeNotice.length
) {
// 自变更通告产生
this.noticeGeneratedData = res.items.selfChangeNotice
}
}
})
}
}
}
}
</script>
<style lang='scss'>
.related-signing {
padding: 0 10px;
.van-collapse-item__content {
padding: 0;
}
.van-col-span {
width: 120px;
font-weight: bold;
}
.van-cell {
margin-right: 0;
}
}
</style>
/**
* @Description: 相关签审包
* @author xioln
* @date 2022-07-02
* @FilePath: src/views/BomTreeDetail/components/relatedSigning.vue
*/
<template>
<div class="related-signing">
<van-collapse v-model="active" accordion>
<van-collapse-item title="相关签审包" name="tableData">
<van-row>
<van-col
v-if="tableData.length !== 0"
span="24"
class="van-col-class"
>
<van-cell is-link v-for="item in tableData" :key="item.key">
<van-col span="24">
<van-col class="van-col-span" span="10">编号</van-col>
<van-col span="14" offset="1">{{ item.number }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">文件名称</van-col>
<van-col span="14" offset="1">{{ item.name }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">状态</van-col>
<van-col span="14" offset="1">{{ item.state }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">创建者</van-col>
<van-col span="14" offset="1">{{ item.creator }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">创建时间</van-col>
<van-col span="14" offset="1">{{ item.createTime }}</van-col>
</van-col>
<template #right-icon>
<!-- <van-icon name="arrow"/> -->
</template>
</van-cell>
</van-col>
<van-col span="24" v-else>
<van-empty description="数据为空"/>
</van-col>
</van-row>
</van-collapse-item>
<van-collapse-item title="相关数据包" name="dataTable">
<van-row>
<van-col
v-if="dataTable.length !== 0"
span="24"
class="van-col-class"
>
<van-cell is-link v-for="item in dataTable" :key="item.key">
<van-col span="24">
<van-col class="van-col-span" span="10">编号</van-col>
<van-col span="14" offset="1">{{ item.number }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">文件名称</van-col>
<van-col span="14" offset="1">{{ item.name }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">状态</van-col>
<van-col span="14" offset="1">{{ item.state }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">创建者</van-col>
<van-col span="14" offset="1">{{ item.creator }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">创建时间</van-col>
<van-col span="14" offset="1">{{ item.createTime }}</van-col>
</van-col>
<template #right-icon>
<!-- <van-icon name="arrow"/> -->
</template>
</van-cell>
</van-col>
<van-col span="24" v-else>
<van-empty description="数据为空"/>
</van-col>
</van-row> </van-collapse-item
><van-collapse-item title="相关发布包" name="publishTable">
<van-row>
<van-col
v-if="publishTable.length !== 0"
span="24"
class="van-col-class"
>
<van-cell is-link v-for="item in publishTable" :key="item.key">
<van-col span="24">
<van-col class="van-col-span" span="10">编号</van-col>
<van-col span="14" offset="1">{{ item.number }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">文件名称</van-col>
<van-col span="14" offset="1">{{ item.name }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">状态</van-col>
<van-col span="14" offset="1">{{ item.state }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">创建者</van-col>
<van-col span="14" offset="1">{{ item.creator }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">创建时间</van-col>
<van-col span="14" offset="1">{{ item.createTime }}</van-col>
</van-col>
<template #right-icon>
<!-- <van-icon name="arrow"/> -->
</template>
</van-cell>
</van-col>
<van-col span="24" v-else>
<van-empty description="数据为空"/>
</van-col>
</van-row>
</van-collapse-item>
</van-collapse>
</div>
</template>
<script>
import { getPromotions } from '@/api/taskDetail'
export default {
name: 'RelatedSigning', // name写在组件的最前方,自定义组件为必填
props: {
oid: {
type: String,
require: true
}
},
components: {},
data () {
return {
active: 'tableData',
tableData: [],
dataTable: [],
publishTable: []
}
},
computed: {},
created () {
// 初始化数据
this.promotables()
},
methods: {
promotables () {
getPromotions({ oid: this.oid }).then((res) => {
const keyArr = Object.keys(res.items)
console.log(keyArr, 'keyArr')
if (keyArr.includes('相关签审包')) {
this.tableData = res.items['相关签审包'] || []
}
if (keyArr.includes('相关数据包')) {
this.dataTable = res.items['相关数据包'] || []
}
if (keyArr.includes('相关发布包')) {
this.publishTable = res.items['相关发布包'] || []
}
})
}
}
}
</script>
<style lang='scss'>
.related-signing {
padding: 0 10px;
.van-collapse-item__content {
padding: 0;
}
.van-col-span {
width: 120px;
font-weight: bold;
}
.van-cell {
margin-right: 0;
}
}
</style>
/**
* @Description: 结构
* @author xioln
* @date 2022-07-01
* @FilePath: src/views/BomTreeDetail/components/structure.vue
*/
<template>
<div class="structure">
<van-row v-if="structureData.length !== 0 || xmlData.length !== 0">
<van-col span="24" class="van-col-class" v-if="structureData.length !== 0">
<div class="sub-title">结构</div>
<van-cell is-link v-for="item in structureData" :key="item.key">
<template #title>
<van-col span="24">
<van-col class="van-col-span" span="10">编号</van-col>
<van-col span="14" offset="1">{{ item.partNumber }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">名称</van-col>
<van-col span="14" offset="1">{{ item.partName }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">版本</van-col>
<van-col span="14" offset="1">{{ item.version }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">状态</van-col>
<van-col span="14" offset="1">{{ item.status }}</van-col>
</van-col>
</template>
<template #right-icon>
<!-- <van-icon name="arrow"/> -->
</template>
</van-cell>
</van-col>
<van-col span="24" class="van-col-class">
<div class="sub-title">紧固件</div>
<van-cell is-link v-for="item in xmlData" :key="item.key">
<template #title>
<van-col span="24">
<van-col class="van-col-span" span="10">编号</van-col>
<van-col span="14" offset="1">{{ item.number }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">名称</van-col>
<van-col span="14" offset="1">{{ item.name }}</van-col>
</van-col>
<van-col span="24">
<van-col class="van-col-span" span="10">数量</van-col>
<van-col span="14" offset="1">{{ item.count }}</van-col>
</van-col>
</template>
<template #right-icon>
<!-- <van-icon name="arrow"/> -->
</template>
</van-cell>
</van-col>
</van-row>
<van-row v-else>
<van-col span="24">
<van-empty description="数据为空" />
</van-col>
</van-row>
</div>
</template>
<script>
import { getPartBom, rModelFasteners } from '@/api/taskDetail'
export default {
name: 'Structure', // name写在组件的最前方,自定义组件为必填
props: {
oid: {
type: String,
require: true
}
},
components: {},
data () {
return {
structureData: [],
xmlData: []
}
},
computed: {},
created () {
// 初始化数据
this.rModelFasteners()
},
methods: {
// 紧固件
rModelFasteners () {
rModelFasteners({ partId: this.oid }).then((res) => {
if (res.items) {
this.xmlData = res.items.fasteners
}
})
},
assemblyTreeData (item) {
// eslint-disable-next-line no-unused-vars
for (const key in this.treeNodeData(item)) {
this.$set(item, key, this.treeNodeData(item)[key])
}
// eslint-disable-next-line no-prototype-builtins
if (item.hasOwnProperty('children') && item.children.length) {
item.children.forEach((item) => {
this.assemblyTreeData(item)
})
}
},
getPartBom (resolve = null) {
const params = {
oid: this.oid,
level: '1'
}
getPartBom(params).then((tree) => {
console.log('tree', tree.items)
this.assemblyTreeData(tree.items)
if (resolve) {
resolve(tree.items.children)
} else {
this.structureData = []
this.structureData = tree.items.children
}
})
},
treeNodeData (item) {
item = Object.assign(item, item.partAttributes)
return {
index: this.i++,
number: item.partNumber,
link: 'link',
oid: item.partId,
version: item.versionId + '.' + item.iterationId,
status: item.lifecycleState.split('___')[1],
FACRIDocLevel: item.partAttributes.hasOwnProperty('FACRIDocLevel')
? item.partAttributes.FACRIDocLevel
: '',
PARTTYPE: item.partAttributes.hasOwnProperty('PARTTYPE')
? item.partAttributes.PARTTYPE
: '',
amount: item.quantity,
// unit: this.unitArray.find(x => x.value === item.unit) ? this.unitArray.find(x => x.value === item.unit).label : '',
FACRICLMC: item.partAttributes.hasOwnProperty('FACRICLMC')
? item.partAttributes.FACRICLMC
: '',
FACRICLPH: item.partAttributes.hasOwnProperty('FACRICLPH')
? item.partAttributes.FACRICLPH
: '',
creator: item.creatorName,
FACRITUFU: item.partAttributes.hasOwnProperty('FACRITUFU')
? item.partAttributes.FACRITUFU
: '',
SPEC: item.partAttributes.hasOwnProperty('SPEC')
? item.partAttributes.SPEC
: '',
FACRIBEIZHU: item.partAttributes.hasOwnProperty('FACRIBEIZHU')
? item.partUseAttributes.FACRIBEIZHU
: '',
hasChildren: this.entranceJudge,
show: true
}
}
}
}
</script>
<style lang='scss'>
.structure {
padding: 0 10px;
.sub-title{
margin-bottom: 10px;
}
.van-collapse-item__content {
padding: 0;
}
.van-col-span {
width: 120px;
font-weight: bold;
}
.van-cell {
margin-right: 0;
}
}
</style>
/**
* @Description: BOM结构树详情页
* @author faker
* @date 2022-05-23
* @FilePath: src/views/BomTreeDetail/index.vue
*/
<template>
<div class="bomStructure">
<header-nav-bar :title="title" left-arrow @click-left="onClickLeft" />
<div class="searchTree">
<van-tabs v-model="activeTab" @change="tabChanged">
<van-tab
v-for="item in tabs"
:key="item.key"
:name="item.key"
:title="item.title"
>
<dee-form
v-if="activeTab === 'baseInfo' || activeTab === 'baseInfoDetail'"
:form="form"
:form-data="formData"
/>
<div v-if="activeTab === 'attachment'" class="data-Package-Info-card">
<van-cell
is-link
v-for="(item, i) in dxContentItems"
:key="i"
:border="false"
>
<template #title>
<div class="title-value-number">
<span class="title-value">{{ item.fileName }}</span>
</div>
</template>
<template #label>
<div class="title-value-style">
<span class="title-value">{{ item.creator.fullName }}</span>
<span class="title-value"> | </span>
<!-- <span class="title-value">{{ moment(item.createTime).format('YYYY-MM-DD HH:mm') }}</span>-->
<span class="title-value">{{ item.createTime }}</span>
</div>
</template>
<template #right-icon>
<!-- <van-icon name="arrow" class="" /> -->
</template>
</van-cell>
</div>
<div v-if="activeTab === 'modelTree'" class="model-tree">
<!-- <tree :id="id" /> -->
</div>
<div v-show="activeTab === 'view'" class="data-detail">
<dx-part-view ref="dxPartViewModel" :id="id" />
</div>
<div v-if="activeTab === 'pdf'" class="pdf-detail">
<pdf :url="url" v-if="url" />
</div>
<div v-if="activeTab === 'affectedData'" class="data-detail">
<affected-data
:affectedData="affectedData"
:affectedAIData="affectedAIData"
/>
</div>
<div v-if="activeTab === 'bindArticle'" class="data-detail">
<bind-article :oid="id" />
</div>
<div v-if="activeTab === 'structure'" class="data-detail">
<structure :oid="id" />
</div>
<div
v-if="activeTab === 'bindArticleCreatedSelf'"
class="data-detail"
>
<bind-article-created-self :oid="id" />
</div>
<div v-if="activeTab === 'relatedSigning'" class="data-detail">
<related-signing :oid="id" />
</div>
<div v-if="activeTab === 'modifieRecord'" class="data-detail">
<modifie-record :oid="id" />
</div>
<div v-if="activeTab === 'generatedData'" class="data-detail">
<van-row>
<van-col
v-if="Object.keys(generatedData).length !== 0"
span="24"
class="van-col-class"
>
<van-cell is-link v-for="(item, i) in generatedData" :key="i">
<template #title>
<van-col span="24">
<span class="van-col-span">编号</span>
<b>
{{ item.changeable.number }}
</b>
<div style="float: right">
<van-tag color="#1989fa">{{ item.state }}</van-tag>
<!-- <van-tag color="#1989fa">{{ item.version }}</van-tag>-->
</div>
</van-col>
<van-col span="24">
<span class="van-col-span">名称</span>
<b>{{ item.changeable.name }}</b>
</van-col>
<van-col span="24">
<span class="van-col-span">版本</span>
<b
><van-tag color="#1989fa">{{
item.version
}}</van-tag></b
>
</van-col>
<!-- <van-col span="24">-->
<!-- <span class="van-col-span">状态</span>-->
<!-- <b>{{ item.state }}</b>-->
<!-- </van-col>-->
<van-col span="24">
<span class="van-col-span">修改时间</span>
<b>{{ item.modifyTime }}</b>
</van-col>
<van-col span="24">
<span class="van-col-span">修改者</span>
<b>{{ item.modifier }}</b>
</van-col>
<van-col span="24">
<span class="van-col-span">备注</span>
<b>{{ item.comment }}</b>
</van-col>
</template>
<template #right-icon>
<!-- <van-icon name="arrow" class="search-icon center" /> -->
</template>
</van-cell>
</van-col>
<van-col v-else span="24" class="van-col-class">
<van-empty description="产生数据为空" />
</van-col>
</van-row>
</div>
<div v-if="activeTab === 'workFlowHistory'" class="data-detail">
<van-row v-if="Object.keys(historyData).length !== 0">
<van-col
span="24"
class="van-col-class"
v-for="(item, i) in historyData"
:key="i"
>
<van-cell>
<van-tag color="#1989fa">
{{ item.process.wfTemplateName }}
</van-tag>
<van-col span="24">
<span class="van-col-span">开始时间</span>
<b>{{ item.process.startTime }}</b>
</van-col>
<van-col span="24">
<span class="van-col-span">结束时间</span>
<b>{{ item.process.endTime }}</b>
</van-col>
<van-col span="24">
<span class="van-col-span">状况</span>
<b>
<van-tag color="#1989fa">
{{ item.process.state.display }}
</van-tag>
</b>
</van-col>
</van-cell>
<van-cell is-link v-for="(doc, i) in item.children" :key="i">
<template #title>
<van-col span="24">
<span class="van-col-span">负责人</span>
<b>{{ doc.workItem.owner.fullName }}</b>
</van-col>
<van-col span="24">
<span class="van-col-span">角色</span>
<b>{{ doc.workItem.role.display }}</b>
</van-col>
<van-col span="24">
<span class="van-col-span">开始时间</span>
<b>{{ doc.workItem.createTime }}</b>
</van-col>
<van-col span="24">
<span class="van-col-span">完成时间</span>
<b>{{ doc.workItem.completeTime }}</b>
</van-col>
<van-col span="24">
<span class="van-col-span">处理结果</span>
<b
><van-tag color="#1989fa">{{
doc.workItem.vote
}}</van-tag></b
>
</van-col>
</template>
<template #right-icon> </template>
</van-cell>
</van-col>
</van-row>
<van-row v-else>
<van-col span="24" class="van-col-class">
<van-empty description="历史记录为空" />
</van-col>
</van-row>
</div>
</van-tab>
</van-tabs>
</div>
</div>
</template>
<script>
import HeaderNavBar from '../../components/headerNavBar/index.vue'
import { getPartById } from '../../api/design.js'
import {
getMBOMNodeType,
getLayouts,
getQuantityUnitDisplay,
getResponsibleDisplay,
SolutionValue,
getPBOMNodeType,
getPDFPreview,
getObject,
getRequestAffectedData,
getRequestGeneratedData,
getDSWorkflowHistory,
getAffectedAI,
getAffectedAIPR,
virtualView
} from '@/api/taskDetail'
import DeeForm from '@/components/form/form'
// import Tree from '@/components/tree/index.vue'
import Tree from '@/views/BomTreeDetail/components/ebomTree.vue'
import moment from 'moment'
import Pdf from '@/components/pdf/index'
import AffectedData from '@/views/BomTreeDetail/components/affectedData'
import DxPartView from '@/views/BomTreeDetail/components/dxPart3DViewer'
import BindArticle from '@/views/BomTreeDetail/components/bindArticle'
import Structure from '@/views/BomTreeDetail/components/structure'
import BindArticleCreatedSelf from '@/views/BomTreeDetail/components/bindArticleCreatedSelf'
import RelatedSigning from '@/views/BomTreeDetail/components/relatedSigning'
import ModifieRecord from '@/views/BomTreeDetail/components/modifieRecord'
import { downloadFile } from '@/utils/http.js'
export default {
// props: {
// basicData: {
// type: Object,
// required: true
// }
// },
components: {
Pdf,
HeaderNavBar,
DeeForm,
Tree,
AffectedData,
DxPartView,
BindArticle,
Structure,
BindArticleCreatedSelf,
RelatedSigning,
ModifieRecord
},
// props: {
// url: {
// type: String,
// default: 'http://devgace.avicgeneral.com/Windchill/ext/gace/config/template/test_abc.pdf'
// }
// },
data () {
return {
pageNum: 1,
tabs: [],
// baseInfoDetail: {},
activeTab: '',
searchInterface: {
baseInfo: 'getPartById',
// attachment: '',
// view: 'getView',
pdf: 'getPDFPreview',
baseInfoDetail: 'getObject',
affectedData: 'getAffectedData',
generatedData: 'getRequestGeneratedData',
workFlowHistory: 'getDSWorkflowHistory'
},
title: '',
id: '',
subTitle: '',
form: {},
dxContentItems: [],
formData: [],
defaultProps: {
children: 'children',
label: 'label'
},
text: '',
loadingTree: false,
treeData: [],
loadInfoInstance: null,
explode: false,
affectedData: [],
affectedAIData: [],
generatedData: [],
historyData: [],
url: '',
isAffectedShow: false,
checkedNode: []
}
},
watch: {
'$route.path': {
handler (val, oldval) {
this.tabs = []
this.initDetail()
},
// 深度观察监听
deep: true
}
},
created () {
this.initDetail()
},
mounted () { },
computed: {},
methods: {
getPDFPreview () {
const params = this.$utils.formDataParams({ oid: this.id })
if (
this.$route.query.dxClassName &&
(this.$route.query.dxClassName.includes('DxChangeNotice') ||
this.$route.query.dxClassName.includes('DxChangeRequest') ||
this.$route.query.dxClassName.includes('DxProblemReport'))
) {
getPDFPreview(params)
.then((res) => {
console.log('res', res)
// const url = res.items
// if (res.items.includes('devgace.avicgeneral.com')) {
// url = res.items.replace('http://devgace.avicgeneral.com/', 'http://114.115.155.252:9400/')
// } else if (res.items.includes('gacemes.avicgeneral.com')) {
// url = res.items.replace('http://gacemes.avicgeneral.com/', 'http://10.19.5.112:9400/')
// } else if (res.items.includes('gace.avicgeneral.com')) {
// url = res.items
// }
this.transformNozzle(res.items)
// this.url = url
})
.catch((e) => {
console.log(e)
})
} else {
virtualView(this.id)
.then((res) => {
this.transformNozzle(res.items)
})
.catch((e) => {
console.log(e)
})
}
},
transformNozzle (deaUrl) {
const fileName = ''
const fileUrl = encodeURIComponent(deaUrl)
downloadFile(
`api/documents/attachments/download?fileName=${fileName}&url=${fileUrl}`
).then((res) => {
this.url = window.URL.createObjectURL(new Blob([res.data]))
})
},
onClickLeft () {
history.back(-1)
},
tabChanged (name, title) {
const tabs = this.tabs
tabs.find((item) => {
// 判断是否存在该tab对应接口
if (item.key === name) {
this.activeTab = name
this.searchInterface[name] && this[this.searchInterface[name]]()
}
})
},
async getMBOMNodeType (id) {
const params = this.$utils.formDataParams({ oid: id })
await getMBOMNodeType(params)
.then((res) => {
this.title = res.items
})
.catch((e) => {
console.log(e)
})
},
async getPBOMNodeType (id) {
const params = this.$utils.formDataParams({ oid: id })
await getPBOMNodeType(params)
.then((res) => {
this.title = res.items
})
.catch((e) => {
console.log(e)
})
},
async getPartById () {
await getPartById(this.id)
.then(async (res) => {
this.initData(res.items)
})
.catch((e) => {
console.log(e)
})
},
// 获取页面的模型属性数据--基本属性
async initDetail () {
this.id = this.$route.query.oid
// this.activeTab = 'baseInfo'
const dxClassName = this.$route.query?.dxClassName
? this.$route.query.dxClassName.substring(
this.$route.query.dxClassName.lastIndexOf('.') + 1
)
: ''
const subTypeName = this.$route.query.subTypeName
this.subTitle = this.$route.query.title
if (this.subTitle === 'EBOM' || this.subTitle === 'PBOM底层') {
this.tabs = [
{ title: '基本信息', key: 'baseInfoDetail' }
// { title: '可视化', key: 'view' }
// { title: '可视化', key: 'view' }
]
} else if (this.subTitle === 'Design') {
this.tabs = [
{ title: '基本信息', key: 'baseInfo' }
// { title: '可视化', key: 'view' }
// { title: '可视化', key: 'view' }
]
} else if (this.subTitle === 'PBOM' || this.subTitle === 'MBOM') {
this.tabs = [{ title: '基本信息', key: 'baseInfo' }]
} else if (this.subTitle === 'PBOMA类工作包') {
this.tabs = [
{ title: '基本信息', key: 'baseInfo' },
{ title: '相关文档', key: 'bindArticle' },
{ title: '历史记录', key: 'workFlowHistory' }
]
} else if (this.subTitle === 'PBOM自制件') {
this.tabs = [
{ title: '基本信息', key: 'baseInfo' },
{ title: '相关文档', key: 'bindArticleCreatedSelf' },
{ title: '相关签审包', key: 'relatedSigning' },
{ title: '更改记录', key: 'modifieRecord' }
]
} else if (this.subTitle === 'PBOM自制件R') {
this.tabs = [
{ title: '基本信息', key: 'baseInfo' },
{ title: '结构', key: 'structure' },
{ title: '相关文档', key: 'bindArticleCreatedSelf' },
{ title: '更改记录', key: 'modifieRecord' }
]
} else if (this.subTitle === '签署文档') {
this.tabs = [
{ title: '基本信息', key: 'baseInfoDetail' },
{ title: '浏览', key: 'pdf' },
{ title: '历史记录', key: 'workFlowHistory' }
]
} else if (
dxClassName === 'DxChangeRequest' ||
dxClassName === 'DxChangeNotice'
) {
// ecr||ecn
this.tabs = [
{ title: '基本信息', key: 'baseInfoDetail' },
{ title: '浏览', key: 'pdf' },
{ title: '受影响数据', key: 'affectedData' },
{ title: '历史记录', key: 'workFlowHistory' }
]
} else if (subTypeName.includes('不合格品审理单')) {
this.title = '不合格品审理单'
this.tabs.push(
{ title: '浏览', key: 'pdf' },
{ title: '历史记录', key: 'workFlowHistory' }
)
} else if (subTypeName.includes('器材代用单')) {
this.title = '器材代用单'
this.tabs.push(
{ title: '浏览', key: 'pdf' },
{ title: '历史记录', key: 'workFlowHistory' }
)
} else if (subTypeName.includes('工艺偏离单')) {
this.title = '工艺偏离单'
this.tabs.push(
{ title: '浏览', key: 'pdf' },
{ title: '历史记录', key: 'workFlowHistory' }
)
} else {
// 通用详情页面
this.tabs = []
this.tabs.push(
{ title: '基本信息', key: 'baseInfoDetail' },
{ title: '浏览', key: 'pdf' },
// { title: '附件', key: 'attachment' },
// { title: '受影响数据', key: 'affectedData' },
// { title: '产生数据', key: 'generatedData' },
{ title: '历史记录', key: 'workFlowHistory' }
)
// await this.getObject()
}
if (subTypeName === 'com.avicgeneral.DS___DS') {
this.tabs.push({ title: '可视化', key: 'view' })
}
this.activeTab = this.tabs[0].key
this.searchInterface[this.activeTab] &&
this[this.searchInterface[this.activeTab]]()
},
async getDSWorkflowHistory () {
const params = this.$utils.formDataParams({ oid: this.id })
await getDSWorkflowHistory(params)
.then(async (res) => {
this.historyData = res.items.map((item) => {
this.$set(
item.process,
'startTime',
moment(item.process.startTime).format('YYYY-MM-DD HH:mm:ss')
)
this.$set(
item.process,
'endTime',
(item.process.endTime &&
moment(item.process.endTime).format('YYYY-MM-DD HH:mm:ss')) ||
'暂未完成'
)
item.children.map((x) => {
this.$set(
x.workItem.owner,
'fullName',
x.workItem.owner.fullName + '(' + x.workItem.owner.name + ')'
)
this.$set(
x.workItem,
'completeTime',
(x.workItem.completeTime &&
moment(x.workItem.completeTime).format(
'YYYY-MM-DD HH:mm:ss'
)) ||
'暂未完成'
)
this.$set(
x.workItem,
'createTime',
moment(x.workItem.createTime).format('YYYY-MM-DD HH:mm:ss')
)
this.$set(x.workItem, 'vote', x.workItem.vote || '暂未处理')
return x
})
return item
})
})
.catch((e) => {
console.log(e)
})
},
getAffectedData () {
const subTypeName = this.$route.query.subTypeName
if (subTypeName.includes('DesignECR')) {
this.isAffectedShow = true
this.getAffectedAI()
} else if (
subTypeName.includes('SupplierPR') ||
subTypeName.includes('DesignPR')
) {
this.isAffectedShow = true
this.getAffectedAIPR()
} else {
this.getRequestAffectedData()
}
},
async getAffectedAI () {
const params = this.$utils.formDataParams({ oid: this.id })
await getAffectedAI(params)
.then(async (res) => {
this.affectedAIData = []
this.affectedAIData.push(...res.items)
})
.catch((e) => {
console.log(e)
})
},
async getAffectedAIPR () {
const params = this.$utils.formDataParams({ oid: this.id })
await getAffectedAIPR(params)
.then(async (res) => {
this.affectedAIData = res.items
})
.catch((e) => {
console.log(e)
})
},
async getRequestAffectedData () {
await getRequestAffectedData(this.id)
.then(async (res) => {
this.affectedData = this.formatData(res.items)
})
.catch((e) => {
console.log(e)
})
},
formatData (items) {
return items.map((item) => {
this.$set(
item,
'modifyTime',
moment(item.changeable.modifyTime).format('YYYY-MM-DD HH:mm:ss')
)
this.$set(item, 'modifier', item.changeable.modifier.fullName)
this.$set(item, 'state', item.changeable.state.display)
this.$set(
item,
'version',
item.changeable.versionId + '.' + item.changeable.iterationId
)
this.$set(item, 'comment', item.comment || '无')
return item
})
},
async getRequestGeneratedData () {
await getRequestGeneratedData(this.id)
.then(async (res) => {
this.generatedData = this.formatData(res.items)
})
.catch((e) => {
console.log(e)
})
},
async getObject () {
const dxClassName = this.$route.query.dxClassName
const subTypeName = this.$route.query.subTypeName
await getObject(this.id, dxClassName, subTypeName)
.then((res) => {
this.initData(res.items)
})
.catch((e) => {
console.log(e)
})
},
async initData (val) {
if (val?.subTypeName) {
this.form = {}
const firstStr = val.subTypeName
const firstIndex = firstStr.indexOf('_')
await getLayouts(firstStr.substring(0, firstIndex), 2).then((x) => {
if (
x.code === 0 &&
x.items.length > 0 &&
Object.prototype.hasOwnProperty.call(x.items[0], 'configDetails')
) {
let formData = []
formData = JSON.parse(x.items[0].configDetails).formData
const form = {}
if (Object.prototype.hasOwnProperty.call(val, 'defaultUnit')) {
getQuantityUnitDisplay(
this.$utils.formDataParams({ unit: val.defaultUnit })
).then((res) => {
// form.defaultUnit = res.items
this.$set(this.form, 'defaultUnit', res.items)
})
}
let n = -1
// 处理标准描述
formData.forEach((item) => {
n = n + 1
let j = -1
item.data.forEach((dataItem) => {
j = j + 1
if (
!Object.prototype.hasOwnProperty.call(dataItem, 'component')
) {
const copy = formData[0].data[0]
const component = { name: 'readable' }
copy.title = dataItem.title
copy.key = dataItem.key
copy.component = component
formData[n].data[j] = copy
}
if (dataItem.key === 'standardDesc') {
// 修改formData
this.changeFormData(formData, 'standardDesc')
// 获取标准描述
this.getStandardDesc(dataItem.key)
}
})
})
val.dynamicProperties.forEach((item) => {
form[item.attrName] = item.attrValue
this.$set(form, item.attrName, item.attrValue)
})
this.dxContentItems = val.dxContentItems.map((item) => {
this.$set(
item,
'createTime',
moment(item.createTime).format('YYYY-MM-DD HH:mm')
)
return item
})
this.$nextTick(() => {
this.form = Object.assign(form, this.getFormData(val))
if (
Object.keys(this.form).includes('responsiblePerson') &&
val.subTypeName.includes('SHActionItem')
) {
if (this.form.responsiblePerson) {
getResponsibleDisplay({
oid: this.form.responsiblePerson
}).then((res) => {
this.form.responsiblePerson = res.items || ''
})
}
}
})
if (Object.keys(this.form).includes('extProposedSolution')) {
// 修改formData
this.changeFormData(this.formData, 'extProposedSolution')
// 获取解决方案值
this.getSolution()
}
this.formData = formData
}
})
// if (this.businessType === 'DxDocument') {
// await this.viewHideAttribute()
// }
if (
firstStr.split('___')[1] === '工序' ||
firstStr.split('___')[1] === '标准工序'
) {
this.formData.push({
title: '',
split: 1,
data: [
{
title: '工序描述',
key: 'longDescription',
isBase: true,
component: {
name: 'readable',
isStandard: true,
disabled: true
}
}
]
})
} else if (
['AO', 'AOR', '软件/电子硬件AOR'].includes(firstStr.split('___')[1])
) {
// this.imgdata()
}
}
// else if (this.subTitle === 'PBOM') {
// // this.getPBOMNodeType(this.id)
// console.log(this.subTitle)
// } else if (this.subTitle === 'MBOM') {
// // this.getMBOMNodeType(this.id)
// console.log(this.subTitle)
// }
},
changeFormData (formData, key) {
formData.forEach((item) => {
item.data.forEach((dataItem) => {
if (dataItem.key === key) {
dataItem.component = {
name: 'readable',
isStandard: true,
disabled: true
}
}
})
})
return formData
},
getStandardDesc (key) {
// const params = {
// oid: this.id
// }
// viewStandardDesc(params).then(res => {
// this.$set(this.form, key, res.items[key])
// })
},
getSolution () {
const params = {
oid: this.id
}
SolutionValue(this.$utils.formDataParams(params)).then((res) => {
if (res.code === 0) {
const response = (res.items && res.items.iba) || {}
// eslint-disable-next-line no-unused-vars
for (const key in response) {
this.form[key] = response[key]
}
}
}) // .catch(err => {})
},
getFormData (x) {
const form = {
name: x.name,
number: x.number,
subTypeName: x.subTypeName.substring(
x.subTypeName.lastIndexOf('_') + 1
),
versionId: x.versionId && x.versionId + '.' + x.iterationId,
state: x.state && x.state.display,
modifier: x.modifier && `${x.modifier.fullName}(${x.modifier.name})`,
creator: x.creator && `${x.creator.fullName}(${x.creator.name})`,
description: x.description && x.description,
view: x.view,
endItem: x.endItem === true ? '是' : '否',
longDescription: x.longDescription,
createTime:
x.createTime && moment(x.createTime).format('YYYY-MM-DD HH:mm'),
modifyTime:
x.modifyTime && moment(x.modifyTime).format('YYYY-MM-DD HH:mm')
}
this.title =
form.subTypeName +
'-' +
form.number +
',' +
form.name +
',' +
form.versionId +
'(' +
form.state +
')'
return form
},
renderContent (h, { data }) {
// const str = data.name ? data.number + ' ' + data.name + ' ' + data.displayVersion : data.target.number + ' ' + data.target.name + ' ' + data.target.displayVersion
return h('span', null, [h('span', null, data.label)])
}
}
}
</script>
<style lang="scss">
.bomStructure {
overflow: hidden;
height: 100%;
width: 100%;
.searchModel {
padding-bottom: 15%;
display: flex;
}
.searchTree {
margin-top: 60px;
.van-tabs__wrap {
height: 50px;
}
.van-tabs__content {
overflow-y: auto;
height: calc(100vh - 170px);
}
.van-tab--active {
color: #1b77ea;
}
.van-tabs__line {
background: linear-gradient(207deg, #68b7f6 0%, #5baaf2 100%);
}
.data-detail {
width: 100%;
.van-row {
width: 100%;
}
.sub-content {
text-align: center;
}
.van-row .van-col a {
font-size: 14px;
line-height: 14px;
height: 14px;
padding: 20px;
}
/*.prompt-text {*/
/* font-size: 12px;*/
/* color: red;*/
/* // background: ;*/
/* padding: 20px 10px;*/
/*}*/
.right {
text-align: right;
}
.center {
font-size: 20px;
}
// .van-cell__title {
// margin-right: 30px;
// }
.van-col-class .van-cell {
background: #f5f9fc;
margin-bottom: 10px;
border-radius: 8px;
font-size: 12px;
}
.van-col-class {
padding: 20px;
}
.van-col-span {
width: 60px;
box-sizing: border-box;
display: inline-block;
text-align: justify;
text-align-last: justify;
vertical-align: middle; /*保证文字和input框上下是对齐的*/
padding-right: 8px;
}
}
}
.data-Package-Info-card {
.custom-title {
margin-right: 4px;
vertical-align: middle;
}
.title-value {
padding-left: 5px;
}
.title-value-style span:nth-child(even) {
color: rgb(78, 84, 87);
font-weight: 600;
}
.title-value-number .title-value {
font-weight: 900;
}
}
.tree-title {
display: block;
/*color:#666;*/
font-size: 3.7333333333333vw;
font-weight: bold;
padding: 0.315rem 1.625rem;
.van-tag {
padding: 0;
margin: 3%;
}
}
.center {
margin-top: 0;
display: flex;
align-items: center;
}
}
</style>
......@@ -65,7 +65,7 @@ export default {
activeTab: null,
tabs: [
{ title: '基本信息', key: 'baseInfoDetail' },
{ title: '浏览', key: 'pdf' }
{ title: '查看附件', key: 'pdf' }
],
dxContentItems: {},
url: '',
......
......@@ -31,7 +31,7 @@
</template>
<script>
import { getInstTaskHisTory } from '@/api/taskDetail'
import { getInstTaskHisTory, getDictListByCode } from '@/api/taskDetail'
export default {
props: {
flowData: {
......@@ -54,8 +54,9 @@ export default {
},
created () {
},
mounted () {
this.getWorkItemHistory()
async mounted () {
await this.getDictArr()
await this.getWorkItemHistory()
},
computed: {},
methods: {
......@@ -87,22 +88,16 @@ export default {
(dateEnd.getTime() - dateStart.getTime()) / (1000 * 60 * 60 * 24)
)
},
getDictArr () {
getDictListByCode('MigrationPlanStatus').then(res => {
if (!res || !res.items) {
return []
}
this.dictArr = res.items.content
})
},
translateStatus(status) {
let str = ''
switch (status) {
case 'COMPLETE':
str = '已完成'
break
case 'BE_RESOLVED':
str = '待处理'
break
case 'PENDING':
str = '被委托人待处理'
break
case 'RUNNING':
str = '进行中'
}
return str
return this.dictArr.find(item => item.dictKey === status)?.dictValue
}
}
}
......
<template>
<div class="taskDetails">
<headerNavBar title="任务详情" @click-left="onClickLeft" />
<headerNavBar :title="$route.query.taskType+'详情'" @click-left="onClickLeft" />
<div class="taskBasicInfo">
<task-basic-info
v-if="basicData && form"
......@@ -15,7 +15,7 @@
v-if="componentsShow"
:class="[
['已办任务', '我发起的任务'].includes($route.query.taskType) &&
item.title !== '签署文档'
item.title !== '签署文档' && item.title !== '签审历史'
? 'form-onlyRead'
: ''
]"
......
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