代码完善

This commit is contained in:
BianLzhaoMin 2025-08-01 18:11:18 +08:00
parent 7b7adb79f3
commit 3b9f4454cd
11 changed files with 2420 additions and 1151 deletions

View File

@ -1,14 +1,21 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= webpackConfig.name %></title>
<!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]-->
<style>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<script async src="https://api.map.baidu.com/api?v=2.0&ak=cClgLBaLgGUdQDilX9dGvieL"></script>
<script src="https://api.map.baidu.com/api?type=webgl&v=2.0&ak=cClgLBaLgGUdQDilX9dGvieL"></script>
<script type="text/javascript" src="//api.map.baidu.com/library/TrackAnimation/src/TrackAnimation_min.js"></script>
<title>
<%= webpackConfig.name %>
</title>
<!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]-->
<style>
html,
body,
#app {
@ -16,6 +23,7 @@
margin: 0px;
padding: 0px;
}
.chromeframe {
margin: 0.2em 0;
background: #ccc;
@ -92,6 +100,7 @@
-ms-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
-ms-transform: rotate(360deg);
@ -105,6 +114,7 @@
-ms-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
-ms-transform: rotate(360deg);
@ -193,16 +203,24 @@
color: #FFF;
opacity: 0.5;
}
/** 去除百度地图的水印和logo */
.BMap_cpyCtrl,
.anchorBL {
display: none;
}
</style>
</head>
<body>
<div id="app">
<div id="loader-wrapper">
<div id="loader"></div>
<div class="loader-section section-left"></div>
<div class="loader-section section-right"></div>
<div class="load_title">正在加载系统资源,请耐心等待</div>
</div>
</div>
</body>
</head>
<body>
<div id="app">
<div id="loader-wrapper">
<div id="loader"></div>
<div class="loader-section section-left"></div>
<div class="loader-section section-right"></div>
<div class="load_title">正在加载系统资源,请耐心等待</div>
</div>
</div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

View File

