Commit a8d4e5e87284b236acccad2475bc8023738a8a76
1 parent
3ed2ca6f
feat(garden): 添加GIS道路管理和坐标转换功能
- 新增GIS道路管理相关控制器、服务和数据对象 - 实现WGS84到GCJ02坐标转换算法和工具类 - 添加GIS道路关联和取消关联功能 - 实现GIS道路坐标批量转换功能 - 添加GIS道路数据导入导出功能 - 新增问题类型级联查询接口优化前端展示 - 配置本地调试Mock认证支持 - 更新部署脚本和数据库表结构变更SQL
Showing
33 changed files
with
1703 additions
and
29 deletions
deploy-test.sh
0 → 100755
| 1 | +#!/bin/bash | ||
| 2 | +set -e | ||
| 3 | + | ||
| 4 | +# ==================== 配置 ==================== | ||
| 5 | +SERVER_HOST="172.17.16.14" | ||
| 6 | +SERVER_USER="root" | ||
| 7 | +SERVER_PASS="JCSS@2025!@#$" | ||
| 8 | +UPLOAD_DIR="/home/user/test_jar" | ||
| 9 | +RESTART_SCRIPT="restart.sh" | ||
| 10 | +JAR_NAME="urbanops-server.jar" | ||
| 11 | +PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)" | ||
| 12 | +JAR_PATH="$PROJECT_DIR/urbanops-server/target/$JAR_NAME" | ||
| 13 | + | ||
| 14 | +# ==================== 函数 ==================== | ||
| 15 | + | ||
| 16 | +check_sshpass() { | ||
| 17 | + if ! command -v sshpass &> /dev/null; then | ||
| 18 | + echo "[check] sshpass 未安装,尝试安装..." | ||
| 19 | + if command -v brew &> /dev/null; then | ||
| 20 | + brew install hudochenkov/sshpass/sshpass | ||
| 21 | + else | ||
| 22 | + echo "[ERROR] 请手动安装 sshpass: brew install hudochenkov/sshpass/sshpass" | ||
| 23 | + exit 1 | ||
| 24 | + fi | ||
| 25 | + fi | ||
| 26 | +} | ||
| 27 | + | ||
| 28 | +build() { | ||
| 29 | + echo "[build] 开始 Maven 打包(跳过测试)..." | ||
| 30 | + cd "$PROJECT_DIR" | ||
| 31 | + mvn clean package -DskipTests | ||
| 32 | + if [ -f "$JAR_PATH" ]; then | ||
| 33 | + echo "[build] 打包完成: $JAR_PATH ($(du -sh "$JAR_PATH" | cut -f1))" | ||
| 34 | + else | ||
| 35 | + echo "[ERROR] 打包失败,未找到 $JAR_PATH" | ||
| 36 | + exit 1 | ||
| 37 | + fi | ||
| 38 | +} | ||
| 39 | + | ||
| 40 | +upload() { | ||
| 41 | + echo "[upload] 上传 JAR 到 $SERVER_HOST:$UPLOAD_DIR/ ..." | ||
| 42 | + sshpass -p "$SERVER_PASS" scp -o StrictHostKeyChecking=no "$JAR_PATH" "$SERVER_USER@$SERVER_HOST:$UPLOAD_DIR/" | ||
| 43 | + echo "[upload] 上传完成" | ||
| 44 | +} | ||
| 45 | + | ||
| 46 | +restart() { | ||
| 47 | + echo "[restart] 调用远程重启脚本..." | ||
| 48 | + sshpass -p "$SERVER_PASS" ssh -o StrictHostKeyChecking=no "$SERVER_USER@$SERVER_HOST" \ | ||
| 49 | + "cd $UPLOAD_DIR && chmod +x $RESTART_SCRIPT && ./$RESTART_SCRIPT" | ||
| 50 | + echo "[restart] 远程重启完成" | ||
| 51 | +} | ||
| 52 | + | ||
| 53 | +# ==================== 主流程 ==================== | ||
| 54 | + | ||
| 55 | +echo "========================================" | ||
| 56 | +echo " UrbanOps 测试环境部署" | ||
| 57 | +echo " 目标: $SERVER_USER@$SERVER_HOST:$UPLOAD_DIR" | ||
| 58 | +echo "========================================" | ||
| 59 | + | ||
| 60 | +check_sshpass | ||
| 61 | +build | ||
| 62 | +upload | ||
| 63 | +restart | ||
| 64 | + | ||
| 65 | +echo "" | ||
| 66 | +echo "========================================" | ||
| 67 | +echo " 部署完成" | ||
| 68 | +echo "========================================" |
pom.xml
| @@ -20,7 +20,7 @@ | @@ -20,7 +20,7 @@ | ||
| 20 | <module>urbanops-module-workorder</module> | 20 | <module>urbanops-module-workorder</module> |
| 21 | <!-- <module>urbanops-module-member</module>--> | 21 | <!-- <module>urbanops-module-member</module>--> |
| 22 | <module>urbanops-module-bpm</module> | 22 | <module>urbanops-module-bpm</module> |
| 23 | - <module>urbanops-module-report</module> | 23 | +<!-- <module>urbanops-module-report</module>--> |
| 24 | <module>urbanops-module-api</module> | 24 | <module>urbanops-module-api</module> |
| 25 | <!-- <module>urbanops-module-mp</module>--> | 25 | <!-- <module>urbanops-module-mp</module>--> |
| 26 | <!-- <module>urbanops-module-pay</module>--> | 26 | <!-- <module>urbanops-module-pay</module>--> |
script/convert_gis_road_coords.py
0 → 100644
| 1 | +#!/usr/bin/env python3 | ||
| 2 | +""" | ||
| 3 | +WGS84 → GCJ02(高德坐标系)坐标转换脚本 | ||
| 4 | +目标表: garden_gis_road | ||
| 5 | +转换字段: starting_latitude/longitude, end_latitude/longitude, gis_polygon_coords | ||
| 6 | + | ||
| 7 | +使用方法: | ||
| 8 | + python3 convert_gis_road_coords.py | ||
| 9 | + | ||
| 10 | +前提: pip install pymysql | ||
| 11 | +""" | ||
| 12 | +import pymysql | ||
| 13 | +import math | ||
| 14 | +import re | ||
| 15 | + | ||
| 16 | +# ========== 数据库配置 ========== | ||
| 17 | +DB_CONFIG = { | ||
| 18 | + 'host': '172.17.16.15', | ||
| 19 | + 'port': 3306, | ||
| 20 | + 'user': 'root', | ||
| 21 | + 'password': 'mysql2025!', | ||
| 22 | + 'database': 'urban_ops_agent', | ||
| 23 | + 'charset': 'utf8mb4', | ||
| 24 | +} | ||
| 25 | + | ||
| 26 | +# ========== WGS84 → GCJ02 算法 ========== | ||
| 27 | +PI = math.pi | ||
| 28 | +A = 6378245.0 # 长半轴 | ||
| 29 | +EE = 0.00669342162296594323 # 偏心率平方 | ||
| 30 | + | ||
| 31 | + | ||
| 32 | +def wgs84_to_gcj02(lng, lat): | ||
| 33 | + """WGS84 转 GCJ02(高德坐标系)""" | ||
| 34 | + if lng < 72.004 or lng > 137.8347 or lat < 0.8293 or lat > 55.8271: | ||
| 35 | + return lng, lat | ||
| 36 | + | ||
| 37 | + x, y = lng - 105.0, lat - 35.0 | ||
| 38 | + | ||
| 39 | + dlat = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * math.sqrt(abs(x)) | ||
| 40 | + dlat += (20.0 * math.sin(6.0 * x * PI) + 20.0 * math.sin(2.0 * x * PI)) * 2.0 / 3.0 | ||
| 41 | + dlat += (20.0 * math.sin(y * PI) + 40.0 * math.sin(y / 3.0 * PI)) * 2.0 / 3.0 | ||
| 42 | + dlat += (160.0 * math.sin(y / 12.0 * PI) + 320.0 * math.sin(y * PI / 30.0)) * 2.0 / 3.0 | ||
| 43 | + | ||
| 44 | + dlng = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * math.sqrt(abs(x)) | ||
| 45 | + dlng += (20.0 * math.sin(6.0 * x * PI) + 20.0 * math.sin(2.0 * x * PI)) * 2.0 / 3.0 | ||
| 46 | + dlng += (20.0 * math.sin(x * PI) + 40.0 * math.sin(x / 3.0 * PI)) * 2.0 / 3.0 | ||
| 47 | + dlng += (150.0 * math.sin(x / 12.0 * PI) + 300.0 * math.sin(x / 30.0 * PI)) * 2.0 / 3.0 | ||
| 48 | + | ||
| 49 | + rad_lat = lat / 180.0 * PI | ||
| 50 | + magic = math.sin(rad_lat) | ||
| 51 | + magic = 1 - EE * magic * magic | ||
| 52 | + sqrt_magic = math.sqrt(magic) | ||
| 53 | + | ||
| 54 | + dlat = (dlat * 180.0) / ((A * (1 - EE)) / (magic * sqrt_magic) * PI) | ||
| 55 | + dlng = (dlng * 180.0) / (A / sqrt_magic * math.cos(rad_lat) * PI) | ||
| 56 | + | ||
| 57 | + return lng + dlng, lat + dlat | ||
| 58 | + | ||
| 59 | + | ||
| 60 | +def transform_wkt(wkt): | ||
| 61 | + """转换 WKT 字符串中的所有坐标对(支持 POLYGON / MULTIPOLYGON)""" | ||
| 62 | + if not wkt or not wkt.strip(): | ||
| 63 | + return wkt | ||
| 64 | + | ||
| 65 | + def convert_pair(m): | ||
| 66 | + nlng, nlat = wgs84_to_gcj02(float(m.group(1)), float(m.group(2))) | ||
| 67 | + return f"{nlng:.6f} {nlat:.6f}" | ||
| 68 | + | ||
| 69 | + return re.sub(r'(\d+\.?\d*)\s+(\d+\.?\d*)', convert_pair, wkt) | ||
| 70 | + | ||
| 71 | + | ||
| 72 | +def main(): | ||
| 73 | + conn = pymysql.connect(**DB_CONFIG) | ||
| 74 | + cur = conn.cursor() | ||
| 75 | + | ||
| 76 | + # 1. 转换起点/终点坐标(如果有的话) | ||
| 77 | + cur.execute( | ||
| 78 | + "SELECT id, starting_latitude, starting_longitude, end_latitude, end_longitude " | ||
| 79 | + "FROM garden_gis_road " | ||
| 80 | + "WHERE (starting_latitude IS NOT NULL AND starting_latitude != '') " | ||
| 81 | + " OR (end_latitude IS NOT NULL AND end_latitude != '')" | ||
| 82 | + ) | ||
| 83 | + rows = cur.fetchall() | ||
| 84 | + updated = 0 | ||
| 85 | + for row in rows: | ||
| 86 | + id_, slat, slng, elat, elng = row | ||
| 87 | + updates = [] | ||
| 88 | + params = [] | ||
| 89 | + | ||
| 90 | + if slat and slng and slat.strip(): | ||
| 91 | + try: | ||
| 92 | + nlng, nlat = wgs84_to_gcj02(float(slng), float(slat)) | ||
| 93 | + updates.append('starting_longitude = %s') | ||
| 94 | + updates.append('starting_latitude = %s') | ||
| 95 | + params.append(str(round(nlng, 6))) | ||
| 96 | + params.append(str(round(nlat, 6))) | ||
| 97 | + except ValueError: | ||
| 98 | + pass | ||
| 99 | + | ||
| 100 | + if elat and elng and elat.strip(): | ||
| 101 | + try: | ||
| 102 | + nlng, nlat = wgs84_to_gcj02(float(elng), float(elat)) | ||
| 103 | + updates.append('end_longitude = %s') | ||
| 104 | + updates.append('end_latitude = %s') | ||
| 105 | + params.append(str(round(nlng, 6))) | ||
| 106 | + params.append(str(round(nlat, 6))) | ||
| 107 | + except ValueError: | ||
| 108 | + pass | ||
| 109 | + | ||
| 110 | + if updates: | ||
| 111 | + sql = 'UPDATE garden_gis_road SET ' + ', '.join(updates) + ' WHERE id = %s' | ||
| 112 | + params.append(id_) | ||
| 113 | + cur.execute(sql, params) | ||
| 114 | + updated += 1 | ||
| 115 | + | ||
| 116 | + conn.commit() | ||
| 117 | + print(f'起点/终点坐标: 转换 {updated} 条') | ||
| 118 | + | ||
| 119 | + # 2. 转换围栏坐标 | ||
| 120 | + cur.execute( | ||
| 121 | + "SELECT COUNT(*) FROM garden_gis_road " | ||
| 122 | + "WHERE gis_polygon_coords IS NOT NULL AND gis_polygon_coords != ''" | ||
| 123 | + ) | ||
| 124 | + total = cur.fetchone()[0] | ||
| 125 | + print(f'围栏坐标记录: {total} 条') | ||
| 126 | + | ||
| 127 | + batch_size = 500 | ||
| 128 | + updated = 0 | ||
| 129 | + for offset in range(0, total, batch_size): | ||
| 130 | + cur.execute( | ||
| 131 | + "SELECT id, gis_polygon_coords FROM garden_gis_road " | ||
| 132 | + "WHERE gis_polygon_coords IS NOT NULL AND gis_polygon_coords != '' " | ||
| 133 | + "LIMIT %s OFFSET %s", | ||
| 134 | + (batch_size, offset) | ||
| 135 | + ) | ||
| 136 | + for id_, wkt in cur.fetchall(): | ||
| 137 | + new_wkt = transform_wkt(wkt) | ||
| 138 | + if new_wkt != wkt: | ||
| 139 | + cur.execute( | ||
| 140 | + "UPDATE garden_gis_road SET gis_polygon_coords = %s WHERE id = %s", | ||
| 141 | + (new_wkt, id_) | ||
| 142 | + ) | ||
| 143 | + updated += 1 | ||
| 144 | + conn.commit() | ||
| 145 | + print(f' 进度: {min(offset + batch_size, total)}/{total}, 已更新: {updated}') | ||
| 146 | + | ||
| 147 | + print(f'围栏坐标: 转换 {updated} 条') | ||
| 148 | + | ||
| 149 | + # 3. 验证 | ||
| 150 | + cur.execute( | ||
| 151 | + "SELECT COUNT(*) FROM garden_gis_road " | ||
| 152 | + "WHERE gis_polygon_coords IS NOT NULL AND gis_polygon_coords != ''" | ||
| 153 | + ) | ||
| 154 | + total = cur.fetchone()[0] | ||
| 155 | + unconverted = 0 | ||
| 156 | + cur.execute( | ||
| 157 | + "SELECT id, gis_polygon_coords FROM garden_gis_road " | ||
| 158 | + "WHERE gis_polygon_coords IS NOT NULL AND gis_polygon_coords != ''" | ||
| 159 | + ) | ||
| 160 | + for id_, wkt in cur.fetchall(): | ||
| 161 | + m = re.search(r'(\d+\.?\d*)\s+(\d+\.?\d*)', wkt) | ||
| 162 | + if m: | ||
| 163 | + wlng, wlat = float(m.group(1)), float(m.group(2)) | ||
| 164 | + nlng, nlat = wgs84_to_gcj02(wlng, wlat) | ||
| 165 | + if abs(wlng - nlng) < 0.00001: | ||
| 166 | + unconverted += 1 | ||
| 167 | + | ||
| 168 | + print(f'\n验证: {unconverted}/{total} 条未转换') | ||
| 169 | + if unconverted == 0: | ||
| 170 | + print('所有坐标已成功转换为 GCJ02(高德坐标系)') | ||
| 171 | + | ||
| 172 | + cur.close() | ||
| 173 | + conn.close() | ||
| 174 | + | ||
| 175 | + | ||
| 176 | +if __name__ == '__main__': | ||
| 177 | + main() |
script/shell/deploy.sh
| 1 | #!/bin/bash | 1 | #!/bin/bash |
| 2 | -set -e | 2 | +set -eo pipefail |
| 3 | 3 | ||
| 4 | DATE=$(date +%Y%m%d%H%M) | 4 | DATE=$(date +%Y%m%d%H%M) |
| 5 | # 基础路径 | 5 | # 基础路径 |
| @@ -9,9 +9,9 @@ SOURCE_PATH=$BASE_PATH/build | @@ -9,9 +9,9 @@ SOURCE_PATH=$BASE_PATH/build | ||
| 9 | # 服务名称。同时约定部署服务的 jar 包名字也为它。 | 9 | # 服务名称。同时约定部署服务的 jar 包名字也为它。 |
| 10 | SERVER_NAME=urbanops-server | 10 | SERVER_NAME=urbanops-server |
| 11 | # 环境 | 11 | # 环境 |
| 12 | -PROFILES_ACTIVE=development | 12 | +PROFILES_ACTIVE=dev |
| 13 | # 健康检查 URL | 13 | # 健康检查 URL |
| 14 | -HEALTH_CHECK_URL=http://127.0.0.1:48080/actuator/health/ | 14 | +HEALTH_CHECK_URL=http://127.0.0.1:48081/actuator/health/ |
| 15 | 15 | ||
| 16 | # heapError 存放路径 | 16 | # heapError 存放路径 |
| 17 | HEAP_ERROR_PATH=$BASE_PATH/heapError | 17 | HEAP_ERROR_PATH=$BASE_PATH/heapError |
| @@ -33,7 +33,8 @@ function backup() { | @@ -33,7 +33,8 @@ function backup() { | ||
| 33 | # 如果存在,则备份到 backup 目录下,使用时间作为后缀 | 33 | # 如果存在,则备份到 backup 目录下,使用时间作为后缀 |
| 34 | else | 34 | else |
| 35 | echo "[backup] 开始备份 $SERVER_NAME ..." | 35 | echo "[backup] 开始备份 $SERVER_NAME ..." |
| 36 | - cp $BASE_PATH/$SERVER_NAME.jar $BASE_PATH/backup/$SERVER_NAME-$DATE.jar | 36 | + mkdir -p "$BASE_PATH/backup" |
| 37 | + cp "$BASE_PATH/$SERVER_NAME.jar" "$BASE_PATH/backup/$SERVER_NAME-$DATE.jar" | ||
| 37 | echo "[backup] 备份 $SERVER_NAME 完成" | 38 | echo "[backup] 备份 $SERVER_NAME 完成" |
| 38 | fi | 39 | fi |
| 39 | } | 40 | } |
| @@ -47,12 +48,12 @@ function transfer() { | @@ -47,12 +48,12 @@ function transfer() { | ||
| 47 | echo "[transfer] $BASE_PATH/$SERVER_NAME.jar 不存在,跳过删除" | 48 | echo "[transfer] $BASE_PATH/$SERVER_NAME.jar 不存在,跳过删除" |
| 48 | else | 49 | else |
| 49 | echo "[transfer] 移除 $BASE_PATH/$SERVER_NAME.jar 完成" | 50 | echo "[transfer] 移除 $BASE_PATH/$SERVER_NAME.jar 完成" |
| 50 | - rm $BASE_PATH/$SERVER_NAME.jar | 51 | + rm "$BASE_PATH/$SERVER_NAME.jar" |
| 51 | fi | 52 | fi |
| 52 | 53 | ||
| 53 | # 复制新 jar 包 | 54 | # 复制新 jar 包 |
| 54 | echo "[transfer] 从 $SOURCE_PATH 中获取 $SERVER_NAME.jar 并迁移至 $BASE_PATH ...." | 55 | echo "[transfer] 从 $SOURCE_PATH 中获取 $SERVER_NAME.jar 并迁移至 $BASE_PATH ...." |
| 55 | - cp $SOURCE_PATH/$SERVER_NAME.jar $BASE_PATH | 56 | + cp "$SOURCE_PATH/$SERVER_NAME.jar" "$BASE_PATH" |
| 56 | 57 | ||
| 57 | echo "[transfer] 转移 $SERVER_NAME.jar 完成" | 58 | echo "[transfer] 转移 $SERVER_NAME.jar 完成" |
| 58 | } | 59 | } |
| @@ -60,7 +61,7 @@ function transfer() { | @@ -60,7 +61,7 @@ function transfer() { | ||
| 60 | # 停止:优雅关闭之前已经启动的服务 | 61 | # 停止:优雅关闭之前已经启动的服务 |
| 61 | function stop() { | 62 | function stop() { |
| 62 | echo "[stop] 开始停止 $BASE_PATH/$SERVER_NAME" | 63 | echo "[stop] 开始停止 $BASE_PATH/$SERVER_NAME" |
| 63 | - PID=$(ps -ef | grep $BASE_PATH/$SERVER_NAME | grep -v "grep" | awk '{print $2}') | 64 | + PID=$(ps -ef | grep "$BASE_PATH/$SERVER_NAME.jar" | grep -v "grep" | awk '{print $2}') |
| 64 | # 如果 Java 服务启动中,则进行关闭 | 65 | # 如果 Java 服务启动中,则进行关闭 |
| 65 | if [ -n "$PID" ]; then | 66 | if [ -n "$PID" ]; then |
| 66 | # 正常关闭 | 67 | # 正常关闭 |
| @@ -70,7 +71,7 @@ function stop() { | @@ -70,7 +71,7 @@ function stop() { | ||
| 70 | for ((i = 0; i < 120; i++)) | 71 | for ((i = 0; i < 120; i++)) |
| 71 | do | 72 | do |
| 72 | sleep 1 | 73 | sleep 1 |
| 73 | - PID=$(ps -ef | grep $BASE_PATH/$SERVER_NAME | grep -v "grep" | awk '{print $2}') | 74 | + PID=$(ps -ef | grep "$BASE_PATH/$SERVER_NAME.jar" | grep -v "grep" | awk '{print $2}') |
| 74 | if [ -n "$PID" ]; then | 75 | if [ -n "$PID" ]; then |
| 75 | echo -e ".\c" | 76 | echo -e ".\c" |
| 76 | else | 77 | else |
| @@ -99,7 +100,8 @@ function start() { | @@ -99,7 +100,8 @@ function start() { | ||
| 99 | echo "[start] PROFILES: $PROFILES_ACTIVE" | 100 | echo "[start] PROFILES: $PROFILES_ACTIVE" |
| 100 | 101 | ||
| 101 | # 开始启动 | 102 | # 开始启动 |
| 102 | - BUILD_ID=dontKillMe nohup java -server $JAVA_OPS $JAVA_AGENT -jar $BASE_PATH/$SERVER_NAME.jar --spring.profiles.active=$PROFILES_ACTIVE & | 103 | + mkdir -p "$HEAP_ERROR_PATH" |
| 104 | + nohup java -server $JAVA_OPS $JAVA_AGENT -jar "$BASE_PATH/$SERVER_NAME.jar" --spring.profiles.active=$PROFILES_ACTIVE >> "$BASE_PATH/nohup.out" 2>&1 & | ||
| 103 | echo "[start] 启动 $BASE_PATH/$SERVER_NAME 完成" | 105 | echo "[start] 启动 $BASE_PATH/$SERVER_NAME 完成" |
| 104 | } | 106 | } |
| 105 | 107 | ||
| @@ -112,7 +114,7 @@ function healthCheck() { | @@ -112,7 +114,7 @@ function healthCheck() { | ||
| 112 | for ((i = 0; i < 120; i++)) | 114 | for ((i = 0; i < 120; i++)) |
| 113 | do | 115 | do |
| 114 | # 请求健康检查地址,只获取状态码。 | 116 | # 请求健康检查地址,只获取状态码。 |
| 115 | - result=`curl -I -m 10 -o /dev/null -s -w %{http_code} $HEALTH_CHECK_URL || echo "000"` | 117 | + result=$(curl -I -m 10 -o /dev/null -s -w %{http_code} "$HEALTH_CHECK_URL" || echo "000") |
| 116 | # 如果状态码为 200,则说明健康检查通过 | 118 | # 如果状态码为 200,则说明健康检查通过 |
| 117 | if [ "$result" == "200" ]; then | 119 | if [ "$result" == "200" ]; then |
| 118 | echo "[healthCheck] 健康检查通过"; | 120 | echo "[healthCheck] 健康检查通过"; |
| @@ -127,24 +129,29 @@ function healthCheck() { | @@ -127,24 +129,29 @@ function healthCheck() { | ||
| 127 | # 健康检查未通过,则异常退出 shell 脚本,不继续部署。 | 129 | # 健康检查未通过,则异常退出 shell 脚本,不继续部署。 |
| 128 | if [ ! "$result" == "200" ]; then | 130 | if [ ! "$result" == "200" ]; then |
| 129 | echo "[healthCheck] 健康检查不通过,可能部署失败。查看日志,自行判断是否启动成功"; | 131 | echo "[healthCheck] 健康检查不通过,可能部署失败。查看日志,自行判断是否启动成功"; |
| 130 | - tail -n 10 nohup.out | 132 | + tail -n 10 "$BASE_PATH/nohup.out" |
| 131 | exit 1; | 133 | exit 1; |
| 132 | # 健康检查通过,打印最后 10 行日志,可能部署的人想看下日志。 | 134 | # 健康检查通过,打印最后 10 行日志,可能部署的人想看下日志。 |
| 133 | else | 135 | else |
| 134 | - tail -n 10 nohup.out | 136 | + tail -n 10 "$BASE_PATH/nohup.out" |
| 135 | fi | 137 | fi |
| 136 | # 如果未配置健康检查,则 sleep 120 秒,人工看日志是否部署成功。 | 138 | # 如果未配置健康检查,则 sleep 120 秒,人工看日志是否部署成功。 |
| 137 | else | 139 | else |
| 138 | echo "[healthCheck] HEALTH_CHECK_URL 未配置,开始 sleep 120 秒"; | 140 | echo "[healthCheck] HEALTH_CHECK_URL 未配置,开始 sleep 120 秒"; |
| 139 | sleep 120 | 141 | sleep 120 |
| 140 | echo "[healthCheck] sleep 120 秒完成,查看日志,自行判断是否启动成功"; | 142 | echo "[healthCheck] sleep 120 秒完成,查看日志,自行判断是否启动成功"; |
| 141 | - tail -n 50 nohup.out | 143 | + tail -n 50 "$BASE_PATH/nohup.out" |
| 142 | fi | 144 | fi |
| 143 | } | 145 | } |
| 144 | 146 | ||
| 145 | # 部署 | 147 | # 部署 |
| 146 | function deploy() { | 148 | function deploy() { |
| 147 | - cd $BASE_PATH | 149 | + cd "$BASE_PATH" || { echo "[deploy] 错误:$BASE_PATH 目录不存在"; exit 1; } |
| 150 | + if [ ! -d "$SOURCE_PATH" ]; then | ||
| 151 | + echo "[deploy] 错误:构建目录 $SOURCE_PATH 不存在" | ||
| 152 | + exit 1 | ||
| 153 | + fi | ||
| 154 | + mkdir -p "$BASE_PATH/backup" "$HEAP_ERROR_PATH" | ||
| 148 | # 备份原 jar | 155 | # 备份原 jar |
| 149 | backup | 156 | backup |
| 150 | # 停止 Java 服务 | 157 | # 停止 Java 服务 |
sql/dis-check-menu.sql
0 → 100644
| 1 | +-- ===================================================== | ||
| 2 | +-- dis核对 完整部署脚本 | ||
| 3 | +-- 数据库: urban_ops_agent | ||
| 4 | +-- 包含: 表结构变更 + 菜单创建 + 角色授权 | ||
| 5 | +-- 执行方式: 在对应环境的数据库中执行此 SQL | ||
| 6 | +-- ===================================================== | ||
| 7 | + | ||
| 8 | +-- ========================================== | ||
| 9 | +-- Part 0: garden_gis_road 表结构变更 | ||
| 10 | +-- ========================================== | ||
| 11 | +-- 新增多边形围栏边界坐标字段(MySQL 8.x 兼容写法) | ||
| 12 | +SET @col_exists = ( | ||
| 13 | + SELECT COUNT(*) FROM information_schema.COLUMNS | ||
| 14 | + WHERE TABLE_SCHEMA = DATABASE() | ||
| 15 | + AND TABLE_NAME = 'garden_gis_road' | ||
| 16 | + AND COLUMN_NAME = 'gis_polygon_coords' | ||
| 17 | +); | ||
| 18 | + | ||
| 19 | +SET @sql = IF(@col_exists = 0, | ||
| 20 | + 'ALTER TABLE garden_gis_road ADD COLUMN gis_polygon_coords LONGTEXT NOT NULL COMMENT ''多边形/矩形围栏边界坐标,格式:POLYGON((x1 y1, x2 y2, ..., xn yn, x1 y1)) 存储的是WGS84坐标系''', | ||
| 21 | + 'SELECT ''COLUMN gis_polygon_coords already exists'' AS info' | ||
| 22 | +); | ||
| 23 | +PREPARE stmt FROM @sql; | ||
| 24 | +EXECUTE stmt; | ||
| 25 | +DEALLOCATE PREPARE stmt; | ||
| 26 | + | ||
| 27 | +-- ========================================== | ||
| 28 | +-- Part 1: 菜单创建 | ||
| 29 | +-- ========================================== | ||
| 30 | + | ||
| 31 | +-- 1. 新增「dis核对」子菜单(位于电子围栏下) | ||
| 32 | +INSERT INTO system_menu | ||
| 33 | +(name, permission, type, sort, parent_id, path, icon, component, component_name, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted) | ||
| 34 | +VALUES | ||
| 35 | +('dis核对', '', 2, 1, 5698, 'disCheck', 'ep:view', 'fence/dis-check/index', 'DisCheck', 0, 1, 0, 1, '1', NOW(), '1', NOW(), 0); | ||
| 36 | + | ||
| 37 | +-- 2. 获取上一步插入的菜单ID,用于后续按钮权限插入 | ||
| 38 | +SET @dis_check_menu_id = LAST_INSERT_ID(); | ||
| 39 | + | ||
| 40 | +-- 3. 新增「导出」按钮权限(挂在新菜单下) | ||
| 41 | +INSERT INTO system_menu | ||
| 42 | +(name, permission, type, sort, parent_id, path, icon, component, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted) | ||
| 43 | +VALUES | ||
| 44 | +('导出', 'garden:gis-road:export', 3, 0, @dis_check_menu_id, '', '', '', 0, 1, 0, 1, '1', NOW(), '1', NOW(), 0); | ||
| 45 | + | ||
| 46 | +-- 4. 新增「查询」按钮权限 | ||
| 47 | +INSERT INTO system_menu | ||
| 48 | +(name, permission, type, sort, parent_id, path, icon, component, status, visible, keep_alive, always_show, creator, create_time, updater, update_time, deleted) | ||
| 49 | +VALUES | ||
| 50 | +('查询', 'garden:gis-road:query', 3, 1, @dis_check_menu_id, '', '', '', 0, 1, 0, 1, '1', NOW(), '1', NOW(), 0); | ||
| 51 | + | ||
| 52 | +-- 5. 给超级管理员(role_id=1)分配菜单权限 | ||
| 53 | +INSERT INTO system_role_menu (role_id, menu_id, creator, create_time, updater, update_time) | ||
| 54 | +VALUES | ||
| 55 | +(1, @dis_check_menu_id, '1', NOW(), '1', NOW()); | ||
| 56 | + | ||
| 57 | +INSERT INTO system_role_menu (role_id, menu_id, creator, create_time, updater, update_time) | ||
| 58 | +SELECT 1, id, '1', NOW(), '1', NOW() | ||
| 59 | +FROM system_menu | ||
| 60 | +WHERE parent_id = @dis_check_menu_id AND deleted = 0; | ||
| 61 | + | ||
| 62 | +-- ===================================================== | ||
| 63 | +-- 验证插入结果 | ||
| 64 | +-- ===================================================== | ||
| 65 | +SELECT id, name, type, parent_id, path, component, permission | ||
| 66 | +FROM system_menu | ||
| 67 | +WHERE parent_id = 5698 OR id = @dis_check_menu_id | ||
| 68 | +ORDER BY parent_id, sort; | ||
| 69 | + | ||
| 70 | +SELECT rm.role_id, rm.menu_id, m.name, m.permission | ||
| 71 | +FROM system_role_menu rm | ||
| 72 | +JOIN system_menu m ON rm.menu_id = m.id | ||
| 73 | +WHERE rm.menu_id = @dis_check_menu_id | ||
| 74 | + OR rm.menu_id IN (SELECT id FROM system_menu WHERE parent_id = @dis_check_menu_id); |
sql/garden_road_add_gis_fields.sql
0 → 100644
sql/sync_land_forest_to_road.sql
0 → 100644
| 1 | +-- ============================================================ | ||
| 2 | +-- 将 garden_gis_land_forest_data 数据同步到 garden_gis_road | ||
| 3 | +-- 按 greenname + greentype 分组聚合 | ||
| 4 | +-- - xbmj 求和 → gis_plot_area | ||
| 5 | +-- - geometry 所有 MULTIPOLYGON 环拼接 → gis_polygon_coords (WKT) | ||
| 6 | +-- - 其他 gis_ 字段取分组内 MAX 值 | ||
| 7 | +-- | ||
| 8 | +-- 注意:MySQL 不支持 ST_Union 聚合函数,geometry 并集通过 | ||
| 9 | +-- GROUP_CONCAT 拼接各 MULTIPOLYGON 的内部环来实现,不做空间融合。 | ||
| 10 | +-- 如需真正融合重叠区域,建议在 Java 层用 JTS 处理。 | ||
| 11 | +-- ============================================================ | ||
| 12 | + | ||
| 13 | +-- 避免 GROUP_CONCAT 默认 1024 字节限制导致 WKT 截断 | ||
| 14 | +SET SESSION group_concat_max_len = 10485760; -- 10MB | ||
| 15 | + | ||
| 16 | +INSERT INTO garden_gis_road ( | ||
| 17 | + gis_plot_name, | ||
| 18 | + gis_green_type_name, | ||
| 19 | + gis_plot_area, | ||
| 20 | + gis_polygon_coords, | ||
| 21 | + gis_owner_unit, | ||
| 22 | + gis_property_unit, | ||
| 23 | + gis_manage_unit, | ||
| 24 | + gis_street, | ||
| 25 | + gis_plot_code, | ||
| 26 | + gis_green_type_code, | ||
| 27 | + street_id, | ||
| 28 | + company_id, | ||
| 29 | + dept_id | ||
| 30 | +) | ||
| 31 | +SELECT | ||
| 32 | + greenname AS gis_plot_name, | ||
| 33 | + greentype AS gis_green_type_name, | ||
| 34 | + ROUND(SUM(xbmj), 2) AS gis_plot_area, | ||
| 35 | + CONCAT( | ||
| 36 | + 'MULTIPOLYGON(', | ||
| 37 | + GROUP_CONCAT( | ||
| 38 | + SUBSTR( | ||
| 39 | + ST_AsText(geometry), | ||
| 40 | + 14, -- 跳过 'MULTIPOLYGON('(13字符) | ||
| 41 | + LENGTH(ST_AsText(geometry)) - 14 -- 去掉首尾各1个括号 | ||
| 42 | + ) | ||
| 43 | + SEPARATOR ',' | ||
| 44 | + ), | ||
| 45 | + ')' | ||
| 46 | + ) AS gis_polygon_coords, | ||
| 47 | + MAX(cqdw) AS gis_owner_unit, | ||
| 48 | + MAX(cqdw) AS gis_property_unit, | ||
| 49 | + MAX(gl_dw) AS gis_manage_unit, | ||
| 50 | + MAX(CONCAT_WS('-', sheng, shi, xian, xiang)) AS gis_street, | ||
| 51 | + '' AS gis_plot_code, | ||
| 52 | + '' AS gis_green_type_code, | ||
| 53 | + '' AS street_id, | ||
| 54 | + 0 AS company_id, | ||
| 55 | + 0 AS dept_id | ||
| 56 | +FROM garden_gis_land_forest_data | ||
| 57 | +WHERE greenname IS NOT NULL | ||
| 58 | + AND greentype IS NOT NULL | ||
| 59 | +GROUP BY greenname, greentype; |
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/admin/gis/GisRoadController.java
0 → 100644
| 1 | +package com.zteits.urbanops.module.garden.controller.admin.gis; | ||
| 2 | + | ||
| 3 | +import com.zteits.urbanops.framework.common.pojo.PageParam; | ||
| 4 | +import org.slf4j.Logger; | ||
| 5 | +import org.slf4j.LoggerFactory; | ||
| 6 | +import org.springframework.web.bind.annotation.*; | ||
| 7 | +import jakarta.annotation.Resource; | ||
| 8 | +import org.springframework.validation.annotation.Validated; | ||
| 9 | +import org.springframework.security.access.prepost.PreAuthorize; | ||
| 10 | +import io.swagger.v3.oas.annotations.tags.Tag; | ||
| 11 | +import io.swagger.v3.oas.annotations.Parameter; | ||
| 12 | +import io.swagger.v3.oas.annotations.Operation; | ||
| 13 | + | ||
| 14 | +import jakarta.validation.*; | ||
| 15 | +import jakarta.servlet.http.*; | ||
| 16 | +import java.io.IOException; | ||
| 17 | +import java.time.LocalDate; | ||
| 18 | +import java.time.format.DateTimeFormatter; | ||
| 19 | +import java.util.*; | ||
| 20 | + | ||
| 21 | +import com.zteits.urbanops.framework.common.pojo.PageResult; | ||
| 22 | +import com.zteits.urbanops.framework.common.pojo.CommonResult; | ||
| 23 | +import static com.zteits.urbanops.framework.common.pojo.CommonResult.success; | ||
| 24 | + | ||
| 25 | +import com.zteits.urbanops.framework.excel.core.util.ExcelUtils; | ||
| 26 | +import com.zteits.urbanops.framework.apilog.core.annotation.ApiAccessLog; | ||
| 27 | +import static com.zteits.urbanops.framework.apilog.core.enums.OperateTypeEnum.*; | ||
| 28 | + | ||
| 29 | +import com.zteits.urbanops.module.garden.controller.admin.gis.vo.*; | ||
| 30 | +import com.zteits.urbanops.module.garden.service.gis.GisRoadService; | ||
| 31 | + | ||
| 32 | +@Tag(name = "管理后台 - GIS 道路管理") | ||
| 33 | +@RestController | ||
| 34 | +@RequestMapping("/garden/gis/road") | ||
| 35 | +@Validated | ||
| 36 | +public class GisRoadController { | ||
| 37 | + private static final Logger log = LoggerFactory.getLogger(GisRoadController.class); | ||
| 38 | + | ||
| 39 | + @Resource | ||
| 40 | + private GisRoadService gisRoadService; | ||
| 41 | + | ||
| 42 | + @GetMapping("/list") | ||
| 43 | + @Operation(summary = "获得 GIS 道路分页列表") | ||
| 44 | + @PreAuthorize("@ss.hasPermission('garden:gis-road:query')") | ||
| 45 | + public CommonResult<PageResult<GisRoadRespVO>> getGisRoadList(@Valid GisRoadPageReqVO pageReqVO) { | ||
| 46 | + PageResult<GisRoadRespVO> pageResult = gisRoadService.getGisRoadPage(pageReqVO); | ||
| 47 | + return success(pageResult); | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + @GetMapping("/list-all") | ||
| 51 | + @Operation(summary = "获得全部 GIS 道路列表(不分页,用于地图渲染)") | ||
| 52 | + @PreAuthorize("@ss.hasPermission('garden:gis-road:query')") | ||
| 53 | + public CommonResult<List<GisRoadRespVO>> getGisRoadAllList(GisRoadPageReqVO reqVO) { | ||
| 54 | + return success(gisRoadService.getGisRoadAllList(reqVO)); | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | + @GetMapping("/get") | ||
| 58 | + @Operation(summary = "获得 GIS 道路详情") | ||
| 59 | + @Parameter(name = "id", description = "编号", required = true, example = "1024") | ||
| 60 | + @PreAuthorize("@ss.hasPermission('garden:gis-road:query')") | ||
| 61 | + public CommonResult<GisRoadRespVO> getGisRoad(@RequestParam("id") Long id) { | ||
| 62 | + return success(gisRoadService.getGisRoad(id)); | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + @GetMapping("/export-excel") | ||
| 66 | + @Operation(summary = "导出 GIS 道路 Excel") | ||
| 67 | + @PreAuthorize("@ss.hasPermission('garden:gis-road:export')") | ||
| 68 | + @ApiAccessLog(operateType = EXPORT) | ||
| 69 | + public void exportGisRoadExcel(@Valid GisRoadPageReqVO pageReqVO, | ||
| 70 | + HttpServletResponse response) throws IOException { | ||
| 71 | + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); | ||
| 72 | + List<GisRoadRespVO> list = gisRoadService.getGisRoadPage(pageReqVO).getList(); | ||
| 73 | + // 只导出表格展示的 6 列数据 | ||
| 74 | + List<GisRoadExportVO> exportList = new ArrayList<>(); | ||
| 75 | + for (GisRoadRespVO vo : list) { | ||
| 76 | + GisRoadExportVO exportVO = new GisRoadExportVO(); | ||
| 77 | + exportVO.setGisPlotName(vo.getGisPlotName()); | ||
| 78 | + exportVO.setRoadName(vo.getRoadName()); | ||
| 79 | + exportVO.setGisPlotArea(vo.getGisPlotArea()); | ||
| 80 | + exportVO.setTotalArea(vo.getTotalArea()); | ||
| 81 | + exportVO.setGisIsRelatedStr(vo.getGisIsRelated() != null && vo.getGisIsRelated() == 1 ? "已关联" : "未关联"); | ||
| 82 | + exportVO.setGisDiffArea(vo.getGisDiffArea()); | ||
| 83 | + exportList.add(exportVO); | ||
| 84 | + } | ||
| 85 | + String filename = "GIS核对" + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")) + ".xls"; | ||
| 86 | + ExcelUtils.write(response, filename, "数据", GisRoadExportVO.class, exportList); | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + @PostMapping("/associate") | ||
| 90 | + @Operation(summary = "关联道路到 GIS 图斑") | ||
| 91 | + @PreAuthorize("@ss.hasPermission('garden:gis-road:update')") | ||
| 92 | + public CommonResult<Boolean> associateRoad(@Valid @RequestBody GisRoadAssociateReqVO reqVO) { | ||
| 93 | + gisRoadService.associateRoad(reqVO); | ||
| 94 | + return success(true); | ||
| 95 | + } | ||
| 96 | + | ||
| 97 | + @PostMapping("/disassociate") | ||
| 98 | + @Operation(summary = "取消 GIS 图斑与道路的关联") | ||
| 99 | + @PreAuthorize("@ss.hasPermission('garden:gis-road:update')") | ||
| 100 | + public CommonResult<Boolean> disassociateRoad(@Valid @RequestBody GisRoadDisassociateReqVO reqVO) { | ||
| 101 | + gisRoadService.disassociateRoad(reqVO); | ||
| 102 | + return success(true); | ||
| 103 | + } | ||
| 104 | + | ||
| 105 | + @PostMapping("/convert-coordinates") | ||
| 106 | + @Operation(summary = "将全部道路坐标从 WGS84 转换为 GCJ02(高德坐标系)") | ||
| 107 | + @PreAuthorize("@ss.hasPermission('garden:gis-road:update')") | ||
| 108 | + public CommonResult<String> convertCoordinates() { | ||
| 109 | + int count = gisRoadService.convertCoordinatesToGcj02(); | ||
| 110 | + log.info("坐标转换完成,共转换 {} 条记录", count); | ||
| 111 | + return success("坐标转换完成,共转换 " + count + " 条记录"); | ||
| 112 | + } | ||
| 113 | + | ||
| 114 | +} |
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/admin/gis/GisTypeController.java
0 → 100644
| 1 | +package com.zteits.urbanops.module.garden.controller.admin.gis; | ||
| 2 | + | ||
| 3 | +import io.swagger.v3.oas.annotations.tags.Tag; | ||
| 4 | +import io.swagger.v3.oas.annotations.Operation; | ||
| 5 | +import org.springframework.web.bind.annotation.*; | ||
| 6 | +import jakarta.annotation.Resource; | ||
| 7 | +import jakarta.validation.Valid; | ||
| 8 | +import java.util.*; | ||
| 9 | + | ||
| 10 | +import com.zteits.urbanops.framework.common.pojo.CommonResult; | ||
| 11 | +import static com.zteits.urbanops.framework.common.pojo.CommonResult.success; | ||
| 12 | +import com.zteits.urbanops.module.garden.dal.dataobject.gis.GisTypeDO; | ||
| 13 | +import com.zteits.urbanops.module.garden.service.gis.GisTypeService; | ||
| 14 | + | ||
| 15 | +@Tag(name = "管理后台 - GIS 绿地类型") | ||
| 16 | +@RestController | ||
| 17 | +@RequestMapping("/garden/gis/type") | ||
| 18 | +public class GisTypeController { | ||
| 19 | + | ||
| 20 | + @Resource | ||
| 21 | + private GisTypeService gisTypeService; | ||
| 22 | + | ||
| 23 | + @GetMapping("/list-by-parent") | ||
| 24 | + @Operation(summary = "按父级编码查子类型(级联下拉用)") | ||
| 25 | + public CommonResult<List<Map<String, Object>>> listByParentCode( | ||
| 26 | + @RequestParam(required = false) String parentCode) { | ||
| 27 | + List<GisTypeDO> list = gisTypeService.listByParentCode(parentCode); | ||
| 28 | + List<Map<String, Object>> result = new ArrayList<>(); | ||
| 29 | + for (GisTypeDO t : list) { | ||
| 30 | + Map<String, Object> m = new HashMap<>(); | ||
| 31 | + m.put("code", t.getTypeCode()); | ||
| 32 | + m.put("name", t.getTypeName()); | ||
| 33 | + m.put("level", t.getLevel()); | ||
| 34 | + m.put("parentCode", t.getParentCode()); | ||
| 35 | + result.add(m); | ||
| 36 | + } | ||
| 37 | + return success(result); | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + @GetMapping("/list-by-level") | ||
| 41 | + @Operation(summary = "按层级查类型列表") | ||
| 42 | + public CommonResult<List<Map<String, Object>>> listByLevel(@RequestParam Integer level) { | ||
| 43 | + List<GisTypeDO> list = gisTypeService.listByLevel(level); | ||
| 44 | + List<Map<String, Object>> result = new ArrayList<>(); | ||
| 45 | + for (GisTypeDO t : list) { | ||
| 46 | + Map<String, Object> m = new HashMap<>(); | ||
| 47 | + m.put("code", t.getTypeCode()); | ||
| 48 | + m.put("name", t.getTypeName()); | ||
| 49 | + m.put("level", t.getLevel()); | ||
| 50 | + m.put("parentCode", t.getParentCode()); | ||
| 51 | + result.add(m); | ||
| 52 | + } | ||
| 53 | + return success(result); | ||
| 54 | + } | ||
| 55 | +} |
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/admin/gis/vo/GisRoadAssociateReqVO.java
0 → 100644
| 1 | +package com.zteits.urbanops.module.garden.controller.admin.gis.vo; | ||
| 2 | + | ||
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 4 | +import lombok.Data; | ||
| 5 | +import jakarta.validation.constraints.NotNull; | ||
| 6 | + | ||
| 7 | +@Schema(description = "管理后台 - GIS 道路关联 Request VO") | ||
| 8 | +@Data | ||
| 9 | +public class GisRoadAssociateReqVO { | ||
| 10 | + | ||
| 11 | + @Schema(description = "GIS道路ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | ||
| 12 | + @NotNull(message = "GIS道路ID不能为空") | ||
| 13 | + private Long id; | ||
| 14 | + | ||
| 15 | + @Schema(description = "关联的道路ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") | ||
| 16 | + @NotNull(message = "道路ID不能为空") | ||
| 17 | + private Long roadId; | ||
| 18 | + | ||
| 19 | +} |
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/admin/gis/vo/GisRoadDisassociateReqVO.java
0 → 100644
| 1 | +package com.zteits.urbanops.module.garden.controller.admin.gis.vo; | ||
| 2 | + | ||
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 4 | +import lombok.Data; | ||
| 5 | +import jakarta.validation.constraints.NotNull; | ||
| 6 | + | ||
| 7 | +@Schema(description = "管理后台 - GIS 道路取消关联 Request VO") | ||
| 8 | +@Data | ||
| 9 | +public class GisRoadDisassociateReqVO { | ||
| 10 | + | ||
| 11 | + @Schema(description = "GIS道路ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | ||
| 12 | + @NotNull(message = "GIS道路ID不能为空") | ||
| 13 | + private Long id; | ||
| 14 | + | ||
| 15 | +} |
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/admin/gis/vo/GisRoadExportVO.java
0 → 100644
| 1 | +package com.zteits.urbanops.module.garden.controller.admin.gis.vo; | ||
| 2 | + | ||
| 3 | +import com.fasterxml.jackson.databind.annotation.JsonSerialize; | ||
| 4 | +import com.zteits.urbanops.module.garden.util.TwoDecimalFloatSerializer; | ||
| 5 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 6 | +import lombok.Data; | ||
| 7 | +import cn.idev.excel.annotation.ExcelIgnoreUnannotated; | ||
| 8 | +import cn.idev.excel.annotation.ExcelProperty; | ||
| 9 | + | ||
| 10 | +@Schema(description = "GIS 道路核对导出 VO") | ||
| 11 | +@Data | ||
| 12 | +@ExcelIgnoreUnannotated | ||
| 13 | +public class GisRoadExportVO { | ||
| 14 | + | ||
| 15 | + @Schema(description = "图斑名称") | ||
| 16 | + @ExcelProperty("图斑名称") | ||
| 17 | + private String gisPlotName; | ||
| 18 | + | ||
| 19 | + @Schema(description = "道路名称") | ||
| 20 | + @ExcelProperty("道路名称") | ||
| 21 | + private String roadName; | ||
| 22 | + | ||
| 23 | + @Schema(description = "图斑面积") | ||
| 24 | + @ExcelProperty("图斑面积(㎡)") | ||
| 25 | + @JsonSerialize(using = TwoDecimalFloatSerializer.class) | ||
| 26 | + private Float gisPlotArea; | ||
| 27 | + | ||
| 28 | + @Schema(description = "道路面积") | ||
| 29 | + @ExcelProperty("道路面积(㎡)") | ||
| 30 | + @JsonSerialize(using = TwoDecimalFloatSerializer.class) | ||
| 31 | + private Float totalArea; | ||
| 32 | + | ||
| 33 | + @Schema(description = "是否关联") | ||
| 34 | + @ExcelProperty("是否关联") | ||
| 35 | + private String gisIsRelatedStr; | ||
| 36 | + | ||
| 37 | + @Schema(description = "差异面积") | ||
| 38 | + @ExcelProperty("差异面积(㎡)") | ||
| 39 | + @JsonSerialize(using = TwoDecimalFloatSerializer.class) | ||
| 40 | + private Float gisDiffArea; | ||
| 41 | + | ||
| 42 | +} |
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/admin/gis/vo/GisRoadPageReqVO.java
0 → 100644
| 1 | +package com.zteits.urbanops.module.garden.controller.admin.gis.vo; | ||
| 2 | + | ||
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 4 | +import lombok.Data; | ||
| 5 | +import com.zteits.urbanops.framework.common.pojo.PageParam; | ||
| 6 | +import org.springframework.format.annotation.DateTimeFormat; | ||
| 7 | +import java.time.LocalDateTime; | ||
| 8 | + | ||
| 9 | +import static com.zteits.urbanops.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | ||
| 10 | + | ||
| 11 | +@Schema(description = "管理后台 - GIS 道路核对分页 Request VO") | ||
| 12 | +@Data | ||
| 13 | +public class GisRoadPageReqVO extends PageParam { | ||
| 14 | + | ||
| 15 | + @Schema(description = "道路名称") | ||
| 16 | + private String roadName; | ||
| 17 | + | ||
| 18 | + @Schema(description = "业务线") | ||
| 19 | + private String busiLine; | ||
| 20 | + | ||
| 21 | + @Schema(description = "街道ID") | ||
| 22 | + private String streetId; | ||
| 23 | + | ||
| 24 | + @Schema(description = "街道名称") | ||
| 25 | + private String streetName; | ||
| 26 | + | ||
| 27 | + @Schema(description = "养护级别") | ||
| 28 | + private Integer levelId; | ||
| 29 | + | ||
| 30 | + @Schema(description = "道路属性") | ||
| 31 | + private String roadAttr; | ||
| 32 | + | ||
| 33 | + @Schema(description = "道路方位") | ||
| 34 | + private String direction; | ||
| 35 | + | ||
| 36 | + @Schema(description = "GIS 图斑编号") | ||
| 37 | + private String gisPlotCode; | ||
| 38 | + | ||
| 39 | + @Schema(description = "GIS 图斑名称") | ||
| 40 | + private String gisPlotName; | ||
| 41 | + | ||
| 42 | + @Schema(description = "是否已关联 (0=未关联, 1=已关联)") | ||
| 43 | + private Integer gisIsRelated; | ||
| 44 | + | ||
| 45 | + @Schema(description = "归属公司ID") | ||
| 46 | + private Long companyId; | ||
| 47 | + | ||
| 48 | + @Schema(description = "部门ID") | ||
| 49 | + private Long deptId; | ||
| 50 | + | ||
| 51 | + @Schema(description = "GIS绿地类型编码(级联查询用)") | ||
| 52 | + private String gisTypeCode; | ||
| 53 | + | ||
| 54 | + @Schema(description = "创建时间") | ||
| 55 | + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | ||
| 56 | + private LocalDateTime[] createTime; | ||
| 57 | + | ||
| 58 | +} |
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/admin/gis/vo/GisRoadRespVO.java
0 → 100644
| 1 | +package com.zteits.urbanops.module.garden.controller.admin.gis.vo; | ||
| 2 | + | ||
| 3 | +import com.fasterxml.jackson.databind.annotation.JsonSerialize; | ||
| 4 | +import com.zteits.urbanops.module.garden.util.TwoDecimalFloatSerializer; | ||
| 5 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 6 | +import lombok.*; | ||
| 7 | +import org.springframework.format.annotation.DateTimeFormat; | ||
| 8 | +import java.time.LocalDateTime; | ||
| 9 | +import cn.idev.excel.annotation.*; | ||
| 10 | + | ||
| 11 | +@Schema(description = "管理后台 - GIS 道路核对 Response VO") | ||
| 12 | +@Data | ||
| 13 | +@ExcelIgnoreUnannotated | ||
| 14 | +public class GisRoadRespVO { | ||
| 15 | + | ||
| 16 | + @Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED) | ||
| 17 | + @ExcelProperty("ID") | ||
| 18 | + private Long id; | ||
| 19 | + | ||
| 20 | + @Schema(description = "关联道路ID") | ||
| 21 | + @ExcelProperty("关联道路ID") | ||
| 22 | + private Long gisRoadId; | ||
| 23 | + | ||
| 24 | + @Schema(description = "道路名称") | ||
| 25 | + @ExcelProperty("道路名称") | ||
| 26 | + private String roadName; | ||
| 27 | + | ||
| 28 | + @Schema(description = "业务线") | ||
| 29 | + @ExcelProperty("业务线") | ||
| 30 | + private String busiLine; | ||
| 31 | + | ||
| 32 | + @Schema(description = "街道ID") | ||
| 33 | + @ExcelProperty("街道ID") | ||
| 34 | + private String streetId; | ||
| 35 | + | ||
| 36 | + @Schema(description = "街道名称") | ||
| 37 | + @ExcelProperty("街道名称") | ||
| 38 | + private String streetName; | ||
| 39 | + | ||
| 40 | + @Schema(description = "养护级别") | ||
| 41 | + @ExcelProperty("养护级别") | ||
| 42 | + private Integer levelId; | ||
| 43 | + | ||
| 44 | + @Schema(description = "道路属性") | ||
| 45 | + @ExcelProperty("道路属性") | ||
| 46 | + private String roadAttr; | ||
| 47 | + | ||
| 48 | + @Schema(description = "道路方位") | ||
| 49 | + @ExcelProperty("道路方位") | ||
| 50 | + private String direction; | ||
| 51 | + | ||
| 52 | + @Schema(description = "行道树绿化面积") | ||
| 53 | + @ExcelProperty("行道树绿化面积") | ||
| 54 | + @JsonSerialize(using = TwoDecimalFloatSerializer.class) | ||
| 55 | + private Float greenBeltTreeArea; | ||
| 56 | + | ||
| 57 | + @Schema(description = "绿化带面积") | ||
| 58 | + @ExcelProperty("绿化带面积") | ||
| 59 | + @JsonSerialize(using = TwoDecimalFloatSerializer.class) | ||
| 60 | + private Float greenBeltArea; | ||
| 61 | + | ||
| 62 | + @Schema(description = "总绿化带面积") | ||
| 63 | + @ExcelProperty("总绿化带面积") | ||
| 64 | + @JsonSerialize(using = TwoDecimalFloatSerializer.class) | ||
| 65 | + private Float totalArea; | ||
| 66 | + | ||
| 67 | + @Schema(description = "行道树面积") | ||
| 68 | + @ExcelProperty("行道树面积") | ||
| 69 | + @JsonSerialize(using = TwoDecimalFloatSerializer.class) | ||
| 70 | + private Float treeArea; | ||
| 71 | + | ||
| 72 | + @Schema(description = "起点经度") | ||
| 73 | + @ExcelProperty("起点经度") | ||
| 74 | + private String startingLatitude; | ||
| 75 | + | ||
| 76 | + @Schema(description = "起点纬度") | ||
| 77 | + @ExcelProperty("起点纬度") | ||
| 78 | + private String startingLongitude; | ||
| 79 | + | ||
| 80 | + @Schema(description = "起点描述") | ||
| 81 | + @ExcelProperty("起点描述") | ||
| 82 | + private String startingRemark; | ||
| 83 | + | ||
| 84 | + @Schema(description = "终点经度") | ||
| 85 | + @ExcelProperty("终点经度") | ||
| 86 | + private String endLatitude; | ||
| 87 | + | ||
| 88 | + @Schema(description = "终点纬度") | ||
| 89 | + @ExcelProperty("终点纬度") | ||
| 90 | + private String endLongitude; | ||
| 91 | + | ||
| 92 | + @Schema(description = "终点描述") | ||
| 93 | + @ExcelProperty("终点描述") | ||
| 94 | + private String endRemark; | ||
| 95 | + | ||
| 96 | + @Schema(description = "备注") | ||
| 97 | + @ExcelProperty("备注") | ||
| 98 | + private String remark; | ||
| 99 | + | ||
| 100 | + @Schema(description = "归属公司ID") | ||
| 101 | + @ExcelProperty("归属公司ID") | ||
| 102 | + private Long companyId; | ||
| 103 | + | ||
| 104 | + @Schema(description = "部门ID") | ||
| 105 | + @ExcelProperty("部门ID") | ||
| 106 | + private Long deptId; | ||
| 107 | + | ||
| 108 | + @Schema(description = "创建者名称") | ||
| 109 | + @ExcelProperty("创建者") | ||
| 110 | + private String creatorName; | ||
| 111 | + | ||
| 112 | + @Schema(description = "创建时间") | ||
| 113 | + @ExcelProperty("创建时间") | ||
| 114 | + private LocalDateTime createTime; | ||
| 115 | + | ||
| 116 | + @Schema(description = "更新者名称") | ||
| 117 | + @ExcelProperty("更新者") | ||
| 118 | + private String updaterName; | ||
| 119 | + | ||
| 120 | + // ========== GIS 核对相关字段 ========== | ||
| 121 | + | ||
| 122 | + @Schema(description = "GIS 图斑编号") | ||
| 123 | + @ExcelProperty("GIS图斑编号") | ||
| 124 | + private String gisPlotCode; | ||
| 125 | + | ||
| 126 | + @Schema(description = "GIS 图斑名称") | ||
| 127 | + @ExcelProperty("GIS图斑名称") | ||
| 128 | + private String gisPlotName; | ||
| 129 | + | ||
| 130 | + @Schema(description = "GIS 图斑面积") | ||
| 131 | + @ExcelProperty("GIS图斑面积") | ||
| 132 | + @JsonSerialize(using = TwoDecimalFloatSerializer.class) | ||
| 133 | + private Float gisPlotArea; | ||
| 134 | + | ||
| 135 | + @Schema(description = "GIS 绿地类型编码") | ||
| 136 | + @ExcelProperty("GIS绿地类型编码") | ||
| 137 | + private String gisGreenTypeCode; | ||
| 138 | + | ||
| 139 | + @Schema(description = "GIS 绿地类型名称") | ||
| 140 | + @ExcelProperty("GIS绿地类型名称") | ||
| 141 | + private String gisGreenTypeName; | ||
| 142 | + | ||
| 143 | + @Schema(description = "GIS 所属街道") | ||
| 144 | + @ExcelProperty("GIS所属街道") | ||
| 145 | + private String gisStreet; | ||
| 146 | + | ||
| 147 | + @Schema(description = "GIS 权属单位") | ||
| 148 | + @ExcelProperty("GIS权属单位") | ||
| 149 | + private String gisOwnerUnit; | ||
| 150 | + | ||
| 151 | + @Schema(description = "GIS 物业单位") | ||
| 152 | + @ExcelProperty("GIS物业单位") | ||
| 153 | + private String gisPropertyUnit; | ||
| 154 | + | ||
| 155 | + @Schema(description = "GIS 养护单位") | ||
| 156 | + @ExcelProperty("GIS养护单位") | ||
| 157 | + private String gisManageUnit; | ||
| 158 | + | ||
| 159 | + @Schema(description = "GIS 差异面积") | ||
| 160 | + @ExcelProperty("GIS差异面积") | ||
| 161 | + @JsonSerialize(using = TwoDecimalFloatSerializer.class) | ||
| 162 | + private Float gisDiffArea; | ||
| 163 | + | ||
| 164 | + @Schema(description = "GIS 差异备注") | ||
| 165 | + @ExcelProperty("GIS差异备注") | ||
| 166 | + private String gisDiffRemark; | ||
| 167 | + | ||
| 168 | + @Schema(description = "是否已关联 (0=未关联, 1=已关联)") | ||
| 169 | + @ExcelProperty("是否已关联") | ||
| 170 | + private Integer gisIsRelated; | ||
| 171 | + | ||
| 172 | + @Schema(description = "关联人") | ||
| 173 | + @ExcelProperty("关联人") | ||
| 174 | + private String gisRelatedUser; | ||
| 175 | + | ||
| 176 | + @Schema(description = "关联时间") | ||
| 177 | + @ExcelProperty("关联时间") | ||
| 178 | + private LocalDateTime gisRelatedTime; | ||
| 179 | + | ||
| 180 | + @Schema(description = "多边形围栏边界坐标 WKT格式") | ||
| 181 | + @ExcelProperty("围栏边界坐标") | ||
| 182 | + private String gisPolygonCoords; | ||
| 183 | + | ||
| 184 | + // ========== 翻译字段 ========== | ||
| 185 | + | ||
| 186 | + @Schema(description = "公司名称") | ||
| 187 | + private String companyName; | ||
| 188 | + | ||
| 189 | + @Schema(description = "部门名称") | ||
| 190 | + private String deptName; | ||
| 191 | + | ||
| 192 | +} |
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/admin/road/vo/RoadPageReqVO.java
| @@ -86,6 +86,9 @@ public class RoadPageReqVO extends PageParam { | @@ -86,6 +86,9 @@ public class RoadPageReqVO extends PageParam { | ||
| 86 | @Schema(description = "更新者", example = "芋艿") | 86 | @Schema(description = "更新者", example = "芋艿") |
| 87 | private String updaterName; | 87 | private String updaterName; |
| 88 | 88 | ||
| 89 | + @Schema(description = "是否关联GIS (0=未关联, 1=已关联)") | ||
| 90 | + private Integer gisIsRelated; | ||
| 91 | + | ||
| 89 | //对应前端排序字段 | 92 | //对应前端排序字段 |
| 90 | public static final Map<String, SFunction<RoadDO, ?>> SORT_FIELD_MAP = Map.of( | 93 | public static final Map<String, SFunction<RoadDO, ?>> SORT_FIELD_MAP = Map.of( |
| 91 | "id", RoadDO::getId, | 94 | "id", RoadDO::getId, |
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/admin/road/vo/RoadRespVO.java
| @@ -122,4 +122,17 @@ public class RoadRespVO { | @@ -122,4 +122,17 @@ public class RoadRespVO { | ||
| 122 | @ExcelProperty("部门(道路负责部门)") | 122 | @ExcelProperty("部门(道路负责部门)") |
| 123 | private String deptName; | 123 | private String deptName; |
| 124 | 124 | ||
| 125 | + @Schema(description = "GIS 图斑名称") | ||
| 126 | + @ExcelProperty("GIS图斑名称") | ||
| 127 | + private String gisPlotName; | ||
| 128 | + | ||
| 129 | + @Schema(description = "GIS 图斑面积") | ||
| 130 | + @ExcelProperty("GIS图斑面积") | ||
| 131 | + @JsonSerialize(using = TwoDecimalFloatSerializer.class) | ||
| 132 | + private Float gisPlotArea; | ||
| 133 | + | ||
| 134 | + @Schema(description = "是否关联GIS (0=未关联, 1=已关联)") | ||
| 135 | + @ExcelProperty("是否关联GIS") | ||
| 136 | + private Integer gisIsRelated; | ||
| 137 | + | ||
| 125 | } | 138 | } |
| 126 | \ No newline at end of file | 139 | \ No newline at end of file |
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/app/problemtype/AppProblemTypeController.java
| 1 | package com.zteits.urbanops.module.garden.controller.app.problemtype; | 1 | package com.zteits.urbanops.module.garden.controller.app.problemtype; |
| 2 | 2 | ||
| 3 | import com.zteits.urbanops.framework.common.pojo.CommonResult; | 3 | import com.zteits.urbanops.framework.common.pojo.CommonResult; |
| 4 | -import com.zteits.urbanops.framework.common.util.object.BeanUtils; | ||
| 5 | -import com.zteits.urbanops.module.garden.controller.admin.problemtype.vo.ProblemTypeRespVO; | ||
| 6 | -import com.zteits.urbanops.module.garden.dal.dataobject.problemtype.GardenProblemTypeDO; | 4 | +import com.zteits.urbanops.module.garden.controller.app.problemtype.vo.ProblemTypeCascadeRespVO; |
| 7 | import com.zteits.urbanops.module.garden.service.problemtype.GardenProblemTypeService; | 5 | import com.zteits.urbanops.module.garden.service.problemtype.GardenProblemTypeService; |
| 8 | import io.swagger.v3.oas.annotations.Operation; | 6 | import io.swagger.v3.oas.annotations.Operation; |
| 9 | import io.swagger.v3.oas.annotations.tags.Tag; | 7 | import io.swagger.v3.oas.annotations.tags.Tag; |
| @@ -28,11 +26,9 @@ public class AppProblemTypeController { | @@ -28,11 +26,9 @@ public class AppProblemTypeController { | ||
| 28 | private GardenProblemTypeService gardenProblemTypeService; | 26 | private GardenProblemTypeService gardenProblemTypeService; |
| 29 | 27 | ||
| 30 | @GetMapping("/list-by-parent") | 28 | @GetMapping("/list-by-parent") |
| 31 | - @Operation(summary = "根据父级编码和层级查询子类型列表(级联下拉用)") | ||
| 32 | - public CommonResult<List<ProblemTypeRespVO>> getProblemTypeListByParent( | ||
| 33 | - @RequestParam(value = "parentCode", required = false) String parentCode, | ||
| 34 | - @RequestParam("level") Integer level) { | ||
| 35 | - List<GardenProblemTypeDO> list = gardenProblemTypeService.getProblemTypeByParentCode(parentCode, level); | ||
| 36 | - return success(BeanUtils.toBean(list, ProblemTypeRespVO.class)); | 29 | + @Operation(summary = "查询问题类型级联列表(级联下拉用)") |
| 30 | + public CommonResult<List<ProblemTypeCascadeRespVO>> getProblemTypeListByParent( | ||
| 31 | + @RequestParam(value = "parentCode", required = false) String parentCode) { | ||
| 32 | + return success(gardenProblemTypeService.getProblemTypeTree(parentCode)); | ||
| 37 | } | 33 | } |
| 38 | } | 34 | } |
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/controller/app/problemtype/vo/ProblemTypeCascadeRespVO.java
0 → 100644
| 1 | +package com.zteits.urbanops.module.garden.controller.app.problemtype.vo; | ||
| 2 | + | ||
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 4 | +import lombok.Data; | ||
| 5 | + | ||
| 6 | +import java.util.ArrayList; | ||
| 7 | +import java.util.List; | ||
| 8 | + | ||
| 9 | +@Schema(description = "APP - 问题类型级联响应 VO") | ||
| 10 | +@Data | ||
| 11 | +public class ProblemTypeCascadeRespVO { | ||
| 12 | + | ||
| 13 | + @Schema(description = "问题类型名称", example = "树木倒伏") | ||
| 14 | + private String label; | ||
| 15 | + | ||
| 16 | + @Schema(description = "问题类型编码", example = "PT001") | ||
| 17 | + private String value; | ||
| 18 | + | ||
| 19 | + @Schema(description = "子类型列表") | ||
| 20 | + private List<ProblemTypeCascadeRespVO> children = new ArrayList<>(); | ||
| 21 | + | ||
| 22 | +} | ||
| 0 | \ No newline at end of file | 23 | \ No newline at end of file |
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/dal/dataobject/gis/GisRoadDO.java
0 → 100644
| 1 | +package com.zteits.urbanops.module.garden.dal.dataobject.gis; | ||
| 2 | + | ||
| 3 | +import com.fasterxml.jackson.databind.annotation.JsonSerialize; | ||
| 4 | +import com.zteits.urbanops.module.garden.util.TwoDecimalFloatSerializer; | ||
| 5 | +import lombok.*; | ||
| 6 | +import com.baomidou.mybatisplus.annotation.*; | ||
| 7 | +import com.zteits.urbanops.framework.mybatis.core.dataobject.BaseDO; | ||
| 8 | + | ||
| 9 | +/** | ||
| 10 | + * GIS 道路核对 DO - garden_gis_road 表 | ||
| 11 | + * | ||
| 12 | + * @author UrbanOps | ||
| 13 | + */ | ||
| 14 | +@TableName("garden_gis_road") | ||
| 15 | +@KeySequence("garden_gis_road_seq") | ||
| 16 | +@Data | ||
| 17 | +@EqualsAndHashCode(callSuper = true) | ||
| 18 | +@ToString(callSuper = true) | ||
| 19 | +@Builder | ||
| 20 | +@NoArgsConstructor | ||
| 21 | +@AllArgsConstructor | ||
| 22 | +public class GisRoadDO extends BaseDO { | ||
| 23 | + | ||
| 24 | + @TableId | ||
| 25 | + private Long id; | ||
| 26 | + | ||
| 27 | + /** 关联道路ID */ | ||
| 28 | + private Long gisRoadId; | ||
| 29 | + | ||
| 30 | + /** 道路名称 */ | ||
| 31 | + private String roadName; | ||
| 32 | + | ||
| 33 | + /** 业务线:yl-园林;wy-物业;sz-市政 */ | ||
| 34 | + private String busiLine; | ||
| 35 | + | ||
| 36 | + /** 街道ID */ | ||
| 37 | + private String streetId; | ||
| 38 | + | ||
| 39 | + /** 街道名称 */ | ||
| 40 | + private String streetName; | ||
| 41 | + | ||
| 42 | + /** 养护级别: 10:特级;11:一级:12:二级;13:三级 */ | ||
| 43 | + private Integer levelId; | ||
| 44 | + | ||
| 45 | + /** 道路属性 */ | ||
| 46 | + private String roadAttr; | ||
| 47 | + | ||
| 48 | + /** 道路方位 W-西 E-东 N-北 S-南 */ | ||
| 49 | + private String direction; | ||
| 50 | + | ||
| 51 | + /** 行道树绿化面积 */ | ||
| 52 | + @JsonSerialize(using = TwoDecimalFloatSerializer.class) | ||
| 53 | + private Float greenBeltTreeArea; | ||
| 54 | + | ||
| 55 | + /** 绿化带面积 */ | ||
| 56 | + @JsonSerialize(using = TwoDecimalFloatSerializer.class) | ||
| 57 | + private Float greenBeltArea; | ||
| 58 | + | ||
| 59 | + /** 总绿化带面积 */ | ||
| 60 | + @JsonSerialize(using = TwoDecimalFloatSerializer.class) | ||
| 61 | + private Float totalArea; | ||
| 62 | + | ||
| 63 | + /** 行道树(棵)面积 */ | ||
| 64 | + @JsonSerialize(using = TwoDecimalFloatSerializer.class) | ||
| 65 | + private Float treeArea; | ||
| 66 | + | ||
| 67 | + /** 起点经度 */ | ||
| 68 | + private String startingLatitude; | ||
| 69 | + | ||
| 70 | + /** 起点纬度 */ | ||
| 71 | + private String startingLongitude; | ||
| 72 | + | ||
| 73 | + /** 起点描述 */ | ||
| 74 | + private String startingRemark; | ||
| 75 | + | ||
| 76 | + /** 终点经度 */ | ||
| 77 | + private String endLatitude; | ||
| 78 | + | ||
| 79 | + /** 终点纬度 */ | ||
| 80 | + private String endLongitude; | ||
| 81 | + | ||
| 82 | + /** 终点描述 */ | ||
| 83 | + private String endRemark; | ||
| 84 | + | ||
| 85 | + /** 备注 */ | ||
| 86 | + private String remark; | ||
| 87 | + | ||
| 88 | + /** 归属公司ID */ | ||
| 89 | + private Long companyId; | ||
| 90 | + | ||
| 91 | + /** 部门ID */ | ||
| 92 | + private Long deptId; | ||
| 93 | + | ||
| 94 | + /** 创建者名称 */ | ||
| 95 | + private String creatorName; | ||
| 96 | + | ||
| 97 | + /** 更新者名称 */ | ||
| 98 | + private String updaterName; | ||
| 99 | + | ||
| 100 | + // ========== GIS 核对相关字段 ========== | ||
| 101 | + | ||
| 102 | + /** GIS 图斑编号 */ | ||
| 103 | + private String gisPlotCode; | ||
| 104 | + | ||
| 105 | + /** GIS 图斑名称 */ | ||
| 106 | + private String gisPlotName; | ||
| 107 | + | ||
| 108 | + /** GIS 图斑面积 */ | ||
| 109 | + @JsonSerialize(using = TwoDecimalFloatSerializer.class) | ||
| 110 | + private Float gisPlotArea; | ||
| 111 | + | ||
| 112 | + /** GIS 绿地类型编码 */ | ||
| 113 | + private String gisGreenTypeCode; | ||
| 114 | + | ||
| 115 | + /** GIS 绿地类型名称 */ | ||
| 116 | + private String gisGreenTypeName; | ||
| 117 | + | ||
| 118 | + /** GIS 所属街道 */ | ||
| 119 | + private String gisStreet; | ||
| 120 | + | ||
| 121 | + /** GIS 权属单位 */ | ||
| 122 | + private String gisOwnerUnit; | ||
| 123 | + | ||
| 124 | + /** GIS 物业单位 */ | ||
| 125 | + private String gisPropertyUnit; | ||
| 126 | + | ||
| 127 | + /** GIS 养护单位 */ | ||
| 128 | + private String gisManageUnit; | ||
| 129 | + | ||
| 130 | + /** GIS 差异面积 */ | ||
| 131 | + @JsonSerialize(using = TwoDecimalFloatSerializer.class) | ||
| 132 | + private Float gisDiffArea; | ||
| 133 | + | ||
| 134 | + /** GIS 差异备注 */ | ||
| 135 | + private String gisDiffRemark; | ||
| 136 | + | ||
| 137 | + /** 是否已关联 (0=未关联, 1=已关联) */ | ||
| 138 | + private Integer gisIsRelated; | ||
| 139 | + | ||
| 140 | + /** 关联人 */ | ||
| 141 | + private String gisRelatedUser; | ||
| 142 | + | ||
| 143 | + /** 关联时间 */ | ||
| 144 | + private java.time.LocalDateTime gisRelatedTime; | ||
| 145 | + | ||
| 146 | + /** 多边形围栏边界坐标 WKT格式: POLYGON((x1 y1, x2 y2, ...)) WGS84坐标系 */ | ||
| 147 | + private String gisPolygonCoords; | ||
| 148 | + | ||
| 149 | +} |
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/dal/dataobject/gis/GisTypeDO.java
0 → 100644
| 1 | +package com.zteits.urbanops.module.garden.dal.dataobject.gis; | ||
| 2 | + | ||
| 3 | +import lombok.*; | ||
| 4 | +import com.baomidou.mybatisplus.annotation.*; | ||
| 5 | +import com.zteits.urbanops.framework.mybatis.core.dataobject.BaseDO; | ||
| 6 | + | ||
| 7 | +/** | ||
| 8 | + * 公园绿地类型字典 DO | ||
| 9 | + */ | ||
| 10 | +@TableName("garden_gis_type") | ||
| 11 | +@Data | ||
| 12 | +@EqualsAndHashCode(callSuper = true) | ||
| 13 | +@ToString(callSuper = true) | ||
| 14 | +@Builder | ||
| 15 | +@NoArgsConstructor | ||
| 16 | +@AllArgsConstructor | ||
| 17 | +public class GisTypeDO extends BaseDO { | ||
| 18 | + | ||
| 19 | + @TableId | ||
| 20 | + private Long id; | ||
| 21 | + | ||
| 22 | + /** 类型编码 */ | ||
| 23 | + private String typeCode; | ||
| 24 | + | ||
| 25 | + /** 类型名称 */ | ||
| 26 | + private String typeName; | ||
| 27 | + | ||
| 28 | + /** 父级编码 */ | ||
| 29 | + private String parentCode; | ||
| 30 | + | ||
| 31 | + /** 层级 */ | ||
| 32 | + private Integer level; | ||
| 33 | + | ||
| 34 | + /** 排序 */ | ||
| 35 | + private Integer sort; | ||
| 36 | + | ||
| 37 | +} |
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/dal/dataobject/road/RoadDO.java
| @@ -122,5 +122,16 @@ public class RoadDO extends BaseDO { | @@ -122,5 +122,16 @@ public class RoadDO extends BaseDO { | ||
| 122 | */ | 122 | */ |
| 123 | private String updaterName; | 123 | private String updaterName; |
| 124 | 124 | ||
| 125 | + // ========== GIS 关联字段 ========== | ||
| 126 | + | ||
| 127 | + /** GIS 图斑名称 */ | ||
| 128 | + private String gisPlotName; | ||
| 129 | + | ||
| 130 | + /** GIS 图斑面积 */ | ||
| 131 | + @JsonSerialize(using = TwoDecimalFloatSerializer.class) | ||
| 132 | + private Float gisPlotArea; | ||
| 133 | + | ||
| 134 | + /** 是否关联GIS (0=未关联, 1=已关联) */ | ||
| 135 | + private Integer gisIsRelated; | ||
| 125 | 136 | ||
| 126 | } | 137 | } |
| 127 | \ No newline at end of file | 138 | \ No newline at end of file |
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/dal/mysql/gis/GisRoadMapper.java
0 → 100644
| 1 | +package com.zteits.urbanops.module.garden.dal.mysql.gis; | ||
| 2 | + | ||
| 3 | +import com.zteits.urbanops.framework.common.pojo.PageResult; | ||
| 4 | +import com.zteits.urbanops.framework.mybatis.core.query.LambdaQueryWrapperX; | ||
| 5 | +import com.zteits.urbanops.framework.mybatis.core.mapper.BaseMapperX; | ||
| 6 | +import com.zteits.urbanops.module.garden.dal.dataobject.gis.GisRoadDO; | ||
| 7 | +import com.zteits.urbanops.module.garden.controller.admin.gis.vo.*; | ||
| 8 | +import org.apache.ibatis.annotations.Mapper; | ||
| 9 | +import java.util.*; | ||
| 10 | + | ||
| 11 | +/** | ||
| 12 | + * GIS 道路核对 Mapper | ||
| 13 | + */ | ||
| 14 | +@Mapper | ||
| 15 | +public interface GisRoadMapper extends BaseMapperX<GisRoadDO> { | ||
| 16 | + | ||
| 17 | + /** XG 大类的子代码(不以 XG 开头,需特殊处理) */ | ||
| 18 | + List<String> XG_CHILD_CODES = Arrays.asList("RG", "AG", "BG", "MG", "WG", "SG", "UG"); | ||
| 19 | + | ||
| 20 | + /** 构建公共查询条件 */ | ||
| 21 | + private LambdaQueryWrapperX<GisRoadDO> buildQueryWrapper(GisRoadPageReqVO reqVO) { | ||
| 22 | + LambdaQueryWrapperX<GisRoadDO> wrapper = new LambdaQueryWrapperX<GisRoadDO>() | ||
| 23 | + .likeIfPresent(GisRoadDO::getRoadName, reqVO.getRoadName()) | ||
| 24 | + .eqIfPresent(GisRoadDO::getBusiLine, reqVO.getBusiLine()) | ||
| 25 | + .eqIfPresent(GisRoadDO::getStreetId, reqVO.getStreetId()) | ||
| 26 | + .likeIfPresent(GisRoadDO::getStreetName, reqVO.getStreetName()) | ||
| 27 | + .eqIfPresent(GisRoadDO::getLevelId, reqVO.getLevelId()) | ||
| 28 | + .eqIfPresent(GisRoadDO::getRoadAttr, reqVO.getRoadAttr()) | ||
| 29 | + .eqIfPresent(GisRoadDO::getDirection, reqVO.getDirection()) | ||
| 30 | + .likeIfPresent(GisRoadDO::getGisPlotCode, reqVO.getGisPlotCode()) | ||
| 31 | + .likeIfPresent(GisRoadDO::getGisPlotName, reqVO.getGisPlotName()) | ||
| 32 | + .eqIfPresent(GisRoadDO::getGisIsRelated, reqVO.getGisIsRelated()) | ||
| 33 | + .eqIfPresent(GisRoadDO::getCompanyId, reqVO.getCompanyId()) | ||
| 34 | + .eqIfPresent(GisRoadDO::getDeptId, reqVO.getDeptId()); | ||
| 35 | + | ||
| 36 | + if (reqVO.getGisTypeCode() != null) { | ||
| 37 | + if ("XG".equals(reqVO.getGisTypeCode())) { | ||
| 38 | + wrapper.in(GisRoadDO::getGisGreenTypeCode, XG_CHILD_CODES); | ||
| 39 | + } else { | ||
| 40 | + wrapper.likeRight(GisRoadDO::getGisGreenTypeCode, reqVO.getGisTypeCode()); | ||
| 41 | + } | ||
| 42 | + } | ||
| 43 | + return wrapper.orderByDesc(GisRoadDO::getId); | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + default PageResult<GisRoadDO> selectPage(GisRoadPageReqVO reqVO) { | ||
| 47 | + return selectPage(reqVO, buildQueryWrapper(reqVO)); | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + /** 不分页查询全部记录(用于地图渲染) */ | ||
| 51 | + default List<GisRoadDO> selectAllList(GisRoadPageReqVO reqVO) { | ||
| 52 | + return selectList(buildQueryWrapper(reqVO)); | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | +} |
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/dal/mysql/gis/GisTypeMapper.java
0 → 100644
| 1 | +package com.zteits.urbanops.module.garden.dal.mysql.gis; | ||
| 2 | + | ||
| 3 | +import com.zteits.urbanops.framework.mybatis.core.mapper.BaseMapperX; | ||
| 4 | +import com.zteits.urbanops.module.garden.dal.dataobject.gis.GisTypeDO; | ||
| 5 | +import org.apache.ibatis.annotations.Mapper; | ||
| 6 | + | ||
| 7 | +@Mapper | ||
| 8 | +public interface GisTypeMapper extends BaseMapperX<GisTypeDO> { | ||
| 9 | +} |
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/dal/mysql/road/RoadMapper.java
| @@ -42,6 +42,7 @@ public interface RoadMapper extends BaseMapperX<RoadDO> { | @@ -42,6 +42,7 @@ public interface RoadMapper extends BaseMapperX<RoadDO> { | ||
| 42 | .likeIfPresent(RoadDO::getCreatorName, reqVO.getCreatorName()) | 42 | .likeIfPresent(RoadDO::getCreatorName, reqVO.getCreatorName()) |
| 43 | .betweenIfPresent(RoadDO::getCreateTime, reqVO.getCreateTime()) | 43 | .betweenIfPresent(RoadDO::getCreateTime, reqVO.getCreateTime()) |
| 44 | .likeIfPresent(RoadDO::getUpdaterName, reqVO.getUpdaterName()) | 44 | .likeIfPresent(RoadDO::getUpdaterName, reqVO.getUpdaterName()) |
| 45 | + .eqIfPresent(RoadDO::getGisIsRelated, reqVO.getGisIsRelated()) | ||
| 45 | .orderByDesc(RoadDO::getId)); | 46 | .orderByDesc(RoadDO::getId)); |
| 46 | } | 47 | } |
| 47 | 48 |
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/gis/GisRoadService.java
0 → 100644
| 1 | +package com.zteits.urbanops.module.garden.service.gis; | ||
| 2 | + | ||
| 3 | +import java.util.*; | ||
| 4 | +import com.zteits.urbanops.module.garden.controller.admin.gis.vo.*; | ||
| 5 | +import com.zteits.urbanops.framework.common.pojo.PageResult; | ||
| 6 | + | ||
| 7 | +/** | ||
| 8 | + * GIS 道路 Service 接口 | ||
| 9 | + * | ||
| 10 | + * @author UrbanOps | ||
| 11 | + */ | ||
| 12 | +public interface GisRoadService { | ||
| 13 | + | ||
| 14 | + /** | ||
| 15 | + * 获得 GIS 道路分页 | ||
| 16 | + * | ||
| 17 | + * @param pageReqVO 分页查询 | ||
| 18 | + * @return GIS 道路分页 | ||
| 19 | + */ | ||
| 20 | + PageResult<GisRoadRespVO> getGisRoadPage(GisRoadPageReqVO pageReqVO); | ||
| 21 | + | ||
| 22 | + /** | ||
| 23 | + * 获得 GIS 道路 | ||
| 24 | + * | ||
| 25 | + * @param id 编号 | ||
| 26 | + * @return GIS 道路 | ||
| 27 | + */ | ||
| 28 | + GisRoadRespVO getGisRoad(Long id); | ||
| 29 | + | ||
| 30 | + /** | ||
| 31 | + * 获得全部 GIS 道路列表(不分页,用于地图渲染) | ||
| 32 | + * | ||
| 33 | + * @param reqVO 查询条件 | ||
| 34 | + * @return GIS 道路列表 | ||
| 35 | + */ | ||
| 36 | + List<GisRoadRespVO> getGisRoadAllList(GisRoadPageReqVO reqVO); | ||
| 37 | + | ||
| 38 | + /** | ||
| 39 | + * 关联道路到 GIS 图斑 | ||
| 40 | + * | ||
| 41 | + * @param reqVO 关联请求 | ||
| 42 | + */ | ||
| 43 | + void associateRoad(GisRoadAssociateReqVO reqVO); | ||
| 44 | + | ||
| 45 | + /** | ||
| 46 | + * 取消 GIS 图斑与道路的关联 | ||
| 47 | + * | ||
| 48 | + * @param reqVO 取消关联请求 | ||
| 49 | + */ | ||
| 50 | + void disassociateRoad(GisRoadDisassociateReqVO reqVO); | ||
| 51 | + | ||
| 52 | + /** | ||
| 53 | + * 将 garden_gis_road 表中所有坐标从 WGS84 转换为 GCJ02(高德坐标系) | ||
| 54 | + * | ||
| 55 | + * @return 转换记录数 | ||
| 56 | + */ | ||
| 57 | + int convertCoordinatesToGcj02(); | ||
| 58 | + | ||
| 59 | +} |
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/gis/GisRoadServiceImpl.java
0 → 100644
| 1 | +package com.zteits.urbanops.module.garden.service.gis; | ||
| 2 | + | ||
| 3 | +import com.zteits.urbanops.module.system.api.dept.DeptApi; | ||
| 4 | +import com.zteits.urbanops.module.system.api.dept.dto.DeptRespDTO; | ||
| 5 | +import org.springframework.stereotype.Service; | ||
| 6 | +import org.springframework.transaction.annotation.Transactional; | ||
| 7 | +import jakarta.annotation.Resource; | ||
| 8 | +import org.springframework.util.CollectionUtils; | ||
| 9 | +import org.springframework.validation.annotation.Validated; | ||
| 10 | + | ||
| 11 | +import java.time.LocalDateTime; | ||
| 12 | +import java.util.*; | ||
| 13 | +import java.util.stream.Collectors; | ||
| 14 | + | ||
| 15 | +import com.zteits.urbanops.module.garden.controller.admin.gis.vo.*; | ||
| 16 | +import com.zteits.urbanops.module.garden.dal.dataobject.gis.GisRoadDO; | ||
| 17 | +import com.zteits.urbanops.module.garden.dal.dataobject.road.RoadDO; | ||
| 18 | +import com.zteits.urbanops.framework.common.pojo.PageResult; | ||
| 19 | +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; | ||
| 20 | +import com.zteits.urbanops.framework.common.util.object.BeanUtils; | ||
| 21 | +import com.zteits.urbanops.framework.security.core.util.SecurityFrameworkUtils; | ||
| 22 | +import com.zteits.urbanops.module.garden.dal.mysql.gis.GisRoadMapper; | ||
| 23 | +import com.zteits.urbanops.module.garden.dal.mysql.road.RoadMapper; | ||
| 24 | +import com.zteits.urbanops.module.garden.util.GisCoordinateUtil; | ||
| 25 | + | ||
| 26 | +/** | ||
| 27 | + * GIS 道路 Service 实现类 | ||
| 28 | + * | ||
| 29 | + * @author UrbanOps | ||
| 30 | + */ | ||
| 31 | +@Service | ||
| 32 | +@Validated | ||
| 33 | +public class GisRoadServiceImpl implements GisRoadService { | ||
| 34 | + | ||
| 35 | + @Resource | ||
| 36 | + private GisRoadMapper gisRoadMapper; | ||
| 37 | + | ||
| 38 | + @Resource | ||
| 39 | + private RoadMapper roadMapper; | ||
| 40 | + | ||
| 41 | + @Resource | ||
| 42 | + private DeptApi deptApi; | ||
| 43 | + | ||
| 44 | + @Override | ||
| 45 | + public PageResult<GisRoadRespVO> getGisRoadPage(GisRoadPageReqVO pageReqVO) { | ||
| 46 | + PageResult<GisRoadDO> pageResult = gisRoadMapper.selectPage(pageReqVO); | ||
| 47 | + PageResult<GisRoadRespVO> page = BeanUtils.toBean(pageResult, GisRoadRespVO.class); | ||
| 48 | + fillDeptAndCompanyName(page.getList()); | ||
| 49 | + return page; | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | + @Override | ||
| 53 | + public GisRoadRespVO getGisRoad(Long id) { | ||
| 54 | + GisRoadDO gisRoadDO = gisRoadMapper.selectById(id); | ||
| 55 | + if (gisRoadDO == null) { | ||
| 56 | + return null; | ||
| 57 | + } | ||
| 58 | + GisRoadRespVO respVO = BeanUtils.toBean(gisRoadDO, GisRoadRespVO.class); | ||
| 59 | + List<GisRoadRespVO> list = new ArrayList<>(); | ||
| 60 | + list.add(respVO); | ||
| 61 | + fillDeptAndCompanyName(list); | ||
| 62 | + return respVO; | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + @Override | ||
| 66 | + public List<GisRoadRespVO> getGisRoadAllList(GisRoadPageReqVO reqVO) { | ||
| 67 | + List<GisRoadDO> list = gisRoadMapper.selectAllList(reqVO); | ||
| 68 | + List<GisRoadRespVO> voList = BeanUtils.toBean(list, GisRoadRespVO.class); | ||
| 69 | + fillDeptAndCompanyName(voList); | ||
| 70 | + return voList; | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | + @Override | ||
| 74 | + @Transactional(rollbackFor = Exception.class) | ||
| 75 | + public void associateRoad(GisRoadAssociateReqVO reqVO) { | ||
| 76 | + GisRoadDO gisRoad = gisRoadMapper.selectById(reqVO.getId()); | ||
| 77 | + if (gisRoad == null) { | ||
| 78 | + throw new IllegalArgumentException("GIS道路不存在: id=" + reqVO.getId()); | ||
| 79 | + } | ||
| 80 | + RoadDO road = roadMapper.selectById(reqVO.getRoadId()); | ||
| 81 | + if (road == null) { | ||
| 82 | + throw new IllegalArgumentException("道路不存在: id=" + reqVO.getRoadId()); | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | + gisRoad.setGisRoadId(road.getId()); | ||
| 86 | + gisRoad.setRoadName(road.getRoadName()); | ||
| 87 | + gisRoad.setTotalArea(road.getTotalArea()); | ||
| 88 | + gisRoad.setCompanyId(road.getCompanyId()); | ||
| 89 | + gisRoad.setDeptId(road.getDeptId()); | ||
| 90 | + | ||
| 91 | + // 差异面积 = GIS面积 - 道路面积 | ||
| 92 | + float gisArea = gisRoad.getGisPlotArea() != null ? gisRoad.getGisPlotArea() : 0; | ||
| 93 | + float roadArea = road.getTotalArea() != null ? road.getTotalArea() : 0; | ||
| 94 | + gisRoad.setGisDiffArea(gisArea - roadArea); | ||
| 95 | + | ||
| 96 | + gisRoad.setGisIsRelated(1); | ||
| 97 | + gisRoad.setGisRelatedUser(SecurityFrameworkUtils.getLoginUserNickname()); | ||
| 98 | + gisRoad.setGisRelatedTime(LocalDateTime.now()); | ||
| 99 | + | ||
| 100 | + gisRoadMapper.updateById(gisRoad); | ||
| 101 | + | ||
| 102 | + // 同步更新 garden_road 的 GIS 关联字段 | ||
| 103 | + road.setGisPlotName(gisRoad.getGisPlotName()); | ||
| 104 | + road.setGisPlotArea(gisRoad.getGisPlotArea()); | ||
| 105 | + road.setGisIsRelated(1); | ||
| 106 | + roadMapper.updateById(road); | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | + @Override | ||
| 110 | + @Transactional(rollbackFor = Exception.class) | ||
| 111 | + public void disassociateRoad(GisRoadDisassociateReqVO reqVO) { | ||
| 112 | + GisRoadDO gisRoad = gisRoadMapper.selectById(reqVO.getId()); | ||
| 113 | + if (gisRoad == null) { | ||
| 114 | + throw new IllegalArgumentException("GIS道路不存在: id=" + reqVO.getId()); | ||
| 115 | + } | ||
| 116 | + | ||
| 117 | + // 同步清空 garden_road 的 GIS 关联字段(LambdaUpdateWrapper 才能将字段设为 null) | ||
| 118 | + if (gisRoad.getGisRoadId() != null) { | ||
| 119 | + roadMapper.update(null, | ||
| 120 | + new LambdaUpdateWrapper<RoadDO>() | ||
| 121 | + .eq(RoadDO::getId, gisRoad.getGisRoadId()) | ||
| 122 | + .set(RoadDO::getGisPlotName, null) | ||
| 123 | + .set(RoadDO::getGisPlotArea, null) | ||
| 124 | + .set(RoadDO::getGisIsRelated, 0)); | ||
| 125 | + } | ||
| 126 | + | ||
| 127 | + // 清空 garden_gis_road 的道路关联信息 | ||
| 128 | + gisRoadMapper.update(null, | ||
| 129 | + new LambdaUpdateWrapper<GisRoadDO>() | ||
| 130 | + .eq(GisRoadDO::getId, gisRoad.getId()) | ||
| 131 | + .set(GisRoadDO::getGisRoadId, null) | ||
| 132 | + .set(GisRoadDO::getRoadName, null) | ||
| 133 | + .set(GisRoadDO::getTotalArea, null) | ||
| 134 | + .set(GisRoadDO::getCompanyId, null) | ||
| 135 | + .set(GisRoadDO::getDeptId, null) | ||
| 136 | + .set(GisRoadDO::getGisDiffArea, null) | ||
| 137 | + .set(GisRoadDO::getGisIsRelated, 0) | ||
| 138 | + .set(GisRoadDO::getGisRelatedUser, null) | ||
| 139 | + .set(GisRoadDO::getGisRelatedTime, null)); | ||
| 140 | + } | ||
| 141 | + | ||
| 142 | + @Override | ||
| 143 | + @Transactional(rollbackFor = Exception.class) | ||
| 144 | + public int convertCoordinatesToGcj02() { | ||
| 145 | + List<GisRoadDO> all = gisRoadMapper.selectList(); | ||
| 146 | + if (CollectionUtils.isEmpty(all)) { | ||
| 147 | + return 0; | ||
| 148 | + } | ||
| 149 | + int count = 0; | ||
| 150 | + for (GisRoadDO road : all) { | ||
| 151 | + boolean updated = false; | ||
| 152 | + | ||
| 153 | + // 转换起点坐标 | ||
| 154 | + if (road.getStartingLatitude() != null && !road.getStartingLatitude().isBlank() | ||
| 155 | + && road.getStartingLongitude() != null && !road.getStartingLongitude().isBlank()) { | ||
| 156 | + try { | ||
| 157 | + double lng = Double.parseDouble(road.getStartingLongitude()); | ||
| 158 | + double lat = Double.parseDouble(road.getStartingLatitude()); | ||
| 159 | + double[] gcj = GisCoordinateUtil.wgs84ToGcj02(lng, lat); | ||
| 160 | + road.setStartingLongitude(String.format("%.6f", gcj[0])); | ||
| 161 | + road.setStartingLatitude(String.format("%.6f", gcj[1])); | ||
| 162 | + updated = true; | ||
| 163 | + } catch (NumberFormatException ignored) { | ||
| 164 | + } | ||
| 165 | + } | ||
| 166 | + | ||
| 167 | + // 转换终点坐标 | ||
| 168 | + if (road.getEndLatitude() != null && !road.getEndLatitude().isBlank() | ||
| 169 | + && road.getEndLongitude() != null && !road.getEndLongitude().isBlank()) { | ||
| 170 | + try { | ||
| 171 | + double lng = Double.parseDouble(road.getEndLongitude()); | ||
| 172 | + double lat = Double.parseDouble(road.getEndLatitude()); | ||
| 173 | + double[] gcj = GisCoordinateUtil.wgs84ToGcj02(lng, lat); | ||
| 174 | + road.setEndLongitude(String.format("%.6f", gcj[0])); | ||
| 175 | + road.setEndLatitude(String.format("%.6f", gcj[1])); | ||
| 176 | + updated = true; | ||
| 177 | + } catch (NumberFormatException ignored) { | ||
| 178 | + } | ||
| 179 | + } | ||
| 180 | + | ||
| 181 | + // 转换多边形围栏坐标 | ||
| 182 | + if (road.getGisPolygonCoords() != null && !road.getGisPolygonCoords().isBlank()) { | ||
| 183 | + String converted = GisCoordinateUtil.transformPolygonWkt(road.getGisPolygonCoords()); | ||
| 184 | + if (!converted.equals(road.getGisPolygonCoords())) { | ||
| 185 | + road.setGisPolygonCoords(converted); | ||
| 186 | + updated = true; | ||
| 187 | + } | ||
| 188 | + } | ||
| 189 | + | ||
| 190 | + if (updated) { | ||
| 191 | + gisRoadMapper.updateById(road); | ||
| 192 | + count++; | ||
| 193 | + } | ||
| 194 | + } | ||
| 195 | + return count; | ||
| 196 | + } | ||
| 197 | + | ||
| 198 | + /** | ||
| 199 | + * 回填部门/公司名称 | ||
| 200 | + */ | ||
| 201 | + private void fillDeptAndCompanyName(List<GisRoadRespVO> list) { | ||
| 202 | + if (CollectionUtils.isEmpty(list)) { | ||
| 203 | + return; | ||
| 204 | + } | ||
| 205 | + // 收集所有公司ID和部门ID | ||
| 206 | + Set<Long> companyIds = list.stream() | ||
| 207 | + .map(GisRoadRespVO::getCompanyId) | ||
| 208 | + .filter(Objects::nonNull) | ||
| 209 | + .collect(Collectors.toSet()); | ||
| 210 | + Set<Long> deptIds = list.stream() | ||
| 211 | + .map(GisRoadRespVO::getDeptId) | ||
| 212 | + .filter(Objects::nonNull) | ||
| 213 | + .collect(Collectors.toSet()); | ||
| 214 | + deptIds.addAll(companyIds); | ||
| 215 | + | ||
| 216 | + if (deptIds.isEmpty()) { | ||
| 217 | + return; | ||
| 218 | + } | ||
| 219 | + | ||
| 220 | + Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(deptIds); | ||
| 221 | + | ||
| 222 | + list.forEach(vo -> { | ||
| 223 | + if (vo.getDeptId() != null) { | ||
| 224 | + DeptRespDTO dept = deptMap.get(vo.getDeptId()); | ||
| 225 | + if (dept != null) { | ||
| 226 | + vo.setDeptName(dept.getName()); | ||
| 227 | + } | ||
| 228 | + } | ||
| 229 | + if (vo.getCompanyId() != null) { | ||
| 230 | + DeptRespDTO company = deptMap.get(vo.getCompanyId()); | ||
| 231 | + if (company != null) { | ||
| 232 | + vo.setCompanyName(company.getName()); | ||
| 233 | + } | ||
| 234 | + } | ||
| 235 | + }); | ||
| 236 | + } | ||
| 237 | + | ||
| 238 | +} |
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/gis/GisTypeService.java
0 → 100644
| 1 | +package com.zteits.urbanops.module.garden.service.gis; | ||
| 2 | + | ||
| 3 | +import java.util.List; | ||
| 4 | +import com.zteits.urbanops.module.garden.dal.dataobject.gis.GisTypeDO; | ||
| 5 | + | ||
| 6 | +public interface GisTypeService { | ||
| 7 | + | ||
| 8 | + /** 按父级编码查子类型列表 */ | ||
| 9 | + List<GisTypeDO> listByParentCode(String parentCode); | ||
| 10 | + | ||
| 11 | + /** 按层级查类型列表 */ | ||
| 12 | + List<GisTypeDO> listByLevel(Integer level); | ||
| 13 | +} |
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/gis/GisTypeServiceImpl.java
0 → 100644
| 1 | +package com.zteits.urbanops.module.garden.service.gis; | ||
| 2 | + | ||
| 3 | +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||
| 4 | +import com.zteits.urbanops.module.garden.dal.dataobject.gis.GisTypeDO; | ||
| 5 | +import com.zteits.urbanops.module.garden.dal.mysql.gis.GisTypeMapper; | ||
| 6 | +import org.springframework.stereotype.Service; | ||
| 7 | +import jakarta.annotation.Resource; | ||
| 8 | +import java.util.List; | ||
| 9 | + | ||
| 10 | +@Service | ||
| 11 | +public class GisTypeServiceImpl implements GisTypeService { | ||
| 12 | + | ||
| 13 | + @Resource | ||
| 14 | + private GisTypeMapper gisTypeMapper; | ||
| 15 | + | ||
| 16 | + @Override | ||
| 17 | + public List<GisTypeDO> listByParentCode(String parentCode) { | ||
| 18 | + return gisTypeMapper.selectList( | ||
| 19 | + new LambdaQueryWrapper<GisTypeDO>() | ||
| 20 | + .eq(GisTypeDO::getParentCode, parentCode == null ? "" : parentCode) | ||
| 21 | + .orderByAsc(GisTypeDO::getSort) | ||
| 22 | + ); | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | + @Override | ||
| 26 | + public List<GisTypeDO> listByLevel(Integer level) { | ||
| 27 | + return gisTypeMapper.selectList( | ||
| 28 | + new LambdaQueryWrapper<GisTypeDO>() | ||
| 29 | + .eq(GisTypeDO::getLevel, level) | ||
| 30 | + .orderByAsc(GisTypeDO::getSort) | ||
| 31 | + ); | ||
| 32 | + } | ||
| 33 | +} |
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/problemtype/GardenProblemTypeService.java
| @@ -2,7 +2,9 @@ package com.zteits.urbanops.module.garden.service.problemtype; | @@ -2,7 +2,9 @@ package com.zteits.urbanops.module.garden.service.problemtype; | ||
| 2 | 2 | ||
| 3 | import com.zteits.urbanops.module.garden.controller.admin.problemtype.vo.ProblemTypePageReqVO; | 3 | import com.zteits.urbanops.module.garden.controller.admin.problemtype.vo.ProblemTypePageReqVO; |
| 4 | import com.zteits.urbanops.module.garden.controller.admin.problemtype.vo.ProblemTypeSaveReqVO; | 4 | import com.zteits.urbanops.module.garden.controller.admin.problemtype.vo.ProblemTypeSaveReqVO; |
| 5 | +import com.zteits.urbanops.module.garden.controller.app.problemtype.vo.ProblemTypeCascadeRespVO; | ||
| 5 | import com.zteits.urbanops.module.garden.dal.dataobject.problemtype.GardenProblemTypeDO; | 6 | import com.zteits.urbanops.module.garden.dal.dataobject.problemtype.GardenProblemTypeDO; |
| 7 | +import com.zteits.urbanops.framework.common.pojo.CommonResult; | ||
| 6 | import com.zteits.urbanops.framework.common.pojo.PageResult; | 8 | import com.zteits.urbanops.framework.common.pojo.PageResult; |
| 7 | import jakarta.validation.Valid; | 9 | import jakarta.validation.Valid; |
| 8 | 10 | ||
| @@ -63,6 +65,14 @@ public interface GardenProblemTypeService { | @@ -63,6 +65,14 @@ public interface GardenProblemTypeService { | ||
| 63 | List<GardenProblemTypeDO> getProblemTypeByParentCode(String parentCode, Integer level); | 65 | List<GardenProblemTypeDO> getProblemTypeByParentCode(String parentCode, Integer level); |
| 64 | 66 | ||
| 65 | /** | 67 | /** |
| 68 | + * 获取问题类型级联树 | ||
| 69 | + * | ||
| 70 | + * @param parentCode 父级编码(为空则返回顶级树) | ||
| 71 | + * @return 级联树列表 | ||
| 72 | + */ | ||
| 73 | + List<ProblemTypeCascadeRespVO> getProblemTypeTree(String parentCode); | ||
| 74 | + | ||
| 75 | + /** | ||
| 66 | * 根据父级编码生成下一个类型编码 | 76 | * 根据父级编码生成下一个类型编码 |
| 67 | * | 77 | * |
| 68 | * @param parentCode 父级编码 | 78 | * @param parentCode 父级编码 |
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/service/problemtype/GardenProblemTypeServiceImpl.java
| @@ -3,13 +3,17 @@ package com.zteits.urbanops.module.garden.service.problemtype; | @@ -3,13 +3,17 @@ package com.zteits.urbanops.module.garden.service.problemtype; | ||
| 3 | import com.zteits.urbanops.framework.common.enums.CommonStatusEnum; | 3 | import com.zteits.urbanops.framework.common.enums.CommonStatusEnum; |
| 4 | import com.zteits.urbanops.module.garden.controller.admin.problemtype.vo.ProblemTypePageReqVO; | 4 | import com.zteits.urbanops.module.garden.controller.admin.problemtype.vo.ProblemTypePageReqVO; |
| 5 | import com.zteits.urbanops.module.garden.controller.admin.problemtype.vo.ProblemTypeSaveReqVO; | 5 | import com.zteits.urbanops.module.garden.controller.admin.problemtype.vo.ProblemTypeSaveReqVO; |
| 6 | +import com.zteits.urbanops.module.garden.controller.app.problemtype.vo.ProblemTypeCascadeRespVO; | ||
| 6 | import com.zteits.urbanops.module.system.dal.dataobject.dict.DictDataDO; | 7 | import com.zteits.urbanops.module.system.dal.dataobject.dict.DictDataDO; |
| 7 | import com.zteits.urbanops.module.system.service.dict.DictDataService; | 8 | import com.zteits.urbanops.module.system.service.dict.DictDataService; |
| 8 | import org.springframework.stereotype.Service; | 9 | import org.springframework.stereotype.Service; |
| 9 | import org.springframework.validation.annotation.Validated; | 10 | import org.springframework.validation.annotation.Validated; |
| 10 | import jakarta.annotation.Resource; | 11 | import jakarta.annotation.Resource; |
| 11 | 12 | ||
| 13 | +import java.util.ArrayList; | ||
| 12 | import java.util.List; | 14 | import java.util.List; |
| 15 | +import java.util.Map; | ||
| 16 | +import java.util.stream.Collectors; | ||
| 13 | 17 | ||
| 14 | import com.zteits.urbanops.module.garden.dal.dataobject.problemtype.GardenProblemTypeDO; | 18 | import com.zteits.urbanops.module.garden.dal.dataobject.problemtype.GardenProblemTypeDO; |
| 15 | import com.zteits.urbanops.framework.common.pojo.PageResult; | 19 | import com.zteits.urbanops.framework.common.pojo.PageResult; |
| @@ -93,6 +97,53 @@ public class GardenProblemTypeServiceImpl implements GardenProblemTypeService { | @@ -93,6 +97,53 @@ public class GardenProblemTypeServiceImpl implements GardenProblemTypeService { | ||
| 93 | } | 97 | } |
| 94 | 98 | ||
| 95 | @Override | 99 | @Override |
| 100 | + public List<ProblemTypeCascadeRespVO> getProblemTypeTree(String parentCode) { | ||
| 101 | + List<GardenProblemTypeDO> allList = gardenProblemTypeMapper.selectList( | ||
| 102 | + new com.zteits.urbanops.framework.mybatis.core.query.LambdaQueryWrapperX<GardenProblemTypeDO>() | ||
| 103 | + .eq(GardenProblemTypeDO::getStatus, 1) | ||
| 104 | + .eq(GardenProblemTypeDO::getParentCode, parentCode) | ||
| 105 | + .orderByAsc(GardenProblemTypeDO::getSort) | ||
| 106 | + .orderByAsc(GardenProblemTypeDO::getId)); | ||
| 107 | + | ||
| 108 | + Map<String, List<GardenProblemTypeDO>> childrenMap = allList.stream() | ||
| 109 | + .filter(item -> item.getParentCode() != null && !item.getParentCode().equals(item.getTypeCode())) | ||
| 110 | + .collect(Collectors.groupingBy(GardenProblemTypeDO::getParentCode)); | ||
| 111 | + | ||
| 112 | + List<ProblemTypeCascadeRespVO> result = new ArrayList<>(); | ||
| 113 | + if (parentCode == null) { | ||
| 114 | + List<GardenProblemTypeDO> rootList = allList.stream() | ||
| 115 | + .filter(item -> item.getParentCode() == null || item.getParentCode().equals(item.getTypeCode())) | ||
| 116 | + .collect(Collectors.toList()); | ||
| 117 | + for (GardenProblemTypeDO root : rootList) { | ||
| 118 | + ProblemTypeCascadeRespVO vo = buildTreeNode(root, childrenMap); | ||
| 119 | + result.add(vo); | ||
| 120 | + } | ||
| 121 | + } else { | ||
| 122 | + List<GardenProblemTypeDO> parentList = allList.stream() | ||
| 123 | + .filter(item -> parentCode.equals(item.getTypeCode())) | ||
| 124 | + .collect(Collectors.toList()); | ||
| 125 | + for (GardenProblemTypeDO parent : parentList) { | ||
| 126 | + ProblemTypeCascadeRespVO vo = buildTreeNode(parent, childrenMap); | ||
| 127 | + result.add(vo); | ||
| 128 | + } | ||
| 129 | + } | ||
| 130 | + return result; | ||
| 131 | + } | ||
| 132 | + | ||
| 133 | + private ProblemTypeCascadeRespVO buildTreeNode(GardenProblemTypeDO item, Map<String, List<GardenProblemTypeDO>> childrenMap) { | ||
| 134 | + ProblemTypeCascadeRespVO vo = new ProblemTypeCascadeRespVO(); | ||
| 135 | + vo.setLabel(item.getTypeName()); | ||
| 136 | + vo.setValue(item.getTypeCode()); | ||
| 137 | + List<GardenProblemTypeDO> children = childrenMap.get(item.getTypeCode()); | ||
| 138 | + if (children != null && !children.isEmpty()) { | ||
| 139 | + for (GardenProblemTypeDO child : children) { | ||
| 140 | + vo.getChildren().add(buildTreeNode(child, childrenMap)); | ||
| 141 | + } | ||
| 142 | + } | ||
| 143 | + return vo; | ||
| 144 | + } | ||
| 145 | + | ||
| 146 | + @Override | ||
| 96 | public String generateNextCode(String parentCode) { | 147 | public String generateNextCode(String parentCode) { |
| 97 | return gardenProblemTypeMapper.generateNextCode(parentCode); | 148 | return gardenProblemTypeMapper.generateNextCode(parentCode); |
| 98 | } | 149 | } |
urbanops-module-garden/src/main/java/com/zteits/urbanops/module/garden/util/GisCoordinateUtil.java
0 → 100644
| 1 | +package com.zteits.urbanops.module.garden.util; | ||
| 2 | + | ||
| 3 | +import java.util.regex.Matcher; | ||
| 4 | +import java.util.regex.Pattern; | ||
| 5 | + | ||
| 6 | +/** | ||
| 7 | + * GIS 坐标转换工具 — WGS84 ↔ GCJ02(高德坐标系) | ||
| 8 | + */ | ||
| 9 | +public class GisCoordinateUtil { | ||
| 10 | + | ||
| 11 | + private static final double PI = Math.PI; | ||
| 12 | + private static final double A = 6378245.0; // 长半轴 | ||
| 13 | + private static final double EE = 0.00669342162296594323; // 偏心率平方 | ||
| 14 | + | ||
| 15 | + /** | ||
| 16 | + * WGS84 转 GCJ02(高德) | ||
| 17 | + */ | ||
| 18 | + public static double[] wgs84ToGcj02(double lng, double lat) { | ||
| 19 | + if (outOfChina(lng, lat)) { | ||
| 20 | + return new double[]{lng, lat}; | ||
| 21 | + } | ||
| 22 | + double dLat = transformLat(lng - 105.0, lat - 35.0); | ||
| 23 | + double dLng = transformLng(lng - 105.0, lat - 35.0); | ||
| 24 | + double radLat = lat / 180.0 * PI; | ||
| 25 | + double magic = Math.sin(radLat); | ||
| 26 | + magic = 1 - EE * magic * magic; | ||
| 27 | + double sqrtMagic = Math.sqrt(magic); | ||
| 28 | + dLat = (dLat * 180.0) / ((A * (1 - EE)) / (magic * sqrtMagic) * PI); | ||
| 29 | + dLng = (dLng * 180.0) / (A / sqrtMagic * Math.cos(radLat) * PI); | ||
| 30 | + return new double[]{lng + dLng, lat + dLat}; | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | + /** | ||
| 34 | + * GCJ02 转 WGS84 | ||
| 35 | + */ | ||
| 36 | + public static double[] gcj02ToWgs84(double lng, double lat) { | ||
| 37 | + if (outOfChina(lng, lat)) { | ||
| 38 | + return new double[]{lng, lat}; | ||
| 39 | + } | ||
| 40 | + double[] gcj = wgs84ToGcj02(lng, lat); | ||
| 41 | + return new double[]{lng * 2 - gcj[0], lat * 2 - gcj[1]}; | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + /** 匹配 WKT 中的坐标对:数字 空格 数字 */ | ||
| 45 | + private static final Pattern COORD_PAIR = Pattern.compile("(\\d+\\.?\\d*)\\s+(\\d+\\.?\\d*)"); | ||
| 46 | + | ||
| 47 | + /** | ||
| 48 | + * 转换 WKT 字符串中的所有坐标对(WGS84 → GCJ02) | ||
| 49 | + * 支持 POLYGON、MULTIPOLYGON 等任意 WKT 格式 | ||
| 50 | + */ | ||
| 51 | + public static String transformPolygonWkt(String wkt) { | ||
| 52 | + if (wkt == null || wkt.isBlank()) { | ||
| 53 | + return wkt; | ||
| 54 | + } | ||
| 55 | + Matcher m = COORD_PAIR.matcher(wkt); | ||
| 56 | + StringBuilder sb = new StringBuilder(); | ||
| 57 | + while (m.find()) { | ||
| 58 | + double lng = Double.parseDouble(m.group(1)); | ||
| 59 | + double lat = Double.parseDouble(m.group(2)); | ||
| 60 | + double[] gcj = wgs84ToGcj02(lng, lat); | ||
| 61 | + m.appendReplacement(sb, String.format("%.6f %.6f", gcj[0], gcj[1])); | ||
| 62 | + } | ||
| 63 | + m.appendTail(sb); | ||
| 64 | + return sb.toString(); | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + private static boolean outOfChina(double lng, double lat) { | ||
| 68 | + return lng < 72.004 || lng > 137.8347 || lat < 0.8293 || lat > 55.8271; | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + private static double transformLat(double x, double y) { | ||
| 72 | + double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x)); | ||
| 73 | + ret += (20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0 / 3.0; | ||
| 74 | + ret += (20.0 * Math.sin(y * PI) + 40.0 * Math.sin(y / 3.0 * PI)) * 2.0 / 3.0; | ||
| 75 | + ret += (160.0 * Math.sin(y / 12.0 * PI) + 320.0 * Math.sin(y * PI / 30.0)) * 2.0 / 3.0; | ||
| 76 | + return ret; | ||
| 77 | + } | ||
| 78 | + | ||
| 79 | + private static double transformLng(double x, double y) { | ||
| 80 | + double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x)); | ||
| 81 | + ret += (20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0 / 3.0; | ||
| 82 | + ret += (20.0 * Math.sin(x * PI) + 40.0 * Math.sin(x / 3.0 * PI)) * 2.0 / 3.0; | ||
| 83 | + ret += (150.0 * Math.sin(x / 12.0 * PI) + 300.0 * Math.sin(x / 30.0 * PI)) * 2.0 / 3.0; | ||
| 84 | + return ret; | ||
| 85 | + } | ||
| 86 | +} |
urbanops-server/pom.xml
| @@ -58,11 +58,11 @@ | @@ -58,11 +58,11 @@ | ||
| 58 | <!-- </dependency>--> | 58 | <!-- </dependency>--> |
| 59 | 59 | ||
| 60 | <!-- 数据报表。默认注释,保证编译速度 --> | 60 | <!-- 数据报表。默认注释,保证编译速度 --> |
| 61 | - <dependency> | ||
| 62 | - <groupId>com.zteits.boot</groupId> | ||
| 63 | - <artifactId>urbanops-module-report</artifactId> | ||
| 64 | - <version>${revision}</version> | ||
| 65 | - </dependency> | 61 | +<!-- <dependency>--> |
| 62 | +<!-- <groupId>com.zteits.boot</groupId>--> | ||
| 63 | +<!-- <artifactId>urbanops-module-report</artifactId>--> | ||
| 64 | +<!-- <version>${revision}</version>--> | ||
| 65 | +<!-- </dependency>--> | ||
| 66 | <!-- 工作流。默认注释,保证编译速度 --> | 66 | <!-- 工作流。默认注释,保证编译速度 --> |
| 67 | <dependency> | 67 | <dependency> |
| 68 | <groupId>com.zteits.boot</groupId> | 68 | <groupId>com.zteits.boot</groupId> |
urbanops-server/src/main/resources/application-local.yaml
| @@ -186,6 +186,9 @@ urbanops: | @@ -186,6 +186,9 @@ urbanops: | ||
| 186 | refund-notify-url: http://yunai.natapp1.cc/admin-api/pay/notify/refund # 支付渠道的【退款】回调地址 | 186 | refund-notify-url: http://yunai.natapp1.cc/admin-api/pay/notify/refund # 支付渠道的【退款】回调地址 |
| 187 | transfer-notify-url: https://yunai.natapp1.cc/admin-api/pay/notify/transfer # 支付渠道的【转账】回调地址 | 187 | transfer-notify-url: https://yunai.natapp1.cc/admin-api/pay/notify/transfer # 支付渠道的【转账】回调地址 |
| 188 | demo: false # 开启演示模式 | 188 | demo: false # 开启演示模式 |
| 189 | + security: | ||
| 190 | + mock-enable: true # 本地调试启用 Mock 认证,Token 格式: test{userId}(如 test1 表示用户ID=1) | ||
| 191 | + mock-secret: test | ||
| 189 | tencent-lbs-key: TVDBZ-TDILD-4ON4B-PFDZA-RNLKH-VVF6E # QQ 地图的密钥 https://lbs.qq.com/service/staticV2/staticGuide/staticDoc | 192 | tencent-lbs-key: TVDBZ-TDILD-4ON4B-PFDZA-RNLKH-VVF6E # QQ 地图的密钥 https://lbs.qq.com/service/staticV2/staticGuide/staticDoc |
| 190 | 193 | ||
| 191 | justauth: | 194 | justauth: |