Compare commits
5 Commits
de52d6daba
...
a0f353f639
| Author | SHA1 | Date |
|---|---|---|
|
|
a0f353f639 | |
|
|
00a33f6417 | |
|
|
635c3f05cc | |
|
|
094145a540 | |
|
|
a75ab14d47 |
|
|
@ -11,7 +11,10 @@
|
|||
<title><%= VITE_GLOB_APP_TITLE %></title>
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<link rel="stylesheet" href="hc/hc.css">
|
||||
|
||||
|
||||
<link href="/public/mapboxgl/mapbox-gl.css" rel="stylesheet">
|
||||
<script src="/public/mapboxgl/mapbox-gl.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
|
|
@ -156,7 +159,6 @@
|
|||
</div>
|
||||
</div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -1328,10 +1328,8 @@ e.setDisabled&&e.setDisabled(!1)}})},resetForm(){Object.keys(this.subFormRefList
|
|||
submitForm() {
|
||||
this.$refs.vFormRef.getFormData().then( (formData) => {
|
||||
// Form Validation OK
|
||||
alert( JSON.stringify(formData) )
|
||||
}).catch( function(error) {
|
||||
// Form Validation Failed
|
||||
alert(error)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -1361,7 +1359,6 @@ e.setDisabled&&e.setDisabled(!1)}})},resetForm(){Object.keys(this.subFormRefList
|
|||
const submitForm = () => {
|
||||
vFormRef.value.getFormData().then(formData => {
|
||||
// Form Validation OK
|
||||
alert( JSON.stringify(formData) )
|
||||
}).catch(error => {
|
||||
// Form Validation failed
|
||||
ElMessage.error(error)
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@
|
|||
"mapbox-extensions":"^1.3.38",
|
||||
"terraformer-wkt-parser": "^1.2.1",
|
||||
"@terraformer/wkt":"2.1.2",
|
||||
"proj4":"2.11.0",
|
||||
"vue3-print-nb":"0.1.4",
|
||||
"ceel-json-editor":"^0.0.3",
|
||||
"@originjs/vite-plugin-commonjs":"^1.0.3",
|
||||
|
|
|
|||
|
|
@ -520,7 +520,6 @@
|
|||
$(document).ready(function () {
|
||||
var IMAGE_BASE_URL = "http://192.168.10.102:9023";
|
||||
function lookImage() {
|
||||
alert(1);
|
||||
}
|
||||
$('.pop-close').click(function () {
|
||||
$('.bgPop2,.pop2').hide();
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -3054,7 +3054,6 @@
|
|||
}), this.geolocationControl.addEventListener("locationSuccess", (function(e) {
|
||||
r.getAddrByPoint(e.point)
|
||||
})), this.geolocationControl.addEventListener("locationError", (function(e) {
|
||||
alert(e.message)
|
||||
})), this.map.addControl(this.geolocationControl), this.map.addEventListener("click", (function(e) {
|
||||
r.getAddrByPoint(e.point)
|
||||
})), this.map.enableScrollWheelZoom(!0), this.loading = !1, this.lng && this.lat && (i = new window.BMap.Point(this.lng, this.lat), this.setPoint(i));
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 431 B |
Binary file not shown.
|
After Width: | Height: | Size: 542 B |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -55,7 +55,8 @@ import { on } from '@/utils/domUtils';
|
|||
let map:Map;
|
||||
|
||||
onMounted(() => {
|
||||
mapboxgl.accessToken = "pk.eyJ1Ijoic2hpY2hhbzEyMyIsImEiOiJja3FobnI1aDEwNGF6Mm9vOXVhNnBzZmFhIn0.2fZKiMqCQHxVY74QShMEGQ"
|
||||
// mapboxgl.accessToken = "pk.eyJ1Ijoic2hpY2hhbzEyMyIsImEiOiJja3FobnI1aDEwNGF6Mm9vOXVhNnBzZmFhIn0.2fZKiMqCQHxVY74QShMEGQ"
|
||||
mapboxgl.accessToken = "123"
|
||||
map = initMap();
|
||||
map.on("load",function(){
|
||||
refreshLocation();
|
||||
|
|
|
|||
|
|
@ -300,7 +300,7 @@
|
|||
])
|
||||
|
||||
function handleBackRows(ModuleId) {
|
||||
alert(ModuleId);
|
||||
|
||||
}
|
||||
|
||||
function dataBaseClick() {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
<!-- empty -->
|
||||
<a-empty
|
||||
v-if="dataList.length==0"
|
||||
v-if="props.layerList.length==0"
|
||||
image="https://gw.alipayobjects.com/mdn/miniapp_social/afts/img/A*pevERLJC9v0AAAAAAAAAAABjAQAAAQ/original"
|
||||
:image-style="{
|
||||
height: '60px',
|
||||
|
|
@ -37,7 +37,7 @@
|
|||
</a-empty>
|
||||
|
||||
<!-- layer list -->
|
||||
<a-card hoverable style="width: 326px;margin-bottom:15px;" v-for="(item,index) in dataList" :key="index">
|
||||
<a-card hoverable style="width: 326px;margin-bottom:15px;" v-for="(item,index) in props.layerList" :key="index">
|
||||
<!-- <template #cover>
|
||||
<img
|
||||
alt="example"
|
||||
|
|
@ -46,12 +46,12 @@
|
|||
</template> -->
|
||||
<template #actions>
|
||||
<setting-outlined key="setting" />
|
||||
<TableOutlined />
|
||||
<DeleteOutlined />
|
||||
<TableOutlined @click="getTableList(item)" />
|
||||
<DeleteOutlined @click="removeLayer(item)" />
|
||||
</template>
|
||||
<a-card-meta :title="item.name" :description="item.description">
|
||||
<template #avatar>
|
||||
<a-checkbox v-model:checked="item.checked" />
|
||||
<a-checkbox v-model:checked="item.checked" @change="handlerLayerShowChange(item)" />
|
||||
<!-- <a-avatar src="https://joeschmoe.io/api/v1/random" /> -->
|
||||
</template>
|
||||
</a-card-meta>
|
||||
|
|
@ -102,7 +102,7 @@
|
|||
|
||||
|
||||
const isSelected = ref();
|
||||
const emits = defineEmits(['changeOpenModal', 'changeOpenInsertShpModal','clearLayerList']);
|
||||
const emits = defineEmits(['changeOpenModal', 'changeOpenInsertShpModal','clearLayerList','handlerLayerShowChange','handlerGetTableList']);
|
||||
const changeClick = () => {
|
||||
emits('changeOpenModal', true);
|
||||
};
|
||||
|
|
@ -116,6 +116,24 @@
|
|||
const handlerClearLayerList = ()=>{
|
||||
emits("clearLayerList")
|
||||
}
|
||||
|
||||
const getTableList = (layer)=> {
|
||||
emits("handlerGetTableList");
|
||||
}
|
||||
|
||||
const removeLayer = (layer)=>{
|
||||
layer.checked = false;
|
||||
emits("handlerLayerShowChange",layer)
|
||||
props.layerList?.forEach((item,index)=>{
|
||||
if(item.id==layer.id){
|
||||
props.layerList.splice(index,1);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const handlerLayerShowChange = (layer)=>{
|
||||
emits("handlerLayerShowChange",layer)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<template>
|
||||
<div class="map-container">
|
||||
<div id="mapContainer" class="map-box"></div>
|
||||
|
||||
<div :id="mapContainerName" class="map-box"></div>
|
||||
|
||||
<!-- 图层控制 -->
|
||||
<div class="layer-control-center" v-if="false">
|
||||
|
|
@ -25,6 +26,38 @@
|
|||
<div class="draw-btn" @click="handlerCancleDraw"> 取消 </div>
|
||||
<div class="draw-btn" @click="handlerDrawComplete"> 保存 </div>
|
||||
</div>
|
||||
|
||||
<!-- 根据输入坐标定位 -->
|
||||
<div class="position-by-lnglat">
|
||||
<div class="to-location">
|
||||
|
||||
</div>
|
||||
<div class="draw-polygon" @click="LocationShow = true">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- -->
|
||||
<div class="to-location-input" v-if="LocationShow">
|
||||
<div class="location-operation">
|
||||
<a-button type="default" size="small" @click="handlerPushLocationItem"><PlusOutlined />添加</a-button>
|
||||
|
||||
<a-button type="default" size="small" @click="handlerClearLocationItem"><ClearOutlined />清空</a-button>
|
||||
|
||||
<span style="float:right;">
|
||||
<CloseOutlined @click="handlerLocationClose" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<a-empty v-if="locationArrays.length==0" />
|
||||
|
||||
<div class="location-item" v-for="(item,index) in locationArrays" :key="index">
|
||||
<a-button type="default" size="small" @click="handlerLocationFlyTo(item)"><EnvironmentOutlined /></a-button>
|
||||
<a-input v-model:value="item.lng" @chagne="handlerLocationChange" addon-before="经度" size="small" style="width:140px;margin:0px 12px;" />
|
||||
<a-input v-model:value="item.lat" @chagne="handlerLocationChange" addon-before="纬度" size="small" style="width:140px;margin-right:12px;" />
|
||||
<a-button type="default" size="small" @click="handlerLocationRemove(index)"><DeleteOutlined /></a-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
@ -40,8 +73,8 @@
|
|||
} from 'vue';
|
||||
|
||||
import { useMessage } from '@/hooks/web/useMessage';
|
||||
|
||||
import mapboxgl, { Map, Popup } from 'mapbox-gl';
|
||||
import {CloseOutlined,EnvironmentOutlined,DeleteOutlined,CopyOutlined,PlusOutlined,ClearOutlined} from "@ant-design/icons-vue"
|
||||
import mapboxgl,{ Map, Popup } from 'mapbox-gl';
|
||||
|
||||
// 图形绘制工具类
|
||||
import MapboxDraw from '@mapbox/mapbox-gl-draw';
|
||||
|
|
@ -72,11 +105,15 @@
|
|||
import { WktToGeojson, GeojsonToWkt } from './src/WktGeojsonTransform';
|
||||
import { features } from 'process';
|
||||
|
||||
const mapContainerName = ref<String>()
|
||||
mapContainerName.value = "mapContainer"+generateUUID();
|
||||
|
||||
const openModal = ref(false);
|
||||
const insertShpModal = ref(false);
|
||||
const changeOpenModal = (value) => {
|
||||
openModal.value = value;
|
||||
};
|
||||
|
||||
const changeOpenInsertShpModal = (value) => {
|
||||
insertShpModal.value = value;
|
||||
};
|
||||
|
|
@ -352,11 +389,11 @@
|
|||
// 初始化地图 返回地图实例
|
||||
const initMap = () => {
|
||||
return new mapboxgl.Map({
|
||||
container: 'mapContainer',
|
||||
container:mapContainerName.value,
|
||||
language: 'zh-cmn',
|
||||
projection: 'equirectangular', // wgs84参考系
|
||||
style: MapboxDefaultStyle,
|
||||
maxZoom: props.mapConfig.maxZoom ? props.mapConfig.maxZoom:18,
|
||||
// maxZoom: props.mapConfig.maxZoom ? props.mapConfig.maxZoom:18,
|
||||
minZoom: props.mapConfig.minZoom ? props.mapConfig.minZoom:1,
|
||||
zoom: props.mapConfig.zoom ? props.mapConfig.zoom:12,
|
||||
pitch:props.mapConfig.angle ? props.mapConfig.angle:0,
|
||||
|
|
@ -773,7 +810,204 @@
|
|||
// 创建查看图斑图层
|
||||
|
||||
|
||||
|
||||
// 粘贴坐标实现定位、绘图相关
|
||||
interface LocationItem {
|
||||
lng:string;
|
||||
lat:string;
|
||||
}
|
||||
|
||||
const LocationShow = ref<Boolean>(false);
|
||||
const locationArrays = ref<LocationItem[]>([]);
|
||||
const locationGeoJson = reactive({
|
||||
point:{
|
||||
"type": "FeatureCollection",
|
||||
"features": []
|
||||
},
|
||||
polyline:{
|
||||
"type": "FeatureCollection",
|
||||
"features": []
|
||||
},
|
||||
polygon:{
|
||||
"type": "FeatureCollection",
|
||||
"features": []
|
||||
}
|
||||
})
|
||||
|
||||
const handlerPushLocationItem = ()=>{
|
||||
let item:LocationItem = {
|
||||
lng:"",
|
||||
lat:"",
|
||||
}
|
||||
locationArrays.value.push(item);
|
||||
}
|
||||
|
||||
const handlerClearLocationItem = ()=>{
|
||||
locationArrays.value = [];
|
||||
locationGeoJson.point.features = [];
|
||||
locationGeoJson.polygon.features = [];
|
||||
locationGeoJson.polyline.features = [];
|
||||
handlerLocationLoadLayer();
|
||||
}
|
||||
|
||||
const handlerLocationClose = ()=>{
|
||||
LocationShow.value = false;
|
||||
}
|
||||
const handlerLocationRemove = (index:number)=>{
|
||||
locationArrays.value.splice(index,1);
|
||||
handlerLocationGeoJson();
|
||||
}
|
||||
|
||||
const handlerLocationChange = (e)=>{
|
||||
|
||||
}
|
||||
|
||||
// 定位跳转
|
||||
const handlerLocationFlyTo = (item:LocationItem)=>{
|
||||
if(item.lng&&item.lat){
|
||||
handlerLocation([item.lng,item.lat]);
|
||||
handlerLocationGeoJson();
|
||||
}
|
||||
}
|
||||
|
||||
// 处理生成geojson数据
|
||||
const handlerLocationGeoJson = ()=>{
|
||||
locationGeoJson.point.features = [];
|
||||
locationGeoJson.polyline.features = [];
|
||||
locationGeoJson.polygon.features = [];
|
||||
|
||||
locationArrays.value?.forEach((item,index)=>{
|
||||
if(item.lng && item.lat){
|
||||
let feature = {
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "Point",
|
||||
"coordinates": [parseFloat(item.lng), parseFloat(item.lat)]
|
||||
}
|
||||
}
|
||||
locationGeoJson.point.features.push(feature);
|
||||
}
|
||||
})
|
||||
if(locationArrays.value?.length>=2){
|
||||
let feature = {
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "LineString",
|
||||
"coordinates": []
|
||||
}
|
||||
}
|
||||
|
||||
locationArrays.value?.forEach((item,index)=>{
|
||||
if(item.lng && item.lat){
|
||||
let coor = [parseFloat(item.lng), parseFloat(item.lat)];
|
||||
feature.geometry.coordinates.push(coor);
|
||||
}
|
||||
})
|
||||
feature.geometry.coordinates.push([parseFloat(locationArrays.value[0].lng),parseFloat(locationArrays.value[0].lat)]);
|
||||
locationGeoJson.polyline.features[0] = feature
|
||||
}
|
||||
if(locationArrays.value?.length>=3){
|
||||
let feature = {
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "MultiLineString",
|
||||
"coordinates": [[]]
|
||||
}
|
||||
}
|
||||
locationArrays.value?.forEach((item,index)=>{
|
||||
if(item.lng && item.lat){
|
||||
let coor = [parseFloat(item.lng), parseFloat(item.lat)];
|
||||
feature.geometry.coordinates[0].push(coor);
|
||||
}
|
||||
})
|
||||
feature.geometry.coordinates[0].push([parseFloat(locationArrays.value[0].lng),parseFloat(locationArrays.value[0].lat)]);
|
||||
locationGeoJson.polygon.features[0] = feature
|
||||
}
|
||||
handlerLocationLoadLayer();
|
||||
console.log("locationGeoJson",locationGeoJson);
|
||||
}
|
||||
|
||||
// 加载点、线、面图层
|
||||
const handlerLocationLoadLayer = ()=>{
|
||||
// 绘制点
|
||||
if(map.getSource("LocationPointSource")){
|
||||
map.getSource("LocationPointSource").setData(locationGeoJson.point);
|
||||
}else{
|
||||
map.addSource("LocationPointSource",{
|
||||
type:"geojson",
|
||||
data:locationGeoJson.point
|
||||
})
|
||||
map.addLayer(
|
||||
{
|
||||
"id": "LocationPointLayer",
|
||||
"type": "circle",
|
||||
"source": "LocationPointSource",
|
||||
paint: {
|
||||
'circle-radius': 5,
|
||||
'circle-color': '#408eff' // 设置点的颜色
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// 绘制线
|
||||
if(map.getSource("LocationPolylineSource")){
|
||||
map.getSource("LocationPolylineSource").setData(locationGeoJson.polyline);
|
||||
}else{
|
||||
map.addSource("LocationPolylineSource",{
|
||||
type:"geojson",
|
||||
data:locationGeoJson.polyline
|
||||
})
|
||||
map.addLayer(
|
||||
{
|
||||
"id": "LocationLineLayer",
|
||||
"type": "line",
|
||||
"source": "LocationPolylineSource",
|
||||
"paint": {
|
||||
'line-color': '#408eff', // 设置线的颜色
|
||||
'line-width': 2 // 设置线的宽度
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// 绘制面
|
||||
if(map.getSource("LocationPolygonSource")){
|
||||
map.getSource("LocationPolygonSource").setData(locationGeoJson.polygon);
|
||||
}else{
|
||||
map.addSource("LocationPolygonSource",{
|
||||
type:"geojson",
|
||||
data:locationGeoJson.polygon
|
||||
})
|
||||
map.addLayer(
|
||||
{
|
||||
"id": "LocationPolygonLayer",
|
||||
"type": "fill",
|
||||
"source": "LocationPolygonSource",
|
||||
"paint": {
|
||||
'fill-color': '#408eff', // 设置填充颜色
|
||||
'fill-opacity': 0.5 // 设置填充透明度
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 绘制点
|
||||
const handlerLocationDrawPoint = ()=>{
|
||||
|
||||
}
|
||||
|
||||
// 绘制线
|
||||
const handlerLocationDrawLine = ()=>{
|
||||
|
||||
}
|
||||
|
||||
// 绘制面
|
||||
const handlerLocationDrawPolygon = ()=>{
|
||||
|
||||
}
|
||||
|
||||
|
||||
defineExpose({
|
||||
handlerDraw,
|
||||
|
|
@ -930,5 +1164,62 @@
|
|||
::v-deep .jas-ctrl-extend-desktop-container {
|
||||
width:320px!important;
|
||||
}
|
||||
|
||||
.position-by-lnglat{
|
||||
width:29px;
|
||||
height:29px;
|
||||
background:#fff;
|
||||
position:absolute;
|
||||
top:10px;
|
||||
right:131px;
|
||||
border-radius:3px;
|
||||
.to-location{
|
||||
display:none;
|
||||
width:29px;
|
||||
height:29px;
|
||||
float:left;
|
||||
background:url(/public/map/location.png);
|
||||
background-size:20px 20px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 4px 5px;
|
||||
&:hover{
|
||||
cursor:pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.draw-polygon{
|
||||
width:29px;
|
||||
height:29px;
|
||||
float:left;
|
||||
background:url(/public/map/draw_polygon.png);
|
||||
background-size:20px 20px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 4px 5px;
|
||||
&:hover{
|
||||
cursor:pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.to-location-input{
|
||||
padding:16px;
|
||||
width:408px;
|
||||
min-height:60px;
|
||||
background: #fff;
|
||||
position:absolute;
|
||||
top:48px;
|
||||
right:10px;
|
||||
border-radius:5px;
|
||||
.location-operation{
|
||||
width:100%;
|
||||
height:40px;
|
||||
border-bottom:1px solid #f1f1f1;
|
||||
margin-bottom:12px;
|
||||
}
|
||||
.location-item{
|
||||
line-height:20px;
|
||||
margin-bottom:6px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
|
@ -19,6 +19,8 @@
|
|||
@changeOpenInsertShpModal="changeOpenInsertShpModal"
|
||||
:layerList="layerList"
|
||||
@clearLayerList="handlerClearLayerList"
|
||||
@handlerLayerShowChange="handlerLayerControler"
|
||||
@handlerGetTableList="handlerGetTableList"
|
||||
/>
|
||||
<div class="close-layer-workspace" @click="changeLayerList">
|
||||
<MenuFoldOutlined v-if="showLayerList" />
|
||||
|
|
@ -33,21 +35,23 @@
|
|||
<!-- <AddLayer v-model:openModal="insertShpModal" /> -->
|
||||
|
||||
<!-- table data list -->
|
||||
<DataListComponent v-if="false" />
|
||||
<DataListComponent v-if="DataTableList" />
|
||||
|
||||
<!-- attribute -->
|
||||
<RightShowInfo v-model:openModal="openRightInfo" />
|
||||
<RightShowInfo :openModal="openRightInfo" />
|
||||
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, onUnmounted, defineProps, reactive, ref, defineExpose } from 'vue';
|
||||
import { useMessage } from '@/hooks/web/useMessage';
|
||||
import mapboxgl, { Map, Popup } from 'mapbox-gl';
|
||||
import { Map, Popup } from 'mapbox-gl';
|
||||
|
||||
// 图形绘制工具类
|
||||
import MapboxDraw from '@mapbox/mapbox-gl-draw';
|
||||
|
||||
|
||||
import U from 'mapbox-gl-utils';
|
||||
import 'mapbox-gl/dist/mapbox-gl.css';
|
||||
import './src/index.less';
|
||||
|
|
@ -69,6 +73,16 @@
|
|||
import AddLayer from './AddLayer/index.vue';
|
||||
import DataListComponent from './DataListComponent/index.vue';
|
||||
import RightShowInfo from './RightShowInfo/index.vue';
|
||||
|
||||
import proj4 from 'proj4';
|
||||
// let fromProjection = "+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs +type=crs";
|
||||
let fromProjection = "+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=39500000 +y_0=0 +ellps=GRS80 +units=m +no_defs +type=crs"
|
||||
// let toProjection = "+proj=longlat +ellps=GRS80 +no_defs +type=crs"
|
||||
let toProjection = "+proj=longlat +datum=WGS84 +no_defs +type=crs";
|
||||
|
||||
// let coordinates = [39591762.54875996,3908085.3169043385];
|
||||
let coordinates = [39592654.90645946,3909001.5344353705]
|
||||
const converted = proj4(fromProjection, toProjection, coordinates);
|
||||
|
||||
const openModal = ref(false);
|
||||
const insertShpModal = ref(false);
|
||||
|
|
@ -81,7 +95,7 @@
|
|||
};
|
||||
|
||||
// layer list
|
||||
const showLayerList = ref<boolean>(true);
|
||||
const showLayerList = ref<boolean>(false);
|
||||
const changeLayerList = ()=>{
|
||||
showLayerList.value = !showLayerList.value;
|
||||
}
|
||||
|
|
@ -93,9 +107,7 @@
|
|||
}
|
||||
|
||||
const handlerClearLayerList = () => {
|
||||
layerList.value?.forEach((item,index)=>{
|
||||
layerList.value?.pop();
|
||||
})
|
||||
layerList.value = [];
|
||||
}
|
||||
|
||||
// map参数类型
|
||||
|
|
@ -130,8 +142,69 @@
|
|||
|
||||
onMounted(() => {
|
||||
mapboxgl.accessToken = MapboxConfig.ACCESS_TOKEN;
|
||||
|
||||
map = initMap();
|
||||
map.on('load', () => {
|
||||
|
||||
|
||||
|
||||
map.addLayer({
|
||||
'id': 'wms-test-layer',
|
||||
'type': 'raster',
|
||||
'source': {
|
||||
'type': 'raster',
|
||||
'tiles': [
|
||||
// "http://175.27.168.120:8080/geoserver/feixian/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&FORMAT=image%2Fjpeg&TRANSPARENT=true&LAYERS=feixian%3Ayingxiang_17&exceptions=application%2Fvnd.ogc.se_inimage&SRS=EPSG%3A4548&STYLES=&WIDTH=728&HEIGHT=768&BBOX=586801.5388788335%2C3908183.1422136417%2C590270.7583843566%2C3911848.0123377703",
|
||||
// "http://175.27.168.120:8080/geoserver/feixian/wms?service=WMS&version=1.1.0&request=GetMap&layers=feixian:yingxiang_17&styles=&bbox={bbox-epsg-3857}&width=256&height=256&srs=EPSG:3857&format=image/png&TRANSPARENT=TRUE"
|
||||
"http://60.213.14.14:8060/geoserver/feixian/wms?service=WMS&version=1.1.0&request=GetMap&layers=feixian:yingxiang&styles=&bbox={bbox-epsg-3857}&width=256&height=256&srs=EPSG:3857&format=image/png&TRANSPARENT=TRUE"
|
||||
],
|
||||
'tileSize': 256
|
||||
},
|
||||
'paint': {}
|
||||
});
|
||||
|
||||
map.addSource('radar', {
|
||||
'type': 'image',
|
||||
// 'url': 'http://175.27.168.120:8080/geoserver/feixian/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&FORMAT=image%2Fjpeg&TRANSPARENT=true&LAYERS=feixian%3Ayingxiang_17&exceptions=application%2Fvnd.ogc.se_inimage&SRS=EPSG%3A4548&STYLES=&WIDTH=728&HEIGHT=768&BBOX=586801.5388788335%2C3908183.1422136417%2C590270.7583843566%2C3911848.0123377703',
|
||||
// 'url':"http://175.27.168.120:8080/geoserver/feixian/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&FORMAT=image%2Fjpeg&TRANSPARENT=true&LAYERS=feixian%3Ayingxiang_17&exceptions=application%2Fvnd.ogc.se_inimage&SRS=EPSG%3A4548&STYLES=&WIDTH=727&HEIGHT=768&BBOX=591035.9133569683%2C3908525.08342436%2C591469.2675472646%2C3908982.893941982",
|
||||
'url':"http://60.213.14.14:8060/geoserver/feixian/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&FORMAT=image%2Fjpeg&TRANSPARENT=true&LAYERS=feixian%3Ayingxiang&exceptions=application%2Fvnd.ogc.se_inimage&SRS=EPSG%3A4527&STYLES=&WIDTH=1024&HEIGHT=1024&BBOX=39591762.54875996%2C3908085.3169043385%2C39592654.90645946%2C3909001.5344353705",
|
||||
'coordinates': [
|
||||
|
||||
|
||||
// EPSG:4548
|
||||
// [118.00090749819051,35.30579563806707],
|
||||
// [118.0057224793592,35.30579563806707],
|
||||
// [118.0057224793592,35.30170937770571],
|
||||
// [118.00090749819051,35.30170937770571],
|
||||
|
||||
// EPSG:4527
|
||||
// [118.00884630303432,35.3058545162185],
|
||||
// [118.01875909202998,35.3058545162185],
|
||||
// [118.01875909202998,35.29767983003392],
|
||||
// [118.00884630303432,35.29767983003392],
|
||||
|
||||
[118.00884630303432,35.30585451621851],
|
||||
[118.01875909202998,35.30585451621851],
|
||||
[118.01875909202998,35.297679830033914],
|
||||
[118.00884630303432,35.297679830033914],
|
||||
|
||||
// [39591762.54875996,3909001.5344353705],
|
||||
// [39592654.90645946,3909001.5344353705],
|
||||
// [39592654.90645946,3908085.3169043385],
|
||||
// [39591762.54875996,3908085.3169043385],
|
||||
]
|
||||
});
|
||||
map.addLayer({
|
||||
id: 'radar-layer',
|
||||
'type': 'raster',
|
||||
'source': 'radar',
|
||||
'paint': {
|
||||
'raster-fade-duration': 0
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
//挂载mapbox-gl-utils
|
||||
// U.init(map);
|
||||
mp = new MP(map);
|
||||
|
|
@ -271,6 +344,39 @@
|
|||
defineExpose({
|
||||
handlerRenderLayer,
|
||||
});
|
||||
|
||||
|
||||
const handlerLayerControler = (layerInfo) => {
|
||||
|
||||
layerInfo.layer = layerInfo.layer? layerInfo.layer : JSON.parse(layerInfo.style);
|
||||
|
||||
if (map.getSource(layerInfo.layer.id)) {
|
||||
if (layerInfo.checked) {
|
||||
map.setLayoutProperty(layerInfo.layer.id, 'visibility', 'visible');
|
||||
} else {
|
||||
map.setLayoutProperty(layerInfo.layer.id, 'visibility', 'none');
|
||||
}
|
||||
} else {
|
||||
map.addLayer(layerInfo.layer);
|
||||
map.on('click', layerInfo.layer.id, function (e) {
|
||||
handlerPreviewFeatureInfo(e);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 图斑属性查看
|
||||
const handlerPreviewFeatureInfo = (e) => {
|
||||
if (e.features) {
|
||||
openRightInfo.value = true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const DataTableList = ref<Boolean>(false);
|
||||
const handlerGetTableList = ()=>{
|
||||
DataTableList.value = true;
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<a-drawer class="right-show-info" placement="right" :open="open" @close="() => (open = false)">
|
||||
<a-drawer class="right-show-info" placement="right" :open="props.openModal" @close="props.openModal = false">
|
||||
<div class="title">
|
||||
<div class="tag"></div>
|
||||
<div class="title-text">操作</div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
export enum MapboxConfig {
|
||||
ACCESS_TOKEN = 'pk.eyJ1Ijoic2hpY2hhbzEyMyIsImEiOiJja3FobnI1aDEwNGF6Mm9vOXVhNnBzZmFhIn0.2fZKiMqCQHxVY74QShMEGQ',
|
||||
// ACCESS_TOKEN = 'pk.eyJ1Ijoic2hpY2hhbzEyMyIsImEiOiJja3FobnI1aDEwNGF6Mm9vOXVhNnBzZmFhIn0.2fZKiMqCQHxVY74QShMEGQ',
|
||||
ACCESS_TOKEN = "1234",
|
||||
TDT_TOKEN = 'b6585bc41ee16251dbe6b1af64f375d9',
|
||||
// add more config options here
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@
|
|||
<div class="file-item" v-for="(item,index) in fileList" :key="index">
|
||||
{{ item.name }}
|
||||
<span class="delete-btn" @click="handlerDelete(index)"><DeleteOutlined/></span>
|
||||
<span class="delete-btn" @click="handlerPreviewFile(item.url)"><CloudDownloadOutlined /></span>
|
||||
|
||||
</div>
|
||||
<Modal :open="previewOpen" :title="previewTitle" :footer="null" @cancel="handleCancel">
|
||||
<img alt="" style="width: 100%" :src="previewImage" />
|
||||
|
|
@ -37,7 +39,7 @@
|
|||
|
||||
<script lang="ts" setup>
|
||||
import { ref, toRefs, watch } from 'vue';
|
||||
import { PlusOutlined,InboxOutlined,DeleteOutlined } from '@ant-design/icons-vue';
|
||||
import { PlusOutlined,InboxOutlined,DeleteOutlined,CloudDownloadOutlined } from '@ant-design/icons-vue';
|
||||
import type { UploadFile, UploadProps } from 'ant-design-vue';
|
||||
import { Modal, UploadDragger } from 'ant-design-vue';
|
||||
import { UploadRequestOption } from 'ant-design-vue/lib/vc-upload/interface';
|
||||
|
|
@ -161,6 +163,10 @@ import { fileUploadApi } from '@/api/sys/upload';
|
|||
emit("change",value);
|
||||
}
|
||||
|
||||
const handlerPreviewFile = (path)=>{
|
||||
window.open(path,"_blank");
|
||||
}
|
||||
|
||||
const handleCancel = () => {
|
||||
previewOpen.value = false;
|
||||
previewTitle.value = '';
|
||||
|
|
@ -255,6 +261,7 @@ function getValue() {
|
|||
float:right;
|
||||
color:#d9d9d9;
|
||||
cursor:pointer;
|
||||
margin:0px 8px;
|
||||
|
||||
}
|
||||
.delete-btn:hover{
|
||||
|
|
|
|||
|
|
@ -4,12 +4,8 @@
|
|||
<div v-if="!$attrs.disabled" class="video-delete-btn" @click="handlerDelete(index)">
|
||||
<CloseOutlined/>
|
||||
</div>
|
||||
<a-image
|
||||
width="100px"
|
||||
:src="item.url"
|
||||
></a-image>
|
||||
<img :src="item.url" width="100px" alt="" @click="handlerPreviewImage(item.url)" >
|
||||
</div>
|
||||
|
||||
|
||||
<Upload
|
||||
v-if="!$attrs.disabled"
|
||||
|
|
@ -37,8 +33,9 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, toRefs, watch,reactive, onMounted } from 'vue';
|
||||
<script setup lang="ts">
|
||||
|
||||
import { ref, toRefs, watch,reactive, onMounted,provide,inject } from 'vue';
|
||||
import { PlusOutlined,CloseOutlined } from '@ant-design/icons-vue';
|
||||
import type { UploadFile, UploadProps,UploadChangeParam } from 'ant-design-vue';
|
||||
import { Modal, Upload } from 'ant-design-vue';
|
||||
|
|
@ -53,6 +50,11 @@
|
|||
import { UploadResultStatus } from '@/components/Upload/src/types/typing';
|
||||
import { actions } from '@/views/demo/page/account/center/data';
|
||||
import { fileUploadApi } from '@/api/sys/upload';
|
||||
import ImagePreview from "@/components/Upload/src/components/image_preview.vue";
|
||||
import { userFormFileStore } from '@/store/modules/formFileUrl';
|
||||
|
||||
const formFileStore = userFormFileStore();
|
||||
|
||||
|
||||
defineOptions({ name: 'ImageUpload' });
|
||||
|
||||
|
|
@ -265,6 +267,15 @@
|
|||
// });
|
||||
// return props.multiple ? list : list.length > 0 ? list[0] : '';
|
||||
}
|
||||
|
||||
const globalImagePreviewUrl = ref<String>("");
|
||||
|
||||
|
||||
function handlerPreviewImage(url):void{
|
||||
globalImagePreviewUrl.value = url+"?"+Math.random();
|
||||
formFileStore.setUrl(url+"?"+Math.random());
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
|
|
@ -327,4 +338,14 @@
|
|||
width:500px;
|
||||
margin:10px;
|
||||
}
|
||||
|
||||
.image-preview{
|
||||
width:100%;
|
||||
height:100%;
|
||||
position:absolute;
|
||||
top:50%;
|
||||
left:50%;
|
||||
transform: translate(-50%,-50%);
|
||||
z-index:999;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -208,7 +208,6 @@
|
|||
async function handleStartUpload() {
|
||||
|
||||
const { maxNumber,action } = props;
|
||||
alert(action);
|
||||
if ((fileListRef.value.length + props.previewFileList?.length ?? 0) > maxNumber) {
|
||||
return createMessage.warning(t('component.upload.maxNumber', [maxNumber]));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,237 @@
|
|||
<template>
|
||||
<div class="image-preview-container" id="imagePreviewContainer">
|
||||
<img id="zoomableImage" draggable="false" :src="imageUrl" />
|
||||
<div class="operation-container">
|
||||
<div>
|
||||
<UndoOutlined />
|
||||
</div>
|
||||
<div>
|
||||
<ZoomInOutlined @click="bigScale" />
|
||||
</div>
|
||||
<div>
|
||||
<ZoomOutOutlined @click="smallScale"/>
|
||||
</div>
|
||||
<div>
|
||||
<RedoOutlined @click="transform" />
|
||||
</div>
|
||||
<div>
|
||||
<CloseOutlined @click="closePreview"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ZoomInOutlined, ZoomOutOutlined, RedoOutlined, UndoOutlined, CloseOutlined } from '@ant-design/icons-vue';
|
||||
import {ref,onMounted,defineEmits,inject,defineProps} from 'vue';
|
||||
|
||||
const emits = defineEmits(["closeImagePreview"])
|
||||
|
||||
const props = defineProps({
|
||||
globalImagePreviewUrl:{
|
||||
type:String
|
||||
}
|
||||
})
|
||||
|
||||
const imageUrl = props.globalImagePreviewUrl
|
||||
|
||||
|
||||
let isDragging = false;
|
||||
let initialMouseX;
|
||||
let initialMouseY;
|
||||
let initialImageX;
|
||||
let initialImageY;
|
||||
|
||||
|
||||
onMounted(()=>{
|
||||
|
||||
const draggableImage = document.getElementById('zoomableImage');
|
||||
const imageContainer = document.getElementById('imagePreviewContainer');
|
||||
|
||||
|
||||
|
||||
|
||||
const zoomableImage = document.getElementById("zoomableImage");
|
||||
// zoomableImage.addEventListener('wheel', handleWheel);
|
||||
|
||||
|
||||
var scale = 1;
|
||||
var minScale = 0.5;
|
||||
var maxScale = 3;
|
||||
var scaleFactor = 0.1;
|
||||
|
||||
var containerRect = imageContainer.getBoundingClientRect();
|
||||
|
||||
imageContainer.addEventListener('wheel', function(event) {
|
||||
event.preventDefault();
|
||||
|
||||
var mouseX = event.clientX - containerRect.left; // 鼠标相对于容器的X坐标
|
||||
var mouseY = event.clientY - containerRect.top; // 鼠标相对于容器的Y坐标
|
||||
|
||||
var delta = -Math.max(-1, Math.min(1, (event.deltaY || -event.detail)));
|
||||
var zoomFactor = Math.exp(delta * scaleFactor);
|
||||
console.log("delta",delta,zoomFactor);
|
||||
|
||||
|
||||
var oldWidth = zoomableImage.clientWidth;
|
||||
var oldHeight = zoomableImage.clientHeight;
|
||||
|
||||
var newWidth = Math.min(Math.max(oldWidth * zoomFactor, containerRect.width * minScale), containerRect.width * maxScale);
|
||||
var newHeight = Math.min(Math.max(oldHeight * zoomFactor, containerRect.height * minScale), containerRect.height * maxScale);
|
||||
|
||||
var widthDiff = newWidth - oldWidth;
|
||||
var heightDiff = newHeight - oldHeight;
|
||||
|
||||
var mouseXPercent = mouseX / containerRect.width;
|
||||
var mouseYPercent = mouseY / containerRect.height;
|
||||
|
||||
var translateX = widthDiff * mouseXPercent;
|
||||
var translateY = heightDiff * mouseYPercent;
|
||||
|
||||
scale *= zoomFactor;
|
||||
|
||||
zoomableImage.style.transformOrigin = mouseXPercent * 100 + '% ' + mouseYPercent * 100 + '%';
|
||||
zoomableImage.style.transform = 'scale(' + scale + ') translate(' + translateX + 'px, ' + translateY + 'px)';
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
draggableImage.addEventListener('mousedown', function(event) {
|
||||
isDragging = true;
|
||||
initialMouseX = event.clientX;
|
||||
initialMouseY = event.clientY;
|
||||
initialImageX = draggableImage.offsetLeft;
|
||||
initialImageY = draggableImage.offsetTop;
|
||||
draggableImage.style.cursor = 'grabbing';
|
||||
});
|
||||
|
||||
document.addEventListener('mousemove', function(event) {
|
||||
if (isDragging) {
|
||||
const deltaX = event.clientX - initialMouseX;
|
||||
const deltaY = event.clientY - initialMouseY;
|
||||
draggableImage.style.left = initialImageX + deltaX + 'px';
|
||||
draggableImage.style.top = initialImageY + deltaY + 'px';
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('mouseup', function() {
|
||||
isDragging = false;
|
||||
draggableImage.style.cursor = 'default';
|
||||
});
|
||||
|
||||
|
||||
})
|
||||
|
||||
function handleWheel(event) {
|
||||
// event.preventDefault();
|
||||
// const delta = Math.sign(event.deltaY);
|
||||
// if (delta > 0) {
|
||||
// if(scale > 0.2){
|
||||
// scale -= scaleStep;
|
||||
// }else if(scale>1.6){
|
||||
// scale -= 0.2;
|
||||
// }
|
||||
// } else {
|
||||
// if(scale>1.6){
|
||||
// scale += 0.2;
|
||||
// }else{
|
||||
// scale += scaleStep;
|
||||
// }
|
||||
|
||||
// }
|
||||
// zoomableImage.style.transform = `scale(${scale})`;
|
||||
const imageContainer = document.getElementById('imagePreviewContainer');
|
||||
let containerRect = imageContainer.getBoundingClientRect();
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
var mouseX = event.clientX - containerRect.left; // 鼠标相对于容器的X坐标
|
||||
var mouseY = event.clientY - containerRect.top; // 鼠标相对于容器的Y坐标
|
||||
|
||||
var delta = Math.max(-1, Math.min(1, (event.deltaY || -event.detail)));
|
||||
|
||||
var zoomFactor = Math.exp(delta * scaleFactor);
|
||||
|
||||
var oldWidth = zoomableImage.clientWidth;
|
||||
var oldHeight = zoomableImage.clientHeight;
|
||||
|
||||
var newWidth = Math.min(Math.max(oldWidth * zoomFactor, containerRect.width * minScale), containerRect.width * maxScale);
|
||||
var newHeight = Math.min(Math.max(oldHeight * zoomFactor, containerRect.height * minScale), containerRect.height * maxScale);
|
||||
|
||||
var widthDiff = newWidth - oldWidth;
|
||||
var heightDiff = newHeight - oldHeight;
|
||||
|
||||
var mouseXPercent = mouseX / containerRect.width;
|
||||
var mouseYPercent = mouseY / containerRect.height;
|
||||
|
||||
var translateX = widthDiff * mouseXPercent;
|
||||
var translateY = heightDiff * mouseYPercent;
|
||||
|
||||
scale *= zoomFactor;
|
||||
|
||||
zoomableImage.style.transformOrigin = mouseXPercent * 100 + '% ' + mouseYPercent * 100 + '%';
|
||||
zoomableImage.style.transform = 'scale(' + scale + ') translate(' + translateX + 'px, ' + translateY + 'px)';
|
||||
}
|
||||
|
||||
function smallScale():void {
|
||||
if(scale>0.4){
|
||||
scale-=0.4;
|
||||
}
|
||||
zoomableImage.style.transform = `scale(${scale})`;
|
||||
}
|
||||
|
||||
function bigScale():void {
|
||||
scale+=0.4;
|
||||
zoomableImage.style.transform = `scale(${scale})`;
|
||||
}
|
||||
|
||||
function closePreview():void{
|
||||
emits("closeImagePreview");
|
||||
}
|
||||
|
||||
</script>
|
||||
<style type="less" scoped>
|
||||
.image-preview-container{
|
||||
position:absolute;
|
||||
z-index:99999999;
|
||||
top:0px;
|
||||
left:0px;
|
||||
width:100%;
|
||||
height: 100%;
|
||||
margin:0px auto;
|
||||
background:rgba(0,0,0,0.4);
|
||||
overflow: hidden;
|
||||
#zoomableImage {
|
||||
position:relative;
|
||||
top:0px;
|
||||
left:20%;
|
||||
width:60%;
|
||||
cursor:default;
|
||||
display: block;
|
||||
max-width: none;
|
||||
max-height: none;
|
||||
transition: transform 0.2s ease-out; /* 添加平滑过渡效果 */
|
||||
}
|
||||
.operation-container{
|
||||
padding:0px 100px;
|
||||
width: calc( 100% - 0px);
|
||||
height:60px;
|
||||
position:absolute;
|
||||
bottom:0px;
|
||||
left:0px;
|
||||
background:rgba(0,0,0,0.3);
|
||||
display: flex;
|
||||
line-height: 60px;
|
||||
color:#fff;
|
||||
div {
|
||||
flex:1;
|
||||
text-align: center;
|
||||
cursor:pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
</style>
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
<template>
|
||||
<div class="image-preview-container" id="imagePreviewContainer">
|
||||
<img id="zoomableImage" draggable="false" src="http://192.168.10.102:9023//20240629\2024062914291178850041.jpg" />
|
||||
<div class="operation-container">
|
||||
<div>
|
||||
<UndoOutlined />
|
||||
</div>
|
||||
<div>
|
||||
<ZoomInOutlined @click="bigScale" />
|
||||
</div>
|
||||
<div>
|
||||
<ZoomOutOutlined @click="smallScale"/>
|
||||
</div>
|
||||
<div>
|
||||
<RedoOutlined @click="transform" />
|
||||
</div>
|
||||
<div>
|
||||
<CloseOutlined @click="closePreview"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ZoomInOutlined, ZoomOutOutlined, RedoOutlined, UndoOutlined, CloseOutlined } from '@ant-design/icons-vue';
|
||||
import {ref,onMounted,defineEmits,} from 'vue';
|
||||
|
||||
const emits = defineEmits(["defineEmits"])
|
||||
|
||||
|
||||
let scale = 1.0;
|
||||
const scaleStep = 0.15;
|
||||
|
||||
let isDragging = false;
|
||||
let initialMouseX;
|
||||
let initialMouseY;
|
||||
let initialImageX;
|
||||
let initialImageY;
|
||||
|
||||
|
||||
|
||||
onMounted(()=>{
|
||||
const zoomableImage = document.getElementById("zoomableImage");
|
||||
zoomableImage.addEventListener('wheel', handleWheel);
|
||||
|
||||
|
||||
const draggableImage = document.getElementById('zoomableImage');
|
||||
const imageContainer = document.getElementById('imagePreviewContainer');
|
||||
|
||||
draggableImage.addEventListener('mousedown', function(event) {
|
||||
isDragging = true;
|
||||
initialMouseX = event.clientX;
|
||||
initialMouseY = event.clientY;
|
||||
initialImageX = draggableImage.offsetLeft;
|
||||
initialImageY = draggableImage.offsetTop;
|
||||
draggableImage.style.cursor = 'grabbing';
|
||||
});
|
||||
|
||||
document.addEventListener('mousemove', function(event) {
|
||||
if (isDragging) {
|
||||
const deltaX = event.clientX - initialMouseX;
|
||||
const deltaY = event.clientY - initialMouseY;
|
||||
draggableImage.style.left = initialImageX + deltaX + 'px';
|
||||
draggableImage.style.top = initialImageY + deltaY + 'px';
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('mouseup', function() {
|
||||
isDragging = false;
|
||||
draggableImage.style.cursor = 'default';
|
||||
});
|
||||
|
||||
|
||||
})
|
||||
|
||||
|
||||
function handleWheel(event) {
|
||||
event.preventDefault();
|
||||
const delta = Math.sign(event.deltaY);
|
||||
if (delta > 0) {
|
||||
if(scale > 0.2){
|
||||
scale -= scaleStep;
|
||||
}else if(scale>1.6){
|
||||
scale -= 0.2;
|
||||
}
|
||||
} else {
|
||||
if(scale>1.6){
|
||||
scale += 0.2;
|
||||
}else{
|
||||
scale += scaleStep;
|
||||
}
|
||||
|
||||
}
|
||||
zoomableImage.style.transform = `scale(${scale})`;
|
||||
}
|
||||
|
||||
function smallScale():void {
|
||||
if(scale>0.4){
|
||||
scale-=0.4;
|
||||
}
|
||||
zoomableImage.style.transform = `scale(${scale})`;
|
||||
}
|
||||
|
||||
function bigScale():void {
|
||||
scale+=0.4;
|
||||
zoomableImage.style.transform = `scale(${scale})`;
|
||||
}
|
||||
|
||||
function closePreview():void{
|
||||
emits("defineEmits");
|
||||
}
|
||||
</script>
|
||||
<style type="less" scoped>
|
||||
.image-preview-container{
|
||||
position:absolute;
|
||||
z-index:99999;
|
||||
width:500px;
|
||||
height:500px;
|
||||
margin:0px auto;
|
||||
background:rgba(0,0,0,0.1);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#zoomableImage{
|
||||
width:100%;
|
||||
position:absolute;
|
||||
cursor:default;
|
||||
}
|
||||
.operation-container{
|
||||
padding:0px 100px;
|
||||
width: calc( 100% - 200px);
|
||||
height:60px;
|
||||
position:absolute;
|
||||
bottom:0px;
|
||||
left:0px;
|
||||
background:rgba(0,0,0,0.2);
|
||||
display: flex;
|
||||
line-height: 60px;
|
||||
color:#fff;
|
||||
}
|
||||
.operation-container div{
|
||||
flex:1;
|
||||
text-align: center;
|
||||
cursor:pointer;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
import type {
|
||||
ProjectConfig,
|
||||
HeaderSetting,
|
||||
MenuSetting,
|
||||
TransitionSetting,
|
||||
MultiTabsSetting,
|
||||
} from '#/config';
|
||||
import type { BeforeMiniState, ApiAddress } from '#/store';
|
||||
|
||||
import { defineStore } from 'pinia';
|
||||
import { store } from '@/store';
|
||||
|
||||
import { resetRouter } from '@/router';
|
||||
import { deepMerge } from '@/utils';
|
||||
|
||||
interface FormFile {
|
||||
url:String
|
||||
}
|
||||
|
||||
export const userFormFileStore = defineStore({
|
||||
id: 'formfileurl',
|
||||
state: (): FormFile => ({
|
||||
url:""
|
||||
}),
|
||||
getters: {
|
||||
getUrl(state): boolean {
|
||||
return state.url;
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
setUrl(url:string): void {
|
||||
this.url = url;
|
||||
},
|
||||
},
|
||||
mutations:{
|
||||
setUrl(url:string): void {
|
||||
this.url = url;
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
// Need to be used outside the setup
|
||||
export function useAppStoreWithOut() {
|
||||
return userFormFileStore(store);
|
||||
}
|
||||
|
||||
|
|
@ -46,6 +46,7 @@ interface PermissionState {
|
|||
changeMenu: number;
|
||||
}
|
||||
|
||||
|
||||
export const usePermissionStore = defineStore({
|
||||
id: 'app-permission',
|
||||
state: (): PermissionState => ({
|
||||
|
|
|
|||
|
|
@ -4,12 +4,17 @@
|
|||
-->
|
||||
<template>
|
||||
<div class="form-panel v-form-container">
|
||||
<ImagePreview v-if="isShowImagePreview" :globalImagePreviewUrl="globalImagePreviewUrl" @closeImagePreview="closeImagePreview"></ImagePreview>
|
||||
<Empty
|
||||
class="empty-text"
|
||||
v-show="formConfig.schemas.length === 0"
|
||||
description="从左侧选择控件添加"
|
||||
/>
|
||||
<Form v-bind="formConfig">
|
||||
<div class="image-preview" v-if="false">
|
||||
<ImagePreview ></ImagePreview>
|
||||
</div>
|
||||
|
||||
<div class="draggable-box">
|
||||
<draggable
|
||||
class="list-main ant-row"
|
||||
|
|
@ -39,10 +44,14 @@
|
|||
<script lang="ts">
|
||||
import draggable from 'vuedraggable';
|
||||
import LayoutItem from '../components/LayoutItem.vue';
|
||||
import { defineComponent, computed } from 'vue';
|
||||
import { defineComponent, computed,ref,inject,watch } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { useFormDesignState } from '../../../hooks/useFormDesignState';
|
||||
import { Form, Empty } from 'ant-design-vue';
|
||||
import ImagePreview from "@/components/Upload/src/components/image_preview.vue";
|
||||
import { userFormFileStore } from '@/store/modules/formFileUrl';
|
||||
|
||||
|
||||
export default defineComponent({
|
||||
name: 'FormComponentPanel',
|
||||
|
|
@ -51,6 +60,7 @@
|
|||
draggable,
|
||||
Form,
|
||||
Empty,
|
||||
ImagePreview
|
||||
},
|
||||
emits: ['handleSetSelectItem'],
|
||||
setup(_, { emit }) {
|
||||
|
|
@ -83,11 +93,28 @@
|
|||
return formConfig.value.layout === 'horizontal' ? 'Col' : 'div';
|
||||
});
|
||||
|
||||
// 图片预览
|
||||
const isShowImagePreview = ref<Boolean>(false);
|
||||
|
||||
const closeImagePreview = ()=>{
|
||||
isShowImagePreview.value = false;
|
||||
}
|
||||
const globalImagePreviewUrl=ref<String>();
|
||||
const formFileStore = userFormFileStore();
|
||||
const formFileState = storeToRefs(formFileStore);
|
||||
watch(formFileState.url, (newValue, oldValue) => {
|
||||
isShowImagePreview.value = true;
|
||||
globalImagePreviewUrl.value = newValue;
|
||||
});
|
||||
|
||||
return {
|
||||
addItem,
|
||||
handleDragStart,
|
||||
formConfig,
|
||||
layoutTag,
|
||||
closeImagePreview,
|
||||
isShowImagePreview,
|
||||
globalImagePreviewUrl
|
||||
};
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
:closeFunc="closeFunc"
|
||||
:destroyOnClose="true"
|
||||
>
|
||||
<ImagePreview style="width:100%;height:" v-if="isShowImagePreview" :globalImagePreviewUrl="globalImagePreviewUrl" @closeImagePreview="closeImagePreview"></ImagePreview>
|
||||
|
||||
<template v-if="tabsColumns.length > 1">
|
||||
<a-tabs style="width: 100%" @change="tabsChange">
|
||||
<a-tab-pane v-for="(colItem, index) in tabsColumns" :tab="colItem.label" :key="index">
|
||||
|
|
@ -150,7 +152,7 @@
|
|||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { unref, ref, reactive } from 'vue';
|
||||
import { unref, ref, reactive,watch } from 'vue';
|
||||
import { FormSchema } from '@/components/Table';
|
||||
import { BasicModal, useModalInner } from '@/components/Modal';
|
||||
import { BasicForm, useForm } from '@/components/Form';
|
||||
|
|
@ -169,6 +171,9 @@
|
|||
import dayjs from 'dayjs';
|
||||
import Icon from '@/components/Icon/Icon.vue';
|
||||
|
||||
import { storeToRefs } from 'pinia';
|
||||
import ImagePreview from "@/components/Upload/src/components/image_preview.vue";
|
||||
import { userFormFileStore } from '@/store/modules/formFileUrl';
|
||||
const subTableDataStore = subTableStore();
|
||||
|
||||
// import FormRender from '@/views/demo/form-design/components/VFormCreate/components/FormRender.vue';
|
||||
|
|
@ -830,4 +835,19 @@
|
|||
createOrModifyList.value = [];
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
// 图片预览
|
||||
const isShowImagePreview = ref<Boolean>(false);
|
||||
const closeImagePreview = ()=>{
|
||||
isShowImagePreview.value = false;
|
||||
}
|
||||
const globalImagePreviewUrl=ref<String>();
|
||||
const formFileStore = userFormFileStore();
|
||||
const formFileState = storeToRefs(formFileStore);
|
||||
watch(formFileState.url, (newValue, oldValue) => {
|
||||
isShowImagePreview.value = true;
|
||||
globalImagePreviewUrl.value = newValue;
|
||||
});
|
||||
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
<template>
|
||||
<ImagePreview style="width:100%;height:" v-if="isShowImagePreview" :globalImagePreviewUrl="globalImagePreviewUrl" @closeImagePreview="closeImagePreview"></ImagePreview>
|
||||
<template v-if="haveTab">
|
||||
<a-tabs v-model:activeKey="selectTab">
|
||||
<a-tab-pane v-for="(tab, tabIndex) in showList" :key="tabIndex" :tab="tab.label">
|
||||
|
|
@ -13,14 +14,13 @@
|
|||
<template v-for="(item, index) in tab.children" :key="index">
|
||||
<template v-if="item.infoShowValue">
|
||||
<a-descriptions-item v-if="item.component === 'ImageUpload'" :label="item.label">
|
||||
<template v-for="(imageItem, imageIndex) in item.infoShowValue" :key="imageIndex">
|
||||
<a-image
|
||||
v-if="imageItem"
|
||||
width="100px"
|
||||
height="100px"
|
||||
:src="`${item.componentProps.server}/${imageItem}`"
|
||||
></a-image>
|
||||
</template>
|
||||
<a-image
|
||||
width="100px"
|
||||
height="100px"
|
||||
:preview="false"
|
||||
:src="`${item.componentProps.server}/${item.infoShowValue}`"
|
||||
@click="handlerPreviewImage(item.componentProps.server+'/'+item.infoShowValue)"
|
||||
></a-image>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item v-else-if="item.component === 'VideoUpload'" :label="item.label">
|
||||
<template v-for="(videoItem, videoIndex) in item.infoShowValue" :key="videoIndex">
|
||||
|
|
@ -36,6 +36,7 @@
|
|||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<a-descriptions
|
||||
:column="2"
|
||||
|
|
@ -77,6 +78,11 @@
|
|||
import { defineProps, watch, ref, defineEmits, onMounted } from "vue"
|
||||
import ShowCardGroupItem from './ShowCardGroupItem/index.vue'
|
||||
import { Modal } from 'ant-design-vue'
|
||||
|
||||
import { storeToRefs } from 'pinia';
|
||||
import ImagePreview from "@/components/Upload/src/components/image_preview.vue";
|
||||
import { userFormFileStore } from '@/store/modules/formFileUrl';
|
||||
|
||||
const props = defineProps(["open","data"])
|
||||
const emits = defineEmits(["update:open"])
|
||||
const showList = ref<any[]>([])
|
||||
|
|
@ -251,6 +257,43 @@ const handleCancel = () => {
|
|||
previewOpen.value = false;
|
||||
previewTitle.value = '';
|
||||
};
|
||||
|
||||
//
|
||||
function handlerPreviewImage(url):void{
|
||||
globalImagePreviewUrl.value = url+"?"+Math.random();
|
||||
formFileStore.setUrl(url+"?"+Math.random());
|
||||
}
|
||||
|
||||
|
||||
// 图片预览
|
||||
const isShowImagePreview = ref<Boolean>(false);
|
||||
const closeImagePreview = ()=>{
|
||||
isShowImagePreview.value = false;
|
||||
}
|
||||
const globalImagePreviewUrl=ref<String>();
|
||||
const formFileStore = userFormFileStore();
|
||||
const formFileState = storeToRefs(formFileStore);
|
||||
watch(formFileState.url, (newValue, oldValue) => {
|
||||
isShowImagePreview.value = true;
|
||||
globalImagePreviewUrl.value = newValue;
|
||||
});
|
||||
|
||||
|
||||
// 图片转Base64
|
||||
function handlerConvertImageToBase64(url, callback) {
|
||||
var img = new Image();
|
||||
img.crossOrigin = 'Anonymous'; // 处理跨域问题
|
||||
img.onload = function () {
|
||||
var canvas = document.createElement('canvas');
|
||||
canvas.width = img.width;
|
||||
canvas.height = img.height;
|
||||
var ctx = canvas.getContext('2d');
|
||||
ctx.drawImage(img, 0, 0);
|
||||
var dataURL = canvas.toDataURL('image/jpeg'); // 或者使用 'image/jpeg' 来获得 JPEG 格式的 base64 字符串
|
||||
callback(dataURL);
|
||||
};
|
||||
img.src = url;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@
|
|||
</div>
|
||||
|
||||
<CallModal @success="submitsuccess" @register="registerModal" />
|
||||
|
||||
<a-modal
|
||||
width="80%"
|
||||
v-model:open="infoCallModalOpen"
|
||||
|
|
|
|||
|
|
@ -89,7 +89,6 @@
|
|||
</template>
|
||||
</a-table>
|
||||
</a-card>
|
||||
|
||||
<a-card title="图层设置" class="card-item" >
|
||||
<template #extra ><PlusOutlined @click="hanelerAddLayer"/></template>
|
||||
<a-table :dataSource="mapConfig.layers" :columns="columns" :pagination="false" >
|
||||
|
|
|
|||
|
|
@ -7,6 +7,15 @@
|
|||
<a-button type="primary" @click="closePage" class="ml-2" danger>关闭 </a-button>
|
||||
</div>
|
||||
|
||||
<div class="maper-container" v-if="mapConfig?.isShowMap">
|
||||
<MapboxMap
|
||||
:mapConfig="mapConfig"
|
||||
@handlerDrawComplete="handlerDrawComplete"
|
||||
@mapOnLoad="onMapboxLoad"
|
||||
ref="MapboxComponent"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div :class="mapConfig?.isShowMap ? 'form-container' : ''">
|
||||
<a-layout>
|
||||
<a-layout>
|
||||
|
|
@ -22,6 +31,8 @@
|
|||
v-if="formVisble"
|
||||
>
|
||||
<div>
|
||||
<ImagePreview style="width:100%;height:" v-if="isShowImagePreview" :globalImagePreviewUrl="globalImagePreviewUrl" @closeImagePreview="closeImagePreview"></ImagePreview>
|
||||
|
||||
<FormViewer
|
||||
ref="formBoxRef"
|
||||
:formConfig="formConfig"
|
||||
|
|
@ -85,7 +96,7 @@
|
|||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</a-layout-content>
|
||||
<a-layout-footer :style="footerStyle">
|
||||
<div :style="footerStyle">
|
||||
<a-tabs v-if="props.isRead == 0" v-model:activeKey="auditName">
|
||||
<a-tab-pane key="audit" :tab="auditTitleVal">
|
||||
<div class="approval-column">
|
||||
|
|
@ -121,20 +132,10 @@
|
|||
</div>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</a-layout-footer>
|
||||
</div>
|
||||
</a-layout>
|
||||
</a-layout>
|
||||
</div>
|
||||
|
||||
<div class="maper-container" v-if="mapConfig?.isShowMap">
|
||||
<MapboxMap
|
||||
:mapConfig="mapConfig"
|
||||
@handlerDrawComplete="handlerDrawComplete"
|
||||
@mapOnLoad="onMapboxLoad"
|
||||
ref="MapboxComponent"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 节点记录信息 -->
|
||||
<div class="info-box" v-if="designerData.nodeLogs.length > 0">
|
||||
<a-drawer v-model:open="infoOpen" class="custom-class" title="记录信息" placement="right">
|
||||
|
|
@ -199,6 +200,10 @@
|
|||
import { flowStore } from '@/store/modules/flow';
|
||||
import { functionsaveForm, LoadFormScheme } from '@/api/demo/formScheme';
|
||||
import { FormViewer } from '@/components/FormViewer';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import ImagePreview from "@/components/Upload/src/components/image_preview.vue";
|
||||
import { userFormFileStore } from '@/store/modules/formFileUrl';
|
||||
|
||||
import {
|
||||
designerDataType,
|
||||
logsType,
|
||||
|
|
@ -314,11 +319,11 @@
|
|||
overFlow: 'auto',
|
||||
color: '#fff',
|
||||
backgroundColor: '#ffffff',
|
||||
zIndex: '9999999999',
|
||||
zIndex: '123',
|
||||
padding: '0px 100px',
|
||||
position: 'fixed',
|
||||
bottom: '0px',
|
||||
left: '0px',
|
||||
right: '0px',
|
||||
});
|
||||
|
||||
function changeActive(activeKey) {
|
||||
|
|
@ -873,6 +878,19 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 图片预览
|
||||
const isShowImagePreview = ref<Boolean>(false);
|
||||
const closeImagePreview = ()=>{
|
||||
isShowImagePreview.value = false;
|
||||
}
|
||||
const globalImagePreviewUrl=ref<String>();
|
||||
const formFileStore = userFormFileStore();
|
||||
const formFileState = storeToRefs(formFileStore);
|
||||
watch(formFileState.url, (newValue, oldValue) => {
|
||||
isShowImagePreview.value = true;
|
||||
globalImagePreviewUrl.value = newValue;
|
||||
});
|
||||
onBeforeMount(() => {
|
||||
getTaskInfo();
|
||||
});
|
||||
|
|
@ -981,4 +999,6 @@
|
|||
.l-from-body {
|
||||
padding: 10px 30px;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -9,101 +9,107 @@
|
|||
>关闭
|
||||
</a-button>
|
||||
</div> -->
|
||||
<a-layout>
|
||||
<div class="maper-container" v-if="mapConfig?.isShowMap">
|
||||
<MapboxMap
|
||||
:mapConfig="mapConfig"
|
||||
@handlerDrawComplete="handlerDrawComplete"
|
||||
@mapOnLoad="onMapboxLoad"
|
||||
ref="MapboxComponent"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div :class="mapConfig?.isShowMap ? 'form-container' : ''">
|
||||
<a-layout>
|
||||
<a-layout-content>
|
||||
<a-tabs v-model:activeKey="activeName" @change="changeActive" type="card" >
|
||||
<a-tab-pane
|
||||
key="form"
|
||||
:tab="
|
||||
designerData.formCurrentNode.formTitle
|
||||
? designerData.formCurrentNode.formTitle
|
||||
: '表单信息'
|
||||
"
|
||||
v-if="formVisble"
|
||||
>
|
||||
<div :class="mapConfig?.isShowMap ? 'form-container' : ''">
|
||||
<FormViewer
|
||||
ref="formBoxRef"
|
||||
:formConfig="formConfig"
|
||||
:processId="designerData.process.id"
|
||||
:formVerison="designerData.formCurrentNode.formVerison"
|
||||
:formRelationId="designerData.formCurrentNode.formRelationId"
|
||||
:instanceInfo="designerData.process.instanceInfo"
|
||||
:issueId="designerData.formCurrentNode.issueId"
|
||||
:isDetail="true"
|
||||
@getFormSuccess="getFormSuccess"
|
||||
v-if="formVisble"
|
||||
/>
|
||||
</div>
|
||||
<div class="maper-container" v-if="mapConfig?.isShowMap">
|
||||
<MapboxMap
|
||||
:mapConfig="mapConfig"
|
||||
@handlerDrawComplete="handlerDrawComplete"
|
||||
@mapOnLoad="onMapboxLoad"
|
||||
ref="MapboxComponent"
|
||||
/>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="flow" tab="流程信息" force-render>
|
||||
<div class="process-design" :style="'display: flex; height:' + designerData.height">
|
||||
<process-viewer
|
||||
v-if="processVisble"
|
||||
:key="`designer-${id}`"
|
||||
:events="['element.click']"
|
||||
@element-click="elementClick"
|
||||
:xml="flowContent"
|
||||
:flowViewer="flowViewer"
|
||||
/>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="record" tab="流转记录" force-render>
|
||||
<div :style="'padding:10px 0 40px 0;overflow:auto; height:' + designerData.height">
|
||||
<a-timeline>
|
||||
<a-timeline-item
|
||||
v-for="(item, index) in designerData.logs"
|
||||
:key="index"
|
||||
:color="item.type"
|
||||
>
|
||||
<div class="title">{{ item.time }}</div>
|
||||
<a-card hoverable size="small">
|
||||
<div class="type-title">{{ item.name }}</div>
|
||||
<div class="content">
|
||||
<span
|
||||
class="link"
|
||||
v-for="(userName, index2) in item.userNames"
|
||||
:key="index2"
|
||||
>{{ userName }}</span
|
||||
>
|
||||
{{ item.des }}
|
||||
</div>
|
||||
</a-card>
|
||||
</a-timeline-item>
|
||||
</a-timeline>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</a-layout-content>
|
||||
<a-layout-footer v-if="designerData.userLogs.length > 0">
|
||||
<a-tabs v-model:activeKey="auditName">
|
||||
<a-tab-pane key="audit" tab="审批信息">
|
||||
<div class="approval-info">
|
||||
<auditInfo :data="designerData.userLogs" />
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</a-layout-footer>
|
||||
<!-- <a-layout-sider :style="footerStyle" v-if="designerData.userLogs.length > 0">
|
||||
<a-tabs v-model:activeKey="auditName">
|
||||
<a-tab-pane key="audit" tab="审批信息">
|
||||
<div class="approval-info">
|
||||
<auditInfo :data="designerData.userLogs" />
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</a-layout-sider> -->
|
||||
<a-layout>
|
||||
<a-layout-content>
|
||||
<a-tabs v-model:activeKey="activeName" @change="changeActive" type="card" >
|
||||
<a-tab-pane
|
||||
key="form"
|
||||
:tab="
|
||||
designerData.formCurrentNode.formTitle
|
||||
? designerData.formCurrentNode.formTitle
|
||||
: '表单信息'
|
||||
"
|
||||
v-if="formVisble"
|
||||
>
|
||||
<div>
|
||||
<ImagePreview v-if="isShowImagePreview" :globalImagePreviewUrl="globalImagePreviewUrl" @closeImagePreview="closeImagePreview"></ImagePreview>
|
||||
<FormViewer
|
||||
ref="formBoxRef"
|
||||
:formConfig="formConfig"
|
||||
:processId="designerData.process.id"
|
||||
:formVerison="designerData.formCurrentNode.formVerison"
|
||||
:formRelationId="designerData.formCurrentNode.formRelationId"
|
||||
:instanceInfo="designerData.process.instanceInfo"
|
||||
:issueId="designerData.formCurrentNode.issueId"
|
||||
:isDetail="true"
|
||||
@getFormSuccess="getFormSuccess"
|
||||
v-if="formVisble"
|
||||
/>
|
||||
</div>
|
||||
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="flow" tab="流程信息" force-render>
|
||||
<div class="process-design" :style="'display: flex; height:' + designerData.height">
|
||||
<process-viewer
|
||||
v-if="processVisble"
|
||||
:key="`designer-${id}`"
|
||||
:events="['element.click']"
|
||||
@element-click="elementClick"
|
||||
:xml="flowContent"
|
||||
:flowViewer="flowViewer"
|
||||
/>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="record" tab="流转记录" force-render>
|
||||
<div :style="'padding:10px 0 40px 0;overflow:auto; height:' + designerData.height">
|
||||
<a-timeline>
|
||||
<a-timeline-item
|
||||
v-for="(item, index) in designerData.logs"
|
||||
:key="index"
|
||||
:color="item.type"
|
||||
>
|
||||
<div class="title">{{ item.time }}</div>
|
||||
<a-card hoverable size="small">
|
||||
<div class="type-title">{{ item.name }}</div>
|
||||
<div class="content">
|
||||
<span
|
||||
class="link"
|
||||
v-for="(userName, index2) in item.userNames"
|
||||
:key="index2"
|
||||
>{{ userName }}</span
|
||||
>
|
||||
{{ item.des }}
|
||||
</div>
|
||||
</a-card>
|
||||
</a-timeline-item>
|
||||
</a-timeline>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</a-layout-content>
|
||||
<div v-if="designerData.userLogs.length > 0" :style="footerStyle">
|
||||
<a-tabs v-model:activeKey="auditName">
|
||||
<a-tab-pane key="audit" tab="审批信息">
|
||||
<div class="approval-info">
|
||||
<auditInfo :data="designerData.userLogs" />
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</div>
|
||||
<!-- <a-layout-sider :style="footerStyle" v-if="designerData.userLogs.length > 0">
|
||||
<a-tabs v-model:activeKey="auditName">
|
||||
<a-tab-pane key="audit" tab="审批信息">
|
||||
<div class="approval-info">
|
||||
<auditInfo :data="designerData.userLogs" />
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</a-layout-sider> -->
|
||||
</a-layout>
|
||||
</a-layout>
|
||||
</a-layout>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 节点记录信息 -->
|
||||
<div class="info-box" v-if="designerData.nodeLogs.length > 0">
|
||||
|
|
@ -132,7 +138,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, onBeforeMount, defineAsyncComponent } from 'vue';
|
||||
import { ref, reactive, onBeforeMount, defineAsyncComponent,watch } from 'vue';
|
||||
import { FormViewer } from '@/components/FormViewer';
|
||||
import { ProcessViewer } from '@/components/ProcessViewer';
|
||||
import { PageWrapper } from '@/components/Page';
|
||||
|
|
@ -143,6 +149,9 @@
|
|||
import { auditInfo } from './page';
|
||||
import { getGeom } from '@/api/sys/layerManagement';
|
||||
import { useMessage } from '@/hooks/web/useMessage';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import ImagePreview from "@/components/Upload/src/components/image_preview.vue";
|
||||
import { userFormFileStore } from '@/store/modules/formFileUrl';
|
||||
|
||||
const { createMessage } = useMessage();
|
||||
const MapboxMap = defineAsyncComponent(() => import('@/components/MapboxMaps/MapComponent.vue'));
|
||||
|
|
@ -206,6 +215,19 @@
|
|||
});
|
||||
const activeName = ref('form');
|
||||
const auditName = ref('audit');
|
||||
const footerStyle = ref({
|
||||
height: '220px',
|
||||
width: '100%',
|
||||
overFlow: 'auto',
|
||||
color: '#fff',
|
||||
backgroundColor: '#ffffff',
|
||||
zIndex: '123',
|
||||
padding: '0px 0px',
|
||||
position: 'fixed',
|
||||
bottom: '0px',
|
||||
right: '0px',
|
||||
});
|
||||
|
||||
function changeActive(activeKey) {
|
||||
if (activeKey == 'flow') {
|
||||
processVisble.value = true;
|
||||
|
|
@ -248,10 +270,12 @@
|
|||
if (auditNode.isInherit) {
|
||||
currentNode = wfData.find((t) => t.type == 'bpmn:StartEvent');
|
||||
mapConfig.value = currentNode.mapConfig;
|
||||
footerStyle.value.width = mapConfig.value?.isShowMap ? '60%' : '100%';
|
||||
} else {
|
||||
currentNode = auditNode;
|
||||
var currentMapNode = wfData.find((t) => t.type == 'bpmn:StartEvent');
|
||||
mapConfig.value = currentMapNode.mapConfig;
|
||||
footerStyle.value.width = mapConfig.value?.isShowMap ? '60%' : '100%';
|
||||
}
|
||||
}
|
||||
if (currentNode.authFields.length > 0) {
|
||||
|
|
@ -488,6 +512,20 @@
|
|||
function onMapboxLoad() {
|
||||
|
||||
}
|
||||
|
||||
// 图片预览
|
||||
const isShowImagePreview = ref<Boolean>(false);
|
||||
const closeImagePreview = ()=>{
|
||||
isShowImagePreview.value = false;
|
||||
}
|
||||
const globalImagePreviewUrl=ref<String>();
|
||||
const formFileStore = userFormFileStore();
|
||||
const formFileState = storeToRefs(formFileStore);
|
||||
watch(formFileState.url, (newValue, oldValue) => {
|
||||
isShowImagePreview.value = true;
|
||||
globalImagePreviewUrl.value = newValue;
|
||||
});
|
||||
|
||||
onBeforeMount(() => {
|
||||
getDetailInfo();
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue