联调接口

This commit is contained in:
2025-12-07 01:19:52 +08:00
parent 21772cae01
commit 478642e780
4 changed files with 126 additions and 122 deletions

View File

@@ -10,6 +10,7 @@
},
"dependencies": {
"@amap/amap-jsapi-loader": "^1.0.1",
"DroneCtrl": "1.0.0",
"axios": "^1.13.2",
"element-plus": "^2.12.0",
"vue": "^3.5.24"

18
pnpm-lock.yaml generated
View File

@@ -14,6 +14,9 @@ importers:
'@amap/amap-jsapi-loader':
specifier: ^1.0.1
version: 1.0.1
DroneCtrl:
specifier: 1.0.0
version: 1.0.0
axios:
specifier: ^1.13.2
version: 1.13.2
@@ -128,28 +131,24 @@ packages:
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@rolldown/binding-linux-arm64-musl@1.0.0-beta.50':
resolution: {integrity: sha512-L0zRdH2oDPkmB+wvuTl+dJbXCsx62SkqcEqdM+79LOcB+PxbAxxjzHU14BuZIQdXcAVDzfpMfaHWzZuwhhBTcw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [musl]
'@rolldown/binding-linux-x64-gnu@1.0.0-beta.50':
resolution: {integrity: sha512-gyoI8o/TGpQd3OzkJnh1M2kxy1Bisg8qJ5Gci0sXm9yLFzEXIFdtc4EAzepxGvrT2ri99ar5rdsmNG0zP0SbIg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [glibc]
'@rolldown/binding-linux-x64-musl@1.0.0-beta.50':
resolution: {integrity: sha512-zti8A7M+xFDpKlghpcCAzyOi+e5nfUl3QhU023ce5NCgUxRG5zGP2GR9LTydQ1rnIPwZUVBWd4o7NjZDaQxaXA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [musl]
'@rolldown/binding-openharmony-arm64@1.0.0-beta.50':
resolution: {integrity: sha512-eZUssog7qljrrRU9Mi0eqYEPm3Ch0UwB+qlWPMKSUXHNqhm3TvDZarJQdTevGEfu3EHAXJvBIe0YFYr0TPVaMA==}
@@ -202,7 +201,7 @@ packages:
resolution: {integrity: sha512-iHmwV3QcVGGvSC1BG5bZ4z6iwa1SOpAPWmnjOErd4Ske+lZua5K9TtAVdx0gMBClJ28DViCbSmZitjWZsWO3LA==}
engines: {node: ^20.19.0 || >=22.12.0}
peerDependencies:
vite: npm:rolldown-vite@7.2.5
vite: ^5.0.0 || ^6.0.0 || ^7.0.0
vue: ^3.2.25
'@vue/compiler-core@3.5.25':
@@ -243,6 +242,9 @@ packages:
'@vueuse/shared@9.13.0':
resolution: {integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==}
DroneCtrl@1.0.0:
resolution: {integrity: sha512-V3WFJas+oJEv1tG41pbHg3gnG5KdSG7VmL6V3xB+G0PtztHwekTHdNAHcx10rR2mbIFB5ITYGIU3HskOAGvkbA==}
async-validator@4.2.5:
resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==}
@@ -395,28 +397,24 @@ packages:
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [linux]
libc: [glibc]
lightningcss-linux-arm64-musl@1.30.2:
resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==}
engines: {node: '>= 12.0.0'}
cpu: [arm64]
os: [linux]
libc: [musl]
lightningcss-linux-x64-gnu@1.30.2:
resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [linux]
libc: [glibc]
lightningcss-linux-x64-musl@1.30.2:
resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==}
engines: {node: '>= 12.0.0'}
cpu: [x64]
os: [linux]
libc: [musl]
lightningcss-win32-arm64-msvc@1.30.2:
resolution: {integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==}
@@ -765,6 +763,8 @@ snapshots:
- '@vue/composition-api'
- vue
DroneCtrl@1.0.0: {}
async-validator@4.2.5: {}
asynckit@0.4.0: {}

View File

@@ -127,6 +127,12 @@ import AMapLoader from '@amap/amap-jsapi-loader'
import { ElMessage, ElMessageBox } from 'element-plus'
import { WebSocketClient, MockWebSocketDataGenerator } from './utils/websocket.js'
import droneImage from './assets/wrj.jpg'
import { getConfig } from ".//utils/request";
import DroneCtrl, {
UploadAreaReq
} from 'DroneCtrl';
const ctrl = new DroneCtrl.default(getConfig());
// 地图相关
const mapContainer = ref(null)
@@ -193,7 +199,7 @@ const initMap = async () => {
// 性能优化:节流处理数据更新
let lastUpdateTime = 0
const UPDATE_INTERVAL = 1000 // 3秒更新一次大幅降低更新频率
let conn = null;
// 初始化WebSocket连接
const initWebSocket = () => {
// 使用模拟数据生成器因为目前没有真实WebSocket服务器
@@ -235,9 +241,14 @@ const toggleWebSocket = () => {
}
wsConnected.value = false
ElMessage.info('已断开连接')
conn.close();
} else {
// 连接
initWebSocket()
conn = ctrl.Message();
conn.onDroneGPS = (data) => {
console.log(data);
};
}
}
@@ -709,6 +720,11 @@ const uploadFence = (fenceId) => {
}
if (pointsData) {
const points = pointsData.points;
ctrl.UploadArea(new UploadAreaReq(points.map(point=>({
longitude: point[0],
latitude: point[1],
}))));
// 输出到控制台
console.log('围栏坐标数据:', pointsData)
console.log('围栏坐标数据(JSON):', JSON.stringify(pointsData, null, 2))

View File

@@ -1,125 +1,112 @@
import axios from 'axios'
import { Notification, MessageBox, Message, Loading } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
import errorCode from '@/utils/errorCode'
import { tansParams, blobValidate } from "@/utils/ruoyi"
import cache from '@/plugins/cache'
import axios from "axios";
import { ElMessage } from "element-plus";
// 是否显示重新登录
export let isRelogin = { show: false }
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 创建axios实例
// 创建 axios 实例
const service = axios.create({
// axios中请求配置有baseURL选项表示请求URL公共部分
baseURL: process.env.VUE_APP_BASE_API,
// 超时
timeout: 10000
})
baseURL: import.meta.env.VITE_APP_BASE_API,
timeout: 50000,
// headers: { "Content-Type": "application/json;charset=utf-8" },
});
// request拦截器
service.interceptors.request.use(config => {
// 是否需要设置 token
const isToken = (config.headers || {}).isToken === false
// 是否需要防止数据重复提交
const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
// if (getToken() && !isToken) {
// config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
// }
// get请求映射params参数
if (config.method === 'get' && config.params) {
let url = config.url + '?' + tansParams(config.params)
url = url.slice(0, -1)
config.params = {}
config.url = url
const useUserStoreHook = () => {
return { };
};
// 请求拦截器
service.interceptors.request.use(
(config) => {
return config;
},
(error) => {
return Promise.reject(error);
}
if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
const requestObj = {
url: config.url,
data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
time: new Date().getTime()
}
const requestSize = Object.keys(JSON.stringify(requestObj)).length // 请求数据大小
const limitSize = 5 * 1024 * 1024 // 限制存放数据5M
if (requestSize >= limitSize) {
console.warn(`[${config.url}]: ` + '请求数据大小超出允许的5M限制无法进行防重复提交验证。')
return config
}
const sessionObj = cache.session.getJSON('sessionObj')
if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
cache.session.setJSON('sessionObj', requestObj)
} else {
const s_url = sessionObj.url // 请求地址
const s_data = sessionObj.data // 请求数据
const s_time = sessionObj.time // 请求时间
const interval = 1000 // 间隔时间(ms),小于此时间视为重复提交
if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
const message = '数据正在处理,请勿重复提交'
console.warn(`[${s_url}]: ` + message)
return Promise.reject(new Error(message))
} else {
cache.session.setJSON('sessionObj', requestObj)
}
}
}
return config
}, error => {
console.log(error)
Promise.reject(error)
})
);
// 响应拦截器
service.interceptors.response.use(res => {
// 未设置状态码则默认成功状态
const code = res.data.code || 200
// 获取错误信息
const msg = errorCode[code] || res.data.msg || errorCode['default']
// 二进制数据则直接返回
if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
return res.data
}
if (code === 401) {
if (!isRelogin.show) {
isRelogin.show = true
MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => {
isRelogin.show = false
store.dispatch('LogOut').then(() => {
location.href = '/index'
})
}).catch(() => {
isRelogin.show = false
})
}
return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
} else if (code === 500) {
Message({ message: msg, type: 'error' })
return Promise.reject(new Error(msg))
} else if (code === 601) {
Message({ message: msg, type: 'warning' })
return Promise.reject('error')
} else if (code !== 200) {
Notification.error({ title: msg })
return Promise.reject('error')
} else {
return res.data
service.interceptors.response.use(
(response) => {
// 响应数据为二进制流处理(Excel导出)
if (response.data instanceof ArrayBuffer) {
return response;
}
return response.data;
},
error => {
console.log('err' + error)
let { message } = error
if (message == "Network Error") {
message = "后端接口连接异常"
} else if (message.includes("timeout")) {
message = "系统接口请求超时"
} else if (message.includes("Request failed with status code")) {
message = "系统接口" + message.substr(message.length - 3) + "异常"
(error) => {
if (error.response && error.response.data) {
// token 过期,重新登录
if (error.response.status == 401) {
localStorage.clear();
ElMessageBox.confirm("当前页面已失效,请重新登录", "提示", {
confirmButtonText: "确定",
type: "warning",
}).then(async () => {
const ipms = new Ipms(getConfig());
const resp = await ipms.GetAuthAddr(new GetAuthAddrReq());
window.location.href =
resp.addr + `&redirect=${window.location.origin}/web/login`;
});
}
Message({ message: message, type: 'error', duration: 5 * 1000 })
return Promise.reject(error)
}
)
ElMessage.error(error.response.data.msg);
return Promise.reject(error.message);
}
);
function fetchsomething(url, params) {
return service({
url: url,
method: params.method,
params: params.method == "GET" ? params.data : null,
responseType: params.responseType,
data: params.data,
headers: params.headers,
});
}
function upload(url, params) {
const req = new FormData();
Object.entries(params.data).map((x) => {
const key = x[0];
const value = x[1];
if (value == null || value == undefined) {
console.log(key, value);
return;
}
if (typeof value == "string") {
req.append(key, value);
} else if (value instanceof Blob) {
req.append(key, value, "avatar");
} else if (Array.isArray(value)) {
for (let i = 0; i < value.length; i++) {
req.append(key, value[i]);
}
} else if (value instanceof Object) {
req.append(key, JSON.stringify(value));
} else {
req.append(key, String(value));
}
});
return service({
url: url,
method: params.method,
params: params.query,
responseType: params.responseType,
data: req,
headers: params.headers,
});
}
export default service
// export let host = `${window.location.protocol}//${window.location.host}`;
export let host = "http://192.168.3.81:5678";
export const getConfig = () => {
return {
host: host,
http_request: fetchsomething,
upload: upload,
};
};
// 导出 axios 实例
export default service;