flx:新增施工图纸
This commit is contained in:
parent
29ba5d4efa
commit
16e596cb14
BIN
src/assets/images/draw-point.png
Normal file
BIN
src/assets/images/draw-point.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
@ -55,6 +55,22 @@ export const editQualityRegionListApi = data => post('xmgl/qualityRegion/edit',
|
|||||||
export const deleteBatchQualityRegionListApi = data => post('xmgl/qualityRegion/deleteBatch', data); //检查部位 删除 节点
|
export const deleteBatchQualityRegionListApi = data => post('xmgl/qualityRegion/deleteBatch', data); //检查部位 删除 节点
|
||||||
// 树状分页
|
// 树状分页
|
||||||
export const getQualityRegionTreePageApi = data => post('xmgl/qualityRegion/tree/page', data); //检查部位 列表查询
|
export const getQualityRegionTreePageApi = data => post('xmgl/qualityRegion/tree/page', data); //检查部位 列表查询
|
||||||
|
|
||||||
|
// 图纸管理
|
||||||
|
// 树形列表查询区域和施工图纸
|
||||||
|
export const getQualityRegionConstructionDrawTreePageApi = data => post('xmgl/qualityRegion/constructionDraw/tree/list', data); //区域施工图纸信息
|
||||||
|
// 列表查询区域施工图纸信息
|
||||||
|
export const getQualityRegionConstructionDrawListApi = data => get('xmgl/qualityRegionConstructionDraw/list', data); //区域施工图纸信息
|
||||||
|
// 添加区域施工图纸信息
|
||||||
|
export const addQualityRegionConstructionDrawApi = data => post('xmgl/qualityRegionConstructionDraw/add', data); //区域施工图纸信息
|
||||||
|
// 编辑区域施工图纸信息
|
||||||
|
export const editQualityRegionConstructionDrawApi = data => post('xmgl/qualityRegionConstructionDraw/edit', data); //区域施工图纸信息
|
||||||
|
// 删除区域施工图纸信息
|
||||||
|
export const deleteQualityRegionConstructionDrawApi = data => post('xmgl/qualityRegionConstructionDraw/delete', data); //区域施工图纸信息
|
||||||
|
// 通过id查询区域施工图纸信息
|
||||||
|
export const getQualityRegionConstructionDrawByIdApi = data => get('xmgl/qualityRegionConstructionDraw/queryById', data); //区域施工图纸信息
|
||||||
|
|
||||||
|
|
||||||
// 批量修改单位和人员数据
|
// 批量修改单位和人员数据
|
||||||
export const batchEditEnterprisesAndUsersApi = data => post('xmgl/qualityRegion/batch/editEnterprisesAndUsers', data); //检查部位 列表查询
|
export const batchEditEnterprisesAndUsersApi = data => post('xmgl/qualityRegion/batch/editEnterprisesAndUsers', data); //检查部位 列表查询
|
||||||
//数据中心
|
//数据中心
|
||||||
|
|||||||
@ -181,34 +181,34 @@ if (process.env.NODE_ENV == "development") {
|
|||||||
// axios.defaults.baseURL = 'http://192.168.34.221:28889/' //郭圣雄本地
|
// axios.defaults.baseURL = 'http://192.168.34.221:28889/' //郭圣雄本地
|
||||||
// axios.defaults.baseURL = 'http://192.168.34.221:28890/' //郭圣雄本地
|
// axios.defaults.baseURL = 'http://192.168.34.221:28890/' //郭圣雄本地
|
||||||
// axios.defaults.baseURL = "http://192.168.34.221:9111/"; //郭圣雄本地
|
// axios.defaults.baseURL = "http://192.168.34.221:9111/"; //郭圣雄本地
|
||||||
// axios.defaults.baseURL = "http://192.168.34.221:19112/"; //郭圣雄本地
|
axios.defaults.baseURL = "http://192.168.34.221:19112/"; //郭圣雄本地
|
||||||
// axios.defaults.baseURL = 'http://192.168.34.155:19111/' //彭洁本地
|
// axios.defaults.baseURL = 'http://192.168.34.155:19111/' //彭洁本地
|
||||||
// axios.defaults.baseURL = 'http://182.90.224.237:51234/' //郭圣雄远程
|
// axios.defaults.baseURL = 'http://182.90.224.237:51234/' //郭圣雄远程
|
||||||
// axios.defaults.baseURL = 'http://jxj.zhgdyun.com:61212/' //彭洁远程
|
// axios.defaults.baseURL = 'http://jxj.zhgdyun.com:61212/' //彭洁远程
|
||||||
// axios.defaults.baseURL ='http://101.43.164.214:45020/' //沈阳和盈
|
// axios.defaults.baseURL ='http://101.43.164.214:45020/' //沈阳和盈
|
||||||
// axios.defaults.baseURL ='http://183.249.224.118:9000/' //嘉兴王江泾公用码头
|
// axios.defaults.baseURL ='http://183.249.224.118:9000/' //嘉兴王江泾公用码头
|
||||||
// axios.defaults.baseURL = 'http://101.43.164.214:11111/' // 百色三标段项目
|
// axios.defaults.baseURL = 'http://101.43.164.214:11111/' // 百色三标段项目
|
||||||
// axios.defaults.baseURL = 'http://125.88.207.86:8088/'//中建四局线上(最新)地址
|
// axios.defaults.baseURL = 'http://125.88.207.86:8088/'//中建四局线上(最新)地址
|
||||||
// axios.defaults.baseURL = 'http://125.88.207.86:8099/'//中建四局(沙湖)线上(最新)地址
|
// axios.defaults.baseURL = 'http://125.88.207.86:8099/'//中建四局(沙湖)线上(最新)地址
|
||||||
// axios.defaults.baseURL = 'http://jxj.zhgdyun.com:15551/'//测试地址
|
// axios.defaults.baseURL = 'http://jxj.zhgdyun.com:15551/'//测试地址
|
||||||
// axios.defaults.baseURL = 'http://47.93.215.234:9809/'//鞍钢正式地址(弃用)
|
// axios.defaults.baseURL = 'http://47.93.215.234:9809/'//鞍钢正式地址(弃用)
|
||||||
// axios.defaults.baseURL = 'http://42.180.188.17:9809/' //鞍钢正式地址
|
// axios.defaults.baseURL = 'http://42.180.188.17:9809/' //鞍钢正式地址
|
||||||
// axios.defaults.baseURL = 'http://47.93.215.234:11211/'//鞍钢测试地址(弃用)
|
// axios.defaults.baseURL = 'http://47.93.215.234:11211/'//鞍钢测试地址(弃用)
|
||||||
// axios.defaults.baseURL = 'http://42.180.188.17:11211/' //鞍钢测试地址
|
// axios.defaults.baseURL = 'http://42.180.188.17:11211/' //鞍钢测试地址
|
||||||
// axios.defaults.baseURL = 'http://8.136.222.164:8808/' //中科安信正式地址
|
// axios.defaults.baseURL = 'http://8.136.222.164:8808/' //中科安信正式地址
|
||||||
// axios.defaults.baseURL = 'http://1.13.185.209:9820/' //中科佳成正式地址
|
// axios.defaults.baseURL = 'http://1.13.185.209:9820/' //中科佳成正式地址
|
||||||
// axios.defaults.baseURL = 'http://192.168.9.249:9820/' //四川网城正式地址
|
// axios.defaults.baseURL = 'http://192.168.9.249:9820/' //四川网城正式地址
|
||||||
// axios.defaults.baseURL = 'http://jxj.zhgdyun.com:34568/' //四川网城外网映射地址
|
// axios.defaults.baseURL = 'http://jxj.zhgdyun.com:34568/' //四川网城外网映射地址
|
||||||
// axios.defaults.baseURL = 'http://192.168.110.220:9809/' //同济正式地址
|
// axios.defaults.baseURL = 'http://192.168.110.220:9809/' //同济正式地址
|
||||||
// axios.defaults.baseURL = 'http://192.168.100.4:9809/' //乌丹(合肥启程)新正式地址
|
// axios.defaults.baseURL = 'http://192.168.100.4:9809/' //乌丹(合肥启程)新正式地址
|
||||||
// axios.defaults.baseURL = "http://jxj.zhgdyun.com:18000"; //包头化工
|
// axios.defaults.baseURL = "http://jxj.zhgdyun.com:18000"; //包头化工
|
||||||
// axios.defaults.baseURL = "http://222.80.185.228:6090"; //木垒
|
// axios.defaults.baseURL = "http://222.80.185.228:6090"; //木垒
|
||||||
// axios.defaults.baseURL = "https://zm.zhgdyun.com:11111";
|
// axios.defaults.baseURL = "https://zm.zhgdyun.com:11111";
|
||||||
// // axios.defaults.baseURL = "http://121.37.106.37:9809";
|
// // axios.defaults.baseURL = "http://121.37.106.37:9809";
|
||||||
// axios.defaults.baseURL = "http://139.9.66.234:20628";
|
// axios.defaults.baseURL = "http://139.9.66.234:20628";
|
||||||
// axios.defaults.baseURL = "http://jxj.zhgdyun.com:9500";
|
// axios.defaults.baseURL = "http://jxj.zhgdyun.com:9500";
|
||||||
// axios.defaults.baseURL = "http://jxj.zhgdyun.com:21000/"; // 潮州
|
// axios.defaults.baseURL = "http://jxj.zhgdyun.com:21000/"; // 潮州
|
||||||
// axios.defaults.baseURL = "http://gszhdz.crpower.com.cn:9809/"; // 敦煌
|
// axios.defaults.baseURL = "http://gszhdz.crpower.com.cn:9809/"; // 敦煌
|
||||||
} else if (process.env.NODE_ENV == "debug") {
|
} else if (process.env.NODE_ENV == "debug") {
|
||||||
axios.defaults.baseURL = "https://www.ceshi.com";
|
axios.defaults.baseURL = "https://www.ceshi.com";
|
||||||
} else if (process.env.NODE_ENV == "production") {
|
} else if (process.env.NODE_ENV == "production") {
|
||||||
@ -402,4 +402,8 @@ function startLoading() {
|
|||||||
|
|
||||||
function endLoading() {
|
function endLoading() {
|
||||||
loading.close();
|
loading.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function baseURL() {
|
||||||
|
return axios.defaults.baseURL;
|
||||||
|
};
|
||||||
547
src/components/ImageAnnotation.vue
Normal file
547
src/components/ImageAnnotation.vue
Normal file
@ -0,0 +1,547 @@
|
|||||||
|
<template>
|
||||||
|
<div class="simple-image-annotator">
|
||||||
|
<div class="controls">
|
||||||
|
<!-- 只有在编辑模式下才显示操作按钮 -->
|
||||||
|
<div v-if="viewMode === 'edit'">
|
||||||
|
<el-button
|
||||||
|
@click="setAddMode"
|
||||||
|
size="medium"
|
||||||
|
type="primary"
|
||||||
|
:class="{ active: mode === 'add' }"
|
||||||
|
>
|
||||||
|
新增点位
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
@click="setDeleteMode"
|
||||||
|
plain
|
||||||
|
size="medium"
|
||||||
|
type="danger"
|
||||||
|
:class="{ active: mode === 'delete' }"
|
||||||
|
>
|
||||||
|
删除点位
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
<!-- 详情模式下显示提示文本 -->
|
||||||
|
<!-- <div v-else-if="viewMode === 'detail'" class="detail-mode-tip">
|
||||||
|
详情模式:已禁止新增和删除操作
|
||||||
|
</div> -->
|
||||||
|
<!-- <button @click="clearAllPoints" class="clear-btn">清空所有点位</button>
|
||||||
|
<span class="point-count">已标注: {{ points.length }} 个点位</span> -->
|
||||||
|
</div>
|
||||||
|
<div class="image-container" ref="imageContainer">
|
||||||
|
<img
|
||||||
|
ref="image"
|
||||||
|
:src="imagePath"
|
||||||
|
alt="标注图片"
|
||||||
|
@load="handleImageLoad"
|
||||||
|
@click="handleImageClick"
|
||||||
|
/>
|
||||||
|
<div class="annotation-layer" ref="annotationLayer" style="position: absolute;">
|
||||||
|
<div
|
||||||
|
v-for="point in points"
|
||||||
|
:key="point.id"
|
||||||
|
class="annotation-point"
|
||||||
|
:style="getPointPositionStyle(point)"
|
||||||
|
@click.stop="handlePointClick(point.id)"
|
||||||
|
@contextmenu.prevent="handleRightClick(point.id)"
|
||||||
|
>
|
||||||
|
<!-- <span class="point-index">{{ point.x }}</span> -->
|
||||||
|
<!-- <span class="delete-btn" @click.stop="deletePoint(index)">×</span> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'SimpleImageAnnotator',
|
||||||
|
props: {
|
||||||
|
imagePath: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
drawingPointData: {
|
||||||
|
type: Array,
|
||||||
|
default() {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
viewMode: {
|
||||||
|
type: String,
|
||||||
|
default: 'edit', // edit: 编辑模式, detail: 详情模式
|
||||||
|
validator(value) {
|
||||||
|
return ['edit', 'detail'].includes(value)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
points: [],
|
||||||
|
imageNaturalWidth: 0,
|
||||||
|
imageNaturalHeight: 0,
|
||||||
|
containerWidth: 0,
|
||||||
|
containerHeight: 0,
|
||||||
|
scale: 1,
|
||||||
|
mode: 'add' // 默认模式为新增点位
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
viewMode(newMode) {
|
||||||
|
// 根据视图模式更新内部状态
|
||||||
|
if (newMode === 'detail') {
|
||||||
|
this.mode = 'detail'
|
||||||
|
} else {
|
||||||
|
this.mode = 'add'
|
||||||
|
}
|
||||||
|
this.$emit('modeChanged', this.mode)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.initContainerSize()
|
||||||
|
window.addEventListener('resize', this.handleResize)
|
||||||
|
// 初始化时根据viewMode设置mode
|
||||||
|
if (this.viewMode === 'detail') {
|
||||||
|
this.mode = 'detail'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
watchRef() {
|
||||||
|
return {
|
||||||
|
imagePath: this.imagePath,
|
||||||
|
drawingPointData: this.drawingPointData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
imagePath: {
|
||||||
|
handler(newPath) {
|
||||||
|
if (newPath) {
|
||||||
|
console.log('Image path changed:', newPath);
|
||||||
|
this.resetViewer()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
immediate: true,
|
||||||
|
deep: true
|
||||||
|
},
|
||||||
|
// watchRef: {
|
||||||
|
// handler(newData) {
|
||||||
|
// this.resetViewer();
|
||||||
|
// if(newData.drawingPointData) {
|
||||||
|
// this.points = newData.drawingPointData;
|
||||||
|
// }
|
||||||
|
// console.log('drawingPointData changed:', this.points);
|
||||||
|
// },
|
||||||
|
// immediate: true,
|
||||||
|
// deep: true
|
||||||
|
// },
|
||||||
|
drawingPointData: {
|
||||||
|
handler(newData) {
|
||||||
|
// this.resetPosit();
|
||||||
|
// 对传入的点位数据进行标准化处理,确保所有点位都包含原始图片尺寸信息
|
||||||
|
const normalizedData = this.normalizePointsData(newData);
|
||||||
|
this.points = JSON.parse(JSON.stringify(normalizedData));
|
||||||
|
console.log('drawingPointData changed:', this.points);
|
||||||
|
},
|
||||||
|
immediate: true,
|
||||||
|
deep: true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.initContainerSize()
|
||||||
|
window.addEventListener('resize', this.handleResize)
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
window.removeEventListener('resize', this.handleResize)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 初始化容器大小
|
||||||
|
initContainerSize() {
|
||||||
|
if (this.$refs.imageContainer) {
|
||||||
|
const container = this.$refs.imageContainer
|
||||||
|
this.containerWidth = container.clientWidth
|
||||||
|
this.containerHeight = container.clientHeight
|
||||||
|
|
||||||
|
// 如果图片已经加载,重新计算缩放
|
||||||
|
if (this.imageNaturalWidth && this.imageNaturalHeight) {
|
||||||
|
this.calculateScale()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 处理窗口大小变化
|
||||||
|
handleResize() {
|
||||||
|
this.initContainerSize()
|
||||||
|
},
|
||||||
|
|
||||||
|
// 处理图片加载
|
||||||
|
handleImageLoad(event) {
|
||||||
|
const img = event.target
|
||||||
|
// 使用图片的实际渲染宽度和高度,而不是原始尺寸
|
||||||
|
this.imageNaturalWidth = img.clientWidth
|
||||||
|
this.imageNaturalHeight = img.clientHeight
|
||||||
|
this.calculateScale()
|
||||||
|
},
|
||||||
|
|
||||||
|
// 计算缩放比例
|
||||||
|
calculateScale() {
|
||||||
|
if (!this.imageNaturalWidth || !this.imageNaturalHeight || !this.$refs.image || !this.$refs.annotationLayer) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取容器和图片的实际尺寸
|
||||||
|
const container = this.$refs.imageContainer
|
||||||
|
const containerRect = container.getBoundingClientRect()
|
||||||
|
const img = this.$refs.image
|
||||||
|
const imgRect = img.getBoundingClientRect()
|
||||||
|
|
||||||
|
// 计算实际显示的缩放比例(基于DOM中图片的实际尺寸)
|
||||||
|
this.scale = imgRect.width / this.imageNaturalWidth
|
||||||
|
|
||||||
|
// 直接将标注层与图片完全重叠
|
||||||
|
const layer = this.$refs.annotationLayer
|
||||||
|
layer.style.width = imgRect.width + 'px'
|
||||||
|
layer.style.height = imgRect.height + 'px'
|
||||||
|
layer.style.left = (containerRect.width - imgRect.width) / 2 + 'px'
|
||||||
|
layer.style.top = (containerRect.height - imgRect.height) / 2 + 'px'
|
||||||
|
layer.style.transformOrigin = 'top left'
|
||||||
|
},
|
||||||
|
|
||||||
|
// 处理图片点击事件
|
||||||
|
handleImageClick(event) {
|
||||||
|
// 只有在编辑模式且为新增模式时才允许添加点位
|
||||||
|
if (this.viewMode === 'edit' && this.mode === 'add') {
|
||||||
|
// 直接使用相对于标注层的位置
|
||||||
|
const annotationLayer = this.$refs.annotationLayer
|
||||||
|
const layerRect = annotationLayer.getBoundingClientRect()
|
||||||
|
// 计算鼠标在标注层内的相对位置(考虑缩放)
|
||||||
|
const x = (event.clientX - layerRect.left) / this.scale
|
||||||
|
const y = (event.clientY - layerRect.top) / this.scale
|
||||||
|
this.addPoint(x, y)
|
||||||
|
}
|
||||||
|
// 删除模式或详情模式下,点击图片空白区域不执行操作
|
||||||
|
},
|
||||||
|
|
||||||
|
// 生成唯一ID
|
||||||
|
generateUniqueId() {
|
||||||
|
return Date.now() + '_' + Math.floor(Math.random() * 10000)
|
||||||
|
},
|
||||||
|
|
||||||
|
// 添加标注点
|
||||||
|
addPoint(x, y) {
|
||||||
|
console.log('Adding point at:', x, y)
|
||||||
|
console.log(this.imageNaturalWidth, this.imageNaturalHeight)
|
||||||
|
// 确保坐标在有效范围内
|
||||||
|
const validX = Math.max(0, Math.min(x, this.imageNaturalWidth))
|
||||||
|
const validY = Math.max(0, Math.min(y, this.imageNaturalHeight))
|
||||||
|
console.log('Valid X, Y:', validX, validY)
|
||||||
|
const newPoint = {
|
||||||
|
id: this.generateUniqueId(),
|
||||||
|
x: validX,
|
||||||
|
y: validY,
|
||||||
|
// 记录点位创建时的原始图片尺寸
|
||||||
|
originalImageWidth: this.imageNaturalWidth,
|
||||||
|
originalImageHeight: this.imageNaturalHeight
|
||||||
|
}
|
||||||
|
|
||||||
|
this.points.push(newPoint)
|
||||||
|
this.$emit('pointsChanged', this.points)
|
||||||
|
this.$emit('pointAdded', newPoint)
|
||||||
|
},
|
||||||
|
|
||||||
|
// 处理标注点点击
|
||||||
|
handlePointClick(pointId) {
|
||||||
|
// 只有在编辑模式且为删除模式时才允许删除点位
|
||||||
|
if (this.viewMode === 'edit' && this.mode === 'delete') {
|
||||||
|
this.deletePoint(pointId)
|
||||||
|
} else {
|
||||||
|
// 新增模式或详情模式下,触发点位选中事件
|
||||||
|
const point = this.points.find(p => p.id === pointId)
|
||||||
|
if (point) {
|
||||||
|
this.$emit('pointSelected', { id: pointId, point })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 设置为新增模式
|
||||||
|
setAddMode() {
|
||||||
|
if (this.viewMode === 'edit') {
|
||||||
|
this.mode = 'add'
|
||||||
|
if (this.$refs.image) {
|
||||||
|
this.$refs.image.style.cursor = 'crosshair'
|
||||||
|
}
|
||||||
|
this.$emit('modeChanged', 'add')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 设置为删除模式
|
||||||
|
setDeleteMode() {
|
||||||
|
if (this.viewMode === 'edit') {
|
||||||
|
this.mode = 'delete'
|
||||||
|
if (this.$refs.image) {
|
||||||
|
this.$refs.image.style.cursor = 'default'
|
||||||
|
}
|
||||||
|
this.$emit('modeChanged', 'delete')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 设置为详情模式
|
||||||
|
setDetailMode() {
|
||||||
|
this.mode = 'detail'
|
||||||
|
if (this.$refs.image) {
|
||||||
|
this.$refs.image.style.cursor = 'default'
|
||||||
|
}
|
||||||
|
this.$emit('modeChanged', 'detail')
|
||||||
|
},
|
||||||
|
|
||||||
|
// 处理右键点击
|
||||||
|
handleRightClick(pointId) {
|
||||||
|
// 只有在编辑模式下才允许右键删除点位
|
||||||
|
if (this.viewMode === 'edit') {
|
||||||
|
this.deletePoint(pointId)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 删除标注点
|
||||||
|
deletePoint(pointId) {
|
||||||
|
const pointIndex = this.points.findIndex(p => p.id === pointId)
|
||||||
|
if (pointIndex !== -1) {
|
||||||
|
const deletedPoint = this.points[pointIndex]
|
||||||
|
this.points.splice(pointIndex, 1)
|
||||||
|
this.$emit('pointsChanged', this.points)
|
||||||
|
this.$emit('pointDeleted', deletedPoint)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算点位在当前图片上的实际显示位置
|
||||||
|
* 考虑点位创建时的原始图片尺寸与当前显示图片尺寸的差异
|
||||||
|
*/
|
||||||
|
getPointPositionStyle(point) {
|
||||||
|
// 获取点位创建时的原始图片尺寸
|
||||||
|
const originalWidth = point.originalImageWidth || this.imageNaturalWidth
|
||||||
|
const originalHeight = point.originalImageHeight || this.imageNaturalHeight
|
||||||
|
|
||||||
|
// 计算相对于原始图片的位置比例
|
||||||
|
const relativeX = point.x / originalWidth
|
||||||
|
const relativeY = point.y / originalHeight
|
||||||
|
|
||||||
|
// 根据当前图片尺寸和相对位置计算实际显示位置
|
||||||
|
const displayX = relativeX * this.imageNaturalWidth
|
||||||
|
const displayY = relativeY * this.imageNaturalHeight
|
||||||
|
|
||||||
|
// 应用当前的缩放比例
|
||||||
|
return {
|
||||||
|
left: displayX * this.scale + 'px',
|
||||||
|
top: displayY * this.scale + 'px'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标准化点位数据,确保所有点位都包含原始图片尺寸信息
|
||||||
|
* @param {Array} pointsArray - 点位数组
|
||||||
|
* @returns {Array} - 标准化后的点位数组
|
||||||
|
*/
|
||||||
|
normalizePointsData(pointsArray) {
|
||||||
|
if (!Array.isArray(pointsArray)) return []
|
||||||
|
|
||||||
|
return pointsArray.map(point => {
|
||||||
|
// 如果点位没有原始图片尺寸信息,添加当前图片尺寸
|
||||||
|
if (!point.originalImageWidth || !point.originalImageHeight) {
|
||||||
|
return {
|
||||||
|
...point,
|
||||||
|
originalImageWidth: this.imageNaturalWidth || point.originalImageWidth,
|
||||||
|
originalImageHeight: this.imageNaturalHeight || point.originalImageHeight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return point
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
// 清空所有标注点
|
||||||
|
clearAllPoints() {
|
||||||
|
this.points = []
|
||||||
|
this.$emit('allPointsCleared')
|
||||||
|
},
|
||||||
|
|
||||||
|
// 重置查看器
|
||||||
|
resetViewer() {
|
||||||
|
// this.points = []
|
||||||
|
this.imageNaturalWidth = 0
|
||||||
|
this.imageNaturalHeight = 0
|
||||||
|
this.scale = 1
|
||||||
|
// 根据视图模式重置mode
|
||||||
|
if (this.viewMode === 'detail') {
|
||||||
|
this.mode = 'detail'
|
||||||
|
} else {
|
||||||
|
this.mode = 'add' // 重置为新增模式
|
||||||
|
}
|
||||||
|
if (this.$refs.image) {
|
||||||
|
this.$refs.image.style.cursor = this.mode === 'add' ? 'crosshair' : 'default'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
resetPosit() {
|
||||||
|
// 标准化点位数据后再设置
|
||||||
|
const normalizedData = this.normalizePointsData(this.drawingPointData);
|
||||||
|
this.points = JSON.parse(JSON.stringify(normalizedData));
|
||||||
|
this.mode = 'add' // 重置为新增模式
|
||||||
|
if (this.$refs.image) {
|
||||||
|
this.$refs.image.style.cursor = 'crosshair'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 获取所有点位
|
||||||
|
getAllPoints() {
|
||||||
|
// 返回点位数组的深拷贝,避免外部直接修改原始数据
|
||||||
|
return JSON.parse(JSON.stringify(this.points))
|
||||||
|
},
|
||||||
|
|
||||||
|
// 获取当前模式
|
||||||
|
getCurrentMode() {
|
||||||
|
return this.mode
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.simple-image-annotator {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-container {
|
||||||
|
position: relative;
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-container img {
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
cursor: crosshair;
|
||||||
|
transition: transform 0.2s;
|
||||||
|
width: 100%;
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 详情模式下图片指针样式 */
|
||||||
|
.detail-mode img {
|
||||||
|
cursor: default !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.annotation-layer {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
transform-origin: top left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.annotation-point {
|
||||||
|
position: absolute;
|
||||||
|
width: 28px;
|
||||||
|
height: 43px;
|
||||||
|
/* background-color: rgba(255, 69, 0, 0.8); */
|
||||||
|
/* border-radius: 50%; */
|
||||||
|
background-image: url("~@/assets/images/draw-point.png");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
pointer-events: all;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: white;
|
||||||
|
font-weight: bold;
|
||||||
|
/* box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); */
|
||||||
|
}
|
||||||
|
|
||||||
|
.annotation-point:hover {
|
||||||
|
/* background-color: rgba(255, 0, 0, 0.9); */
|
||||||
|
transform: translate(-50%, -50%) scale(1.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.annotation-point .delete-btn {
|
||||||
|
position: absolute;
|
||||||
|
top: -8px;
|
||||||
|
right: -8px;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: #ff4500;
|
||||||
|
font-size: 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
border: 1px solid #ff4500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.annotation-point .delete-btn:hover {
|
||||||
|
background-color: #ff4500;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.point-index {
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.controls {
|
||||||
|
padding: 0 10px 10px;
|
||||||
|
background-color: white;
|
||||||
|
/* border-top: 1px solid #e0e0e0; */
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control-btn {
|
||||||
|
padding: 6px 16px;
|
||||||
|
background-color: #4CAF50;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control-btn:hover {
|
||||||
|
background-color: #45a049;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control-btn.active {
|
||||||
|
background-color: #2196F3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clear-btn {
|
||||||
|
padding: 6px 16px;
|
||||||
|
background-color: #ff4500;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.2s;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clear-btn:hover {
|
||||||
|
background-color: #ff6347;
|
||||||
|
}
|
||||||
|
|
||||||
|
.point-count {
|
||||||
|
color: #666;
|
||||||
|
font-size: 14px;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -3611,6 +3611,14 @@ const routes2 = [{
|
|||||||
"@/views/projectFront/operationManagement/truckCraneMonitoring.vue",
|
"@/views/projectFront/operationManagement/truckCraneMonitoring.vue",
|
||||||
], resolve),
|
], resolve),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/project/operationManagement/bridgeCraneMonitor",
|
||||||
|
name: "运维管理_桥吊监测",
|
||||||
|
component: (resolve) =>
|
||||||
|
require([
|
||||||
|
"@/views/projectFront/operationManagement/bridgeCraneMonitor.vue",
|
||||||
|
], resolve),
|
||||||
|
},
|
||||||
// 车辆定位
|
// 车辆定位
|
||||||
{
|
{
|
||||||
path: "/project/vehiclePosition/realTimeMonitor",
|
path: "/project/vehiclePosition/realTimeMonitor",
|
||||||
|
|||||||
@ -2,12 +2,13 @@ import Vue from "vue";
|
|||||||
import Vuex from "vuex";
|
import Vuex from "vuex";
|
||||||
import createPersistedState from "vuex-persistedstate";
|
import createPersistedState from "vuex-persistedstate";
|
||||||
import { initAI } from '@/util/ai';
|
import { initAI } from '@/util/ai';
|
||||||
|
import { baseURL } from '@/assets/js/http';
|
||||||
Vue.use(Vuex);
|
Vue.use(Vuex);
|
||||||
// import user from './module/user'
|
// import user from './module/user'
|
||||||
// import fileList from './module/fileList'
|
// import fileList from './module/fileList'
|
||||||
// import sideMenu from './module/sideMenu'
|
// import sideMenu from './module/sideMenu'
|
||||||
// import imgReview from './module/imgReview'
|
// import imgReview from './module/imgReview'
|
||||||
|
console.log(1111111111, baseURL())
|
||||||
export default new Vuex.Store({
|
export default new Vuex.Store({
|
||||||
plugins: [
|
plugins: [
|
||||||
createPersistedState({
|
createPersistedState({
|
||||||
@ -83,8 +84,8 @@ export default new Vuex.Store({
|
|||||||
// FILEURL: "http://192.168.34.155:19111/image/", //洁本地
|
// FILEURL: "http://192.168.34.155:19111/image/", //洁本地
|
||||||
// UPLOADURL: 'http://192.168.34.221:9111/upload/image/', // 郭圣雄本地
|
// UPLOADURL: 'http://192.168.34.221:9111/upload/image/', // 郭圣雄本地
|
||||||
// FILEURL: 'http://192.168.34.221:9111/image/', //郭圣雄本地
|
// FILEURL: 'http://192.168.34.221:9111/image/', //郭圣雄本地
|
||||||
// UPLOADURL: 'http://192.168.34.221:19112/upload/image/', // 郭圣雄本地
|
UPLOADURL: 'http://192.168.34.221:19112/upload/image/', // 郭圣雄本地
|
||||||
// FILEURL: 'http://192.168.34.221:19112/image/', //郭圣雄本地
|
FILEURL: 'http://192.168.34.221:19112/image/', //郭圣雄本地
|
||||||
// WORKFLOWURL: "http://192.168.34.216:88/#/workspace/forms", //jiayu工作流地址(本地)
|
// WORKFLOWURL: "http://192.168.34.216:88/#/workspace/forms", //jiayu工作流地址(本地)
|
||||||
// WORKFLOWURL: "http://192.168.34.138:88/#/workspace/forms", //坤工作流地址(本地)
|
// WORKFLOWURL: "http://192.168.34.138:88/#/workspace/forms", //坤工作流地址(本地)
|
||||||
// WORKFLOWURL: "http://192.168.34.129:88/#/workspace/forms", //罗峰工作流地址(本地)
|
// WORKFLOWURL: "http://192.168.34.129:88/#/workspace/forms", //罗峰工作流地址(本地)
|
||||||
@ -94,16 +95,15 @@ export default new Vuex.Store({
|
|||||||
// FILEURL:'http://182.90.224.237:51234/image/',//郭圣雄远程
|
// FILEURL:'http://182.90.224.237:51234/image/',//郭圣雄远程
|
||||||
// UPLOADURL: 'http://42.180.188.17:11211/upload/image', //测试
|
// UPLOADURL: 'http://42.180.188.17:11211/upload/image', //测试
|
||||||
// FILEURL: 'http://42.180.188.17:11211/image/', //测试
|
// FILEURL: 'http://42.180.188.17:11211/image/', //测试
|
||||||
BASEURL: baseUrl ?
|
// BASEURL: baseUrl ?
|
||||||
baseUrl : window.location.protocol + "//" + window.location.host + "/", //正式环境
|
// baseUrl : window.location.protocol + "//" + window.location.host + "/", //正式环境
|
||||||
UPLOADURL: window.location.protocol + "//" + window.location.host + "/upload/image", //正式环境
|
// UPLOADURL: window.location.protocol + "//" + window.location.host + "/upload/image", //正式环境
|
||||||
FILEURL: window.location.protocol + "//" + window.location.host + "/image/", //正式环境
|
// FILEURL: window.location.protocol + "//" + window.location.host + "/image/", //正式环境
|
||||||
// // WORKFLOWURL: 'http://47.93.215.234:19998/#/workspace/forms',//鞍钢平台工作流地址(弃用)
|
// // WORKFLOWURL: 'http://47.93.215.234:19998/#/workspace/forms',//鞍钢平台工作流地址(弃用)
|
||||||
// // WORKFLOWURL: 'http://47.93.215.234:19098/#/workspace/forms',//鞍钢测试平台工作流地址(弃用)
|
// // WORKFLOWURL: 'http://47.93.215.234:19098/#/workspace/forms',//鞍钢测试平台工作流地址(弃用)
|
||||||
// WORKFLOWURL: 'http://42.180.188.17:19998/#/workspace/forms', //鞍钢平台工作流地址
|
// WORKFLOWURL: 'http://42.180.188.17:19998/#/workspace/forms', //鞍钢平台工作流地址
|
||||||
// WORKFLOWURL: "http://42.180.188.17:19098/#/workspace/forms", //鞍钢测试平台工作流地址
|
// WORKFLOWURL: "http://42.180.188.17:19098/#/workspace/forms", //鞍钢测试平台工作流地址
|
||||||
PREVIEWURL: "http://219.147.96.221:8012/onlinePreview",
|
PREVIEWURL: "http://219.147.96.221:8012/onlinePreview",
|
||||||
|
|
||||||
// UPLOADURL: 'http://192.168.34.221:8111/upload/image', //演示平台 雄本地
|
// UPLOADURL: 'http://192.168.34.221:8111/upload/image', //演示平台 雄本地
|
||||||
// FILEURL: 'http://192.168.34.221:8111/image/', //演示平台 雄本地
|
// FILEURL: 'http://192.168.34.221:8111/image/', //演示平台 雄本地
|
||||||
|
|
||||||
|
|||||||
@ -201,6 +201,10 @@ export default {
|
|||||||
key: "priorityNameDic",
|
key: "priorityNameDic",
|
||||||
value: "问题等级二",
|
value: "问题等级二",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: "regionDrawId",
|
||||||
|
value: "施工图纸",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: "urgentLevel",
|
key: "urgentLevel",
|
||||||
value: "紧急程度",
|
value: "紧急程度",
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- 业务中心 -->
|
<!-- 业务中心 -->
|
||||||
<div class="business whiteBlock">
|
<div class="business" :class="{'whiteBlock': activeIndex == '1'}">
|
||||||
<!-- <el-menu
|
<!-- <el-menu
|
||||||
:default-active="activeIndex"
|
:default-active="activeIndex"
|
||||||
class="business-menu-demo"
|
class="business-menu-demo"
|
||||||
@ -12,21 +12,28 @@
|
|||||||
</el-menu> -->
|
</el-menu> -->
|
||||||
|
|
||||||
|
|
||||||
<check v-if="activeIndex == '1'" style="width:100%;height:calc(100%)"></check>
|
<check @updateValue="updateValue" v-if="activeIndex == '1'" style="width:100%;height:calc(100%)"></check>
|
||||||
|
<BlueprintsManagement @updateValue="updateValue" v-else-if="activeIndex == '2'" style="width:100%;height:calc(100%)"></BlueprintsManagement>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import check from "./businessModule/checkPoint.vue";
|
import check from "./businessModule/checkPoint.vue";
|
||||||
|
import BlueprintsManagement from "./businessModule/blueprintsManagement.vue";
|
||||||
export default {
|
export default {
|
||||||
name: "business",
|
name: "business",
|
||||||
components: {
|
components: {
|
||||||
check,
|
check,BlueprintsManagement
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
activeIndex:'1',
|
activeIndex:'1',
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
methods: {
|
||||||
|
updateValue(val) {
|
||||||
|
this.activeIndex = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -43,6 +43,16 @@
|
|||||||
@click="deleteAttendanceBatch"
|
@click="deleteAttendanceBatch"
|
||||||
>删除</el-button
|
>删除</el-button
|
||||||
>
|
>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
size="medium"
|
||||||
|
@click="sendValue"
|
||||||
|
v-permission="{
|
||||||
|
key: 'business_drawing',
|
||||||
|
menuPath: '/project/quality/business',
|
||||||
|
}"
|
||||||
|
>图纸管理</el-button
|
||||||
|
>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div class="check_box">
|
<div class="check_box">
|
||||||
@ -465,6 +475,10 @@ export default {
|
|||||||
this.getMachineList();
|
this.getMachineList();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
sendValue() {
|
||||||
|
// this.safetyRiskDetailShow = true;
|
||||||
|
this.$emit("updateValue", 2);
|
||||||
|
},
|
||||||
handleSelectAll(selection) {
|
handleSelectAll(selection) {
|
||||||
console.log(selection);
|
console.log(selection);
|
||||||
if (selection.length >= this.tableData.length) {
|
if (selection.length >= this.tableData.length) {
|
||||||
|
|||||||
@ -276,6 +276,10 @@ export default {
|
|||||||
key: "priorityNameDic",
|
key: "priorityNameDic",
|
||||||
value: "问题等级二",
|
value: "问题等级二",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
key: "regionDrawId",
|
||||||
|
value: "施工图纸",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: "urgentLevel",
|
key: "urgentLevel",
|
||||||
value: "紧急程度",
|
value: "紧急程度",
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user