完成初版
This commit is contained in:
149
assetsMap/boundary-doc.md
Normal file
149
assetsMap/boundary-doc.md
Normal file
@@ -0,0 +1,149 @@
|
||||
# 资产边界数据配置说明
|
||||
|
||||
## 数据格式
|
||||
|
||||
边界数据存储在表单字段 **"资产边界数据"** 中,格式为 JSON 字符串。
|
||||
|
||||
## 整体结构
|
||||
|
||||
```json
|
||||
{
|
||||
"regions": [ 区域1, 区域2, ... ],
|
||||
"color": "#ff0000"
|
||||
}
|
||||
```
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `regions` | 数组 | 区域列表,每个区域是一个独立的外圈(可带孔洞) |
|
||||
| `color` | 字符串 | 边界颜色,十六进制色值,如 `#ff0000`(红色)、`#3498db`(蓝色) |
|
||||
|
||||
## 单个区域结构
|
||||
|
||||
```json
|
||||
{
|
||||
"id": 1780905134732976,
|
||||
"outer": [ 坐标点1, 坐标点2, ... ],
|
||||
"holes": [ 孔洞1, 孔洞2, ... ]
|
||||
}
|
||||
```
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `id` | 数字 | 区域唯一标识(系统自动生成的随机整数),手动配置时可随意填一个不重复的数字 |
|
||||
| `outer` | 数组 | 外圈边界坐标,至少 3 个点 |
|
||||
| `holes` | 数组 | 孔洞列表,每个孔洞也是一个坐标数组(至少 3 个点),可为空数组 `[]` |
|
||||
|
||||
## 坐标格式
|
||||
|
||||
每个坐标点为 **`[纬度, 经度]`**,注意顺序是 **纬度在前,经度在后**。
|
||||
|
||||
示例:`[30.68239, 111.31176]`
|
||||
|
||||
## 配置示例
|
||||
|
||||
### 1. 单个简单区域(无孔洞)
|
||||
|
||||
```json
|
||||
{
|
||||
"regions": [
|
||||
{
|
||||
"id": 100001,
|
||||
"outer": [
|
||||
[30.68, 111.31],
|
||||
[30.69, 111.38],
|
||||
[30.74, 111.38],
|
||||
[30.74, 111.34],
|
||||
[30.74, 111.30],
|
||||
[30.71, 111.28]
|
||||
],
|
||||
"holes": []
|
||||
}
|
||||
],
|
||||
"color": "#ff0000"
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 单个区域带一个孔洞
|
||||
|
||||
```json
|
||||
{
|
||||
"regions": [
|
||||
{
|
||||
"id": 100002,
|
||||
"outer": [
|
||||
[30.68, 111.31],
|
||||
[30.69, 111.38],
|
||||
[30.74, 111.38],
|
||||
[30.74, 111.30],
|
||||
[30.71, 111.28]
|
||||
],
|
||||
"holes": [
|
||||
[
|
||||
[30.70, 111.33],
|
||||
[30.72, 111.37],
|
||||
[30.73, 111.35],
|
||||
[30.72, 111.32]
|
||||
]
|
||||
]
|
||||
}
|
||||
],
|
||||
"color": "#ff0000"
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 多个独立区域
|
||||
|
||||
```json
|
||||
{
|
||||
"regions": [
|
||||
{
|
||||
"id": 100003,
|
||||
"outer": [
|
||||
[30.68, 111.31],
|
||||
[30.69, 111.38],
|
||||
[30.74, 111.38],
|
||||
[30.71, 111.28]
|
||||
],
|
||||
"holes": []
|
||||
},
|
||||
{
|
||||
"id": 100004,
|
||||
"outer": [
|
||||
[30.68, 111.43],
|
||||
[30.67, 111.50],
|
||||
[30.74, 111.52],
|
||||
[30.75, 111.44],
|
||||
[30.71, 111.39]
|
||||
],
|
||||
"holes": [
|
||||
[
|
||||
[30.69, 111.45],
|
||||
[30.72, 111.50],
|
||||
[30.74, 111.48],
|
||||
[30.72, 111.41]
|
||||
]
|
||||
]
|
||||
}
|
||||
],
|
||||
"color": "#ff0000"
|
||||
}
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **坐标顺序**:必须是 `[纬度, 经度]`,即 `[lat, lng]`
|
||||
2. **最少点数**:每个外圈和孔洞至少需要 **3 个坐标点**
|
||||
3. **孔洞范围**:孔洞必须完全位于其所属外圈内部
|
||||
4. **区域 ID**:`id` 为任意不重复的数字,建议使用时间戳+随机数
|
||||
5. **颜色值**:支持标准十六进制格式,如 `#ff0000`、`#3498db`、`#27ae60`
|
||||
6. **多区域共用一个颜色**:所有区域使用同一个 `color` 值
|
||||
7. **字段名称**:存储在表单字段 **"资产边界数据"** 中
|
||||
|
||||
## 坐标获取方式
|
||||
|
||||
推荐使用坐标拾取工具获取经纬度:
|
||||
- **高德坐标拾取器**:https://lbs.amap.com/tools/picker
|
||||
- **百度坐标拾取器**:https://api.map.baidu.com/lbsapi/getpoint/index.html
|
||||
|
||||
在地图上依次点击区域顶点,复制坐标填入即可。
|
||||
1420
assetsMap/map.html
1420
assetsMap/map.html
File diff suppressed because it is too large
Load Diff
1069
assetsMap/mapbak.html
Normal file
1069
assetsMap/mapbak.html
Normal file
File diff suppressed because it is too large
Load Diff
BIN
assetsMap/markicon.png
Normal file
BIN
assetsMap/markicon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
@@ -4,4 +4,7 @@
|
||||
<bean id="assetsMapPlugin" class="com.seeyon.apps.assetsmap.AssetsMapPlugin"/>
|
||||
<bean id="assetsMapConfigProvider" class="com.seeyon.apps.assetsmap.config.AssetsMapConfigProvider"/>
|
||||
<bean id="assetsQueryService" class="com.seeyon.apps.assetsmap.service.AssetsQueryService"/>
|
||||
<bean id="goMapFieldCtrl" class="com.seeyon.apps.assetsmap.fieldCtrl.GoMapFieldCtrl"/>
|
||||
<bean id="boundConfigFieldCtrl" class="com.seeyon.apps.assetsmap.fieldCtrl.BoundConfigFieldCtrl"/>
|
||||
<bean id="locationFieldCtrl" class="com.seeyon.apps.assetsmap.fieldCtrl.LocationFieldCtrl"/>
|
||||
</beans>
|
||||
@@ -0,0 +1,36 @@
|
||||
.customButton_class_box {
|
||||
width: 35%;
|
||||
line-height: 24px;
|
||||
height:24px;
|
||||
color: #1f85ec;
|
||||
cursor: pointer;
|
||||
font-family: "Microsoft YaHei"!important;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
word-break:keep-all;
|
||||
box-sizing: border-box;
|
||||
-webkit-box-sizing : border-box;
|
||||
-moz-box-sizing : border-box;
|
||||
text-align: center;
|
||||
outline: none;
|
||||
border: 1px solid #1f85ec;
|
||||
background-color: #fff;
|
||||
border-radius: 15px;
|
||||
-webkit-border-radius: 15px;
|
||||
-moz-border-radius: 15px;
|
||||
}
|
||||
.customInputArea{
|
||||
width: 65%;
|
||||
height:auto;
|
||||
color: #1f85ec;
|
||||
font-family: "Microsoft YaHei"!important;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
word-break:keep-all;
|
||||
}
|
||||
.customButton_box_content{
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 101 KiB |
@@ -0,0 +1,498 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<title>配置资产边界</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet-draw@1.0.4/dist/leaflet.draw.css" />
|
||||
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
|
||||
<script src="https://unpkg.com/leaflet-draw@1.0.4/dist/leaflet.draw.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
|
||||
<style>
|
||||
* { margin:0; padding:0; box-sizing:border-box; }
|
||||
html, body { height:100%; overflow:hidden; font-family:"Microsoft YaHei",Arial,sans-serif; }
|
||||
#app { display:flex; height:100%; }
|
||||
|
||||
/* 左侧地图 */
|
||||
#mapWrap { flex:1; position:relative; min-width:0; }
|
||||
#map { height:100%; width:100%; }
|
||||
|
||||
/* 右侧配置面板 */
|
||||
#configPanel {
|
||||
width:360px; height:100%; background:#fff;
|
||||
border-left:1px solid #e0e0e0; display:flex; flex-direction:column;
|
||||
flex-shrink:0; z-index:10000;
|
||||
}
|
||||
.panel-header {
|
||||
padding:12px 16px; background:#f7f8fa; border-bottom:1px solid #eee;
|
||||
font-size:14px; font-weight:bold; color:#333; flex-shrink:0;
|
||||
}
|
||||
.panel-body {
|
||||
flex:1; overflow-y:auto; padding:12px 16px;
|
||||
}
|
||||
.panel-footer {
|
||||
padding:10px 16px; border-top:1px solid #eee; display:flex; gap:8px; flex-shrink:0;
|
||||
}
|
||||
|
||||
/* 基本设置 */
|
||||
.setting-row {
|
||||
display:flex; align-items:center; gap:8px; margin-bottom:10px;
|
||||
}
|
||||
.setting-row label { font-size:12px; color:#888; white-space:nowrap; }
|
||||
.setting-row input[type="color"] { width:36px; height:30px; border:1px solid #ddd; border-radius:4px; cursor:pointer; }
|
||||
.setting-row span { font-size:12px; color:#888; }
|
||||
|
||||
/* 区域卡片 */
|
||||
.region-card {
|
||||
border:1px solid #e0e0e0; border-radius:6px; padding:10px 12px;
|
||||
margin-bottom:8px; background:#fafafa; cursor:pointer;
|
||||
}
|
||||
.region-card:hover { border-color:#27ae60; }
|
||||
.region-card.selected { border-color:#27ae60; background:#e8f5e9; }
|
||||
.region-header {
|
||||
display:flex; justify-content:space-between; align-items:center; margin-bottom:6px;
|
||||
}
|
||||
.region-header span { font-size:13px; font-weight:bold; color:#333; }
|
||||
.region-header .del-btn { color:#e74c3c; cursor:pointer; font-size:16px; padding:0 4px; }
|
||||
.region-info { font-size:12px; color:#888; }
|
||||
.hole-info { font-size:11px; color:#e74c3c; margin-top:4px; padding-left:10px; border-left:2px solid #e74c3c; }
|
||||
|
||||
/* 按钮 */
|
||||
.btn {
|
||||
flex:1; padding:9px 0; border:none; border-radius:6px;
|
||||
cursor:pointer; font-size:13px; font-weight:bold; transition:all 0.2s;
|
||||
}
|
||||
.btn-primary { background:#27ae60; color:#fff; }
|
||||
.btn-primary:hover { background:#219653; }
|
||||
.btn-success { background:#3498db; color:#fff; }
|
||||
.btn-reset { background:#f0f0f0; color:#666; border:1px solid #ddd; }
|
||||
.btn-danger { background:#e74c3c; color:#fff; }
|
||||
|
||||
.tip { font-size:11px; color:#999; margin-top:4px; }
|
||||
|
||||
/* 移动端 */
|
||||
@media (max-width:768px) {
|
||||
#app { flex-direction:column; }
|
||||
#mapWrap { height:50%; flex:none; }
|
||||
#configPanel { width:100%; height:50%; flex:none; border-left:none; border-top:1px solid #e0e0e0; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
<div id="mapWrap"><div id="map"></div></div>
|
||||
<div id="configPanel">
|
||||
<div class="panel-header">配置资产区域边界</div>
|
||||
<div class="panel-body">
|
||||
<!-- 颜色 -->
|
||||
<div class="setting-row">
|
||||
<label>边界颜色:</label>
|
||||
<input type="color" v-model="color" @change="onColorChange">
|
||||
<span>{{color}}</span>
|
||||
</div>
|
||||
|
||||
<!-- 区域列表 -->
|
||||
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;">
|
||||
<span style="font-size:13px;font-weight:bold;">区域列表 ({{regions.length}})</span>
|
||||
<button class="btn btn-primary" style="flex:none;padding:5px 12px;" @click="addRegion">+ 新增区域</button>
|
||||
</div>
|
||||
|
||||
<div v-if="regions.length === 0" style="text-align:center;padding:20px;color:#ccc;">
|
||||
暂无区域,点击"新增区域"开始
|
||||
</div>
|
||||
|
||||
<div v-for="(r, ri) in regions" :key="r.id"
|
||||
class="region-card" :class="{selected: selectedRegionIndex === ri}"
|
||||
@click="selectRegionCard(ri)">
|
||||
<div class="region-header">
|
||||
<span>区域 {{ri + 1}} <span style="font-size:11px;color:#aaa;">ID:{{r.id}}</span></span>
|
||||
<span class="del-btn" @click.stop="removeRegion(ri)">×</span>
|
||||
</div>
|
||||
<div class="region-info">
|
||||
外圈:{{r.outer ? r.outer.length : 0}} 个点
|
||||
<span v-if="r.holes && r.holesCount > 0"> | 孔洞:{{r.holesCount}} 个</span>
|
||||
</div>
|
||||
<div v-if="r.holes && r.holesCount > 0" class="hole-info">
|
||||
孔洞共 {{r.holesCount}} 个
|
||||
</div>
|
||||
<div style="display:flex;gap:4px;margin-top:6px;">
|
||||
<button class="btn" style="flex:none;padding:3px 8px;font-size:11px;background:#9b59b6;color:#fff;border:none;border-radius:4px;cursor:pointer;" @click.stop="startDrawHole(ri)">挖洞</button>
|
||||
<button v-if="r.holes && r.holesCount > 0" class="btn" style="flex:none;padding:3px 8px;font-size:11px;background:#e67e22;color:#fff;border:none;border-radius:4px;cursor:pointer;" @click.stop="clearHoles(ri)">清除孔洞</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tip">提示:点击区域卡片选中后,可在地图上看到高亮显示</div>
|
||||
</div>
|
||||
|
||||
<div class="panel-footer">
|
||||
<button class="btn btn-primary" @click="confirmSave">确认保存</button>
|
||||
<button class="btn btn-reset" @click="cancelClose">取消</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// 从父页面获取已有边界数据
|
||||
var oldBoundConfig = '';
|
||||
var assetsId = '';
|
||||
var _host = '';
|
||||
try {
|
||||
var params = window.parentDialogObj['boundConfigDialog'].getTransParams();
|
||||
console.log(window.parentDialogObj['boundConfigDialog'])
|
||||
console.log('[boundConfig] 父页面传入的参数:', JSON.stringify(params));
|
||||
oldBoundConfig = params.oldBoundConfig || '';
|
||||
assetsId = params.assetsId || params.assetId || params.assetsNo || '';
|
||||
} catch(e) {
|
||||
console.warn('获取父页面参数异常:', e);
|
||||
}
|
||||
// 尝试从父页面URL推断host
|
||||
try {
|
||||
_host = window.parent.location.origin || '';
|
||||
} catch(e) {}
|
||||
|
||||
console.log('[boundConfig] oldBoundConfig:', oldBoundConfig ? (oldBoundConfig.substring(0, 100) + '...') : '(空)');
|
||||
console.log('[boundConfig] assetsId:', assetsId);
|
||||
new Vue({
|
||||
el: '#app',
|
||||
data: {
|
||||
map: null,
|
||||
drawnItems: null,
|
||||
color: '#ff0000',
|
||||
regions: [],
|
||||
assetsId: assetsId,
|
||||
selectedRegionIndex: -1,
|
||||
_drawingMode: null // 'new' | 'hole'
|
||||
},
|
||||
mounted() {
|
||||
this.initMap();
|
||||
|
||||
},
|
||||
methods: {
|
||||
initMap() {
|
||||
console.log('[boundConfig] initMap, assetsId:', assetsId);
|
||||
this.map = L.map('map').setView([30.2856, 109.4783], 13);
|
||||
L.tileLayer('http://localhost:3080/seeyon/seeyonExtend/assetsMap/map/{z}/{x}/{y}/tile.png', { maxZoom: 18, minZoom: 8 }).addTo(this.map);
|
||||
this.drawnItems = L.featureGroup().addTo(this.map);
|
||||
this.markerGroup = L.layerGroup().addTo(this.map);
|
||||
this.markerIcon = L.divIcon({
|
||||
html: '<img src="./markicon.png" style="width:48px;height:48px;" onerror="this.style.display=\'none\';this.parentNode.innerHTML=\'<div style=width:24px;height:24px;background:#e74c3c;border-radius:50%;border:3px solid #fff;box-shadow:0 0 4px rgba(0,0,0,0.4);></div>\';">',
|
||||
className: 'custom-marker-icon',
|
||||
iconSize: [48, 48],
|
||||
iconAnchor: [24, 24]
|
||||
});
|
||||
|
||||
// 绘制控件
|
||||
var self = this;
|
||||
this.drawControl = new L.Control.Draw({
|
||||
draw: {
|
||||
polygon: {
|
||||
allowIntersection: false,
|
||||
shapeOptions: { color: self.color, weight: 2, fillOpacity: 0.3 }
|
||||
},
|
||||
polyline: false, rectangle: false, circle: false, circlemarker: false, marker: false
|
||||
},
|
||||
edit: { featureGroup: self.drawnItems, remove: true }
|
||||
});
|
||||
this.map.addControl(this.drawControl);
|
||||
// 同步颜色到绘制控件
|
||||
this.syncDrawColor();
|
||||
|
||||
// 绘制完成事件
|
||||
this.map.on(L.Draw.Event.CREATED, function(e) {
|
||||
var layer = e.layer;
|
||||
var latlngs = layer.getLatLngs()[0].map(function(ll) { return [ll.lat, ll.lng]; });
|
||||
|
||||
if (self._drawingMode === 'hole' && self.selectedRegionIndex >= 0 && self.selectedRegionIndex < self.regions.length) {
|
||||
// 挖洞:将绘制的多边形作为孔洞添加到选中的区域
|
||||
var region = self.regions[self.selectedRegionIndex];
|
||||
if (!region.holes) region.holes = [];
|
||||
region.holes.push(latlngs);
|
||||
region.holesCount = region.holes.length;
|
||||
} else if (self._pendingRegionIndex >= 0 && self._pendingRegionIndex < self.regions.length) {
|
||||
self.regions[self._pendingRegionIndex].outer = latlngs;
|
||||
} else {
|
||||
self.regions.push({ id: self.generateId(), outer: latlngs, holes: [], holesCount: 0 });
|
||||
self.selectedRegionIndex = self.regions.length - 1;
|
||||
}
|
||||
self._drawingMode = null;
|
||||
self._pendingRegionIndex = -1;
|
||||
self.refreshMap();
|
||||
});
|
||||
|
||||
// 编辑完成事件
|
||||
this.map.on(L.Draw.Event.EDITED, function(e) {
|
||||
var layers = e.layers;
|
||||
layers.eachLayer(function(layer) {
|
||||
var latlngs = layer.getLatLngs();
|
||||
var idx = self.findRegionByLayer(layer);
|
||||
if (idx >= 0) {
|
||||
self.regions[idx].outer = latlngs[0].map(function(ll) { return [ll.lat, ll.lng]; });
|
||||
// 保留孔洞
|
||||
var holes = [];
|
||||
for (var i = 1; i < latlngs.length; i++) {
|
||||
holes.push(latlngs[i].map(function(ll) { return [ll.lat, ll.lng]; }));
|
||||
}
|
||||
self.regions[idx].holes = holes;
|
||||
self.regions[idx].holesCount = holes.length;
|
||||
}
|
||||
});
|
||||
self.refreshMap();
|
||||
});
|
||||
|
||||
// 删除事件
|
||||
this.map.on(L.Draw.Event.DELETED, function(e) {
|
||||
// 删除对应 region
|
||||
e.layers.eachLayer(function(layer) {
|
||||
var idx = self.findRegionByLayer(layer);
|
||||
if (idx >= 0) {
|
||||
self.regions.splice(idx, 1);
|
||||
}
|
||||
});
|
||||
if (self.selectedRegionIndex >= self.regions.length) {
|
||||
self.selectedRegionIndex = self.regions.length - 1;
|
||||
}
|
||||
self.refreshMap();
|
||||
});
|
||||
|
||||
this._pendingRegionIndex = -1;
|
||||
|
||||
setTimeout(function() {
|
||||
self.map.invalidateSize();
|
||||
self.loadAssetLocation();
|
||||
self.loadBoundData();
|
||||
}, 200);
|
||||
},
|
||||
|
||||
findRegionByLayer(layer) {
|
||||
if (layer._regionIndex !== undefined && layer._regionIndex >= 0) {
|
||||
return layer._regionIndex;
|
||||
}
|
||||
var latlngs = layer.getLatLngs()[0];
|
||||
if (!latlngs || latlngs.length === 0) return -1;
|
||||
var firstPt = [latlngs[0].lat, latlngs[0].lng];
|
||||
for (var i = 0; i < this.regions.length; i++) {
|
||||
var r = this.regions[i];
|
||||
if (r.outer && r.outer.length > 0 &&
|
||||
Math.abs(r.outer[0][0] - firstPt[0]) < 0.0001 &&
|
||||
Math.abs(r.outer[0][1] - firstPt[1]) < 0.0001) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
},
|
||||
|
||||
loadBoundData() {
|
||||
console.log('[boundConfig] loadBoundData, oldBoundConfig:', oldBoundConfig);
|
||||
if (!oldBoundConfig) {
|
||||
console.log('[boundConfig] oldBoundConfig为空,跳过');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
var bound = typeof oldBoundConfig === 'string' ? JSON.parse(oldBoundConfig) : oldBoundConfig;
|
||||
console.log('[boundConfig] 解析后的边界数据:', bound);
|
||||
this.color = bound.color || '#ff0000';
|
||||
this.syncDrawColor();
|
||||
this.regions = this.normalizeBoundary(bound);
|
||||
console.log('[boundConfig] regions数量:', this.regions.length);
|
||||
this.refreshMap();
|
||||
} catch(e) {
|
||||
console.error('[boundConfig] 解析边界数据失败:', e, '原始数据:', oldBoundConfig);
|
||||
}
|
||||
},
|
||||
|
||||
// 根据 assetsId(资产编号)调接口获取经纬度,在地图上标点
|
||||
loadAssetLocation() {
|
||||
if (!assetsId) {
|
||||
console.log('[boundConfig] assetsId为空,跳过标点');
|
||||
return;
|
||||
}
|
||||
var self = this;
|
||||
var url = _host + '/seeyon/rest/assetsRegion/getByBounds';
|
||||
console.log('[boundConfig] 请求资产位置, url:', url, 'assetId:', assetsId);
|
||||
fetch(url, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ assetId: assetsId })
|
||||
}).then(function(r) {
|
||||
console.log('[boundConfig] 响应状态:', r.status);
|
||||
return r.json();
|
||||
}).then(function(d) {
|
||||
console.log('[boundConfig] 资产位置返回:', d);
|
||||
if (d.code === 0 && d.data && d.data.length > 0) {
|
||||
var region = d.data[0];
|
||||
var lat = parseFloat(region.lat);
|
||||
var lng = parseFloat(region.lng);
|
||||
console.log('[boundConfig] 经纬度:', lat, lng);
|
||||
if (!isNaN(lat) && !isNaN(lng)) {
|
||||
var m = L.marker([lat, lng], { icon: self.markerIcon });
|
||||
m.bindPopup(
|
||||
'<b>' + (region.assets && region.assets[0] ? region.assets[0].assetName : assetsId) + '</b><br>' +
|
||||
'坐标:' + lat + ', ' + lng,
|
||||
{ offset: [0, -24] }
|
||||
);
|
||||
m.addTo(self.markerGroup);
|
||||
self.map.setView([lat, lng], 16);
|
||||
setTimeout(function() { m.openPopup(); }, 300);
|
||||
}
|
||||
} else {
|
||||
console.warn('[boundConfig] 未查到资产位置数据, code:', d.code, 'data:', d.data);
|
||||
}
|
||||
}).catch(function(err) {
|
||||
console.error('[boundConfig] 请求资产位置失败:', err);
|
||||
});
|
||||
},
|
||||
|
||||
normalizeBoundary(bound) {
|
||||
if (!bound) return [];
|
||||
var self = this;
|
||||
if (bound.regions && Array.isArray(bound.regions)) {
|
||||
return bound.regions.map(function(r) {
|
||||
var holes = r.holes || [];
|
||||
return {
|
||||
id: r.id || self.generateId(),
|
||||
outer: r.outer || [],
|
||||
holes: holes,
|
||||
holesCount: holes.length
|
||||
};
|
||||
});
|
||||
}
|
||||
if (!bound.polygon || bound.polygon.length === 0) return [];
|
||||
var polygon = bound.polygon;
|
||||
if (typeof polygon[0][0] === 'number') {
|
||||
return [{ id: self.generateId(), outer: polygon, holes: [], holesCount: 0 }];
|
||||
}
|
||||
if (typeof polygon[0][0][0] === 'number') {
|
||||
return [{ id: self.generateId(), outer: polygon[0], holes: polygon.slice(1), holesCount: polygon.length - 1 }];
|
||||
}
|
||||
return polygon.map(function(r) {
|
||||
if (typeof r[0][0] === 'number') {
|
||||
return { id: self.generateId(), outer: r, holes: [], holesCount: 0 };
|
||||
}
|
||||
var h = r.slice(1);
|
||||
return { id: self.generateId(), outer: r[0], holes: h, holesCount: h.length };
|
||||
});
|
||||
},
|
||||
|
||||
generateId() {
|
||||
return Date.now() * 1000 + Math.floor(Math.random() * 1000);
|
||||
},
|
||||
|
||||
onColorChange() {
|
||||
this.syncDrawColor();
|
||||
this.refreshMap();
|
||||
},
|
||||
|
||||
syncDrawColor() {
|
||||
// 重建绘制控件以同步颜色
|
||||
if (this.drawControl) {
|
||||
this.map.removeControl(this.drawControl);
|
||||
}
|
||||
var self = this;
|
||||
this.drawControl = new L.Control.Draw({
|
||||
draw: {
|
||||
polygon: {
|
||||
allowIntersection: false,
|
||||
shapeOptions: { color: self.color, fillColor: self.color, weight: 2, fillOpacity: 0.3 }
|
||||
},
|
||||
polyline: false, rectangle: false, circle: false, circlemarker: false, marker: false
|
||||
},
|
||||
edit: { featureGroup: self.drawnItems, remove: true }
|
||||
});
|
||||
this.map.addControl(this.drawControl);
|
||||
},
|
||||
|
||||
refreshMap() {
|
||||
this.drawnItems.clearLayers();
|
||||
var self = this;
|
||||
this.regions.forEach(function(region, idx) {
|
||||
if (!region.outer || region.outer.length < 3) return;
|
||||
var rings = [region.outer].concat(region.holes || []);
|
||||
var isSelected = (idx === self.selectedRegionIndex);
|
||||
var polygon = L.polygon(rings, {
|
||||
color: isSelected ? '#27ae60' : self.color,
|
||||
fillColor: isSelected ? '#27ae60' : self.color,
|
||||
weight: isSelected ? 4 : 2,
|
||||
fillOpacity: isSelected ? 0.5 : 0.3
|
||||
});
|
||||
polygon._regionIndex = idx;
|
||||
self.drawnItems.addLayer(polygon);
|
||||
});
|
||||
if (this.drawnItems.getLayers().length > 0) {
|
||||
this.map.fitBounds(this.drawnItems.getBounds(), { padding: [30, 30] });
|
||||
}
|
||||
},
|
||||
|
||||
selectRegionCard(index) {
|
||||
this.selectedRegionIndex = index;
|
||||
this.refreshMap();
|
||||
},
|
||||
|
||||
addRegion() {
|
||||
// 直接触发多边形绘制,绘制完成后再添加到 regions
|
||||
this._pendingRegionIndex = -1;
|
||||
this._drawingMode = 'new';
|
||||
new L.Draw.Polygon(this.map, {
|
||||
shapeOptions: { color: this.color, weight: 2, fillOpacity: 0.3 },
|
||||
allowIntersection: false
|
||||
}).enable();
|
||||
},
|
||||
|
||||
startDrawHole(index) {
|
||||
if (!this.regions[index] || !this.regions[index].outer || this.regions[index].outer.length < 3) {
|
||||
alert('请先绘制外圈边界!');
|
||||
return;
|
||||
}
|
||||
this.selectedRegionIndex = index;
|
||||
this._drawingMode = 'hole';
|
||||
new L.Draw.Polygon(this.map, {
|
||||
shapeOptions: { color: '#9b59b6', weight: 2, fillOpacity: 0.3 },
|
||||
allowIntersection: false
|
||||
}).enable();
|
||||
},
|
||||
|
||||
clearHoles(index) {
|
||||
if (this.regions[index]) {
|
||||
this.regions[index].holes = [];
|
||||
this.regions[index].holesCount = 0;
|
||||
this.refreshMap();
|
||||
}
|
||||
},
|
||||
|
||||
removeRegion(index) {
|
||||
this.regions.splice(index, 1);
|
||||
if (this.selectedRegionIndex >= this.regions.length) {
|
||||
this.selectedRegionIndex = this.regions.length - 1;
|
||||
}
|
||||
this.refreshMap();
|
||||
},
|
||||
|
||||
confirmSave() {
|
||||
var cleanRegions = this.regions
|
||||
.filter(function(r) { return r.outer && r.outer.length >= 3; })
|
||||
.map(function(r) {
|
||||
return {
|
||||
id: r.id,
|
||||
outer: r.outer,
|
||||
holes: (r.holes || []).filter(function(h) { return h && h.length >= 3; })
|
||||
};
|
||||
});
|
||||
var result = JSON.stringify({ regions: cleanRegions, color: this.color });
|
||||
// 设置返回值供父页面获取
|
||||
window._boundConfigResult = result;
|
||||
alert('数据已生成,请点击"确认保存"按钮完成保存');
|
||||
},
|
||||
|
||||
cancelClose() {
|
||||
window._boundConfigResult = '';
|
||||
}
|
||||
}
|
||||
});
|
||||
function OK() {
|
||||
// 弹框框架调用此函数获取返回值
|
||||
return window._boundConfigResult || '';
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,191 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<title>坐标定位</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
|
||||
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
|
||||
<style>
|
||||
* { margin:0; padding:0; box-sizing:border-box; }
|
||||
body { font-family:"Microsoft YaHei",Arial,sans-serif; height:100vh; display:flex; overflow:hidden; }
|
||||
#app { display:flex; width:100%; height:100vh; }
|
||||
|
||||
#mapWrap { flex:1; position:relative; min-width:0; height:100%; }
|
||||
#map { height:100%; width:100%; }
|
||||
|
||||
#sidePanel {
|
||||
width:320px; height:100vh; background:#fff;
|
||||
border-left:1px solid #e0e0e0;
|
||||
display:flex; flex-direction:column; flex-shrink:0;
|
||||
position:relative; z-index:10000;
|
||||
box-shadow:-2px 0 12px rgba(0,0,0,0.08);
|
||||
}
|
||||
|
||||
.panel-section {
|
||||
padding:16px; border-bottom:2px solid #eee; flex-shrink:0;
|
||||
}
|
||||
.panel-section .title {
|
||||
font-size:14px; font-weight:bold; color:#333; margin-bottom:12px;
|
||||
}
|
||||
|
||||
.input-group {
|
||||
margin-bottom:10px;
|
||||
}
|
||||
.input-group label {
|
||||
display:block; font-size:12px; color:#888; margin-bottom:4px;
|
||||
}
|
||||
.input-group input {
|
||||
width:100%; padding:10px 12px; border:1px solid #ddd; border-radius:6px;
|
||||
font-size:14px; background:#fff;
|
||||
}
|
||||
.input-group input:focus {
|
||||
outline:none; border-color:#27ae60; box-shadow:0 0 0 2px rgba(39,174,96,0.1);
|
||||
}
|
||||
|
||||
.btn {
|
||||
width:100%; padding:10px 0; border:none; border-radius:6px;
|
||||
cursor:pointer; font-size:14px; font-weight:bold; transition:all 0.2s;
|
||||
}
|
||||
.btn-primary { background:#27ae60; color:#fff; }
|
||||
.btn-primary:hover { background:#219653; }
|
||||
|
||||
.tip-box {
|
||||
padding:10px 12px; background:#f0fff0; border:1px solid #d4edda;
|
||||
border-radius:6px; font-size:12px; color:#27ae60; margin-top:12px;
|
||||
}
|
||||
.tip-box b { color:#333; }
|
||||
|
||||
.custom-marker-icon { background:none !important; border:none !important; }
|
||||
|
||||
@media (max-width:768px) {
|
||||
#app { display:block; position:relative; }
|
||||
#mapWrap { width:100%; height:55%; }
|
||||
#sidePanel {
|
||||
position:absolute; bottom:0; left:0;
|
||||
width:100%; height:45%;
|
||||
border-left:none; border-top:1px solid #e0e0e0;
|
||||
border-radius:12px 12px 0 0;
|
||||
box-shadow:0 -2px 12px rgba(0,0,0,0.08);
|
||||
}
|
||||
.input-group input { min-height:44px; font-size:15px; }
|
||||
.btn { min-height:44px; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
<div id="mapWrap"><div id="map"></div></div>
|
||||
|
||||
<div id="sidePanel">
|
||||
<div class="panel-section">
|
||||
<div class="title">坐标定位</div>
|
||||
<div class="input-group">
|
||||
<label>纬度 (纬度在前)</label>
|
||||
<input type="text" v-model="lat" placeholder="如:30.2856" @keyup.enter="locateByCoord" class="lat-tag">
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<label>经度 (经度在后)</label>
|
||||
<input type="text" v-model="lng" placeholder="如:109.4783" @keyup.enter="locateByCoord" class="lng-tag">
|
||||
</div>
|
||||
<button class="btn btn-primary" @click="locateByCoord">定位到此坐标</button>
|
||||
</div>
|
||||
|
||||
<div class="panel-section" v-if="lat && lng">
|
||||
<div class="title">当前坐标</div>
|
||||
<div class="tip-box">
|
||||
纬度:<b>{{lat}}</b><br>
|
||||
经度:<b>{{lng}}</b>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||
<script>
|
||||
new Vue({
|
||||
el: "#app",
|
||||
data: {
|
||||
map: null,
|
||||
markerGroup: null,
|
||||
markerIcon: null,
|
||||
activeMarker: null,
|
||||
lat: '',
|
||||
lng: ''
|
||||
},
|
||||
mounted() {
|
||||
this.initMap();
|
||||
// 从URL参数读取初始坐标
|
||||
var params = new URLSearchParams(window.location.search);
|
||||
var initLat = parseFloat(params.get('lat'));
|
||||
var initLng = parseFloat(params.get('lng'));
|
||||
if (!isNaN(initLat) && !isNaN(initLng)) {
|
||||
this.lat = initLat + '';
|
||||
this.lng = initLng + '';
|
||||
this.locateByCoord();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initMap() {
|
||||
this.map = L.map('map').setView([30.2856, 109.4783], 13);
|
||||
L.tileLayer('http://localhost:3080/seeyon/seeyonExtend/assetsMap/map/{z}/{x}/{y}/tile.png', { maxZoom: 18, minZoom: 8 }).addTo(this.map);
|
||||
var self = this;
|
||||
setTimeout(function() { self.map.invalidateSize(); }, 100);
|
||||
|
||||
this.markerIcon = L.divIcon({
|
||||
html: '<img src="./markicon.png" style="width:48px;height:48px;">',
|
||||
className: 'custom-marker-icon',
|
||||
iconSize: [48, 48],
|
||||
iconAnchor: [24, 24]
|
||||
});
|
||||
this.markerGroup = L.layerGroup().addTo(this.map);
|
||||
|
||||
// 点击地图:放大到18级,回写经纬度
|
||||
this.map.on('click', function(e) {
|
||||
var clickLat = parseFloat(e.latlng.lat.toFixed(6));
|
||||
var clickLng = parseFloat(e.latlng.lng.toFixed(6));
|
||||
self.lat = clickLat + '';
|
||||
self.lng = clickLng + '';
|
||||
self.placeMarker(clickLat, clickLng);
|
||||
self.map.setView([clickLat, clickLng], 18);
|
||||
});
|
||||
},
|
||||
|
||||
// 输入坐标定位
|
||||
locateByCoord() {
|
||||
var lat = parseFloat(this.lat);
|
||||
var lng = parseFloat(this.lng);
|
||||
if (isNaN(lat) || isNaN(lng)) {
|
||||
alert('请输入有效的经纬度');
|
||||
return;
|
||||
}
|
||||
this.placeMarker(lat, lng);
|
||||
this.map.setView([lat, lng], 18);
|
||||
},
|
||||
|
||||
// 在地图上放置标记
|
||||
placeMarker(lat, lng) {
|
||||
this.markerGroup.clearLayers();
|
||||
var self = this;
|
||||
var m = L.marker([lat, lng], { icon: this.markerIcon });
|
||||
m.bindPopup(
|
||||
'纬度:<b>' + lat + '</b><br>经度:<b>' + lng + '</b>',
|
||||
{ offset: [0, -24] }
|
||||
);
|
||||
m.addTo(this.markerGroup);
|
||||
self.activeMarker = m;
|
||||
setTimeout(function() { m.openPopup(); }, 200);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function OK() {
|
||||
var latlng = '';
|
||||
const latText = $('.lat-tag').val();
|
||||
const lngText = $('.lng-tag').val();
|
||||
latlng = latText + "," +lngText
|
||||
return latlng;
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
@@ -0,0 +1,177 @@
|
||||
(function (factory) {
|
||||
var nameSpace = 'field_17179214358792461983';
|
||||
if (!window[nameSpace]) {
|
||||
console.log("开始实例化边界区域配置按钮")
|
||||
var Builder = factory();
|
||||
window[nameSpace] = { instance: {} };
|
||||
window[nameSpace].init = function (options) {
|
||||
window[nameSpace].instance[options.privateId] = new Builder(options);
|
||||
};
|
||||
}
|
||||
})(function () {
|
||||
function App(options) {
|
||||
var self = this;
|
||||
self.initParams(options);
|
||||
self.initDom();
|
||||
self.events();
|
||||
}
|
||||
|
||||
App.prototype = {
|
||||
initParams: function (options) {
|
||||
var self = this;
|
||||
self.adaptation = options.adaptation;
|
||||
self.privateId = options.privateId;
|
||||
self.preUrl = options.url_prefix;
|
||||
self.adaptation.formMessage = options.formMessage;
|
||||
self.messageObj = options.getData;
|
||||
},
|
||||
initDom: function () {
|
||||
var self = this;
|
||||
// 修复:避免重复加载CSS
|
||||
if (!document.querySelector('link[href="' + self.preUrl + '/css/goMapBtn.css' + '"]')) {
|
||||
dynamicLoading.css(self.preUrl + '/css/goMapBtn.css');
|
||||
}
|
||||
self.appendChildDom();
|
||||
},
|
||||
events: function () {
|
||||
var self = this;
|
||||
self.adaptation.ObserverEvent.listen('Event' + self.privateId, function () {
|
||||
self.messageObj = self.adaptation.childrenGetData(self.privateId);
|
||||
self.appendChildDom();
|
||||
});
|
||||
},
|
||||
|
||||
openBoundConfig: function (privateId,messageObj,adaptation) {
|
||||
var self = this;
|
||||
messageObj = adaptation.childrenGetData(privateId);
|
||||
|
||||
var targetObj = messageObj.formdata.formmains[messageObj.formdata.alldata.tableInfo.formmain.tableName];
|
||||
var boundData = '';
|
||||
var assetsId = '';
|
||||
if (targetObj) {
|
||||
for (var key in targetObj) {
|
||||
if (targetObj.hasOwnProperty(key) && !/^auxiliary/.test(key)) {
|
||||
var display = targetObj[key].display;
|
||||
// 修复:去掉未定义的 fieldMap
|
||||
if (display === "资产边界数据") {
|
||||
boundData = targetObj[key].showValue;
|
||||
}
|
||||
if (display === "资产编号") {
|
||||
assetsId = targetObj[key].showValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var dialog = $.dialog({
|
||||
id: 'boundConfigDialog',
|
||||
url: self.preUrl + '/html/boundConfig.html',
|
||||
width: 1100,
|
||||
height: 750,
|
||||
title: '配置资产区域边界',
|
||||
transParams: { oldBoundConfig: boundData, assetsId: assetsId },
|
||||
type: 'panel',
|
||||
checkMax: true,
|
||||
closeParam: {
|
||||
'show': false,
|
||||
autoClose: false,
|
||||
handler: function () { }
|
||||
},
|
||||
buttons: [{
|
||||
text: "确认保存",
|
||||
handler: function () {
|
||||
var result = dialog.getReturnValue();
|
||||
console.log("资产边界数据: " + result)
|
||||
// 修复:参数顺序与回填对应
|
||||
backFill(result, messageObj.id, "资产边界数据", privateId, messageObj, adaptation);
|
||||
dialog.close()
|
||||
}
|
||||
}, {
|
||||
text: "取消",
|
||||
handler: function () {
|
||||
dialog.close();
|
||||
}
|
||||
}]
|
||||
});
|
||||
},
|
||||
|
||||
appendChildDom: function () {
|
||||
var self = this;
|
||||
var doJump = function () {
|
||||
|
||||
self.openBoundConfig(self.privateId, self.messageObj, self.adaptation);
|
||||
};
|
||||
|
||||
var domStructure = '<section class="customButton_box_content">' +
|
||||
'<div class="customButton_class_box ' + self.privateId + '" title="' + self.messageObj.display.escapeHTML() + '">' + self.messageObj.display.escapeHTML() + '</div>' +
|
||||
'</section>';
|
||||
|
||||
var $container = document.querySelector('#' + self.privateId);
|
||||
if (!$container) return;
|
||||
|
||||
$container.innerHTML = domStructure;
|
||||
|
||||
var $btn = document.querySelector('.' + self.privateId);
|
||||
if ($btn) {
|
||||
$btn.removeEventListener('click', doJump);
|
||||
$btn.addEventListener('click', doJump);
|
||||
}
|
||||
|
||||
if (self.messageObj.auth === 'hide') {
|
||||
$container.innerHTML = '<div class="cap4-text__browse" style="line-height: 1.8; color: rgb(0, 0, 0) !important;">***</div>';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function backFill(boundConfig, fieldName, fieldDisplay, privateId, messageObj, adaptation) {
|
||||
var param = {};
|
||||
param.masterId = messageObj.formdata.content.contentDataId;
|
||||
param.value = boundConfig;
|
||||
param.formId = messageObj.formdata.content.contentTemplateId;
|
||||
param.fieldName = fieldName;
|
||||
param.fieldDisplay = fieldDisplay;
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: '/seeyon/rest/assetsRegion/formBackFill',
|
||||
data: JSON.stringify(param),
|
||||
dataType: "json",
|
||||
contentType: 'application/json;charset=UTF-8',
|
||||
success: function (res) {
|
||||
if (res.code == 0) {
|
||||
var backfillData = {};
|
||||
backfillData.tableName = adaptation.formMessage.tableName;
|
||||
backfillData.tableCategory = 'formmain';
|
||||
backfillData.updateData = res.data;
|
||||
adaptation.backfillFormControlData(backfillData, privateId);
|
||||
} else {
|
||||
$.alert(res.message);
|
||||
}
|
||||
},
|
||||
error: function (e) {
|
||||
top.$.error(e.responseText || '保存失败');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var dynamicLoading = {
|
||||
css: function (path) {
|
||||
if (!path) return;
|
||||
var head = document.getElementsByTagName('head')[0];
|
||||
var link = document.createElement('link');
|
||||
link.href = path;
|
||||
link.rel = 'stylesheet';
|
||||
link.type = 'text/css';
|
||||
head.appendChild(link);
|
||||
},
|
||||
js: function (path) {
|
||||
if (!path) return;
|
||||
var head = document.getElementsByTagName('head')[0];
|
||||
var script = document.createElement('script');
|
||||
script.src = path;
|
||||
script.type = 'text/javascript';
|
||||
head.appendChild(script);
|
||||
}
|
||||
}
|
||||
|
||||
return App;
|
||||
});
|
||||
@@ -0,0 +1,114 @@
|
||||
(function (factory) {
|
||||
var nameSpace = 'field_17179215134928371056';
|
||||
if (!window[nameSpace]) {
|
||||
console.log("开始实例化跳转地图按钮")
|
||||
var Builder = factory();
|
||||
window[nameSpace] = {
|
||||
instance: {}
|
||||
};
|
||||
window[nameSpace].init = function (options) {
|
||||
window[nameSpace].instance[options.privateId] = new Builder(options);
|
||||
};
|
||||
}
|
||||
})(function () {
|
||||
function App(options) {
|
||||
var self = this;
|
||||
self.initParams(options);
|
||||
//初始化dom
|
||||
self.initDom();
|
||||
//事件
|
||||
self.events();
|
||||
}
|
||||
|
||||
App.prototype = {
|
||||
initParams: function (options) {
|
||||
console.log("开始初始化参数")
|
||||
var self = this;
|
||||
self.adaptation = options.adaptation;
|
||||
self.privateId = options.privateId;
|
||||
self.preUrl = options.url_prefix;
|
||||
self.adaptation.formMessage = options.formMessage;
|
||||
self.messageObj = options.getData;
|
||||
console.log(self.messageObj)
|
||||
},
|
||||
initDom: function () {
|
||||
var self = this;
|
||||
console.log("开始渲染dom")
|
||||
dynamicLoading.css(self.preUrl + '/css/goMapBtn.css');
|
||||
self.appendChildDom();
|
||||
},
|
||||
events: function () {
|
||||
var self = this;
|
||||
// 监听是否数据刷新
|
||||
console.log("设置事件监听")
|
||||
self.adaptation.ObserverEvent.listen('Event' + self.privateId, function () {
|
||||
self.messageObj = self.adaptation.childrenGetData(self.privateId);
|
||||
self.appendChildDom();
|
||||
});
|
||||
},
|
||||
goMap: function (privateId, messageObj, adaptation) {
|
||||
// 获取表单中的资产编号,跳转到资产地图
|
||||
console.log("privateId:" + privateId)
|
||||
console.log("messageObj:" + messageObj)
|
||||
console.log(adaptation)
|
||||
messageObj = adaptation.childrenGetData(privateId);
|
||||
var targetObj = messageObj.formdata.formmains[adaptation.formMessage.tableName];
|
||||
if (!targetObj) return;
|
||||
var assetNo;
|
||||
for (var key in targetObj) {
|
||||
if (targetObj.hasOwnProperty(key) && !/^auxiliary/.test(key)) {
|
||||
if (targetObj[key].display === "资产编号") {
|
||||
assetNo = targetObj[key].showValue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (assetNo) {
|
||||
var baseUrl = window.location.origin + '/seeyon/seeyonExtend/assetsMap/map.html';
|
||||
window.open(baseUrl + '?assetId=' + encodeURIComponent(assetNo), '_blank');
|
||||
} else {
|
||||
$.alert('未找到资产编号字段');
|
||||
}
|
||||
},
|
||||
appendChildDom: function () {
|
||||
var self = this;
|
||||
var doJump = function () {
|
||||
self.goMap(self.privateId, self.messageObj, self.adaptation)
|
||||
}
|
||||
var domStructure = '<section class="customButton_box_content">' +
|
||||
'<div class="customButton_class_box ' + self.privateId + '" title="' + self.messageObj.display.escapeHTML() + '">' + self.messageObj.display.escapeHTML() + '</div>' +
|
||||
'</section>';
|
||||
document.querySelector('#' + self.privateId).innerHTML = domStructure;
|
||||
var content = self.messageObj.formdata.content
|
||||
document.querySelector('.' + self.privateId).removeEventListener('click', doJump);
|
||||
document.querySelector('.' + self.privateId).addEventListener('click', doJump);
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
var dynamicLoading = {
|
||||
css: function (path) {
|
||||
if (!path || path.length === 0) {
|
||||
throw new Error('argument "path" is required !');
|
||||
}
|
||||
var head = document.getElementsByTagName('head')[0];
|
||||
var link = document.createElement('link');
|
||||
link.href = path;
|
||||
link.rel = 'stylesheet';
|
||||
link.type = 'text/css';
|
||||
head.appendChild(link);
|
||||
},
|
||||
js: function (path) {
|
||||
if (!path || path.length === 0) {
|
||||
throw new Error('argument "path" is required !');
|
||||
}
|
||||
var head = document.getElementsByTagName('head')[0];
|
||||
var script = document.createElement('script');
|
||||
script.src = path;
|
||||
script.type = 'text/javascript';
|
||||
head.appendChild(script);
|
||||
}
|
||||
}
|
||||
return App;
|
||||
});
|
||||
@@ -0,0 +1,166 @@
|
||||
(function(factory) {
|
||||
var nameSpace = 'field_17179214358792461984';
|
||||
if (!window[nameSpace]) {
|
||||
console.log("开始实例化资产定位按钮")
|
||||
var Builder = factory();
|
||||
window[nameSpace] = {
|
||||
instance: {}
|
||||
};
|
||||
window[nameSpace].init = function(options) {
|
||||
window[nameSpace].instance[options.privateId] = new Builder(options);
|
||||
};
|
||||
}
|
||||
})(function() {
|
||||
function App(options) {
|
||||
var self = this;
|
||||
self.initParams(options);
|
||||
//初始化dom
|
||||
self.initDom();
|
||||
//事件
|
||||
self.events();
|
||||
}
|
||||
|
||||
App.prototype = {
|
||||
initParams: function(options) {
|
||||
console.log("开始初始化参数")
|
||||
var self = this;
|
||||
self.adaptation = options.adaptation;
|
||||
self.privateId = options.privateId;
|
||||
self.preUrl = options.url_prefix;
|
||||
self.adaptation.formMessage = options.formMessage;
|
||||
self.messageObj = options.getData;
|
||||
console.log(self.messageObj)
|
||||
},
|
||||
initDom: function() {
|
||||
var self = this;
|
||||
console.log("开始渲染dom")
|
||||
dynamicLoading.css(self.preUrl + '/css/goMapBtn.css');
|
||||
self.appendChildDom();
|
||||
},
|
||||
events: function() {
|
||||
var self = this;
|
||||
// 监听是否数据刷新
|
||||
console.log("设置事件监听")
|
||||
self.adaptation.ObserverEvent.listen('Event' + self.privateId, function() {
|
||||
self.messageObj = self.adaptation.childrenGetData(self.privateId);
|
||||
self.appendChildDom();
|
||||
});
|
||||
},
|
||||
goLocation: function(privateId,messageObj,adaptation) {
|
||||
var privateId1;
|
||||
var privateId2;
|
||||
messageObj = adaptation.childrenGetData(privateId);
|
||||
var tableName = messageObj.formdata.alldata.tableInfo.formmain.tableName
|
||||
var dialog = $.dialog({
|
||||
id: 'dialog',
|
||||
url: this.preUrl + '/html/location.html',
|
||||
width: 1080,
|
||||
height: 720,
|
||||
title: '资产位置定位',
|
||||
type: 'panel',
|
||||
checkMax: true,
|
||||
closeParam: {
|
||||
'show': false,
|
||||
autoClose: false,
|
||||
handler: function() {}
|
||||
},
|
||||
buttons: [{
|
||||
text: "确认",
|
||||
handler: function() {
|
||||
var latlng = dialog.getReturnValue();
|
||||
// 回填数据
|
||||
const [lat, lng] = latlng.split(',');
|
||||
backFill(lat, messageObj.id, "纬度-", privateId,messageObj, adaptation,tableName);
|
||||
backFill(lng, messageObj.id, "经度-", privateId,messageObj, adaptation,tableName);
|
||||
dialog.close()
|
||||
}
|
||||
}, {
|
||||
text: "取消",
|
||||
handler: function() {
|
||||
dialog.close()
|
||||
}
|
||||
}]
|
||||
});
|
||||
},
|
||||
appendChildDom: function() {
|
||||
var self = this;
|
||||
var doBiz = function() {
|
||||
self.goLocation(self.privateId, self.messageObj, self.adaptation)
|
||||
}
|
||||
|
||||
var domStructure = '<section class="customButton_box_content">' +
|
||||
'<div class="customButton_class_box ' + self.privateId + '" title="' + self.messageObj.display
|
||||
.escapeHTML() + '">' + self.messageObj.display.escapeHTML() + '</div>' +
|
||||
'</section>';
|
||||
document.querySelector('#' + self.privateId).innerHTML = domStructure;
|
||||
|
||||
var content = self.messageObj.formdata.content
|
||||
document.querySelector('.' + self.privateId).removeEventListener('click', doBiz);
|
||||
document.querySelector('.' + self.privateId).addEventListener('click', doBiz);
|
||||
//渲染隐藏权限
|
||||
if (self.messageObj.auth === 'hide') {
|
||||
document.querySelector('#' + self.privateId).innerHTML =
|
||||
'<div class="cap4-text__browse" style="line-height: 1.8; color: rgb(0, 0, 0) !important;">***</div>';
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
function backFill(latlng, fieldName, fieldDisplay, privateId, messageObj, adaptation,tableName) {
|
||||
var param = new Object();
|
||||
param.masterId = messageObj.formdata.content.contentDataId;
|
||||
param.value = latlng;
|
||||
param.formId = messageObj.formdata.content.contentTemplateId;
|
||||
param.fieldDisplay = fieldDisplay;
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: '/seeyon/rest/assetsRegion/formBackFill',
|
||||
data: JSON.stringify(param),
|
||||
dataType: "json",
|
||||
contentType: 'application/json;charset=UTF-8',
|
||||
success: function(res) {
|
||||
// 后台解析数据后 将数据填写到表单中
|
||||
if (res.code == 0) {
|
||||
var backfill = {};
|
||||
backfill.tableName = tableName;
|
||||
// 回填主表
|
||||
backfill.tableCategory = 'formmain';
|
||||
// 后台组装的data数据
|
||||
console.log(res.data)
|
||||
backfill.updateData = res.data;
|
||||
adaptation.backfillFormControlData(backfill, privateId);
|
||||
} else {
|
||||
// 报错
|
||||
$.alert(res.message);
|
||||
}
|
||||
},
|
||||
complete: function() {},
|
||||
error: function(e) {
|
||||
top.$.error(e.responseText);
|
||||
}
|
||||
});
|
||||
}
|
||||
var dynamicLoading = {
|
||||
css: function(path) {
|
||||
if (!path || path.length === 0) {
|
||||
throw new Error('argument "path" is required !');
|
||||
}
|
||||
var head = document.getElementsByTagName('head')[0];
|
||||
var link = document.createElement('link');
|
||||
link.href = path;
|
||||
link.rel = 'stylesheet';
|
||||
link.type = 'text/css';
|
||||
head.appendChild(link);
|
||||
},
|
||||
js: function(path) {
|
||||
if (!path || path.length === 0) {
|
||||
throw new Error('argument "path" is required !');
|
||||
}
|
||||
var head = document.getElementsByTagName('head')[0];
|
||||
var script = document.createElement('script');
|
||||
script.src = path;
|
||||
script.type = 'text/javascript';
|
||||
head.appendChild(script);
|
||||
}
|
||||
}
|
||||
return App;
|
||||
});
|
||||
@@ -3,6 +3,7 @@ package com.seeyon.apps.assetsmap.constants;
|
||||
public enum AssetsMapConstans {
|
||||
plugin("assetsmap",""),
|
||||
ASSETSFORMNO("assetsformno","资产表单"),
|
||||
ASSETSDETAILURLCONFIGFORMNO("","资产详情URL配置表单"),
|
||||
;
|
||||
|
||||
private String defaultValue;
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.seeyon.apps.assetsmap.fieldCtrl;
|
||||
|
||||
import com.seeyon.cap4.form.bean.ParamDefinition;
|
||||
import com.seeyon.cap4.form.bean.fieldCtrl.FormFieldCustomCtrl;
|
||||
import com.seeyon.cap4.form.util.Enums;
|
||||
|
||||
public class BoundConfigFieldCtrl extends FormFieldCustomCtrl {
|
||||
@Override
|
||||
public String getPCInjectionInfo() {
|
||||
return "{path:'apps_res/cap/customCtrlResources/goMapBtnResources',jsUri:'/js/boundConfig.js',initMethod:'init',nameSpace:'" + getNameSpace() + "'}";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMBInjectionInfo() {
|
||||
return "{path:'http://mapResource.v5.cmp/v1.0.0/',weixinpath:'invoice',jsUri:'js/location.js',initMethod:'init',nameSpace:'"+getNameSpace()+"'}";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return "17179214358792461983";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canUse(Enums.FormType formType) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getDefaultVal(String s) {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
public String getNameSpace() {
|
||||
return "field_" + this.getKey();
|
||||
}
|
||||
|
||||
public String getFieldLength() {
|
||||
return "20";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return "绘制资产边界";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
setPluginId("assetsmap");
|
||||
setIcon("cap-icon-custom-button");
|
||||
ParamDefinition param = new ParamDefinition();
|
||||
param.setParamType(Enums.ParamType.button);
|
||||
addDefinition(param);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.seeyon.apps.assetsmap.fieldCtrl;
|
||||
|
||||
import com.seeyon.cap4.form.bean.ParamDefinition;
|
||||
import com.seeyon.cap4.form.bean.fieldCtrl.FormFieldCustomCtrl;
|
||||
import com.seeyon.cap4.form.util.Enums;
|
||||
|
||||
|
||||
public class GoMapFieldCtrl extends FormFieldCustomCtrl {
|
||||
@Override
|
||||
public String getPCInjectionInfo() {
|
||||
return "{path:'apps_res/cap/customCtrlResources/goMapBtnResources',jsUri:'/js/goMapInit.js',initMethod:'init',nameSpace:'" + getNameSpace() + "'}";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMBInjectionInfo() {
|
||||
return "{path:'http://mapResource.v5.cmp/v1.0.0/',weixinpath:'invoice',jsUri:'js/location.js',initMethod:'init',nameSpace:'"+getNameSpace()+"'}";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return "17179215134928371056";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canUse(Enums.FormType formType) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getDefaultVal(String s) {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
public String getNameSpace() {
|
||||
return "field_" + this.getKey();
|
||||
}
|
||||
|
||||
public String getFieldLength() {
|
||||
return "20";
|
||||
}
|
||||
@Override
|
||||
public String getText() {
|
||||
return "跳转资产地图按钮";
|
||||
}
|
||||
|
||||
/**
|
||||
* 控件初始化接口,此接口在控件初始化的时候,会调用,主要用于定义控件所属插件id、在表单编辑器中的图标、表单编辑器中有哪些属性可以设置。
|
||||
* 使用举例:在接口中定义自定义控件在在表单编辑器中有哪些控件属性需要配置
|
||||
*/
|
||||
@Override
|
||||
public void init() {
|
||||
//设置图标和插件ID
|
||||
setPluginId("assetsmap");
|
||||
setIcon("cap-icon-custom-button");
|
||||
// 自定义参数
|
||||
|
||||
ParamDefinition esignContractCompareBtnParam = new ParamDefinition();
|
||||
esignContractCompareBtnParam.setParamType(Enums.ParamType.button);
|
||||
addDefinition(esignContractCompareBtnParam);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.seeyon.apps.assetsmap.fieldCtrl;
|
||||
|
||||
import com.seeyon.cap4.form.bean.ParamDefinition;
|
||||
import com.seeyon.cap4.form.bean.fieldCtrl.FormFieldCustomCtrl;
|
||||
import com.seeyon.cap4.form.util.Enums;
|
||||
|
||||
public class LocationFieldCtrl extends FormFieldCustomCtrl {
|
||||
@Override
|
||||
public String getPCInjectionInfo() {
|
||||
return "{path:'apps_res/cap/customCtrlResources/goMapBtnResources',jsUri:'/js/location.js',initMethod:'init',nameSpace:'" + getNameSpace() + "'}";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMBInjectionInfo() {
|
||||
return getPCInjectionInfo();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return "17179214358792461984";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canUse(Enums.FormType formType) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getDefaultVal(String s) {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
public String getNameSpace() {
|
||||
return "field_" + this.getKey();
|
||||
}
|
||||
|
||||
public String getFieldLength() {
|
||||
return "20";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return "资产定位按钮";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
setPluginId("assetsmap");
|
||||
setIcon("cap-icon-custom-button");
|
||||
ParamDefinition param = new ParamDefinition();
|
||||
param.setParamType(Enums.ParamType.button);
|
||||
addDefinition(param);
|
||||
}
|
||||
}
|
||||
49
src/main/java/com/seeyon/apps/assetsmap/kit/A8FolderKit.java
Normal file
49
src/main/java/com/seeyon/apps/assetsmap/kit/A8FolderKit.java
Normal file
@@ -0,0 +1,49 @@
|
||||
package com.seeyon.apps.assetsmap.kit;
|
||||
|
||||
import com.seeyon.ctp.common.SystemEnvironment;
|
||||
|
||||
/**
|
||||
* Description
|
||||
* <pre>获取A8产品下面的文件夹路径</pre>
|
||||
* Date 2019年10月11日 上午9:42:49<br>
|
||||
* Copyright(c) Beijing Seeyon Software Co.,LTD
|
||||
*/
|
||||
public class A8FolderKit {
|
||||
|
||||
private static String A8_APPLICAION_FLODER = "";
|
||||
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* <pre>获取到A8的安装模目录,ApacheJetspeed目录的父目录</pre>
|
||||
* @return
|
||||
*/
|
||||
public static String getApplicationFolder() {
|
||||
if("".equals(A8_APPLICAION_FLODER)) {
|
||||
String installPath = SystemEnvironment.getApplicationFolder();
|
||||
A8_APPLICAION_FLODER = installPath.split("ApacheJetspeed")[0].replaceAll("\\\\", "/");
|
||||
}
|
||||
return A8_APPLICAION_FLODER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* <pre>获取配置文件的地址</pre>
|
||||
* @return
|
||||
*/
|
||||
public static String getCodePropertiesPath() {
|
||||
String path = getApplicationFolder() + "ApacheJetspeed/webapps/seeyon/WEB-INF/classes/code.properties";
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
public static String getPropertiesPath(String fileName) {
|
||||
String path = getApplicationFolder() + "ApacheJetspeed/webapps/seeyon/WEB-INF/classes/" + fileName;
|
||||
return path;
|
||||
}
|
||||
|
||||
public static String getZSJCodePropertiesPath() {
|
||||
String path = getApplicationFolder() + "ApacheJetspeed/webapps/seeyon/WEB-INF/classes/ZSJcode.properties";
|
||||
return path;
|
||||
}
|
||||
}
|
||||
196
src/main/java/com/seeyon/apps/assetsmap/kit/CAP4FormKit.java
Normal file
196
src/main/java/com/seeyon/apps/assetsmap/kit/CAP4FormKit.java
Normal file
@@ -0,0 +1,196 @@
|
||||
package com.seeyon.apps.assetsmap.kit;
|
||||
|
||||
import com.seeyon.cap4.form.bean.*;
|
||||
import com.seeyon.cap4.form.service.CAP4FormManager;
|
||||
import com.seeyon.ctp.common.exceptions.BusinessException;
|
||||
import com.seeyon.ctp.common.log.CtpLogFactory;
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Description
|
||||
* <pre>操作CAP4表单和字段</pre>
|
||||
* @author FanGaowei<br>
|
||||
* Copyright(c) Beijing Seeyon Software Co.,LTD
|
||||
*/
|
||||
public class CAP4FormKit {
|
||||
|
||||
private static final Log LOGGER = CtpLogFactory.getLog(CAP4FormKit.class);
|
||||
|
||||
public static FormBean getFormBean(CAP4FormManager cap4FormManager, String code) {
|
||||
FormBean formBean = null;
|
||||
try {
|
||||
formBean = cap4FormManager.getFormByFormCode(code);
|
||||
} catch(BusinessException e) {
|
||||
LOGGER.error("获取表单发生异常,编号:" + code, e);
|
||||
}
|
||||
return formBean;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据表单的显示名称获取字段的值
|
||||
* @param bean
|
||||
* @param disPlay
|
||||
* @return
|
||||
*/
|
||||
public static Object getFieldValue(FormDataBean bean, String disPlay) {
|
||||
if(bean == null) {
|
||||
return null;
|
||||
}
|
||||
FormTableBean table = bean.getFormTable();
|
||||
if(table == null) {
|
||||
return null;
|
||||
}
|
||||
FormFieldBean field = table.getFieldBeanByDisplay(disPlay);
|
||||
if(field == null) {
|
||||
return null;
|
||||
}
|
||||
return bean.getFieldValue(field.getName());
|
||||
}
|
||||
|
||||
|
||||
public static int getIntValue(FormDataBean bean, String disPlay) {
|
||||
Object value = getFieldValue(bean, disPlay);
|
||||
return StrKit.toInteger(value);
|
||||
}
|
||||
|
||||
public static String getFieldStrValue(FormDataBean bean, String disPlay) {
|
||||
Object value = getFieldValue(bean, disPlay);
|
||||
return StrKit.str(value);
|
||||
}
|
||||
|
||||
public static Object getFieldValueByName(FormDataBean bean, String fieldName) {
|
||||
return bean.getFieldValue(fieldName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据表单的显示名称获取字段是 field000?
|
||||
* @param bean
|
||||
* @param disPlay
|
||||
* @return
|
||||
*/
|
||||
public static String getFieldTaleId(FormBean bean, String disPlay) {
|
||||
if(bean == null) {
|
||||
return null;
|
||||
}
|
||||
FormTableBean table = bean.getMasterTableBean();
|
||||
return getFieldTaleId(table, disPlay);
|
||||
}
|
||||
|
||||
/**
|
||||
* 直接根据table来获取
|
||||
* @param table
|
||||
* @param disPlay
|
||||
* @return
|
||||
*/
|
||||
public static String getFieldTaleId(FormTableBean table, String disPlay) {
|
||||
if(table == null) {
|
||||
return null;
|
||||
}
|
||||
FormFieldBean field = table.getFieldBeanByDisplay(disPlay);
|
||||
if(field == null) {
|
||||
return null;
|
||||
}
|
||||
return field.getName();
|
||||
}
|
||||
|
||||
public static String getFieldTaleId(FormDataBean bean, String disPlay) {
|
||||
if(bean == null) {
|
||||
return null;
|
||||
}
|
||||
FormTableBean table = bean.getFormTable();
|
||||
if(table == null) {
|
||||
return null;
|
||||
}
|
||||
FormFieldBean field = table.getFieldBeanByDisplay(disPlay);
|
||||
if(field == null) {
|
||||
return null;
|
||||
}
|
||||
return field.getName();
|
||||
}
|
||||
|
||||
public static FormFieldBean getFieldBean(FormDataBean bean, String disPlay) {
|
||||
if(bean == null) {
|
||||
return null;
|
||||
}
|
||||
FormTableBean table = bean.getFormTable();
|
||||
if(table == null) {
|
||||
return null;
|
||||
}
|
||||
return table.getFieldBeanByDisplay(disPlay);
|
||||
}
|
||||
|
||||
public static FormFieldBean getFieldBean(FormTableBean bean, String disPlay) {
|
||||
if(bean == null) {
|
||||
return null;
|
||||
}
|
||||
return bean.getFieldBeanByDisplay(disPlay);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* <pre></pre>
|
||||
* @param bean 这里的bean必须是getMasterBean() 方法获取到的bean
|
||||
* @param disPlay
|
||||
* @param value
|
||||
*/
|
||||
public static void setCellValue(FormDataBean bean, String disPlay, Object value) {
|
||||
FormFieldBean cell = CAP4FormKit.getFieldBean(bean, disPlay);
|
||||
if(cell != null) {
|
||||
bean.addFieldValue(cell.getName(), value);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setCellValue(FormDataSubBean bean, String disPlay, Object value) {
|
||||
FormFieldBean cell = CAP4FormKit.getFieldBean(bean, disPlay);
|
||||
if(cell != null) {
|
||||
bean.addFieldValue(cell.getName(), value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* <pre>只适用于只有一个子表的表单</pre>
|
||||
* @param colManager
|
||||
* @param data
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static List<FormDataSubBean> getSubBeans(FormDataMasterBean master) throws Exception {
|
||||
Map<String, List<FormDataSubBean>> subs = master.getSubTables();
|
||||
|
||||
if(null != subs && subs.size() > 0) {
|
||||
for(String key : subs.keySet()) {
|
||||
return subs.get(key);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static List<FormDataSubBean> getSubBeansByDisPlay(FormDataMasterBean master, String display) throws Exception {
|
||||
Map<String, List<FormDataSubBean>> subs = master.getSubTables();
|
||||
|
||||
if(null != subs && subs.size() > 0) {
|
||||
for(String key : subs.keySet()) {
|
||||
if(display.equals(subs.get(key).get(0).getFormTable().getDisplay())) {
|
||||
return subs.get(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* <pre>获取从表字段</pre>
|
||||
* @param sub
|
||||
* @param disPlay
|
||||
* @return
|
||||
*/
|
||||
public static Object getSubFieldValue(FormDataSubBean sub, String disPlay) {
|
||||
return getFieldValue(sub, disPlay);
|
||||
}
|
||||
}
|
||||
92
src/main/java/com/seeyon/apps/assetsmap/kit/DBKit.java
Normal file
92
src/main/java/com/seeyon/apps/assetsmap/kit/DBKit.java
Normal file
@@ -0,0 +1,92 @@
|
||||
package com.seeyon.apps.assetsmap.kit;
|
||||
|
||||
import com.seeyon.ctp.common.exceptions.BusinessException;
|
||||
import com.seeyon.ctp.util.JDBCAgent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 直接操作数据库的类
|
||||
* </pre>
|
||||
* @date 2018年11月8日 上午11:10:15
|
||||
* @Copyright(c) Beijing Seeyon Software Co.,LTD
|
||||
*/
|
||||
public class DBKit {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static List<Map<String, Object>> excuteSQL(String sql, List<Object> params) throws Exception {
|
||||
List<Map<String, Object>> list = new ArrayList<>();
|
||||
JDBCAgent jdbc = new JDBCAgent(true, false);
|
||||
try {
|
||||
if(null == params) {
|
||||
jdbc.execute(sql);
|
||||
} else {
|
||||
jdbc.execute(sql, params);
|
||||
}
|
||||
if(!sql.startsWith("update")) {
|
||||
list = jdbc.resultSetToList();
|
||||
}
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
} finally {
|
||||
jdbc.close();
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static int updateBatch(String sql, List<List<Object>> params) throws BusinessException {
|
||||
JDBCAgent agent = new JDBCAgent(true, false);
|
||||
try {
|
||||
agent.batch1Prepare(sql);
|
||||
for(List<Object> param : params) {
|
||||
agent.batch2Add(param);
|
||||
}
|
||||
return agent.batch3Execute();
|
||||
} catch(Exception e) {
|
||||
throw new BusinessException(e);
|
||||
} finally {
|
||||
agent.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 不成熟,按照这个自己进行sql的编写,只需要获取字段是 数据库的 field000? 就行 根据cap4formkit。getFieldTableId
|
||||
* sub表也一样,只是多一步判断而已,如果只有一个重复表就不存在
|
||||
* @param formbean 根据表单编号获取
|
||||
* @param fields field1, "商品编号" 会解析成 field000x as field1, 如果不存在则直接用后面的
|
||||
* @param conditions
|
||||
* @param params
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
/*public static List<Map<String, Object>> selectSQL(FormBean formbean, Map<String, String> fields, List<FormCondition> conditions) throws Exception {
|
||||
List<Object> params = new ArrayList<Object>();
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("select ");
|
||||
for(String key : fields.keySet()) {
|
||||
String field = CAP4FormKit.getFieldTaleId(formbean, fields.get(key));
|
||||
if(StrKit.isNull(field)) {
|
||||
field = fields.get(key);
|
||||
}
|
||||
sb.append(" ").append(field).append(" as ").append(key).append(",");
|
||||
}
|
||||
sb.deleteCharAt(sb.lastIndexOf(","));
|
||||
sb.append(" from ").append(formbean.getMasterTableBean().getTableName());
|
||||
sb.append(" where 1 = 1 ");
|
||||
if(!StrKit.isNull(conditions)) {
|
||||
for(FormCondition c : conditions) {
|
||||
sb.append(ConditionKit.getWhere(formbean, c));
|
||||
params.add(c.getParam1());
|
||||
if(null != c.getParam2()) {
|
||||
params.add(c.getParam2());
|
||||
}
|
||||
}
|
||||
}
|
||||
return excuteSQL(sb.toString(), params);
|
||||
}*/
|
||||
|
||||
}
|
||||
293
src/main/java/com/seeyon/apps/assetsmap/kit/DateKit.java
Normal file
293
src/main/java/com/seeyon/apps/assetsmap/kit/DateKit.java
Normal file
@@ -0,0 +1,293 @@
|
||||
package com.seeyon.apps.assetsmap.kit;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 日期处理工具类
|
||||
* @Copyright Beijing Seeyon Software Co.,LTD
|
||||
*/
|
||||
public class DateKit {
|
||||
|
||||
private static SimpleDateFormat simple = new SimpleDateFormat("yyyyMMdd");
|
||||
|
||||
private static SimpleDateFormat sixFormat = new SimpleDateFormat("yyMMdd");
|
||||
|
||||
private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
private static SimpleDateFormat dayFormat = new SimpleDateFormat("yyyy-MM-dd");
|
||||
|
||||
private static SimpleDateFormat monthFormat = new SimpleDateFormat("yyyy-MM");
|
||||
|
||||
private static SimpleDateFormat weekDay = new SimpleDateFormat("MM-dd");
|
||||
|
||||
private static SimpleDateFormat hour = new SimpleDateFormat("HH:mm");
|
||||
|
||||
private static SimpleDateFormat detailDate = new SimpleDateFormat("yyyy-MM-dd HH:mm");
|
||||
|
||||
|
||||
private static final String dayNames[] = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五","星期六" };
|
||||
|
||||
public static int getYear(Date date) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(date);
|
||||
return cal.get(Calendar.YEAR);
|
||||
}
|
||||
|
||||
public static String getSixDate() {
|
||||
return getSixDate(null);
|
||||
}
|
||||
|
||||
public static String getSixDate(Date date) {
|
||||
if(null == date) {
|
||||
return sixFormat.format(new Date());
|
||||
}
|
||||
return sixFormat.format(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取这个时间属于一年的第几周
|
||||
* @param date
|
||||
* @return
|
||||
*/
|
||||
public static int getWeekNum(Date date) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(date);
|
||||
int week = cal.get(Calendar.WEEK_OF_YEAR);
|
||||
// 如果是星期天,那么需要减1
|
||||
if("星期日".equals(DateKit.getDayWeekName(date))) {
|
||||
week -= 1;
|
||||
}
|
||||
return week;
|
||||
}
|
||||
|
||||
/**
|
||||
* Description:
|
||||
*
|
||||
* <pre>
|
||||
* 获取一周
|
||||
* </pre>
|
||||
*
|
||||
* @param date
|
||||
* @return
|
||||
*/
|
||||
public static void getWeekInterval(Map<String, Object> param) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
// 判断要计算的日期是否是周日,如果是则减一天计算周六的,否则会出问题,计算到下一周去了
|
||||
int dayWeek = cal.get(Calendar.DAY_OF_WEEK);// 获得当前日期是一个星期的第几天
|
||||
if(1 == dayWeek) {
|
||||
cal.add(Calendar.DAY_OF_MONTH, -1);
|
||||
}
|
||||
// System.out.println("要计算日期为:" + sdf.format(cal.getTime())); // 输出要计算日期
|
||||
// 设置一个星期的第一天,按中国的习惯一个星期的第一天是星期一
|
||||
cal.setFirstDayOfWeek(Calendar.MONDAY);
|
||||
// 获得当前日期是一个星期的第几天
|
||||
int day = cal.get(Calendar.DAY_OF_WEEK);
|
||||
// 根据日历的规则,给当前日期减去星期几与一个星期第一天的差值
|
||||
cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);
|
||||
param.put("startDate", cal.getTime());
|
||||
// System.out.println("所在周星期一的日期:" + imptimeBegin);
|
||||
cal.add(Calendar.DATE, 6);
|
||||
param.put("endDate", cal.getTime());
|
||||
// System.out.println("所在周星期日的日期:" + imptimeEnd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Description:
|
||||
*
|
||||
* <pre>
|
||||
* 根据传入的日期,获取当前日期所在的一周时间段
|
||||
* </pre>
|
||||
*
|
||||
* @param date
|
||||
* @return
|
||||
*/
|
||||
public static void getWeekInterval(Map<String, Object> param, Date now) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(now);
|
||||
// 判断要计算的日期是否是周日,如果是则减一天计算周六的,否则会出问题,计算到下一周去了
|
||||
int dayWeek = cal.get(Calendar.DAY_OF_WEEK);// 获得当前日期是一个星期的第几天
|
||||
if(1 == dayWeek) {
|
||||
cal.add(Calendar.DAY_OF_MONTH, -1);
|
||||
}
|
||||
// System.out.println("要计算日期为:" + sdf.format(cal.getTime())); // 输出要计算日期
|
||||
// 设置一个星期的第一天,按中国的习惯一个星期的第一天是星期一
|
||||
cal.setFirstDayOfWeek(Calendar.MONDAY);
|
||||
// 获得当前日期是一个星期的第几天
|
||||
int day = cal.get(Calendar.DAY_OF_WEEK);
|
||||
// 根据日历的规则,给当前日期减去星期几与一个星期第一天的差值
|
||||
cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);
|
||||
String time = DateKit.getDayDate(cal.getTime()) + " 00:00:00";
|
||||
try {
|
||||
param.put("beginDate", DateKit.getdayDate(time));
|
||||
} catch(Exception e) {
|
||||
// TODO
|
||||
}
|
||||
// System.out.println("所在周星期一的日期:" + imptimeBegin);
|
||||
cal.add(Calendar.DATE, 6);
|
||||
time = DateKit.getDayDate(cal.getTime()) + " 23:59:59";
|
||||
try {
|
||||
param.put("endDate", DateKit.getdayDate(time));
|
||||
} catch(Exception e) {
|
||||
//
|
||||
}
|
||||
// System.out.println("所在周星期日的日期:" + imptimeEnd);
|
||||
}
|
||||
|
||||
public static String getSimpleDate(Date date) {
|
||||
if(date == null) {
|
||||
return "";
|
||||
}
|
||||
return simple.format(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* 给日志格式化使用
|
||||
* @param date
|
||||
* @return
|
||||
*/
|
||||
public static String getDate4Cal(Date date) {
|
||||
if(date == null) {
|
||||
return "";
|
||||
}
|
||||
return hour.format(date);
|
||||
}
|
||||
|
||||
public static String getDateString(Date date) {
|
||||
if(date == null) {
|
||||
return "";
|
||||
}
|
||||
return sdf.format(date);
|
||||
}
|
||||
|
||||
public static String getDayDate(Date date) {
|
||||
if(date == null) {
|
||||
return "";
|
||||
}
|
||||
return dayFormat.format(date);
|
||||
}
|
||||
|
||||
public static String getWeekDay(Date date) {
|
||||
if(date == null) {
|
||||
return "";
|
||||
}
|
||||
return weekDay.format(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Description:
|
||||
*
|
||||
* <pre>
|
||||
* 获取多少天以后的日期
|
||||
* </pre>
|
||||
*
|
||||
* @param day
|
||||
* @return
|
||||
*/
|
||||
public static Date getDayAfter(int day) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.add(Calendar.DATE, day);
|
||||
return cal.getTime();
|
||||
}
|
||||
// 获得某天的几天后
|
||||
public static Date getDayAfter(Date d, int day) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(d);
|
||||
cal.add(Calendar.DATE, day);
|
||||
return cal.getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取一个月有多少天
|
||||
* @param year
|
||||
* @param month
|
||||
* @return
|
||||
*/
|
||||
public static int getDaysByYearMonth(int year, int month) {
|
||||
Calendar a = Calendar.getInstance();
|
||||
a.set(Calendar.YEAR, year);
|
||||
a.set(Calendar.MONTH, month);
|
||||
a.set(Calendar.DATE, 1);
|
||||
a.roll(Calendar.DATE, -1);
|
||||
int maxDate = a.get(Calendar.DATE);
|
||||
return maxDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取今天是星期几
|
||||
* @param date
|
||||
* @return
|
||||
*/
|
||||
public static String getDayWeekName(Date date) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(date);
|
||||
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1;
|
||||
if(dayOfWeek < 0)
|
||||
dayOfWeek = 0;
|
||||
return dayNames[dayOfWeek];
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析时间,先解析yyyy-MM-dd HH:mm:ss
|
||||
* @param dateStr
|
||||
* @return
|
||||
* @throws ParseException
|
||||
* @throws Exception
|
||||
*/
|
||||
public static Date getdayDate(String dateStr) throws Exception {
|
||||
try {
|
||||
return sdf.parse(dateStr);
|
||||
} catch(Exception e) {
|
||||
try {
|
||||
return detailDate.parse(dateStr);
|
||||
} catch(Exception e1) {
|
||||
try {
|
||||
return dayFormat.parse(dateStr);
|
||||
} catch(Exception e2) {
|
||||
try {
|
||||
return simple.parse(dateStr);
|
||||
}
|
||||
catch(Exception e3) {
|
||||
return monthFormat.parse(dateStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据时间获取周区间字符串
|
||||
* @param now
|
||||
* @return 第XX周:2018-08-27至2018-09-02
|
||||
*/
|
||||
public static String getWeekNumAndDateZone(Date now) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("第");
|
||||
sb.append(getWeekNum(now));
|
||||
sb.append("周:");
|
||||
Map<String, Object> param = new HashMap<String, Object>();
|
||||
getWeekInterval(param, now);
|
||||
Date beginDate = (Date)param.get("beginDate");
|
||||
Date endDate = (Date)param.get("endDate");
|
||||
sb.append(dayFormat.format(beginDate));
|
||||
sb.append("至");
|
||||
sb.append(dayFormat.format(endDate));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据日期和时间获取一个返回该日期该时间的date
|
||||
* @param d 日期
|
||||
* @param time 时间 HH:mm格式
|
||||
* @return d日期+time时间
|
||||
* @throws ParseException
|
||||
*/
|
||||
public static Date getDateFromTime(Date d, String time) throws ParseException {
|
||||
String dateTime = dayFormat.format(d) + " " + time;
|
||||
return detailDate.parse(dateTime);
|
||||
}
|
||||
}
|
||||
115
src/main/java/com/seeyon/apps/assetsmap/kit/StrKit.java
Normal file
115
src/main/java/com/seeyon/apps/assetsmap/kit/StrKit.java
Normal file
@@ -0,0 +1,115 @@
|
||||
package com.seeyon.apps.assetsmap.kit;
|
||||
|
||||
import org.apache.tools.ant.util.DateUtils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @date 2018年5月23日上午9:05:01
|
||||
* @Copyright Beijing Seeyon Software Co.,LTD
|
||||
*/
|
||||
public class StrKit {
|
||||
|
||||
public static String str(Object o) {
|
||||
if(o == null) {
|
||||
return "";
|
||||
}
|
||||
if(o instanceof Date) {
|
||||
return DateUtils.format((Date) o, "yyyy-MM-dd HH:mm:ss");
|
||||
}
|
||||
if(o instanceof String) {
|
||||
return (String)o;
|
||||
}
|
||||
return o.toString();
|
||||
}
|
||||
|
||||
public static float toFloat(Object o) {
|
||||
if(o == null) {
|
||||
return 0f;
|
||||
} else if(o instanceof Float) {
|
||||
return (Float)o;
|
||||
} else if(o instanceof String) {
|
||||
return Float.valueOf((String)o);
|
||||
} else if(o instanceof BigDecimal) {
|
||||
return ((BigDecimal)o).floatValue();
|
||||
}
|
||||
return 0f;
|
||||
}
|
||||
|
||||
public static Long toLong(Object o) {
|
||||
if(null == o) {
|
||||
return 0L;
|
||||
} else if(o instanceof Long) {
|
||||
return (Long)o;
|
||||
} else if(o instanceof String) {
|
||||
if("".equals(o)) {
|
||||
return 0L;
|
||||
}
|
||||
return Long.valueOf((String)o);
|
||||
} else if(o instanceof BigDecimal) {
|
||||
return ((BigDecimal)o).longValue();
|
||||
}
|
||||
return 0L;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取int值,为空返回0
|
||||
* @param obj 对象
|
||||
* @return
|
||||
*/
|
||||
public static Integer toInteger(Object obj) {
|
||||
if(obj == null) {
|
||||
return 0;
|
||||
} else if(obj instanceof Long){
|
||||
return ((Long)obj).intValue();
|
||||
} else if(obj instanceof BigDecimal) {
|
||||
return ((BigDecimal)obj).intValue();
|
||||
}else if(obj instanceof String) {
|
||||
String o = (String) obj;
|
||||
if("".equals(o)) {
|
||||
return 0;
|
||||
} else {
|
||||
try {
|
||||
return Integer.valueOf((String) obj);
|
||||
} catch(Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else if(obj instanceof Integer) {
|
||||
return (Integer) obj;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static List<?> toList(Object o) {
|
||||
if(o == null) {
|
||||
return null;
|
||||
} else if(o instanceof List) {
|
||||
return (List<?>) o;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断对象是否为空
|
||||
* @param o
|
||||
* @return
|
||||
*/
|
||||
public static boolean isNull(Object o) {
|
||||
if(null == o) {
|
||||
return true;
|
||||
}
|
||||
if(o instanceof String) {
|
||||
return "".equals((String) o);
|
||||
}
|
||||
if(o instanceof Collection) {
|
||||
// 集合数量为0 则为空
|
||||
return ((Collection<?>) o).size() == 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,158 +1,469 @@
|
||||
package com.seeyon.apps.assetsmap.service;
|
||||
|
||||
import cn.hutool.log.Log;
|
||||
import com.seeyon.apps.assetsmap.config.AssetsMapConfigProvider;
|
||||
import com.seeyon.apps.assetsmap.constants.AssetsMapConstans;
|
||||
import com.seeyon.apps.assetsmap.vo.AssetsCatagory;
|
||||
import com.seeyon.apps.assetsmap.vo.AssetsItem;
|
||||
import com.seeyon.apps.assetsmap.vo.BoundsQueryVo;
|
||||
import com.seeyon.apps.assetsmap.vo.RegionVo;
|
||||
import com.seeyon.ctp.common.AppContext;
|
||||
import com.seeyon.ctp.common.exceptions.BusinessException;
|
||||
import com.seeyon.ctp.organization.bo.V3xOrgDepartment;
|
||||
import com.seeyon.ctp.common.po.ctpenumnew.CtpEnumItem;
|
||||
import com.seeyon.ctp.organization.bo.V3xOrgAccount;
|
||||
import com.seeyon.ctp.organization.manager.OrgManager;
|
||||
import com.seeyon.ctp.util.JDBCAgent;
|
||||
import com.seeyon.utils.form.*;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class AssetsQueryService {
|
||||
|
||||
private AssetsMapConfigProvider configProvider = (AssetsMapConfigProvider) AppContext.getBean("assetsMapConfigProvider");
|
||||
private OrgManager orgManager = (OrgManager) AppContext.getBean("orgManager");
|
||||
private static final Log log = Log.get(AssetsQueryService.class);
|
||||
// 部门名称缓存,避免 N+1 查询
|
||||
private Map<Long, String> deptCache = new HashMap<>();
|
||||
|
||||
private String getFormNo(){
|
||||
return configProvider.getBizConfigByKey(AssetsMapConstans.ASSETSFORMNO);
|
||||
}
|
||||
|
||||
private TableContext getMasterTableContext() throws Exception {
|
||||
return FormTableExecutor.master(getFormNo());
|
||||
}
|
||||
|
||||
public List<RegionVo> queryAllZoneAssets() throws Exception {
|
||||
System.out.println("表单编码为:" + getFormNo());
|
||||
TableContext tableContext = FormTableExecutor.master(getFormNo());
|
||||
List<FormColumn> formColumns = FormTableExecutor.query(tableContext,null, null, true);
|
||||
List<RegionVo> regionVos = new ArrayList<>();
|
||||
List<FormWhereCondition> conditions = buildQueryCondition();
|
||||
List<FormColumn> formColumns = FormTableExecutor.query(tableContext, null, conditions, true);
|
||||
System.out.println("查询出的数据条数:" + formColumns.size());
|
||||
|
||||
// 用 Map 做 O(1) 查找,替代 List 遍历
|
||||
Map<String, RegionVo> regionMap = new HashMap<>();
|
||||
|
||||
for (FormColumn formColumn : formColumns) {
|
||||
Map<String, Object> fieldsMap = formColumn.getFieldsMap();
|
||||
if(fieldsMap == null) {
|
||||
if (fieldsMap == null) {
|
||||
continue;
|
||||
}
|
||||
upsertRegionVos(regionVos,fieldsMap);
|
||||
upsertRegionVos(regionMap, fieldsMap);
|
||||
}
|
||||
return regionVos;
|
||||
return new ArrayList<>(regionMap.values());
|
||||
}
|
||||
|
||||
public void upsertRegionVos(List<RegionVo> regionVos, Map<String, Object> fieldsMap) {
|
||||
private List<FormWhereCondition> buildQueryCondition() {
|
||||
long currentAccountId = AppContext.currentAccountId();
|
||||
List<FormWhereCondition> conditions = new ArrayList<>();
|
||||
conditions.add(FormWhereCondition.build().display("所属单位-").value(currentAccountId).concatFactor(ClauseFactor.OR));
|
||||
conditions.add(FormWhereCondition.build().display("管理单位-").value(currentAccountId).concatFactor(ClauseFactor.OR));
|
||||
return conditions;
|
||||
}
|
||||
|
||||
String latStr = (String) fieldsMap.get("纬度");
|
||||
String lngStr = (String) fieldsMap.get("经度");
|
||||
/**
|
||||
* 视口懒加载:通过数据库层经纬度范围过滤,只查询视口内的资产
|
||||
* 生成 SQL: WHERE 纬度 >= south AND 纬度 <= north AND 经度 >= west AND 经度 <= east
|
||||
*/
|
||||
public List<RegionVo> queryAssetsByBounds(BoundsQueryVo vo) throws Exception {
|
||||
TableContext tableContext = FormTableExecutor.master(getFormNo());
|
||||
List<FormWhereCondition> conditions = new ArrayList<>();
|
||||
// 如果传了 assetId,按 资产编号 精确查询,忽略经纬度范围
|
||||
if (StringUtils.isNotBlank(vo.getAssetId())) {
|
||||
conditions.add(FormWhereCondition.build().display("资产编号").value(vo.getAssetId()));
|
||||
} else {
|
||||
conditions.add(FormWhereCondition.build().display("经度-").between(vo.getWest(), vo.getEast()));
|
||||
conditions.add(FormWhereCondition.build().display("纬度-").between(vo.getSouth(), vo.getNorth()));
|
||||
}
|
||||
conditions.add(FormWhereCondition.build().display("经度-").clauseFactor(ClauseFactor.NOT_NULL));
|
||||
conditions.add(FormWhereCondition.build().display("纬度-").clauseFactor(ClauseFactor.NOT_NULL));
|
||||
// 代码层过滤权限,避免 LIKE 导致索引失效
|
||||
boolean showAll = showAll();
|
||||
log.info("是否允许查看所有数据: " + showAll);
|
||||
final String permIdStr = showAll ? null : (AppContext.currentAccountId() + "");
|
||||
if (StringUtils.isNotBlank(vo.getOwner())) {
|
||||
conditions.add(FormWhereCondition.build().display("所属单位").value(vo.getOwner()));
|
||||
}
|
||||
|
||||
// 1️⃣ 经纬度必须有
|
||||
if (StringUtils.isAnyBlank(latStr, lngStr)) {
|
||||
if (StringUtils.isNotBlank(vo.getLevel2())) {
|
||||
conditions.add(FormWhereCondition.build().display("资产类型二级").value(vo.getLevel2()));
|
||||
}
|
||||
if (StringUtils.isNotBlank(vo.getLevel1())) {
|
||||
conditions.add(FormWhereCondition.build().display("资产类型一级").value(vo.getLevel1()));
|
||||
}
|
||||
if (StringUtils.isNotBlank(vo.getLevel3())) {
|
||||
conditions.add(FormWhereCondition.build().display("资产分类-").value(vo.getLevel3()));
|
||||
}
|
||||
System.out.println("开始查询资产数据");
|
||||
List<FormColumn> formColumns = FormTableExecutor.query(tableContext, null, conditions, true);
|
||||
|
||||
// 代码层过滤权限(当前单位及下级单位)
|
||||
if (!showAll && formColumns != null) {
|
||||
List<String> unitIds = getCurrentAndChildUnitIds();
|
||||
formColumns = formColumns.stream()
|
||||
.filter(col -> {
|
||||
Map<String, Object> fields = col.getFieldsMap();
|
||||
if (fields == null) return false;
|
||||
Object permObj = fields.get("查看权限-选单位");
|
||||
String perm = permObj == null ? null : permObj.toString();
|
||||
return hasPermission(perm, unitIds);
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
log.info("权限过滤后的数据条数: " + formColumns.size());
|
||||
Map<String, RegionVo> regionMap = new HashMap<>();
|
||||
for (FormColumn formColumn : formColumns) {
|
||||
Map<String, Object> fieldsMap = formColumn.getFieldsMap();
|
||||
if (fieldsMap == null) continue;
|
||||
upsertRegionVos(regionMap, fieldsMap);
|
||||
}
|
||||
log.info("返回资产数据结果");
|
||||
return new ArrayList<>(regionMap.values());
|
||||
}
|
||||
|
||||
private boolean showAll() throws Exception {
|
||||
V3xOrgAccount currentAccount = orgManager.getAccountById(AppContext.currentAccountId());
|
||||
if(currentAccount == null) {
|
||||
return false;
|
||||
}else {
|
||||
return currentAccount.getName().contains("国清办")
|
||||
|| currentAccount.getName().contains("国资局")
|
||||
|| currentAccount.getName().contains("软件开发");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前登录者单位及其所有下级单位的ID列表
|
||||
*/
|
||||
private List<String> getCurrentAndChildUnitIds() {
|
||||
List<String> ids = new ArrayList<>();
|
||||
long currentAccountId = AppContext.currentAccountId();
|
||||
JDBCAgent jdbcAgent = new JDBCAgent();
|
||||
try {
|
||||
// 查当前单位的 path
|
||||
jdbcAgent.execute("select path from org_unit where id = ?", currentAccountId);
|
||||
List list = jdbcAgent.resultSetToList();
|
||||
if (list == null || list.isEmpty()) {
|
||||
ids.add(String.valueOf(currentAccountId));
|
||||
return ids;
|
||||
}
|
||||
Map unitMap = (Map) list.get(0);
|
||||
String rootPath = unitMap.get("path") + "";
|
||||
|
||||
// 查所有子单位
|
||||
jdbcAgent.execute("select id from org_unit where path like ?", rootPath + "%");
|
||||
list = jdbcAgent.resultSetToList();
|
||||
if (list != null) {
|
||||
for (Object o : list) {
|
||||
Map map = (Map) o;
|
||||
ids.add(map.get("id") + "");
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
ids.add(String.valueOf(currentAccountId));
|
||||
} finally {
|
||||
jdbcAgent.close();
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查权限字段是否包含当前单位或下级单位
|
||||
* permField: 逗号分隔的单位ID字符串,如 "100,200,300"
|
||||
* unitIds: 当前单位及下级单位ID列表
|
||||
*/
|
||||
private boolean hasPermission(String permField, List<String> unitIds) {
|
||||
if (StringUtils.isBlank(permField) || unitIds == null || unitIds.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
// 用逗号分隔后逐一匹配
|
||||
String[] permParts = permField.split(",");
|
||||
for (String part : permParts) {
|
||||
String trimmed = part.trim();
|
||||
if (unitIds.contains(trimmed)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存资产边界数据到表单字段"资产边界数据"
|
||||
* polygonData: JSON格式,包含polygon坐标和color颜色
|
||||
*/
|
||||
public void saveAssetPolygon(String assetId, String polygonData) throws Exception {
|
||||
if (StringUtils.isBlank(assetId)) {
|
||||
throw new IllegalArgumentException("assetId不能为空");
|
||||
}
|
||||
List<FormUpdateField> updateFields = new ArrayList<>();
|
||||
updateFields.add(FormUpdateField.build().display("资产边界数据").value(polygonData));
|
||||
List<FormWhereCondition> conditions = new ArrayList<>();
|
||||
conditions.add(FormWhereCondition.build().display("id").value(assetId));
|
||||
FormTableExecutor.update(getMasterTableContext(),updateFields,conditions);
|
||||
}
|
||||
|
||||
|
||||
public String getDetailBaseUrlByAssetsType(String assetsType) throws Exception {
|
||||
TableContext master = FormTableExecutor.master(configProvider.getBizConfigByKey(AssetsMapConstans.ASSETSDETAILURLCONFIGFORMNO));
|
||||
List<FormWhereCondition> conditions = new ArrayList<>();
|
||||
if(StringUtils.isBlank(assetsType)) {
|
||||
conditions.add(FormWhereCondition.build().display("资产类型").value("不动产"));
|
||||
}else {
|
||||
conditions.add(FormWhereCondition.build().display("资产类型").value(assetsType));
|
||||
}
|
||||
FormColumn formColumn = FormTableExecutor.queryOne(master, conditions, true);
|
||||
if(formColumn == null) {
|
||||
return null;
|
||||
}
|
||||
Object urlObj = formColumn.getFieldsMap().get("前置地址");
|
||||
return urlObj == null ? null : urlObj.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询单个资产的边界数据
|
||||
*/
|
||||
public Map<String, String> getAssetBound(String assetId) throws Exception {
|
||||
if (StringUtils.isBlank(assetId)) {
|
||||
return null;
|
||||
}
|
||||
TableContext tableContext = FormTableExecutor.master(getFormNo());
|
||||
List<FormWhereCondition> conditions = new ArrayList<>();
|
||||
conditions.add(FormWhereCondition.build().display("id").value(assetId));
|
||||
FormColumn formColumn = FormTableExecutor.queryOne(tableContext, conditions, true);
|
||||
if (formColumn == null) {
|
||||
log.info("getAssetBound: 未查到记录, assetId=" + assetId);
|
||||
return null;
|
||||
}
|
||||
Map<String, Object> fieldsMap = formColumn.getFieldsMap();
|
||||
if (fieldsMap == null) {
|
||||
return null;
|
||||
}
|
||||
log.info("getAssetBound: 查到记录, assetId=" + assetId + ", 资产编号=" + fieldsMap.get("资产编号") + ", 资产名称=" + fieldsMap.get("资产名称"));
|
||||
log.info("getAssetBound: 资产边界数据字段值=" + fieldsMap.get("资产边界数据") + ", 类型=" + (fieldsMap.get("资产边界数据") == null ? "null" : fieldsMap.get("资产边界数据").getClass().getName()));
|
||||
Object boundObj = fieldsMap.get("资产边界数据");
|
||||
String boundData = boundObj == null ? null : boundObj.toString();
|
||||
Map<String, String> result = new HashMap<>();
|
||||
result.put("boundData", boundData);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回当前登录者单位的树形结构
|
||||
* path 每4字符代表一个层级,如 0000 → 00000001 → 000000010001
|
||||
*/
|
||||
public List<Map<String, Object>> getDeptSelectOptions() throws BusinessException {
|
||||
long currentAccountId = AppContext.currentAccountId();
|
||||
JDBCAgent jdbcAgent = new JDBCAgent();
|
||||
try {
|
||||
// 查当前单位的 path
|
||||
jdbcAgent.execute("select path from org_unit where id = ?", currentAccountId);
|
||||
List list = jdbcAgent.resultSetToList();
|
||||
if (list == null || list.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
Map unitMap = (Map) list.get(0);
|
||||
String rootPath = unitMap.get("path") + "";
|
||||
|
||||
// 查所有子单位
|
||||
jdbcAgent.execute("select id, name, path from org_unit where path like ?", rootPath + "%");
|
||||
list = jdbcAgent.resultSetToList();
|
||||
|
||||
// 用 LinkedHashMap 保持插入顺序,path → node
|
||||
Map<String, Map<String, Object>> nodeMap = new LinkedHashMap<>();
|
||||
for (Object o : list) {
|
||||
Map map = (Map) o;
|
||||
String path = map.get("path") + "";
|
||||
Map<String, Object> node = new LinkedHashMap<>();
|
||||
node.put("id", map.get("id") + "");
|
||||
node.put("name", map.get("name") + "");
|
||||
node.put("path", path);
|
||||
node.put("children", new ArrayList<Map<String, Object>>());
|
||||
nodeMap.put(path, node);
|
||||
}
|
||||
|
||||
// 按 path 长度排序(浅层先处理),逐个挂到父节点
|
||||
List<Map<String, Object>> roots = new ArrayList<>();
|
||||
List<String> sortedPaths = new ArrayList<>(nodeMap.keySet());
|
||||
Collections.sort(sortedPaths, Comparator.comparingInt(String::length));
|
||||
|
||||
for (String path : sortedPaths) {
|
||||
Map<String, Object> node = nodeMap.get(path);
|
||||
if (path.equals(rootPath) || path.length() <= 4) {
|
||||
roots.add(node);
|
||||
} else {
|
||||
// 父节点 path = 去掉最后4字符
|
||||
String parentPath = path.substring(0, path.length() - 4);
|
||||
Map<String, Object> parent = nodeMap.get(parentPath);
|
||||
if (parent != null) {
|
||||
((List<Map<String, Object>>) parent.get("children")).add(node);
|
||||
} else {
|
||||
// 找不到父节点,作为根节点
|
||||
roots.add(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
return roots;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return new ArrayList<>();
|
||||
} finally {
|
||||
jdbcAgent.close();
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String,AssetsCatagory> getAssetsCatagorySelectOptions() throws Exception {
|
||||
TableContext tableContext = FormTableExecutor.master(getFormNo());
|
||||
Map<String, CtpEnumItem> enumItemMap = EnumMapUtils.getEnumItemMap(tableContext.getTableBean(), "资产分类");
|
||||
if(enumItemMap == null) {
|
||||
return new HashMap<>();
|
||||
}
|
||||
Map<String,AssetsCatagory> resultMap = new HashMap<>();
|
||||
for (String key : enumItemMap.keySet()) {
|
||||
CtpEnumItem tempItem = enumItemMap.get(key);
|
||||
AssetsCatagory assetsCatagory = new AssetsCatagory();
|
||||
assetsCatagory.setId(tempItem.getId() + "");
|
||||
assetsCatagory.setShowValue(key);
|
||||
resultMap.put(key,assetsCatagory);
|
||||
}
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成 region 的唯一 key,用于 Map 查找
|
||||
*/
|
||||
private String regionKey(double lat, double lng, String address) {
|
||||
return lat + "_" + lng + "_" + address;
|
||||
}
|
||||
|
||||
/**
|
||||
* 优化:接收 Map 而非 List,O(1) 查找替代 O(n) 遍历
|
||||
*/
|
||||
public void upsertRegionVos(Map<String, RegionVo> regionMap, Map<String, Object> fieldsMap) {
|
||||
|
||||
BigDecimal latObj = (BigDecimal) fieldsMap.get("纬度-");
|
||||
BigDecimal lngObj = (BigDecimal) fieldsMap.get("经度-");
|
||||
|
||||
if (latObj == null || lngObj == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
double lat = Double.parseDouble(latStr);
|
||||
double lng = Double.parseDouble(lngStr);
|
||||
double lat = Double.parseDouble(latObj.toString());
|
||||
double lng = Double.parseDouble(lngObj.toString());
|
||||
|
||||
String address = (String) fieldsMap.get("位置详情");
|
||||
String owner = (String) fieldsMap.get("权属公司");
|
||||
Object addrObj = fieldsMap.get("所在位置");
|
||||
String address = addrObj == null ? null : addrObj.toString();
|
||||
|
||||
// 2️⃣ 地址 & 权属公司建议也做非空控制(关键!)
|
||||
if (StringUtils.isAnyBlank(address)) {
|
||||
if (StringUtils.isBlank(address)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String assetId = getStringValue(fieldsMap,"id");
|
||||
String assetId = getStringValue(fieldsMap, "id");
|
||||
AssetsItem newAsset = buildAssetsItem(fieldsMap);
|
||||
Long managerId = fieldsMap.get("运营单位") == null ? null : Long.parseLong(fieldsMap.get("运营单位") + "");
|
||||
String deptName = getDeptName(managerId);
|
||||
// 3️⃣ 查找区域
|
||||
for (RegionVo regionVo : regionVos) {
|
||||
|
||||
// 3.1 经纬度必须存在
|
||||
if (regionVo.getLat() == null || regionVo.getLng() == null) {
|
||||
continue;
|
||||
}
|
||||
String key = regionKey(lat, lng, address);
|
||||
RegionVo regionVo = regionMap.get(key);
|
||||
|
||||
boolean sameLocation =
|
||||
Double.compare(regionVo.getLat(), lat) == 0 &&
|
||||
Double.compare(regionVo.getLng(), lng) == 0;
|
||||
|
||||
// 3.2 地址 & 权属公司必须非空才参与匹配
|
||||
if (!sameLocation ||
|
||||
StringUtils.isAnyBlank(regionVo.getAddress())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean sameAddress = address.equals(regionVo.getAddress());
|
||||
|
||||
if (sameAddress) {
|
||||
|
||||
// 4️⃣ 判断资产是否存在
|
||||
if (regionVo != null) {
|
||||
// 判断资产是否已存在
|
||||
boolean exists = regionVo.getAssets().stream()
|
||||
.anyMatch(a -> a.getId().equals(assetId) );
|
||||
|
||||
.anyMatch(a -> a.getId().equals(assetId));
|
||||
if (!exists) {
|
||||
regionVo.getAssets().add(newAsset);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 5️⃣ 新建区域(这里可以放心,因为关键字段都有值)
|
||||
} else {
|
||||
// 新建区域
|
||||
RegionVo newRegion = new RegionVo();
|
||||
newRegion.setLat(lat);
|
||||
newRegion.setLng(lng);
|
||||
newRegion.setAddress(address);
|
||||
newRegion.setOwner(owner);
|
||||
newRegion.setManager(deptName);
|
||||
newRegion.setManager(getStringValue(fieldsMap,"管理单位"));
|
||||
|
||||
List<AssetsItem> assets = new ArrayList<>();
|
||||
assets.add(newAsset);
|
||||
newRegion.setAssets(assets);
|
||||
|
||||
regionVos.add(newRegion);
|
||||
regionMap.put(key, newRegion);
|
||||
}
|
||||
}
|
||||
|
||||
private String getDeptName(Long deptId) {
|
||||
if(deptId != null) {
|
||||
try {
|
||||
V3xOrgDepartment department = orgManager.getDepartmentById(deptId);
|
||||
if(department != null) {
|
||||
return department.getName();
|
||||
}
|
||||
}catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 优化:带缓存的单位名称查询
|
||||
*/
|
||||
private String getUnitName(Long unitId) {
|
||||
if (unitId == null) {
|
||||
return null;
|
||||
}
|
||||
if (deptCache.containsKey(unitId)) {
|
||||
return deptCache.get(unitId);
|
||||
}
|
||||
try {
|
||||
V3xOrgAccount account = orgManager.getAccountById(unitId);
|
||||
String name = account != null ? account.getName() : null;
|
||||
deptCache.put(unitId, name);
|
||||
return name;
|
||||
} catch (Exception e) {
|
||||
deptCache.put(unitId, null);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private AssetsItem buildAssetsItem(Map<String, Object> fieldsMap) {
|
||||
AssetsItem assetsItem = new AssetsItem();
|
||||
assetsItem.setId(getStringValue(fieldsMap,"id"));
|
||||
assetsItem.setArea(fieldsMap.get("资产面积") == null ? null : Double.parseDouble(fieldsMap.get("资产面积") + ""));
|
||||
assetsItem.setTenant(getStringValue(fieldsMap,"租户名称"));
|
||||
assetsItem.setPurpose(getStringValue(fieldsMap,"资产用途"));
|
||||
assetsItem.setRemark(getStringValue(fieldsMap,"备注"));
|
||||
assetsItem.setOwner(getStringValue(fieldsMap,"权属单位"));
|
||||
assetsItem.setAssetName(getStringValue(fieldsMap,"资产名称"));
|
||||
assetsItem.setAddress(getStringValue(fieldsMap,"位置详情"));
|
||||
String certNo = fieldsMap.get("权证号码") == null ? null : (String)fieldsMap.get("权证号码");
|
||||
// assetsItem.setManager(fieldsMap.get("运营单位") == null ? null : (String)fieldsMap.get("运营单位") + "");
|
||||
Long managerId = fieldsMap.get("运营单位") == null ? null : Long.parseLong(fieldsMap.get("运营单位") + "");
|
||||
assetsItem.setLat(getStringValue(fieldsMap,"纬度"));
|
||||
assetsItem.setLng(getStringValue(fieldsMap,"经度"));
|
||||
assetsItem.setManager(getDeptName(managerId));
|
||||
assetsItem.setCertNo(certNo);
|
||||
assetsItem.setStatus(getStringValue(fieldsMap,"资产状态"));
|
||||
assetsItem.setId(getStringValue(fieldsMap, "id"));
|
||||
assetsItem.setArea(fieldsMap.get("数量面积") == null ? null : Double.parseDouble(fieldsMap.get("数量面积") + ""));
|
||||
assetsItem.setAssetCode(getStringValue(fieldsMap, "资产编号"));
|
||||
assetsItem.setRemark(getStringValue(fieldsMap, "备注"));
|
||||
assetsItem.setAssetName(getStringValue(fieldsMap, "资产名称"));
|
||||
assetsItem.setAddress(getStringValue(fieldsMap, "所在位置"));
|
||||
assetsItem.setLat(Optional.ofNullable(fieldsMap.get("纬度-")).map(Object::toString).orElse(null));
|
||||
assetsItem.setLng(Optional.ofNullable(fieldsMap.get("经度-")).map(Object::toString).orElse(null));
|
||||
assetsItem.setManager(getStringValue(fieldsMap,"管理单位"));
|
||||
assetsItem.setAssetType(getStringValue(fieldsMap, "资产类型一级"));
|
||||
return assetsItem;
|
||||
}
|
||||
|
||||
private String getStringValue(Map<String, Object> fieldsMap, String key) {
|
||||
return fieldsMap.get(key) == null ? null : (String)fieldsMap.get(key);
|
||||
Object val = fieldsMap.get(key);
|
||||
return val == null ? null : val.toString();
|
||||
}
|
||||
|
||||
public Integer countAssets(String type) throws BusinessException {
|
||||
/**
|
||||
* 优化:一次查询全量数据,内存中分类计数,替代3次独立查询
|
||||
*/
|
||||
public Map<String, Integer> countAllStats() throws Exception {
|
||||
TableContext tableContext = FormTableExecutor.master(getFormNo());
|
||||
List<FormColumn> formColumns = FormTableExecutor.query(tableContext, null, null, true);
|
||||
|
||||
int total = 0;
|
||||
int rented = 0;
|
||||
int vacant = 0;
|
||||
|
||||
String rentedValue = EnumMapUtils.getEnumItemValueByDisplayValue(tableContext.getTableBean(), "资产状态", "已租");
|
||||
String vacantValue = EnumMapUtils.getEnumItemValueByDisplayValue(tableContext.getTableBean(), "资产状态", "待租");
|
||||
|
||||
for (FormColumn col : formColumns) {
|
||||
Map<String, Object> fields = col.getFieldsMap();
|
||||
if (fields == null) continue;
|
||||
total++;
|
||||
String status = fields.get("资产状态") == null ? null : fields.get("资产状态") + "";
|
||||
if (rentedValue != null && rentedValue.equals(status)) {
|
||||
rented++;
|
||||
} else if (vacantValue != null && vacantValue.equals(status)) {
|
||||
vacant++;
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Integer> result = new HashMap<>();
|
||||
result.put("total", total);
|
||||
result.put("rented", rented);
|
||||
result.put("vacant", vacant);
|
||||
return result;
|
||||
}
|
||||
|
||||
public Integer countAssets(String type) throws Exception {
|
||||
TableContext tableContext = FormTableExecutor.master(getFormNo());
|
||||
List<FormWhereCondition> conditions = new ArrayList<FormWhereCondition>();
|
||||
if(type == null || "0".equals(type)) {
|
||||
@@ -168,10 +479,76 @@ public class AssetsQueryService {
|
||||
return formColumns.size();
|
||||
}
|
||||
|
||||
public List<AssetsItem> queryAssetsByKeyword(String keyword) throws BusinessException {
|
||||
/**
|
||||
* 按筛选条件分页查询资产列表(不走视口),用于地图右侧列表展示
|
||||
* 返回格式: {records: [...], total: n}
|
||||
*/
|
||||
public Map<String, Object> queryAssetList(BoundsQueryVo vo) throws Exception {
|
||||
TableContext tableContext = FormTableExecutor.master(getFormNo());
|
||||
List<FormWhereCondition> conditions = new ArrayList<>();
|
||||
if (StringUtils.isNotBlank(vo.getOwner())) {
|
||||
conditions.add(FormWhereCondition.build().display("所属单位").value(vo.getOwner()));
|
||||
}
|
||||
if (StringUtils.isNotBlank(vo.getLevel1())) {
|
||||
conditions.add(FormWhereCondition.build().display("资产类型一级").value(vo.getLevel1()));
|
||||
}
|
||||
if (StringUtils.isNotBlank(vo.getLevel2())) {
|
||||
conditions.add(FormWhereCondition.build().display("资产类型二级").value(vo.getLevel2()));
|
||||
}
|
||||
if (StringUtils.isNotBlank(vo.getLevel3())) {
|
||||
conditions.add(FormWhereCondition.build().display("资产分类-").value(vo.getLevel3()));
|
||||
}
|
||||
if (StringUtils.isNotBlank(vo.getKeyword())) {
|
||||
conditions.add(FormWhereCondition.build().display("资产名称").value(vo.getKeyword()).clauseFactor(ClauseFactor.LIKE)
|
||||
.concatFactor(ClauseFactor.OR));
|
||||
conditions.add(FormWhereCondition.build().display("资产编号").value(vo.getKeyword()).clauseFactor(ClauseFactor.LIKE));
|
||||
}
|
||||
|
||||
// 先查全量用于权限过滤
|
||||
List<FormColumn> formColumns = FormTableExecutor.query(tableContext, null, conditions, true);
|
||||
|
||||
// 权限过滤(当前单位及下级单位)
|
||||
boolean showAll = showAll();
|
||||
if (!showAll) {
|
||||
List<String> unitIds = getCurrentAndChildUnitIds();
|
||||
formColumns = formColumns.stream()
|
||||
.filter(col -> {
|
||||
Map<String, Object> fields = col.getFieldsMap();
|
||||
if (fields == null) return false;
|
||||
String perm = (String) fields.get("查看权限-选单位");
|
||||
return hasPermission(perm, unitIds);
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
int total = formColumns.size();
|
||||
|
||||
// 分页
|
||||
int pageNum = vo.getPageNum() != null && vo.getPageNum() > 0 ? vo.getPageNum() : 1;
|
||||
int pageSize = vo.getPageSize() != null && vo.getPageSize() > 0 ? vo.getPageSize() : 10;
|
||||
int fromIndex = (pageNum - 1) * pageSize;
|
||||
int toIndex = Math.min(fromIndex + pageSize, total);
|
||||
|
||||
List<AssetsItem> records = new ArrayList<>();
|
||||
if (fromIndex < total) {
|
||||
List<FormColumn> pageColumns = formColumns.subList(fromIndex, toIndex);
|
||||
for (FormColumn col : pageColumns) {
|
||||
Map<String, Object> fieldsMap = col.getFieldsMap();
|
||||
if (fieldsMap == null) continue;
|
||||
records.add(buildAssetsItem(fieldsMap));
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("records", records);
|
||||
result.put("total", total);
|
||||
return result;
|
||||
}
|
||||
|
||||
public List<AssetsItem> queryAssetsByKeyword(String keyword) throws Exception {
|
||||
List<FormWhereCondition> conditions = new ArrayList<FormWhereCondition>();
|
||||
if(StringUtils.isNotBlank(keyword)){
|
||||
conditions.add(FormWhereCondition.build().display("位置详情").value(keyword).concatFactor(ClauseFactor.OR).clauseFactor(ClauseFactor.LIKE));
|
||||
conditions.add(FormWhereCondition.build().display("所在位置").value(keyword).concatFactor(ClauseFactor.OR).clauseFactor(ClauseFactor.LIKE));
|
||||
}
|
||||
TableContext tableContext = FormTableExecutor.master(getFormNo());
|
||||
List<FormColumn> formColumns = FormTableExecutor.pageQuery(tableContext,null, conditions, 1,10,true);
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.seeyon.apps.assetsmap.vo;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class AssetsCatagory {
|
||||
private String id;
|
||||
private String showValue;
|
||||
private Map<String,AssetsCatagory> children;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getShowValue() {
|
||||
return showValue;
|
||||
}
|
||||
|
||||
public void setShowValue(String showValue) {
|
||||
this.showValue = showValue;
|
||||
}
|
||||
|
||||
public Map<String, AssetsCatagory> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
public void setChildren(Map<String, AssetsCatagory> children) {
|
||||
this.children = children;
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package com.seeyon.apps.assetsmap.vo;
|
||||
|
||||
public class AssetsItem {
|
||||
private String id;
|
||||
private String assetCode;
|
||||
private String assetName;
|
||||
private Long regionId;
|
||||
private String purpose;
|
||||
@@ -15,6 +16,9 @@ public class AssetsItem {
|
||||
private String lng;
|
||||
private String lat;
|
||||
private String address;
|
||||
private String assetType;
|
||||
private String assetCategory;
|
||||
private String boundData;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
@@ -24,6 +28,14 @@ public class AssetsItem {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getAssetCode() {
|
||||
return assetCode;
|
||||
}
|
||||
|
||||
public void setAssetCode(String assetCode) {
|
||||
this.assetCode = assetCode;
|
||||
}
|
||||
|
||||
public Long getRegionId() {
|
||||
return regionId;
|
||||
}
|
||||
@@ -127,4 +139,28 @@ public class AssetsItem {
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public String getAssetType() {
|
||||
return assetType;
|
||||
}
|
||||
|
||||
public void setAssetType(String assetType) {
|
||||
this.assetType = assetType;
|
||||
}
|
||||
|
||||
public String getAssetCategory() {
|
||||
return assetCategory;
|
||||
}
|
||||
|
||||
public void setAssetCategory(String assetCategory) {
|
||||
this.assetCategory = assetCategory;
|
||||
}
|
||||
|
||||
public String getBoundData() {
|
||||
return boundData;
|
||||
}
|
||||
|
||||
public void setBoundData(String boundData) {
|
||||
this.boundData = boundData;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.seeyon.apps.assetsmap.vo;
|
||||
|
||||
public class BoundsQueryVo {
|
||||
private Double south;
|
||||
private Double west;
|
||||
private Double north;
|
||||
private Double east;
|
||||
private String owner;
|
||||
private String level1;
|
||||
private String level2;
|
||||
private String level3;
|
||||
private String assetId;
|
||||
private String keyword;
|
||||
private Integer pageNum;
|
||||
private Integer pageSize;
|
||||
|
||||
public Double getSouth() { return south; }
|
||||
public void setSouth(Double south) { this.south = south; }
|
||||
public Double getWest() { return west; }
|
||||
public void setWest(Double west) { this.west = west; }
|
||||
public Double getNorth() { return north; }
|
||||
public void setNorth(Double north) { this.north = north; }
|
||||
public Double getEast() { return east; }
|
||||
public void setEast(Double east) { this.east = east; }
|
||||
public String getOwner() { return owner; }
|
||||
public void setOwner(String owner) { this.owner = owner; }
|
||||
public String getLevel1() { return level1; }
|
||||
public void setLevel1(String level1) { this.level1 = level1; }
|
||||
public String getLevel2() { return level2; }
|
||||
public void setLevel2(String level2) { this.level2 = level2; }
|
||||
public String getLevel3() { return level3; }
|
||||
public void setLevel3(String level3) { this.level3 = level3; }
|
||||
public String getAssetId() { return assetId; }
|
||||
public void setAssetId(String assetId) { this.assetId = assetId; }
|
||||
public String getKeyword() { return keyword; }
|
||||
public void setKeyword(String keyword) { this.keyword = keyword; }
|
||||
public Integer getPageNum() { return pageNum; }
|
||||
public void setPageNum(Integer pageNum) { this.pageNum = pageNum; }
|
||||
public Integer getPageSize() { return pageSize; }
|
||||
public void setPageSize(Integer pageSize) { this.pageSize = pageSize; }
|
||||
}
|
||||
@@ -2,7 +2,15 @@ package com.seeyon.ctp.rest.resources.assetsmap;
|
||||
|
||||
import cn.hutool.log.Log;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.seeyon.aicloud.common.JsonUtils;
|
||||
import com.seeyon.apps.assetsmap.kit.CAP4FormKit;
|
||||
import com.seeyon.apps.assetsmap.service.AssetsQueryService;
|
||||
import com.seeyon.apps.assetsmap.vo.AssetsCatagory;
|
||||
import com.seeyon.apps.assetsmap.vo.BoundsQueryVo;
|
||||
import com.seeyon.cap4.form.bean.FormDataMasterBean;
|
||||
import com.seeyon.cap4.form.bean.FormFieldBean;
|
||||
import com.seeyon.cap4.form.service.CAP4FormManager;
|
||||
import com.seeyon.cap4.template.util.CAPFormUtil;
|
||||
import com.seeyon.ctp.common.AppContext;
|
||||
import com.seeyon.ctp.rest.resources.BaseResource;
|
||||
|
||||
@@ -10,12 +18,15 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import javax.ws.rs.*;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Path("/assetsRegion")
|
||||
@Produces({"application/json", "application/xml"})
|
||||
public class AssetsRegionResources extends BaseResource {
|
||||
|
||||
private static final Log log = Log.get(AssetsRegionResources.class);
|
||||
private CAP4FormManager cap4FormManager = (CAP4FormManager) AppContext.getBean("cap4FormManager");
|
||||
private AssetsQueryService assetsQueryService = (AssetsQueryService) AppContext.getBean("assetsQueryService");
|
||||
|
||||
|
||||
@@ -34,12 +45,82 @@ public class AssetsRegionResources extends BaseResource {
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/search")
|
||||
@Path("/getByBounds")
|
||||
@Produces({"application/json"})
|
||||
@Consumes({"application/json"})
|
||||
public Response search(JSONObject params) {
|
||||
public Response getByBounds(BoundsQueryVo vo){
|
||||
try {
|
||||
return this.success(this.assetsQueryService.queryAssetsByKeyword(params.getString("keyword")));
|
||||
log.info("按视口查询资产");
|
||||
return success(assetsQueryService.queryAssetsByBounds(vo));
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
e.printStackTrace();
|
||||
return fail("查询失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/queryAssetList")
|
||||
@Produces({"application/json"})
|
||||
@Consumes({"application/json"})
|
||||
public Response queryAssetList(BoundsQueryVo vo){
|
||||
try {
|
||||
return success(assetsQueryService.queryAssetList(vo));
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
e.printStackTrace();
|
||||
return fail("查询失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/getDeptOptions")
|
||||
@Produces({"application/json"})
|
||||
public Response getDeptOptions(){
|
||||
try {
|
||||
return success(assetsQueryService.getDeptSelectOptions());
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
e.printStackTrace();
|
||||
return fail("查询失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/getCategoryOptions")
|
||||
@Produces({"application/json"})
|
||||
public Response getCategoryOptions(){
|
||||
try {
|
||||
log.info("查询分类");
|
||||
Map<String, AssetsCatagory> resMap = assetsQueryService.getAssetsCatagorySelectOptions();
|
||||
log.info("查询结果: " + JsonUtils.toJSONString(resMap));
|
||||
return success(resMap);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
e.printStackTrace();
|
||||
return fail("查询失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/getAssetBound")
|
||||
@Produces({"application/json"})
|
||||
public Response getAssetBound(@QueryParam("assetId") String assetId){
|
||||
try {
|
||||
return success(assetsQueryService.getAssetBound(assetId));
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
e.printStackTrace();
|
||||
return fail("查询失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/search")
|
||||
@Produces({"application/json"})
|
||||
public Response search(@QueryParam("keyword") String keyword) {
|
||||
try {
|
||||
return this.success(this.assetsQueryService.queryAssetsByKeyword(keyword));
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), new Object[]{e});
|
||||
e.printStackTrace();
|
||||
@@ -47,6 +128,48 @@ public class AssetsRegionResources extends BaseResource {
|
||||
}
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/formBackFill")
|
||||
@Produces({"application/json"})
|
||||
@Consumes({"application/json"})
|
||||
public Response boundRefCallBack(Map<String, Object> params) {
|
||||
try {
|
||||
String masterId = (String) params.get("masterId");
|
||||
String fieldDisplay = (String) params.get("fieldDisplay");
|
||||
Object value = params.get("value");
|
||||
|
||||
FormDataMasterBean cacheFormData = cap4FormManager.getSessioMasterDataBean(Long.parseLong(masterId));
|
||||
FormFieldBean fieldBean = CAP4FormKit.getFieldBean(cacheFormData, fieldDisplay);
|
||||
Map<String, Object> displayValueMap = CAPFormUtil.getDisplayValueMap(value, fieldBean, null);
|
||||
cacheFormData.addFieldValue(fieldBean.getName(), value);
|
||||
|
||||
Map<String, Object> mainData = new HashMap<>();
|
||||
mainData.put(fieldBean.getName(), displayValueMap);
|
||||
|
||||
return success(mainData);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return fail("保存失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/saveAssetPolygon")
|
||||
@Produces({"application/json"})
|
||||
@Consumes({"application/json"})
|
||||
public Response saveAssetPolygon(JSONObject params){
|
||||
try {
|
||||
String assetId = params.getString("assetId");
|
||||
String polygonData = params.getString("polygonData");
|
||||
assetsQueryService.saveAssetPolygon(assetId, polygonData);
|
||||
return success("保存成功");
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
e.printStackTrace();
|
||||
return fail("保存失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Path("/countAssets")
|
||||
@GET
|
||||
@Produces({"application/json"})
|
||||
@@ -60,4 +183,30 @@ public class AssetsRegionResources extends BaseResource {
|
||||
return fail("查询失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Path("/countAllStats")
|
||||
@GET
|
||||
@Produces({"application/json"})
|
||||
public Response countAllStats(){
|
||||
try {
|
||||
return success(assetsQueryService.countAllStats());
|
||||
}catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
e.printStackTrace();
|
||||
return fail("查询失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Path("/getDetailBaseUrlByAssetsType")
|
||||
@GET
|
||||
@Produces({"application/json"})
|
||||
public Response getDetailBaseUrlByAssetsType(@QueryParam("assetsType")String assetsType){
|
||||
try {
|
||||
return success(assetsQueryService.getDetailBaseUrlByAssetsType(assetsType));
|
||||
}catch (Exception e) {
|
||||
log.error(e.getMessage(),e);
|
||||
e.printStackTrace();
|
||||
return fail("查询失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user