diff --git a/package-lock.json b/package-lock.json index 854781c..de5c2c7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,7 +26,7 @@ "@vue/compiler-sfc": "^3.5.39", "less": "^4.1.3", "naive-ui": "^2.44.1", - "typescript": "^7.0.2", + "typescript": "^5.9.3", "unplugin-vue-components": "^28.7.0", "vite": "8.1.4", "vue-tsc": "^3.3.9" @@ -956,346 +956,6 @@ "undici-types": "~6.21.0" } }, - "node_modules/@typescript/typescript-aix-ppc64": { - "version": "7.0.2", - "resolved": "https://registry.npmmirror.com/@typescript/typescript-aix-ppc64/-/typescript-aix-ppc64-7.0.2.tgz", - "integrity": "sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-darwin-arm64": { - "version": "7.0.2", - "resolved": "https://registry.npmmirror.com/@typescript/typescript-darwin-arm64/-/typescript-darwin-arm64-7.0.2.tgz", - "integrity": "sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-darwin-x64": { - "version": "7.0.2", - "resolved": "https://registry.npmmirror.com/@typescript/typescript-darwin-x64/-/typescript-darwin-x64-7.0.2.tgz", - "integrity": "sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-freebsd-arm64": { - "version": "7.0.2", - "resolved": "https://registry.npmmirror.com/@typescript/typescript-freebsd-arm64/-/typescript-freebsd-arm64-7.0.2.tgz", - "integrity": "sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-freebsd-x64": { - "version": "7.0.2", - "resolved": "https://registry.npmmirror.com/@typescript/typescript-freebsd-x64/-/typescript-freebsd-x64-7.0.2.tgz", - "integrity": "sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-linux-arm": { - "version": "7.0.2", - "resolved": "https://registry.npmmirror.com/@typescript/typescript-linux-arm/-/typescript-linux-arm-7.0.2.tgz", - "integrity": "sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-linux-arm64": { - "version": "7.0.2", - "resolved": "https://registry.npmmirror.com/@typescript/typescript-linux-arm64/-/typescript-linux-arm64-7.0.2.tgz", - "integrity": "sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-linux-loong64": { - "version": "7.0.2", - "resolved": "https://registry.npmmirror.com/@typescript/typescript-linux-loong64/-/typescript-linux-loong64-7.0.2.tgz", - "integrity": "sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-linux-mips64el": { - "version": "7.0.2", - "resolved": "https://registry.npmmirror.com/@typescript/typescript-linux-mips64el/-/typescript-linux-mips64el-7.0.2.tgz", - "integrity": "sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-linux-ppc64": { - "version": "7.0.2", - "resolved": "https://registry.npmmirror.com/@typescript/typescript-linux-ppc64/-/typescript-linux-ppc64-7.0.2.tgz", - "integrity": "sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-linux-riscv64": { - "version": "7.0.2", - "resolved": "https://registry.npmmirror.com/@typescript/typescript-linux-riscv64/-/typescript-linux-riscv64-7.0.2.tgz", - "integrity": "sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-linux-s390x": { - "version": "7.0.2", - "resolved": "https://registry.npmmirror.com/@typescript/typescript-linux-s390x/-/typescript-linux-s390x-7.0.2.tgz", - "integrity": "sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-linux-x64": { - "version": "7.0.2", - "resolved": "https://registry.npmmirror.com/@typescript/typescript-linux-x64/-/typescript-linux-x64-7.0.2.tgz", - "integrity": "sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-netbsd-arm64": { - "version": "7.0.2", - "resolved": "https://registry.npmmirror.com/@typescript/typescript-netbsd-arm64/-/typescript-netbsd-arm64-7.0.2.tgz", - "integrity": "sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-netbsd-x64": { - "version": "7.0.2", - "resolved": "https://registry.npmmirror.com/@typescript/typescript-netbsd-x64/-/typescript-netbsd-x64-7.0.2.tgz", - "integrity": "sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-openbsd-arm64": { - "version": "7.0.2", - "resolved": "https://registry.npmmirror.com/@typescript/typescript-openbsd-arm64/-/typescript-openbsd-arm64-7.0.2.tgz", - "integrity": "sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-openbsd-x64": { - "version": "7.0.2", - "resolved": "https://registry.npmmirror.com/@typescript/typescript-openbsd-x64/-/typescript-openbsd-x64-7.0.2.tgz", - "integrity": "sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-sunos-x64": { - "version": "7.0.2", - "resolved": "https://registry.npmmirror.com/@typescript/typescript-sunos-x64/-/typescript-sunos-x64-7.0.2.tgz", - "integrity": "sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-win32-arm64": { - "version": "7.0.2", - "resolved": "https://registry.npmmirror.com/@typescript/typescript-win32-arm64/-/typescript-win32-arm64-7.0.2.tgz", - "integrity": "sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=16.20.0" - } - }, - "node_modules/@typescript/typescript-win32-x64": { - "version": "7.0.2", - "resolved": "https://registry.npmmirror.com/@typescript/typescript-win32-x64/-/typescript-win32-x64-7.0.2.tgz", - "integrity": "sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=16.20.0" - } - }, "node_modules/@vicons/fluent": { "version": "0.12.0", "resolved": "https://registry.npmmirror.com/@vicons/fluent/-/fluent-0.12.0.tgz", @@ -3598,38 +3258,17 @@ "license": "0BSD" }, "node_modules/typescript": { - "version": "7.0.2", - "resolved": "https://registry.npmmirror.com/typescript/-/typescript-7.0.2.tgz", - "integrity": "sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==", + "version": "5.9.3", + "resolved": "https://registry.npmmirror.com/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "devOptional": true, "license": "Apache-2.0", "bin": { - "tsc": "bin/tsc" + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" }, "engines": { - "node": ">=16.20.0" - }, - "optionalDependencies": { - "@typescript/typescript-aix-ppc64": "7.0.2", - "@typescript/typescript-darwin-arm64": "7.0.2", - "@typescript/typescript-darwin-x64": "7.0.2", - "@typescript/typescript-freebsd-arm64": "7.0.2", - "@typescript/typescript-freebsd-x64": "7.0.2", - "@typescript/typescript-linux-arm": "7.0.2", - "@typescript/typescript-linux-arm64": "7.0.2", - "@typescript/typescript-linux-loong64": "7.0.2", - "@typescript/typescript-linux-mips64el": "7.0.2", - "@typescript/typescript-linux-ppc64": "7.0.2", - "@typescript/typescript-linux-riscv64": "7.0.2", - "@typescript/typescript-linux-s390x": "7.0.2", - "@typescript/typescript-linux-x64": "7.0.2", - "@typescript/typescript-netbsd-arm64": "7.0.2", - "@typescript/typescript-netbsd-x64": "7.0.2", - "@typescript/typescript-openbsd-arm64": "7.0.2", - "@typescript/typescript-openbsd-x64": "7.0.2", - "@typescript/typescript-sunos-x64": "7.0.2", - "@typescript/typescript-win32-arm64": "7.0.2", - "@typescript/typescript-win32-x64": "7.0.2" + "node": ">=14.17" } }, "node_modules/ufo": { diff --git a/package.json b/package.json index a842f27..7d2a7c2 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "@vue/compiler-sfc": "^3.5.39", "less": "^4.1.3", "naive-ui": "^2.44.1", - "typescript": "^7.0.2", + "typescript": "^5.9.3", "unplugin-vue-components": "^28.7.0", "vite": "8.1.4", "vue-tsc": "^3.3.9" diff --git a/src/api/alarm.ts b/src/api/alarm.ts index f15d252..e4f0776 100644 --- a/src/api/alarm.ts +++ b/src/api/alarm.ts @@ -1,66 +1,84 @@ import request from "@/utils/request"; +import type { ApiResult, OrderItem, PageParam, PageResult } from "@/types/api"; +import type { RosCar } from "./rosCar"; +/** + * 告警列表查询条件,对应后端 com.haizhiyustc.ros.dto.RosInspectionRecordLineImageQueryDTO + */ export interface RosInspectionRecordLineImageQueryDTO { + /** 识别类型 */ recognizeType?: number | string; + /** 开始时间 */ startTime?: string; + /** 结束时间 */ endTime?: string; + /** 是否预警 */ warning?: boolean; + /** 关键字 */ keyword?: string; } -export interface OrderItem { - property: string; - tableIndex?: number; - asc?: boolean; -} - -export interface PageParam { - page?: number; - limit?: number; - orderList?: OrderItem[]; - query?: T; -} - export type RosInspectionRecordLineImagePageQuery = Partial & { keyword?: string; }; -export interface RosInspectionRecordLineImageCar { - id?: string; - deviceKey?: string; - deviceNo?: string; - name?: string; -} - +/** + * 巡检路线抓拍图片识别记录,对应后端 com.haizhiyustc.ros.entity.RosInspectionRecordLineImage + * recognitionStatus: 0待执行 1执行中 2执行成功 3执行失败 + */ export interface RosInspectionRecordLineImage { + /** 巡检记录id */ recordId: string; + /** 巡检设备id快照 */ carId?: string; - car?: RosInspectionRecordLineImageCar; + /** 关联的小车信息 */ + car?: RosCar; + /** 抓拍动作id */ recordActionId: string; + /** 所属任务id */ taskId?: string; + /** 识别类型 */ recognizeType?: number; + /** 图片访问地址 */ imageUrl?: string; + /** 抓拍时间 */ captureTime?: string; + /** 抓拍时的小车位姿x */ poseX?: number; + /** 抓拍时的小车位姿y */ poseY?: number; + /** 抓拍时的小车朝向 */ poseYaw?: number; + /** 识别状态:0待执行 1执行中 2执行成功 3执行失败 */ recognitionStatus?: number; + /** AI识别提示词 */ prompt?: string; + /** AI识别结果 */ recognitionResult?: string; + /** 是否预警 */ warning?: boolean; + /** 预警值 */ warningValue?: string; + /** 失败原因 */ failReason?: string; + /** 开始识别时间 */ startTime?: string; + /** 结束识别时间 */ endTime?: string; + /** 创建时间 */ createTime?: string; + /** 更新时间 */ updateTime?: string; + /** 主键id */ id?: string; } // 查询近期告警列表 +// 返回告警列表,对应后端 warnList 接口 +// 返回: ApiResult> export function getRecentAlarmList(data: RosInspectionRecordLineImageQueryDTO) { - return request({ + return request>({ url: "/admin/rosInspectionRecordLineImage/warnList", data, }); @@ -68,7 +86,7 @@ export function getRecentAlarmList(data: RosInspectionRecordLineImageQueryDTO) { // 分页查询告警列表 export function getAlarmPage(data: PageParam) { - return request({ + return request>>({ url: "/admin/rosInspectionRecordLineImage/list", method: "POST", data, diff --git a/src/api/rosCar.ts b/src/api/rosCar.ts index 7ef053c..e6abffe 100644 --- a/src/api/rosCar.ts +++ b/src/api/rosCar.ts @@ -1,8 +1,238 @@ import request from "@/utils/request"; +import type { ApiResult, PageParam, PageResult } from "@/types/api"; + +/** + * 升降柱状态,对应后端 com.haizhiyustc.ros.dto.RosLiftDTO + */ +export interface RosLift { + /** 升降柱接口是否调用成功 */ + liftSuccess?: boolean; + /** 升降柱接口返回码 */ + liftCode?: number; + /** 升降柱接口返回消息 */ + liftMessage?: string; + /** 升降柱设备状态码 */ + liftDeviceStatusCode?: string; + /** 升降柱设备状态描述 */ + liftDeviceStatusDescription?: string; + /** 升降柱错误码 */ + liftErrorCode?: string; + /** 升降柱错误描述 */ + liftErrorDescription?: string; + /** 升降柱高度 */ + liftHeight?: number; + [key: string]: unknown; +} + +/** + * ROS 小车,对应后端 com.haizhiyustc.ros.entity.RosCar + * status: 0空闲 1巡检 2离线 3充电中 + */ +export interface RosCar { + /** 主键id */ + id?: string; + /** 设备唯一标识 */ + deviceKey?: string; + /** 设备编号 */ + deviceNo?: string; + /** 小车信号 */ + signal?: string; + /** 小车名称 */ + name?: string; + /** 电量百分比 */ + batteryLevel?: number; + /** 电压 */ + voltage?: number; + /** 当前状态:0空闲 1巡检 2离线 3充电中 */ + status?: number; + /** 所属项目名称 */ + projectName?: string; + /** 当前 X 坐标 */ + poseX?: number; + /** 当前 Y 坐标 */ + poseY?: number; + /** 当前朝向 */ + poseYaw?: number; + /** 相机 WebRTC 地址 */ + cameraWebrtcUrl?: string; + /** 相机编号 */ + cameraNo?: string; + /** 红外相机 WebRTC 地址 */ + cameraWebrtcUrl2?: string; + /** 红外相机编号 */ + cameraNo2?: string; + /** 云台预制点 */ + panTiltPreset?: number; + /** 地图 PGM 文件 URL 地址 */ + mapPgmUrl?: string; + /** 地图 YAML 文件 URL 地址 */ + mapYamlUrl?: string; + /** 升降柱高度 */ + liftHeight?: number; + /** 升降柱状态 */ + lift?: RosLift; + /** 创建时间 */ + createTime?: string; + /** 更新时间 */ + updateTime?: string; + [key: string]: unknown; +} + +/** + * 巡检记录,对应后端 com.haizhiyustc.ros.entity.RosInspectionRecord + * status: 0执行中 1执行完成 2执行失败 3已停止 + */ +export interface RosInspectionRecord { + /** 主键id */ + id?: string; + /** 所属巡检任务id */ + taskId?: string; + /** 巡检设备id */ + carId?: string; + /** 巡检说明快照 */ + remark?: string; + /** 全局限速快照 */ + maxVelocity?: number; + /** 插值密度快照(米/点) */ + interpolationDensity?: number; + /** 巡检地图名快照 */ + mapName?: string; + /** 巡检轮数快照 */ + roundCount?: number; + /** 当前执行轮次,从1开始 */ + currentRoundIndex?: number; + /** 开始时间 */ + startTime?: string; + /** 结束时间 */ + endTime?: string; + /** 执行状态:0执行中 1执行完成 2执行失败 3已停止 */ + status?: number; + /** 失败原因 */ + failReason?: string; + /** 当前执行节点id */ + currentNodeId?: string; + /** 当前执行的动作id */ + currentActionId?: string; + /** 开始执行时的小车电量 */ + startBatteryLevel?: number; + /** 执行结束后小车电量 */ + endBatteryLevel?: number; + /** 开始执行时的小车位姿x */ + startPoseX?: number; + /** 开始执行时的小车位姿y */ + startPoseY?: number; + /** 执行结束时的小车位姿x */ + endPoseX?: number; + /** 执行结束时的小车位姿y */ + endPoseY?: number; + /** 总动作数 */ + totalActionCount?: number; + /** 当前节点序号 */ + currentNodeIndex?: number; + /** 创建时间 */ + createTime?: string; + /** 更新时间 */ + updateTime?: string; + [key: string]: unknown; +} + +/** + * 巡检任务节点模板,对应后端 com.haizhiyustc.ros.dto.RosInspectionTaskNodeDTO + * type: via_point 途经点 / action_point 任务点 + */ +export interface RosInspectionTaskNodeDTO { + /** 节点类型:via_point 途经点 / action_point 任务点 */ + type?: string; + /** 位姿x */ + poseX?: number; + /** 位姿y */ + poseY?: number; + /** 节点顺序 */ + nodeIndex?: number; + [key: string]: unknown; +} + +/** + * 巡检任务轮次模板,对应后端 com.haizhiyustc.ros.dto.RosInspectionTaskRoundDTO + * direction: forward 正走 / backward 倒走 + */ +export interface RosInspectionTaskRoundDTO { + /** 轮次,从1开始 */ + roundIndex?: number; + /** 本轮行走方向:forward 正走 / backward 倒走 */ + direction?: string; + [key: string]: unknown; +} + +/** + * 巡检任务动作模板,对应后端 RosInspectionTaskDetailDTO.RosInspectionActionDTO + * command: 0升降柱 1云台旋转 2抓拍识别 + */ +export interface RosInspectionActionDTO { + /** 节点顺序 */ + nodeIndex?: number; + /** 轮次 */ + roundIndex?: number; + /** 动作类型:0升降柱 1云台旋转 2抓拍识别 */ + command?: number; + /** 动作参数 */ + params?: Record; + [key: string]: unknown; +} + +/** + * 巡检任务模板详情,对应后端 com.haizhiyustc.ros.dto.RosInspectionTaskDetailDTO + */ +export interface RosInspectionTaskDetailDTO { + /** 主键id */ + id?: string; + /** 巡检设备id */ + carId?: string; + /** 巡检说明 */ + remark?: string; + /** 巡检状态:0待执行 1执行中 2已停止 */ + status?: number; + /** 全局限速 */ + maxVelocity?: number; + /** ROS2端生成平滑曲线时的插值密度(米/点) */ + interpolationDensity?: number; + /** 巡检地图名 */ + mapName?: string; + /** 巡检轮数 */ + roundCount?: number; + /** 巡检节点模板列表 */ + nodes?: RosInspectionTaskNodeDTO[]; + /** 巡检轮次模板列表 */ + rounds?: RosInspectionTaskRoundDTO[]; + /** 巡检动作模板列表 */ + actions?: RosInspectionActionDTO[]; + [key: string]: unknown; +} + +/** + * 巡检任务下发结果,对应后端 com.haizhiyustc.ros.dto.RosDispatchResultDTO + */ +export interface RosDispatchResultDTO { + /** 巡检记录id */ + recordId?: string; + /** 小车是否接受本次下发 */ + accepted?: boolean; + /** 下发结果说明 */ + message?: string; + [key: string]: unknown; +} + +/** + * 小车分页查询条件,对应后端 com.haizhiyustc.ros.entity.RosCar 的字段过滤 + */ +export type RosCarQuery = Partial & { + /** 关键字 */ + keyword?: string; +}; // 小车分页列表 -export function getRosCarList(data: unknown) { - return request({ +export function getRosCarList(data: PageParam) { + return request>>({ url: "/admin/rosCar/list", data, }); @@ -10,7 +240,7 @@ export function getRosCarList(data: unknown) { // 保存巡检任务模板 export function saveRosInspectionTask(data: unknown) { - return request({ + return request>({ url: "/admin/rosInspectionTask/save", data, }); @@ -18,7 +248,7 @@ export function saveRosInspectionTask(data: unknown) { // 巡检任务模板详情 export function getRosInspectionTaskDetail(cardId: string) { - return request({ + return request>({ url: "/admin/rosInspectionTask/detail", params: { cardId }, }); @@ -26,7 +256,7 @@ export function getRosInspectionTaskDetail(cardId: string) { // 查询小车当前巡检状态 export function getCurrentRosInspection(carId: string) { - return request({ + return request>({ url: "/admin/rosCar/currentInspection", params: { carId }, }); @@ -34,7 +264,7 @@ export function getCurrentRosInspection(carId: string) { // 下发巡检任务 export function dispatchRosInspectionTask(taskId: string) { - return request({ + return request>({ url: "/admin/rosInspectionTask/dispatch", params: { taskId }, }); @@ -42,7 +272,7 @@ export function dispatchRosInspectionTask(taskId: string) { // 停止已下发的巡检任务 export function stopDispatchRosInspectionTask(taskId: string) { - return request({ + return request>({ url: "/admin/rosInspectionTask/stopDispatch", params: { taskId }, }); @@ -54,7 +284,7 @@ export function uploadFile(file: File) { data.append("file", file); - return request({ + return request>({ url: "/admin/file/upload", data, }); @@ -66,7 +296,7 @@ export function updateRosCarMapUrls(data: { mapPgmUrl?: string; mapYamlUrl?: string; }) { - return request({ + return request>({ url: "/admin/rosCar/updateMapUrls", data, }); diff --git a/src/api/user.js b/src/api/user.js deleted file mode 100644 index 8c95d17..0000000 --- a/src/api/user.js +++ /dev/null @@ -1,52 +0,0 @@ -import request, { BASE_URL } from '@/utils/request' -export function getPublicKey() { - return request({ - url: 'admin/account/publicKey' - }) -} -export function login(data) { - return request({ - url: 'admin/account/login', - data - }) -} - -export function captcha() { - return BASE_URL + '/admin/account/captcha' -} -export function getInfo() { - return request({ - url: 'admin/account/info', - }) -} - -export function updateInfo(data) { - return request({ - url: 'admin/account/update', - data - }) -} - -export function updatePwd(data) { - return request({ - url: 'admin/account/updatePwd', - data - }) -} - -// 发送重置密码验证码 -export function getVerifyCode(data) { - return request({ - url: '/admin/sysUser/getVerifyCode', - data - }) -} - -//忘记密码 -export function resetUserPassword(data) { - return request({ - url: '/admin/sysUser/resetUserPassword', - data - }) -} - diff --git a/src/api/user.ts b/src/api/user.ts new file mode 100644 index 0000000..b82a504 --- /dev/null +++ b/src/api/user.ts @@ -0,0 +1,107 @@ +import request, { BASE_URL } from '@/utils/request' +import type { ApiResult } from '@/types/api' + +/** + * 登录返回,对应后端 com.haizhiyustc.system.vo.SysUserLoginVO + */ +export interface LoginResult { + /** 用户id */ + userId: string; + /** 登录令牌 */ + token: string; + /** 令牌请求头名称 */ + tokenName: string; +} + +/** + * 用户个人资料,对应后端 UserInfoVO.UserInfoProfile + */ +export interface UserProfile { + /** 账号id */ + id?: string; + /** 头像 */ + avatar?: string; + /** 登录账号 */ + account?: string; + /** 账户名 */ + name?: string; + /** 性别 */ + gender?: string; + /** 邮箱 */ + email?: string; + /** 手机号 */ + phone?: string; + /** 状态 */ + status?: number; + [key: string]: unknown; +} + +/** + * 当前登录用户信息,对应后端 com.haizhiyustc.system.vo.UserInfoVO + */ +export interface UserInfoVO { + /** 账号名 */ + name?: string; + /** 角色 */ + role?: string; + /** 角色列表 */ + roles?: string[]; + /** 权限列表 */ + permissions?: string[]; + /** 用户个人资料 */ + profile?: UserProfile; + [key: string]: unknown; +} + +export function getPublicKey() { + return request>({ + url: 'admin/account/publicKey' + }) +} + +export function login(data: Record) { + return request>({ + url: 'admin/account/login', + data + }) +} + +export function captcha(): string { + return BASE_URL + '/admin/account/captcha' +} + +export function getInfo() { + return request>({ + url: 'admin/account/info', + }) +} + +export function updateInfo(data: Record) { + return request>({ + url: 'admin/account/update', + data + }) +} + +export function updatePwd(data: Record) { + return request>({ + url: 'admin/account/updatePwd', + data + }) +} + +// 发送重置密码验证码 +export function getVerifyCode(data: Record) { + return request>({ + url: '/admin/sysUser/getVerifyCode', + data + }) +} + +//忘记密码 +export function resetUserPassword(data: Record) { + return request>({ + url: '/admin/sysUser/resetUserPassword', + data + }) +} diff --git a/src/router/routerGuard.js b/src/router/routerGuard.ts similarity index 96% rename from src/router/routerGuard.js rename to src/router/routerGuard.ts index 4b97e11..56f40ee 100644 --- a/src/router/routerGuard.js +++ b/src/router/routerGuard.ts @@ -1,6 +1,6 @@ import router from './index' import { getToken } from '@/utils/auth' -import { useUserStore } from '@/store/modules/user.js' +import { useUserStore } from '@/store/modules/user' const whiteList = ['/login'] // no redirect whitelist diff --git a/src/store/index.js b/src/store/index.js deleted file mode 100644 index cd3e62e..0000000 --- a/src/store/index.js +++ /dev/null @@ -1,5 +0,0 @@ -import { createPinia } from 'pinia' - -export function setupStore(app) { - app.use(createPinia()) -} diff --git a/src/store/index.ts b/src/store/index.ts new file mode 100644 index 0000000..8df6bd0 --- /dev/null +++ b/src/store/index.ts @@ -0,0 +1,6 @@ +import { createPinia } from 'pinia' +import type { App } from 'vue' + +export function setupStore(app: App) { + app.use(createPinia()) +} diff --git a/src/store/modules/app.js b/src/store/modules/app.ts similarity index 50% rename from src/store/modules/app.js rename to src/store/modules/app.ts index 5d033a9..46c0b9c 100644 --- a/src/store/modules/app.js +++ b/src/store/modules/app.ts @@ -1,21 +1,31 @@ import { defineStore } from 'pinia' import { nextTick } from 'vue' -import { useDark } from '@vueuse/core' const sidebarStatusKey = 'sidebar_status' +interface AppState { + /** 侧边栏是否展开,持久化在 localStorage */ + sidebarStatus: boolean + /** 当前设备类型,desktop/mobile */ + device: string + /** 应用配置 */ + config: Record + /** 页面刷新标记,reloadPage 控制 true/false 触发重新渲染 */ + reloadFlag: boolean + /** 是否暗色模式 */ + isDark: boolean +} + export const useAppStore = defineStore('app', { - state() { - return { - sidebarStatus: localStorage.getItem(sidebarStatusKey) ? localStorage.getItem(sidebarStatusKey) === '1' : true, - device: 'desktop', - config: {}, - reloadFlag: true, - isDark: !useDark(), - } - }, + state: (): AppState => ({ + sidebarStatus: localStorage.getItem(sidebarStatusKey) ? localStorage.getItem(sidebarStatusKey) === '1' : true, + device: 'desktop', + config: {}, + reloadFlag: true, + isDark: !window.matchMedia('(prefers-color-scheme: dark)').matches, + }), getters: { - sidebar() { + sidebar(): boolean { return this.sidebarStatus } }, @@ -28,11 +38,11 @@ export const useAppStore = defineStore('app', { localStorage.setItem(sidebarStatusKey, '0') } }, - closeSideBar(withoutAnimation) { + closeSideBar(withoutAnimation: boolean) { localStorage.setItem(sidebarStatusKey, '0') this.sidebarStatus = false }, - toggleDevice(device) { + toggleDevice(device: string) { this.device = device }, async reloadPage() { diff --git a/src/store/modules/user.js b/src/store/modules/user.js deleted file mode 100644 index 4da5a05..0000000 --- a/src/store/modules/user.js +++ /dev/null @@ -1,112 +0,0 @@ -import { getToken, removeToken, setToken } from "@/utils/auth.js"; -import { getInfo, login as doLogin } from "@/api/user.js"; -import { defineStore } from "pinia"; -import { resetRouter } from "@/router"; - -export const useUserStore = defineStore("user", { - state() { - return { - userInfo: { - token: getToken() || "", - id: "", - avatar: "", - name: "", - profile: {}, - permissions: [], - dictMap: {}, - dictTreeMap: {}, - dictIdMap: {}, - dynamicAttrs: [], - companyLogStatus: null, - attrIds: [], - regionIds: [], - }, - }; - }, - getters: { - userId() { - return this.userInfo?.id || ""; - }, - name() { - return this.userInfo?.name || ""; - }, - avatar() { - return this.userInfo?.profile?.avatar || ""; - }, - permissions() { - return this.userInfo?.permissions || []; - }, - dictMap() { - return this.userInfo?.dictMap || {}; - }, - dictTreeMap() { - return this.userInfo?.dictTreeMap || {}; - }, - dictIdMap() { - return this.userInfo?.dictIdMap || {}; - }, - dynamicAttrs() { - return this.userInfo?.dynamicAttrs || []; - }, - companyLogStatus() { - return this.userInfo?.companyLogStatus || 0; - }, - attrIds() { - return this.userInfo?.attrIds || []; - }, - regionIds() { - return this.userInfo?.regionIds || []; - }, - }, - actions: { - async login(userInfo) { - const res = await doLogin(userInfo); - const { token, tokenName } = res.data; - this.userInfo.token = token; - setToken(token, tokenName); - return true; - }, - async getInfo() { - const res = await getInfo(); - const data = res.data; - const { - name, - profile, - permissions, - dynamicAttrs, - attrIds, - companyLogStatus, - regionIds, - } = data; - - // 保留当前的 token,避免被覆盖 - const currentToken = this.userInfo.token || getToken(); - - this.userInfo = { - token: currentToken, - id: profile.id, - name, - profile, - permissions, - dynamicAttrs, - attrIds, - companyLogStatus, - regionIds, - }; - return data; - }, - // user logout - async logout() { - await this.resetToken(); - await resetRouter(); - return true; - }, - async resetToken() { - this.userInfo = { - profile: {}, - permissions: [], - }; - removeToken(); - }, - }, -}); diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts new file mode 100644 index 0000000..2de2905 --- /dev/null +++ b/src/store/modules/user.ts @@ -0,0 +1,73 @@ +import { getToken, removeToken, setToken } from "@/utils/auth"; +import { getInfo, login as doLogin } from "@/api/user"; +import type { UserInfoVO } from "@/api/user"; +import { defineStore } from "pinia"; +import { resetRouter } from "@/router"; + +// store 侧用户信息:后端返回结构 + 登录令牌,token 独立维护 +type UserInfo = Partial & { + token?: string | null; +}; + +export const useUserStore = defineStore("user", { + state: (): { userInfo: UserInfo } => ({ + userInfo: { + token: getToken() || "", + name: "", + profile: {}, + permissions: [], + }, + }), + getters: { + userId(): string { + return this.userInfo?.profile?.id || ""; + }, + name(): string { + return this.userInfo?.name || ""; + }, + avatar(): string { + return this.userInfo?.profile?.avatar || ""; + }, + permissions(): string[] { + return this.userInfo?.permissions || []; + }, + }, + actions: { + async login(userInfo: Record) { + const res = await doLogin(userInfo); + const { token, tokenName } = res.data; + this.userInfo.token = token; + setToken(token, tokenName); + return true; + }, + async getInfo() { + const res = await getInfo(); + const data = res.data; + const { name, profile, permissions } = data; + + // 保留当前的 token,避免被覆盖 + const currentToken = this.userInfo.token || getToken(); + + this.userInfo = { + token: currentToken, + name, + profile, + permissions, + }; + return data; + }, + // user logout + async logout() { + await this.resetToken(); + await resetRouter(); + return true; + }, + async resetToken() { + this.userInfo = { + profile: {}, + permissions: [], + }; + removeToken(); + }, + }, +}); diff --git a/src/types/api.ts b/src/types/api.ts new file mode 100644 index 0000000..922eb9b --- /dev/null +++ b/src/types/api.ts @@ -0,0 +1,48 @@ +/** + * 后端统一返回结构,对应后端 com.haizhiyustc.common.web.api.ApiResult + * code: 200 成功 / 401 未登录或登录过期 / 500 失败 + */ +export interface ApiResult { + /** 状态码 */ + code: number; + /** 返回的数据 */ + data: T; + /** 说明信息 */ + msg: string; +} + +/** + * 分页结果,对应后端 easy-query 的 EasyPageResult(仅返回 data 与 total) + */ +export interface PageResult { + /** 符合条件的总记录数 */ + total?: number; + /** 当前页数据列表 */ + data?: T[]; +} + +/** + * 排序项,对应后端 com.haizhiyustc.common.crud.bean.OrderItem + */ +export interface OrderItem { + /** 排序属性名 */ + property: string; + /** 关联表序号 */ + tableIndex?: number; + /** 是否升序,默认 false 降序 */ + asc?: boolean; +} + +/** + * 分页请求参数,对应后端 com.haizhiyustc.common.crud.bean.PageParam + */ +export interface PageParam { + /** 页码,从1开始 */ + page?: number; + /** 每页条数 */ + limit?: number; + /** 排序列表 */ + orderList?: OrderItem[]; + /** 查询条件 */ + query?: T; +} diff --git a/src/types/js-modules.d.ts b/src/types/js-modules.d.ts index 559fde5..2bc2251 100644 --- a/src/types/js-modules.d.ts +++ b/src/types/js-modules.d.ts @@ -9,55 +9,12 @@ interface Window { create(options: Record): unknown; warning(options: Record): unknown; }; -} - -declare module "@/utils/auth" { - export function getToken(): string | null; - export function getTokenName(): string | null; - export function setToken(tokenValue: string, tokenNameValue?: string): void; - export function removeToken(): void; -} - -declare module "@/utils/auth.js" { - export function getToken(): string | null; - export function getTokenName(): string | null; - export function setToken(tokenValue: string, tokenNameValue?: string): void; - export function removeToken(): void; -} - -declare module "@/store/modules/user" { - export function useUserStore(): { - login(userInfo: Record): Promise; - logout(): Promise; + $loadingBar: { + start(): void; + finish(): void; + error(): void; + [key: string]: unknown; }; } -declare module "@/store/modules/user.js" { - export function useUserStore(): { - login(userInfo: Record): Promise; - logout(): Promise; - }; -} - -declare module "@/utils/passwordEncrypt.js" { - export function encryptPasswordPayload>( - payload: T, - fields: Array, - ): Promise; -} - -declare module "@/utils/request" { - import type { AxiosRequestConfig } from "axios"; - - export const BASE_URL: string; - const request: (config: AxiosRequestConfig) => Promise; - export default request; -} - -declare module "@/utils/request.js" { - import type { AxiosRequestConfig } from "axios"; - - export const BASE_URL: string; - const request: (config: AxiosRequestConfig) => Promise; - export default request; -} +declare var $loadingBar: Window["$loadingBar"]; diff --git a/src/utils/auth.js b/src/utils/auth.ts similarity index 72% rename from src/utils/auth.js rename to src/utils/auth.ts index 608c076..3dff346 100644 --- a/src/utils/auth.js +++ b/src/utils/auth.ts @@ -1,10 +1,10 @@ const TokenKey = "token"; const TOKEN_NAME_KEY = "tokenName"; -let token = null; -let tokenName = null; +let token: string | null = null; +let tokenName: string | null = null; -export function getToken() { +export function getToken(): string | null { const storedToken = token || window.localStorage.getItem(TokenKey); if (!storedToken || storedToken === "null" || storedToken === "undefined") { token = null; @@ -15,21 +15,21 @@ export function getToken() { return token; } -export function setToken(tokenValue, tokenNameValue) { +export function setToken(tokenValue: string, tokenNameValue?: string): void { token = tokenValue; tokenName = tokenNameValue || "Authorization"; window.localStorage.setItem(TokenKey, token); window.localStorage.setItem(TOKEN_NAME_KEY, tokenName); } -export function removeToken() { +export function removeToken(): void { token = null; tokenName = null; window.localStorage.removeItem(TokenKey); window.localStorage.removeItem(TOKEN_NAME_KEY); } -export function getTokenName() { +export function getTokenName(): string | null { tokenName = tokenName || window.localStorage.getItem(TOKEN_NAME_KEY); return tokenName; } diff --git a/src/utils/passwordEncrypt.js b/src/utils/passwordEncrypt.ts similarity index 66% rename from src/utils/passwordEncrypt.js rename to src/utils/passwordEncrypt.ts index b5af411..6653f13 100644 --- a/src/utils/passwordEncrypt.js +++ b/src/utils/passwordEncrypt.ts @@ -1,12 +1,12 @@ import { JSEncrypt } from 'jsencrypt' import { getPublicKey } from '@/api/user' -export async function getPasswordPublicKey() { +export async function getPasswordPublicKey(): Promise { const res = await getPublicKey() return res.data } -export function encryptPassword(plainText, publicKey) { +export function encryptPassword(plainText: string, publicKey: string): string { const encryptor = new JSEncrypt() encryptor.setPublicKey(formatPublicKey(publicKey)) const encrypted = encryptor.encrypt(plainText) @@ -16,16 +16,19 @@ export function encryptPassword(plainText, publicKey) { return encrypted } -export async function encryptPasswordPayload(payload, fields) { +export async function encryptPasswordPayload>( + payload: T, + fields: Array, +): Promise { const publicKey = await getPasswordPublicKey() const nextPayload = { ...payload } for (const field of fields) { - nextPayload[field] = encryptPassword(payload[field] || '', publicKey) + nextPayload[field] = encryptPassword(String(payload[field] || ''), publicKey) as T[keyof T] } return nextPayload } -function formatPublicKey(publicKey) { +function formatPublicKey(publicKey: string): string { if (!publicKey) { return '' } diff --git a/src/utils/request.js b/src/utils/request.ts similarity index 87% rename from src/utils/request.js rename to src/utils/request.ts index 79b3d4e..bb4970e 100644 --- a/src/utils/request.js +++ b/src/utils/request.ts @@ -1,4 +1,4 @@ -import axios from "axios"; +import axios, { type AxiosRequestConfig } from "axios"; import { useUserStore } from "@/store/modules/user"; import { getToken, getTokenName } from "@/utils/auth"; import router from "@/router"; @@ -70,16 +70,21 @@ service.interceptors.response.use( }, ); -export default service; +// 响应拦截器已解包 response.data,对外暴露的请求方法保持 Promise 语义 +const request = (config: AxiosRequestConfig): Promise => { + return service.request(config); +}; -function showApiMessage(res) { +export default request; + +function showApiMessage(res: { msg?: string }) { window.$message.error(res.msg || "error", { duration: 5 * 1000, }); } // 弹窗确认防抖 -let noLoginAlert = null; +let noLoginAlert: unknown = null; function handleNoLogin() { if (noLoginAlert == null) { diff --git a/src/views/login/index.vue b/src/views/login/index.vue index 173cec5..74d14ed 100644 --- a/src/views/login/index.vue +++ b/src/views/login/index.vue @@ -1,8 +1,8 @@