diff --git a/.DS_Store b/.DS_Store index d2e8512..7fbefe0 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/.env.development b/.env.development new file mode 100644 index 0000000..3397d4f --- /dev/null +++ b/.env.development @@ -0,0 +1,21 @@ +# 环境变量 (命名必须以 VITE_ 开头) +# 接口前缀 +VITE_API_PREFIX = '/dev-api' + +# 接口地址 +VITE_API_BASE_URL = 'http://pms.dtyx.net:9158/' + +# 接口地址 (WebSocket) +VITE_API_WS_URL = 'ws://localhost:8000' + +# 地址前缀 +VITE_BASE = '/' + +# 是否开启开发者工具 +VITE_OPEN_DEVTOOLS = false + +# 应用配置面板 +VITE_APP_SETTING = true + +# 客户端ID +VITE_CLIENT_ID = 'ef51c9a3e9046c4f2ea45142c8a8344a' \ No newline at end of file diff --git a/.env.production b/.env.production new file mode 100644 index 0000000..debf235 --- /dev/null +++ b/.env.production @@ -0,0 +1,17 @@ +# 环境变量 (命名必须以 VITE_ 开头) + +# 是否在打包时启用 Mock +VITE_BUILD_MOCK = false + +# 接口地址 +VITE_API_BASE_URL = 'https://api.continew.top' +VITE_API_WS_URL = 'wss://api.continew.top' + +# 地址前缀 +VITE_BASE = '/' + +# 应用配置面板 +VITE_APP_SETTING = true + +# 客户端ID +VITE_CLIENT_ID = 'ef51c9a3e9046c4f2ea45142c8a8344a' \ No newline at end of file diff --git a/.env.test b/.env.test new file mode 100644 index 0000000..0367139 --- /dev/null +++ b/.env.test @@ -0,0 +1,22 @@ +# 环境变量 (命名必须以 VITE_ 开头) + +# 是否在打包时启用 Mock +VITE_BUILD_MOCK = true + +# 接口前缀 +VITE_API_PREFIX = '/test-api' + +# 接口地址 +VITE_API_BASE_URL = 'http://localhost:8000' + +# 地址前缀 +VITE_BASE = '/test' + +# 是否开启开发者工具 +VITE_OPEN_DEVTOOLS = true + +# 应用配置面板 +VITE_APP_SETTING = false + +# 客户端ID +VITE_CLIENT_ID = 'ef51c9a3e9046c4f2ea45142c8a8344a' diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..35410ca --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/I3M-Web.iml b/.idea/I3M-Web.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/I3M-Web.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..03d9549 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..29e4152 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..c814c8a --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..797acea --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..7d8fc57 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/AUTO_RECOGNITION_GUIDE.md b/AUTO_RECOGNITION_GUIDE.md new file mode 100644 index 0000000..f132cd2 --- /dev/null +++ b/AUTO_RECOGNITION_GUIDE.md @@ -0,0 +1,95 @@ +# 自动识别功能使用说明 + +## 功能概述 + +工业图像自动识别功能允许用户使用AI算法自动检测图像中的各种缺陷类型,包括裂纹、腐蚀、磨损、变形等。 + +## 使用步骤 + +### 1. 准备工作 +1. 在左侧项目管理树中选择项目、机组或部件 +2. 在下方图像列表中选择一张需要识别的图像 +3. 确保图像已在右上角预览区域显示 + +### 2. 启动自动识别 +1. 点击顶部工具栏中的"自动标注"按钮 +2. 界面会自动切换到识别模式: + - 左侧显示"自动识别设置"面板 + - 右侧显示"识别结果"面板 + +### 3. 配置识别参数 +在左侧设置面板中: +- **识别算法**: 选择YOLOv5、YOLOv8或R-CNN +- **置信度**: 调整识别置信度阈值(0-100%) +- **缺陷类型**: 选择要识别的缺陷类型 + - 裂纹 (Crack) + - 划痕 (Scratch) + - 腐蚀 (Corrosion) + - 变形 (Deformation) + - 孔洞 (Hole) + - 污垢 (Dirt) + +### 4. 开始识别 +1. 配置完参数后,点击"开始识别"按钮 +2. 系统会显示识别进度 +3. 识别完成后,结果会在右侧面板显示 + +### 5. 查看识别结果 +右侧识别结果面板显示: +- **统计信息**: 各类缺陷的数量和平均置信度 +- **详细列表**: 每个缺陷的具体信息 + - 缺陷类型和颜色标识 + - 置信度百分比 + - 位置坐标 + - 尺寸大小 + - 修复建议 + +### 6. 结果操作 +- **选择结果**: 点击结果项可在图像上高亮显示 +- **保存结果**: 将识别结果保存到系统 +- **导出结果**: 导出识别结果为文件 + +### 7. 退出识别模式 +点击左上角的关闭按钮(×)可退出识别模式,返回正常的项目管理界面。 + +## 缺陷类型说明 + +| 缺陷类型 | 描述 | 修复建议 | +|---------|------|----------| +| 裂纹 | 表面或内部的线状断裂 | 立即维修,防止扩散 | +| 腐蚀 | 金属表面的化学腐蚀 | 清洁并涂保护层 | +| 磨损 | 表面材料的磨损消失 | 定期监测,必要时更换 | +| 变形 | 结构形状的改变 | 检查结构完整性 | +| 划痕 | 表面的轻微划伤 | 轻微处理即可 | +| 孔洞 | 表面的洞穴或孔隙 | 立即修补 | +| 污垢 | 表面的污染物 | 清洁处理 | + +## 注意事项 + +1. **图像质量**: 确保图像清晰度足够,便于AI识别 +2. **光照条件**: 良好的光照有助于提高识别准确度 +3. **置信度设置**: 根据实际需要调整置信度阈值 +4. **人工复核**: 置信度低于60%的结果建议人工复核 +5. **数据保存**: 及时保存重要的识别结果 + +## 技术参数 + +- **支持格式**: JPG, PNG, BMP等常见图像格式 +- **识别算法**: YOLOv5, YOLOv8, R-CNN +- **置信度范围**: 0-100% +- **处理时间**: 通常3-10秒(根据图像大小) +- **准确率**: 一般在85-95%之间 + +## 故障排除 + +### 常见问题 +1. **无法启动识别**: 检查是否选择了图像 +2. **识别结果为空**: 调整置信度阈值或更换图像 +3. **识别时间过长**: 检查网络连接或联系技术支持 +4. **结果不准确**: 调整算法参数或使用不同的识别算法 + +### 性能优化建议 +- 使用适当的图像分辨率(建议800x600以上) +- 确保图像对比度清晰 +- 避免过度曝光或过暗的图像 +- 定期清理缓存数据 \ No newline at end of file diff --git a/src/.DS_Store b/src/.DS_Store new file mode 100644 index 0000000..7d60bf8 Binary files /dev/null and b/src/.DS_Store differ diff --git a/src/apis/attach-info/index.ts b/src/apis/attach-info/index.ts new file mode 100644 index 0000000..e3a7390 --- /dev/null +++ b/src/apis/attach-info/index.ts @@ -0,0 +1,96 @@ +import http from '@/utils/http' +const { request } = http +import type { AttachInfoData, BusinessTypeResult } from './type' + +/** + * 批量新增附件信息 + * @param businessType 业务类型 + * @param files 文件列表 + */ +export function batchAddAttachment(businessType: string, formData: FormData) { + return request({ + url: `/attach-info/batch/${businessType}`, + method: 'post', + data: formData, + headers: { + 'Content-Type': 'multipart/form-data' + } + }) +} + +/** + * 新增单个附件信息 + * @param businessType 业务类型 + * @param formData 表单数据 + */ +export function addAttachment(formData: FormData) { + return request({ + url: `/attach-info/model`, + method: 'post', + data: formData, + headers: { + 'Content-Type': 'multipart/form-data' + } + }) +} +/** + * 新增单个附件信息 + * @param businessType 业务类型 + * @param formData 表单数据 + */ +export function addAttachmentByDefectMarkPic(formData: FormData) { + return request({ + url: `/attach-info/defect_mark_pic`, + method: 'post', + data: formData, + headers: { + 'Content-Type': 'multipart/form-data' + } + }) +} +/** + * 新增单个附件信息 + * @param businessType 业务类型 + * @param formData 表单数据 + */ +export function addAttachInsurance(formData: FormData) { + return request({ + url: `/attach-info/insurance_file`, + method: 'post', + data: formData, + headers: { + 'Content-Type': 'multipart/form-data' + } + }) +} +/** + * 查询附件业务类型 + */ +export function getAttachBusinessTypes() { + return request({ + url: '/common/list/attach-business_type', + method: 'get' + }) +} + +/** + * 获取附件列表 + * @param businessType 业务类型 + */ +export function getAttachmentList(businessType: string) { + return request({ + url: `/attach-info/list/${businessType}`, + method: 'get' + }) +} + +/** + * 删除附件 + * @param id 附件ID + */ +export function deleteAttachment(id: string | number) { + return request({ + url: `/attach-info/${id}`, + method: 'delete' + }) +} \ No newline at end of file diff --git a/src/apis/attach-info/type.ts b/src/apis/attach-info/type.ts new file mode 100644 index 0000000..816366e --- /dev/null +++ b/src/apis/attach-info/type.ts @@ -0,0 +1,34 @@ +/** + * 附件信息数据类型 + */ +export interface AttachInfoData { + id: string | number + fileName: string + fileUrl: string + fileType: string + fileSize: number + createTime: string + businessType: string + remark?: string + userDefinedPath?: string +} + +/** + * 业务类型结果 + */ +export interface BusinessTypeResult { + code: number + data: BusinessType[] + msg: string + status: number +} + +/** + * 业务类型 + */ +export interface BusinessType { + id: number + name: string + code: string + description?: string +} \ No newline at end of file diff --git a/src/apis/common/common.ts b/src/apis/common/common.ts index 72a56da..33e8608 100644 --- a/src/apis/common/common.ts +++ b/src/apis/common/common.ts @@ -45,3 +45,8 @@ export function listMenuType() { export function uploadFile(data: FormData) { return http.post(`${BASE_URL}/file`, data) } + +/** @desc 查询缺陷类型列表 */ +export function listDefectType() { + return http.get(`${BASE_URL}/list/defect-type`) +} diff --git a/src/apis/common/index.ts b/src/apis/common/index.ts index 8dbb1bd..24eb3a0 100644 --- a/src/apis/common/index.ts +++ b/src/apis/common/index.ts @@ -1,3 +1,4 @@ export * from './common' export * from './captcha' export * from './dashboard' +export * from './type' diff --git a/src/apis/common/type.ts b/src/apis/common/type.ts index a9a41f2..d7749b6 100644 --- a/src/apis/common/type.ts +++ b/src/apis/common/type.ts @@ -58,3 +58,17 @@ export interface CheckBehaviorCaptchaResp { repCode: string repMsg: string } + +/** 缺陷类型响应类型 - 根据实际API返回结构 */ +export interface DefectTypeResp { + [key: string]: string // 键是缺陷代码,值是缺陷名称 +} + +/** 缺陷类型选项类型 - 用于前端组件 */ +export interface DefectTypeOption { + code: string; + label: string; + value: string; + name?: string; // 兼容性字段 + sort?: number; // 兼容性字段 +} diff --git a/src/apis/employee/index.ts b/src/apis/employee/index.ts new file mode 100644 index 0000000..ae68c25 --- /dev/null +++ b/src/apis/employee/index.ts @@ -0,0 +1,77 @@ +import http from '@/utils/http' +import type { CertificationInfo, CertificationListParams, CertificationListResponse, SimpleUserInfo } from './type' + +const { request } = http + +// 导出类型定义 +export type { CertificationInfo, CertificationListParams, CertificationListResponse, SimpleUserInfo } + +// 新增人员资质 +export function createCertification(data: CertificationInfo) { + return request({ + url: '/certification', + method: 'post', + data + }) +} + +// 查询人员资质信息列表 +export function getCertificationList(params: CertificationListParams) { + return request({ + url: '/certification/list', + method: 'get', + params + }) +} + +// 查询人员资质详情 +export function getCertificationDetail(certificationId: string) { + return request({ + url: `/certification/detail/${certificationId}`, + method: 'get' + }) +} + +// 修改人员资质信息 +export function updateCertification(certificationId: string, data: CertificationInfo) { + return request({ + url: `/certification/${certificationId}`, + method: 'put', + data + }) +} + +// 删除人员资质 +export function deleteCertification(certificationId: string) { + return request({ + url: `/certification/${certificationId}`, + method: 'delete' + }) +} + +// 批量删除人员资质 +export function batchDeleteCertification(ids: string[]) { + return request({ + url: '/certification/batch', + method: 'delete', + data: { ids } + }) +} + +// 导出人员资质 +export function exportCertification(params: CertificationListParams) { + return request({ + url: '/certification/export', + method: 'get', + params, + responseType: 'blob' + }) +} + +// 获取用户列表(用于下拉选择) +export function getUserList() { + return request({ + url: '/user/list', + method: 'get' + }) +} \ No newline at end of file diff --git a/src/apis/employee/type.ts b/src/apis/employee/type.ts new file mode 100644 index 0000000..6f87b83 --- /dev/null +++ b/src/apis/employee/type.ts @@ -0,0 +1,38 @@ +/** 人员资质信息接口 */ +export interface CertificationInfo { + certificationId?: string + certificationCode: string + certificationImage: string + certificationName: string + certificationType: string + userId: string + validityDateBegin: string + validityDateEnd: string + createTime?: string + updateTime?: string +} + +/** 人员资质列表查询参数 */ +export interface CertificationListParams { + certificationName?: string + certificationType?: string + userName?: string + current?: number + size?: number +} + +/** 人员资质列表响应 */ +export interface CertificationListResponse { + records: CertificationInfo[] + total: number + current: number + size: number +} + +/** 用户信息简化版 */ +export interface SimpleUserInfo { + userId: string + userName: string + account: string + name: string +} \ No newline at end of file diff --git a/src/apis/health-record/index.ts b/src/apis/health-record/index.ts new file mode 100644 index 0000000..23284c2 --- /dev/null +++ b/src/apis/health-record/index.ts @@ -0,0 +1,136 @@ +import http from '@/utils/http' + +const { request } = http + +export interface HealthRecord { + id?: string + employeeName: string + employeeId: string + checkupDate: string + hospital: string + checkType: string + result: string + nextCheckupDate: string + summary?: string + suggestions?: string + remarks?: string + reportFiles?: any[] +} + +export interface HealthRecordListParams { + employeeName?: string + employeeId?: string + hospital?: string + result?: string + checkupDateStart?: string + checkupDateEnd?: string + current?: number + size?: number +} + +export interface HealthRecordListResponse { + records: HealthRecord[] + total: number + current: number + size: number +} + +// 新增健康记录 +export function createHealthRecord(data: HealthRecord) { + return request({ + url: '/health-record', + method: 'post', + data + }) +} + +// 查询健康记录列表 +export function getHealthRecordList(params: HealthRecordListParams) { + return request({ + url: '/health-record/list', + method: 'get', + params + }) +} + +// 查询健康记录详情 +export function getHealthRecordDetail(id: string) { + return request({ + url: `/health-record/detail/${id}`, + method: 'get' + }) +} + +// 编辑健康记录 +export function updateHealthRecord(id: string, data: HealthRecord) { + return request({ + url: `/health-record/${id}`, + method: 'put', + data + }) +} + +// 删除健康记录 +export function deleteHealthRecord(id: string) { + return request({ + url: `/health-record/${id}`, + method: 'delete' + }) +} + +// 上传体检报告 +export function uploadHealthReport(file: File, recordId: string) { + const formData = new FormData() + formData.append('file', file) + formData.append('recordId', recordId) + + return request({ + url: '/health-record/upload-report', + method: 'post', + data: formData, + headers: { + 'Content-Type': 'multipart/form-data' + } + }) +} + +// 下载体检报告 +export function downloadHealthReport(fileId: string) { + return request({ + url: `/health-record/download-report/${fileId}`, + method: 'get', + responseType: 'blob' + }) +} + +// 获取员工健康记录历史 +export function getEmployeeHealthHistory(employeeId: string) { + return request({ + url: `/health-record/employee/${employeeId}`, + method: 'get' + }) +} + +// 导出健康记录 +export function exportHealthRecords(params: HealthRecordListParams) { + return request({ + url: '/health-record/export', + method: 'get', + params, + responseType: 'blob' + }) +} + +// 安排体检 +export function scheduleHealthCheck(data: { + employeeIds: string[] + checkupDate: string + hospital: string + checkType: string +}) { + return request({ + url: '/health-record/schedule', + method: 'post', + data + }) +} \ No newline at end of file diff --git a/src/apis/index.ts b/src/apis/index.ts index b970b6c..182c8cd 100644 --- a/src/apis/index.ts +++ b/src/apis/index.ts @@ -7,6 +7,15 @@ export * from './code' export * from './schedule' export * from './project' export * from './project/task' +export * from './attach-info' +export * from './model-config' +// 保险相关模块 +export * as InsuranceAPI from './insurance' +export * as InsuranceCompanyAPI from './insurance-company' +export * as InsuranceTypeAPI from './insurance-type' +export * as HealthRecordAPI from './health-record' +export * as InsuranceFileAPI from './insurance-file' +export * as EmployeeAPI from './employee' export * from './area/type' export * from './auth/type' @@ -16,3 +25,5 @@ export * from './system/type' export * from './code/type' export * from './schedule/type' export * from './project/type' +export * from './attach-info/type' +export * from './model-config/type' diff --git a/src/apis/industrial-image/defect.ts b/src/apis/industrial-image/defect.ts new file mode 100644 index 0000000..ab0f267 --- /dev/null +++ b/src/apis/industrial-image/defect.ts @@ -0,0 +1,239 @@ +import http from '@/utils/http' + +// 缺陷检测请求参数 +export interface DefectDetectionRequest { + confThreshold: number + defectTypeList: string[] + imageId: string + modelId: string +} + +// 手动添加缺陷请求参数 +export interface ManualDefectAddRequest { + attachId: string + axial: number + chordwise: number + defectCode: string + defectLevel: string + defectName: string + defectPosition: string + defectType: string + description: string + detectionDate: string + labelInfo: string + markInfo: { + bbox: number[] + clsId: number + confidence: number + label: string + } + repairIdea: string + repairStatus: string + source: string +} + +// 缺陷检测结果 +export interface DefectDetectionResult { + attachId: string + attachPath: string + axial: number + chordwise: number + defectCode: string + defectId: string + defectLevel: string + defectLevelLabel: string + defectName: string + defectPosition: string + defectType: string + defectTypeLabel: string + description: string + detectionDate: string + imageId: string + labelInfo: string + markInfo: { + bbox: number[] + clsId: number + confidence: number + label: string + } + repairIdea: string + repairStatus: string + repairStatusLabel: string + source: string + sourceLabel: string +} + +// API响应结构 +export interface DefectDetectionResponse { + code: number + data: DefectDetectionResult[] + msg: string + status: number + success: boolean +} + +// 手动添加缺陷响应结构 +export interface ManualDefectAddResponse { + code: number + data: DefectDetectionResult + msg: string + status: number + success: boolean +} + +/** @desc 单图自动标注缺陷 */ +export const detectDefects = (params: DefectDetectionRequest) => { + return http.post('/defect/detect', params) +} + +/** @desc 手动添加缺陷记录 */ +export const addManualDefect = (params: ManualDefectAddRequest,imageId:string) => { + return http.post(`/defect/${imageId}`, params) +} + +// 缺陷相关的其他接口 + +// 缺陷列表查询参数接口 +export interface DefectListParams { + defectId?: string; + defectLevel?: string; + defectType?: string; + keyword?: string; + turbineId?: string; + imageId?: string; // 添加imageId参数,用于按图像筛选缺陷 +} + +/** @desc 获取缺陷列表 */ +export const getDefectList = (params: DefectListParams) => { + return http.get<{ + code: number + data: DefectDetectionResult[] + msg: string + status: number + success: boolean + }>('/defect/list', params ) +} + +/** @desc 添加缺陷 */ +export const addDefect = (params: Partial) => { + return http.post<{ + code: number + data: DefectDetectionResult + msg: string + status: number + success: boolean + }>('/defect/add', params) +} + +/** @desc 更新缺陷 */ +export const updateDefect = (defectId: string, params: Partial) => { + return http.put<{ + code: number + data: DefectDetectionResult + msg: string + status: number + success: boolean + }>(`/defect/${defectId}`, params) +} + +/** @desc 删除缺陷 */ +export const deleteDefect = (defectId: string) => { + return http.del<{ + code: number + msg: string + status: number + success: boolean + }>(`/defect/${defectId}`) +} + +/** @desc 上传标注后的图片作为附件 */ +export const uploadAnnotatedImage = (imageBlob: Blob, fileName: string) => { + const formData = new FormData() + formData.append('file', imageBlob, fileName) + + return http.post<{ + code: number + data: AttachInfoData + msg: string + status: number + success: boolean + }>('/attach-info/defect_mark_pic', formData, { + headers: { + 'Content-Type': 'multipart/form-data' + } + }) +} + +// 附件信息数据类型 +export interface AttachInfoData { + attachId: string + attachPath: string + fileName: string + fileSize: number + contentType: string + uploadTime: string + [key: string]: any +} + +// 缺陷信息接口 +export interface DefectInfo { + id: string; + defectId?: string; + defectName?: string; + defectLevel?: string; + defectType?: string; + defectPosition?: string; + detectionDate?: string; + description?: string; + repairStatus?: string; + repairIdea?: string; + labelInfo?: string; + markInfo?: { + bbox?: number[]; + clsId?: number; + confidence?: number; + label?: string; + [key: string]: any; + }; + [key: string]: any; +} + +// 缺陷等级类型 +export interface DefectLevelType { + code: string; + name: string; + value: string; + sort: number; + description?: string; +} + +// 缺陷类型 +export interface DefectType { + code: string; + name: string; + value: string; + sort: number; + description?: string; +} + +// 获取缺陷等级列表 +export const getDefectLevels = () => { + return http.get<{ + code: number; + data: DefectLevelType[]; + msg: string; + status: number; + success: boolean; + }>('/common/list/defect-level') +} + +// 获取缺陷类型列表 +export const getDefectTypes = () => { + return http.get<{ + code: number; + data: DefectType[]; + msg: string; + status: number; + success: boolean; + }>('/common/list/defect-type') +} \ No newline at end of file diff --git a/src/apis/industrial-image/index.ts b/src/apis/industrial-image/index.ts new file mode 100644 index 0000000..a657163 --- /dev/null +++ b/src/apis/industrial-image/index.ts @@ -0,0 +1,341 @@ +import type * as T from './type' +import http from '@/utils/http' + +export type * from './type' +export * from './defect' + +/** @desc 获取项目列表(分页) */ +export const getProjectList = (params: T.ProjectQuery) => { + return http.get>('/project/list', params) +} + +/** @desc 获取项目详情 */ +export const getProjectDetail = (projectId: string) => { + return http.get(`/project/detail/${projectId}`) +} + +/** @desc 获取机组列表 */ +export const getTurbineList = (params?: T.TurbineQuery) => { + return http.get('/turbine/list', params) +} + +/** @desc 获取机组详情 */ +export const getTurbineDetail = (turbineId: string) => { + return http.get(`/turbine/info/${turbineId}`) +} + +/** @desc 获取部件列表 */ +export const getPartList = (params?: T.PartQuery) => { + return http.get('/part/list', params) +} + +/** @desc 获取部件详情 */ +export const getPartDetail = (partId: string) => { + return http.get(`/part/detail/${partId}`) +} + +/** @desc 获取项目树 */ +export const getProjectTree = () => { + return http.get(`/industrial-image/project-tree`) +} + +/** @desc 获取图像列表 */ +export const getImageList = (params?: { + imageTypes?: string[] + keyword?: string + partId?: string + turbineId?: string +}) => { + return http.get<{ + code: number + data: Array<{ + imageId: string + imageName: string + audioList?: any[] + cameraManufacturer?: string + cameraModel?: string + collectorName?: string + focalDistance?: string + gps?: string + humidness?: number + imageResolution?: string + imageType?: string + imageTypeLabel?: string + partId?: string + partName?: string + shootingDistance?: number + shootingMethod?: string + shootingMethodLabel?: string + shootingTime?: string + temperature?: string + weather?: string + weatherLabel?: string + windLevel?: number + filePath?: string + imagePath?: string + }> + msg: string + status: number + success: boolean + }>('/image/list', params) +} + +/** @desc 获取图像详情 */ +export function getImageDetail(imageId: string) { + return http.get(`/industrial-image/image/${imageId}`) +} + +/** @desc 搜索图像 */ +export function searchImages(query: T.ImageQuery) { + return http.get(`/industrial-image/images/search`, query) +} + +/** @desc 查询通用图片来源 */ +export const getImageSources = () => { + return http.get + msg: string + status: number + }>>('/common/list/common-image-source') +} + +/** @desc 上传单张图片 */ +export const uploadSingleImage = (imageSource: string, file: File, params?: { + altitude?: string + latitude?: string + longitude?: string + partId?: string + uploadUser?: string +}) => { + const formData = new FormData() + formData.append('file', file) + + // 构建查询参数 + const queryParams = new URLSearchParams() + if (params?.altitude) queryParams.append('altitude', params.altitude) + if (params?.latitude) queryParams.append('latitude', params.latitude) + if (params?.longitude) queryParams.append('longitude', params.longitude) + if (params?.partId) queryParams.append('partId', params.partId) + if (params?.uploadUser) queryParams.append('uploadUser', params.uploadUser) + + const url = `/common/upload-image/${imageSource}${queryParams.toString() ? '?' + queryParams.toString() : ''}` + + return http.post(url, formData, { + headers: { + 'Content-Type': 'multipart/form-data' + } + }) +} + +/** @desc 批量上传图片 */ +export const batchUploadImages = (imageSource: string, files: File[], params?: { + altitude?: string + latitude?: string + longitude?: string + partId?: string + uploadUser?: string +}) => { + const formData = new FormData() + + // 添加文件 + files.forEach(file => { + formData.append('files', file) + }) + + // 构建查询参数 + const queryParams = new URLSearchParams() + if (params?.altitude) queryParams.append('altitude', params.altitude) + if (params?.latitude) queryParams.append('latitude', params.latitude) + if (params?.longitude) queryParams.append('longitude', params.longitude) + if (params?.partId) queryParams.append('partId', params.partId) + if (params?.uploadUser) queryParams.append('uploadUser', params.uploadUser) + + const url = `/common/batch-upload-image/${imageSource}${queryParams.toString() ? '?' + queryParams.toString() : ''}` + + return http.post(url, formData, { + headers: { + 'Content-Type': 'multipart/form-data' + } + }) +} + +/** @desc 单图自动标注缺陷 */ +export const detectDefects = (params: { + confThreshold: number + defectTypeList: string[] + imageId: string + modelId: string +}) => { + return http.post('/defect/detect', params, { + headers: { + 'Content-Type': 'application/json' + } + }) +} + +/** @desc 图像导入接口(使用新的API规范) */ +export const uploadImageToPartV2 = ( + imageSource: string, + partId: string, + files: File[], + params: Partial +) => { + const formData = new FormData() + + // 添加文件 + files.forEach(file => { + formData.append('files', file) + }) + + // 添加其他参数 + if (params.collectorId) formData.append('collectorId', params.collectorId) + if (params.collectorName) formData.append('collectorName', params.collectorName) + if (params.humidness !== undefined) formData.append('humidness', params.humidness.toString()) + if (params.gps) formData.append('imageList[0].GPS', params.gps) + if (params.xResolution) formData.append('imageList[0].XResolution', params.xResolution) + if (params.yResolution) formData.append('imageList[0].YResolution', params.yResolution) + if (params.altitude) formData.append('imageList[0].altitude', params.altitude) + if (params.cameraManufacturer) formData.append('imageList[0].cameraManufacturer', params.cameraManufacturer) + if (params.cameraModel) formData.append('imageList[0].cameraModel', params.cameraModel) + if (params.focalDistance) formData.append('imageList[0].focalDistance', params.focalDistance) + if (params.focalDistance35) formData.append('imageList[0].focalDistance35', params.focalDistance35) + if (params.imageHeight) formData.append('imageList[0].imageHeight', params.imageHeight) + if (params.imageId) formData.append('imageList[0].imageId', params.imageId) + if (params.imageName) formData.append('imageList[0].imageName', params.imageName) + if (params.imagePath) formData.append('imageList[0].imagePath', params.imagePath) + if (params.imageResolution) formData.append('imageList[0].imageResolution', params.imageResolution) + if (params.imageSize) formData.append('imageList[0].imageSize', params.imageSize) + if (params.imageWidth) formData.append('imageList[0].imageWidth', params.imageWidth) + if (params.latitude) formData.append('imageList[0].latitude', params.latitude) + if (params.longitude) formData.append('imageList[0].longitude', params.longitude) + if (params.resolutionUnits) formData.append('imageList[0].resolutionUnits', params.resolutionUnits) + if (params.shootingTime) formData.append('imageList[0].shootingTime', params.shootingTime) + if (params.shootingDistance !== undefined) formData.append('shootingDistance', params.shootingDistance.toString()) + if (params.shootingMethod) formData.append('shootingMethod', params.shootingMethod) + if (params.shootingTimeBegin) formData.append('shootingTimeBegin', params.shootingTimeBegin) + if (params.shootingTimeEnd) formData.append('shootingTimeEnd', params.shootingTimeEnd) + if (params.temperatureMax !== undefined) formData.append('temperatureMax', params.temperatureMax.toString()) + if (params.temperatureMin !== undefined) formData.append('temperatureMin', params.temperatureMin.toString()) + if (params.weather) formData.append('weather', params.weather) + if (params.windLevel !== undefined) formData.append('windLevel', params.windLevel.toString()) + + return http.post(`/image/${imageSource}/upload/${partId}`, formData, { + headers: { + 'Content-Type': 'multipart/form-data' + } + }) +} + +/** @desc 图像导入接口(更新为使用真实接口) */ +export const importImages = (files: FileList | File[], params: T.ImageImportParams) => { + const fileArray = Array.from(files) + + // 使用批量上传接口 + return batchUploadImages(params.imageSource || 'default', fileArray, { + partId: params.componentId, + uploadUser: params.uploadUser + }).then(response => { + // 如果需要自动标注 + if (params.autoAnnotate && params.annotationTypes && params.annotationTypes.length > 0) { + // 这里可以添加自动标注逻辑 + return response + } + return response + }) +} + +/** @desc 自动标注接口(更新为使用真实接口) */ +export const autoAnnotateImage = (params: T.AutoAnnotationParams) => { + return detectDefects({ + confThreshold: params.confidenceThreshold || 0.5, + defectTypeList: params.annotationTypes, + imageId: params.imageId, + modelId: params.params?.modelId || 'default' + }) +} + +/** @desc 获取图像标注信息 */ +export const getImageAnnotations = (imageId: string) => { + return http.get(`/industrial-image/annotations/${imageId}`) +} + +/** @desc 删除标注 */ +export const deleteAnnotation = (imageId: string, annotationId: string) => { + return http.del(`/industrial-image/annotations/${imageId}/${annotationId}`) +} + +/** @desc 确认标注 */ +export const confirmAnnotation = (imageId: string, annotationId: string) => { + return http.post(`/industrial-image/annotations/${imageId}/${annotationId}/confirm`) +} + +/** @desc 上传图像(保留旧接口兼容性) */ +export const uploadImage = (file: File, params: { projectId: string; componentId?: string }) => { + return uploadSingleImage('default', file, { + partId: params.componentId, + uploadUser: 'current-user' + }) +} + +/** @desc 删除图像 */ +export const deleteImage = (imageId: string) => { + return http.del(`/industrial-image/images/${imageId}`) +} + +/** @desc 批量删除图像 */ +export function batchDeleteImages(imageIds: string[]) { + return http.del(`/industrial-image/images`, { ids: imageIds }) +} + +/** @desc 开始图像处理 */ +export const processImage = (params: T.ImageProcessParams) => { + return http.post(`/industrial-image/process`, params) +} + +/** @desc 获取处理结果 */ +export const getProcessResult = (processId: string) => { + return http.get(`/industrial-image/process/${processId}`) +} + +/** @desc 获取图像的所有处理结果 */ +export function getImageProcessResults(imageId: string) { + return http.get(`/industrial-image/image/${imageId}/results`) +} + +/** @desc 取消图像处理 */ +export function cancelImageProcess(processId: string) { + return http.post(`/industrial-image/process/${processId}/cancel`) +} + +/** @desc 重新处理图像 */ +export function reprocessImage(params: T.ImageProcessParams) { + return http.post(`/industrial-image/process/reprocess`, params) +} + +/** @desc 批量处理 */ +export const batchProcessImages = (imageIds: string[], processType: string) => { + return http.post(`/industrial-image/batch-process`, { + imageIds, + processType + }) +} + +/** @desc 导出处理结果 */ +export function exportProcessResults(query: T.ImageQuery) { + return http.get(`/industrial-image/export/results`, query, { + responseType: 'blob' + }) +} + +/** @desc 生成检测报告 */ +export function generateReport(projectId: string) { + return http.post(`/industrial-image/report/generate`, { projectId }, { + responseType: 'blob' + }) +} + diff --git a/src/apis/industrial-image/type.ts b/src/apis/industrial-image/type.ts new file mode 100644 index 0000000..5d9e24c --- /dev/null +++ b/src/apis/industrial-image/type.ts @@ -0,0 +1,415 @@ +/** 工业图像处理相关类型定义 */ + +/** 项目实体接口定义 */ +export interface ProjectInfo { + projectId: string // 项目id + projectName: string // 项目名称 + scale?: string // 项目规模 + turbineModel?: string // 风机型号 + status?: number // 状态:0待施工,1施工中,2已完工,3已验收,4已验收 + statusLabel?: string // 项目状态文本 + coverUrl?: string // 项目封面 + client?: string // 委托单位 + clientContact?: string // 委托单位联系人 + clientPhone?: string // 委托单位联系电话 + farmName?: string // 风场名称 + farmAddress?: string // 风场地址 + inspectionUnit?: string // 检查单位 + inspectionContact?: string // 检查单位联系人 + inspectionPhone?: string // 检查单位联系电话 + projectManagerId?: string // 项目经理id + projectManagerName?: string // 项目经理名称 + qualityOfficerId?: string // 质量员id + auditorId?: string // 安全员id + constructionPersonnel?: string // 施工人员 + constructionPersonnelId?: string // 施工人员id + constructionTeamLeaderId?: string // 施工组长id + constructorIds?: string // 施工人员id + constructorName?: string // 施工人员名称 + workType?: string // 项目工作类型 可能有多项,逗号分隔 + job?: string // 项目工作内容 可能有多项,json对象保存 + discloseContent?: string // 交底内容 + technicalContent?: string // 技术方案内容 + safetyContent?: string // 安全措施内容 + createBy?: string // 创建者 + createTime?: string // 创建时间 + updateBy?: string // 更新者 + idList?: string[] // id集合 +} + +/** 机组信息接口 */ +export interface TurbineInfo { + turbineId?: string // 机组ID + projectId: string // 项目ID + turbineName: string // 机组名称 + turbineDesc?: string // 机组描述 + turbineManufacturer?: string // 机组厂商 + turbineModel?: string // 机组型号 + power?: string // 功率 + status?: number // 状态 + createTime?: string // 创建时间 + updateTime?: string // 更新时间 + parts?: PartInfo[] // 部件列表 +} + +/** 部件信息接口 */ +export interface PartInfo { + partId: string // 部件ID + partCode?: string // 部件编码 + partDesc?: string // 部件描述 + partManufacturer?: string // 部件厂商 + partModel?: string // 部件型号 + partName: string // 部件名称 + partType: string // 部件类型 + turbineId: string // 机组ID + createTime?: string // 创建时间 + updateTime?: string // 更新时间 +} + +/** 项目查询参数 */ +export interface ProjectQuery { + projectName?: string + status?: number + page?: number + pageSize?: number +} + +/** 机组查询参数 */ +export interface TurbineQuery { + projectId?: string + turbineName?: string + turbineDesc?: string + turbineManufacturer?: string + turbineModel?: string +} + +/** 部件查询参数 */ +export interface PartQuery { + turbineId?: string + partName?: string + partType?: string + partManufacturer?: string + partModel?: string +} + +/** 分页结果接口 */ +export interface PageResult { + list: T[] + total: number + page: number + pageSize: number +} + +/** 项目节点类型 */ +export interface ProjectTreeNode { + id: string + name: string + type: 'project' | 'turbine' | 'part' + parentId?: string + children?: ProjectTreeNode[] + /** 图像数量 */ + imageCount?: number + /** 状态 */ + status?: string | number + /** 创建时间 */ + createTime?: string + /** 是否为叶子节点 */ + isLeaf?: boolean + /** 是否已加载子节点 */ + loaded?: boolean + /** 是否展开 */ + expanded?: boolean + /** 原始数据 */ + rawData?: ProjectInfo | TurbineInfo | PartInfo +} + +/** 缺陷标注信息 */ +export interface DefectAnnotation { + id: string + /** 缺陷类型 */ + type: string + /** 缺陷名称 */ + name: string + /** 置信度 */ + confidence: number + /** 边界框 [x, y, width, height] */ + bbox: [number, number, number, number] + /** 缺陷描述 */ + description?: string + /** 标注方式 */ + annotationType: 'auto' | 'manual' + /** 标注人员 */ + annotator?: string + /** 标注时间 */ + annotationTime?: string + /** 是否已确认 */ + confirmed?: boolean +} + +/** 工业图像信息 */ +export interface IndustrialImage { + id: string + /** 图像名称 */ + name: string + /** 图像路径 */ + path: string + /** 图像路径(API返回字段)*/ + imagePath?: string + /** 缩略图路径 */ + thumbnailPath?: string + /** 图像类型 */ + type: string + /** 文件大小 */ + size: number + /** 图像宽度 */ + width?: number + /** 图像高度 */ + height?: number + /** 所属项目ID */ + projectId: string + /** 所属组件ID */ + componentId?: string + /** 拍摄时间 */ + captureTime?: string + /** 处理状态 */ + processStatus?: 'pending' | 'processing' | 'completed' | 'failed' + /** 缺陷数量 */ + defectCount?: number + /** 缺陷标注列表 */ + annotations?: DefectAnnotation[] + /** 是否已标注 */ + isAnnotated?: boolean + /** 标注状态 */ + annotationStatus?: 'none' | 'auto' | 'manual' | 'verified' + /** 创建时间 */ + createTime?: string + /** 更新时间 */ + updateTime?: string + + // 扩展字段 - 来自真实API + /** 部件名称 */ + partName?: string + /** 相机制造商 */ + cameraManufacturer?: string + /** 相机型号 */ + cameraModel?: string + /** 采集员姓名 */ + collectorName?: string + /** 焦距 */ + focalDistance?: string + /** GPS坐标 */ + gps?: string + /** 湿度 */ + humidness?: number + /** 拍摄距离 */ + shootingDistance?: number + /** 拍摄方式 */ + shootingMethod?: string + /** 拍摄方式标签 */ + shootingMethodLabel?: string + /** 温度 */ + temperature?: string + /** 天气 */ + weather?: string + /** 天气标签 */ + weatherLabel?: string + /** 风力等级 */ + windLevel?: number +} + +/** 图像查询参数 */ +export interface ImageQuery { + /** 项目ID */ + projectId?: string + /** 组件ID */ + componentId?: string + /** 图像名称搜索 */ + keyword?: string + /** 图像类型 */ + type?: string + /** 处理状态 */ + processStatus?: string + /** 标注状态 */ + annotationStatus?: string + /** 页码 */ + page?: number + /** 每页数量 */ + size?: number +} + +/** 图像导入参数 */ +export interface ImageImportParams { + /** 项目ID */ + projectId: string + /** 组件ID */ + componentId?: string + /** 图像来源 */ + imageSource?: string + /** 上传用户 */ + uploadUser?: string + /** 海拔 */ + altitude?: string + /** 纬度 */ + latitude?: string + /** 经度 */ + longitude?: string + /** 部件ID */ + partId?: string + /** 是否自动标注 */ + autoAnnotate?: boolean + /** 标注类型 */ + annotationTypes?: string[] +} + +/** 图像上传参数(基于新API) */ +export interface ImageUploadParams { + /** 图像源 */ + imageSource: string + /** 部件ID */ + partId: string + /** 采集员ID */ + collectorId?: string + /** 采集员姓名 */ + collectorName?: string + /** 湿度(百分比) */ + humidness?: number + /** GPS坐标 */ + gps?: string + /** X分辨率 */ + xResolution?: string + /** Y分辨率 */ + yResolution?: string + /** 海拔 */ + altitude?: string + /** 相机制造商 */ + cameraManufacturer?: string + /** 相机型号 */ + cameraModel?: string + /** 焦距 */ + focalDistance?: string + /** 35毫米焦距 */ + focalDistance35?: string + /** 图像高度 */ + imageHeight?: string + /** 图像ID */ + imageId?: string + /** 图像名称 */ + imageName?: string + /** 图像路径 */ + imagePath?: string + /** 图像分辨率 */ + imageResolution?: string + /** 图像大小 */ + imageSize?: string + /** 图像宽度 */ + imageWidth?: string + /** 纬度 */ + latitude?: string + /** 经度 */ + longitude?: string + /** 焦平面分辨率单位 */ + resolutionUnits?: string + /** 拍摄时间 */ + shootingTime?: string + /** 拍摄距离 */ + shootingDistance?: number + /** 拍摄方式 */ + shootingMethod?: string + /** 拍摄时间开始 */ + shootingTimeBegin?: string + /** 拍摄时间结束 */ + shootingTimeEnd?: string + /** 温度最高 */ + temperatureMax?: number + /** 温度最低 */ + temperatureMin?: number + /** 天气 */ + weather?: string + /** 风力等级 */ + windLevel?: number +} + +/** 自动标注参数 */ +export interface AutoAnnotationParams { + /** 图像ID */ + imageId: string + /** 标注类型 */ + annotationTypes: string[] + /** 置信度阈值 */ + confidenceThreshold?: number + /** 其他参数 */ + params?: Record +} + +/** 手动标注参数 */ +export interface ManualAnnotationParams { + /** 图像ID */ + imageId: string + /** 标注列表 */ + annotations: Omit[] +} + +/** 标注结果 */ +export interface AnnotationResult { + /** 图像ID */ + imageId: string + /** 标注列表 */ + annotations: DefectAnnotation[] + /** 标注数量 */ + annotationCount: number + /** 处理时间 */ + processTime?: number + /** 标注状态 */ + status: 'success' | 'failed' + /** 错误信息 */ + error?: string +} + +/** 图像处理参数 */ +export interface ImageProcessParams { + /** 图像ID */ + imageId: string + /** 处理类型 */ + processType: 'defect_detection' | 'quality_analysis' | 'measurement' + /** 处理参数 */ + params?: Record +} + +/** 图像处理结果 */ +export interface ImageProcessResult { + /** 处理ID */ + processId: string + /** 图像ID */ + imageId: string + /** 处理类型 */ + processType: string + /** 处理状态 */ + status: 'pending' | 'processing' | 'completed' | 'failed' + /** 处理结果 */ + result?: { + /** 检测到的缺陷 */ + defects?: Array<{ + id: string + type: string + confidence: number + bbox: [number, number, number, number] + description?: string + }> + /** 质量分析结果 */ + qualityScore?: number + /** 测量结果 */ + measurements?: Array<{ + type: string + value: number + unit: string + }> + } + /** 处理耗时(毫秒) */ + processTime?: number + /** 错误信息 */ + error?: string + /** 创建时间 */ + createTime?: string + /** 完成时间 */ + completeTime?: string +} \ No newline at end of file diff --git a/src/apis/insurance-company/index.ts b/src/apis/insurance-company/index.ts new file mode 100644 index 0000000..2c74583 --- /dev/null +++ b/src/apis/insurance-company/index.ts @@ -0,0 +1,91 @@ +import http from '@/utils/http' + +const { request } = http + +export interface InsuranceCompany { + id?: string + contact: string + contactPhone: string + insuranceCompanyName: string + status: string + email?: string + address?: string + startDate?: string +} + +export interface InsuranceCompanyListParams { + contact?: string + contactPhone?: string + insuranceCompanyName?: string + status?: string + current?: number + size?: number +} + +export interface InsuranceCompanyListResponse { + records: InsuranceCompany[] + total: number + current: number + size: number +} + +// 新增保险公司信息 +export function createInsuranceCompany(data: InsuranceCompany) { + return request({ + url: '/insurance-company', + method: 'post', + data + }) +} + +// 查询保险公司信息列表 +export function getInsuranceCompanyList(params: InsuranceCompanyListParams) { + return request({ + url: '/insurance-company/list', + method: 'get', + params + }) +} + +// 查询保险公司详情 +export function getInsuranceCompanyDetail(id: string) { + return request({ + url: `/insurance-company/detail/${id}`, + method: 'get' + }) +} + +// 编辑保险公司信息 +export function updateInsuranceCompany(id: string, data: InsuranceCompany) { + return request({ + url: `/insurance-company/${id}`, + method: 'put', + data + }) +} + +// 删除保险公司 +export function deleteInsuranceCompany(id: string) { + return request({ + url: `/insurance-company/${id}`, + method: 'delete' + }) +} + +// 终止合作 +export function terminateCooperation(id: string) { + return request({ + url: `/insurance-company/terminate/${id}`, + method: 'post' + }) +} + +// 恢复合作 +export function resumeCooperation(id: string) { + return request({ + url: `/insurance-company/resume/${id}`, + method: 'post' + }) +} + +// 获取所有有效保险公司(用于下拉选择) diff --git a/src/apis/insurance-file/index.ts b/src/apis/insurance-file/index.ts new file mode 100644 index 0000000..b63c751 --- /dev/null +++ b/src/apis/insurance-file/index.ts @@ -0,0 +1,168 @@ +import http from '@/utils/http' + +const { request } = http + +export interface InsuranceFile { + id?: string + employeeName: string + employeeId: string + fileName: string + fileType: string + fileSize?: number + filePath?: string + uploadDate?: string + description?: string + remarks?: string +} + +export interface InsuranceFileListParams { + employeeName?: string + employeeId?: string + fileType?: string + uploadDateStart?: string + uploadDateEnd?: string + current?: number + size?: number +} + +export interface InsuranceFileListResponse { + records: InsuranceFile[] + total: number + current: number + size: number +} + +export interface UploadInsuranceFileParams { + employeeId: string + fileType: string + description?: string + file: File +} + +// 上传保单文件 +export function uploadInsuranceFile(data: UploadInsuranceFileParams) { + const formData = new FormData() + formData.append('file', data.file) + formData.append('employeeId', data.employeeId) + formData.append('fileType', data.fileType) + if (data.description) { + formData.append('description', data.description) + } + + return request({ + url: '/insurance-file/upload', + method: 'post', + data: formData, + headers: { + 'Content-Type': 'multipart/form-data' + } + }) +} + +// 查询保单文件列表 +export function getInsuranceFileList(params: InsuranceFileListParams) { + return request({ + url: '/insurance-file/list', + method: 'get', + params + }) +} + +// 查询文件详情 +export function getInsuranceFileDetail(id: string) { + return request({ + url: `/insurance-file/detail/${id}`, + method: 'get' + }) +} + +// 更新文件信息 +export function updateInsuranceFile(id: string, data: Partial) { + return request({ + url: `/insurance-file/${id}`, + method: 'put', + data + }) +} + +// 删除文件 +export function deleteInsuranceFile(id: string) { + return request({ + url: `/insurance-file/${id}`, + method: 'delete' + }) +} + +// 批量删除文件 +export function batchDeleteInsuranceFiles(ids: string[]) { + return request({ + url: '/insurance-file/batch', + method: 'delete', + data: { ids } + }) +} + +// 下载文件 +export function downloadInsuranceFile(id: string) { + return request({ + url: `/insurance-file/download/${id}`, + method: 'get', + responseType: 'blob' + }) +} + +// 预览文件 +export function previewInsuranceFile(id: string) { + return request({ + url: `/insurance-file/preview/${id}`, + method: 'get', + responseType: 'blob' + }) +} + +// 获取员工所有文件 +export function getEmployeeFiles(employeeId: string) { + return request({ + url: `/insurance-file/employee/${employeeId}`, + method: 'get' + }) +} + +// 按文件类型统计 +export function getInsuranceFileStatistics() { + return request<{ + fileType: string + count: number + totalSize: number + }[]>({ + url: '/insurance-file/statistics', + method: 'get' + }) +} + +// 批量上传文件 +export function batchUploadFiles(data: { + files: File[] + employeeId: string + fileType: string + description?: string +}) { + const formData = new FormData() + data.files.forEach((file, index) => { + formData.append(`files[${index}]`, file) + }) + formData.append('employeeId', data.employeeId) + formData.append('fileType', data.fileType) + if (data.description) { + formData.append('description', data.description) + } + + return request({ + url: '/insurance-file/batch-upload', + method: 'post', + data: formData, + headers: { + 'Content-Type': 'multipart/form-data' + } + }) +} \ No newline at end of file diff --git a/src/apis/insurance-type/index.ts b/src/apis/insurance-type/index.ts new file mode 100644 index 0000000..6e3b6c1 --- /dev/null +++ b/src/apis/insurance-type/index.ts @@ -0,0 +1,76 @@ +import http from '@/utils/http' + +const { request } = http + +export interface InsuranceType { + id?: string + description: string + insuranceTypeName: string + coverage?: string +} + +export interface InsuranceTypeListParams { + insuranceTypeName?: string + description?: string + current?: number + size?: number +} + +export interface InsuranceTypeListResponse { + records: InsuranceType[] + total: number + current: number + size: number +} + +// 新增保险类型 +export function createInsuranceType(data: InsuranceType) { + return request({ + url: '/insurance-type', + method: 'post', + data + }) +} + +// 查询保险类型列表 +export function getInsuranceTypeList(params?: InsuranceTypeListParams) { + return request({ + url: '/insurance-type/list', + method: 'get', + params + }) +} + +// 查询保险类型详情 +export function getInsuranceTypeDetail(insuranceTypeId: string) { + return request({ + url: `/insurance-type/detail/${insuranceTypeId}`, + method: 'get' + }) +} + +// 编辑保险类型 +export function updateInsuranceType(id: string, data: InsuranceType) { + return request({ + url: `/insurance-type/${id}`, + method: 'put', + data + }) +} + +// 删除保险类型 +export function deleteInsuranceType(id: string) { + return request({ + url: `/insurance-type/${id}`, + method: 'delete' + }) +} + +// 批量删除保险类型 +export function batchDeleteInsuranceType(ids: string[]) { + return request({ + url: '/insurance-type/batch', + method: 'delete', + data: { ids } + }) +} diff --git a/src/apis/insurance/index.ts b/src/apis/insurance/index.ts new file mode 100644 index 0000000..9144f0f --- /dev/null +++ b/src/apis/insurance/index.ts @@ -0,0 +1,78 @@ +import http from '@/utils/http' +import type { InsuranceInfo, InsuranceListParams, InsuranceListResponse, RenewInsuranceParams } from './type' + +const { request } = http + +// 导出类型定义 +export type { InsuranceInfo, InsuranceListParams, InsuranceListResponse, RenewInsuranceParams } + +// 新增保险信息 +export function createInsurance(data: InsuranceInfo) { + return request({ + url: '/insurance-info', + method: 'post', + data + }) +} + +// 查询保险信息列表 +export function getInsuranceList(params: InsuranceListParams) { + return request({ + url: '/insurance-info/list', + method: 'get', + params + }) +} + +// 查询保险信息详情 +export function getInsuranceDetail(id: string) { + return request({ + url: `/insurance-info/detail/${id}`, + method: 'get' + }) +} + +// 编辑保险信息 +export function updateInsurance(id: string, data: InsuranceInfo) { + return request({ + url: `/insurance-info/${id}`, + method: 'put', + data + }) +} + +// 删除保险信息 +export function deleteInsurance(id: string) { + return request({ + url: `/insurance-info/${id}`, + method: 'delete' + }) +} + +// 续保 +export function renewInsurance(id: string, data: RenewInsuranceParams) { + return request({ + url: `/insurance-info/renew/${id}`, + method: 'post', + data + }) +} + +// 批量删除保险信息 +export function batchDeleteInsurance(ids: string[]) { + return request({ + url: '/insurance-info/batch', + method: 'delete', + data: { ids } + }) +} + +// 导出保险信息 +export function exportInsurance(params: InsuranceListParams) { + return request({ + url: '/insurance-info/export', + method: 'get', + params, + responseType: 'blob' + }) +} \ No newline at end of file diff --git a/src/apis/insurance/type.ts b/src/apis/insurance/type.ts new file mode 100644 index 0000000..57d0d31 --- /dev/null +++ b/src/apis/insurance/type.ts @@ -0,0 +1,41 @@ +/** 保险信息接口 */ +export interface InsuranceInfo { + id?: string + attachInfoId:string + insuranceCompanyId: string + insuranceTypeId: string + userId: string + insuranceBillCode: string + effectiveDate: string + expireDate: string + insuranceAmount: number + insurancePremium: number + beneficiary: string + remark?: string + status?: string + createTime?: string + updateTime?: string +} + +/** 保险信息列表查询参数 */ +export interface InsuranceListParams { + insuranceCompanyId?: string + insuranceTypeId?: string + userId?: string + current?: number + size?: number +} + +/** 保险信息列表响应 */ +export interface InsuranceListResponse { + records: InsuranceInfo[] + total: number + current: number + size: number +} + +/** 续保参数 */ +export interface RenewInsuranceParams { + expireDate: string + insurancePremium: number +} \ No newline at end of file diff --git a/src/apis/model-config/index.ts b/src/apis/model-config/index.ts new file mode 100644 index 0000000..64399e6 --- /dev/null +++ b/src/apis/model-config/index.ts @@ -0,0 +1,71 @@ +import http from '@/utils/http' +import type { ModelConfigRequest, ModelConfigResponse, ModelConfigListResponse, ModelConfigDetailResponse } from './type' + +const { request } = http + +/** + * 创建模型配置 + * @param data 模型配置数据 + */ +export function createModelConfig(data: ModelConfigRequest) { + return request({ + url: '/model-config', + method: 'post', + data + }) +} + +/** + * 更新模型配置 + * @param data 模型配置数据 + */ +export function updateModelConfig(data: ModelConfigRequest) { + return request({ + url: '/model-config', + method: 'put', + data + }) +} + +/** + * 获取模型配置列表 + * @param params 查询参数 + */ +export function getModelConfigList(params?: { + confThreshold?: number + keyword?: string + modelId?: string + modelName?: string + modelPath?: string + nmsThreshold?: number + page?: number + pageSize?: number +}) { + return request({ + url: '/model-config/list', + method: 'get', + params + }) +} + +/** + * 获取模型配置详情 + * @param modelId 模型ID + */ +export function getModelConfigDetail(modelId: string) { + return request({ + url: `/model-config/${modelId}`, + method: 'get' + }) +} + +/** + * 删除模型配置 + * @param modelId 模型ID + */ +export function deleteModelConfig(modelId: string) { + return request({ + url: `/model-config/${modelId}`, + method: 'delete' + }) +} \ No newline at end of file diff --git a/src/apis/model-config/type.ts b/src/apis/model-config/type.ts new file mode 100644 index 0000000..ce57bf4 --- /dev/null +++ b/src/apis/model-config/type.ts @@ -0,0 +1,52 @@ +/** + * 模型配置请求对象 + */ +export interface ModelConfigRequest { + attachId: string + confThreshold: number + modelId: string + modelName: string + nmsThreshold: number +} + +/** + * 模型配置响应对象 + */ +export interface ModelConfigResponse { + attachId: string + confThreshold: number + modelId: string + modelName: string + nmsThreshold: number + modelPath?: string +} + +/** + * 模型配置列表响应 + */ +export interface ModelConfigListResponse { + code: number + data: { + confThreshold?: number + idList?: string[] + modelId: string + modelName: string + modelPath: string + nmsThreshold?: number + page: number + pageSize: number + msg: string + status: number + success: boolean + } +} + +/** + * 模型配置详情响应 + */ +export interface ModelConfigDetailResponse { + code: number + data: ModelConfigResponse + msg: string + status: number +} \ No newline at end of file diff --git a/src/components/Chart/index.vue b/src/components/Chart/index.vue index b7a9656..80ef9c7 100644 --- a/src/components/Chart/index.vue +++ b/src/components/Chart/index.vue @@ -3,7 +3,7 @@ diff --git a/src/components/ImageImport/index.vue b/src/components/ImageImport/index.vue new file mode 100644 index 0000000..97119ee --- /dev/null +++ b/src/components/ImageImport/index.vue @@ -0,0 +1,692 @@ + + + + + \ No newline at end of file diff --git a/src/components/ImageImportWizard/index.vue b/src/components/ImageImportWizard/index.vue new file mode 100644 index 0000000..dc93715 --- /dev/null +++ b/src/components/ImageImportWizard/index.vue @@ -0,0 +1,1130 @@ + + + + + \ No newline at end of file diff --git a/src/components/IndustrialImageList/index.ts b/src/components/IndustrialImageList/index.ts new file mode 100644 index 0000000..dc538a8 --- /dev/null +++ b/src/components/IndustrialImageList/index.ts @@ -0,0 +1,4 @@ +import IndustrialImageList from './index.vue' + +export type { IndustrialImage } from './index.vue' +export default IndustrialImageList \ No newline at end of file diff --git a/src/components/IndustrialImageList/index.vue b/src/components/IndustrialImageList/index.vue new file mode 100644 index 0000000..fddb4c6 --- /dev/null +++ b/src/components/IndustrialImageList/index.vue @@ -0,0 +1,529 @@ + + + + + \ No newline at end of file diff --git a/src/config/setting.ts b/src/config/setting.ts index dde1cf2..eed7aed 100644 --- a/src/config/setting.ts +++ b/src/config/setting.ts @@ -9,7 +9,7 @@ export const defaultSettings: App.AppSettings = { menuAccordion: true, menuDark: false, copyrightDisplay: true, - layout: 'mix', + layout: 'left', enableColorWeaknessMode: false, enableMourningMode: false, } diff --git a/src/layout/LayoutDefault.vue b/src/layout/LayoutDefault.vue index 6718c3b..9a34aa6 100644 --- a/src/layout/LayoutDefault.vue +++ b/src/layout/LayoutDefault.vue @@ -5,7 +5,7 @@
- + diff --git a/src/layout/LayoutMix.vue b/src/layout/LayoutMix.vue index b57d6fe..e68643b 100644 --- a/src/layout/LayoutMix.vue +++ b/src/layout/LayoutMix.vue @@ -5,7 +5,7 @@ :style="appStore.menuDark ? appStore.themeCSSVar : undefined" > - + @@ -86,7 +86,7 @@ const checkAndShowNotices = () => { } const getMenuIcon = (item: RouteRecordRaw) => { - return item.meta?.icon || item.children?.[0].meta?.icon + return item.meta?.icon || item.children?.[0].meta?.icon || '' } // 克隆是菜单的路由 @@ -177,7 +177,7 @@ onMounted(() => { background-color: var(--color-bg-1); display: flex; flex-direction: column; - overflow: hidden; + overflow-x: scroll; } &-right { diff --git a/src/layout/components/Asider/index.vue b/src/layout/components/Asider/index.vue index 6e0fbb7..fe39bd7 100644 --- a/src/layout/components/Asider/index.vue +++ b/src/layout/components/Asider/index.vue @@ -4,14 +4,14 @@ :style="appStore.menuDark ? appStore.themeCSSVar : undefined" > - + - + @@ -68,13 +68,22 @@ const handleCollapse = (isCollapsed: boolean) => { .menu-scroll-view { flex: 1; - overflow: hidden; + overflow: auto; } .menu { flex: 1; - overflow: hidden; + overflow: auto; background-color: inherit; } } + +:deep(.arco-scrollbar) { + overflow-x: hidden; + overflow-y: auto; +} + +:deep(.arco-scrollbar-container) { + overflow-x: hidden !important; +} diff --git a/src/layout/components/Logo.vue b/src/layout/components/Logo.vue index 4138179..ad0db9e 100644 --- a/src/layout/components/Logo.vue +++ b/src/layout/components/Logo.vue @@ -13,7 +13,8 @@ const props = withDefaults(defineProps(), { collapsed: false, }) const appStore = useAppStore() -const title = computed(() => appStore.getTitle()) +// const title = computed(() => appStore.getTitle()) +const title = "武汉迪特聚能有限公司管理平台" const logo = computed(() => appStore.getLogo()) interface Props { @@ -31,9 +32,10 @@ const toHome = () => { height: 56px; padding: 0 12px; color: var(--color-text-1); - font-size: 20px; + font-size: 16px; line-height: 1; display: flex; + font-weight: 600; align-items: center; flex-shrink: 0; cursor: pointer; diff --git a/src/layout/components/Menu/MenuItem.vue b/src/layout/components/Menu/MenuItem.vue index 22f94bf..c342fe4 100644 --- a/src/layout/components/Menu/MenuItem.vue +++ b/src/layout/components/Menu/MenuItem.vue @@ -15,7 +15,9 @@ :icon="onlyOneChild?.meta?.icon || item?.meta?.icon" /> - {{ onlyOneChild?.meta?.title }} + + {{ onlyOneChild?.meta?.title }} + @@ -72,3 +74,20 @@ watchEffect(() => { } }) + + diff --git a/src/layout/components/Menu/index.vue b/src/layout/components/Menu/index.vue index ea85dcb..85c7cbc 100644 --- a/src/layout/components/Menu/index.vue +++ b/src/layout/components/Menu/index.vue @@ -89,4 +89,29 @@ const onCollapse = (collapsed: boolean) => { } - + diff --git a/src/router/route.ts b/src/router/route.ts index dde18ec..3fbba31 100644 --- a/src/router/route.ts +++ b/src/router/route.ts @@ -11,27 +11,27 @@ export const systemRoutes: RouteRecordRaw[] = [ component: () => import('@/views/login/index.vue'), meta: { hidden: true }, }, - { - path: '/company', - name: 'Company', - component: Layout, - redirect: '/company/overview', - meta: { title: '企业概览', icon: 'company', hidden: false, sort: 1 }, - children: [ - { - path: '/company/overview', - name: 'CompanyOverview', - component: () => import('@/views/company/overview/index.vue'), - meta: { title: '企业概览', icon: 'overview', hidden: false }, - } - ], - }, + // { + // path: '/company', + // name: 'Company', + // component: Layout, + // redirect: '/company/overview', + // meta: { title: '企业概览', icon: 'company', hidden: false, sort: 1 }, + // children: [ + // { + // path: '/company/overview', + // name: 'CompanyOverview', + // component: () => import('@/views/company/overview/index.vue'), + // meta: { title: '企业概览', icon: 'dashboard', hidden: false }, + // } + // ], + // }, { path: '/organization', name: 'Organization', component: Layout, redirect: '/organization/hr/member', - meta: { title: '组织架构', icon: 'organization', hidden: false, sort: 2 }, + meta: { title: '组织架构', icon: 'user-group', hidden: false, sort: 2 }, children: [ { path: '/organization/hr', @@ -73,14 +73,113 @@ export const systemRoutes: RouteRecordRaw[] = [ { path: '/organization/hr/salary', name: 'HRSalary', - component: () => import('@/views/hr/salary/index.vue'), + component: () => import('@/components/ParentView/index.vue'), + redirect: '/organization/hr/salary/overview', meta: { title: '工资', icon: 'salary', hidden: false }, + children: [ + { + path: '/organization/hr/salary/overview', + name: 'HRSalaryOverview', + component: () => import('@/views/hr/salary/index.vue'), + meta: { title: '工资概览', icon: 'salary', hidden: false }, + }, + ] + }, + // { + // path: '/organization/hr/salary/insurance', + // name: 'HRInsurance', + // component: () => import('@/components/ParentView/index.vue'), + // redirect: '/organization/hr/salary/insurance/overview', + // meta: { title: '保险', icon: 'safety', hidden: false }, + // children: [ + // { + // path: '/organization/hr/salary/insurance/overview', + // name: 'HRInsuranceOverview', + // component: () => import('@/views/hr/salary/insurance/overview/index.vue'), + // meta: { title: '工作台概览', icon: 'dashboard', hidden: false }, + // }, + // { + // path: '/organization/hr/salary/insurance/my-insurance', + // name: 'HRMyInsurance', + // component: () => import('@/views/hr/salary/insurance/my-insurance/index.vue'), + // meta: { title: '我的保险', icon: 'shield', hidden: false }, + // }, + // { + // path: '/organization/hr/salary/insurance/health-records', + // name: 'HRHealthRecords', + // component: () => import('@/views/hr/salary/insurance/health-records/index.vue'), + // meta: { title: '健康档案', icon: 'heart', hidden: false }, + // }, + // { + // path: '/organization/hr/salary/insurance/policy-files', + // name: 'HRPolicyFiles', + // component: () => import('@/views/hr/salary/insurance/policy-files/index.vue'), + // meta: { title: '保单文件', icon: 'file', hidden: false }, + // }, + // { + // path: '/organization/hr/salary/insurance/personal-info', + // name: 'HRPersonalInfo', + // component: () => import('@/views/hr/salary/insurance/personal-info/index.vue'), + // meta: { title: '个人信息', icon: 'user', hidden: false }, + // } + // ] + // }, + { + path: '/organization/hr/salary/system-insurance', + name: 'HRSystemInsurance', + component: () => import('@/components/ParentView/index.vue'), + redirect: '/organization/hr/salary/system-insurance/overview', + meta: { title: '人员保险', icon: 'settings', hidden: false }, + children: [ + { + path: '/organization/hr/salary/system-insurance/overview', + name: 'HRSystemInsuranceOverview', + component: () => import('@/views/hr/salary/system-insurance/overview/index.vue'), + meta: { title: '工作台概览', icon: 'dashboard', hidden: false }, + }, + { + path: '/organization/hr/salary/system-insurance/management', + name: 'HRSystemInsuranceManagement', + component: () => import('@/views/hr/salary/system-insurance/management/index.vue'), + meta: { title: '保险管理', icon: 'shield', hidden: false }, + }, + { + path: '/organization/hr/salary/system-insurance/health-management', + name: 'HRSystemHealthManagement', + component: () => import('@/views/hr/salary/system-insurance/health-management/index.vue'), + meta: { title: '健康档案管理', icon: 'heart', hidden: false }, + }, + { + path: '/organization/hr/salary/system-insurance/file-management', + name: 'HRSystemFileManagement', + component: () => import('@/views/hr/salary/system-insurance/file-management/index.vue'), + meta: { title: '保单文件管理', icon: 'file', hidden: false }, + }, + { + path: '/organization/hr/salary/system-insurance/company-management', + name: 'HRSystemCompanyManagement', + component: () => import('@/views/hr/salary/system-insurance/company-management/index.vue'), + meta: { title: '保险公司管理', icon: 'building', hidden: false }, + }, + { + path: '/organization/hr/salary/system-insurance/type-management', + name: 'HRSystemTypeManagement', + component: () => import('@/views/hr/salary/system-insurance/type-management/index.vue'), + meta: { title: '保险类型管理', icon: 'category', hidden: false }, + } + ] + }, + { + path: '/organization/hr/salary/certification', + name: 'HRCertification', + component: () => import('@/views/hr/salary/certification/index.vue'), + meta: { title: '人员资质管理', icon: 'idcard', hidden: false }, }, { path: '/organization/hr/contribution', name: 'HRContribution', component: () => import('@/views/hr/contribution/index.vue'), - meta: { title: '责献积分制度、与企业共同发展', icon: 'contribution', hidden: false }, + meta: { title: '责献积分制度', icon: 'contribution', hidden: false }, } ] }, @@ -89,12 +188,21 @@ export const systemRoutes: RouteRecordRaw[] = [ name: 'OrganizationRole', component: () => import('@/views/system/role/index.vue'), meta: { title: '角色管理', icon: 'role', hidden: false }, - }, + } + ], + }, + { + path: '/asset-management', + name: 'AssetManagement', + component: Layout, + redirect: '/asset-management/device/inventory', + meta: { title: '资产管理', icon: 'property-safety', hidden: false, sort: 3 }, + children: [ { - path: '/organization/log', - name: 'OrganizationLog', - component: () => import('@/views/monitor/log/index.vue'), - meta: { title: '操作日志', icon: 'log', hidden: false }, + path: '/asset-management/intellectual-property', + name: 'IntellectualProperty', + component: () => import('@/views/system-resource/information-system/software-management/index.vue'), + meta: { title: '其他资产', icon: 'copyright', hidden: false }, } ], }, @@ -103,7 +211,7 @@ export const systemRoutes: RouteRecordRaw[] = [ name: 'ProductsServices', component: Layout, redirect: '/products-services/products/hardware/tower-monitoring', - meta: { title: '产品与服务', icon: 'products', hidden: false, sort: 3 }, + meta: { title: '产品与服务', icon: 'heart', hidden: false, sort: 4 }, children: [ { path: '/products-services/products', @@ -156,7 +264,7 @@ export const systemRoutes: RouteRecordRaw[] = [ path: '/products-services/products/software/field-assistant', name: 'FieldAssistant', component: () => import('@/views/service/lightning-detection/index.vue'), - meta: { title: '风电外业智能助手(外业数据实时处理)', icon: 'assistant', hidden: false }, + meta: { title: '风电外业智能助手', icon: 'assistant', hidden: false }, }, { path: '/products-services/products/software/blade-report', @@ -179,7 +287,7 @@ export const systemRoutes: RouteRecordRaw[] = [ name: 'Services', component: () => import('@/components/ParentView/index.vue'), redirect: '/products-services/services/lightning-detection', - meta: { title: '服务', icon: 'service', hidden: false }, + meta: { title: '服务', icon: 'customer-service', hidden: false }, children: [ { path: '/products-services/services/lightning-detection', @@ -243,52 +351,71 @@ export const systemRoutes: RouteRecordRaw[] = [ path: '/project-management', name: 'ProjectManagement', component: Layout, - redirect: '/project-management/bidding/tender-documents', - meta: { title: '项目管理', icon: 'project', hidden: false, sort: 4 }, + redirect: '/project-management/project-template/tender-documents', + meta: { title: '项目管理', icon: 'apps', hidden: false, sort: 4 }, children: [ { - path: '/project-management/bidding', - name: 'ProjectBidding', + path: '/project-management/project-template', + name: 'ProjectTemplate', + component: () => import('@/components/ParentView/index.vue'), + redirect: '/project-management/project-template/tender-documents', meta: { - title: '项目投标', - icon: 'gavel' + title: '施工立项', + icon: 'file-protect', + hidden: false }, children: [ { - path: '/project-management/bidding/tender-documents', + path: '/project-management/project-template/tender-documents', name: 'TenderDocuments', component: () => import('@/views/project-management/bidding/tender-documents/index.vue'), meta: { - title: '招标文件管理', - icon: 'file-text' + title: '招标文件', + icon: 'file-text', + hidden: false } }, { - path: '/project-management/bidding/bid-documents', + path: '/project-management/project-template/bid-documents', name: 'BidDocuments', component: () => import('@/views/project-management/bidding/bid-documents/index.vue'), meta: { - title: '投标文件管理', - icon: 'file-text' + title: '投标文件', + icon: 'file-text', + hidden: false } }, { - path: '/project-management/bidding/award-notice', + path: '/project-management/project-template/award-notice', name: 'AwardNotice', component: () => import('@/views/project-management/bidding/award-notice/index.vue'), meta: { - title: '中标通知书管理', - icon: 'trophy' + title: '中标通知书', + icon: 'trophy', + hidden: false } - } + }, + { + path: '/project-management/projects/initiation', + name: 'ProjectInitiation', + component: () => import('@/views/project/index.vue'), + meta: { + title: '立项管理', + icon: 'plus-circle', + hidden: false + } + }, ] }, { path: '/project-management/contract', name: 'ProjectContract', + component: () => import('@/components/ParentView/index.vue'), + redirect: '/project-management/contract/revenue-contract', meta: { - title: '合同管理', - icon: 'file-text' + title: '市场商务管理', + icon: 'file-text', + hidden: false }, children: [ { @@ -296,8 +423,9 @@ export const systemRoutes: RouteRecordRaw[] = [ name: 'RevenueContract', component: () => import('@/views/project-management/contract/revenue-contract/index.vue'), meta: { - title: '收入合同管理', - icon: 'dollar' + title: '收入合同', + icon: 'dollar', + hidden: false } }, { @@ -305,8 +433,9 @@ export const systemRoutes: RouteRecordRaw[] = [ name: 'ExpenseContract', component: () => import('@/views/project-management/contract/expense-contract/index.vue'), meta: { - title: '支出合同管理', - icon: 'credit-card' + title: '支出合同', + icon: 'credit-card', + hidden: false } }, { @@ -314,8 +443,9 @@ export const systemRoutes: RouteRecordRaw[] = [ name: 'CostManagement', component: () => import('@/views/project-management/contract/cost-management/index.vue'), meta: { - title: '成本管理', - icon: 'bar-chart' + title: '成本费用', + icon: 'bar-chart', + hidden: false } } ] @@ -323,27 +453,73 @@ export const systemRoutes: RouteRecordRaw[] = [ { path: '/project-management/projects', name: 'ProjectsManagement', + component: () => import('@/components/ParentView/index.vue'), + redirect: '/project-management/projects/progress', meta: { - title: '项目管理', - icon: 'briefcase' + title: '组织实施管理', + icon: 'briefcase', + hidden: false }, children: [ + { - path: '/project-management/projects/initiation', - name: 'ProjectInitiation', - component: () => import('@/views/project-management/projects/initiation/index.vue'), + path: '/project-management/projects/progress', + name: 'ProjectProgress', + component: () => import('@/views/project-management/projects/progress/index.vue'), meta: { - title: '立项管理', - icon: 'plus-circle' + title: '进度管理', + icon: 'schedule', + hidden: false } }, { - path: '/project-management/projects/management', - name: 'ProjectDetailManagement', + path: '/project-management/projects/budget', + name: 'ProjectBudget', component: () => import('@/views/project-management/projects/management/index.vue'), meta: { - title: '项目详细管理', - icon: 'settings' + title: '预算管理', + icon: 'fund', + hidden: false + } + }, + { + path: '/project-management/projects/personnel-distribution', + name: 'PersonnelDistribution', + component: () => import('@/views/project-management/projects/personnel-distribution/index.vue'), + meta: { + title: '人员分布图', + icon: 'team', + hidden: false + } + }, + { + path: '/project-management/projects/device', + name: 'DeviceManagement', + component: () => import('@/views/system-resource/device-management/index.vue'), + meta: { + title: '设备管理', + icon: 'plus-circle', + hidden: false + } + }, + { + path: '/project-management/projects/safety', + name: 'SafetyManagement', + component: () => import('@/views/project-management/projects/safety/index.vue'), + meta: { + title: '安全管理', + icon: 'safety', + hidden: false + } + }, + { + path: '/project-management/projects/quality', + name: 'QualityManagement', + component: () => import('@/views/project-management/projects/quality/index.vue'), + meta: { + title: '质量管理', + icon: 'audit', + hidden: false } } ] @@ -351,57 +527,245 @@ export const systemRoutes: RouteRecordRaw[] = [ ], }, { - path: '/', - name: 'Project', + path: '/construction-operation-platform', + name: 'ConstructionOperationPlatform', component: Layout, - redirect: '/project', - meta: { title: '项目管理(旧)', icon: 'project-old', hidden: true, sort: 5 }, + redirect: '/construction-operation-platform/implementation-workflow/field-construction', + meta: { title: '施工操作台', icon: 'tool', hidden: false, sort: 5 }, children: [ { - path: '/project', - name: 'ProjectList', - component: () => import('@/views/project/index.vue'), - meta: { title: '项目列表', icon: 'list', hidden: false }, - }, - { - path: '/project/detail/:id', - name: 'ProjectDetail', - component: () => import('@/views/project/detail/index.vue'), - meta: { title: '项目详情', icon: 'detail', hidden: true }, - }, - { - path: '/project/task', - name: 'TaskBoard', - component: () => import('@/views/project/task/index.vue'), - meta: { title: '任务看板', icon: 'table', hidden: false }, - }, - { - path: '/project/kanban', - name: 'ProjectKanban', - component: () => import('@/views/project/kanban/index.vue'), - meta: { title: '项目进度', icon: 'kanban', hidden: false }, - }, - { - path: '/project/budget', - name: 'ProjectBudget', - component: () => import('@/views/project/budget/index.vue'), - meta: { title: '项目预算', icon: 'budget', hidden: false }, + path: '/construction-operation-platform/implementation-workflow', + name: 'ImplementationWorkflow', + component: () => import('@/components/ParentView/index.vue'), + redirect: '/construction-operation-platform/implementation-workflow/field-construction', + meta: { title: '项目实施工作流程', icon: 'fork', hidden: false }, + children: [ + { + path: '/construction-operation-platform/implementation-workflow/field-construction', + name: 'FieldConstruction', + component: () => import('@/components/ParentView/index.vue'), + redirect: '/construction-operation-platform/implementation-workflow/field-construction/project-list', + meta: { title: '外业施工', icon: 'construction', hidden: false }, + children: [ + { + path: '/project-management/projects/list', + name: 'ProjectList', + component: () => import('@/views/project-management/projects/list/index.vue'), + meta: { + title: '项目列表', + icon: 'unordered-list', + hidden: false + } + }, + { + path: '/construction-operation-platform/implementation-workflow/field-construction/technology', + name: 'FieldConstructionTechnology', + component: () => import('@/views/project-operation-platform/implementation-workflow/field-construction/project-list/index.vue'), + meta: { title: '现场工艺', icon: 'tool', hidden: false }, + } + ] + }, + { + path: '/construction-operation-platform/implementation-workflow/data-processing', + name: 'DataProcessing', + component: () => import('@/components/ParentView/index.vue'), + redirect: '/construction-operation-platform/implementation-workflow/data-processing/data-storage', + meta: { title: '数据处理', icon: 'filter', hidden: false }, + children: [ + { + path: '/construction-operation-platform/implementation-workflow/data-processing/data-storage', + name: 'DataStorage', + component: () => import('@/components/ParentView/index.vue'), + redirect: '/construction-operation-platform/implementation-workflow/data-processing/data-storage/raw-data', + meta: { title: '数据入库', icon: 'database', hidden: false }, + children: [ + { + path: '/construction-operation-platform/implementation-workflow/data-processing/data-storage/raw-data', + name: 'RawData', + component: () => import('@/views/operation-platform/data-processing/data-storage/index.vue'), + meta: { title: '原数据管理', icon: 'file', hidden: false }, + }, + { + path: '/construction-operation-platform/implementation-workflow/data-processing/data-storage/preprocessed-data', + name: 'PreprocessedData', + component: () => import('@/views/construction-operation-platform/implementation-workflow/data-processing/data-preprocessing/index.vue'), + meta: { title: '数据预处理', icon: 'filter', hidden: false }, + }, + { + path: '/construction-operation-platform/implementation-workflow/data-processing/data-storage/attachment', + name: 'AttachmentManagement', + component: () => import('@/views/operation-platform/data-processing/data-storage/index.vue'), + meta: { title: '附件管理', icon: 'attachment', hidden: false }, + }, + { + path: '/construction-operation-platform/implementation-workflow/data-processing/data-storage/model-config', + name: 'ModelConfig', + component: () => import('@/views/construction-operation-platform/implementation-workflow/data-processing/model-config/index.vue'), + meta: { title: '模型配置', icon: 'robot', hidden: false }, + }, + + ] + }, + { + path: '/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection', + name: 'IntelligentInspection', + component: () => import('@/components/ParentView/index.vue'), + redirect: '/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm', + meta: { title: '智能巡检平台', icon: 'scan', hidden: false }, + children: [ + { + path: '/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm', + name: 'DefectAlgorithm', + component: () => import('@/views/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm/index.vue'), + meta: { title: '缺陷检测算法', icon: 'code', hidden: false }, + }, + { + path: '/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/tree-visualization', + name: 'TreeVisualization', + component: () => import('@/views/project-operation-platform/data-processing/key-info-extraction/index.vue'), + meta: { title: '树状可视化管理', icon: 'cluster', hidden: false }, + }, + { + path: '/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/standard-info', + name: 'StandardInfo', + component: () => import('@/views/project-operation-platform/data-processing/standard-info/index.vue'), + meta: { title: '标准信息库', icon: 'book', hidden: false }, + }, + { + path: '/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/report-generation', + name: 'ReportGeneration', + component: () => import('@/views/project-operation-platform/data-processing/report-generation/index.vue'), + meta: { title: '报告生成', icon: 'file-add', hidden: false }, + }, + { + path: '/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/lifecycle-management', + name: 'LifecycleManagement', + component: () => import('@/views/project-operation-platform/lifecycle-management/index.vue'), + meta: { title: '全生命周期管理', icon: 'reload', hidden: false }, + }, + { + path: '/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/drone-services', + name: 'DroneServices', + component: () => import('@/views/project-operation-platform/route-planning/index.vue'), + meta: { title: '无人机云服务', icon: 'cloud-server', hidden: false }, + }, + { + path: '/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/report-review', + name: 'ReportReview', + component: () => import('@/views/project-operation-platform/data-processing/report-review/index.vue'), + meta: { title: '报告修改审核', icon: 'audit', hidden: false }, + } + ] + } + ] + }, + { + path: '/construction-operation-platform/implementation-workflow/tower-monitoring-video', + name: 'TowerMonitoringVideo', + component: () => import('@/components/ParentView/index.vue'), + redirect: '/construction-operation-platform/implementation-workflow/tower-monitoring-video/clearance-distance', + meta: { title: '塔下监测预告', icon: 'video-camera', hidden: false }, + children: [ + { + path: '/construction-operation-platform/implementation-workflow/tower-monitoring-video/clearance-distance', + name: 'ClearanceDistance', + component: () => import('@/views/project-operation-platform/data-processing/clearance-detection/index.vue'), + meta: { title: '净空距离检测', icon: 'fullscreen', hidden: false }, + }, + { + path: '/construction-operation-platform/implementation-workflow/tower-monitoring-video/deformation-monitoring', + name: 'DeformationMonitoring', + component: () => import('@/views/project-operation-platform/data-processing/deformation-detection/index.vue'), + meta: { title: '形变检测', icon: 'line-chart', hidden: false }, + }, + { + path: '/construction-operation-platform/implementation-workflow/tower-monitoring-video/image-detection', + name: 'ImageDetection', + component: () => import('@/views/project-operation-platform/data-processing/wide-angle-video/index.vue'), + meta: { title: '图像检测', icon: 'picture', hidden: false }, + } + ] + }, + { + path: '/construction-operation-platform/implementation-workflow/project-delivery', + name: 'ProjectDelivery', + component: () => import('@/views/project-operation-platform/quality-management/process-verification/index.vue'), + meta: { title: '项目交付', icon: 'check-circle', hidden: false }, + }, + { + path: '/construction-operation-platform/implementation-workflow/reliability-assessment', + name: 'ReliabilityAssessment', + component: () => import('@/views/project-operation-platform/quality-management/process-verification/index.vue'), + meta: { title: '可靠性评估', icon: 'safety-certificate', hidden: false }, + }, + { + path: '/construction-operation-platform/implementation-workflow/data-quality-assessment', + name: 'DataQualityAssessment', + component: () => import('@/views/project-operation-platform/data-processing/data-quality-assessment/index.vue'), + meta: { title: '数据质量评估', icon: 'audit', hidden: false }, + }, + { + path: '/construction-operation-platform/implementation-workflow/defect-storage', + name: 'DefectStorage', + component: () => import('@/views/project-operation-platform/quality-management/defect-storage/index.vue'), + meta: { title: '缺陷入库', icon: 'folder-add', hidden: false }, + }, + { + path: '/construction-operation-platform/implementation-workflow/other', + name: 'Other', + component: () => import('@/components/ParentView/index.vue'), + redirect: '/construction-operation-platform/implementation-workflow/other/route-planning', + meta: { title: '其他', icon: 'more', hidden: false }, + children: [ + { + path: '/construction-operation-platform/implementation-workflow/other/route-planning', + name: 'RoutesPlanningOther', + component: () => import('@/views/project-operation-platform/route-planning/index.vue'), + meta: { title: '航线规划', icon: 'compass', hidden: false }, + }, + { + path: '/construction-operation-platform/implementation-workflow/other/3d-model', + name: '3DModelOther', + component: () => import('@/views/project-operation-platform/data-processing/3d-model/index.vue'), + meta: { title: '三维模型', icon: 'cube', hidden: false }, + }, + { + path: '/construction-operation-platform/implementation-workflow/other/report-template', + name: 'ReportTemplateOther', + component: () => import('@/views/project-operation-platform/data-processing/report-template/index.vue'), + meta: { title: '报告模版库', icon: 'book', hidden: false }, + } + ] + } + ] } ], }, - { - path: '/pwdExpired', - component: () => import('@/views/login/pwdExpired/index.vue'), - meta: { hidden: true }, + path: '/chat-platform', + name: 'ChatPlatform', + component: Layout, + redirect: '/chat-platform/options', + meta: { title: '聊天平台', icon: 'message', hidden: false, sort: 6 }, + children: [ + // { + // path: '/chat-platform/options', + // name: 'ChatOptions', + // component: () => import('@/views/default/redirect/index.vue'), // 临时使用一个组件,实际开发中需要替换 + // meta: { + // title: '二级选项1', + // icon: 'setting', + // hidden: false + // } + // } + ] }, { path: '/enterprise-settings', name: 'EnterpriseSettings', - meta: { - title: '企业设置', - icon: 'building' - }, + component: Layout, + redirect: '/enterprise-settings/company-info', + meta: { title: '企业设置', icon: 'setting', hidden: false, sort: 7 }, children: [ { path: '/enterprise-settings/company-info', @@ -409,7 +773,8 @@ export const systemRoutes: RouteRecordRaw[] = [ component: () => import('@/views/enterprise-settings/company-info/index.vue'), meta: { title: '企业信息', - icon: 'info-circle' + icon: 'info-circle', + hidden: false } }, { @@ -418,7 +783,8 @@ export const systemRoutes: RouteRecordRaw[] = [ component: () => import('@/views/enterprise-settings/admin-permissions/index.vue'), meta: { title: '管理员权限', - icon: 'user-switch' + icon: 'lock', + hidden: false } }, { @@ -427,7 +793,8 @@ export const systemRoutes: RouteRecordRaw[] = [ component: () => import('@/views/enterprise-settings/data-migration/index.vue'), meta: { title: '数据迁移', - icon: 'swap' + icon: 'database', + hidden: false } }, { @@ -435,8 +802,58 @@ export const systemRoutes: RouteRecordRaw[] = [ name: 'VersionUpgrade', component: () => import('@/views/enterprise-settings/version-upgrade/index.vue'), meta: { - title: '版本升级提醒', - icon: 'arrow-up' + title: '版本升级提醒', + icon: 'upgrade', + hidden: false + } + } + ] + }, + { + path: '/enterprise-dashboard', + name: 'EnterpriseDashboard', + component: Layout, + redirect: '/enterprise-dashboard/overview', + meta: { title: '企业看板', icon: 'dashboard', hidden: false, sort: 8 }, + children: [ + { + path: '/enterprise-dashboard/overview', + name: 'DashboardOverview', + component: () => import('@/views/enterprise-dashboard/overview/index.vue'), + meta: { + title: '数据概览', + icon: 'bar-chart', + hidden: false + } + }, + { + path: '/enterprise-dashboard/member-data', + name: 'MemberData', + component: () => import('@/views/enterprise-dashboard/member-data/index.vue'), + meta: { + title: '成员活跃数据', + icon: 'team', + hidden: false + } + }, + { + path: '/enterprise-dashboard/function-usage', + name: 'FunctionUsage', + component: () => import('@/views/enterprise-dashboard/function-usage/index.vue'), + meta: { + title: '功能使用情况', + icon: 'appstore', + hidden: false + } + }, + { + path: '/enterprise-dashboard/application-data', + name: 'ApplicationData', + component: () => import('@/views/enterprise-dashboard/application-data/index.vue'), + meta: { + title: '应用使用数据', + icon: 'pie-chart', + hidden: false } } ] @@ -444,26 +861,73 @@ export const systemRoutes: RouteRecordRaw[] = [ { path: '/system-resource', name: 'SystemResource', - meta: { - title: '系统资源管理', - icon: 'cluster' - }, + component: Layout, + redirect: '/system-resource/device-management/warehouse', + meta: { title: '关于平台', icon: 'server', hidden: false, sort: 9 }, children: [ - { - path: '/system-resource/device-management', - name: 'DeviceManagement', - component: () => import('@/views/system-resource/device-management/index.vue'), - meta: { - title: '设备管理', - icon: 'desktop' - } - }, + { + path: '/system-resource/device-management/warehouse', + name: 'DeviceWarehouse', + component: () => import('@/views/system-resource/device-management/index.vue'), + meta: { + title: '库存管理', + icon: 'warehouse', + hidden: false + } + }, + { + path: '/system-resource/device-management/online', + name: 'DeviceOnline', + component: () => import('@/components/ParentView/index.vue'), + redirect: '/system-resource/device-management/online/drone', + meta: { + title: '在线管理', + icon: 'cloud', + hidden: false + }, + children: [ + { + path: '/system-resource/device-management/online/drone', + name: 'DeviceDrone', + component: () => import('@/views/system-resource/device-management/index.vue'), + meta: { + title: '无人机', + icon: 'drone', + hidden: false + } + }, + { + path: '/system-resource/device-management/online/nest', + name: 'DeviceNest', + component: () => import('@/views/system-resource/device-management/index.vue'), + meta: { + title: '机巢', + icon: 'nest', + hidden: false + } + }, + { + path: '/system-resource/device-management/online/smart-terminal', + name: 'DeviceSmartTerminal', + component: () => import('@/views/system-resource/device-management/index.vue'), + meta: { + title: '其他智能终端', + icon: 'terminal', + hidden: false + } + } + ] + } + , { path: '/system-resource/information-system', name: 'InformationSystem', + component: () => import('@/components/ParentView/index.vue'), + redirect: '/system-resource/information-system/software-management', meta: { title: '信息化系统管理', - icon: 'code' + icon: 'code', + hidden: false }, children: [ { @@ -472,7 +936,8 @@ export const systemRoutes: RouteRecordRaw[] = [ component: () => import('@/views/system-resource/information-system/software-management/index.vue'), meta: { title: '软件管理', - icon: 'appstore' + icon: 'appstore', + hidden: false } }, { @@ -481,13 +946,35 @@ export const systemRoutes: RouteRecordRaw[] = [ component: () => import('@/views/system-resource/information-system/system-backup/index.vue'), meta: { title: '系统备份管理', - icon: 'save' + icon: 'save', + hidden: false } } ] + }, + { + path: '/system-resource/about', + name: 'About', + component: () => import('@/views/dashboard/workplace/index.vue'), + meta: { + title: '关于我们', + icon: 'info-circle', + hidden: false + } } ] - } + }, + + { + path: '/', + redirect: '/project-management/projects/initiation', + meta: { hidden: true }, + }, + { + path: '/pwdExpired', + component: () => import('@/views/login/pwdExpired/index.vue'), + meta: { hidden: true }, + }, ] // 固定路由(默认路由) diff --git a/src/types/components.d.ts b/src/types/components.d.ts index 7ea3f11..92efec9 100644 --- a/src/types/components.d.ts +++ b/src/types/components.d.ts @@ -49,6 +49,9 @@ declare module 'vue' { IconTableSize: typeof import('./../components/icons/IconTableSize.vue')['default'] IconTreeAdd: typeof import('./../components/icons/IconTreeAdd.vue')['default'] IconTreeReduce: typeof import('./../components/icons/IconTreeReduce.vue')['default'] + ImageImport: typeof import('./../components/ImageImport/index.vue')['default'] + ImageImportWizard: typeof import('./../components/ImageImportWizard/index.vue')['default'] + IndustrialImageList: typeof import('./../components/IndustrialImageList/index.vue')['default'] JsonPretty: typeof import('./../components/JsonPretty/index.vue')['default'] MinuteForm: typeof import('./../components/GenCron/CronForm/component/minute-form.vue')['default'] MonthForm: typeof import('./../components/GenCron/CronForm/component/month-form.vue')['default'] diff --git a/src/views/.DS_Store b/src/views/.DS_Store new file mode 100644 index 0000000..754f88a Binary files /dev/null and b/src/views/.DS_Store differ diff --git a/src/views/construction-operation-platform/implementation-workflow/data-processing/data-preprocessing/index.vue b/src/views/construction-operation-platform/implementation-workflow/data-processing/data-preprocessing/index.vue new file mode 100644 index 0000000..2fde12e --- /dev/null +++ b/src/views/construction-operation-platform/implementation-workflow/data-processing/data-preprocessing/index.vue @@ -0,0 +1,532 @@ + + + + + \ No newline at end of file diff --git a/src/views/construction-operation-platform/implementation-workflow/data-processing/data-storage/components/AttachmentManagement.vue b/src/views/construction-operation-platform/implementation-workflow/data-processing/data-storage/components/AttachmentManagement.vue new file mode 100644 index 0000000..19265cb --- /dev/null +++ b/src/views/construction-operation-platform/implementation-workflow/data-processing/data-storage/components/AttachmentManagement.vue @@ -0,0 +1,380 @@ + + + + + \ No newline at end of file diff --git a/src/views/construction-operation-platform/implementation-workflow/data-processing/data-storage/components/AttachmentUpload.vue b/src/views/construction-operation-platform/implementation-workflow/data-processing/data-storage/components/AttachmentUpload.vue new file mode 100644 index 0000000..4bfb83e --- /dev/null +++ b/src/views/construction-operation-platform/implementation-workflow/data-processing/data-storage/components/AttachmentUpload.vue @@ -0,0 +1,234 @@ + + + + + \ No newline at end of file diff --git a/src/views/construction-operation-platform/implementation-workflow/data-processing/data-storage/index.vue b/src/views/construction-operation-platform/implementation-workflow/data-processing/data-storage/index.vue new file mode 100644 index 0000000..8faa19c --- /dev/null +++ b/src/views/construction-operation-platform/implementation-workflow/data-processing/data-storage/index.vue @@ -0,0 +1,27 @@ + + + + + \ No newline at end of file diff --git a/src/views/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm/.DS_Store b/src/views/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm/.DS_Store new file mode 100644 index 0000000..dbd07c1 Binary files /dev/null and b/src/views/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm/.DS_Store differ diff --git a/src/views/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm/components/AutoRecognitionSettings.vue b/src/views/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm/components/AutoRecognitionSettings.vue new file mode 100644 index 0000000..b722607 --- /dev/null +++ b/src/views/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm/components/AutoRecognitionSettings.vue @@ -0,0 +1,354 @@ + + + + + \ No newline at end of file diff --git a/src/views/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm/components/DefectDetailsForm.vue b/src/views/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm/components/DefectDetailsForm.vue new file mode 100644 index 0000000..5433b36 --- /dev/null +++ b/src/views/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm/components/DefectDetailsForm.vue @@ -0,0 +1,445 @@ + + + + + \ No newline at end of file diff --git a/src/views/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm/components/DefectDetailsPanel.vue b/src/views/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm/components/DefectDetailsPanel.vue new file mode 100644 index 0000000..d6d2bd8 --- /dev/null +++ b/src/views/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm/components/DefectDetailsPanel.vue @@ -0,0 +1,709 @@ + + + + + \ No newline at end of file diff --git a/src/views/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm/components/DefectListPanel.vue b/src/views/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm/components/DefectListPanel.vue new file mode 100644 index 0000000..36045bd --- /dev/null +++ b/src/views/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm/components/DefectListPanel.vue @@ -0,0 +1,331 @@ + + + + + \ No newline at end of file diff --git a/src/views/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm/components/HeaderToolbar.vue b/src/views/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm/components/HeaderToolbar.vue new file mode 100644 index 0000000..403bad7 --- /dev/null +++ b/src/views/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm/components/HeaderToolbar.vue @@ -0,0 +1,96 @@ + + + + + \ No newline at end of file diff --git a/src/views/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm/components/ImagePreview.vue b/src/views/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm/components/ImagePreview.vue new file mode 100644 index 0000000..7c3e9f8 --- /dev/null +++ b/src/views/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm/components/ImagePreview.vue @@ -0,0 +1,359 @@ + + + + + \ No newline at end of file diff --git a/src/views/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm/components/ProjectTree.vue b/src/views/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm/components/ProjectTree.vue new file mode 100644 index 0000000..d58e5cd --- /dev/null +++ b/src/views/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm/components/ProjectTree.vue @@ -0,0 +1,139 @@ + + + + + \ No newline at end of file diff --git a/src/views/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm/components/RecognitionResults.vue b/src/views/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm/components/RecognitionResults.vue new file mode 100644 index 0000000..eb08fca --- /dev/null +++ b/src/views/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm/components/RecognitionResults.vue @@ -0,0 +1,451 @@ + + + + + \ No newline at end of file diff --git a/src/views/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm/hooks/useIndustrialImage.ts b/src/views/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm/hooks/useIndustrialImage.ts new file mode 100644 index 0000000..435f6d4 --- /dev/null +++ b/src/views/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm/hooks/useIndustrialImage.ts @@ -0,0 +1,1074 @@ +import { ref, reactive, computed } from 'vue' +import { Message, Modal } from '@arco-design/web-vue' +import { + getProjectList, + getTurbineList, + getPartList, + getImageList, + deleteImage, + autoAnnotateImage, + generateReport, + batchUploadImages, + uploadImageToPartV2, + type ProjectTreeNode, + type IndustrialImage, + type ProjectInfo, + type TurbineInfo, + type PartInfo +} from '@/apis/industrial-image' +import { + detectDefects, + getDefectList, + addDefect, + updateDefect, + deleteDefect, + addManualDefect, + type DefectDetectionRequest, + type DefectDetectionResult, + type ManualDefectAddRequest +} from '@/apis/industrial-image/defect' +import type { TreeNodeData, ImageInfo } from '@/apis/industrial-image/type' +import type { DefectInfo } from '@/apis/industrial-image/defect' +import type { Annotation } from '@/views/project-operation-platform/data-processing/industrial-image/components/ImageCanvas.vue' + +export function useIndustrialImage() { + // 项目树数据 + const projectTreeData = ref([]) + const selectedKeys = ref([]) + const currentProjectId = ref('') + + // 图像列表数据 + const imageList = ref([]) + const selectedImage = ref(null) + const selectedImageId = ref('') + const searchKeyword = ref('') + + // 模态框状态 + const previewModalVisible = ref(false) + const previewImage = ref(null) + const processModalVisible = ref(false) + const processImage = ref(null) + const importModalVisible = ref(false) + const annotationModalVisible = ref(false) + + // 图像导入向导相关数据 + const importWizardVisible = ref(false) + const selectedTurbineId = ref('') + const currentTurbineParts = ref([]) + + // 自动识别相关状态 + const isAutoRecognitionMode = ref(false) + const recognitionResults = ref([]) + const isRecognizing = ref(false) + + // 手动标注相关状态 + const isManualAnnotationMode = ref(false) + const defectList = ref([]) + const selectedDefect = ref(null) + + // Canvas 标注相关状态 + const selectedDefectAnnotations = computed(() => { + if (!selectedDefect.value) return [] + // 将缺陷数据转换为 Canvas 标注格式 + return [{ + id: selectedDefect.value.id, + type: 'rectangle' as const, + points: selectedDefect.value.boundingBox ? [ + { x: selectedDefect.value.boundingBox.x, y: selectedDefect.value.boundingBox.y }, + { x: selectedDefect.value.boundingBox.x + selectedDefect.value.boundingBox.width, + y: selectedDefect.value.boundingBox.y + selectedDefect.value.boundingBox.height } + ] : [], + color: selectedDefect.value.severity === 'high' ? '#ff4d4f' : '#faad14', + label: selectedDefect.value.defectType + }] + }) + + // 报告生成相关状态 + const reportGenerationVisible = ref(false) + const reportUnitData = ref<{ + id: string + name: string + type: 'project' | 'turbine' | 'part' + } | null>(null) + + // 加载状态 + const loading = ref(false) + + // 计算属性 + const currentImageId = computed(() => selectedImageId.value) + + // 加载项目树数据 + const loadProjectTree = async () => { + try { + loading.value = true + const response = await getProjectList({ page: 1, pageSize: 1000 }) + + // 处理不同的返回数据结构 + let projects: ProjectInfo[] = [] + if (Array.isArray(response.data)) { + projects = response.data + } else if (response.data?.list) { + projects = response.data.list + } else { + projects = [] + } + + projectTreeData.value = projects.map(project => ({ + id: project.projectId, + name: project.projectName, + type: 'project' as const, + children: [], + isLeaf: false, + loaded: false, + expanded: false, + status: project.status, + createTime: project.createTime, + rawData: project + })) + + // 默认选中第一个项目 + if (projectTreeData.value.length > 0) { + const firstProject = projectTreeData.value[0] + selectedKeys.value = [firstProject.id] + currentProjectId.value = firstProject.id + console.log('默认选中第一个项目:', firstProject.name) + + // 加载图像列表 + loadImageList() + } + } catch (error) { + console.error('加载项目列表失败:', error) + Message.error('加载项目列表失败') + } finally { + loading.value = false + } + } + + // 懒加载子节点 + const handleLoadMore = async (node: ProjectTreeNode) => { + if (!node || node.loaded) return + + try { + if (node.type === 'project') { + const response = await getTurbineList({ projectId: node.id }) + const turbines = response.data || [] + + node.children = turbines.map(turbine => ({ + id: turbine.turbineId || turbine.projectId, + name: turbine.turbineName || turbine.turbineDesc || `机组${turbine.turbineId || turbine.projectId}`, + type: 'turbine' as const, + parentId: node.id, + children: [], + isLeaf: false, + loaded: false, + expanded: false, + status: turbine.status, + createTime: turbine.createTime, + rawData: turbine + })) + } else if (node.type === 'turbine') { + const turbineData = node.rawData as TurbineInfo + const response = await getPartList({ + turbineId: turbineData?.turbineId || node.id + }) + const parts = response.data || [] + + node.children = parts.map(part => ({ + id: part.partId, + name: part.partName || part.partType || `部件${part.partId}`, + type: 'part' as const, + parentId: node.id, + children: [], + isLeaf: true, + loaded: true, + expanded: false, + status: part.partType, + createTime: part.createTime, + rawData: part + })) + } + + node.loaded = true + } catch (error) { + console.error('加载子节点失败:', error) + Message.error('加载子节点失败') + } + } + + // 处理节点选择 + const handleNodeSelect = (keys: string[]) => { + if (keys.length > 0) { + selectedKeys.value = keys + currentProjectId.value = keys[0] + + const selectedNode = findSelectedNode(projectTreeData.value, keys[0]) + if (selectedNode) { + console.log('选中节点:', selectedNode) + + // 如果选中的是机组节点,设置为当前选中的机组 + if (selectedNode.type === 'turbine') { + selectedTurbineId.value = selectedNode.id + // 加载该机组下的部件信息 + loadTurbineParts(selectedNode) + } + } + + loadImageList() + } + } + + // 加载指定机组的部件信息 + const loadTurbineParts = async (turbineNode: ProjectTreeNode) => { + try { + const turbineData = turbineNode.rawData as TurbineInfo + const response = await getPartList({ + turbineId: turbineData?.turbineId || turbineNode.id + }) + + const parts = response.data || [] + console.log('加载的部件信息:', parts) + + currentTurbineParts.value = parts + console.log('设置部件信息完成,数量:', currentTurbineParts.value.length) + } catch (error) { + console.error('加载机组部件失败:', error) + Message.error('加载机组部件失败') + currentTurbineParts.value = [] + } + } + + // 加载图像列表 + const loadImageList = async () => { + try { + loading.value = true + + const selectedNode = findSelectedNode(projectTreeData.value, currentProjectId.value) + if (!selectedNode) { + imageList.value = [] + return + } + + // 构建查询参数 + const params: { + imageTypes?: string[] + keyword?: string + partId?: string + turbineId?: string + } = {} + + // 添加关键字搜索 + if (searchKeyword.value) { + params.keyword = searchKeyword.value + } + + // 根据选中节点类型设置查询参数 + if (selectedNode.type === 'project') { + // 选中项目时,不设置特定的过滤条件,查询所有图像 + console.log('选中项目节点,查询所有图像') + } else if (selectedNode.type === 'turbine') { + params.turbineId = selectedNode.id + } else if (selectedNode.type === 'part') { + params.partId = selectedNode.id + // 如果选中部件,也需要找到对应的机组ID + const turbineNode = findParentNode(projectTreeData.value, selectedNode.id) + if (turbineNode) { + params.turbineId = turbineNode.id + } + } + + console.log('查询图像列表参数:', params) + // 调用真实API + const response = await getImageList(params) + imageList.value = response.data + } catch (error) { + Message.error('加载图像列表失败') + imageList.value = [] + } finally { + loading.value = false + } + } + + + + // 查找选中的节点 + const findSelectedNode = (nodes: ProjectTreeNode[], nodeId: string): ProjectTreeNode | null => { + if (!nodes || !Array.isArray(nodes) || !nodeId) return null + + for (const node of nodes) { + if (!node) continue + + if (node.id === nodeId) { + return node + } + if (node.children && node.children.length > 0) { + const found = findSelectedNode(node.children, nodeId) + if (found) return found + } + } + return null + } + + // 查找父节点 + const findParentNode = (nodes: ProjectTreeNode[], childId: string): ProjectTreeNode | null => { + if (!nodes || !Array.isArray(nodes) || !childId) return null + + for (const node of nodes) { + if (!node) continue + + if (node.children && node.children.length > 0) { + const childFound = node.children.find(child => child && child.id === childId) + if (childFound) return node + + const found = findParentNode(node.children, childId) + if (found) return found + } + } + return null + } + + // 图像操作 + const handleImageSelect = (image: any) => { + console.log('选中图像:', image) + selectedImage.value = image + + // 尝试多种可能的图像ID字段名 + const imageId = image.imageId || image.id || image.image_id || image.key || image.attachId + selectedImageId.value = imageId || '' + + console.log('设置图像ID:', selectedImageId.value) + + if (!selectedImageId.value) { + console.warn('图像ID为空,图像数据结构:', image) + Message.warning('图像ID为空,标注功能可能无法正常使用') + } + + // 确保图像对象有必要的字段 + if (!image.attachId && imageId) { + image.attachId = imageId + } + } + + const handleImagePreview = (image: any) => { + previewImage.value = image + previewModalVisible.value = true + } + + const handleImageProcess = (image: any) => { + processImage.value = image + processModalVisible.value = true + } + + const handleImageDelete = (image: any) => { + Modal.confirm({ + title: '确认删除', + content: `确定要删除图像"${image.imageName}"吗?`, + onOk: async () => { + try { + await deleteImage(image.imageId) + Message.success('删除成功') + loadImageList() + } catch (error) { + console.error('删除图像失败:', error) + Message.error('删除图像失败') + } + } + }) + } + + const handleSearch = (keyword: string) => { + searchKeyword.value = keyword + loadImageList() + } + + // 头部按钮操作 + const handleStart = () => { + Message.info('开始处理功能') + } + + const handleIndustrialImage = () => { + Message.info('工业图像功能') + } + + const handleImportImages = () => { + // 检查是否选择了机组 + const selectedNode = findSelectedNode(projectTreeData.value, currentProjectId.value) + if (!selectedNode) { + Message.warning('请先选择一个项目或机组') + return + } + + if (selectedNode.type === 'turbine') { + // 如果选中的是机组,直接打开向导 + importWizardVisible.value = true + } else if (selectedNode.type === 'project') { + // 如果选中的是项目,提示用户选择机组 + Message.warning('请先选择一个机组来导入图像') + } else { + // 如果选中的是部件,使用原来的导入方式 + importModalVisible.value = true + } + } + + const handleAutoAnnotate = async () => { + if (!selectedImage.value) { + Message.warning('请先选择一张图像') + return + } + + // 切换到自动识别模式 + isAutoRecognitionMode.value = true + + // 清空之前的识别结果 + recognitionResults.value = [] + + Message.info('已切换到自动识别模式') + } + + const handleManualAnnotate = () => { + if (!selectedImage.value) { + Message.warning('请先选择一张图像') + return + } + + // 切换到手动标注模式 + isManualAnnotationMode.value = true + + // 加载对应的缺陷列表 + loadDefectList() + + Message.info('已切换到手动标注模式') + } + + const handleGenerateReport = async () => { + const selectedNode = findSelectedNode(projectTreeData.value, currentProjectId.value) + if (!selectedNode) { + Message.warning('请先选择一个项目、机组或部件') + return + } + + // 设置报告单位数据 + reportUnitData.value = { + id: selectedNode.id, + name: selectedNode.name, + type: selectedNode.type + } + + // 显示报告生成对话框 + reportGenerationVisible.value = true + } + + // 模态框事件处理 + const handleImportSuccess = () => { + loadImageList() + Message.success('图像导入成功') + } + + const handleAnnotationSaved = () => { + loadImageList() + Message.success('标注保存成功') + } + + const handleProcessSuccess = () => { + loadImageList() + } + + // 向导导入成功处理 + const handleWizardImportSuccess = async (data: any) => { + console.log('向导导入成功:', data) + + try { + // 构建上传参数 + const uploadParams = { + collectorName: data.imageInfo.operator, + humidness: data.imageInfo.humidity, + shootingDistance: data.imageInfo.captureDistance, + shootingMethod: data.imageInfo.captureMethod, + shootingTimeBegin: data.imageInfo.startTime, + shootingTimeEnd: data.imageInfo.endTime, + temperatureMax: data.imageInfo.maxTemperature, + temperatureMin: data.imageInfo.minTemperature, + weather: data.imageInfo.weather, + windLevel: data.imageInfo.windPower + } + + // 使用新的API接口上传图像 + const response = await uploadImageToPartV2( + 'default', // 图像源 + data.part.partId, // 部件ID + data.images, // 文件列表 + uploadParams + ) + + console.log('批量上传响应:', response) + + // 重新加载图像列表 + loadImageList() + + Message.success(`成功导入${data.images.length}张图像到${data.part.name}`) + } catch (error) { + console.error('批量上传失败:', error) + Message.error('图像上传失败,请重试') + } + } + + // 加载缺陷列表 + const loadDefectList = async () => { + try { + // 构建查询参数 + const params: any = {} + + // 如果有图像ID,添加到参数 + if (selectedImage.value?.id) { + params.imageId = selectedImage.value.id + } else if (selectedImageId.value) { + params.imageId = selectedImageId.value + } + + // 如果有选中的节点,按照节点类型添加筛选条件 + if (selectedKeys.value && selectedKeys.value.length > 0) { + const selectedNodeId = selectedKeys.value[0] + const selectedNode = findSelectedNode(projectTreeData.value, selectedNodeId) + + if (!selectedNode) { + console.warn('找不到选中的节点:', selectedNodeId) + } else if (selectedNode.type === 'turbine') { + params.turbineId = selectedNode.id + } else if (selectedNode.type === 'part') { + params.partId = selectedNode.id + + // 添加机组ID + const turbineNode = findParentNode(projectTreeData.value, selectedNode.id) + if (turbineNode) { + params.turbineId = turbineNode.id + } + } + } + + console.log('加载缺陷列表参数:', params) + const response = await getDefectList(params) + + if (response.data && response.data.code === 0) { + // 检查返回数据结构 + const resultData = response.data.data + + // 将结果转换为DefectInfo[]类型 + let defects: DefectInfo[] = [] + + if (resultData) { + if ('list' in resultData && Array.isArray(resultData.list)) { + // 分页结构 + defects = resultData.list.map((item: any) => ({ + id: item.id || item.defectId || `defect-${Date.now()}-${Math.random().toString(36).substr(2, 5)}`, + ...item + })) + } else if (Array.isArray(resultData)) { + // 直接数组结构 + defects = resultData.map((item: any) => ({ + id: item.id || item.defectId || `defect-${Date.now()}-${Math.random().toString(36).substr(2, 5)}`, + ...item + })) + } + } + + console.log('处理后的缺陷列表数据:', defects) + defectList.value = defects + } else { + console.error('加载缺陷列表失败:', response) + defectList.value = [] + } + } catch (error) { + console.error('加载缺陷列表失败:', error) + Message.error('加载缺陷列表失败') + defectList.value = [] + } + } + + // 更新选中缺陷的标注 + const updateSelectedDefectAnnotations = () => { + if (!selectedDefect.value || !selectedDefect.value.labelInfo) { + selectedDefectAnnotations.value = [] + return + } + + try { + // 尝试解析labelInfo + const labelInfo = JSON.parse(selectedDefect.value.labelInfo) + if (Array.isArray(labelInfo)) { + selectedDefectAnnotations.value = labelInfo + } else { + selectedDefectAnnotations.value = [labelInfo] + } + } catch (error) { + console.error('解析标注信息失败:', error) + selectedDefectAnnotations.value = [] + } + } + + // 选择缺陷 + const handleDefectSelect = (defect: DefectInfo) => { + selectedDefect.value = defect + updateSelectedDefectAnnotations() + } + + const handleAddDefect = async (defectForm: any, nodeId: string) => { + try { + const selectedNode = findSelectedNode(projectTreeData.value, nodeId) + if (!selectedNode) { + Message.error('无法找到选中的节点') + return + } + + // 构建缺陷数据 + const defectData: Partial = { + defectName: defectForm.defectName, + defectType: defectForm.defectType, + defectLevel: defectForm.defectLevel, + defectPosition: defectForm.defectPosition, + description: defectForm.description, + repairIdea: defectForm.repairIdea, + imageId: selectedImage.value?.imageId || '', + detectionDate: new Date().toISOString(), + source: 'manual' + } + + // 根据节点类型设置相关ID + if (selectedNode.type === 'part') { + // TODO: 设置 partId 和 turbineId + const turbineNode = findParentNode(projectTreeData.value, selectedNode.id) + if (turbineNode) { + // defectData.turbineId = turbineNode.id + // defectData.partId = selectedNode.id + } + } + + const response = await addDefect(defectData) + + if (response.data.success) { + Message.success('缺陷添加成功') + loadDefectList() // 重新加载缺陷列表 + } else { + Message.error('缺陷添加失败') + } + } catch (error) { + console.error('添加缺陷失败:', error) + Message.error('添加缺陷失败') + } + } + + const handleEditDefect = async (defect: DefectDetectionResult) => { + try { + const response = await updateDefect(defect.defectId, defect) + + if (response.data.success) { + Message.success('缺陷更新成功') + loadDefectList() // 重新加载缺陷列表 + } else { + Message.error('缺陷更新失败') + } + } catch (error) { + console.error('更新缺陷失败:', error) + Message.error('更新缺陷失败') + } + } + + const handleDeleteDefectById = async (defectId: string) => { + try { + const response = await deleteDefect(defectId) + + if (response.data.success) { + Message.success('缺陷删除成功') + loadDefectList() // 重新加载缺陷列表 + } else { + Message.error('缺陷删除失败') + } + } catch (error) { + console.error('删除缺陷失败:', error) + Message.error('删除缺陷失败') + } + } + + // Canvas 标注相关方法 + const handleAnnotationAdd = async (annotation: any) => { + try { + // 检查是否有选中的图像 + if (!selectedImageId.value && !selectedImage.value?.imageId) { + Message.error('请先选择一张图像') + return + } + + // 获取有效的图像ID + const imageId = selectedImageId.value || selectedImage.value?.imageId || selectedImage.value?.id + + if (!imageId) { + console.error('无法获取图像ID,选中的图像数据:', selectedImage.value) + Message.error('无法获取图像ID,请重新选择图像') + return + } + + console.log('添加标注 - 图像ID:', imageId) + console.log('添加标注 - 标注数据:', annotation) + + // 构造符合API要求的缺陷数据 + const defectData: ManualDefectAddRequest = { + attachId: selectedImage.value?.attachId || '', + axial: 0, + chordwise: 0, + defectCode: 'MANUAL_001', + defectLevel: 'MEDIUM', + defectName: annotation.label || '手动标注缺陷', + defectPosition: 'UNKNOWN', + defectType: annotation.label || 'UNKNOWN', + description: '手动标注缺陷', + detectionDate: new Date().toISOString(), + labelInfo: JSON.stringify(annotation), + markInfo: { + bbox: annotation.type === 'rectangle' ? [ + Math.min(annotation.points[0].x, annotation.points[1].x), + Math.min(annotation.points[0].y, annotation.points[1].y), + Math.abs(annotation.points[1].x - annotation.points[0].x), + Math.abs(annotation.points[1].y - annotation.points[0].y) + ] : [], + clsId: 1, + confidence: 1.0, + label: annotation.defectType || '手动标注' + }, + repairIdea: '', + repairStatus: 'PENDING', + source: 'MANUAL' + } + + console.log('发送给后端的缺陷数据:', defectData) + + // 调用API添加缺陷,传递两个参数:缺陷数据和图像ID + await addManualDefect(defectData, imageId) + + // 重新加载缺陷列表 + await loadDefectList() + + Message.success('标注添加成功') + } catch (error) { + console.error('添加标注失败:', error) + Message.error('添加标注失败') + } + } + + const handleAnnotationUpdate = async (annotation: any) => { + try { + // 更新标注逻辑 + await updateDefect(annotation.id, annotation) + await loadDefectList() + Message.success('标注更新成功') + } catch (error) { + console.error('更新标注失败:', error) + Message.error('更新标注失败') + } + } + + const handleAnnotationDelete = async (annotationId: string) => { + try { + await deleteDefect(annotationId) + await loadDefectList() + Message.success('标注删除成功') + } catch (error) { + console.error('删除标注失败:', error) + Message.error('删除标注失败') + } + } + + // 报告生成相关方法 + const handleReportGenerated = async (reportData: any) => { + try { + console.log('生成报告数据:', reportData) + + // 这里可以调用后端API生成报告 + // await generateReport(reportData) + + Message.success('报告生成成功') + reportGenerationVisible.value = false + } catch (error) { + console.error('生成报告失败:', error) + Message.error('生成报告失败') + } + } + + // 关闭自动识别模式 + const handleCloseAutoRecognition = () => { + isAutoRecognitionMode.value = false + recognitionResults.value = [] + } + + // 关闭手动标注模式 + const handleCloseManualAnnotation = () => { + isManualAnnotationMode.value = false + defectList.value = [] + selectedDefect.value = null + } + + // 开始自动识别 + const handleStartRecognition = async (settings: { + algorithm: string + confidence: number + defectTypes: string[] + }) => { + if (!selectedImage.value) { + Message.warning('请先选择一张图像') + return + } + + try { + isRecognizing.value = true + + // 调用真实的缺陷检测API + const detectParams: DefectDetectionRequest = { + confThreshold: settings.confidence / 100, // 转换为0-1的置信度 + defectTypeList: settings.defectTypes, + imageId: selectedImage.value.imageId, + modelId: settings.algorithm // 使用算法作为模型ID + } + + const response = await detectDefects(detectParams) + + // 检查返回结构,适配API实际返回的数据格式 + let detectedDefects: DefectDetectionResult[] = [] + + if (response && response.data) { + if (Array.isArray(response.data)) { + // 直接使用返回的数组 + detectedDefects = response.data + } else if (typeof response.data === 'object' && 'data' in response.data && Array.isArray(response.data.data)) { + // 使用嵌套的data数组 + detectedDefects = response.data.data + } + } + + if (detectedDefects.length > 0) { + recognitionResults.value = detectedDefects + + // 检查是否有attachPath,如果有则更新当前显示的图片路径 + const firstResult = detectedDefects[0] + if (firstResult.attachPath && firstResult.attachPath !== selectedImage.value.imagePath) { + // 更新当前选中图像的路径为识别后返回的attachPath + selectedImage.value = { + ...selectedImage.value, + imagePath: firstResult.attachPath + } + console.log('图片路径已更新为识别后的路径:', firstResult.attachPath) + } + + Message.success(`识别完成,发现${detectedDefects.length}个缺陷`) + } else { + recognitionResults.value = [] + Message.info('未发现缺陷') + } + + // 不再需要类型映射,因为RecognitionResults组件已经处理了自定义类型 + + } catch (error) { + console.error('识别失败:', error) + Message.error('识别失败') + recognitionResults.value = [] + } finally { + isRecognizing.value = false + } + } + + // 选择识别结果 + const handleRecognitionResultSelect = (index: number) => { + const result = recognitionResults.value[index] + if (result) { + // 这里可以在图像上高亮显示选中的缺陷 + console.log('选中识别结果:', result) + } + } + + // 保存识别结果 + const handleSaveRecognitionResults = async (results: DefectDetectionResult[]) => { + if (!results || results.length === 0) { + Message.warning('没有识别结果需要保存') + return + } + + if (!selectedImage.value) { + Message.warning('当前没有选中的图像') + return + } + + try { + console.log('开始保存识别结果:', results) + + let successCount = 0 + let failCount = 0 + const errors: string[] = [] + + // 为每个识别结果创建缺陷记录 + for (let i = 0; i < results.length; i++) { + const result = results[i] + + try { + // 构建缺陷数据,转换识别结果为手动添加缺陷的格式 + const defectData: ManualDefectAddRequest = { + attachId: selectedImage.value.imageId, // 使用图像ID作为附件ID + // axial: result.axial || 0, + // chordwise: result.chordwise || 0, + // defectCode: result.defectCode || `AUTO-${Date.now()}-${i + 1}`, // 自动生成缺陷编码 + defectCode: '', + defectLevel: result.defectLevel || 'medium', // 默认中等级别 + defectName: result.defectName || `自动识别缺陷-${i + 1}`, + defectPosition: result.defectPosition || '自动识别位置', + defectType: result.defectType || 'unknown', + description: result.description || `自动识别发现的${result.defectType || '未知'}类型缺陷`, + detectionDate: result.detectionDate || new Date().toISOString(), + labelInfo: result.labelInfo || JSON.stringify(result.markInfo || {}), + markInfo: result.markInfo || { + bbox: [0, 0, 0, 0], + clsId: 0, + confidence: 0.8, + label: result.defectType || '自动识别' + }, + repairIdea: result.repairIdea || '建议进一步检查确认', + repairStatus: result.repairStatus || 'pending', + source: 'auto' // 标记为自动识别来源 + } + + // 调用手动添加缺陷接口 + const response = await addManualDefect(defectData,selectedImage.value.imageId) + + if (response.data.success) { + successCount++ + console.log(`缺陷 ${i + 1} 保存成功:`, response.data.data) + } else { + failCount++ + errors.push(`缺陷 ${i + 1}: ${response.data.msg || '保存失败'}`) + } + } catch (error: any) { + failCount++ + console.error(`保存缺陷 ${i + 1} 失败:`, error) + errors.push(`缺陷 ${i + 1}: ${error.message || '网络错误'}`) + } + } + + // 显示保存结果 + if (successCount > 0 && failCount === 0) { + Message.success(`所有识别结果已保存!共保存 ${successCount} 个缺陷记录`) + } else if (successCount > 0 && failCount > 0) { + Message.warning(`部分识别结果保存成功!成功 ${successCount} 个,失败 ${failCount} 个`) + if (errors.length > 0) { + console.warn('保存失败的详情:', errors) + } + } else { + Message.error(`保存失败!所有 ${failCount} 个识别结果都未能保存`) + if (errors.length > 0) { + console.error('保存失败的详情:', errors) + } + } + + // 如果有成功保存的,重新加载缺陷列表 + if (successCount > 0) { + loadDefectList() + } + + } catch (error) { + console.error('保存识别结果失败:', error) + Message.error('保存识别结果失败') + } + } + + // 导出识别结果 + const handleExportRecognitionResults = (results: any[]) => { + console.log('导出识别结果:', results) + // 实际项目中这里应该调用导出接口 + } + + // 初始化 + const init = () => { + if (!projectTreeData.value) { + projectTreeData.value = [] + } + loadProjectTree() + } + + return { + // 数据 + projectTreeData, + selectedKeys, + currentProjectId, + imageList, + selectedImage, + selectedImageId, + searchKeyword, + previewModalVisible, + previewImage, + processModalVisible, + processImage, + importModalVisible, + annotationModalVisible, + loading, + currentImageId, + + // 向导相关状态 + importWizardVisible, + selectedTurbineId, + currentTurbineParts, + + // 自动识别相关状态 + isAutoRecognitionMode, + recognitionResults, + isRecognizing, + + // 手动标注相关状态 + isManualAnnotationMode, + defectList, + selectedDefect, + selectedDefectAnnotations, + + // 报告生成相关状态 + reportGenerationVisible, + reportUnitData, + + // 方法 + loadProjectTree, + handleLoadMore, + handleNodeSelect, + loadImageList, + handleImageSelect, + handleImagePreview, + handleImageProcess, + handleImageDelete, + handleSearch, + handleStart, + handleIndustrialImage, + handleImportImages, + handleAutoAnnotate, + handleManualAnnotate, + handleGenerateReport, + handleImportSuccess, + handleAnnotationSaved, + handleProcessSuccess, + handleWizardImportSuccess, + + // 自动识别相关方法 + handleCloseAutoRecognition, + handleStartRecognition, + handleRecognitionResultSelect, + handleSaveRecognitionResults, + handleExportRecognitionResults, + + // 手动标注相关方法 + handleCloseManualAnnotation, + loadDefectList, + handleDefectSelect, + handleAddDefect, + handleEditDefect, + handleDeleteDefectById, + + // Canvas 标注相关方法 + handleAnnotationAdd, + handleAnnotationUpdate, + handleAnnotationDelete, + + // 报告生成相关方法 + handleReportGenerated, + + init + } +} \ No newline at end of file diff --git a/src/views/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm/index.vue b/src/views/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm/index.vue new file mode 100644 index 0000000..da19d81 --- /dev/null +++ b/src/views/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm/index.vue @@ -0,0 +1,870 @@ + + + + + \ No newline at end of file diff --git a/src/views/construction-operation-platform/implementation-workflow/data-processing/model-config/index.vue b/src/views/construction-operation-platform/implementation-workflow/data-processing/model-config/index.vue new file mode 100644 index 0000000..c9e51d5 --- /dev/null +++ b/src/views/construction-operation-platform/implementation-workflow/data-processing/model-config/index.vue @@ -0,0 +1,498 @@ + + + + + \ No newline at end of file diff --git a/src/views/default/error/components/ErrorPage.vue b/src/views/default/error/components/ErrorPage.vue index 728889e..a4dea79 100644 --- a/src/views/default/error/components/ErrorPage.vue +++ b/src/views/default/error/components/ErrorPage.vue @@ -38,7 +38,7 @@ const IconMap: Record = { const router = useRouter() // 返回首页 const back = () => { - router.replace({ path: '/' }) + router.replace({ path: '/project-management/bidding/tender-documents' }) } diff --git a/src/views/enterprise-dashboard/application-data/index.vue b/src/views/enterprise-dashboard/application-data/index.vue new file mode 100644 index 0000000..65165ee --- /dev/null +++ b/src/views/enterprise-dashboard/application-data/index.vue @@ -0,0 +1,484 @@ + + + + + \ No newline at end of file diff --git a/src/views/enterprise-dashboard/function-usage/index.vue b/src/views/enterprise-dashboard/function-usage/index.vue new file mode 100644 index 0000000..88e39f6 --- /dev/null +++ b/src/views/enterprise-dashboard/function-usage/index.vue @@ -0,0 +1,375 @@ + + + + + \ No newline at end of file diff --git a/src/views/enterprise-dashboard/member-data/index.vue b/src/views/enterprise-dashboard/member-data/index.vue new file mode 100644 index 0000000..0d2ff82 --- /dev/null +++ b/src/views/enterprise-dashboard/member-data/index.vue @@ -0,0 +1,494 @@ + + + + + \ No newline at end of file diff --git a/src/views/enterprise-dashboard/overview/index.vue b/src/views/enterprise-dashboard/overview/index.vue new file mode 100644 index 0000000..7587973 --- /dev/null +++ b/src/views/enterprise-dashboard/overview/index.vue @@ -0,0 +1,267 @@ + + + + + \ No newline at end of file diff --git a/src/views/enterprise-settings/admin-permissions/index.vue b/src/views/enterprise-settings/admin-permissions/index.vue index 7c7dce7..20816b8 100644 --- a/src/views/enterprise-settings/admin-permissions/index.vue +++ b/src/views/enterprise-settings/admin-permissions/index.vue @@ -101,7 +101,7 @@ import { Message } from '@arco-design/web-vue' import type { TableColumnData } from '@arco-design/web-vue' // 搜索表单 -const searchForm = reactive({ +let searchForm = reactive({ username: '', adminType: '', status: '', diff --git a/src/views/hr/attendance/index.vue b/src/views/hr/attendance/index.vue index c805f2b..4abc637 100644 --- a/src/views/hr/attendance/index.vue +++ b/src/views/hr/attendance/index.vue @@ -54,7 +54,7 @@ import { Message } from '@arco-design/web-vue' import type { TableColumnData } from '@arco-design/web-vue' // 搜索表单 -const searchForm = reactive({ +let searchForm = reactive({ userName: '', deptName: '', status: '', diff --git a/src/views/hr/contribution/index.vue b/src/views/hr/contribution/index.vue index 1eeabe2..d8251ff 100644 --- a/src/views/hr/contribution/index.vue +++ b/src/views/hr/contribution/index.vue @@ -104,7 +104,7 @@ import { Message } from '@arco-design/web-vue' import type { TableColumnData } from '@arco-design/web-vue' // 搜索表单 -const searchForm = reactive({ +let searchForm = reactive({ userName: '', deptName: '', pointLevel: '', diff --git a/src/views/hr/performance/index.vue b/src/views/hr/performance/index.vue index bb5bcad..0f404d4 100644 --- a/src/views/hr/performance/index.vue +++ b/src/views/hr/performance/index.vue @@ -61,7 +61,7 @@ import { Message } from '@arco-design/web-vue' import type { TableColumnData } from '@arco-design/web-vue' // 搜索表单 -const searchForm = reactive({ +let searchForm = reactive({ userName: '', deptName: '', performanceLevel: '', diff --git a/src/views/hr/salary/certification/index.vue b/src/views/hr/salary/certification/index.vue new file mode 100644 index 0000000..82a00ce --- /dev/null +++ b/src/views/hr/salary/certification/index.vue @@ -0,0 +1,601 @@ + + + + + \ No newline at end of file diff --git a/src/views/hr/salary/index.vue b/src/views/hr/salary/index.vue index 591e228..81568b3 100644 --- a/src/views/hr/salary/index.vue +++ b/src/views/hr/salary/index.vue @@ -71,7 +71,7 @@ import { Message } from '@arco-design/web-vue' import type { TableColumnData } from '@arco-design/web-vue' // 搜索表单 -const searchForm = reactive({ +let searchForm = reactive({ userName: '', deptName: '', salaryMonth: '', diff --git a/src/views/hr/salary/insurance/health-records/index.vue b/src/views/hr/salary/insurance/health-records/index.vue new file mode 100644 index 0000000..0e22117 --- /dev/null +++ b/src/views/hr/salary/insurance/health-records/index.vue @@ -0,0 +1,309 @@ + + + + + \ No newline at end of file diff --git a/src/views/hr/salary/insurance/my-insurance/index.vue b/src/views/hr/salary/insurance/my-insurance/index.vue new file mode 100644 index 0000000..2d43a6b --- /dev/null +++ b/src/views/hr/salary/insurance/my-insurance/index.vue @@ -0,0 +1,209 @@ + + + + + \ No newline at end of file diff --git a/src/views/hr/salary/insurance/overview/index.vue b/src/views/hr/salary/insurance/overview/index.vue new file mode 100644 index 0000000..43493c7 --- /dev/null +++ b/src/views/hr/salary/insurance/overview/index.vue @@ -0,0 +1,243 @@ + + + + + \ No newline at end of file diff --git a/src/views/hr/salary/insurance/personal-info/index.vue b/src/views/hr/salary/insurance/personal-info/index.vue new file mode 100644 index 0000000..d901323 --- /dev/null +++ b/src/views/hr/salary/insurance/personal-info/index.vue @@ -0,0 +1,351 @@ + + + + + \ No newline at end of file diff --git a/src/views/hr/salary/insurance/policy-files/index.vue b/src/views/hr/salary/insurance/policy-files/index.vue new file mode 100644 index 0000000..b113b4c --- /dev/null +++ b/src/views/hr/salary/insurance/policy-files/index.vue @@ -0,0 +1,184 @@ + + + + + \ No newline at end of file diff --git a/src/views/hr/salary/system-insurance/company-management/index.vue b/src/views/hr/salary/system-insurance/company-management/index.vue new file mode 100644 index 0000000..9b0beb8 --- /dev/null +++ b/src/views/hr/salary/system-insurance/company-management/index.vue @@ -0,0 +1,507 @@ + + + + + \ No newline at end of file diff --git a/src/views/hr/salary/system-insurance/file-management/index.vue b/src/views/hr/salary/system-insurance/file-management/index.vue new file mode 100644 index 0000000..406b107 --- /dev/null +++ b/src/views/hr/salary/system-insurance/file-management/index.vue @@ -0,0 +1,409 @@ + + + + + \ No newline at end of file diff --git a/src/views/hr/salary/system-insurance/health-management/index.vue b/src/views/hr/salary/system-insurance/health-management/index.vue new file mode 100644 index 0000000..ee65d4f --- /dev/null +++ b/src/views/hr/salary/system-insurance/health-management/index.vue @@ -0,0 +1,516 @@ + + + + + \ No newline at end of file diff --git a/src/views/hr/salary/system-insurance/management/index.vue b/src/views/hr/salary/system-insurance/management/index.vue new file mode 100644 index 0000000..f7f3635 --- /dev/null +++ b/src/views/hr/salary/system-insurance/management/index.vue @@ -0,0 +1,659 @@ + + + + + \ No newline at end of file diff --git a/src/views/hr/salary/system-insurance/overview/index.vue b/src/views/hr/salary/system-insurance/overview/index.vue new file mode 100644 index 0000000..1c868e0 --- /dev/null +++ b/src/views/hr/salary/system-insurance/overview/index.vue @@ -0,0 +1,310 @@ + + + + + \ No newline at end of file diff --git a/src/views/hr/salary/system-insurance/type-management/index.vue b/src/views/hr/salary/system-insurance/type-management/index.vue new file mode 100644 index 0000000..3dfcf4f --- /dev/null +++ b/src/views/hr/salary/system-insurance/type-management/index.vue @@ -0,0 +1,279 @@ + + + + + \ No newline at end of file diff --git a/src/views/hr/workload/index.vue b/src/views/hr/workload/index.vue index 818f4df..010bef6 100644 --- a/src/views/hr/workload/index.vue +++ b/src/views/hr/workload/index.vue @@ -52,7 +52,7 @@ import { Message } from '@arco-design/web-vue' import type { TableColumnData } from '@arco-design/web-vue' // 搜索表单 -const searchForm = reactive({ +let searchForm = reactive({ userName: '', projectName: '', startDate: '', diff --git a/src/views/login/components/account/index.vue b/src/views/login/components/account/index.vue index f7b8f7b..561b0c9 100644 --- a/src/views/login/components/account/index.vue +++ b/src/views/login/components/account/index.vue @@ -108,7 +108,7 @@ const handleLogin = async () => { const { rememberMe } = loginConfig.value loginConfig.value.account = rememberMe ? form.account : '' await router.push({ - path: (redirect as string) || '/', + path: (redirect as string) || '/project-management/projects/initiation', query: { ...othersQuery, }, diff --git a/src/views/login/social/index.vue b/src/views/login/social/index.vue index dd677e8..f7c6a8c 100644 --- a/src/views/login/social/index.vue +++ b/src/views/login/social/index.vue @@ -28,7 +28,7 @@ const handleSocialLogin = () => { .then(() => { tabsStore.reset() router.push({ - path: (redirect as string) || '/', + path: (redirect as string) || '/project-management/bidding/tender-documents', query: { ...othersQuery, }, diff --git a/src/views/operation-platform/data-processing/data-storage/index.vue b/src/views/operation-platform/data-processing/data-storage/index.vue new file mode 100644 index 0000000..e038ba8 --- /dev/null +++ b/src/views/operation-platform/data-processing/data-storage/index.vue @@ -0,0 +1,502 @@ + + + + + \ No newline at end of file diff --git a/src/views/product/hardware/custom-drone/index.vue b/src/views/product/hardware/custom-drone/index.vue index 51e573a..45d7291 100644 --- a/src/views/product/hardware/custom-drone/index.vue +++ b/src/views/product/hardware/custom-drone/index.vue @@ -67,7 +67,7 @@ import { Message } from '@arco-design/web-vue' import type { TableColumnData } from '@arco-design/web-vue' // 搜索表单 -const searchForm = reactive({ +let searchForm = reactive({ droneName: '', model: '', status: '', diff --git a/src/views/product/hardware/tower-monitoring/index.vue b/src/views/product/hardware/tower-monitoring/index.vue index 63a02bb..b20c2da 100644 --- a/src/views/product/hardware/tower-monitoring/index.vue +++ b/src/views/product/hardware/tower-monitoring/index.vue @@ -55,7 +55,7 @@ import { Message } from '@arco-design/web-vue' import type { TableColumnData } from '@arco-design/web-vue' // 搜索表单 -const searchForm = reactive({ +let searchForm = reactive({ deviceName: '', location: '', status: '', diff --git a/src/views/project-management/bidding/award-notice/index.vue b/src/views/project-management/bidding/award-notice/index.vue index 9e2315c..441e409 100644 --- a/src/views/project-management/bidding/award-notice/index.vue +++ b/src/views/project-management/bidding/award-notice/index.vue @@ -67,7 +67,7 @@ import { Message } from '@arco-design/web-vue' import type { TableColumnData } from '@arco-design/web-vue' // 搜索表单 -const searchForm = reactive({ +let searchForm = reactive({ projectName: '', noticeCode: '', sendStatus: '', diff --git a/src/views/project-management/bidding/bid-documents/index.vue b/src/views/project-management/bidding/bid-documents/index.vue index 8ebd588..9a4e8b6 100644 --- a/src/views/project-management/bidding/bid-documents/index.vue +++ b/src/views/project-management/bidding/bid-documents/index.vue @@ -67,7 +67,7 @@ import { Message } from '@arco-design/web-vue' import type { TableColumnData } from '@arco-design/web-vue' // 搜索表单 -const searchForm = reactive({ +let searchForm = reactive({ projectName: '', bidCode: '', status: '', diff --git a/src/views/project-management/bidding/tender-documents/index.vue b/src/views/project-management/bidding/tender-documents/index.vue index ce56429..6cdfb84 100644 --- a/src/views/project-management/bidding/tender-documents/index.vue +++ b/src/views/project-management/bidding/tender-documents/index.vue @@ -67,7 +67,7 @@ import { Message } from '@arco-design/web-vue' import type { TableColumnData } from '@arco-design/web-vue' // 搜索表单 -const searchForm = reactive({ +let searchForm = reactive({ projectName: '', tenderCode: '', status: '', diff --git a/src/views/project-management/contract/cost-management/index.vue b/src/views/project-management/contract/cost-management/index.vue index 3763cf8..1b97c1e 100644 --- a/src/views/project-management/contract/cost-management/index.vue +++ b/src/views/project-management/contract/cost-management/index.vue @@ -83,7 +83,7 @@ import { Message } from '@arco-design/web-vue' import type { TableColumnData } from '@arco-design/web-vue' // 搜索表单 -const searchForm = reactive({ +let searchForm = reactive({ projectName: '', costType: '', costCategory: '', diff --git a/src/views/project-management/contract/expense-contract/index.vue b/src/views/project-management/contract/expense-contract/index.vue index 18a5d8d..871f4c1 100644 --- a/src/views/project-management/contract/expense-contract/index.vue +++ b/src/views/project-management/contract/expense-contract/index.vue @@ -72,7 +72,7 @@ import { Message } from '@arco-design/web-vue' import type { TableColumnData } from '@arco-design/web-vue' // 搜索表单 -const searchForm = reactive({ +let searchForm = reactive({ contractName: '', contractCode: '', supplier: '', diff --git a/src/views/project-management/contract/revenue-contract/index.vue b/src/views/project-management/contract/revenue-contract/index.vue index aac0ba4..6a6c018 100644 --- a/src/views/project-management/contract/revenue-contract/index.vue +++ b/src/views/project-management/contract/revenue-contract/index.vue @@ -72,7 +72,7 @@ import { Message } from '@arco-design/web-vue' import type { TableColumnData } from '@arco-design/web-vue' // 搜索表单 -const searchForm = reactive({ +let searchForm = reactive({ contractName: '', contractCode: '', client: '', diff --git a/src/views/project-management/projects/initiation/index.vue b/src/views/project-management/projects/initiation/index.vue index 4c602fa..c4e48c6 100644 --- a/src/views/project-management/projects/initiation/index.vue +++ b/src/views/project-management/projects/initiation/index.vue @@ -81,7 +81,7 @@ import { Message } from '@arco-design/web-vue' import type { TableColumnData } from '@arco-design/web-vue' // 搜索表单 -const searchForm = reactive({ +let searchForm = reactive({ projectName: '', projectCode: '', projectType: '', diff --git a/src/views/project-management/projects/list/components/ProjectTable.vue b/src/views/project-management/projects/list/components/ProjectTable.vue new file mode 100644 index 0000000..14630d4 --- /dev/null +++ b/src/views/project-management/projects/list/components/ProjectTable.vue @@ -0,0 +1,329 @@ + + + + + \ No newline at end of file diff --git a/src/views/project-management/projects/list/index.vue b/src/views/project-management/projects/list/index.vue new file mode 100644 index 0000000..d014238 --- /dev/null +++ b/src/views/project-management/projects/list/index.vue @@ -0,0 +1,268 @@ + + + + + \ No newline at end of file diff --git a/src/views/project-management/projects/list/types.ts b/src/views/project-management/projects/list/types.ts new file mode 100644 index 0000000..28e1665 --- /dev/null +++ b/src/views/project-management/projects/list/types.ts @@ -0,0 +1,46 @@ +// 项目状态枚举 +export enum ProjectStatus { + NOT_STARTED = 'not_started', + IN_PROGRESS = 'in_progress', + COMPLETED = 'completed', + PAUSED = 'paused', + CANCELLED = 'cancelled' +} + +// 项目数据接口 +export interface ProjectData { + id: number + projectName: string + unitCount: number + startDate: string + endDate: string + status: ProjectStatus + progress: number + manager: string + isMyProject: boolean + description?: string + location?: string + client?: string + budget?: number + team?: string[] +} + +// 选项卡类型 +export type TabKey = 'all' | 'my' | 'pending' + +// 项目筛选条件 +export interface ProjectFilter { + keyword?: string + status?: ProjectStatus + manager?: string + dateRange?: [string, string] +} + +// 项目统计信息 +export interface ProjectStats { + total: number + inProgress: number + completed: number + notStarted: number + myProjects: number +} \ No newline at end of file diff --git a/src/views/project-management/projects/management/index.vue b/src/views/project-management/projects/management/index.vue index 394035f..caab495 100644 --- a/src/views/project-management/projects/management/index.vue +++ b/src/views/project-management/projects/management/index.vue @@ -103,7 +103,7 @@ import { Message } from '@arco-design/web-vue' import type { TableColumnData } from '@arco-design/web-vue' // 搜索表单 -const searchForm = reactive({ +let searchForm = reactive({ projectName: '', projectCode: '', status: '', diff --git a/src/views/project-management/projects/personnel-distribution/index.vue b/src/views/project-management/projects/personnel-distribution/index.vue new file mode 100644 index 0000000..f549f6e --- /dev/null +++ b/src/views/project-management/projects/personnel-distribution/index.vue @@ -0,0 +1,423 @@ + + + + + \ No newline at end of file diff --git a/src/views/project-management/projects/progress/index.vue b/src/views/project-management/projects/progress/index.vue new file mode 100644 index 0000000..812e92c --- /dev/null +++ b/src/views/project-management/projects/progress/index.vue @@ -0,0 +1,476 @@ + + + + + \ No newline at end of file diff --git a/src/views/project-management/projects/quality/components/QualityMeetingModal.vue b/src/views/project-management/projects/quality/components/QualityMeetingModal.vue new file mode 100644 index 0000000..cfd5621 --- /dev/null +++ b/src/views/project-management/projects/quality/components/QualityMeetingModal.vue @@ -0,0 +1,278 @@ + + + + + \ No newline at end of file diff --git a/src/views/project-management/projects/quality/index.vue b/src/views/project-management/projects/quality/index.vue new file mode 100644 index 0000000..521441d --- /dev/null +++ b/src/views/project-management/projects/quality/index.vue @@ -0,0 +1,501 @@ + + + + + \ No newline at end of file diff --git a/src/views/project-management/projects/safety/components/SafetyMeetingModal.vue b/src/views/project-management/projects/safety/components/SafetyMeetingModal.vue new file mode 100644 index 0000000..4745131 --- /dev/null +++ b/src/views/project-management/projects/safety/components/SafetyMeetingModal.vue @@ -0,0 +1,278 @@ + + + + + \ No newline at end of file diff --git a/src/views/project-management/projects/safety/index.vue b/src/views/project-management/projects/safety/index.vue new file mode 100644 index 0000000..9bd0733 --- /dev/null +++ b/src/views/project-management/projects/safety/index.vue @@ -0,0 +1,505 @@ + + + + + \ No newline at end of file diff --git a/src/views/project-operation-platform/data-analysis/index.vue b/src/views/project-operation-platform/data-analysis/index.vue new file mode 100644 index 0000000..6163ea2 --- /dev/null +++ b/src/views/project-operation-platform/data-analysis/index.vue @@ -0,0 +1,17 @@ + + + + + diff --git a/src/views/project-operation-platform/data-processing/3d-model/index.vue b/src/views/project-operation-platform/data-processing/3d-model/index.vue new file mode 100644 index 0000000..ec7ccf8 --- /dev/null +++ b/src/views/project-operation-platform/data-processing/3d-model/index.vue @@ -0,0 +1,569 @@ + + + + + \ No newline at end of file diff --git a/src/views/project-operation-platform/data-processing/clearance-detection/index.vue b/src/views/project-operation-platform/data-processing/clearance-detection/index.vue new file mode 100644 index 0000000..8678cf6 --- /dev/null +++ b/src/views/project-operation-platform/data-processing/clearance-detection/index.vue @@ -0,0 +1,298 @@ + + + + + \ No newline at end of file diff --git a/src/views/project-operation-platform/data-processing/data-quality-assessment/index.vue b/src/views/project-operation-platform/data-processing/data-quality-assessment/index.vue new file mode 100644 index 0000000..0d8b739 --- /dev/null +++ b/src/views/project-operation-platform/data-processing/data-quality-assessment/index.vue @@ -0,0 +1,418 @@ + + + + + \ No newline at end of file diff --git a/src/views/project-operation-platform/data-processing/data-storage/index.vue b/src/views/project-operation-platform/data-processing/data-storage/index.vue new file mode 100644 index 0000000..7bb5dcc --- /dev/null +++ b/src/views/project-operation-platform/data-processing/data-storage/index.vue @@ -0,0 +1,17 @@ + + + + + \ No newline at end of file diff --git a/src/views/project-operation-platform/data-processing/defect-identification/index.vue b/src/views/project-operation-platform/data-processing/defect-identification/index.vue new file mode 100644 index 0000000..efa0454 --- /dev/null +++ b/src/views/project-operation-platform/data-processing/defect-identification/index.vue @@ -0,0 +1,17 @@ + + + + + diff --git a/src/views/project-operation-platform/data-processing/deformation-detection/index.vue b/src/views/project-operation-platform/data-processing/deformation-detection/index.vue new file mode 100644 index 0000000..d57f3e6 --- /dev/null +++ b/src/views/project-operation-platform/data-processing/deformation-detection/index.vue @@ -0,0 +1,311 @@ + + + + + \ No newline at end of file diff --git a/src/views/project-operation-platform/data-processing/industrial-image/components/DefectDetailsPanel.vue b/src/views/project-operation-platform/data-processing/industrial-image/components/DefectDetailsPanel.vue new file mode 100644 index 0000000..6143b9a --- /dev/null +++ b/src/views/project-operation-platform/data-processing/industrial-image/components/DefectDetailsPanel.vue @@ -0,0 +1,647 @@ + + + + + \ No newline at end of file diff --git a/src/views/project-operation-platform/data-processing/industrial-image/components/DefectListPanel.vue b/src/views/project-operation-platform/data-processing/industrial-image/components/DefectListPanel.vue new file mode 100644 index 0000000..f6dc18c --- /dev/null +++ b/src/views/project-operation-platform/data-processing/industrial-image/components/DefectListPanel.vue @@ -0,0 +1,313 @@ + + + + + \ No newline at end of file diff --git a/src/views/project-operation-platform/data-processing/industrial-image/components/HeaderToolbar.vue b/src/views/project-operation-platform/data-processing/industrial-image/components/HeaderToolbar.vue new file mode 100644 index 0000000..403bad7 --- /dev/null +++ b/src/views/project-operation-platform/data-processing/industrial-image/components/HeaderToolbar.vue @@ -0,0 +1,96 @@ + + + + + \ No newline at end of file diff --git a/src/views/project-operation-platform/data-processing/industrial-image/components/ImageCanvas.vue b/src/views/project-operation-platform/data-processing/industrial-image/components/ImageCanvas.vue new file mode 100644 index 0000000..f5ab152 --- /dev/null +++ b/src/views/project-operation-platform/data-processing/industrial-image/components/ImageCanvas.vue @@ -0,0 +1,579 @@ + + + + + \ No newline at end of file diff --git a/src/views/project-operation-platform/data-processing/industrial-image/components/ImagePreview.vue b/src/views/project-operation-platform/data-processing/industrial-image/components/ImagePreview.vue new file mode 100644 index 0000000..7c3e9f8 --- /dev/null +++ b/src/views/project-operation-platform/data-processing/industrial-image/components/ImagePreview.vue @@ -0,0 +1,359 @@ + + + + + \ No newline at end of file diff --git a/src/views/project-operation-platform/data-processing/industrial-image/components/ProjectTree.vue b/src/views/project-operation-platform/data-processing/industrial-image/components/ProjectTree.vue new file mode 100644 index 0000000..d58e5cd --- /dev/null +++ b/src/views/project-operation-platform/data-processing/industrial-image/components/ProjectTree.vue @@ -0,0 +1,139 @@ + + + + + \ No newline at end of file diff --git a/src/views/project-operation-platform/data-processing/industrial-image/components/RecognitionResults.vue b/src/views/project-operation-platform/data-processing/industrial-image/components/RecognitionResults.vue new file mode 100644 index 0000000..0bfeb56 --- /dev/null +++ b/src/views/project-operation-platform/data-processing/industrial-image/components/RecognitionResults.vue @@ -0,0 +1,401 @@ + + + + + \ No newline at end of file diff --git a/src/views/project-operation-platform/data-processing/industrial-image/components/ReportGenerationModal.vue b/src/views/project-operation-platform/data-processing/industrial-image/components/ReportGenerationModal.vue new file mode 100644 index 0000000..2c2d6d0 --- /dev/null +++ b/src/views/project-operation-platform/data-processing/industrial-image/components/ReportGenerationModal.vue @@ -0,0 +1,487 @@ + + + + + \ No newline at end of file diff --git a/src/views/project-operation-platform/data-processing/key-info-extraction/index.vue b/src/views/project-operation-platform/data-processing/key-info-extraction/index.vue new file mode 100644 index 0000000..589a879 --- /dev/null +++ b/src/views/project-operation-platform/data-processing/key-info-extraction/index.vue @@ -0,0 +1,17 @@ + + + + + diff --git a/src/views/project-operation-platform/data-processing/report-generation/index.vue b/src/views/project-operation-platform/data-processing/report-generation/index.vue new file mode 100644 index 0000000..4532556 --- /dev/null +++ b/src/views/project-operation-platform/data-processing/report-generation/index.vue @@ -0,0 +1,315 @@ + + + + + diff --git a/src/views/project-operation-platform/data-processing/report-review/index.vue b/src/views/project-operation-platform/data-processing/report-review/index.vue new file mode 100644 index 0000000..cc9a2fb --- /dev/null +++ b/src/views/project-operation-platform/data-processing/report-review/index.vue @@ -0,0 +1,17 @@ + + + + + diff --git a/src/views/project-operation-platform/data-processing/report-template/index.vue b/src/views/project-operation-platform/data-processing/report-template/index.vue new file mode 100644 index 0000000..c50cced --- /dev/null +++ b/src/views/project-operation-platform/data-processing/report-template/index.vue @@ -0,0 +1,447 @@ + + + + + diff --git a/src/views/project-operation-platform/data-processing/standard-info/index.vue b/src/views/project-operation-platform/data-processing/standard-info/index.vue new file mode 100644 index 0000000..2b8c1bb --- /dev/null +++ b/src/views/project-operation-platform/data-processing/standard-info/index.vue @@ -0,0 +1,425 @@ + + + + + \ No newline at end of file diff --git a/src/views/project-operation-platform/data-processing/voice-to-text/index.vue b/src/views/project-operation-platform/data-processing/voice-to-text/index.vue new file mode 100644 index 0000000..6eb533a --- /dev/null +++ b/src/views/project-operation-platform/data-processing/voice-to-text/index.vue @@ -0,0 +1,17 @@ + + + + + diff --git a/src/views/project-operation-platform/data-processing/wide-angle-video/index.vue b/src/views/project-operation-platform/data-processing/wide-angle-video/index.vue new file mode 100644 index 0000000..5a2d2d2 --- /dev/null +++ b/src/views/project-operation-platform/data-processing/wide-angle-video/index.vue @@ -0,0 +1,17 @@ + + + + + diff --git a/src/views/project-operation-platform/defect-tracking/index.vue b/src/views/project-operation-platform/defect-tracking/index.vue new file mode 100644 index 0000000..bf94c9c --- /dev/null +++ b/src/views/project-operation-platform/defect-tracking/index.vue @@ -0,0 +1,17 @@ + + + + + diff --git a/src/views/project-operation-platform/implementation-workflow/field-construction/project-list/index.vue b/src/views/project-operation-platform/implementation-workflow/field-construction/project-list/index.vue new file mode 100644 index 0000000..97c140b --- /dev/null +++ b/src/views/project-operation-platform/implementation-workflow/field-construction/project-list/index.vue @@ -0,0 +1,17 @@ + + + + + \ No newline at end of file diff --git a/src/views/project-operation-platform/lifecycle-management/index.vue b/src/views/project-operation-platform/lifecycle-management/index.vue new file mode 100644 index 0000000..561c7e4 --- /dev/null +++ b/src/views/project-operation-platform/lifecycle-management/index.vue @@ -0,0 +1,17 @@ + + + + + diff --git a/src/views/project-operation-platform/project-initiation/index.vue b/src/views/project-operation-platform/project-initiation/index.vue new file mode 100644 index 0000000..baccbd7 --- /dev/null +++ b/src/views/project-operation-platform/project-initiation/index.vue @@ -0,0 +1,17 @@ + + + + + \ No newline at end of file diff --git a/src/views/project-operation-platform/quality-management/data-quality/index.vue b/src/views/project-operation-platform/quality-management/data-quality/index.vue new file mode 100644 index 0000000..1c3d77f --- /dev/null +++ b/src/views/project-operation-platform/quality-management/data-quality/index.vue @@ -0,0 +1,17 @@ + + + + + diff --git a/src/views/project-operation-platform/quality-management/defect-storage/index.vue b/src/views/project-operation-platform/quality-management/defect-storage/index.vue new file mode 100644 index 0000000..813d233 --- /dev/null +++ b/src/views/project-operation-platform/quality-management/defect-storage/index.vue @@ -0,0 +1,17 @@ + + + + + diff --git a/src/views/project-operation-platform/quality-management/process-verification/index.vue b/src/views/project-operation-platform/quality-management/process-verification/index.vue new file mode 100644 index 0000000..06a5e53 --- /dev/null +++ b/src/views/project-operation-platform/quality-management/process-verification/index.vue @@ -0,0 +1,387 @@ + + + + + diff --git a/src/views/project-operation-platform/route-planning/index.vue b/src/views/project-operation-platform/route-planning/index.vue new file mode 100644 index 0000000..96f1904 --- /dev/null +++ b/src/views/project-operation-platform/route-planning/index.vue @@ -0,0 +1,629 @@ + + + + + diff --git a/src/views/project/budget/index.vue b/src/views/project/budget/index.vue index 857fcf7..a81792b 100644 --- a/src/views/project/budget/index.vue +++ b/src/views/project/budget/index.vue @@ -118,7 +118,7 @@ import BudgetAuditModal from './components/BudgetAuditModal.vue' import BudgetDetailModal from './components/BudgetDetailModal.vue' // 搜索表单 -const searchForm = reactive({ +let searchForm = reactive({ projectName: '', projectCode: '', auditStatus: '', diff --git a/src/views/project/detail/index.vue b/src/views/project/detail/index.vue index 85c972f..f5e0435 100644 --- a/src/views/project/detail/index.vue +++ b/src/views/project/detail/index.vue @@ -379,7 +379,7 @@ const fetchTaskData = async () => { } const goBack = () => { - router.push('/project') + router.push('/project-management/legacy/list') } const editProject = () => { @@ -398,7 +398,7 @@ const deleteProjectItem = async () => { try { await deleteProject(projectId.value) Message.success('删除成功') - router.push('/project') + router.push('/project-management/legacy/list') } catch (error) { console.error(error) Message.error('删除失败') diff --git a/src/views/project/index.vue b/src/views/project/index.vue index b9cbb7a..a5a3f5a 100644 --- a/src/views/project/index.vue +++ b/src/views/project/index.vue @@ -44,7 +44,7 @@ @@ -60,45 +56,21 @@ - - - - - - - - - + + + @@ -106,13 +78,13 @@ import { ref, reactive, onMounted } from 'vue' import { Message } from '@arco-design/web-vue' import type { TableColumnData } from '@arco-design/web-vue' +import DeviceAddModal from './components/DeviceAddModal.vue' // 搜索表单 -const searchForm = reactive({ - deviceName: '', +let searchForm = reactive({ + projectName: '', deviceType: '', status: '', - location: '', page: 1, size: 10 }) @@ -120,11 +92,17 @@ const searchForm = reactive({ // 查询条件配置 const queryFormColumns = [ { - field: 'deviceName', - label: '设备名称', - type: 'input' as const, + field: 'projectName', + label: '项目选择', + type: 'select' as const, props: { - placeholder: '请输入设备名称' + placeholder: '请选择项目', + options: [ + { label: '风电塔下检测项目', value: '风电塔下检测项目' }, + { label: '叶片维修项目', value: '叶片维修项目' }, + { label: '防雷检测项目', value: '防雷检测项目' }, + { label: '太阳能巡检项目', value: '太阳能巡检项目' } + ] } }, { @@ -134,12 +112,9 @@ const queryFormColumns = [ props: { placeholder: '请选择设备类型', options: [ - { label: '服务器', value: '服务器' }, - { label: '交换机', value: '交换机' }, - { label: '路由器', value: '路由器' }, - { label: '存储设备', value: '存储设备' }, - { label: '防火墙', value: '防火墙' }, - { label: '打印机', value: '打印机' } + { label: '检测设备', value: '检测设备' }, + { label: '安全设备', value: '安全设备' }, + { label: '车辆', value: '车辆' } ] } }, @@ -150,119 +125,86 @@ const queryFormColumns = [ props: { placeholder: '请选择设备状态', options: [ - { label: '在线', value: 'online' }, - { label: '离线', value: 'offline' }, - { label: '维护中', value: 'maintenance' }, - { label: '故障', value: 'error' } + { label: '使用中', value: 'using' }, + { label: '可用', value: 'available' }, + { label: '维修中', value: 'maintenance' } ] } - }, - { - field: 'location', - label: '位置', - type: 'input' as const, - props: { - placeholder: '请输入位置信息' - } } ] // 表格列配置 const tableColumns: TableColumnData[] = [ - { title: '设备编号', dataIndex: 'deviceCode', width: 120 }, { title: '设备名称', dataIndex: 'deviceName', width: 150 }, { title: '设备类型', dataIndex: 'deviceType', slotName: 'deviceType', width: 120 }, - { title: 'IP地址', dataIndex: 'ipAddress', width: 130 }, - { title: 'MAC地址', dataIndex: 'macAddress', width: 150 }, - { title: '设备状态', dataIndex: 'status', slotName: 'status', width: 130 }, - { title: '健康状况', dataIndex: 'healthStatus', slotName: 'healthStatus', width: 100 }, - { title: '负载率', dataIndex: 'loadRate', slotName: 'loadRate', width: 120 }, - { title: '位置', dataIndex: 'location', slotName: 'location', width: 150 }, - { title: '负责人', dataIndex: 'manager', width: 100 }, - { title: '最后维护', dataIndex: 'lastMaintenance', width: 120 }, - { title: '采购日期', dataIndex: 'purchaseDate', width: 120 }, - { title: '保修期至', dataIndex: 'warrantyUntil', width: 120 }, - { title: '备注', dataIndex: 'remark', width: 200, ellipsis: true, tooltip: true }, - { title: '操作', slotName: 'action', width: 200, fixed: 'right' } + { title: '型号', dataIndex: 'model', width: 120 }, + { title: '序列号', dataIndex: 'serialNumber', width: 150 }, + { title: '状态', dataIndex: 'status', slotName: 'status', width: 120 }, + { title: '当前使用人', dataIndex: 'currentUser', width: 100 }, + { title: '所属项目', dataIndex: 'projectName', width: 150 }, + { title: '操作', slotName: 'action', width: 150, fixed: 'right' } ] // 数据状态 const loading = ref(false) +const addModalVisible = ref(false) const dataList = ref([ { id: 1, - deviceCode: 'SRV-001', - deviceName: '主服务器-01', - deviceType: '服务器', - ipAddress: '192.168.1.10', - macAddress: '00:1B:21:3C:4D:5E', - status: 'online', - healthStatus: '良好', - loadRate: 65, - location: { building: 'A栋', room: '机房101' }, - manager: '张工程师', - lastMaintenance: '2024-03-01', - purchaseDate: '2023-01-15', - warrantyUntil: '2026-01-15', - remark: '核心业务服务器,24小时运行' + deviceName: '红外热像仪', + deviceType: '检测设备', + model: 'FLIR T1020', + serialNumber: 'IR20230001', + status: 'using', + currentUser: '李四', + projectName: '风电塔下检测项目' }, { id: 2, - deviceCode: 'SW-001', - deviceName: '核心交换机', - deviceType: '交换机', - ipAddress: '192.168.1.1', - macAddress: '00:1B:21:3C:4D:5F', - status: 'online', - healthStatus: '良好', - loadRate: 45, - location: { building: 'A栋', room: '机房101' }, - manager: '李工程师', - lastMaintenance: '2024-02-15', - purchaseDate: '2023-03-20', - warrantyUntil: '2026-03-20', - remark: '网络核心设备' + deviceName: '安全信号装置', + deviceType: '安全设备', + model: '3M DBI-SALA', + serialNumber: 'SA20230001', + status: 'using', + currentUser: '李四', + projectName: '风电塔下检测项目' }, { id: 3, - deviceCode: 'FW-001', - deviceName: '主防火墙', - deviceType: '防火墙', - ipAddress: '192.168.1.254', - macAddress: '00:1B:21:3C:4D:60', - status: 'maintenance', - healthStatus: '注意', - loadRate: 80, - location: { building: 'A栋', room: '机房101' }, - manager: '王工程师', - lastMaintenance: '2024-03-10', - purchaseDate: '2023-05-10', - warrantyUntil: '2026-05-10', - remark: '安全防护设备,需要定期更新规则' + deviceName: '叶片内窥镜', + deviceType: '检测设备', + model: 'Olympus IPLEX GX/GT', + serialNumber: 'EN20230001', + status: 'available', + currentUser: '', + projectName: '叶片维修项目' }, { id: 4, - deviceCode: 'STO-001', - deviceName: '存储阵列-01', - deviceType: '存储设备', - ipAddress: '192.168.1.20', - macAddress: '00:1B:21:3C:4D:61', - status: 'offline', - healthStatus: '故障', - loadRate: 0, - location: { building: 'A栋', room: '机房102' }, - manager: '赵工程师', - lastMaintenance: '2024-01-20', - purchaseDate: '2023-08-01', - warrantyUntil: '2026-08-01', - remark: '主存储设备,目前离线维修中' + deviceName: '防雷测试仪', + deviceType: '检测设备', + model: 'FLUKE 1653', + serialNumber: 'LT20230001', + status: 'using', + currentUser: '王五', + projectName: '叶片维修项目' + }, + { + id: 5, + deviceName: '高空作业车', + deviceType: '车辆', + model: 'JLG 600S', + serialNumber: 'HV20230001', + status: 'maintenance', + currentUser: '', + projectName: '太阳能巡检项目' } ]) const pagination = reactive({ current: 1, pageSize: 10, - total: 4, + total: 5, showTotal: true, showPageSize: true }) @@ -270,12 +212,9 @@ const pagination = reactive({ // 获取设备类型颜色 const getDeviceTypeColor = (type: string) => { const colorMap: Record = { - '服务器': 'blue', - '交换机': 'green', - '路由器': 'cyan', - '存储设备': 'purple', - '防火墙': 'red', - '打印机': 'orange' + '检测设备': 'blue', + '安全设备': 'green', + '车辆': 'orange' } return colorMap[type] || 'gray' } @@ -283,10 +222,9 @@ const getDeviceTypeColor = (type: string) => { // 获取状态颜色 const getStatusColor = (status: string) => { const colorMap: Record = { - 'online': 'green', - 'offline': 'red', - 'maintenance': 'orange', - 'error': 'red' + 'using': 'blue', + 'available': 'green', + 'maintenance': 'orange' } return colorMap[status] || 'gray' } @@ -294,10 +232,9 @@ const getStatusColor = (status: string) => { // 获取状态文本 const getStatusText = (status: string) => { const textMap: Record = { - 'online': '在线', - 'offline': '离线', - 'maintenance': '维护中', - 'error': '故障' + 'using': '使用中', + 'available': '可用', + 'maintenance': '维修中' } return textMap[status] || status } @@ -305,35 +242,17 @@ const getStatusText = (status: string) => { // 获取状态点样式 const getStatusDotClass = (status: string) => { const classMap: Record = { - 'online': 'online-dot', - 'offline': 'offline-dot', - 'maintenance': 'maintenance-dot', - 'error': 'error-dot' + 'using': 'using-dot', + 'available': 'available-dot', + 'maintenance': 'maintenance-dot' } - return classMap[status] || 'offline-dot' -} - -// 获取健康状况颜色 -const getHealthColor = (health: string) => { - const colorMap: Record = { - '良好': 'green', - '注意': 'orange', - '故障': 'red', - '未知': 'gray' - } - return colorMap[health] || 'gray' -} - -// 获取负载颜色 -const getLoadColor = (load: number) => { - if (load >= 80) return '#ff4d4f' - if (load >= 60) return '#faad14' - return '#52c41a' + return classMap[status] || 'available-dot' } // 搜索和重置 const search = async () => { loading.value = true + // 这里应该调用API获取数据 setTimeout(() => { loading.value = false }, 1000) @@ -341,10 +260,9 @@ const search = async () => { const reset = () => { Object.assign(searchForm, { - deviceName: '', + projectName: '', deviceType: '', status: '', - location: '', page: 1, size: 10 }) @@ -369,11 +287,11 @@ const onPageSizeChange = (size: number) => { // 操作方法 const openAddModal = () => { - Message.info('新增设备功能开发中...') + addModalVisible.value = true } -const batchImport = () => { - Message.info('批量导入功能开发中...') +const handleAddSuccess = () => { + search() // 重新加载数据 } const exportData = () => { @@ -388,24 +306,8 @@ const editRecord = (record: any) => { Message.info(`编辑设备: ${record.deviceName}`) } -const remoteControl = (record: any) => { - Message.info(`远程控制: ${record.deviceName}`) -} - -const viewMonitoring = (record: any) => { - Message.info(`设备监控: ${record.deviceName}`) -} - -const deviceMaintenance = (record: any) => { - Message.info(`设备维护: ${record.deviceName}`) -} - -const powerControl = (record: any) => { - Message.info(`电源控制: ${record.deviceName}`) -} - -const deleteRecord = (record: any) => { - Message.info(`删除设备: ${record.deviceName}`) +const returnDevice = (record: any) => { + Message.info(`归还设备: ${record.deviceName}`) } onMounted(() => { @@ -421,19 +323,15 @@ onMounted(() => { display: inline-block; } -.online-dot { - background-color: #52c41a; +.using-dot { + background-color: #1890ff; } -.offline-dot { - background-color: #d9d9d9; +.available-dot { + background-color: #52c41a; } .maintenance-dot { background-color: #faad14; } - -.error-dot { - background-color: #ff4d4f; -} \ No newline at end of file diff --git a/src/views/system-resource/information-system/software-management/index.vue b/src/views/system-resource/information-system/software-management/index.vue index 79539ed..a52537d 100644 --- a/src/views/system-resource/information-system/software-management/index.vue +++ b/src/views/system-resource/information-system/software-management/index.vue @@ -101,7 +101,7 @@ import { Message } from '@arco-design/web-vue' import type { TableColumnData } from '@arco-design/web-vue' // 搜索表单 -const searchForm = reactive({ +let searchForm = reactive({ softwareName: '', softwareType: '', status: '', diff --git a/src/views/system/role/RoleAddDrawer.vue b/src/views/system/role/RoleAddDrawer.vue index 4149a3a..f3ea6e2 100644 --- a/src/views/system/role/RoleAddDrawer.vue +++ b/src/views/system/role/RoleAddDrawer.vue @@ -12,13 +12,13 @@
基础信息 - + - + - + diff --git a/src/views/system/user/UserAddDrawer.vue b/src/views/system/user/UserAddDrawer.vue index 5618565..addf87d 100644 --- a/src/views/system/user/UserAddDrawer.vue +++ b/src/views/system/user/UserAddDrawer.vue @@ -285,6 +285,21 @@ const columns: ColumnItem[] = reactive([ uncheckedText: '禁用', }, }, + { + label: '资质名称', + type: 'input', + field: 'certificationName', + span: 12, + }, + { + label: '有效期', + field: 'certificationExpireDate', + span: 12, + type: 'date-picker', + props: { + valueFormat: 'YYYY-MM-DD', + }, + }, ]) // 重置 diff --git a/src/views/test-import-wizard/index.vue b/src/views/test-import-wizard/index.vue new file mode 100644 index 0000000..b8e9c9d --- /dev/null +++ b/src/views/test-import-wizard/index.vue @@ -0,0 +1,279 @@ + + + + + \ No newline at end of file