@ -3,81 +3,84 @@ import { Message, MessageBox, Notification, Loading } from 'element-ui'
let loadingInstance
export default {
// 消息提示
msg(content) {
Message.info(content)
},
// 错误消息
msgError(content) {
Message.error(content)
},
// 成功消息
msgSuccess(content) {
Message.success(content)
},
// 警告消息
msgWarning(content) {
Message.warning(content)
},
// 弹出提示
alert(content) {
MessageBox.alert(content, "系统提示")
},
// 错误提示
alertError(content) {
MessageBox.alert(content, "系统提示", { type: 'error' })
},
// 成功提示
alertSuccess(content) {
MessageBox.alert(content, "系统提示", { type: 'success' })
},
// 警告提示
alertWarning(content) {
MessageBox.alert(content, "系统提示", { type: 'warning' })
},
// 通知提示
notify(content) {
Notification.info(content)
},
// 错误通知
notifyError(content) {
Notification.error(content)
},
// 成功通知
notifySuccess(content) {
Notification.success(content)
},
// 警告通知
notifyWarning(content) {
Notification.warning(content)
},
// 确认窗体
confirm(content) {
return MessageBox.confirm(content, "系统提示", {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: "warning",
})
},
// 提交内容
prompt(content) {
return MessageBox.prompt(content, "系统提示", {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: "warning",
})
},
// 打开遮罩层
loading(content) {
loadingInstance = Loading.service({
lock: true,
text: content,
spinner: "el-icon-loading",
background: "rgba(0, 0, 0, 0.7)",
})
},
// 关闭遮罩层
closeLoading() {
loadingInstance.close()
}
// 消息提示
msg(content) {
Message.info(content)
},
// 错误消息
msgError(content) {
Message.closeAll()
Message.error(content)
},
// 成功消息
msgSuccess(content) {
Message.closeAll()
Message.success(content)
},
// 警告消息
msgWarning(content) {
Message.closeAll()
Message.warning(content)
},
// 弹出提示
alert(content) {
MessageBox.alert(content, '系统提示')
},
// 错误提示
alertError(content) {
MessageBox.alert(content, '系统提示', { type: 'error' })
},
// 成功提示
alertSuccess(content) {
MessageBox.alert(content, '系统提示', { type: 'success' })
},
// 警告提示
alertWarning(content) {
MessageBox.alert(content, '系统提示', { type: 'warning' })
},
// 通知提示
notify(content) {
Notification.info(content)
},
// 错误通知
notifyError(content) {
Notification.error(content)
},
// 成功通知
notifySuccess(content) {
Notification.success(content)
},
// 警告通知
notifyWarning(content) {
Notification.warning(content)
},
// 确认窗体
confirm(content) {
return MessageBox.confirm(content, '系统提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
},
// 提交内容
prompt(content) {
return MessageBox.prompt(content, '系统提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
},
// 打开遮罩层
loading(content) {
loadingInstance = Loading.service({
lock: true,
text: content,
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)',
})
},
// 关闭遮罩层
closeLoading() {
loadingInstance.close()
},
}

View File

@ -75,7 +75,7 @@
/>
<!-- 添加或修改层级对话框 -->
<el-dialog width="40%" append-to-body :title="addOrEditFormTitle" :visible.sync="addOrEditFormVisible">
<el-dialog width="50%" append-to-body :title="addOrEditFormTitle" :visible.sync="addOrEditFormVisible">
<AddOrEditForm ref="addOrEditComponentRef" @closeAddOrEditFormDialog="closeAddOrEditFormDialog" />
</el-dialog>
</div>

View File

@ -3,10 +3,10 @@
<div>
<el-form :model="addOrEditForm" :rules="addOrEditFormRules" ref="addOrEditFormRef" label-width="100px">
<el-form-item label="上级节点" prop="deviceName">
<el-input v-model="addOrEditForm.deviceName" placeholder="请输入设备名称" />
<el-input v-model="addOrEditForm.deviceName" disabled />
</el-form-item>
<el-form-item label="分类名称" prop="proName">
<el-input v-model="addOrEditForm.proName" placeholder="请输入设备编码" />
<el-input v-model="addOrEditForm.proName" placeholder="请输入分类名称" />
</el-form-item>
<el-form-item>
@ -30,25 +30,12 @@ export default {
projectId: '',
level: '',
nodeCount: '',
proName: '',
parentId: '', //id
},
addOrEditFormRules: {
deviceName: [{ required: true, message: '请输入设备名称', trigger: 'blur' }],
proName: [{ required: true, message: '请输入设备编码', trigger: 'blur' }],
Keeper: [{ required: true, message: '请选择设备保管人', trigger: 'change' }],
proName: [{ required: true, message: '请输入分类名称', trigger: 'blur' }],
},
KeeperList: [
{
id: '张三',
name: '张三',
},
{
id: '李四',
name: '李四',
},
],
}
},
methods: {
@ -78,12 +65,12 @@ export default {
},
setFormData(data) {
const { deviceName, id, level, nodeCount, projectId } = data
const { deviceName, level, nodeCount, projectId, id } = data
this.addOrEditForm = {
deviceName,
projectId,
parentId: id,
level: parseInt(level) + 1,
level: level,
nodeCount,
}
},

View File

@ -9,7 +9,12 @@
@keyup.enter.native="handleQuery"
/> -->
<el-select v-model="queryParams.projectId" placeholder="请选择项目名称" style="width: 100%">
<el-select
placeholder="请选择项目名称"
style="width: 240px"
@change="handleProjectChange"
v-model="queryParams.projectId"
>
<el-option :key="item.id" :value="item.id" :label="item.name" v-for="item in projectSelectList" />
</el-select>
</el-form-item>
@ -35,44 +40,36 @@
</el-form-item>
</el-form>
<!-- <el-row :gutter="10" class="mb8">
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">新增</el-button>
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAddLevelTwo">
新增
</el-button>
<el-button type="primary" plain icon="el-icon-view" size="mini" @click="handleModelPreview">
模型预览
</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getModelList"></right-toolbar>
</el-row> -->
<!-- <right-toolbar :showSearch.sync="showSearch" @queryTable="getModelList"></right-toolbar> -->
</el-row>
<el-table
border
row-key="id"
v-loading="loading"
:data="modelList"
:tree-props="{ children: 'nodes' }"
default-expand-all
>
<el-table border row-key="id" v-loading="loading" :data="modelList" default-expand-all>
<el-table-column label="序号" align="center" type="index" />
<el-table-column label="项目名称">
<el-table-column label="分类名称" align="center">
<template slot-scope="{ row }">
<span>{{ row.name }}</span>
<el-tag style="margin-left: 10px" size="mini" type="primary">节点{{ row.level }}</el-tag>
<span>{{ row.nodeName }}</span>
<el-tag style="margin-left: 10px" size="mini" type="primary">节点{{ row.nodelevel }}</el-tag>
</template>
</el-table-column>
<el-table-column label="层级名称">
<template slot-scope="{ row }">
<!-- 只在项目级(第一级)显示层级名称 -->
<span v-if="row.level === 1">{{ row.levelName }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="340">
<el-table-column label="所属项目" align="center" prop="proName" />
<el-table-column label="层级名称" align="center" prop="levelName" />
<el-table-column label="操作" align="center" width="180">
<template slot-scope="{ row }">
<el-button
size="mini"
type="text"
icon="el-icon-plus"
@click="handleAddChild(row)"
v-if="row.level < row.nodeCount"
v-if="row.nodelevel < row.nodeCount"
>
新增
</el-button>
@ -82,7 +79,7 @@
type="text"
:icon="row.modelUrl ? 'el-icon-view' : 'el-icon-upload'"
@click="row.modelUrl ? handleViewModel(row) : handleUploadModel(row)"
v-if="row.nodeCount === row.level"
v-if="row.nodeCount == row.nodelevel"
>
{{ row.modelUrl ? '查看模型' : '上传模型' }}
</el-button>
@ -102,8 +99,8 @@
type="text"
icon="el-icon-delete"
style="color: #f56c6c"
@click="handleDelete(row)"
v-if="row.level != 1"
@click="handleDelete(row.id)"
v-if="row.nodeCount == row.nodelevel || row.children.length == 0"
>
删除
</el-button>
@ -144,7 +141,7 @@
</div>
</el-dialog>
<el-dialog width="50%" append-to-body :title="useOrReturnFormTitle" :visible.sync="useOrReturnFormVisible">
<el-dialog width="80%" append-to-body :title="useOrReturnFormTitle" :visible.sync="useOrReturnFormVisible">
<UseOrReturnForm
ref="useOrReturnFormComponentRef"
v-if="useOrReturnFormVisible"
@ -157,15 +154,24 @@
<el-dialog width="40%" append-to-body :title="addOrEditFormTitle" :visible.sync="addOrEditFormVisible">
<AddOrEditForm ref="addOrEditComponentRef" @closeAddOrEditFormDialog="closeAddOrEditFormDialog" />
</el-dialog>
<el-dialog title="模型预览" :visible.sync="viewDialogVisible" width="60%" append-to-body>
<dxf-viewer :entities="dxfPreviewUrl"></dxf-viewer>
<el-dialog
title="模型预览"
width="90%"
append-to-body
@close="onCloseMapView"
:visible.sync="modelPreviewVisible"
>
<!-- <dxf-viewer :entities="dxfPreviewUrl"></dxf-viewer> -->
<div id="map-container"> </div>
</el-dialog>
</div>
</template>
<script>
import AddOrEditForm from './addOrEditForm.vue'
import UseOrReturnForm from './useOrReturnForm.vue'
// import UseOrReturnForm from './useOrReturnForm.vue'
import UseOrReturnForm from './useOrReturnFormNew.vue'
import UseRecordTable from './useRecordTable.vue'
import DxfViewer from './DxfViewer.vue'
@ -261,6 +267,10 @@ export default {
],
},
],
map: null,
modelPreviewVisible: false,
modelPreviewInfoList: [],
}
},
created() {
@ -294,13 +304,23 @@ export default {
return
} */
/* 新需求 重新做 上面建议不要删除 有需要直接可以查看 */
// openView({ id: row.id })
// .then((response) => {
// this.dxfPreviewUrl = response.data
// this.viewDialogVisible = true
// })
// .catch((error) => {
// // console.error(':', error)
// })
openView({ id: row.id })
.then((response) => {
this.dxfPreviewUrl = response.data
this.viewDialogVisible = true
.then((res) => {
this.modelPreviewInfoList = res.data
this.modelPreviewVisible = true
this.initMap()
})
.catch((error) => {
console.error('获取项目详情失败:', error)
.catch((err) => {
console.error('获取模型详情失败:', err)
})
},
@ -325,14 +345,13 @@ export default {
//
handleAddChild(row) {
const { id, proName, nodeName, level, nodeCount, projectId } = row
const name = nodeName || proName // nodeName proName
const { id, nodeName, nodelevel, nodeCount, projectId } = row
this.addOrEditFormTitle = '新增'
this.editForm = null
this.addOrEditFormVisible = true
const editForm = { deviceName: name, id, level, nodeCount, projectId }
const editForm = { deviceName: nodeName, id, level: nodelevel * 1 + 1, nodeCount, projectId }
this.$nextTick(() => {
this.$refs.addOrEditComponentRef.setFormData(editForm)
})
@ -351,64 +370,69 @@ export default {
//
// -
// -
getModelList() {
async getModelList() {
this.loading = true
getModelListApi(this.queryParams)
.then((response) => {
const rawList = response.rows || []
//
const formatNodes = (nodes, level = 2) => {
//
if (!Array.isArray(nodes)) return []
const { rows: res } = await getModelListApi(this.queryParams)
console.log(res, '模型列表')
this.loading = false
this.modelList = this.onBuildTree(res)
// getModelListApi(this.queryParams)
// .then((response) => {
// const rawList = response.rows || []
return nodes
.filter((item) => item && item.nodeId) //
.map((item) => ({
...item,
id: item.nodeId,
name: item.nodeName || '未命名节点',
level: level, //
// +1
nodes: formatNodes(item.nodes || item.children || [], level + 1),
}))
}
// //
// const formatNodes = (nodes, level = 2) => {
// //
// if (!Array.isArray(nodes)) return []
//
const formatted = rawList.map((project) => {
const children = project.children || []
// return nodes
// .filter((item) => item && item.nodeId) //
// .map((item) => ({
// ...item,
// id: item.nodeId,
// name: item.nodeName || '',
// level: level, //
// // +1
// nodes: formatNodes(item.nodes || item.children || [], level + 1),
// }))
// }
//
let levelName = ''
let nodeCount = ''
if (this.levelList && this.levelList.length > 0) {
const levelConfig = this.levelList.find(
(item) => item.configId == project.level, //
)
levelName = levelConfig ? levelConfig.configName : ''
}
// //
// const formatted = rawList.map((project) => {
// const children = project.children || []
return {
...project,
id: project.projectId,
name: project.proName || '未命名项目',
level: 1, // 1
levelName: project.levelName, //
nodes: formatNodes(children),
rawData: project,
nodeCount: project.nodeCount,
}
})
// //
// let levelName = ''
// let nodeCount = ''
// if (this.levelList && this.levelList.length > 0) {
// const levelConfig = this.levelList.find(
// (item) => item.configId == project.level, //
// )
// levelName = levelConfig ? levelConfig.configName : ''
// }
this.modelList = formatted
this.total = response.total
this.loading = false
})
.catch((error) => {
console.error('获取模型列表失败:', error)
this.loading = false
this.$message.error('模型数据加载失败,请重试')
})
// return {
// ...project,
// id: project.projectId,
// name: project.proName || '',
// level: 1, // 1
// levelName: project.levelName, //
// nodes: formatNodes(children),
// rawData: project,
// nodeCount: project.nodeCount,
// }
// })
// this.modelList = formatted
// this.total = response.total
// this.loading = false
// })
// .catch((error) => {
// console.error(':', error)
// this.loading = false
// this.$message.error('')
// })
},
//
handleUploadModel(row) {
@ -467,19 +491,20 @@ export default {
},
//
handleDelete(row) {
handleDelete(id) {
this.$modal
.confirm('是否确认删除当前节点数据吗?')
.then(async () => {
// row.level
let res
if (row.level === 1) {
// level 1
res = await delProject(row.id) // 使 delProject API
} else {
res = await delModelApi({ id: row.id }) // 使 delModelApi
}
// let res
// if (row.level === 1) {
// // level 1
// res = await delProject(row.id) // 使 delProject API
// } else {
// res = await delModelApi({ id: row.id }) // 使 delModelApi
// }
const res = await delModelApi({ id })
if (res.code === 200) {
this.$modal.msgSuccess('删除成功')
this.getModelList()
@ -573,6 +598,237 @@ export default {
this.getModelList()
}
},
//
handleAddLevelTwo() {
this.addOrEditFormTitle = '新增'
this.editForm = null
this.addOrEditFormVisible = true
const deviceName = this.projectSelectList.find((item) => item.id === this.queryParams.projectId).name
const nodeCount = this.projectSelectList.find((item) => item.id === this.queryParams.projectId).nodeCount
const editForm = {
deviceName,
level: 2,
nodeCount,
projectId: this.queryParams.projectId,
id: this.queryParams.projectId,
}
this.$nextTick(() => {
this.$refs.addOrEditComponentRef.setFormData(editForm)
})
},
//
handleProjectChange() {
this.getModelList()
},
//
onBuildTree(data) {
// 1. nodelevel"2"
const topNodes = data.filter((item) => item.nodelevel == '2')
return topNodes.map((node) => ({
...node,
children: this.findChildren(node, data), //
}))
},
//
findChildren(node, data) {
// parentIdid
const children = data.filter((item) => item.parentId == node.id)
//
if (children.length > 0) {
// nodes
return children.map((child) => ({
...child,
children: this.findChildren(child, data), //
}))
}
// null
return []
},
//
handleModelPreview() {
this.modelPreviewVisible = true
//
this.initMap()
},
//
onCloseMapView() {
//
if (this.map) {
this.map = null
}
},
//
initMap() {
//
const lon = this.projectSelectList.find((item) => item.id == this.queryParams.projectId).lon * 1
const lat = this.projectSelectList.find((item) => item.id == this.queryParams.projectId).lat * 1
this.$nextTick(() => {
this.map = new BMapGL.Map('map-container') //
this.map.setMapType(BMAP_EARTH_MAP) //
this.map.setDisplayOptions({
poiText: false, // POI
poiIcon: false, // POI
building: false, //
})
let point = new BMapGL.Point(lon, lat) //
this.map.centerAndZoom(point, 16) //
this.map.enableScrollWheelZoom(true) //
this.drawModel(this.modelPreviewInfoList)
})
},
// drawModel
async drawModel(modelInfoList) {
//
this.map.clearOverlays()
for (const item of modelInfoList) {
try {
if (item.entityType === 'LINE') {
const geometry = JSON.parse(item.geometry)
const start = geometry.start
const end = geometry.end
//
const polyline = new BMapGL.Polyline(
[new BMapGL.Point(start[0], start[1]), new BMapGL.Point(end[0], end[1])],
{ strokeColor: 'red', strokeWeight: 2, strokeOpacity: 0.8 },
)
this.map.addOverlay(polyline)
} else if (item.entityType === 'CIRCLE') {
const geometry = JSON.parse(item.geometry)
const center = geometry.center
const radius = geometry.radius
//
if (center.length > 0) {
const circle = new BMapGL.Circle(new BMapGL.Point(center[0], center[1]), radius, {
strokeColor: 'blue',
strokeWeight: 2,
fillColor: 'rgba(0,0,255,0.3)',
})
this.map.addOverlay(circle)
}
} else {
//
const pointList = JSON.parse(item.geometry)
if (pointList.points.length > 0) {
// [x, y, ..., angle]
const path = pointList.points.map((p) => {
const [lng, lat, , , angle] = p //
return {
point: new BMapGL.Point(lng, lat),
angle: angle || 0, // 0
}
})
let overlay = null
if (path.length === 1) {
// 1.
const { point, angle } = path[0]
//
const arrowIcon = new BMapGL.Icon(
'//api.map.baidu.com/img/markers.png', //
new BMapGL.Size(20, 34),
{
anchor: new BMapGL.Size(10, 34), //
imageOffset: new BMapGL.Size(0, 0), //
},
)
overlay = new BMapGL.Marker(point, {
icon: arrowIcon,
rotation: (angle * 180) / Math.PI, //
})
} else if (path.length === 2) {
// 2. 线线
const linePoints = path.map((p) => p.point)
const endAngle = (path[1].angle * 180) / Math.PI //
// 线
overlay = new BMapGL.Polyline(linePoints, {
strokeColor: 'green',
strokeWeight: 2,
})
//
const arrowMarker = new BMapGL.Marker(linePoints[1], {
icon: new BMapGL.Icon(
'//api.map.baidu.com/img/markers.png',
new BMapGL.Size(20, 34),
{ anchor: new BMapGL.Size(10, 34) },
),
rotation: endAngle,
})
this.map.addOverlay(arrowMarker) //
} else {
// 3.
const polygonPoints = path.map((p) => p.point)
overlay = new BMapGL.Polygon(polygonPoints, {
strokeColor: '#3388ff',
strokeWeight: 2,
fillColor: 'rgba(51,136,255,0.2)',
})
}
this.map.addOverlay(overlay)
}
}
} catch (error) {
console.error('绘制图元失败:', item, error)
}
}
const points = this.map
.getOverlays()
.map((overlay) => {
if (overlay instanceof BMapGL.Marker) {
return overlay.getPosition()
} else if (overlay instanceof BMapGL.Polyline || overlay instanceof BMapGL.Polygon) {
return overlay.getPath()
} else if (overlay instanceof BMapGL.Circle) {
return overlay.getCenter()
}
})
.flat()
.filter(Boolean) //
if (points.length > 0) {
//
const viewport = this.map.getViewport(points)
// n
const zoomOffset = 2 // 1-3
// const adjustedZoom = Math.min(
// viewport.zoom + zoomOffset,
// this.map.getMaxZoom(), //
// )
const adjustedZoom = Math.min(
16, // 18
this.map.getMaxZoom(),
)
//
this.map.setViewport(points, {
zoom: adjustedZoom, // 使
padding: [50, 50, 50, 50], //
})
}
},
},
}
</script>
@ -600,4 +856,8 @@ export default {
color: #409eff;
background-color: #f0f7ff;
}
#map-container {
min-height: 76vh;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,662 @@
<template>
<div>
<!-- 上传表单 -->
<el-form
:model="useOrReturnForm"
:rules="useOrReturnFormRules"
ref="useOrReturnFormRef"
label-width="120px"
v-show="!showLayerDialog"
>
<el-form-item label="模型文件" prop="files">
<el-upload
class="upload-demo"
action="/dev-api/common/upload"
:on-success="handleSuccess"
:on-remove="handleRemove"
:before-upload="beforeUpload"
:headers="uploadHeaders"
:file-list="fileList"
:limit="1"
:auto-upload="true"
:show-file-list="true"
:disabled="fileList.length >= 1"
>
<div v-if="fileList.length < 1" class="upload-demo">
<el-button size="small" icon="el-icon-paperclip">上传模型</el-button>
<div class="upload-demo-tip">仅支持上传dxf文件</div>
</div>
</el-upload>
</el-form-item>
<el-form-item>
<el-button @click="cancel">取消</el-button>
<el-button type="primary" @click="goToNextStep" :disabled="!fileList.length">下一步</el-button>
</el-form-item>
</el-form>
<!-- 图层和实体预览 -->
<div v-if="showLayerDialog" class="layer-container">
<div class="all-select">
<div class="item-index"> </div>
<el-checkbox v-model="allSelect">全选</el-checkbox>
</div>
<div class="layer-item" :key="layer.layerName" v-for="(layer, index) in layerList">
<div class="item-index">
{{ index + 1 }}
</div>
<el-checkbox v-model="layer.checked" style="margin-right: 10px" />
<span @click="handleLayerSelectNew(layer)">
{{ layer.layerName }}
</span>
</div>
<div class="btn-group">
<el-button type="primary" @click="onHandleBack">上一步</el-button>
<el-button type="primary" @click="onHandleConfirm">确认</el-button>
</div>
</div>
</div>
</template>
<script>
import { getToken } from '@/utils/auth'
import { addModel } from '@/api/basic/model'
export default {
name: 'UseOrReturnForm',
props: {
projectId: {
type: String,
default: '',
},
},
data() {
return {
useOrReturnForm: {
modelName: '',
modelType: '',
version: '',
designer: '',
user: '',
files: [],
modelUrl: '',
projectId: '',
},
useOrReturnFormRules: {
files: [{ required: true, message: '请上传模型文件', trigger: 'change' }],
},
fileList: [],
showLayerDialog: false,
layerList: [],
selectedLayerEntities: [],
selectedLayerIndex: 0,
selectedEntities: [],
cadData: [],
svgSize: 400,
zoomLevel: 1,
panning: false,
panStartX: 0,
panStartY: 0,
panX: 0,
panY: 0,
originX: 200,
originY: 200,
viewBox: { x: 0, y: 0 },
}
},
computed: {
uploadHeaders() {
return {
Authorization: 'Bearer ' + getToken(),
}
},
previewEntities() {
return this.getAllSelectedEntities()
},
allSelect: {
get() {
return this.layerList.every((layer) => layer.checked)
},
set(value) {
this.layerList.forEach((layer) => (layer.checked = value))
},
},
},
mounted() {
this.useOrReturnForm.projectId = this.projectId
window.addEventListener('resize', this.adjustSVGSize)
this.adjustSVGSize()
},
beforeDestroy() {
window.removeEventListener('resize', this.adjustSVGSize)
},
methods: {
adjustSVGSize() {
if (this.$refs.previewWrapper) {
const width = this.$refs.previewWrapper.clientWidth
this.svgSize = Math.min(600, Math.max(400, width - 40))
}
},
getAllSelectedEntities() {
const allEntities = []
this.layerList.forEach((layer) => {
layer.entities.forEach((entity) => {
if (this.selectedEntities.includes(entity.id)) {
allEntities.push(entity)
}
})
})
return allEntities
},
getPolylinePoints(entity) {
if (!entity.points || !Array.isArray(entity.points)) return ''
return entity.points
.map((point) => {
return `${point.x},${point.y}`
})
.join(' ')
},
zoomIn() {
this.zoomLevel = Math.min(5, this.zoomLevel + 0.1)
},
zoomOut() {
this.zoomLevel = Math.max(0.1, this.zoomLevel - 0.1)
},
handleWheel(event) {
event.preventDefault()
const delta = Math.sign(event.deltaY)
if (delta > 0) {
this.zoomOut()
} else {
this.zoomIn()
}
},
fitToView() {
this.zoomLevel = 1
this.panX = 0
this.panY = 0
this.viewBox = { x: 0, y: 0 }
},
startPan(event) {
this.panning = true
this.panStartX = event.clientX
this.panStartY = event.clientY
},
pan(event) {
if (!this.panning) return
const dx = event.clientX - this.panStartX
const dy = event.clientY - this.panStartY
this.panX += dx / this.zoomLevel
this.panY += dy / this.zoomLevel
this.panStartX = event.clientX
this.panStartY = event.clientY
this.viewBox.x = -this.panX
this.viewBox.y = -this.panY
},
endPan() {
this.panning = false
},
cancel() {
this.$emit('closeUseOrReturnFormDialog')
},
goToNextStep() {
this.showLayerDialog = true
if (!this.cadData || !this.cadData.length) {
this.$message.error('无效的CAD数据无法进入下一步')
return
}
const map = {}
this.cadData.forEach((entity) => {
if (!map[entity.layerName]) {
map[entity.layerName] = { layerName: entity.layerName, entities: [] }
}
if (!entity.id) {
entity.id = entity.layerName + '_' + Math.random().toString(36).substr(2, 9)
}
map[entity.layerName].entities.push(entity)
})
this.layerList = Object.values(map)
this.layerList.forEach((layer) => {
// layer.checked = false
this.$set(layer, 'checked', false)
})
console.log(this.layerList, 'layerList---')
this.selectedLayerIndex = 0
this.selectedLayerEntities = this.layerList[0].entities || []
this.selectedEntities = []
},
handleLayerSelect(index) {
this.selectedLayerIndex = parseInt(index)
this.selectedLayerEntities = this.layerList[this.selectedLayerIndex].entities
},
selectEntity(entity) {
entity.selected = !entity.selected
const idx = this.selectedEntities.indexOf(entity.id)
console.log(JSON.stringify(this.selectedEntities))
if (entity.selected) {
if (idx === -1) this.selectedEntities.push(entity.id)
} else {
if (idx !== -1) this.selectedEntities.splice(idx, 1)
}
},
async submitForm() {
this.$refs.useOrReturnFormRef.validate(async (valid) => {
if (!valid) return
const selectedEntities = []
this.layerList.forEach((layer) => {
layer.entities.forEach((entity) => {
if (entity.selected) {
selectedEntities.push({
entityId: entity.entityId || entity.id || '',
entityType: entity.entityType || '',
color: entity.color || '',
lineweight: entity.lineweight || '',
thickness: entity.thickness || '',
startPoint: entity.startPoint || null,
endPoint: entity.endPoint || null,
centerPoint: entity.centerPoint || null,
radius: entity.radius != null ? entity.radius : null,
// points: entity.points || [],
geometry: entity.geometry || {}, // geometry
layerName: layer.layerName || '',
})
}
})
})
const formData = {
projectId: this.useOrReturnForm.projectId,
modelName: this.useOrReturnForm.modelName,
modelUrl: this.useOrReturnForm.modelUrl,
fileName: this.useOrReturnForm.fileName,
version: this.useOrReturnForm.version,
designer: this.useOrReturnForm.designer,
designerName: this.useOrReturnForm.designerName,
remark: this.useOrReturnForm.remark,
modelType: this.useOrReturnForm.modelType,
modelIds: this.useOrReturnForm.modelIds,
createBy: this.useOrReturnForm.createBy,
createTime: this.useOrReturnForm.createTime,
selectedEntities: selectedEntities,
}
try {
const res = await addModel(formData)
if (res.code === 200) {
this.$modal.msgSuccess('模型添加成功')
this.$emit('closeUseOrReturnFormDialog')
this.$emit('refreshParentList')
this.resetForm()
} else {
this.$modal.msgError(res.msg || '提交失败')
}
} catch (error) {
this.$modal.msgError('提交异常: ' + error.message)
}
})
},
//
async onHandleConfirm() {
// this.submitForm()
const isSelect = this.layerList.some((layer) => layer.checked)
if (!isSelect) {
this.$modal.msgError('请选择图层')
return
}
const selectedEntities = []
this.layerList.forEach((layer) => {
if (layer.checked) {
layer.entities.forEach((entity) => {
selectedEntities.push({
entityId: entity.entityId || entity.id || '',
entityType: entity.entityType || '',
color: entity.color || '',
lineweight: entity.lineweight || '',
thickness: entity.thickness || '',
startPoint: entity.startPoint || null,
endPoint: entity.endPoint || null,
centerPoint: entity.centerPoint || null,
radius: entity.radius != null ? entity.radius : null,
// points: entity.points || [],
geometry: entity.geometry || {}, // geometry
layerName: layer.layerName || '',
})
})
}
})
const formData = {
projectId: this.useOrReturnForm.projectId,
modelName: this.useOrReturnForm.modelName,
modelUrl: this.useOrReturnForm.modelUrl,
fileName: this.useOrReturnForm.fileName,
version: this.useOrReturnForm.version,
designer: this.useOrReturnForm.designer,
designerName: this.useOrReturnForm.designerName,
remark: this.useOrReturnForm.remark,
modelType: this.useOrReturnForm.modelType,
modelIds: this.useOrReturnForm.modelIds,
createBy: this.useOrReturnForm.createBy,
createTime: this.useOrReturnForm.createTime,
selectedEntities: selectedEntities,
}
try {
const res = await addModel(formData)
if (res.code === 200) {
this.$modal.msgSuccess('模型添加成功')
this.$emit('closeUseOrReturnFormDialog')
this.$emit('refreshParentList')
this.resetForm()
} else {
this.$modal.msgError(res.msg || '提交失败')
}
} catch (error) {
this.$modal.msgError('提交异常: ' + error.message)
}
},
//
onHandleBack() {
this.showLayerDialog = false
},
resetForm() {
this.$refs.useOrReturnFormRef.resetFields()
this.fileList = []
this.useOrReturnForm.files = []
this.selectedEntities = []
this.showLayerDialog = false
this.fitToView()
},
handleSuccess(response, file, fileList) {
if (response.code === 200) {
console.log(response, '上传结果---')
this.cadData = response.data.cadData || []
const uploaded = response.data || {
name: file.name,
url: response.fileUrl || response.url,
uid: file.uid,
}
this.fileList = fileList
this.useOrReturnForm.files = [uploaded]
this.useOrReturnForm.modelUrl = uploaded.url
this.$refs.useOrReturnFormRef.validateField('files')
} else {
this.$message.error(response.msg || '文件上传失败')
this.handleRemove(file)
}
},
handleRemove(file, fileList) {
this.fileList = fileList
this.useOrReturnForm.files = []
this.useOrReturnForm.modelUrl = ''
this.cadData = []
this.$refs.useOrReturnFormRef.validateField('files')
},
beforeUpload(file) {
const isDxf = file.name.toLowerCase().endsWith('.dxf')
if (!isDxf) this.$message.error('只能上传DXF格式的文件!')
return isDxf
},
handleLayerSelectNew(item) {
this.$set(item, 'checked', !item.checked)
},
},
}
</script>
<style scoped lang="scss">
.upload-demo {
display: flex;
align-items: center;
}
.upload-demo-tip {
margin-left: 10px;
color: #f56c6c;
}
.layer-container {
max-height: 76vh;
overflow-y: auto;
/* 滚动条样式优化 */
&::-webkit-scrollbar {
width: 8px;
}
&::-webkit-scrollbar-thumb {
background-color: #dcdfe6;
border-radius: 4px;
}
.layer-item {
display: flex;
align-items: center;
padding: 8px 0;
margin-bottom: 10px;
border-radius: 6px;
box-shadow: 0 2px 8px rgb(0 0 0 / 0.05);
background-color: #fff;
cursor: pointer;
& span {
flex: 1;
}
}
.layer-item:hover {
background-color: #e6f2ff;
color: #409eff;
}
}
.left-panel {
width: 260px;
background: #f7f9fc;
border-right: 1px solid #dcdfe6;
padding: 20px 15px;
overflow-y: auto;
}
.panel-title {
font-weight: 600;
font-size: 18px;
margin-bottom: 20px;
color: #303133;
border-bottom: 2px solid #409eff;
padding-bottom: 6px;
}
.layer-menu {
background: transparent;
border: none;
}
.layer-menu-item {
font-size: 15px;
padding: 8px 15px !important;
display: flex;
justify-content: space-between;
color: #606266;
cursor: pointer;
}
.layer-menu-item:hover {
background-color: #e6f2ff;
color: #409eff;
}
.el-menu-item.is-active {
background-color: #409eff !important;
color: #fff !important;
font-weight: 600;
}
.entity-count {
color: #909399;
font-weight: 400;
}
.right-panel {
flex: 1;
padding: 20px 25px;
background: #fff;
overflow-y: auto;
display: flex;
flex-direction: column;
}
.entity-row {
margin-bottom: 15px;
flex-wrap: wrap;
display: flex;
gap: 15px;
}
.entity-card {
cursor: pointer;
border-radius: 6px;
transition: all 0.3s ease;
margin-bottom: 15px;
box-shadow: 0 2px 8px rgb(0 0 0 / 0.05);
width: 30%;
min-width: 200px;
}
.entity-card:hover {
transform: translateY(-3px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.entity-card.active {
border: 2px solid #409eff;
background-color: #f0f7ff;
}
.entity-info {
font-size: 13px;
color: #4a4a4a;
}
.entity-info div {
margin-bottom: 4px;
line-height: 1.3;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.preview-container {
margin-top: 20px;
padding: 15px;
background: #f8fafc;
border: 1px solid #e4e7ed;
border-radius: 6px;
}
.preview-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
.zoom-controls {
display: flex;
align-items: center;
gap: 10px;
}
.zoom-controls span {
min-width: 50px;
text-align: center;
font-size: 14px;
}
.preview-wrapper {
height: 300px;
width: 100%;
background: white;
border: 1px solid #dcdfe6;
border-radius: 4px;
overflow: hidden;
position: relative;
}
.preview-svg {
width: 100%;
height: 100%;
background: #f9f9f9;
cursor: move;
}
.coordinate-indicator {
margin-top: 10px;
display: flex;
justify-content: space-between;
font-size: 12px;
color: #666;
}
.layer-footer {
text-align: right;
margin-top: 20px;
padding-top: 10px;
border-top: 1px solid #eee;
}
.layer-footer button {
min-width: 100px;
margin-left: 15px;
font-weight: 600;
}
/* ------------------------------ */
.all-select {
display: flex;
align-items: center;
padding: 8px 0;
}
.item-index {
width: 30px;
text-align: center;
margin-right: 10px;
}
.btn-group {
display: flex;
justify-content: flex-end;
margin-top: 20px;
}
</style>

View File

@ -57,7 +57,7 @@
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="proList" @selection-change="handleSelectionChange" border>
<el-table v-loading="loading" :data="proList" border>
<el-table-column label="序号" align="center" type="index" />
<el-table-column label="项目名称" align="center" prop="proName" />
<el-table-column label="层级配置" align="center" prop="level" />
@ -94,8 +94,8 @@
/>
<!-- 添加或修改岗位对话框 -->
<el-dialog :title="title" :visible.sync="open" width="550px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-dialog :title="title" :visible.sync="open" width="40%" append-to-body>
<el-form ref="form" :model="form" :rules="addOrEditRules" label-width="auto">
<el-form-item label="项目名称" prop="proName">
<el-input v-model="form.proName" placeholder="请输入项目名称" />
</el-form-item>
@ -109,6 +109,35 @@
/>
</el-select>
</el-form-item>
<el-form-item label="负责人" prop="chargePerson">
<el-input v-model="form.chargePerson" placeholder="请输入负责人" />
</el-form-item>
<el-form-item label="项目所在地" prop="location">
<div style="display: flex; align-items: center">
<el-input v-model="form.location" placeholder="请输入项目所在地" />
<el-button type="primary" @click="handleMapAdd" style="margin-left: 10px"> 选择地址 </el-button>
</div>
</el-form-item>
<!-- <el-form-item label="经纬度" prop="longitude">
<el-input disabled style="width: 48%" v-model="form.longitude" />
<el-input disabled style="width: 48%; margin-left: 4%" v-model="form.latitude" />
</el-form-item> -->
<el-row :gutter="10">
<el-col :span="12">
<el-form-item label="经度" prop="longitude">
<el-input disabled v-model="form.longitude" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item prop="longitude" label="纬度">
<el-input disabled v-model="form.latitude" />
</el-form-item>
</el-col>
</el-row>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入备注" />
</el-form-item>
@ -126,9 +155,19 @@
:fullscreen="false"
:visible.sync="mapVisible"
:close-on-click-modal="false"
style="margin-top: 8.5vh"
@close="handleMapClose"
width="80%"
>
<div style="margin-bottom: 10px">
<div style="display: flex; align-items: center; margin-bottom: 14px">
<el-input v-model="searchAddress" placeholder="请输入地址" />
<el-button type="primary" @click="handleSearch" style="margin-left: 6px">搜索</el-button>
</div>
<div id="map-container" style="height: 70vh; background-color: #bfc"> </div>
<div style="text-align: right; margin-top: 10px">
<el-button type="primary" size="small" @click="findLocation">确定</el-button>
</div>
<!-- <div style="margin-bottom: 10px">
<label>关键词<input v-model="keyword" class="lineinput" style="width: 200px" size="mini" /></label>
<label>地区<input v-model="location2" class="lineinput" style="width: 200px" size="mini" /></label>
</div>
@ -188,7 +227,7 @@
>取消</el-button
>
<el-button type="primary" size="small" icon="el-icon-check" @click="findLocation">确定</el-button>
</div>
</div> -->
</el-dialog>
</div>
</template>
@ -237,19 +276,28 @@ export default {
},
//
form: {
longitude: '',
latitude: '',
location: '',
remark: '',
level: '',
proName: '', //
level: '', //
chargePerson: '', //
location: '', //
longitude: '', //
latitude: '', //
remark: '', //
},
//
rules: {
addOrEditRules: {
proName: [{ required: true, message: '项目名称不能为空', trigger: 'blur' }],
level: [{ required: true, message: '请选择层级配置', trigger: 'change' }],
chargePerson: [{ required: true, message: '请输入负责人', trigger: 'blur' }],
location: [{ required: true, message: '请选择项目所在地', trigger: 'blur' }],
longitude: [{ required: true, message: '请选择项目所在地', trigger: 'blur' }],
latitude: [{ required: true, message: '请选择项目所在地', trigger: 'blur' }],
},
levelList: [],
searchAddress: '',
marker: null,
}
},
created() {
@ -281,14 +329,13 @@ export default {
//
reset() {
this.form = {
proId: undefined,
proName: undefined,
proType: undefined,
unit: undefined,
chargePerson: undefined,
location: undefined,
remark: undefined,
level: undefined,
proName: '', //
level: '', //
chargePerson: '', //
location: '', //
longitude: '', //
latitude: '', //
remark: '', //
}
this.resetForm('form')
},
@ -309,8 +356,54 @@ export default {
this.title = '新增项目'
},
/** 地图选点操作 */
mapAdd() {
this.mapVisible = true
handleMapAdd() {
const this_ = this
this_.mapVisible = true
this.$nextTick(() => {
this_.map = new BMapGL.Map('map-container') //
let point = new BMapGL.Point(117.13805, 31.8734) //
// let point = new BMapGL.Point(116.404, 39.915) //
this_.map.centerAndZoom(point, 12) //
this_.map.enableScrollWheelZoom(true) //
this_.map.setHeading(64.5) //
this_.map.setTilt(73) //
var geoc = new BMapGL.Geocoder()
this_.map.addEventListener('click', function (e) {
var pt = e.latlng
geoc.getLocation(pt, function (res) {
var addComp = res.addressComponents
this_.form.location = `${addComp.province}${addComp.city}${addComp.district}${addComp.street}${addComp.streetNumber}`
this_.form.longitude = e.latlng.lng
this_.form.latitude = e.latlng.lat
})
this_.map.clearOverlays()
const points = new BMapGL.Point(e.latlng.lng, e.latlng.lat)
// let marker = new BMapGL.Marker(point) //
// this_.map.addOverlay(marker)
if (this_.marker) {
this_.map.removeOverlay(this_.marker)
}
//
this_.marker = new BMapGL.Marker(points)
this_.map.addOverlay(this_.marker)
//
this_.map.centerAndZoom(points, 16)
//
const infoWindow = new BMapGL.InfoWindow(this_.form.location)
this_.marker.addEventListener('click', () => {
this_.map.openInfoWindow(infoWindow, points)
})
//
this_.map.openInfoWindow(infoWindow, points)
})
})
},
/** 修改按钮操作 */
handleUpdate(row) {
@ -396,10 +489,10 @@ export default {
//
findLocation() {
this.mapVisible = false
this.$emit('findlocdata', this.form)
this.temp.location = this.keyword
this.temp.lng = this.form.longitude
this.temp.lat = this.form.latitude
// this.$emit('findlocdata', this.form)
// this.temp.location = this.keyword
// this.temp.lng = this.form.longitude
// this.temp.lat = this.form.latitude
},
/** 删除按钮操作 */
handleDelete(row) {
@ -425,6 +518,61 @@ export default {
`项目信息表.xlsx`,
)
},
//
handleSearch() {
console.log(this.searchAddress, '搜索地址')
const geoc = new BMapGL.Geocoder()
geoc.getPoint(
this.searchAddress,
(point) => {
if (point) {
//
if (this.marker) {
this.map.removeOverlay(this.marker)
}
//
this.marker = new BMapGL.Marker(point)
this.map.addOverlay(this.marker)
//
this.map.centerAndZoom(point, 16)
//
const infoWindow = new BMapGL.InfoWindow(this.searchAddress)
this.marker.addEventListener('click', () => {
this.map.openInfoWindow(infoWindow, point)
})
//
this.map.openInfoWindow(infoWindow, point)
console.log('坐标点:', point)
} else {
this.$message.error('未找到该地址对应的位置')
}
},
'全国',
) // ''
},
//
handleMapClose() {
this.mapVisible = false
if (this.marker) {
this.map.removeOverlay(this.marker)
}
//
if (this.map) {
this.map.removeAllOverlays()
this.map.removeAllListeners()
this.map.clear()
this.map = null
}
},
},
}
</script>

View File

@ -1,284 +1,438 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="项目名称" prop="proName">
<el-input
v-model="queryParams.proName"
placeholder="请输入项目名称"
clearable
@keyup.enter.native="handleQuery"
<div class="app-container">
<el-form
:model="queryParams"
ref="queryForm"
size="small"
:inline="true"
v-show="showSearch"
label-width="68px"
>
<el-form-item label="项目名称" prop="proName">
<el-input
v-model="queryParams.proName"
placeholder="请输入项目名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="堪查人" prop="surveyUser">
<el-input
v-model="queryParams.surveyUser"
placeholder="请输入堪查人"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="勘查时间" prop="surveyTime">
<el-date-picker
v-model="queryParams.surveyTime"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
placeholder="请选择日期选择"
clearable
>
</el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['basic:survey:add']"
>新增</el-button
>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="proList">
<el-table-column label="序号" align="center" type="index" />
<el-table-column label="所属项目" align="center" prop="proName" />
<el-table-column label="堪查人" align="center" prop="surveyUser" />
<el-table-column label="勘查附件" align="center" prop="surveyAttach">
<template slot-scope="{ row }">
<template v-if="row.surveyAttach.length > 0">
<template v-for="(item, index) in row.surveyAttach">
<el-button type="text" @click="handlePreviewFile(item)">附件{{ index + 1 }}</el-button>
<br />
</template>
</template>
</template>
</el-table-column>
<el-table-column label="勘查内容" align="center" prop="surveyContent" />
<el-table-column label="操作" align="center">
<template slot-scope="scope">
<el-button
size="mini"
type="primary"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['basic:survey:edit']"
>编辑</el-button
>
<el-button
size="mini"
type="danger"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['basic:survey:remove']"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</el-form-item>
<el-form-item label="堪查人" prop="surveyUser">
<el-input
v-model="queryParams.surveyUser"
placeholder="请输入堪查人"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="勘查时间" prop="surveyTime">
<el-date-picker v-model="queryParams.surveyTime"
<!-- 添加或修改岗位对话框 -->
<el-dialog :title="title" :visible.sync="open" width="50%" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="项目名称" prop="proId">
<el-select
v-model="form.proId"
placeholder="请选择项目"
style="width: 100%"
@change="handleProChange"
>
<el-option
v-for="item in projectOptions"
:key="item.proId"
:label="item.proName"
:value="item.proId"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="勘查时间" prop="surveyTime" style="width: 100%">
<el-date-picker
clearable
format="yyyy-MM-dd"
style="width: 100%"
v-model="form.surveyTime"
value-format="yyyy-MM-dd"
placeholder="请选择日期选择" clearable>
</el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
placeholder="请选择日期选择"
>
</el-date-picker>
</el-form-item>
<el-form-item label="勘查人" prop="surveyUser" style="width: 100%">
<el-input v-model="form.surveyUser" placeholder="请输入勘查人" />
</el-form-item>
<el-form-item label="勘查内容" prop="surveyContent" style="width: 100%">
<el-input v-model="form.surveyContent" placeholder="请输入勘查内容" />
</el-form-item>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
v-hasPermi="['basic:survey:add']"
>新增</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="proList" @selection-change="handleSelectionChange">
<el-table-column label="序号" align="center" type="index" />
<el-table-column label="所属项目" align="center" prop="proName" />
<el-table-column label="堪查人" align="center" prop="surveyUser" />
<el-table-column label="勘查附件" align="center" prop="surveyAttach" />
<el-table-column label="勘查内容" align="center" prop="surveyContent" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
icon="el-icon-edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['basic:survey:edit']"
>编辑</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
v-hasPermi="['basic:survey:remove']"
>删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改岗位对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="项目名称" prop="proId">
<el-select v-model="form.proId" placeholder="请选择项目">
<el-option
v-for="item in projectOptions"
:key="item.proId"
:label="item.proName"
:value="item.proId">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="勘查时间" prop="surveyTime">
<el-date-picker v-model="form.surveyTime"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
placeholder="请选择日期选择" clearable>
</el-date-picker>
</el-form-item>
<el-form-item label="勘查人" prop="surveyUser">
<el-input v-model="form.surveyUser" placeholder="请输入勘查人" />
</el-form-item>
<el-form-item label="勘查内容" prop="surveyContent">
<el-input v-model="form.surveyContent" placeholder="请输入勘查内容" />
</el-form-item>
<el-form-item label="勘查附件" prop="surveyAttach">
<el-upload
action=""
:auto-upload="false"
:multiple="true"
:limit="3"
:on-change="handleFileChange"
:http-request="customUpload"
:file-list="fileList">
<el-button size="small">上传附件</el-button>
<div slot="tip">支持扩展名.doc/.pdf/.xlsx</div>
</el-upload>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
<el-form-item label="勘察模型" prop="surveyContent" style="width: 100%">
<el-select
v-model="form.modelId"
placeholder="请选择勘察模型"
style="width: 100%"
@change="handleModelChange"
>
<el-option v-for="item in modelOptions" :key="item.id" :label="item.nodeName" :value="item.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="勘查结果" prop="surveyResult" style="width: 100%">
<el-input
type="textarea"
:autosize="{ minRows: 2, maxRows: 4 }"
v-model="form.surveyResult"
placeholder="请输入勘查结果"
/>
</el-form-item>
<el-form-item label="勘查附件" prop="fileList">
<el-upload
:limit="3"
:multiple="true"
:auto-upload="true"
:on-preview="handlePreview"
:on-remove="handleRemove"
:on-success="handleSuccess"
:file-list="form.fileList"
:headers="headers"
action="/dev-api/common/uploadFile"
>
<el-button size="small">上传附件</el-button>
</el-upload>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listSurvey, getSurvey, delSurvey, addSurvey, updateSurvey, projectSelect } from "@/api/basic/survey"
import { listSurvey, getSurvey, delSurvey, addSurvey, updateSurvey, projectSelect } from '@/api/basic/survey'
import { getModelListApi } from '@/api/basic/model'
import { getToken } from '@/utils/auth'
export default {
name: "Post",
dicts: ['sys_normal_disable'],
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
projectOptions: [],
//
proList: [],
//
title: "",
//
dateRange: [],
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
proName: undefined,
unit: undefined,
chargePerson: undefined
},
//
form: {},
//
rules: {
proId: [
{ required: true, message: "项目名称不能为空", trigger: "blur" }
],
surveyTime: [
{ required: true, message: "勘查时间不能为空", trigger: "blur" }
],
surveyUser: [
{ required: true, message: "勘查人不能为空", trigger: "blur" }
],
surveyContent: [
{ required: true, message: "勘查内同不能为空", trigger: "blur" }
]
}
}
},
created() {
this.getList()
},
methods: {
/** 查询岗位列表 */
getList() {
this.loading = true
listSurvey(this.queryParams).then(response => {
this.proList = response.rows
this.total = response.total
this.loading = false
})
},
//
cancel() {
this.open = false
this.reset()
},
//
reset() {
this.form = {
id: undefined,
proId: undefined,
proName: undefined,
proType: undefined,
unit: undefined,
chargePerson: undefined,
location: undefined,
remark: undefined,
dataRange: undefined
}
this.resetForm("form")
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm")
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
projectSelect().then(response => {
this.open = true
this.projectOptions = response.rows
this.title = "添加勘查日志"
})
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const id = row.id || this.ids
projectSelect().then(response => {
this.projectOptions = response.rows
})
getSurvey(id).then(response => {
this.form = response.data
this.open = true
this.title = "修改勘查日志"
})
},
/** 提交按钮 */
submitForm: function() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.id != undefined) {
updateSurvey(this.form).then(response => {
this.$modal.msgSuccess("修改成功")
this.open = false
this.getList()
})
} else {
addSurvey(this.form).then(response => {
this.$modal.msgSuccess("新增成功")
this.open = false
this.getList()
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids
this.$modal.confirm('是否确认删除项目编号为"' + ids + '"的数据项?').then(function() {
return delSurvey(ids)
}).then(() => {
this.getList()
this.$modal.msgSuccess("删除成功")
}).catch(() => {})
},
name: 'Post',
dicts: ['sys_normal_disable'],
data() {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
projectOptions: [],
//
proList: [],
//
title: '',
//
dateRange: [],
//
open: false,
//
queryParams: {
pageNum: 1,
pageSize: 10,
proName: undefined,
surveyUser: undefined,
surveyTime: undefined,
},
//
form: {
fileList: [],
},
//
rules: {
proId: [{ required: true, message: '项目名称不能为空', trigger: 'blur' }],
surveyTime: [{ required: true, message: '勘查时间不能为空', trigger: 'blur' }],
surveyUser: [{ required: true, message: '勘查人不能为空', trigger: 'blur' }],
surveyContent: [{ required: true, message: '勘查内同不能为空', trigger: 'blur' }],
modelId: [{ required: true, message: '请选择勘察模型', trigger: 'change' }],
surveyResult: [{ required: true, message: '请输入勘察结果', trigger: 'blur' }],
fileList: [{ required: true, message: '请上传勘察附件', trigger: 'change' }],
},
}
//
modelOptions: [],
//
headers: {
Authorization: 'Bearer ' + getToken(),
},
}
},
created() {
this.getList()
},
methods: {
/** 查询岗位列表 */
getList() {
this.loading = true
listSurvey(this.queryParams).then((response) => {
this.proList = response.rows
this.proList.forEach((item) => {
if (item.surveyAttach) {
item.surveyAttach = item.surveyAttach.split(',')
} else {
item.surveyAttach = []
}
})
this.total = response.total
this.loading = false
})
},
//
cancel() {
this.open = false
this.reset()
},
//
reset() {
this.form = {
// id: undefined,
// proId: undefined,
// proName: undefined,
// proType: undefined,
// unit: undefined,
// chargePerson: undefined,
// location: undefined,
// remark: undefined,
// dataRange: undefined,
id: null,
projectName: '', //
proId: '', // ID
surveyUser: '', //
surveyTime: '', //
surveyContent: '', //
modelId: '', // id
surveyResult: '', //
surveyAttach: '', //
modelName: '', //
fileList: [],
}
this.resetForm('form')
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm('queryForm')
this.handleQuery()
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
projectSelect().then((response) => {
this.open = true
this.projectOptions = response.rows
this.title = '添加勘查日志'
})
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const id = row.id || this.ids
projectSelect().then((response) => {
this.projectOptions = response.rows
})
getSurvey(id).then(async (response) => {
this.form = response.data
const fileList = response.data.surveyAttach.split(',')
this.form.fileList = fileList.map((item, index) => ({
name: '附件' + (index + 1),
url: item,
}))
const { rows: res } = await getModelListApi({ page: 1, pageSize: 999, projectId: this.form.proId })
this.modelOptions = res.filter((item) => item.nodelevel == item.nodeCount)
this.open = true
this.title = '修改勘查日志'
})
},
/** 提交按钮 */
submitForm: function () {
this.$refs['form'].validate((valid) => {
if (valid) {
const {
id,
// projectName, //
proId, // ID
surveyUser, //
surveyTime, //
surveyContent, //
modelId, // id
surveyResult, //
modelName, //
fileList,
} = this.form
const params = {
// projectName,
proId, // ID
surveyUser, //
surveyTime, //
surveyContent, //
modelId, // id
surveyResult, //
surveyAttach: fileList.map((item) => item.url).join(','), //
modelName, //
}
if (id) {
params.id = id
updateSurvey(params).then((response) => {
this.$modal.msgSuccess('修改成功')
this.open = false
this.getList()
})
} else {
addSurvey(params).then((response) => {
this.$modal.msgSuccess('新增成功')
this.open = false
this.getList()
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
const ids = row.id || this.ids
this.$modal
.confirm('是否确认删除项目编号为"' + ids + '"的数据项?')
.then(function () {
return delSurvey(ids)
})
.then(() => {
this.getList()
this.$modal.msgSuccess('删除成功')
})
.catch(() => {})
},
handlePreviewFile(item) {
window.open(item, '_blank')
},
handlePreview(file) {
window.open(file.url, '_blank')
},
handleSuccess(response, file, fileList) {
console.log(response, file, fileList)
if (file.response.code === 200) {
this.form.fileList.push({
name: file.response.data.newFileName,
...file.response.data,
})
}
},
handleRemove(file, fileList) {
console.log(file, fileList)
this.form.fileList = this.form.fileList.filter((item) => item.url !== file.url)
},
async handleProChange(val) {
console.log(val)
const { rows: res } = await getModelListApi({ page: 1, pageSize: 999, projectId: val })
this.modelOptions = res.filter((item) => item.nodelevel == item.nodeCount)
},
handleModelChange(val) {
this.form.modelName = this.modelOptions.find((item) => item.id == val).nodeName
},
},
}
</script>

View File

@ -1,84 +1,111 @@
<template>
<div class="app-container home"> 首页 </div>
<div class="app-container home" id="map-content"> </div>
</template>
<script>
import { listProject } from '@/api/basic/project'
export default {
name: 'Index',
data() {
return {
//
version: '3.9.0',
map: null,
markers: [],
}
},
methods: {
goTarget(href) {
window.open(href, '_blank')
//
async getProjectList() {
const { rows: res } = await listProject({
pageNum: 1,
pageSize: 1000,
})
this.$nextTick(() => {
if (!this.map) {
this.initMap()
}
if (res.length > 0) {
res.forEach((item) => {
this.addMarker(item)
})
}
})
},
//
initMap() {
this.map = new BMapGL.Map('map-content') //
let point = new BMapGL.Point(117.13805, 31.8734) //
this.map.centerAndZoom(point, 12) //
this.map.enableScrollWheelZoom(true) //
},
//
addMarker(item) {
const point = new BMapGL.Point(item.longitude, item.latitude)
const icon = new BMapGL.Icon(require('@/assets/images/location.png'), new BMapGL.Size(36, 36), {
anchor: new BMapGL.Size(12, 24), // 使
})
// marker
const marker = new BMapGL.Marker(point, {
icon: icon,
})
this.map.addOverlay(marker)
// #002db6
// label
const label = new BMapGL.Label(item.proName, {
position: point,
offset: new BMapGL.Size(-60, 10), // 使marker
})
// label
label.setStyle({
color: '#002db6', //
backgroundColor: 'transparent', //
border: 'none', //
textAlign: 'center', //
padding: '5px',
whiteSpace: 'nowrap', //
fontSize: '18px',
})
this.map.addOverlay(label)
//
const infoWindow = new BMapGL.InfoWindow(`
<div style="padding: 10px;">
<h3 style="color: #002db6; margin: 0 0 10px 0; font-size: 18px;">${item.proName}</h3>
<p>负责人: ${item.chargePerson}</p>
<p>所在地: ${item.location}</p>
</div>
`)
// label
label.addEventListener('mouseover', () => {
this.map.openInfoWindow(infoWindow, point)
})
label.addEventListener('mouseout', () => {
this.map.closeInfoWindow(infoWindow)
})
},
},
created() {
this.getProjectList()
},
updated() {
this.getProjectList()
},
}
</script>
<style scoped lang="scss">
.home {
blockquote {
padding: 10px 20px;
margin: 0 0 20px;
font-size: 17.5px;
border-left: 5px solid #eee;
}
hr {
margin-top: 20px;
margin-bottom: 20px;
border: 0;
border-top: 1px solid #eee;
}
.col-item {
margin-bottom: 20px;
}
ul {
padding: 0;
margin: 0;
}
font-family: 'open sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 13px;
color: #676a6c;
overflow-x: hidden;
ul {
list-style-type: none;
}
h4 {
margin-top: 0px;
}
h2 {
margin-top: 10px;
font-size: 26px;
font-weight: 100;
}
p {
margin-top: 10px;
b {
font-weight: 700;
}
}
.update-log {
ol {
display: block;
list-style-type: decimal;
margin-block-start: 1em;
margin-block-end: 1em;
margin-inline-start: 0;
margin-inline-end: 0;
padding-inline-start: 40px;
}
}
min-height: calc(100vh - 84px);
}
</style>