地图单个加载,数据填报bug修改

This commit is contained in:
扈兆增 2026-05-13 08:44:35 +08:00
parent 48262cc162
commit b69e2eb18e
21 changed files with 2831 additions and 2379 deletions

View File

@ -69,7 +69,8 @@ export function importFishZip(data: FormData) {
url: '/data/fishDraft/importZip',
method: 'post',
data,
headers: { 'Content-Type': 'multipart/form-data' }
headers: { 'Content-Type': 'multipart/form-data' },
timeout: 1000 * 60 * 5 // 5分钟
});
}
// 取消导入任务

View File

@ -56138,7 +56138,30 @@ const fetchPointData = _.debounce(async () => {
matrixIds_index: ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"],
tileMatrixSetID: "EPSG:3857_qgc_sx_gjjdx_arcgistiles_l13",
});
//
mapClass.addBaseDataLayer({
id: "hydropBase",
key: "hydropBase",
urlType: "gisurl",
url:
"https://211.99.26.225:18085/geoserver/gwc/service/tms/1.0.0/qgc%3AstationEra1117@EPSG%3A900913@pbf/{z}/{x}/{y}.pbf",
geojson_url:
"https://211.99.26.225:18085/geoserver/qgc/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=qgc:stationEra1117&maxFeatures=50&outputFormat=application/json&token=bearer a9a0f227-1df3-4e68-b380-2eca5bb49bd1",
url_3d: "https://211.99.26.225:18085/geoserver/qgc/wms",
_layer: "stationEra1117",
layers: "qgc:stationEra1117",
rasteropacity: 0.5,
visible: true,
minZoom: 0,
maxZoom: 20,
type: "vector",
layerType: "line",
paint: {
"line-color": "#C5C6F3",
"line-width": 1,
"line-opacity": 1,
},
});
//
// mapClass.addBaseDataLayer(
// {
@ -56352,34 +56375,12 @@ watch(
watch(
() => JidiSelectEventStore.selectedItem,
(newVal) => {
console.log(newVal);
if (newVal) {
// if (newVal.wbsCode == "all") {
// } else {
// mapClass.addBaseDataLayer({
// id: "hydropBase",
// key: "hydropBase",
// urlType: "gisurl",
// url:
// "https://211.99.26.225:18085/geoserver/gwc/service/tms/1.0.0/qgc%3AstationEra1117@EPSG%3A900913@pbf/{z}/{x}/{y}.pbf",
// geojson_url:
// "https://211.99.26.225:18085/geoserver/qgc/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=qgc:stationEra1117&maxFeatures=50&outputFormat=application/json&token=bearer a9a0f227-1df3-4e68-b380-2eca5bb49bd1",
// url_3d: "https://211.99.26.225:18085/geoserver/qgc/wms",
// _layer: "stationEra1117",
// layers: "qgc:stationEra1117",
// rasteropacity: 0.5,
// visible: true,
// minZoom: 0,
// maxZoom: 20,
// type: "vector",
// layerType: "line",
// paint: {
// "line-color": "#C5C6F3",
// "line-width": 1,
// "line-opacity": 1,
// },
// });
// }
if (newVal.wbsCode == "all") {
mapClass.jdPanelControlShowAndHidden(newVal.wbsCode, false);
} else {
mapClass.jdPanelControlShowAndHidden(newVal.wbsCode, true);
}
}
},
{ deep: true }
@ -56401,8 +56402,6 @@ onUnmounted(() => {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
visibility: visible;
}
#mapContainer {
@ -56410,6 +56409,7 @@ onUnmounted(() => {
height: 100%;
position: absolute;
background-color: #fff;
cursor: grab;
z-index: 1;
}
/* 消除瓦片之间的缝隙和默认边框 */

View File

@ -1,6 +1,6 @@
import type { layer, MapInterface } from "./map.d";
import type { layer, MapInterface } from './map.d';
// import { MapLeaflet } from "./map.leaflet";
import { MapOl } from "./map.ol";
import { MapOl } from './map.ol';
interface MapClassInterface extends MapInterface {
layers: Map<string, layer>;
@ -16,7 +16,8 @@ export type MDOptions = {
isRemove?: boolean; // 是否移除标签
};
export const mapServerBaseUrl = localStorage.getItem("gisurl") || "http://210.72.227.199:18084/";
export const mapServerBaseUrl =
localStorage.getItem('gisurl') || 'http://210.72.227.199:18084/';
export class MapClass implements MapClassInterface {
layers: Map<string, layer>;
@ -38,14 +39,14 @@ export class MapClass implements MapClassInterface {
}
// 地图初始化
init(container: HTMLElement, rectangle?: any): Promise<any> {
return this.service.init(container, rectangle).then((map) => {
return this.service.init(container, rectangle).then(map => {
this.view = map;
return map;
});
}
// 基地面板控制
jdPanelControlShowAndHidden(baseid: String, isAll: boolean): void {
this.service.jdPanelControlShowAndHidden(baseid, isAll)
this.service.jdPanelControlShowAndHidden(baseid, isAll);
}
mdLayerShowOrHidden(): void {
// layerType: String, key?: String, baseid: String, checked: boolean, isAll: boolean
@ -53,62 +54,71 @@ export class MapClass implements MapClassInterface {
}
// 添加基础数据图层
addBaseDataLayer(layer: any): void {
return this.service.addBaseDataLayer(layer)
return this.service.addBaseDataLayer(layer);
}
// 基础图层显示影隐藏方法
controlBaseLayerTreeShowAndHidden(layerType: String, key: String, checked: boolean) {
this.service.controlBaseLayerTreeShowAndHidden(layerType, key, checked)
controlBaseLayerTreeShowAndHidden(
layerType: String,
key: String,
checked: boolean
) {
this.service.controlBaseLayerTreeShowAndHidden(layerType, key, checked);
}
// 图层树控制描点数据显示隐藏方法
mdLayerTreeShowOrHidden(layerType: String, checked?: boolean) {
this.service.mdLayerTreeShowOrHidden(layerType, checked)
this.service.mdLayerTreeShowOrHidden(layerType, checked);
}
// 初始化加载描点数据
addInitDataLayer = (pointData: any[], layerType: any, mdoptions?: any) => {
return this.service.addInitDataLayer(pointData, layerType, mdoptions)
}
return this.service.addInitDataLayer(pointData, layerType, mdoptions);
};
//切换底图
baseLayerSwitcher(key: string): void {
this.service.baseLayerSwitcher(key)
this.service.baseLayerSwitcher(key);
}
// 添加梯级流域图
addTertiarybasinLayer(layer: layer, fillcolor: any, outlineColor: any, datas: any): void {
this.service.addTertiarybasinLayer(layer, fillcolor, outlineColor, datas)
addTertiarybasinLayer(
layer: layer,
fillcolor: any,
outlineColor: any,
datas: any
): void {
this.service.addTertiarybasinLayer(layer, fillcolor, outlineColor, datas);
}
// 移除梯级流域图
removeTertiarybasinLayer(layer: layer): void {
this.service.removeTertiarybasinLayer?.(layer)
this.service.removeTertiarybasinLayer?.(layer);
}
// 缩放
zoomToggle(type: 'out' | 'in') {
this.service.zoomToggle(type)
this.service.zoomToggle(type);
}
/**
*
*/
lengthCalculate(): void {
this.service.lengthCalculate()
this.service.lengthCalculate();
}
/**
*
*/
areCalculate(): void {
this.service.areCalculate()
this.service.areCalculate();
}
/**
*
*/
removeQueryLayer(): void {
this.service.removeQueryLayer()
this.service.removeQueryLayer();
}
// 地图打印
mapOutPut() {
this.service.mapOutPut()
this.service.mapOutPut();
}
// 销毁地图
destroy(): void {
this.service.destroy()
this.service.destroy();
}
// 切换地图视图
@ -122,8 +132,7 @@ export class MapClass implements MapClassInterface {
}
// 飞行到指定的点
flyTopanto(): void {
// this.service.flyTopanto(point)
flyTopanto(position: number[], zoom: number): void {
this.service.flyTopanto(position, zoom);
}
}

View File

@ -1,15 +1,14 @@
import { MDOptions } from './map.class'
import { MDOptions } from './map.class';
export type layerType =
| "markers"
| "tiledMap"
| "tiledMapQuery"
| "geoJson"
| "arcgisFeature"
| "dynamicMapLayer"
| "arcgisMap"
| "label"
| "vector";
| 'markers'
| 'tiledMap'
| 'tiledMapQuery'
| 'geoJson'
| 'arcgisFeature'
| 'dynamicMapLayer'
| 'arcgisMap'
| 'label'
| 'vector';
export type layerOption = {
opacity?: number;
data?: Array<any>;
@ -18,34 +17,34 @@ export type layerOption = {
hoverEvent?: Function;
legendImages?: Array<any> | null | undefined;
geoJsonLegend?: Array<any> | null | undefined;
tiledMapType?: undefined | "superMap";
tiledMapType?: undefined | 'superMap';
};
export interface layer {
id: string
key: string
_layer?: any
type?: layerType
url?: string
url_3d?: string
geojson_url: string
label?: string
thumbnail?: string
visible?: boolean
option?: layerOption
tempobj?: any
layers?: any
rasteropacity?: any
imgUrl?: any
minZoom?: any
maxZoom?: any
minHeight?: number
maxHeight?: number
id: string;
key: string;
_layer?: any;
type?: layerType;
url?: string;
url_3d?: string;
geojson_url: string;
label?: string;
thumbnail?: string;
visible?: boolean;
option?: layerOption;
tempobj?: any;
layers?: any;
rasteropacity?: any;
imgUrl?: any;
minZoom?: any;
maxZoom?: any;
minHeight?: number;
maxHeight?: number;
/** layer 类型 */
layerType?: string
matrixIds_index?: string[]
tileMatrixSetID?: string
urlType: string
layerType?: string;
matrixIds_index?: string[];
tileMatrixSetID?: string;
urlType: string;
}
export interface MapInterface {
@ -54,48 +53,59 @@ export interface MapInterface {
* @param container DOM容器
* @return any
*/
init(container: HTMLElement, rectangle?: any, center?: any, altitude?: number, bearing?: number): Promise<any>
init(
container: HTMLElement,
rectangle?: any,
center?: any,
altitude?: number,
bearing?: number
): Promise<any>;
/**
*
* @param pointData
* @param layerType
*/
addInitDataLayer(pointData: any[], layerType: any, mdoptions: MDOptions): void
addInitDataLayer(
pointData: any[],
layerType: any,
mdoptions: MDOptions
): void;
/**
*
* @param layer
*/
addBaseDataLayer(layer: any): void
addBaseDataLayer(layer: any): void;
/**
*
* @param layer
*/
baseLayerSwitcher(key: string): void
baseLayerSwitcher(key: string): void;
/**
* 2D或者3D视图
* @param type '2D' | '3D'
*/
switchView(type: '2D' | '3D'): any | null
switchView(type: '2D' | '3D'): any | null;
/**
*
* out
* in
*/
zoomToggle(type: 'out' | 'in'): void
zoomToggle(type: 'out' | 'in'): void;
/**
*
*/
mapOutPut(): void
mapOutPut(): void;
//飞行到指定的点
fitBounds(bbox,bearing):void
flyTopanto(positon,zoom,stcd):void
fitBounds(bbox, bearing): void;
flyTopanto(positon, zoom): void;
// /**
// * 加载倾斜摄影数据
// * @param HH3DUrlArray
@ -131,7 +141,7 @@ export interface MapInterface {
* @param baseid
* @param isAll
*/
jdPanelControlShowAndHidden(baseid: String, isAll: boolean): void
jdPanelControlShowAndHidden(baseid: String, isAll: boolean): void;
/**
*
* @param layerType
@ -139,49 +149,58 @@ export interface MapInterface {
* @param checked
* @param isAll
*/
mdLayerShowOrHidden(): void
mdLayerShowOrHidden(): void;
// layerType: String, key?: String, baseid: String, checked: boolean, isAll: boolean
/**
*
* @param layerType
* @param checked
*/
controlBaseLayerTreeShowAndHidden(layerType: String, key: String, checked: boolean): void
controlBaseLayerTreeShowAndHidden(
layerType: String,
key: String,
checked: boolean
): void;
/**
*
* @param layerType
* @param checked
*/
mdLayerTreeShowOrHidden(layerType: String, checked?: boolean): void
mdLayerTreeShowOrHidden(layerType: String, checked?: boolean): void;
/**
*
*/
lengthCalculate(): void
lengthCalculate(): void;
/**
*
*/
areCalculate(): void
areCalculate(): void;
/**
*
*/
removeQueryLayer(): void
removeQueryLayer(): void;
/**
*
* @param layer
* @param fillcolor
*/
addTertiarybasinLayer(layer: layer, fillcolor: any, outlineColor: any, datas: any): void
addTertiarybasinLayer(
layer: layer,
fillcolor: any,
outlineColor: any,
datas: any
): void;
/**
*
* @param layer
*/
removeTertiarybasinLayer(layer: layer): void
removeTertiarybasinLayer(layer: layer): void;
/**
*
*/
destroy(): void
destroy(): void;
}

View File

@ -55,8 +55,10 @@ export class MapOl implements MapInterface {
// ✅ 新增:存储 key -> layer 实例,用于控制显示隐藏和切换
private layerRegistry: Map<string, any> = new Map();
// ✅ 新增:记录当前正在显示的“切换 Key”用于判断是否需要重新加载或只是切换显隐
// 基础图层配置
private baseLayerConfig: TileLayer | null = null;
// private hydropBaseConfig: TileLayer | null = null;
// 基地配置
private hydropBaseConfig: any | null = null;
private REGISTRY_KEY = 'customBaseLayer';
// ✅ 新增:量算相关属性
@ -70,9 +72,9 @@ export class MapOl implements MapInterface {
// ✅ 新增:声明用于存储 mask 事件监听器的引用,以便后续移除
private _maskPrerender: any = null;
private _maskPostrender: any = null;
// private BASEID: string = '01';
private BASEID: string = '';
constructor() {
this.loadGeoJsonData();
// this.loadGeoJsonData();
this.loadGeoJsonData1();
}
private async loadGeoJsonData(): Promise<void> {
@ -83,6 +85,15 @@ export class MapOl implements MapInterface {
console.error('配置加载失败:', error);
}
}
private async loadGeoJsonData2(url): Promise<any> {
try {
const response = await fetch(url);
const data = await response.json();
return data;
} catch (error) {
console.error('配置加载失败:', error);
}
}
private async loadGeoJsonData1(): Promise<void> {
try {
const response = await fetch('/data/geoJson1.json');
@ -402,8 +413,6 @@ export class MapOl implements MapInterface {
matrixIds[z] = `${matrixSetName}:${z}`;
}
console.log('Using Matrix IDs sample:', matrixIds[0], matrixIds[1]);
// 4. 创建 WMTS 图层
const wmtsLayer = new TileLayer({
source: new WMTS({
@ -428,6 +437,7 @@ export class MapOl implements MapInterface {
} else {
wmtsLayer.setZIndex(-99);
}
console.log('基础图层', wmtsLayer);
// 5. 注册与添加
this.layerRegistry.set(layer.key, wmtsLayer);
this.map.addLayer(wmtsLayer);
@ -445,141 +455,11 @@ export class MapOl implements MapInterface {
this.map.addLayer(tileLayer);
} else if (layer.type === 'vector') {
if (layer.key === 'hydropBase') {
// this.hydropBaseConfig = layer;
this.hydropBaseConfig = layer;
}
// ✅ 1. 创建矢量源,关键是要配置投影转换
const vectorSource = new VectorSource({
features: new GeoJSON().readFeatures(this.geoJsonData1, {
dataProjection: 'EPSG:4326',
featureProjection: 'EPSG:3857' // 确保转换到地图使用的投影
})
// url: layer.geojson_url +`&BASEID=BASEID'${this.BASEID}'` , // 远程 GeoJSON 地址
// format: new GeoJSON({
// featureProjection: 'EPSG:3857'
// })
});
// ✅ 2. 创建矢量图层,添加默认样式防止透明
const vectorLayer = new VectorLayer({
source: vectorSource,
style: new Style({
stroke: new Stroke({
color: '#3399CC', // 默认蓝色边框
width: 2
}),
fill: new Fill({
color: 'rgba(51, 153, 204, 0.4)' // 默认半透明填充
})
}),
// ✅ 3. 调整 zIndex确保在底图之上可见
zIndex: 101,
visible: true
});
// 监听数据加载完成事件
vectorSource.on('featuresloadend', () => {
// 获取所有加载的要素
const features = vectorSource.getFeatures();
const feature = features[0];
const geometry = feature.getGeometry();
console.log(geometry);
// this.addClipToRasterLayer(this.layerRegistry.get(this.REGISTRY_KEY), geometry);
// this.applyMapMask(geometry);
});
// 4. 注册与添加
this.layerRegistry.set(layer.key, vectorLayer);
// this.map.addLayer(vectorLayer);
layer._layer = vectorLayer;
const targetBaseLayer = this.layerRegistry.get(this.REGISTRY_KEY);
this.applyMapMask(targetBaseLayer as TileLayer, this.geoJsonData1);
console.log(`矢量图层 [${layer.key}] 已加载: ${layer.url}`);
}
}
/**
*
* @param layer TileLayer
* @param clipGeometry Polygon MultiPolygonEPSG:3857
*/
// private addClipToRasterLayer(layer: TileLayer<any>, clipGeometry: Geometry): void {
// if (!layer || !clipGeometry) return;
// // 处理几何类型,统一为多边形数组
// let polygons: Polygon[] = [];
// const type = clipGeometry.getType();
// if (type === 'Polygon') {
// polygons = [clipGeometry as Polygon];
// } else if (type === 'MultiPolygon') {
// const multiPolygon = clipGeometry as MultiPolygon;
// const coords = multiPolygon.getCoordinates();
// polygons = coords.map(coord => new Polygon(coord));
// } else {
// console.error('不支持的几何类型:', type);
// return;
// }
// // 预存储所有外环坐标
// const allRings: number[][][] = [];
// for (const polygon of polygons) {
// const coords = polygon.getCoordinates();
// if (coords && coords[0] && coords[0].length > 0) {
// allRings.push(coords[0]);
// }
// }
// // 移除旧事件
// layer.removeEventListener('prerender');
// layer.removeEventListener('postrender');
// // 渲染前:设置裁切区域
// layer.on('prerender', (event) => {
// const context = event.context;
// const frameState = event.frameState;
// if (!context || !frameState) return;
// // 获取坐标转像素函数
// const toPixel = frameState.coordinateToPixel;
// if (!toPixel) return;
// context.save();
// context.beginPath();
// let hasPath = false;
// for (const ring of allRings) {
// if (!ring || ring.length === 0) continue;
// for (let i = 0; i < ring.length; i++) {
// const coord = ring[i];
// const pixel = toPixel(coord);
// if (!pixel || pixel.length < 2) continue;
// if (i === 0) {
// context.moveTo(pixel[0], pixel[1]);
// } else {
// context.lineTo(pixel[0], pixel[1]);
// }
// hasPath = true;
// }
// context.closePath();
// }
// if (hasPath) {
// context.clip();
// } else {
// context.restore();
// }
// });
// // 渲染后:恢复状态
// layer.on('postrender', (event) => {
// if (event.context) {
// event.context.restore();
// }
// });
// }
// 在 addBaseDataLayer 方法的 vector 分支末尾,或者专门提供一个方法来激活遮罩
enableNortheastMask(): void {
// 1. 获取全量底图图层
@ -603,12 +483,52 @@ export class MapOl implements MapInterface {
* @param regionId ID ( "hebei", "13", "01" Key )
* @param isAll (true: ; false: regionId )
*/
jdPanelControlShowAndHidden(_regionId: string): void {
// this.BASEID = regionId;
// console.log(this.layerRegistry);
// console.log(this.layerRegistry.keys());
// this.addBaseDataLayer(this.hydropBaseConfig);
// this.controlBaseLayerTreeShowAndHidden(this.REGISTRY_KEY,this.REGISTRY_KEY,false)
async jdPanelControlShowAndHidden(
_regionId: string,
isAll: boolean
): Promise<void> {
if (!this.map || !this.hydropBaseConfig) {
console.warn('地图未初始化或 hydropBaseConfig 未配置');
return;
}
// 1. 更新当前选中的区域 ID
this.BASEID = _regionId;
console.log(`切换区域至: ${this.BASEID}`);
if (!isAll) {
// ✅ 情况 A: isAll == false -> 清空裁切
this.clearMapMask();
return;
}
// 2. 获取底图图层 (用于应用遮罩的目标)
const baseLayer = this.layerRegistry.get(this.REGISTRY_KEY) as TileLayer;
if (!baseLayer) {
console.warn('未找到底图图层,无法应用遮罩');
return;
}
try {
const url =
this.hydropBaseConfig.geojson_url +
`&cql_filter=BASEID='${this.BASEID}'`;
console.log('正在请求裁切数据:', url);
// 等待数据加载
const geoJsonData = await this.loadGeoJsonData2(url);
console.log('获取到的原始 GeoJSON:', geoJsonData);
// ✅ 新增:在应用遮罩前,先让地图视角聚焦到该区域
this.fitViewToGeoJson(geoJsonData);
console.log('基础图层', baseLayer);
// 应用遮罩
this.applyMapMask(baseLayer, geoJsonData);
} catch (error) {
console.error('加载裁切数据失败:', error);
// 出错时也清空遮罩,保证用户体验
this.clearMapMask();
}
}
/**
*
@ -1224,38 +1144,18 @@ export class MapOl implements MapInterface {
private applyMapMask(rasterLayer: TileLayer, clipGeoJson: any): void {
if (!rasterLayer || !clipGeoJson) return;
// 1. 解析 GeoJSON
// 1. 解析 GeoJSON 为 OL Features (EPSG:3857)
const features = new GeoJSON().readFeatures(clipGeoJson, {
dataProjection: 'EPSG:4326',
featureProjection: 'EPSG:3857'
});
// if (!features || features.length === 0) {
// console.warn('裁切数据为空');
// return;
// }
if (!features || features.length === 0) {
console.warn('裁切数据为空,无法应用遮罩');
return;
}
// // ✅ 调试:添加绿线图层
// const debugVectorSource = new VectorSource({ features: features });
// let debugLayer = this.map!.getLayers()
// .getArray()
// .find((l: any) => l.get('isDebugMask'));
// if (debugLayer) {
// this.map!.removeLayer(debugLayer);
// }
// debugLayer = new VectorLayer({
// source: debugVectorSource,
// style: new Style({
// stroke: new Stroke({ color: '#00FF00', width: 2 }),
// fill: new Fill({ color: 'rgba(0, 255, 0, 0.1)' })
// }),
// zIndex: 9999,
// visible: true
// });
// debugLayer.set('isDebugMask', true);
// this.map!.addLayer(debugLayer);
// 移除旧监听器
// 2. 移除旧的监听器,防止重复绑定
if (this._maskPrerender) {
rasterLayer.un('prerender', this._maskPrerender);
}
@ -1263,108 +1163,209 @@ export class MapOl implements MapInterface {
rasterLayer.un('postrender', this._maskPostrender);
}
// 3. 定义 prerender 事件处理函数
// OpenLayers 在 prerender 时context 已经包含了当前帧的状态
const maskPrerender = (event: any) => {
const context = event.context;
if (!context || !this.map) return;
const frameState = event.frameState;
if (!frameState) return;
if (!context || !frameState || !this.map) return;
// ✅ 关键步骤 1: 保存当前 Canvas 状态
context.save();
// ✅ 关键步骤 2: 重置变换矩阵,确保我们操作的是屏幕像素坐标
// OpenLayers 默认可能应用了平移/缩放,我们需要手动控制
context.setTransform(1, 0, 0, 1, 0, 0);
context.beginPath();
let hasPath = false;
let hasValidPath = false;
// 遍历所有特征,绘制路径
for (const feature of features) {
const geom: any = feature.getGeometry();
const geom = feature.getGeometry();
if (!geom) continue;
const type = geom.getType();
// 处理 Polygon
if (type === 'Polygon') {
const rings = geom.getCoordinates() as number[][][];
const rings = (geom as any).getCoordinates() as number[][][];
for (const ring of rings) {
// ✅ 传递 frameState 给 drawRing
this.drawRing(context, ring, frameState);
hasPath = true;
if (this.drawRingToContext(context, ring, frameState)) {
hasValidPath = true;
}
} else if (type === 'MultiPolygon') {
const polygons = geom.getCoordinates() as number[][][][];
}
}
// 处理 MultiPolygon
else if (type === 'MultiPolygon') {
const polygons = (geom as any).getCoordinates() as number[][][][];
for (const polygonRings of polygons) {
for (const ring of polygonRings) {
// ✅ 传递 frameState 给 drawRing
this.drawRing(context, ring, frameState);
hasPath = true;
if (this.drawRingToContext(context, ring, frameState)) {
hasValidPath = true;
}
}
}
}
if (hasPath) {
context.strokeStyle = 'red';
context.lineWidth = 2;
}
// ✅ 关键步骤 3: 如果绘制了有效路径,则执行裁剪
if (hasValidPath) {
// 闭合路径(虽然 drawRing 里做了 closePath但为了保险
context.save();
// 先用外描边创建裁剪区域
context.lineWidth = 6;
context.strokeStyle = '#6D64DF';
context.stroke();
context.fillStyle = 'rgba(255, 255, 0, 0.2)';
context.fill();
// context.clip();
context.clip(); // 裁剪到外描边的内部区域
context.strokeStyle = '#CCC9F4';
context.lineWidth = 5;
context.stroke();
// 执行裁剪!此后所有绘制操作仅在此路径内可见
context.clip();
// 可选:如果你希望裁剪区域外有半透明黑色遮罩,可以在这里绘制一个全屏矩形
// 但通常我们只希望“隐藏”外部,所以只需 clip 即可OL 会自动绘制瓦片
} else {
console.warn('未能生成有效的裁切路径');
}
context.restore();
};
// 4. 定义 postrender 事件处理函数
// 用于恢复 Canvas 状态,避免影响其他图层或后续帧
const maskPostrender = (event: any) => {
if (event.context) {
event.context.restore();
}
};
// 5. 绑定新的事件监听器
this._maskPrerender = maskPrerender;
this._maskPostrender = maskPostrender;
rasterLayer.on('prerender', this._maskPrerender);
rasterLayer.on('postrender', this._maskPostrender);
// 6. 强制触发重绘
rasterLayer.changed();
console.log('地图遮罩已应用');
}
private drawRing(
/**
* Ring Canvas
* @returns boolean
*/
private drawRingToContext(
context: CanvasRenderingContext2D,
ring: number[][],
frameState: any
) {
if (!ring || ring.length === 0) return;
): boolean {
if (!ring || ring.length < 3) return false; // 至少需要3个点构成面
// ✅ 关键:获取当前 Canvas 的像素比(高清屏通常为 2
// frameState.pixelRatio 是 OL 内部使用的像素比
const pixelRatio = frameState.pixelRatio || window.devicePixelRatio || 1;
let moved = false;
for (let i = 0; i < ring.length; i++) {
const coord = ring[i];
if (!this.map || !Array.isArray(coord) || typeof coord[0] !== 'number')
continue;
// 坐标有效性检查
if (!coord || coord.length < 2 || typeof coord[0] !== 'number') continue;
// ✅ 1. 获取相对于地图容器的 CSS 像素坐标
const cssPixel = this.map.getPixelFromCoordinate(
// 获取 CSS 像素坐标
const cssPixel = this.map?.getPixelFromCoordinate(
coord as [number, number]
);
if (!cssPixel) continue;
// ✅ 2. 转换为 Canvas 内部物理像素坐标
// 因为我们在 maskPrerender 中执行了 context.setTransform(1, 0, 0, 1, 0, 0);
// 此时 Canvas 的原点是左上角,单位是物理像素。
// 而 getPixelFromCoordinate 返回的是 CSS 像素。
// 所以必须乘以 pixelRatio。
// 转换为物理像素坐标
const canvasX = cssPixel[0] * pixelRatio;
const canvasY = cssPixel[1] * pixelRatio;
if (i === 0) {
if (!moved) {
context.moveTo(canvasX, canvasY);
moved = true;
} else {
context.lineTo(canvasX, canvasY);
}
}
if (moved) {
context.closePath();
return true;
}
return false;
}
/**
* GeoJSON 使
* @param geoJson GeoJSON
*/
private fitViewToGeoJson(geoJson: any): void {
if (!this.map || !this.view) return;
try {
// 1. 将 GeoJSON 转换为 OpenLayers 的 Feature 数组
// 注意:这里假设输入的是 EPSG:4326需要转换到地图使用的 EPSG:3857
const features = new GeoJSON().readFeatures(geoJson, {
dataProjection: 'EPSG:4326',
featureProjection: 'EPSG:3857'
});
if (!features || features.length === 0) return;
// 2. 创建一个临时的矢量源来计算所有要素的包围盒
const source = new VectorSource({
features: features
});
// 3. 获取包围盒 [minX, minY, maxX, maxY]
const extent = source.getExtent();
// 检查包围盒是否有效
if (extent[0] === Infinity || extent[0] === -Infinity) {
console.warn('无法计算有效的地图包围盒');
return;
}
// 4. 调整视图
// padding: 设置四周留白,防止图形贴边
// duration: 动画持续时间
// maxZoom: 限制最大缩放级别,防止放大过度导致像素化
this.view.fit(extent, {
padding: [50, 50, 50, 50], // 上右下左留白
duration: 1000, // 1秒动画
maxZoom: 15 // 根据底图精度调整,避免过度放大
});
console.log('地图视野已调整至裁切区域');
} catch (e) {
console.error('调整地图视野失败:', e);
}
}
/**
*
*/
private clearMapMask(): void {
const baseLayer = this.layerRegistry.get(this.REGISTRY_KEY) as TileLayer;
if (!baseLayer) return;
console.log('正在清除地图遮罩...');
if (this._maskPrerender) {
baseLayer.un('prerender', this._maskPrerender);
this._maskPrerender = null;
}
if (this._maskPostrender) {
baseLayer.un('postrender', this._maskPostrender);
this._maskPostrender = null;
}
// 强制重绘以移除遮罩效果
baseLayer.changed();
}
/**
* ()
@ -1386,7 +1387,33 @@ export class MapOl implements MapInterface {
mdLayerShowOrHidden(): void {}
switchView(): void {}
fitBounds(): void {}
flyTopanto(): void {}
/**
*
* @param position [, ] (EPSG:4326)
* @param zoom
*/
flyTopanto(position: number[], zoom: number): void {
if (!this.map || !this.view) {
console.warn('地图未初始化,无法执行飞行定位');
return;
}
// 1. 将经纬度 [lon, lat] 转换为地图投影坐标 (EPSG:3857)
const targetCenter = fromLonLat(position);
// 2. 执行动画
// duration: 动画持续时间,单位毫秒,例如 1000ms (1秒)
this.view.animate(
{
center: targetCenter,
duration: 1000
},
{
zoom: zoom,
duration: 1000
}
);
}
/**
*
*/

View File

@ -16,7 +16,7 @@ const routeKey = computed(() => router.path + Math.random());
<template>
<section class="app-main">
<!-- <GisView /> -->
<GisView />
<div class="gi-panels">
<router-view v-slot="{ Component, route }" :key="routeKey">
<transition name="router-fade" mode="out-in">
@ -49,6 +49,6 @@ const routeKey = computed(() => router.path + Math.random());
position: absolute;
width: 100%;
height: 100%;
z-index: 900;
pointer-events: none;
}
</style>

View File

@ -9,9 +9,7 @@ const jidiDataNum = ref(9);
const itemClick = (index: any) => {
useJidiSelectEventStore().updataJidiData(index);
};
onMounted(() => {
JidiSelectEventStore.jidiData[0].selected = true;
});
onMounted(() => {});
</script>
<template>
@ -24,7 +22,10 @@ onMounted(() => {
>
<div class="title" @click="isOpen = !isOpen">
<div>水电基地</div>
<div style="padding-right: 5px;" :style="{ transform: !isOpen ? 'rotate(180deg)' : 'rotate(0deg)' }">
<div
style="padding-right: 5px"
:style="{ transform: !isOpen ? 'rotate(180deg)' : 'rotate(0deg)' }"
>
<i class="icon iconfont icon-topOutline"></i>
</div>
</div>

View File

@ -2,715 +2,83 @@ import { defineStore } from 'pinia';
import { ref } from 'vue';
export const useJidiSelectEventStore = defineStore('jidiSelectEvent', () => {
const jidiData:any = ref([
const jidiData: any = ref([
{
"_tls": {},
"id": null,
"recordUser": null,
"recordTime": null,
"modifyTime": null,
"displayRecordUser": null,
"isolateType": null,
"wbsType": null,
"wbsCode": "all",
"wbsName": "当前全部",
"wbsSname": null,
"wbsNameEn": null,
"wbsSnameEn": null,
"enable": null,
"description": null,
"parentId": null,
"parentCode": null,
"treeLevel": null,
"hasChildren": null,
"objId": null,
"topWbsType": null,
"fullPath": null,
"internal": null,
"lgtd": null,
"lttd": null,
"area": null,
"perimeter": null,
"synopsis": null,
"introduce": null,
"logo": null,
"inffile": null,
"orderIndex": null,
"filterContent": null,
"departmentId": null,
"systemId": null,
"platformId": null,
"reachWwqtg": null,
"maxElev": null,
"minElev": null,
"datTp": null,
"rvAg": null,
"ifInnRv": null,
"showControl": null,
"stcd": null,
"displayDepartment": null
wbsCode: 'all',
wbsName: '当前全部',
selected: true
},
{
"_tls": {},
"id": null,
"recordUser": null,
"recordTime": null,
"modifyTime": null,
"displayRecordUser": null,
"isolateType": null,
"wbsType": null,
"wbsCode": "01",
"wbsName": "金沙江干流",
"wbsSname": null,
"wbsNameEn": null,
"wbsSnameEn": null,
"enable": null,
"description": null,
"parentId": null,
"parentCode": null,
"treeLevel": null,
"hasChildren": null,
"objId": null,
"topWbsType": null,
"fullPath": null,
"internal": null,
"lgtd": null,
"lttd": null,
"area": null,
"perimeter": null,
"synopsis": null,
"introduce": null,
"logo": null,
"inffile": null,
"orderIndex": null,
"filterContent": null,
"departmentId": null,
"systemId": null,
"platformId": null,
"reachWwqtg": null,
"maxElev": null,
"minElev": null,
"datTp": null,
"rvAg": null,
"ifInnRv": null,
"showControl": null,
"stcd": null,
"displayDepartment": null
wbsCode: '01',
wbsName: '金沙江干流',
selected: false
},
{
"_tls": {},
"id": null,
"recordUser": null,
"recordTime": null,
"modifyTime": null,
"displayRecordUser": null,
"isolateType": null,
"wbsType": null,
"wbsCode": "02",
"wbsName": "雅砻江干流",
"wbsSname": null,
"wbsNameEn": null,
"wbsSnameEn": null,
"enable": null,
"description": null,
"parentId": null,
"parentCode": null,
"treeLevel": null,
"hasChildren": null,
"objId": null,
"topWbsType": null,
"fullPath": null,
"internal": null,
"lgtd": null,
"lttd": null,
"area": null,
"perimeter": null,
"synopsis": null,
"introduce": null,
"logo": null,
"inffile": null,
"orderIndex": null,
"filterContent": null,
"departmentId": null,
"systemId": null,
"platformId": null,
"reachWwqtg": null,
"maxElev": null,
"minElev": null,
"datTp": null,
"rvAg": null,
"ifInnRv": null,
"showControl": null,
"stcd": null,
"displayDepartment": null
wbsCode: '02',
wbsName: '雅砻江干流',
selected: false
},
{
"_tls": {},
"id": null,
"recordUser": null,
"recordTime": null,
"modifyTime": null,
"displayRecordUser": null,
"isolateType": null,
"wbsType": null,
"wbsCode": "03",
"wbsName": "大渡河干流",
"wbsSname": null,
"wbsNameEn": null,
"wbsSnameEn": null,
"enable": null,
"description": null,
"parentId": null,
"parentCode": null,
"treeLevel": null,
"hasChildren": null,
"objId": null,
"topWbsType": null,
"fullPath": null,
"internal": null,
"lgtd": null,
"lttd": null,
"area": null,
"perimeter": null,
"synopsis": null,
"introduce": null,
"logo": null,
"inffile": null,
"orderIndex": null,
"filterContent": null,
"departmentId": null,
"systemId": null,
"platformId": null,
"reachWwqtg": null,
"maxElev": null,
"minElev": null,
"datTp": null,
"rvAg": null,
"ifInnRv": null,
"showControl": null,
"stcd": null,
"displayDepartment": null
wbsCode: '03',
wbsName: '大渡河干流',
selected: false
},
{
"_tls": {},
"id": null,
"recordUser": null,
"recordTime": null,
"modifyTime": null,
"displayRecordUser": null,
"isolateType": null,
"wbsType": null,
"wbsCode": "04",
"wbsName": "乌江干流",
"wbsSname": null,
"wbsNameEn": null,
"wbsSnameEn": null,
"enable": null,
"description": null,
"parentId": null,
"parentCode": null,
"treeLevel": null,
"hasChildren": null,
"objId": null,
"topWbsType": null,
"fullPath": null,
"internal": null,
"lgtd": null,
"lttd": null,
"area": null,
"perimeter": null,
"synopsis": null,
"introduce": null,
"logo": null,
"inffile": null,
"orderIndex": null,
"filterContent": null,
"departmentId": null,
"systemId": null,
"platformId": null,
"reachWwqtg": null,
"maxElev": null,
"minElev": null,
"datTp": null,
"rvAg": null,
"ifInnRv": null,
"showControl": null,
"stcd": null,
"displayDepartment": null
wbsCode: '04',
wbsName: '乌江干流',
selected: false
},
{
"_tls": {},
"id": null,
"recordUser": null,
"recordTime": null,
"modifyTime": null,
"displayRecordUser": null,
"isolateType": null,
"wbsType": null,
"wbsCode": "05",
"wbsName": "长江上游干流",
"wbsSname": null,
"wbsNameEn": null,
"wbsSnameEn": null,
"enable": null,
"description": null,
"parentId": null,
"parentCode": null,
"treeLevel": null,
"hasChildren": null,
"objId": null,
"topWbsType": null,
"fullPath": null,
"internal": null,
"lgtd": null,
"lttd": null,
"area": null,
"perimeter": null,
"synopsis": null,
"introduce": null,
"logo": null,
"inffile": null,
"orderIndex": null,
"filterContent": null,
"departmentId": null,
"systemId": null,
"platformId": null,
"reachWwqtg": null,
"maxElev": null,
"minElev": null,
"datTp": null,
"rvAg": null,
"ifInnRv": null,
"showControl": null,
"stcd": null,
"displayDepartment": null
wbsCode: '05',
wbsName: '长江上游干流',
selected: false
},
{
"_tls": {},
"id": null,
"recordUser": null,
"recordTime": null,
"modifyTime": null,
"displayRecordUser": null,
"isolateType": null,
"wbsType": null,
"wbsCode": "10",
"wbsName": "湘西",
"wbsSname": null,
"wbsNameEn": null,
"wbsSnameEn": null,
"enable": null,
"description": null,
"parentId": null,
"parentCode": null,
"treeLevel": null,
"hasChildren": null,
"objId": null,
"topWbsType": null,
"fullPath": null,
"internal": null,
"lgtd": null,
"lttd": null,
"area": null,
"perimeter": null,
"synopsis": null,
"introduce": null,
"logo": null,
"inffile": null,
"orderIndex": null,
"filterContent": null,
"departmentId": null,
"systemId": null,
"platformId": null,
"reachWwqtg": null,
"maxElev": null,
"minElev": null,
"datTp": null,
"rvAg": null,
"ifInnRv": null,
"showControl": null,
"stcd": null,
"displayDepartment": null
wbsCode: '10',
wbsName: '湘西',
selected: false
},
{
"_tls": {},
"id": null,
"recordUser": null,
"recordTime": null,
"modifyTime": null,
"displayRecordUser": null,
"isolateType": null,
"wbsType": null,
"wbsCode": "08",
"wbsName": "黄河上游干流",
"wbsSname": null,
"wbsNameEn": null,
"wbsSnameEn": null,
"enable": null,
"description": null,
"parentId": null,
"parentCode": null,
"treeLevel": null,
"hasChildren": null,
"objId": null,
"topWbsType": null,
"fullPath": null,
"internal": null,
"lgtd": null,
"lttd": null,
"area": null,
"perimeter": null,
"synopsis": null,
"introduce": null,
"logo": null,
"inffile": null,
"orderIndex": null,
"filterContent": null,
"departmentId": null,
"systemId": null,
"platformId": null,
"reachWwqtg": null,
"maxElev": null,
"minElev": null,
"datTp": null,
"rvAg": null,
"ifInnRv": null,
"showControl": null,
"stcd": null,
"displayDepartment": null
wbsCode: '08',
wbsName: '黄河上游干流',
selected: false
},
{
"_tls": {},
"id": null,
"recordUser": null,
"recordTime": null,
"modifyTime": null,
"displayRecordUser": null,
"isolateType": null,
"wbsType": null,
"wbsCode": "09",
"wbsName": "黄河中游干流",
"wbsSname": null,
"wbsNameEn": null,
"wbsSnameEn": null,
"enable": null,
"description": null,
"parentId": null,
"parentCode": null,
"treeLevel": null,
"hasChildren": null,
"objId": null,
"topWbsType": null,
"fullPath": null,
"internal": null,
"lgtd": null,
"lttd": null,
"area": null,
"perimeter": null,
"synopsis": null,
"introduce": null,
"logo": null,
"inffile": null,
"orderIndex": null,
"filterContent": null,
"departmentId": null,
"systemId": null,
"platformId": null,
"reachWwqtg": null,
"maxElev": null,
"minElev": null,
"datTp": null,
"rvAg": null,
"ifInnRv": null,
"showControl": null,
"stcd": null,
"displayDepartment": null
wbsCode: '09',
wbsName: '黄河中游干流',
selected: false
},
{
"_tls": {},
"id": null,
"recordUser": null,
"recordTime": null,
"modifyTime": null,
"displayRecordUser": null,
"isolateType": null,
"wbsType": null,
"wbsCode": "06",
"wbsName": "南盘江-红水河",
"wbsSname": null,
"wbsNameEn": null,
"wbsSnameEn": null,
"enable": null,
"description": null,
"parentId": null,
"parentCode": null,
"treeLevel": null,
"hasChildren": null,
"objId": null,
"topWbsType": null,
"fullPath": null,
"internal": null,
"lgtd": null,
"lttd": null,
"area": null,
"perimeter": null,
"synopsis": null,
"introduce": null,
"logo": null,
"inffile": null,
"orderIndex": null,
"filterContent": null,
"departmentId": null,
"systemId": null,
"platformId": null,
"reachWwqtg": null,
"maxElev": null,
"minElev": null,
"datTp": null,
"rvAg": null,
"ifInnRv": null,
"showControl": null,
"stcd": null,
"displayDepartment": null
wbsCode: '06',
wbsName: '南盘江-红水河',
selected: false
},
{
"_tls": {},
"id": null,
"recordUser": null,
"recordTime": null,
"modifyTime": null,
"displayRecordUser": null,
"isolateType": null,
"wbsType": null,
"wbsCode": "12",
"wbsName": "东北",
"wbsSname": null,
"wbsNameEn": null,
"wbsSnameEn": null,
"enable": null,
"description": null,
"parentId": null,
"parentCode": null,
"treeLevel": null,
"hasChildren": null,
"objId": null,
"topWbsType": null,
"fullPath": null,
"internal": null,
"lgtd": null,
"lttd": null,
"area": null,
"perimeter": null,
"synopsis": null,
"introduce": null,
"logo": null,
"inffile": null,
"orderIndex": null,
"filterContent": null,
"departmentId": null,
"systemId": null,
"platformId": null,
"reachWwqtg": null,
"maxElev": null,
"minElev": null,
"datTp": null,
"rvAg": null,
"ifInnRv": null,
"showControl": null,
"stcd": null,
"displayDepartment": null
wbsCode: '12',
wbsName: '东北',
selected: false
},
{
"_tls": {},
"id": null,
"recordUser": null,
"recordTime": null,
"modifyTime": null,
"displayRecordUser": null,
"isolateType": null,
"wbsType": null,
"wbsCode": "07",
"wbsName": "澜沧江干流",
"wbsSname": null,
"wbsNameEn": null,
"wbsSnameEn": null,
"enable": null,
"description": null,
"parentId": null,
"parentCode": null,
"treeLevel": null,
"hasChildren": null,
"objId": null,
"topWbsType": null,
"fullPath": null,
"internal": null,
"lgtd": null,
"lttd": null,
"area": null,
"perimeter": null,
"synopsis": null,
"introduce": null,
"logo": null,
"inffile": null,
"orderIndex": null,
"filterContent": null,
"departmentId": null,
"systemId": null,
"platformId": null,
"reachWwqtg": null,
"maxElev": null,
"minElev": null,
"datTp": null,
"rvAg": null,
"ifInnRv": null,
"showControl": null,
"stcd": null,
"displayDepartment": null
wbsCode: '07',
wbsName: '澜沧江干流',
selected: false
},
{
"_tls": {},
"id": null,
"recordUser": null,
"recordTime": null,
"modifyTime": null,
"displayRecordUser": null,
"isolateType": null,
"wbsType": null,
"wbsCode": "13",
"wbsName": "怒江干流",
"wbsSname": null,
"wbsNameEn": null,
"wbsSnameEn": null,
"enable": null,
"description": null,
"parentId": null,
"parentCode": null,
"treeLevel": null,
"hasChildren": null,
"objId": null,
"topWbsType": null,
"fullPath": null,
"internal": null,
"lgtd": null,
"lttd": null,
"area": null,
"perimeter": null,
"synopsis": null,
"introduce": null,
"logo": null,
"inffile": null,
"orderIndex": null,
"filterContent": null,
"departmentId": null,
"systemId": null,
"platformId": null,
"reachWwqtg": null,
"maxElev": null,
"minElev": null,
"datTp": null,
"rvAg": null,
"ifInnRv": null,
"showControl": null,
"stcd": null,
"displayDepartment": null
wbsCode: '13',
wbsName: '怒江干流'
},
{
"_tls": {},
"id": null,
"recordUser": null,
"recordTime": null,
"modifyTime": null,
"displayRecordUser": null,
"isolateType": null,
"wbsType": null,
"wbsCode": "11",
"wbsName": "闽浙赣",
"wbsSname": null,
"wbsNameEn": null,
"wbsSnameEn": null,
"enable": null,
"description": null,
"parentId": null,
"parentCode": null,
"treeLevel": null,
"hasChildren": null,
"objId": null,
"topWbsType": null,
"fullPath": null,
"internal": null,
"lgtd": null,
"lttd": null,
"area": null,
"perimeter": null,
"synopsis": null,
"introduce": null,
"logo": null,
"inffile": null,
"orderIndex": null,
"filterContent": null,
"departmentId": null,
"systemId": null,
"platformId": null,
"reachWwqtg": null,
"maxElev": null,
"minElev": null,
"datTp": null,
"rvAg": null,
"ifInnRv": null,
"showControl": null,
"stcd": null,
"displayDepartment": null
wbsCode: '11',
wbsName: '闽浙赣'
},
{
"_tls": {},
"id": null,
"recordUser": null,
"recordTime": null,
"modifyTime": null,
"displayRecordUser": null,
"isolateType": null,
"wbsType": null,
"wbsCode": "other",
"wbsName": "其他",
"wbsSname": null,
"wbsNameEn": null,
"wbsSnameEn": null,
"enable": null,
"description": null,
"parentId": null,
"parentCode": null,
"treeLevel": null,
"hasChildren": null,
"objId": null,
"topWbsType": null,
"fullPath": null,
"internal": null,
"lgtd": null,
"lttd": null,
"area": null,
"perimeter": null,
"synopsis": null,
"introduce": null,
"logo": null,
"inffile": null,
"orderIndex": null,
"filterContent": null,
"departmentId": null,
"systemId": null,
"platformId": null,
"reachWwqtg": null,
"maxElev": null,
"minElev": null,
"datTp": null,
"rvAg": null,
"ifInnRv": null,
"showControl": null,
"stcd": null,
"displayDepartment": null
wbsCode: 'other',
wbsName: '其他'
}
]);
]);
const selectedItem = ref(jidiData.value[0]);
const updataJidiData = (index: any) => {
console.log(index);
selectedItem.value = jidiData.value[index];
jidiData.value.forEach((item: any) => {
item.selected = false;

View File

@ -24,10 +24,7 @@
<script lang="ts" setup>
import { ref, reactive, onMounted, h, computed, nextTick } from "vue";
import {
batchApproveByApprovalId,
batchReject,
} from "@/api/shengPiJiLu";
import { batchApproveByApprovalId, batchReject } from "@/api/shengPiJiLu";
import { Tag, message } from "ant-design-vue";
import BasicTable from "@/components/BasicTable/index.vue";
import ApprovalDetailSearch from "../shengPiJiLu/approvalDetailSearch.vue";
@ -37,7 +34,10 @@ import { getFishDraftPage } from "@/api/guoYuSheShiShuJuTianBao";
const baseUrl = import.meta.env.VITE_APP_PREVIEW_URL;
let columns = ref([
{ dataIndex: "hbrvnm", key: "hbrvnm", title: "流域",
{
dataIndex: "hbrvnm",
key: "hbrvnm",
title: "流域",
customCell: (_, index) => {
if (index === 0) {
return { rowSpan: 2 };
@ -51,7 +51,10 @@ let columns = ref([
}
},
},
{ dataIndex: "ennm", key: "ennm", title: "电站名称",
{
dataIndex: "ennm",
key: "ennm",
title: "电站名称",
customCell: (_, index) => {
if (index === 0) {
return { rowSpan: 2 };
@ -63,7 +66,8 @@ let columns = ref([
if (index === 2) {
return { colSpan: 1 };
}
},},
},
},
{ dataIndex: "stnm", key: "stnm", title: "月份" },
{ dataIndex: "startTime", key: "startTime", title: "过鱼开始时间" },
{ dataIndex: "endTime", key: "endTime", title: "过鱼结束时间" },
@ -291,7 +295,6 @@ const handName = (val: any, arr: any) => {
return dictName1;
};
//
const searchData = ref<any>({
hbrvcd: "all",
@ -317,10 +320,12 @@ const computedSearchParams = computed(() => ({
<style scoped lang="scss">
.guoYuDaoShuTongJi-page {
position: relative;
z-index: 900;
pointer-events: all;
width: 100%;
height: 100%;
background-color: #ffffff;
padding: 20px;
}
</style>

View File

@ -351,6 +351,9 @@ onMounted(() => {
<style lang="scss" scoped>
.guoYuSheShiShuJuHistory-page {
position: relative;
z-index: 900;
pointer-events: all;
width: 100%;
height: 100%;
background-color: #ffffff;

View File

@ -113,10 +113,9 @@
<a-form-item label="过鱼时间" name="strdt">
<a-date-picker
v-model:value="formData.strdt"
show-time
style="width: 100%"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
placeholder="选择日期"
:disabled="isView"
/>
@ -770,6 +769,7 @@ const handleOk = async () => {
...formData,
fwet: fwet,
fsz: fsz,
strdt: formData.strdt + " 00:00:00",
picpth: finalPicPaths.join(","), //
vdpth: finalVideoPaths.join(","),
};

View File

@ -147,10 +147,9 @@
<template v-else-if="column.dataIndex === 'strdtStr'">
<a-date-picker
v-model:value="editingData.strdtStr"
show-time
style="width: 100%"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
@change="(val) => delWarning(val, 'strdtStr')"
/>
</template>
@ -664,7 +663,7 @@ const saveEdit = async (index: number) => {
// 2.
const newData = [...props.fileTableData];
newData[index] = { ...editingData.value };
newData[index].strdt = newData[index].strdtStr;
newData[index].strdt = newData[index].strdtStr + " 00:00:00";
emit("update:fileLoading", true);
try {
const res: any = await revalidateAndUpdateRow({

View File

@ -717,13 +717,16 @@ const fileChange = (file: File) => {
visible.value = true;
fileLoading.value = true;
fileTableData.value = [];
const formData = new FormData();
formData.append("file", file);
let res: any = await importFishZip(formData);
console.log(res);
if (res && res?.code == 0) {
if (visible.value) importBtn();
setTimeout(() => {
if (visible.value) importBtn();
}, 5000);
const formData = new FormData();
formData.append("file", file);
await importFishZip(formData);
if (visible.value) importBtn();
}
});
};
//
@ -1005,6 +1008,9 @@ onMounted(() => {
<style lang="scss" scoped>
.guoYuSheShiShuJuTianBao-page {
position: relative;
z-index: 900;
pointer-events: all;
width: 100%;
height: 100%;
background-color: #ffffff;

View File

@ -1031,6 +1031,9 @@ const computedSearchParams = computed(() => ({
<style scoped lang="scss">
.shengPiJiLu-page {
position: relative;
z-index: 900;
pointer-events: all;
width: 100%;
height: 100%;
background-color: #ffffff;

View File

@ -1,7 +1,6 @@
<script lang="ts">
export default {
name: 'dept'
name: "dept",
};
</script>
@ -18,7 +17,7 @@ import {
reviseDepartment,
} from "@/api/dept";
import { useAppStore } from '@/store/modules/app';
import { useAppStore } from "@/store/modules/app";
//
interface Tree {
[x: string]: any;
@ -75,10 +74,11 @@ function getTree() {
const params = {
parentid: "0",
};
treeloading.value = true
getTreelist(params).then((res: any) => {
treeloading.value = true;
getTreelist(params)
.then((res: any) => {
treedata.value = res;
treeloading.value = false
treeloading.value = false;
if (checkedtreeid.value == "") {
checkedtreeid.value = res[0].id;
}
@ -87,19 +87,19 @@ function getTree() {
});
getData();
})
.catch(()=>{
treeloading.value = false
})
.catch(() => {
treeloading.value = false;
});
}
//
function getData() {
const params = {
id: checkedtreeid.value,
};
loading.value = true
loading.value = true;
gettableData(params).then((res) => {
tableData.value = res.data;
loading.value = false
loading.value = false;
});
}
const multipleSelection = ref([]);
@ -118,11 +118,11 @@ function handleSelectionChange(val: any) {
}
//
function switchChange(row: any) {
const elMessage = ref('')
if (row.isvaild == '0') {
elMessage.value = "确定设置该部门为无效吗?"
} else if (row.isvaild == '1') {
elMessage.value = "确定设置该部门为有效吗?"
const elMessage = ref("");
if (row.isvaild == "0") {
elMessage.value = "确定设置该部门为无效吗?";
} else if (row.isvaild == "1") {
elMessage.value = "确定设置该部门为有效吗?";
}
ElMessageBox.confirm(elMessage.value, "提示信息", {
confirmButtonText: "确定",
@ -142,7 +142,6 @@ function switchChange(row: any) {
message: "改变成功",
});
});
})
.catch(() => {
getData();
@ -204,7 +203,7 @@ function confirmClick(formEl: any) {
}
dialogVisible.value = false;
}
})
});
}
//
function handleClose() {
@ -238,7 +237,6 @@ function remove(data: any) {
type: "success",
});
});
});
}
@ -320,10 +318,10 @@ function delClick() {
}).then(() => {
let id = [] as any[];
multipleSelection.value.forEach((item: any) => {
id.push(item.id)
})
id.push(item.id);
});
let params = {
id: id.join(','),
id: id.join(","),
};
delTreelist(params).then(() => {
getTree();
@ -339,7 +337,8 @@ function dateFormat(row: any) {
if (daterc != null) {
var date = new Date(daterc);
var year = date.getFullYear();
var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1;
var month =
date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1;
date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1;
var day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
var hours = date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
@ -367,26 +366,54 @@ const vMove = {
document.onmousemove = document.onmouseup = null;
};
};
}
}
},
};
</script>
<template>
<div class="faulttemplate-box">
<aside id="silderLeft">
<div v-hasPerm="['add:org']" class="p-[15px]"><el-button class="w-full mb-[15px]" style="color: #0099ff; border: 1px solid #0099ff;"
@click="causeAdd"> <img src="@/assets/MenuIcon/u241.png" style="margin-right: 10px;"> 新增企业</el-button></div>
<el-tree :class="useAppStore().size === 'default' ? 'silderLeft-large' : 'silderLeft-default'" v-loading="treeloading"
ref="treeRef" node-key="id" :data="treedata" :highlight-current="true" :props="defaultProps"
@node-click="handleNodeClick" style="height: calc(100vh - 215px); overflow: auto">
<div v-hasPerm="['add:org']" class="p-[15px]">
<el-button
class="w-full mb-[15px]"
style="color: #0099ff; border: 1px solid #0099ff"
@click="causeAdd"
>
<img src="@/assets/MenuIcon/u241.png" style="margin-right: 10px" />
新增企业</el-button
>
</div>
<el-tree
:class="
useAppStore().size === 'default' ? 'silderLeft-large' : 'silderLeft-default'
"
v-loading="treeloading"
ref="treeRef"
node-key="id"
:data="treedata"
:highlight-current="true"
:props="defaultProps"
@node-click="handleNodeClick"
style="height: calc(100vh - 215px); overflow: auto"
>
<template #default="{ node, data }">
<span class="custom-tree-node">
<span>{{ node.label }}</span>
<span style="font-size: 16px;">
<el-icon v-hasPerm="['update:org']" class="treeediticon" title="修改" @click="() => edittree(data)">
<span style="font-size: 16px">
<el-icon
v-hasPerm="['update:org']"
class="treeediticon"
title="修改"
@click="() => edittree(data)"
>
<EditPen />
</el-icon>
<el-icon v-hasPerm="['del:org']" class="treedelicon" title="删除" @click="() => remove(data)">
<el-icon
v-hasPerm="['del:org']"
class="treedelicon"
title="删除"
@click="() => remove(data)"
>
<Delete />
</el-icon>
</span>
@ -401,36 +428,80 @@ const vMove = {
<el-row style="margin-bottom: 10px">
<el-col :span="24" class="top-nav">
<div>
<el-input v-model="querystr" placeholder="请输入部门名称" clearable style="width: 200px;"
@keyup.enter="searchOrganizations" />
<el-button type="primary" style="margin-left: 10px;" @click="searchOrganizations">搜索</el-button>
<el-input
v-model="querystr"
placeholder="请输入部门名称"
clearable
style="width: 200px"
@keyup.enter="searchOrganizations"
/>
<el-button
type="primary"
style="margin-left: 10px"
@click="searchOrganizations"
>搜索</el-button
>
</div>
<div class="left-nav">
<el-button v-hasPerm="['add:org']" type="primary" @click="addClick"><img style="margin-right:5px;" src="@/assets/MenuIcon/jscz_xz.png" alt=""> 新增</el-button>
<el-button v-hasPerm="['del:org']" :disabled="multipleSelection.length <= 0" :type="multipleSelection.length > 0 ? 'primary' : ''"
@click="delClick"><el-icon>
<el-button v-hasPerm="['add:org']" type="primary" @click="addClick"
><img
style="margin-right: 5px"
src="@/assets/MenuIcon/jscz_xz.png"
alt=""
/>
新增</el-button
>
<el-button
v-hasPerm="['del:org']"
:disabled="multipleSelection.length <= 0"
:type="multipleSelection.length > 0 ? 'primary' : ''"
@click="delClick"
><el-icon>
<Delete />
</el-icon> </el-button>
</el-icon>
删除</el-button
>
</div>
</el-col>
</el-row>
<el-table v-loading="loading" :data="tableData" style="width: 100%; margin-bottom: 20px" row-key="id" border
@selection-change="handleSelectionChange" default-expand-all :header-cell-style="{background:'rgb(250 250 250)',height:'50px'}" >
<el-table
v-loading="loading"
:data="tableData"
style="width: 100%; margin-bottom: 20px"
row-key="id"
border
@selection-change="handleSelectionChange"
default-expand-all
:header-cell-style="{ background: 'rgb(250 250 250)', height: '50px' }"
>
<el-table-column type="selection" width="50" align="center" />
<el-table-column prop="orgcode" label="部门编号" width="100"></el-table-column>
<el-table-column prop="orgname" label="部门名称" width="140"></el-table-column>
<el-table-column prop="manager" label="负责人" width="120"></el-table-column>
<el-table-column prop="custom1" label="联系信息" width="160"></el-table-column>
<el-table-column prop="description" label="部门描述" min-width="100"></el-table-column>
<el-table-column
prop="description"
label="部门描述"
min-width="100"
></el-table-column>
<el-table-column prop="isvaild" label="是否有效" align="center" width="120">
<template #default="scope">
<el-switch v-model="scope.row.isvaild" active-value="1" inactive-value="0" @change="switchChange(scope.row)"
style="margin-right: 4px"></el-switch>
<el-switch
v-model="scope.row.isvaild"
active-value="1"
inactive-value="0"
@change="switchChange(scope.row)"
style="margin-right: 4px"
></el-switch>
<span v-if="scope.row.isvaild == 1" style="color: #0099ff">有效</span>
<span v-else style="color: #d7d7d7">无效</span>
</template>
</el-table-column>
<el-table-column prop="lastmodifier" label="最近修改者" width="174"></el-table-column>
<el-table-column
prop="lastmodifier"
label="最近修改者"
width="174"
></el-table-column>
<el-table-column prop="lastmodifydate" label="最近修改日期" width="196">
<template #default="scope">
{{ dateFormat(scope.row.lastmodifydate) }}
@ -438,11 +509,28 @@ const vMove = {
</el-table-column>
<el-table-column fixed="right" label="操作" width="80">
<template #default="scope">
<span style="display: flex;display: -webkit-flex;justify-content: space-around; -webkit-justify-content: space-around; ">
<img v-hasPerm="['update:org']" src="@/assets/MenuIcon/lbcz_xg.png" title="修改" style="cursor: pointer;"
@click="editdepartment(scope.row)" >
<img v-hasPerm="['del:org']" src="@/assets/MenuIcon/lbcz_sc.png" title="删除" style="cursor: pointer;"
@click="deldepartment(scope.row)" >
<span
style="
display: flex;
display: -webkit-flex;
justify-content: space-around;
-webkit-justify-content: space-around;
"
>
<img
v-hasPerm="['update:org']"
src="@/assets/MenuIcon/lbcz_xg.png"
title="修改"
style="cursor: pointer"
@click="editdepartment(scope.row)"
/>
<img
v-hasPerm="['del:org']"
src="@/assets/MenuIcon/lbcz_sc.png"
title="删除"
style="cursor: pointer"
@click="deldepartment(scope.row)"
/>
</span>
</template>
</el-table-column>
@ -450,55 +538,118 @@ const vMove = {
</main>
<!-- 部门 弹框-->
<el-dialog v-model="dialogVisible" :before-close="handleClose" :title="title" draggable width="620px">
<el-dialog
v-model="dialogVisible"
:before-close="handleClose"
:title="title"
draggable
width="620px"
>
<el-form ref="infoForm" :model="info" label-width="90px" :rules="moderules">
<el-form-item label="部门编号" prop="orgcode">
<el-input v-model="info.orgcode" style="width: 100%" :disabled="true"></el-input>
<el-input
v-model="info.orgcode"
style="width: 100%"
:disabled="true"
></el-input>
</el-form-item>
<el-form-item label="部门名称" prop="orgname">
<el-input v-model="info.orgname" style="width: 100%" placeholder="请输入部门名称"></el-input>
<el-input
v-model="info.orgname"
style="width: 100%"
placeholder="请输入部门名称"
></el-input>
</el-form-item>
<el-form-item label="负责人" prop="manager" placeholder="请输入负责人姓名">
<el-input v-model="info.manager" style="width: 100%"></el-input>
</el-form-item>
<el-form-item label="联系信息" prop="custom1">
<el-input type="textarea" v-model="info.custom1" :autosize="{ minRows: 2 }" style="width: 100%"
placeholder="请输入联系信息"></el-input>
<el-input
type="textarea"
v-model="info.custom1"
:autosize="{ minRows: 2 }"
style="width: 100%"
placeholder="请输入联系信息"
></el-input>
</el-form-item>
<el-form-item label="部门描述" prop="description">
<el-input type="textarea" v-model="info.description" :autosize="{ minRows: 2 }" style="width: 100%"
placeholder="请输入部门描述"></el-input>
<el-input
type="textarea"
v-model="info.description"
:autosize="{ minRows: 2 }"
style="width: 100%"
placeholder="请输入部门描述"
></el-input>
</el-form-item>
</el-form>
<span class="dialog-footer">
<el-button style="padding: 10px 15px" @click="handleClose"> </el-button>
<el-button type="primary" style="padding: 10px 15px" @click="confirmClick(infoForm)">确定</el-button>
<el-button
type="primary"
style="padding: 10px 15px"
@click="confirmClick(infoForm)"
>确定</el-button
>
</span>
</el-dialog>
<!-- 企业弹框-->
<el-dialog v-model="dialogCause" :before-close="handleClose" :title="title" draggable width="620px">
<el-dialog
v-model="dialogCause"
:before-close="handleClose"
:title="title"
draggable
width="620px"
>
<el-form ref="causeForm" :model="causeInfo" label-width="90px" :rules="rules">
<el-form-item label="企业编号" prop="orgcode">
<el-input v-model="causeInfo.orgcode" style="width: 100%" :disabled="true"></el-input>
<el-input
v-model="causeInfo.orgcode"
style="width: 100%"
:disabled="true"
></el-input>
</el-form-item>
<el-form-item label="企业名称" prop="orgname">
<el-input v-model="causeInfo.orgname" style="width: 100%" placeholder="请输入企业名称"></el-input>
<el-input
v-model="causeInfo.orgname"
style="width: 100%"
placeholder="请输入企业名称"
></el-input>
</el-form-item>
<el-form-item label="负责人" prop="manager">
<el-input v-model="causeInfo.manager" style="width: 100%" placeholder="请输入负责人姓名"> </el-input>
<el-input
v-model="causeInfo.manager"
style="width: 100%"
placeholder="请输入负责人姓名"
>
</el-input>
</el-form-item>
<el-form-item label="企业描述" prop="description">
<el-input v-model="causeInfo.description" type="textarea" :autosize="{ minRows: 2 }" style="width: 100%"
placeholder="请输入企业描述"></el-input>
<el-input
v-model="causeInfo.description"
type="textarea"
:autosize="{ minRows: 2 }"
style="width: 100%"
placeholder="请输入企业描述"
></el-input>
</el-form-item>
<el-form-item label="联系信息" prop="custom1">
<el-input v-model="causeInfo.custom1" type="textarea" :autosize="{ minRows: 2 }" style="width: 100%"
placeholder="请输入企业联系信息"></el-input>
<el-input
v-model="causeInfo.custom1"
type="textarea"
:autosize="{ minRows: 2 }"
style="width: 100%"
placeholder="请输入企业联系信息"
></el-input>
</el-form-item>
</el-form>
<span class="dialog-footer">
<el-button style="padding: 10px 15px" @click="handleClose"> </el-button>
<el-button type="primary" style="padding: 10px 15px" @click="editisrepetition(causeForm)">确定</el-button>
<el-button
type="primary"
style="padding: 10px 15px"
@click="editisrepetition(causeForm)"
>确定</el-button
>
</span>
</el-dialog>
</div>
@ -515,6 +666,9 @@ const vMove = {
}
.faulttemplate-box {
position: relative;
z-index: 900;
pointer-events: all;
height: 100%;
display: -webkit-flex;
display: flex;
@ -601,7 +755,6 @@ const vMove = {
justify-content: space-between;
-webkit-justify-content: space-between;
padding-right: 8px;
}
.faulttemplate-box {
@ -627,7 +780,7 @@ const vMove = {
color: #fff;
margin: 0 5px;
}
:deep(.el-table__cell){
:deep(.el-table__cell) {
color: #383838;
}
.top-nav {
@ -635,4 +788,5 @@ const vMove = {
display: flex;
justify-content: space-between;
-webkit-justify-content: space-between;
}</style>
}
</style>

View File

@ -1,30 +1,40 @@
<script lang="ts">
export default {
name: 'dept'
name: "dept",
};
</script>
<script setup lang="ts">
import { onMounted, reactive, ref, nextTick } from 'vue';
import { ElMessage, ElMessageBox, FormRules } from 'element-plus'
import Sortable from 'sortablejs';
import { useAppStore } from '@/store/modules/app';
import Page from '@/components/Pagination/page.vue'
import { onMounted, reactive, ref, nextTick } from "vue";
import { ElMessage, ElMessageBox, FormRules } from "element-plus";
import Sortable from "sortablejs";
import { useAppStore } from "@/store/modules/app";
import Page from "@/components/Pagination/page.vue";
import {
getTreelist, addDict, updateDict, deleteById, changeDictOrder, getDictItemById, addDictionaryItem, updateDictionaryItem, deleteDictItemById, deleteDictItemByIds, changeItemOrder
} from '@/api/dict';
getTreelist,
addDict,
updateDict,
deleteById,
changeDictOrder,
getDictItemById,
addDictionaryItem,
updateDictionaryItem,
deleteDictItemById,
deleteDictItemByIds,
changeItemOrder,
} from "@/api/dict";
const treeloading = ref(false);
const activeName = ref('00');
const activeName = ref("00");
// -
const treedata: any = ref([])
const treedata: any = ref([]);
const treeRef = ref();
const treeId = ref('');
const defaultProps = { label: 'dictName' }
const treeId = ref("");
const defaultProps = { label: "dictName" };
//
const title = ref('');
const title = ref("");
const dialogdict = ref(false);
const dictInfoRef = ref()
const dictInfoRef = ref();
const dictInfo = ref({
id: "",
dictCode: "",
@ -34,15 +44,15 @@ const dictInfo = ref({
//
const rules = reactive<FormRules>({
dictName: [{ required: true, message: "请输入字典名称", trigger: "blur" }],
dictCode: [{ required: true, message: "请输入字典编码", trigger: "blur" }]
dictCode: [{ required: true, message: "请输入字典编码", trigger: "blur" }],
});
//
const querystr = ref({
dictId: '',
dictName: '',
dictId: "",
dictName: "",
size: 10,
current: 1
current: 1,
});
//
const tableData = ref([]) as any;
@ -50,27 +60,27 @@ const multipleSelection = ref([]);
// const total = ref(0);
const tableloading = ref(false);
// /
const titleItem = ref('');
const titleItem = ref("");
const dialogdictItem = ref(false);
const dictInfoRefItem = ref()
const dictInfoRefItem = ref();
const dictInfoItem = ref({
id: "",
dictId: "",
itemCode: "",
dictName: "",
parentCode: "",
custom1: ""
custom1: "",
});
//
const dictItemrules = reactive<FormRules>({
dictName: [{ required: true, message: "请输入项名称", trigger: "blur" }],
itemCode: [{ required: true, message: "请输入项编码", trigger: "blur" }]
itemCode: [{ required: true, message: "请输入项编码", trigger: "blur" }],
});
//
onMounted(() => {
getTree()
rowDrop()
})
getTree();
rowDrop();
});
const vMove = {
mounted(el: any) {
@ -87,10 +97,10 @@ const vMove = {
document.onmousemove = document.onmouseup = null;
};
};
}
}
},
};
function rowDrop() {
const tbody = document.querySelector('.draggable .el-table__body-wrapper tbody');
const tbody = document.querySelector(".draggable .el-table__body-wrapper tbody");
Sortable.create(tbody, {
draggable: ".draggable .el-table__row",
onEnd(data: any) {
@ -106,30 +116,31 @@ function rowDrop() {
changeItemOrder(params).then(() => {
init();
});
}
},
});
}
//
function getTree() {
const params = {
dictType: activeName.value
}
treeloading.value = true
getTreelist(params).then((res) => {
treedata.value = res.data
treeloading.value = false
dictType: activeName.value,
};
treeloading.value = true;
getTreelist(params)
.then((res) => {
treedata.value = res.data;
treeloading.value = false;
if (treeId.value == "") {
treeId.value = res.data[0].id;
}
nextTick(() => {
treeRef.value?.setCurrentKey(treeId.value);
});
if (res.data.length == 0) treeId.value = ''
if (res.data.length == 0) treeId.value = "";
init();
})
.catch(()=>{
treeloading.value = false
})
.catch(() => {
treeloading.value = false;
});
}
//
function handleNodeClick(row: any) {
@ -138,8 +149,8 @@ function handleNodeClick(row: any) {
}
// / -
function activeNameChange(name: any) {
activeName.value = name.props.name
getTree()
activeName.value = name.props.name;
getTree();
}
//
@ -196,7 +207,7 @@ function dictSave(formEl: any) {
type: "success",
message: "新增成功",
});
})
});
} else if (dictInfo.value.id) {
const params = {
dictCode: dictInfo.value.dictCode,
@ -216,7 +227,7 @@ function dictSave(formEl: any) {
return false;
}
}
})
});
}
//
function treenodeDrop(before: any, after: any) {
@ -226,22 +237,21 @@ function treenodeDrop(before: any, after: any) {
};
changeDictOrder(params).then(() => {
getTree();
});
}
const allowDrop:any = (draggingNode: any, dropNode: any, type: any) => {
const allowDrop: any = (draggingNode: any, dropNode: any, type: any) => {
//
if (type === 'inner' || Number(dropNode.data.pid) === 0) return
if (type === "inner" || Number(dropNode.data.pid) === 0) return;
if (draggingNode.nextSibling === undefined) {
return type === 'prev'
return type === "prev";
} else if (dropNode.nextSibling === undefined) {
return type === 'next'
return type === "next";
} else if (draggingNode.nextSibling.id !== dropNode.id) {
return type === 'prev'
return type === "prev";
} else {
return type === 'next'
return type === "next";
}
}
};
//
function dictClose() {
dictInfoRef.value.resetFields();
@ -251,19 +261,21 @@ function dictClose() {
function init() {
tableloading.value = true;
querystr.value.dictId = treeId.value;
getDictItemById(querystr.value).then((result: any) => {
getDictItemById(querystr.value)
.then((result: any) => {
if (result.data.records == null) {
tableData.value = []
tableData.value = [];
total.value = 0;
tableloading.value = false;
return
return;
}
tableData.value = result.data.records;
total.value = result.data.total;
querystr.value.size = result.data.size;
querystr.value.current = result.data.current
querystr.value.current = result.data.current;
tableloading.value = false;
}).catch(() => {
})
.catch(() => {
tableloading.value = false;
});
}
@ -277,7 +289,7 @@ function addClick() {
itemCode: "",
dictName: "",
parentCode: "",
custom1: ""
custom1: "",
});
dictInfoItem.value = info.value;
}
@ -315,10 +327,10 @@ function delsClick() {
}).then(() => {
let id = [] as any[];
multipleSelection.value.forEach((item: any) => {
id.push(item.id)
})
id.push(item.id);
});
let params = {
id: id.join(','),
id: id.join(","),
};
deleteDictItemByIds(params).then(() => {
init();
@ -344,7 +356,7 @@ function dictItemSave(formEl: any) {
itemCode: dictInfoItem.value.itemCode,
dictName: dictInfoItem.value.dictName,
parentCode: dictInfoItem.value.parentCode,
custom1: dictInfoItem.value.custom1
custom1: dictInfoItem.value.custom1,
};
addDictionaryItem(params).then(() => {
init();
@ -353,7 +365,7 @@ function dictItemSave(formEl: any) {
type: "success",
message: "新增字典项成功",
});
})
});
} else if (dictInfoItem.value.id) {
const params = {
dictId: dictInfoItem.value.dictId,
@ -375,7 +387,7 @@ function dictItemSave(formEl: any) {
return false;
}
}
})
});
}
//
function handleSelectionChange(val: any) {
@ -383,28 +395,59 @@ function handleSelectionChange(val: any) {
}
//
const total = ref()
const total = ref();
</script>
<template>
<div class="faulttemplate-box">
<aside id="silderLeft">
<el-tabs :class="useAppStore().size === 'default' ? 'silderLeft-large' : 'silderLeft-default'" v-model="activeName"
class="demo-tabs" @tab-click="activeNameChange">
<el-tabs
:class="
useAppStore().size === 'default' ? 'silderLeft-large' : 'silderLeft-default'
"
v-model="activeName"
class="demo-tabs"
@tab-click="activeNameChange"
>
<el-tab-pane label="系统配置" name="00"></el-tab-pane>
<el-tab-pane label="用户配置" name="01"></el-tab-pane>
</el-tabs>
<div class="menu-box">
<el-button style="border:1px solid #0099FF;width:100%;color:#0099FF;margin-bottom:10px;" @click="dictAdd"> <img
src="@/assets/MenuIcon/czan_xz.png" alt="" style="width: 14px; margin-right: 5px;"> 新增字典</el-button>
<el-tree v-loading="treeloading" ref="treeRef"
:class="useAppStore().size === 'default' ? 'silderLeft-large' : 'silderLeft-default'" node-key="id"
:allow-drop="allowDrop" :data="treedata" draggable :highlight-current="true" :props="defaultProps"
@node-click="handleNodeClick" @node-drop="treenodeDrop" style="height:calc(100vh - 254px);overflow: auto;">
<el-button
style="
border: 1px solid #0099ff;
width: 100%;
color: #0099ff;
margin-bottom: 10px;
"
@click="dictAdd"
>
<img
src="@/assets/MenuIcon/czan_xz.png"
alt=""
style="width: 14px; margin-right: 5px"
/>
新增字典</el-button
>
<el-tree
v-loading="treeloading"
ref="treeRef"
:class="
useAppStore().size === 'default' ? 'silderLeft-large' : 'silderLeft-default'
"
node-key="id"
:allow-drop="allowDrop"
:data="treedata"
draggable
:highlight-current="true"
:props="defaultProps"
@node-click="handleNodeClick"
@node-drop="treenodeDrop"
style="height: calc(100vh - 254px); overflow: auto"
>
<template #default="{ node, data }">
<span class="custom-tree-node">
<span class="custom-tree-node-img">
<img src="@/assets/images/linefeed.png" alt="">
<img src="@/assets/images/linefeed.png" alt="" />
<span>{{ node.label }}</span>
</span>
<span>
@ -426,93 +469,225 @@ const total = ref()
<section class="silderRight">
<el-row>
<el-col :span="24" class="top-nav">
<div style="margin-bottom:10px">
<el-input v-model="querystr.dictName" placeholder="请输入项名称" clearable style="width: 200px;margin-right: 10px;"
@keyup.enter="init" />
<div style="margin-bottom: 10px">
<el-input
v-model="querystr.dictName"
placeholder="请输入项名称"
clearable
style="width: 200px; margin-right: 10px"
@keyup.enter="init"
/>
<el-button type="primary" @click="init">搜索</el-button>
</div>
<div class="left-nav">
<el-button type="primary" @click="addClick()"> <img src="@/assets/MenuIcon/jscz_xz.png" alt=""
style="width: 14px;margin-right: 3px;"> 新增</el-button>
<el-button :type="multipleSelection.length > 0 ? 'primary' : ''" :disabled="multipleSelection.length <= 0"
@click="delsClick">
<el-button type="primary" @click="addClick()">
<img
src="@/assets/MenuIcon/jscz_xz.png"
alt=""
style="width: 14px; margin-right: 3px"
/>
新增</el-button
>
<el-button
:type="multipleSelection.length > 0 ? 'primary' : ''"
:disabled="multipleSelection.length <= 0"
@click="delsClick"
>
<el-icon>
<Delete />
</el-icon> </el-button>
</el-icon>
删除</el-button
>
</div>
</el-col>
</el-row>
<div class="draggable">
<el-table v-loading="tableloading" :data="tableData" row-key="id" style="width: 100%;margin-bottom: 20px;" border
@selection-change="handleSelectionChange" default-expand-all
:header-cell-style="{ background: 'rgb(250 250 250)', height: '50px' }">
<el-table
v-loading="tableloading"
:data="tableData"
row-key="id"
style="width: 100%; margin-bottom: 20px"
border
@selection-change="handleSelectionChange"
default-expand-all
:header-cell-style="{ background: 'rgb(250 250 250)', height: '50px' }"
>
<el-table-column type="selection" width="50" align="center" />
<el-table-column prop="orderNo" label="序号" width="80">
<template #default="scope">
<span class="custom-tree-node-img">
<img src="@/assets/images/linefeed.png" alt="">
<img src="@/assets/images/linefeed.png" alt="" />
{{ scope.row.orderNo }}
</span>
</template>
</el-table-column>
<el-table-column prop="itemCode" label="项编码" width="160"></el-table-column>
<el-table-column prop="dictName" label="项名称" width="140"></el-table-column>
<el-table-column prop="parentCode" label="父项编码" width="180"></el-table-column>
<el-table-column
prop="parentCode"
label="父项编码"
width="180"
></el-table-column>
<el-table-column prop="custom1" label="备注"></el-table-column>
<el-table-column fixed="right" label="操作" width="110">
<template #default="scope">
<span style="display: flex;display: -webkit-flex; justify-content: space-around; -webkit-justify-content: space-around;">
<img src="@/assets/MenuIcon/lbcz_xg.png" alt="" itle="修改" style="cursor: pointer;"
@click="editClick(scope.row)">
<img src="@/assets/MenuIcon/lbcz_sc.png" alt="" title="删除" style="cursor: pointer;"
@click="delClick(scope.row)">
<span
style="
display: flex;
display: -webkit-flex;
justify-content: space-around;
-webkit-justify-content: space-around;
"
>
<img
src="@/assets/MenuIcon/lbcz_xg.png"
alt=""
itle="修改"
style="cursor: pointer"
@click="editClick(scope.row)"
/>
<img
src="@/assets/MenuIcon/lbcz_sc.png"
alt=""
title="删除"
style="cursor: pointer"
@click="delClick(scope.row)"
/>
</span>
</template>
</el-table-column>
</el-table>
<Page :total="total" v-model:size="querystr.size" v-model:current="querystr.current" @pagination="init()" ></Page>
<Page
:total="total"
v-model:size="querystr.size"
v-model:current="querystr.current"
@pagination="init()"
></Page>
</div>
</section>
<!-- 子项 弹框-->
<el-dialog v-model="dialogdictItem" :before-close="dictItemClose" :title="titleItem" draggable width="620px">
<el-form ref="dictInfoRefItem" :model="dictInfoItem" label-width="80px" style="margin-top:10px"
:rules="dictItemrules">
<el-dialog
v-model="dialogdictItem"
:before-close="dictItemClose"
:title="titleItem"
draggable
width="620px"
>
<el-form
ref="dictInfoRefItem"
:model="dictInfoItem"
label-width="80px"
style="margin-top: 10px"
:rules="dictItemrules"
>
<el-form-item label="项编码" prop="itemCode">
<el-input v-model="dictInfoItem.itemCode" style="width:100%" placeholder="请输入项编码"></el-input>
<el-input
v-model="dictInfoItem.itemCode"
style="width: 100%"
placeholder="请输入项编码"
></el-input>
</el-form-item>
<el-form-item label="项名称" prop="dictName">
<el-input v-model="dictInfoItem.dictName" style="width:100%" placeholder="请输入项名称"></el-input>
<el-input
v-model="dictInfoItem.dictName"
style="width: 100%"
placeholder="请输入项名称"
></el-input>
</el-form-item>
<el-form-item label="父项编码" prop="parentCode">
<el-input v-model="dictInfoItem.parentCode" style="width:100%" placeholder="请输入父项编码"></el-input>
<el-input
v-model="dictInfoItem.parentCode"
style="width: 100%"
placeholder="请输入父项编码"
></el-input>
</el-form-item>
<p style="color:#f56c6c;font-size: 12px;width: 70%;margin: auto; margin-top: -15px; padding: 5px 0px;">
如果添加项为子项则需输入父项编码</p>
<p
style="
color: #f56c6c;
font-size: 12px;
width: 70%;
margin: auto;
margin-top: -15px;
padding: 5px 0px;
"
>
如果添加项为子项则需输入父项编码
</p>
<el-form-item label="备注">
<el-input v-model="dictInfoItem.custom1" :rows="5" type="textarea" style="width:100%"
placeholder="请输入备注"></el-input>
<el-input
v-model="dictInfoItem.custom1"
:rows="5"
type="textarea"
style="width: 100%"
placeholder="请输入备注"
></el-input>
</el-form-item>
</el-form>
<span class="dialog-footer" style="display: flex; display: -webkit-flex; justify-content: flex-end; -webkit-justify-content: flex-end;">
<el-button style="padding: 10px 15px;" @click="dictItemClose"> </el-button>
<el-button type="primary" style="padding: 10px 15px;" @click="dictItemSave(dictInfoRefItem)">确定</el-button>
<span
class="dialog-footer"
style="
display: flex;
display: -webkit-flex;
justify-content: flex-end;
-webkit-justify-content: flex-end;
"
>
<el-button style="padding: 10px 15px" @click="dictItemClose"> </el-button>
<el-button
type="primary"
style="padding: 10px 15px"
@click="dictItemSave(dictInfoRefItem)"
>确定</el-button
>
</span>
</el-dialog>
<!-- 字典弹框-->
<el-dialog v-model="dialogdict" :before-close="dictClose" :title="title" draggable width="620px">
<el-form ref="dictInfoRef" :model="dictInfo" label-width="90px" style="margin-top:10px" :rules="rules">
<el-dialog
v-model="dialogdict"
:before-close="dictClose"
:title="title"
draggable
width="620px"
>
<el-form
ref="dictInfoRef"
:model="dictInfo"
label-width="90px"
style="margin-top: 10px"
:rules="rules"
>
<el-form-item label="字典类型">
<el-input :value="dictInfo.dictType == '00' ? '系统配置' : '用户配置'" style="width:100%" :disabled="true"></el-input>
<el-input
:value="dictInfo.dictType == '00' ? '系统配置' : '用户配置'"
style="width: 100%"
:disabled="true"
></el-input>
</el-form-item>
<el-form-item label="字典编码" prop="dictCode">
<el-input v-model="dictInfo.dictCode" style="width:100%" placeholder="请输入字典编码"></el-input>
<el-input
v-model="dictInfo.dictCode"
style="width: 100%"
placeholder="请输入字典编码"
></el-input>
</el-form-item>
<el-form-item label="字典名称" prop="dictName">
<el-input v-model="dictInfo.dictName" style="width:100%" placeholder="请输入字典名称"></el-input>
<el-input
v-model="dictInfo.dictName"
style="width: 100%"
placeholder="请输入字典名称"
></el-input>
</el-form-item>
</el-form>
<span class="dialog-footer" style="display: flex;display: -webkit-flex; justify-content: flex-end;-webkit-justify-content: flex-end;">
<span
class="dialog-footer"
style="
display: flex;
display: -webkit-flex;
justify-content: flex-end;
-webkit-justify-content: flex-end;
"
>
<el-button @click="dictClose"> </el-button>
<el-button type="primary" @click="dictSave(dictInfoRef)">确定</el-button>
</span>
@ -535,6 +710,9 @@ const total = ref()
}
.faulttemplate-box {
position: relative;
z-index: 900;
pointer-events: all;
height: 100%;
display: flex;
background-color: #f2f4f9;

File diff suppressed because it is too large Load Diff

View File

@ -7,8 +7,8 @@ export default {
<script setup lang="ts">
import { onMounted, ref } from "vue";
import { getLogList, exportExcel } from "@/api/record";
import { downloadFile } from '@/utils/index';
import Page from '@/components/Pagination/page.vue'
import { downloadFile } from "@/utils/index";
import Page from "@/components/Pagination/page.vue";
// import { VueDevToolsTimelineColors } from "@intlify/vue-devtools";
//
@ -18,7 +18,7 @@ const tableData: any = ref([]);
const queryParams = ref({
current: 1,
size: 20,
opttype: ''
opttype: "",
});
//
const operationTime: any = ref();
@ -26,39 +26,41 @@ const operationTime: any = ref();
const total = ref(0);
//
const type: any = ref([
{ name: '登录(login)', value: '00' },
{ name: '添加(insert)', value: '01' },
{ name: '修改(update)', value: '02' },
{ name: '删除(delete)', value: '03' },
{ name: '查询(select)', value: '04' },
{ name: '其他(other)', value: '05' }
{ name: "登录(login)", value: "00" },
{ name: "添加(insert)", value: "01" },
{ name: "修改(update)", value: "02" },
{ name: "删除(delete)", value: "03" },
{ name: "查询(select)", value: "04" },
{ name: "其他(other)", value: "05" },
]);
//
const loading = ref(false)
const loading = ref(false);
//
const LogDetails = ref(false)
const LogDetails = ref(false);
//
function init() {
let params = {
optType: queryParams.value.opttype,
current: queryParams.value.current,
size: queryParams.value.size,
startDate: '',
endDate: ''
startDate: "",
endDate: "",
};
if (operationTime.value != null) {
params.startDate = operationTime.value[0];
params.endDate = operationTime.value[1];
}
loading.value = true;
getLogList(params).then((result: any) => {
getLogList(params)
.then((result: any) => {
tableData.value = result.data.list;
total.value = result.data.total;
queryParams.value.size = result.data.size
pcode.value = result.data.size
queryParams.value.current = result.data.current
queryParams.value.size = result.data.size;
pcode.value = result.data.size;
queryParams.value.current = result.data.current;
loading.value = false;
}).catch(() => {
})
.catch(() => {
loading.value = false;
});
}
@ -86,78 +88,141 @@ function leadingOut() {
optType: queryParams.value.opttype,
current: queryParams.value.current,
size: queryParams.value.size,
startDate: '',
endDate: ''
startDate: "",
endDate: "",
};
if (operationTime.value != null) {
params.startDate = operationTime.value[0];
params.endDate = operationTime.value[1];
}
exportExcel(params).then((response: any) => {
downloadFile(response, '日志', 'xlsx')
downloadFile(response, "日志", "xlsx");
});
}
//
const pcode = ref(20)
const pcode = ref(20);
onMounted(() => {
init();
});
//
const Logdata:any = ref([])
function Loglist(row:any){
console.log(row)
Logdata.value.push(row)
if(Logdata.value.length == 2){
Logdata.value.shift()
const Logdata: any = ref([]);
function Loglist(row: any) {
console.log(row);
Logdata.value.push(row);
if (Logdata.value.length == 2) {
Logdata.value.shift();
}
console.log(Logdata.value)
LogDetails.value = true
console.log(Logdata.value);
LogDetails.value = true;
}
function handleClose(){
LogDetails.value = false
function handleClose() {
LogDetails.value = false;
}
</script>
<template>
<div>
<div class="record-box">
<div
style="margin-bottom: 10px;display: flex; display: -webkit-flex; align-items: center; -webkit-align-items: center;">
<el-select v-model="queryParams.opttype" placeholder="日志类型" clearable @change="init"
style="width: 220px;margin-right:10px;">
<el-option v-for="item in type" :key="item.value" :label="item.name" :value="item.name" />
style="
margin-bottom: 10px;
display: flex;
display: -webkit-flex;
align-items: center;
-webkit-align-items: center;
"
>
<el-select
v-model="queryParams.opttype"
placeholder="日志类型"
clearable
@change="init"
style="width: 220px; margin-right: 10px"
>
<el-option
v-for="item in type"
:key="item.value"
:label="item.name"
:value="item.name"
/>
</el-select>
<div style="width: 350px;">
<el-date-picker v-model="operationTime" value-format="YYYY-MM-DD" start-placeholder="操作开始时间"
end-placeholder="操作结束时间" type="daterange" @change="init" />
<div style="width: 350px">
<el-date-picker
v-model="operationTime"
value-format="YYYY-MM-DD"
start-placeholder="操作开始时间"
end-placeholder="操作结束时间"
type="daterange"
@change="init"
/>
</div>
<el-button type="primary" style="margin-left: 10px" @click="init">搜索</el-button>
<div
style="width: 100%; display:flex; display: -webkit-flex; justify-content: flex-end; -webkit-justify-content: flex-end;">
<el-button type="primary" @click="leadingOut"><img src="@/assets/MenuIcon/jscz_scdc.png" alt=""
style="margin-right: 5px;">导出</el-button>
style="
width: 100%;
display: flex;
display: -webkit-flex;
justify-content: flex-end;
-webkit-justify-content: flex-end;
"
>
<el-button type="primary" @click="leadingOut"
><img
src="@/assets/MenuIcon/jscz_scdc.png"
alt=""
style="margin-right: 5px"
/></el-button
>
</div>
</div>
<el-table v-loading="loading" :data="tableData"
style="width: 100%; height: calc(100vh - 266px);margin-bottom: 20px;" border
:header-cell-style="{ background: 'rgb(250 250 250)', height: '50px' }">
<el-table-column type="index" label="序号" width="70" align="center"></el-table-column>
<el-table
v-loading="loading"
:data="tableData"
style="width: 100%; height: calc(100vh - 266px); margin-bottom: 20px"
border
:header-cell-style="{ background: 'rgb(250 250 250)', height: '50px' }"
>
<el-table-column
type="index"
label="序号"
width="70"
align="center"
></el-table-column>
<el-table-column prop="usercode" label="操作账户" width="100"></el-table-column>
<el-table-column prop="username" label="用户姓名" width="180"></el-table-column>
<el-table-column prop="requestip" label="IP地址" width="140"></el-table-column>
<el-table-column prop="browser" label="浏览器" width="130"></el-table-column>
<el-table-column prop="opttype" label="日志类型" width="130" align="center"></el-table-column>
<el-table-column
prop="opttype"
label="日志类型"
width="130"
align="center"
></el-table-column>
<el-table-column prop="module" label="模块名称" width="170"></el-table-column>
<el-table-column prop="description" label="日志描述" min-width="100">
<template #default="scope">
<div style="display: flex;display: -webkit-flex;justify-content: space-between; align-items: center;-webkit-justify-content: space-between; -webkit-align-items: center;">
<div
style="
display: flex;
display: -webkit-flex;
justify-content: space-between;
align-items: center;
-webkit-justify-content: space-between;
-webkit-align-items: center;
"
>
<div>{{ scope.row.description }}</div>
<div><img src="@/assets/MenuIcon/xqing.png" alt="" style="cursor: pointer;" title="详情" @click="Loglist(scope.row)" ></div>
<div>
<img
src="@/assets/MenuIcon/xqing.png"
alt=""
style="cursor: pointer"
title="详情"
@click="Loglist(scope.row)"
/>
</div>
</div>
</template>
</el-table-column>
@ -167,17 +232,43 @@ function handleClose(){
</template>
</el-table-column>
</el-table>
<Page :total="total" v-model:size="queryParams.size" v-model:current="queryParams.current" @pagination="init()">
<Page
:total="total"
v-model:size="queryParams.size"
v-model:current="queryParams.current"
@pagination="init()"
>
</Page>
</div>
<el-dialog title="日志详情" v-model="LogDetails" width="90%" :before-close="handleClose" top="30px" draggable :destroy-on-close="false">
<el-table v-loading="loading" :data="Logdata"
style="width: 100%; height: calc(50vh - 266px);margin-bottom: 20px;" border
:header-cell-style="{ background: 'rgb(250 250 250)', height: '50px' }">
<el-table-column type="index" label="序号" width="70" align="center"></el-table-column>
<el-dialog
title="日志详情"
v-model="LogDetails"
width="90%"
:before-close="handleClose"
top="30px"
draggable
:destroy-on-close="false"
>
<el-table
v-loading="loading"
:data="Logdata"
style="width: 100%; height: calc(50vh - 266px); margin-bottom: 20px"
border
:header-cell-style="{ background: 'rgb(250 250 250)', height: '50px' }"
>
<el-table-column
type="index"
label="序号"
width="70"
align="center"
></el-table-column>
<el-table-column prop="username" label="用户姓名" width="110"></el-table-column>
<el-table-column prop="module" label="模块名称" width="120"></el-table-column>
<el-table-column prop="description" label="日志描述" width="240"></el-table-column>
<el-table-column
prop="description"
label="日志描述"
width="240"
></el-table-column>
<el-table-column prop="method" label="方法"></el-table-column>
<el-table-column prop="params" label="参数"></el-table-column>
</el-table>
@ -185,8 +276,11 @@ function handleClose(){
</div>
</template>
<style scoped >
<style scoped>
.record-box {
position: relative;
z-index: 900;
pointer-events: all;
padding: 20px;
width: 100%;
height: calc(100vh - 130px);

View File

@ -1433,6 +1433,9 @@ function handleClearSelection() {
}
.faulttemplate-box {
position: relative;
z-index: 900;
pointer-events: all;
height: 100%;
display: flex;
display: -webkit-flex;

View File

@ -7,24 +7,36 @@ export default {
<script setup lang="ts">
import { onMounted, ref, nextTick } from "vue";
import { ElForm, ElMessage, ElMessageBox } from "element-plus";
import { listRolePages, isvaildTo, addDept, renewDept, deleDept, assignmentPer, setMenuById, setOrgscope, postOrgscope } from "@/api/role";
import {
listRolePages,
isvaildTo,
addDept,
renewDept,
deleDept,
assignmentPer,
setMenuById,
setOrgscope,
postOrgscope,
} from "@/api/role";
//
const tableData: any = ref([]);
const multipleSelection = ref([]);
//
const tree = ref()
const tree = ref();
//
const loading = ref(false)
const loading = ref(false);
function gettableData() {
let params = {
rolename: input.value,
};
loading.value = true;
listRolePages(params).then((result) => {
listRolePages(params)
.then((result) => {
tableData.value = result;
loading.value = false;
}).catch(() => {
})
.catch(() => {
loading.value = false;
});
}
@ -33,11 +45,11 @@ function handleSelectionChange(val: any) {
multipleSelection.value = val;
}
function switchChange(row: any) {
const elMessage = ref()
if (row.isvaild == '0') {
elMessage.value = "确定设置该角色为无效吗?"
} else if (row.isvaild == '1') {
elMessage.value = "确定设置该角色为有效吗?"
const elMessage = ref();
if (row.isvaild == "0") {
elMessage.value = "确定设置该角色为无效吗?";
} else if (row.isvaild == "1") {
elMessage.value = "确定设置该角色为有效吗?";
}
ElMessageBox.confirm(elMessage.value, "提示信息", {
confirmButtonText: "确定",
@ -99,7 +111,6 @@ function addClick() {
function confirmClick(formEl: any) {
formEl.validate((valid: any) => {
if (valid) {
if (!info.value.id) {
const params = {
rolename: info.value.rolename,
@ -133,8 +144,8 @@ function handleClose() {
dialogVisible.value = false;
businessVisible.value = false;
organizeVisible.value = false;
accessVisible.value = false
businessVisible.value = false
accessVisible.value = false;
businessVisible.value = false;
if (infoForm.value != null) infoForm.value.resetFields();
}
//-rules
@ -155,8 +166,7 @@ function businessclick() {
ElMessageBox.confirm("此模块允许用户进行定制。", "提示信息", {
confirmButtonText: "确定",
type: "warning",
})
.then(() => {
}).then(() => {
businessVisible.value = false;
});
}
@ -167,55 +177,54 @@ function businessclick() {
// }
//
const organizeVisible = ref(false);
const deptdata = ref()
const roleIda = ref('')
const deptdata = ref();
const roleIda = ref("");
function organizeclick(row: any) {
organizeVisible.value = true;
roleIda.value = row.id
roleIda.value = row.id;
const params = {
roleId: row.id
}
roleId: row.id,
};
setOrgscope(params).then((res) => {
deptdata.value = res
})
deptdata.value = res;
});
}
function accessCheckAllChange(indexone: any) {
const Arrayall: any = ref([])
const Arrayall: any = ref([]);
for (var j = 0; j < deptdata.value[indexone].children.length; j++) {
Arrayall.value.push(deptdata.value[indexone].children[j].orgname)
Arrayall.value.push(deptdata.value[indexone].children[j].orgname);
}
deptdata.value[indexone].array = deptdata.value[indexone].checkinfo ? Arrayall : []
deptdata.value[indexone].bool = false
deptdata.value[indexone].array = deptdata.value[indexone].checkinfo ? Arrayall : [];
deptdata.value[indexone].bool = false;
}
function accessCheckedCitiesChanges(indexone: any) {
const checkedCount = deptdata.value[indexone].array.length
const cities = deptdata.value[indexone].children.length
deptdata.value[indexone].checkinfo = checkedCount === cities
deptdata.value[indexone].bool = checkedCount > 0 && checkedCount < cities
const checkedCount = deptdata.value[indexone].array.length;
const cities = deptdata.value[indexone].children.length;
deptdata.value[indexone].checkinfo = checkedCount === cities;
deptdata.value[indexone].bool = checkedCount > 0 && checkedCount < cities;
}
function organizesubmit() {
const allid: any = ref([])
const allid: any = ref([]);
deptdata.value.forEach((item: any) => {
item.children.forEach((element: any) => {
item.array.forEach((res: any) => {
if (res == element.orgname) {
allid.value.push(element.id)
allid.value.push(element.id);
}
})
})
})
});
});
});
const params = {
id: roleIda.value,
orgscope: allid.value.toString()
}
orgscope: allid.value.toString(),
};
postOrgscope(params).then(() => {
ElMessage({
type: "success",
message: "组织范围修改成功",
});
organizeVisible.value = false
})
organizeVisible.value = false;
});
}
//
function delrole(row: any) {
@ -223,8 +232,7 @@ function delrole(row: any) {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
}).then(() => {
let params = {
id: row.id,
};
@ -235,67 +243,65 @@ function delrole(row: any) {
message: "删除成功",
});
});
})
});
}
//
const accessVisible: any = ref()
const accessdata: any = ref([])
const accessVisible: any = ref();
const accessdata: any = ref([]);
//key
const DefaultDeployment: any = ref([])
const DefaultDeployment: any = ref([]);
//id
const Passparameter: any = ref([])
const Passparameter: any = ref([]);
const defaultProps = {
children: 'children',
label: 'name',
}
const rowid = ref()
children: "children",
label: "name",
};
const rowid = ref();
function menuChange(data: any, ids: any) {
data.forEach((item: any) => {
if (item.checkinfo == true) {
ids.push(item.id)
DefaultDeployment.value.push(item.id)
ids.push(item.id);
DefaultDeployment.value.push(item.id);
}
if (item.children) {
menuChange(item.children, ids)
menuChange(item.children, ids);
}
})
});
}
function assignment(row: any) {
rowid.value = row.id
accessVisible.value = true
rowid.value = row.id;
accessVisible.value = true;
const params = {
roleId: rowid.value
}
roleId: rowid.value,
};
assignmentPer(params).then((res: any) => {
accessdata.value = res
let ids: any = []
menuChange(res, ids)
accessdata.value = res;
let ids: any = [];
menuChange(res, ids);
nextTick(() => {
tree.value.setCheckedKeys(ids)
})
})
tree.value.setCheckedKeys(ids);
});
});
}
//
function currentChecked(_nodeObj: any, SelectedObj: any) {
Passparameter.value = SelectedObj.checkedKeys.concat(SelectedObj.halfCheckedKeys)
Passparameter.value = SelectedObj.checkedKeys.concat(SelectedObj.halfCheckedKeys);
}
// --
function accesssubmit() {
const parans = {
id: rowid.value,
menuIds: Passparameter.value.toString()
}
menuIds: Passparameter.value.toString(),
};
setMenuById(parans).then(() => {
accessVisible.value = false
gettableData()
accessVisible.value = false;
gettableData();
ElMessage({
type: "success",
message: "修改成功",
});
})
});
}
//
function delClick() {
@ -306,10 +312,10 @@ function delClick() {
}).then(() => {
let id = [] as any[];
multipleSelection.value.forEach((item: any) => {
id.push(item.id)
})
id.push(item.id);
});
let params = {
id: id.join(','),
id: id.join(","),
};
deleDept(params).then(() => {
gettableData();
@ -346,24 +352,55 @@ onMounted(() => {
<div class="invalidcatalogue-box">
<div class="conductproject-bg-box">
<div
style="display: flex;display: -webkit-flex; justify-content: space-between; -webkit-justify-content: space-between;margin-bottom: 10px">
<div style="display: flex;display: -webkit-flex;">
<el-input v-model="input" placeholder="请输入角色名称" @keyup.enter="gettableData" style="width: 200px" clearable />
<el-button type="primary" style="margin-left: 10px" @click="gettableData">搜索</el-button>
style="
display: flex;
display: -webkit-flex;
justify-content: space-between;
-webkit-justify-content: space-between;
margin-bottom: 10px;
"
>
<div style="display: flex; display: -webkit-flex">
<el-input
v-model="input"
placeholder="请输入角色名称"
@keyup.enter="gettableData"
style="width: 200px"
clearable
/>
<el-button type="primary" style="margin-left: 10px" @click="gettableData"
>搜索</el-button
>
</div>
<div>
<el-button v-hasPerm="['add:role']" type="primary" @click="addClick">
<img src="@/assets/MenuIcon/jscz_xz.png" alt="" style="margin-right: 3px">
新增</el-button>
<el-button v-hasPerm="['del:role']" :type="multipleSelection.length > 0 ? 'primary' : ''"
:disabled="multipleSelection.length <= 0" @click="delClick"><el-icon>
<img src="@/assets/MenuIcon/jscz_xz.png" alt="" style="margin-right: 3px" />
新增</el-button
>
<el-button
v-hasPerm="['del:role']"
:type="multipleSelection.length > 0 ? 'primary' : ''"
:disabled="multipleSelection.length <= 0"
@click="delClick"
><el-icon>
<Delete />
</el-icon> </el-button>
</el-icon>
删除</el-button
>
</div>
</div>
<el-table v-loading="loading" :data="tableData" style="width: 100%; height: calc(100vh - 220px)" border
<el-table
v-loading="loading"
:data="tableData"
style="width: 100%; height: calc(100vh - 220px)"
border
@selection-change="handleSelectionChange"
:header-cell-style="{ background: 'rgb(250 250 250)', color: '#383838', height: '50px' }">
:header-cell-style="{
background: 'rgb(250 250 250)',
color: '#383838',
height: '50px',
}"
>
<el-table-column type="selection" width="50" align="center"></el-table-column>
<el-table-column prop="rolecode" label="角色编号" width="100"></el-table-column>
<el-table-column prop="rolename" label="角色名称" width="180"></el-table-column>
@ -374,16 +411,29 @@ onMounted(() => {
<span v-show="scope.row.level == '3'">一般用户</span>
</template>
</el-table-column>
<el-table-column prop="description" label="角色描述" min-width="100"></el-table-column>
<el-table-column
prop="description"
label="角色描述"
min-width="100"
></el-table-column>
<el-table-column prop="isvaild" label="是否有效" align="center" width="120">
<template #default="scope">
<el-switch v-model="scope.row.isvaild" @change="switchChange(scope.row)" style="margin-right: 4px"
active-value="1" inactive-value="0"></el-switch>
<el-switch
v-model="scope.row.isvaild"
@change="switchChange(scope.row)"
style="margin-right: 4px"
active-value="1"
inactive-value="0"
></el-switch>
<span v-if="scope.row.isvaild == 1" style="color: #0099ff">有效</span>
<span v-else style="color: #d7d7d7">无效</span>
</template>
</el-table-column>
<el-table-column prop="lastmodifier" label="最近修改者" width="120"></el-table-column>
<el-table-column
prop="lastmodifier"
label="最近修改者"
width="120"
></el-table-column>
<el-table-column prop="lastmodifydate" label="最近修改日期" width="200">
<template #default="scope">
{{ dateFormat(scope.row.lastmodifydate) }}
@ -392,71 +442,199 @@ onMounted(() => {
<el-table-column fixed="right" label="操作" width="200">
<template #default="scope">
<span
style="display: flex;display: -webkit-flex; justify-content: space-around;-webkit-justify-content: space-around; ">
<img v-hasPerm="['update:role']" src="@/assets/MenuIcon/lbcz_xg.png" alt="" title="修改"
@click="editrole(scope.row)" style="cursor: pointer; ">
<img src="@/assets/MenuIcon/lbcz_zyw.png" alt="" title="业务范围" @click="businessclick"
style="cursor: pointer;">
<img src="@/assets/MenuIcon/u343.png" alt="" title="组织范围" @click="organizeclick(scope.row)"
style="cursor: pointer; ">
<img src="@/assets/MenuIcon/lbcz_qx.png" alt="" title="权限分配" @click="assignment(scope.row)"
style="cursor: pointer; ">
<img v-hasPerm="['del:role']" src="@/assets/MenuIcon/lbcz_sc.png" alt="" title="删除"
@click="delrole(scope.row)" style="cursor: pointer; ">
style="
display: flex;
display: -webkit-flex;
justify-content: space-around;
-webkit-justify-content: space-around;
"
>
<img
v-hasPerm="['update:role']"
src="@/assets/MenuIcon/lbcz_xg.png"
alt=""
title="修改"
@click="editrole(scope.row)"
style="cursor: pointer"
/>
<img
src="@/assets/MenuIcon/lbcz_zyw.png"
alt=""
title="业务范围"
@click="businessclick"
style="cursor: pointer"
/>
<img
src="@/assets/MenuIcon/u343.png"
alt=""
title="组织范围"
@click="organizeclick(scope.row)"
style="cursor: pointer"
/>
<img
src="@/assets/MenuIcon/lbcz_qx.png"
alt=""
title="权限分配"
@click="assignment(scope.row)"
style="cursor: pointer"
/>
<img
v-hasPerm="['del:role']"
src="@/assets/MenuIcon/lbcz_sc.png"
alt=""
title="删除"
@click="delrole(scope.row)"
style="cursor: pointer"
/>
</span>
</template>
</el-table-column>
</el-table>
</div>
<el-dialog v-model="dialogVisible" :close-on-click-modal="false" draggable :before-close="handleClose" :title="title"
append-to-body width="620px" height="600px">
<el-dialog
v-model="dialogVisible"
:close-on-click-modal="false"
draggable
:before-close="handleClose"
:title="title"
append-to-body
width="620px"
height="600px"
>
<el-form ref="infoForm" :model="info" :rules="rules" label-width="110px">
<el-form-item label="角色名称:" prop="rolename">
<el-input v-model="info.rolename" style="width: 100%" placeholder="请输入角色名称"></el-input>
<el-input
v-model="info.rolename"
style="width: 100%"
placeholder="请输入角色名称"
></el-input>
</el-form-item>
<el-form-item label="角色级别:" prop="level">
<el-select v-model="info.level" placeholder=" " style="width: 100%">
<el-option v-for="item in faultList" :key="item.value" :label="item.label" :value="item.value" />
<el-option
v-for="item in faultList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="角色描述:">
<el-input v-model="info.description" style="width: 100%" placeholder="请输入角色描述"></el-input>
<el-input
v-model="info.description"
style="width: 100%"
placeholder="请输入角色描述"
></el-input>
</el-form-item>
<span class="dialog-footer"
style="display: flex;display: -webkit-flex; justify-content: flex-end;-webkit-justify-content: flex-end;">
<span
class="dialog-footer"
style="
display: flex;
display: -webkit-flex;
justify-content: flex-end;
-webkit-justify-content: flex-end;
"
>
<el-button @click="handleClose"> </el-button>
<el-button type="primary" @click="confirmClick(infoForm)"> </el-button>
</span>
</el-form>
</el-dialog>
<el-dialog title="组织范围" v-model="organizeVisible" width="60%" draggable :before-close="handleClose">
<div v-for="(item, indexone) in deptdata" :label="item.name" :key="item.id" style="width:90%;margin:auto">
<div style=" font-size: 15px; font-weight: 700; display: inline-block; margin: 8px 0px;">{{ item.orgname }}</div>
<div style="display: flex; display: -webkit-flex;align-items: center;-webkit-align-items: center;">
<el-dialog
title="组织范围"
v-model="organizeVisible"
width="60%"
draggable
:before-close="handleClose"
>
<div
v-for="(item, indexone) in deptdata"
:label="item.name"
:key="item.id"
style="width: 90%; margin: auto"
>
<div
style="
font-size: 15px;
font-weight: 700;
display: inline-block;
margin: 8px 0px;
"
>
{{ item.orgname }}
</div>
<div
style="
display: flex;
display: -webkit-flex;
align-items: center;
-webkit-align-items: center;
"
>
<div>部门选择</div>
<div style="display: flex; display: -webkit-flex;margin-left: 60px;">
<el-checkbox v-model="item.checkinfo" :indeterminate="item.bool"
@change="accessCheckAllChange(indexone)">全选</el-checkbox>
<el-checkbox-group v-model="item.array" @change="accessCheckedCitiesChanges(indexone)"
style="margin-left:20px">
<el-checkbox v-for="k in item.children" :key="k.id" :label="k.orgname">{{ k.orgname }}</el-checkbox>
<div style="display: flex; display: -webkit-flex; margin-left: 60px">
<el-checkbox
v-model="item.checkinfo"
:indeterminate="item.bool"
@change="accessCheckAllChange(indexone)"
>全选</el-checkbox
>
<el-checkbox-group
v-model="item.array"
@change="accessCheckedCitiesChanges(indexone)"
style="margin-left: 20px"
>
<el-checkbox v-for="k in item.children" :key="k.id" :label="k.orgname">{{
k.orgname
}}</el-checkbox>
</el-checkbox-group>
</div>
</div>
<div class="line"></div>
</div>
<span class="dialog-footer"
style="display: flex; display: -webkit-flex;; justify-content: flex-end;-webkit-justify-content: flex-end;">
<span
class="dialog-footer"
style="
display: flex;
display: -webkit-flex;
justify-content: flex-end;
-webkit-justify-content: flex-end;
"
>
<el-button @click="organizeVisible = false"> </el-button>
<el-button type="primary" @click="organizesubmit"> </el-button>
</span>
</el-dialog>
<el-dialog title="权限分配" v-model="accessVisible" width="500px" :before-close="handleClose" :destroy-on-close="false" draggable style="max-height: 640px;" >
<el-tree ref="tree" style="max-height: 400px;overflow:auto" :data="accessdata" show-checkbox node-key="id" accordion
:default-expanded-keys="DefaultDeployment" :props="defaultProps" @check="currentChecked" />
<span class="dialog-footer"
style="display: flex;display: -webkit-flex; justify-content: flex-end;-webkit-justify-content: flex-end;">
<el-dialog
title="权限分配"
v-model="accessVisible"
width="500px"
:before-close="handleClose"
:destroy-on-close="false"
draggable
style="max-height: 640px"
>
<el-tree
ref="tree"
style="max-height: 400px; overflow: auto"
:data="accessdata"
show-checkbox
node-key="id"
accordion
:default-expanded-keys="DefaultDeployment"
:props="defaultProps"
@check="currentChecked"
/>
<span
class="dialog-footer"
style="
display: flex;
display: -webkit-flex;
justify-content: flex-end;
-webkit-justify-content: flex-end;
"
>
<el-button @click="accessVisible = false"> </el-button>
<el-button type="primary" @click="accesssubmit"> </el-button>
</span>
@ -466,6 +644,9 @@ onMounted(() => {
<style scoped>
.invalidcatalogue-box {
position: relative;
z-index: 900;
pointer-events: all;
padding-right: 10px;
}

File diff suppressed because it is too large Load Diff