2026-05-21 16:37:40 +08:00
|
|
|
|
package com.seeyon.apps.assetsmap.service;
|
|
|
|
|
|
|
2026-06-18 16:26:31 +08:00
|
|
|
|
import cn.hutool.log.Log;
|
2026-05-21 16:37:40 +08:00
|
|
|
|
import com.seeyon.apps.assetsmap.config.AssetsMapConfigProvider;
|
|
|
|
|
|
import com.seeyon.apps.assetsmap.constants.AssetsMapConstans;
|
2026-06-18 16:26:31 +08:00
|
|
|
|
import com.seeyon.apps.assetsmap.vo.AssetsCatagory;
|
2026-05-21 16:37:40 +08:00
|
|
|
|
import com.seeyon.apps.assetsmap.vo.AssetsItem;
|
2026-06-18 16:26:31 +08:00
|
|
|
|
import com.seeyon.apps.assetsmap.vo.BoundsQueryVo;
|
2026-05-21 16:37:40 +08:00
|
|
|
|
import com.seeyon.apps.assetsmap.vo.RegionVo;
|
|
|
|
|
|
import com.seeyon.ctp.common.AppContext;
|
|
|
|
|
|
import com.seeyon.ctp.common.exceptions.BusinessException;
|
2026-06-18 16:26:31 +08:00
|
|
|
|
import com.seeyon.ctp.common.po.ctpenumnew.CtpEnumItem;
|
|
|
|
|
|
import com.seeyon.ctp.organization.bo.V3xOrgAccount;
|
2026-05-21 16:37:40 +08:00
|
|
|
|
import com.seeyon.ctp.organization.manager.OrgManager;
|
2026-06-18 16:26:31 +08:00
|
|
|
|
import com.seeyon.ctp.util.JDBCAgent;
|
2026-05-21 16:37:40 +08:00
|
|
|
|
import com.seeyon.utils.form.*;
|
2026-06-18 16:26:31 +08:00
|
|
|
|
import org.apache.commons.lang.StringUtils;
|
2026-05-21 16:37:40 +08:00
|
|
|
|
|
2026-06-18 16:26:31 +08:00
|
|
|
|
import java.math.BigDecimal;
|
|
|
|
|
|
import java.util.*;
|
|
|
|
|
|
import java.util.stream.Collectors;
|
2026-05-21 16:37:40 +08:00
|
|
|
|
|
|
|
|
|
|
public class AssetsQueryService {
|
|
|
|
|
|
|
|
|
|
|
|
private AssetsMapConfigProvider configProvider = (AssetsMapConfigProvider) AppContext.getBean("assetsMapConfigProvider");
|
|
|
|
|
|
private OrgManager orgManager = (OrgManager) AppContext.getBean("orgManager");
|
2026-06-18 16:26:31 +08:00
|
|
|
|
private static final Log log = Log.get(AssetsQueryService.class);
|
|
|
|
|
|
// 部门名称缓存,避免 N+1 查询
|
|
|
|
|
|
private Map<Long, String> deptCache = new HashMap<>();
|
2026-05-21 16:37:40 +08:00
|
|
|
|
|
|
|
|
|
|
private String getFormNo(){
|
|
|
|
|
|
return configProvider.getBizConfigByKey(AssetsMapConstans.ASSETSFORMNO);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-18 16:26:31 +08:00
|
|
|
|
private TableContext getMasterTableContext() throws Exception {
|
|
|
|
|
|
return FormTableExecutor.master(getFormNo());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-21 16:37:40 +08:00
|
|
|
|
public List<RegionVo> queryAllZoneAssets() throws Exception {
|
|
|
|
|
|
TableContext tableContext = FormTableExecutor.master(getFormNo());
|
2026-06-18 16:26:31 +08:00
|
|
|
|
List<FormWhereCondition> conditions = buildQueryCondition();
|
|
|
|
|
|
List<FormColumn> formColumns = FormTableExecutor.query(tableContext, null, conditions, true);
|
2026-05-21 16:37:40 +08:00
|
|
|
|
System.out.println("查询出的数据条数:" + formColumns.size());
|
2026-06-18 16:26:31 +08:00
|
|
|
|
|
|
|
|
|
|
// 用 Map 做 O(1) 查找,替代 List 遍历
|
|
|
|
|
|
Map<String, RegionVo> regionMap = new HashMap<>();
|
|
|
|
|
|
|
2026-05-21 16:37:40 +08:00
|
|
|
|
for (FormColumn formColumn : formColumns) {
|
|
|
|
|
|
Map<String, Object> fieldsMap = formColumn.getFieldsMap();
|
2026-06-18 16:26:31 +08:00
|
|
|
|
if (fieldsMap == null) {
|
2026-05-21 16:37:40 +08:00
|
|
|
|
continue;
|
|
|
|
|
|
}
|
2026-06-18 16:26:31 +08:00
|
|
|
|
upsertRegionVos(regionMap, fieldsMap);
|
2026-05-21 16:37:40 +08:00
|
|
|
|
}
|
2026-06-18 16:26:31 +08:00
|
|
|
|
return new ArrayList<>(regionMap.values());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
2026-05-21 16:37:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-18 16:26:31 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 视口懒加载:通过数据库层经纬度范围过滤,只查询视口内的资产
|
|
|
|
|
|
* 生成 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()));
|
|
|
|
|
|
}
|
2026-05-21 16:37:40 +08:00
|
|
|
|
|
2026-06-18 16:26:31 +08:00
|
|
|
|
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);
|
2026-05-21 16:37:40 +08:00
|
|
|
|
|
2026-06-18 16:26:31 +08:00
|
|
|
|
// 代码层过滤权限(当前单位及下级单位)
|
|
|
|
|
|
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("软件开发");
|
2026-05-21 16:37:40 +08:00
|
|
|
|
}
|
2026-06-18 16:26:31 +08:00
|
|
|
|
}
|
2026-05-21 16:37:40 +08:00
|
|
|
|
|
2026-06-18 16:26:31 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 获取当前登录者单位及其所有下级单位的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") + "";
|
2026-05-21 16:37:40 +08:00
|
|
|
|
|
2026-06-18 16:26:31 +08:00
|
|
|
|
// 查所有子单位
|
|
|
|
|
|
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;
|
|
|
|
|
|
}
|
2026-05-21 16:37:40 +08:00
|
|
|
|
|
2026-06-18 16:26:31 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 检查权限字段是否包含当前单位或下级单位
|
|
|
|
|
|
* 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;
|
2026-05-21 16:37:40 +08:00
|
|
|
|
}
|
2026-06-18 16:26:31 +08:00
|
|
|
|
// 用逗号分隔后逐一匹配
|
|
|
|
|
|
String[] permParts = permField.split(",");
|
|
|
|
|
|
for (String part : permParts) {
|
|
|
|
|
|
String trimmed = part.trim();
|
|
|
|
|
|
if (unitIds.contains(trimmed)) {
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2026-05-21 16:37:40 +08:00
|
|
|
|
|
2026-06-18 16:26:31 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 保存资产边界数据到表单字段"资产边界数据"
|
|
|
|
|
|
* 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);
|
|
|
|
|
|
}
|
2026-05-21 16:37:40 +08:00
|
|
|
|
|
|
|
|
|
|
|
2026-06-18 16:26:31 +08:00
|
|
|
|
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();
|
|
|
|
|
|
}
|
2026-05-21 16:37:40 +08:00
|
|
|
|
|
2026-06-18 16:26:31 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 查询单个资产的边界数据
|
|
|
|
|
|
*/
|
|
|
|
|
|
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<>();
|
2026-05-21 16:37:40 +08:00
|
|
|
|
}
|
2026-06-18 16:26:31 +08:00
|
|
|
|
Map unitMap = (Map) list.get(0);
|
|
|
|
|
|
String rootPath = unitMap.get("path") + "";
|
2026-05-21 16:37:40 +08:00
|
|
|
|
|
2026-06-18 16:26:31 +08:00
|
|
|
|
// 查所有子单位
|
|
|
|
|
|
jdbcAgent.execute("select id, name, path from org_unit where path like ?", rootPath + "%");
|
|
|
|
|
|
list = jdbcAgent.resultSetToList();
|
2026-05-21 16:37:40 +08:00
|
|
|
|
|
2026-06-18 16:26:31 +08:00
|
|
|
|
// 用 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);
|
|
|
|
|
|
}
|
2026-05-21 16:37:40 +08:00
|
|
|
|
|
2026-06-18 16:26:31 +08:00
|
|
|
|
// 按 path 长度排序(浅层先处理),逐个挂到父节点
|
|
|
|
|
|
List<Map<String, Object>> roots = new ArrayList<>();
|
|
|
|
|
|
List<String> sortedPaths = new ArrayList<>(nodeMap.keySet());
|
|
|
|
|
|
Collections.sort(sortedPaths, Comparator.comparingInt(String::length));
|
2026-05-21 16:37:40 +08:00
|
|
|
|
|
2026-06-18 16:26:31 +08:00
|
|
|
|
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);
|
|
|
|
|
|
}
|
2026-05-21 16:37:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-06-18 16:26:31 +08:00
|
|
|
|
return roots;
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
|
return new ArrayList<>();
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
jdbcAgent.close();
|
2026-05-21 16:37:40 +08:00
|
|
|
|
}
|
2026-06-18 16:26:31 +08:00
|
|
|
|
}
|
2026-05-21 16:37:40 +08:00
|
|
|
|
|
2026-06-18 16:26:31 +08:00
|
|
|
|
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;
|
|
|
|
|
|
}
|
2026-05-21 16:37:40 +08:00
|
|
|
|
|
2026-06-18 16:26:31 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 生成 region 的唯一 key,用于 Map 查找
|
|
|
|
|
|
*/
|
|
|
|
|
|
private String regionKey(double lat, double lng, String address) {
|
|
|
|
|
|
return lat + "_" + lng + "_" + address;
|
2026-05-21 16:37:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-18 16:26:31 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 优化:接收 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(latObj.toString());
|
|
|
|
|
|
double lng = Double.parseDouble(lngObj.toString());
|
|
|
|
|
|
|
|
|
|
|
|
Object addrObj = fieldsMap.get("所在位置");
|
|
|
|
|
|
String address = addrObj == null ? null : addrObj.toString();
|
|
|
|
|
|
|
|
|
|
|
|
if (StringUtils.isBlank(address)) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
String assetId = getStringValue(fieldsMap, "id");
|
|
|
|
|
|
AssetsItem newAsset = buildAssetsItem(fieldsMap);
|
|
|
|
|
|
|
|
|
|
|
|
String key = regionKey(lat, lng, address);
|
|
|
|
|
|
RegionVo regionVo = regionMap.get(key);
|
2026-05-21 16:37:40 +08:00
|
|
|
|
|
2026-06-18 16:26:31 +08:00
|
|
|
|
if (regionVo != null) {
|
|
|
|
|
|
// 判断资产是否已存在
|
|
|
|
|
|
boolean exists = regionVo.getAssets().stream()
|
|
|
|
|
|
.anyMatch(a -> a.getId().equals(assetId));
|
|
|
|
|
|
if (!exists) {
|
|
|
|
|
|
regionVo.getAssets().add(newAsset);
|
2026-05-21 16:37:40 +08:00
|
|
|
|
}
|
2026-06-18 16:26:31 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
// 新建区域
|
|
|
|
|
|
RegionVo newRegion = new RegionVo();
|
|
|
|
|
|
newRegion.setLat(lat);
|
|
|
|
|
|
newRegion.setLng(lng);
|
|
|
|
|
|
newRegion.setAddress(address);
|
|
|
|
|
|
newRegion.setManager(getStringValue(fieldsMap,"管理单位"));
|
|
|
|
|
|
|
|
|
|
|
|
List<AssetsItem> assets = new ArrayList<>();
|
|
|
|
|
|
assets.add(newAsset);
|
|
|
|
|
|
newRegion.setAssets(assets);
|
|
|
|
|
|
|
|
|
|
|
|
regionMap.put(key, newRegion);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 优化:带缓存的单位名称查询
|
|
|
|
|
|
*/
|
|
|
|
|
|
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;
|
2026-05-21 16:37:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private AssetsItem buildAssetsItem(Map<String, Object> fieldsMap) {
|
|
|
|
|
|
AssetsItem assetsItem = new AssetsItem();
|
2026-06-18 16:26:31 +08:00
|
|
|
|
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, "资产类型一级"));
|
2026-05-21 16:37:40 +08:00
|
|
|
|
return assetsItem;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private String getStringValue(Map<String, Object> fieldsMap, String key) {
|
2026-06-18 16:26:31 +08:00
|
|
|
|
Object val = fieldsMap.get(key);
|
|
|
|
|
|
return val == null ? null : val.toString();
|
2026-05-21 16:37:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-18 16:26:31 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 优化:一次查询全量数据,内存中分类计数,替代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 {
|
2026-05-21 16:37:40 +08:00
|
|
|
|
TableContext tableContext = FormTableExecutor.master(getFormNo());
|
|
|
|
|
|
List<FormWhereCondition> conditions = new ArrayList<FormWhereCondition>();
|
|
|
|
|
|
if(type == null || "0".equals(type)) {
|
|
|
|
|
|
conditions = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
if("1".equals(type)) {
|
|
|
|
|
|
conditions.add(FormWhereCondition.build().display("资产状态").value(EnumMapUtils.getEnumItemValueByDisplayValue(tableContext.getTableBean(),"资产状态","已租")));
|
|
|
|
|
|
}
|
|
|
|
|
|
if("2".equals(type)) {
|
|
|
|
|
|
conditions.add(FormWhereCondition.build().display("资产状态").value(EnumMapUtils.getEnumItemValueByDisplayValue(tableContext.getTableBean(),"资产状态","待租")));
|
|
|
|
|
|
}
|
|
|
|
|
|
List<FormColumn> formColumns = FormTableExecutor.query(tableContext,null, conditions, true);
|
|
|
|
|
|
return formColumns.size();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-06-18 16:26:31 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 按筛选条件分页查询资产列表(不走视口),用于地图右侧列表展示
|
|
|
|
|
|
* 返回格式: {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 {
|
2026-05-21 16:37:40 +08:00
|
|
|
|
List<FormWhereCondition> conditions = new ArrayList<FormWhereCondition>();
|
|
|
|
|
|
if(StringUtils.isNotBlank(keyword)){
|
2026-06-18 16:26:31 +08:00
|
|
|
|
conditions.add(FormWhereCondition.build().display("所在位置").value(keyword).concatFactor(ClauseFactor.OR).clauseFactor(ClauseFactor.LIKE));
|
2026-05-21 16:37:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
TableContext tableContext = FormTableExecutor.master(getFormNo());
|
|
|
|
|
|
List<FormColumn> formColumns = FormTableExecutor.pageQuery(tableContext,null, conditions, 1,10,true);
|
|
|
|
|
|
List<AssetsItem> assetsItems = new ArrayList<AssetsItem>();
|
|
|
|
|
|
for (FormColumn formColumn : formColumns) {
|
|
|
|
|
|
AssetsItem assetsItem = buildAssetsItem(formColumn.getFieldsMap());
|
|
|
|
|
|
assetsItems.add(assetsItem);
|
|
|
|
|
|
}
|
|
|
|
|
|
return assetsItems;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|