From 2feea5fd8f3a26e029131de18bf4d3f0e8d413bb Mon Sep 17 00:00:00 2001 From: "Mr.j" <2221464500@qq.com> Date: Thu, 14 Aug 2025 15:22:55 +0800 Subject: [PATCH 01/10] =?UTF-8?q?=E5=AE=8C=E5=96=84=E6=94=B6=E8=B4=A7?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E9=9A=8F=E7=9D=80=E6=B5=81=E7=A8=8B=E5=8F=98?= =?UTF-8?q?=E5=8C=96=EF=BC=8C=E7=A1=AE=E4=BF=9D=E5=9C=A8=E9=87=87=E8=B4=AD?= =?UTF-8?q?=E5=AE=A1=E6=89=B9=E5=90=8E=E9=80=9A=E8=BF=87=E5=90=8E=E6=89=8D?= =?UTF-8?q?=E5=87=BA=E7=8E=B0=E6=94=B6=E8=B4=A7=E7=8A=B6=E6=80=81,?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=94=AF=E4=BB=98=E7=8A=B6=E6=80=81=E5=92=8C?= =?UTF-8?q?=E6=94=B6=E8=8E=B7=E7=8A=B6=E6=80=81=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/equipment/type.ts | 1 + .../components/ProcurementModal.vue | 54 ++++++- .../procurement/components/ReceiptModal.vue | 139 +++++++++++------- .../device-management/procurement/index.vue | 110 ++++++++++++-- 4 files changed, 233 insertions(+), 71 deletions(-) diff --git a/src/apis/equipment/type.ts b/src/apis/equipment/type.ts index f9bf6d9..1e2403f 100644 --- a/src/apis/equipment/type.ts +++ b/src/apis/equipment/type.ts @@ -457,6 +457,7 @@ export interface ReceiptRequest { useStatus?: string healthStatus?: string receiptStatus?: string + paymentStatus?: string // 其他管理信息 depreciationMethod?: string diff --git a/src/views/system-resource/device-management/procurement/components/ProcurementModal.vue b/src/views/system-resource/device-management/procurement/components/ProcurementModal.vue index 260162c..a84a405 100644 --- a/src/views/system-resource/device-management/procurement/components/ProcurementModal.vue +++ b/src/views/system-resource/device-management/procurement/components/ProcurementModal.vue @@ -87,11 +87,15 @@ + + + 选择设备类型后自动生成,格式:设备类型+顺序号+日期 + @@ -528,6 +532,7 @@ import { Message } from '@arco-design/web-vue' import type { FormInstance } from '@arco-design/web-vue' import { equipmentProcurementApi } from '@/apis/equipment/procurement' import type { EquipmentResp, EquipmentReq } from '@/apis/equipment/type' +import { IconInfoCircle } from '@arco-design/web-vue/es/icon' interface Props { visible: boolean @@ -692,6 +697,40 @@ watch([() => formData.unitPrice, () => formData.quantity], ([newUnitPrice, newQu } }) +// 生成设备序列号 +const generateEquipmentSn = (equipmentType: string) => { + // 获取当前时间戳作为顺序号 + const timestamp = Date.now() + const orderNumber = timestamp.toString().slice(-6) // 取后6位作为顺序号 + + // 获取设备类型简称 + const typeMap: Record = { + 'detection': 'DET', + 'security': 'SEC', + 'office': 'OFF', + 'car': 'CAR', + 'other': 'OTH' + } + const typeCode = typeMap[equipmentType] || 'OTH' + + // 格式化当前时间(年月日) + const now = new Date() + const dateStr = now.getFullYear().toString().slice(-2) + + (now.getMonth() + 1).toString().padStart(2, '0') + + now.getDate().toString().padStart(2, '0') + + // 生成序列号:设备类型+顺序号+当前时间 + return `${typeCode}${orderNumber}${dateStr}` +} + +// 监听设备类型变化,自动生成序列号 +watch(() => formData.equipmentType, (newType) => { + if (newType && !formData.equipmentSn) { + // 只有在序列号为空时才自动生成 + formData.equipmentSn = generateEquipmentSn(newType) + } +}) + // 初始化表单数据 const initFormData = () => { if (props.procurementData) { @@ -841,7 +880,7 @@ const fillTestData = () => { const nextMaintenanceTime = nextMaintenanceDate.toISOString().slice(0, 19).replace('T', ' ') // 生成随机序列号 - const randomSn = 'SN' + Math.random().toString(36).substr(2, 8).toUpperCase() + const randomSn = generateEquipmentSn('detection') // 生成随机资产编号 const randomAssetCode = 'ZC' + Math.random().toString(36).substr(2, 6).toUpperCase() @@ -949,6 +988,15 @@ const handleCancel = () => { color: var(--color-text-1); margin-bottom: 8px; } + + .field-tip { + margin-top: 4px; + font-size: 12px; + color: var(--color-text-3); + display: flex; + align-items: center; + line-height: 1.4; + } } .arco-input, diff --git a/src/views/system-resource/device-management/procurement/components/ReceiptModal.vue b/src/views/system-resource/device-management/procurement/components/ReceiptModal.vue index 17ebc74..11264ca 100644 --- a/src/views/system-resource/device-management/procurement/components/ReceiptModal.vue +++ b/src/views/system-resource/device-management/procurement/components/ReceiptModal.vue @@ -27,9 +27,15 @@ {{ equipmentData?.equipmentModel || '-' }} + + {{ equipmentData?.equipmentSn || '-' }} + {{ equipmentData?.brand || '-' }} + + {{ equipmentData?.specification || '-' }} + {{ equipmentData?.supplierName || '-' }} @@ -370,6 +376,32 @@ watch(() => props.equipmentData, () => { } }, { deep: true }) +// 生成设备序列号 +const generateEquipmentSn = (equipmentType: string, inStockTime: string) => { + // 获取当前时间戳作为顺序号 + const timestamp = Date.now() + const orderNumber = timestamp.toString().slice(-6) // 取后6位作为顺序号 + + // 获取设备类型简称 + const typeMap: Record = { + 'detection': 'DET', + 'security': 'SEC', + 'office': 'OFF', + 'car': 'CAR', + 'other': 'OTH' + } + const typeCode = typeMap[equipmentType] || 'OTH' + + // 格式化入库时间(年月日) + const date = new Date(inStockTime) + const dateStr = date.getFullYear().toString().slice(-2) + + (date.getMonth() + 1).toString().padStart(2, '0') + + date.getDate().toString().padStart(2, '0') + + // 生成序列号:设备类型+顺序号+入库时间 + return `${typeCode}${orderNumber}${dateStr}` +} + // 提交表单 const handleSubmit = async () => { try { @@ -380,13 +412,37 @@ const handleSubmit = async () => { throw new Error('设备ID不能为空') } - console.log('📦 开始提交收货数据...') - console.log('📦 设备数据:', props.equipmentData) - console.log('📦 表单数据:', formData) - - // 构建收货请求数据 - const receiptData: ReceiptRequest = { - // 收货特有信息 + // 1. 获取采购阶段的设备信息 + const procurementData = props.equipmentData + + // 2. 生成设备序列号 + const equipmentSn = generateEquipmentSn( + procurementData.equipmentType || 'other', + formData.receiptTime || new Date().toISOString() + ) + + // 3. 合并收货信息和设备信息 + const equipmentData = { + // 采购阶段的数据(已有) + equipmentId: procurementData.equipmentId, + equipmentName: procurementData.equipmentName, + equipmentModel: procurementData.equipmentModel, + equipmentType: procurementData.equipmentType, + equipmentSn: equipmentSn, // 使用生成的序列号 + brand: procurementData.brand, + specification: procurementData.specification, + assetCode: procurementData.assetCode, + + // 采购信息(已有) + purchaseOrder: procurementData.purchaseOrder, + supplierName: procurementData.supplierName, + purchasePrice: procurementData.purchasePrice, + purchaseTime: procurementData.purchaseTime, + quantity: procurementData.quantity, + unitPrice: procurementData.unitPrice, + totalPrice: procurementData.totalPrice, + + // 收货相关信息 receiptTime: formData.receiptTime ? formatDateTime(formData.receiptTime) : formatDateTime(new Date()), receiptPerson: formData.receiptPerson, receiptQuantity: formData.receiptQuantity, @@ -400,62 +456,31 @@ const handleSubmit = async () => { storageLocation: formData.storageLocation, storageManager: formData.storageManager, - // 设备基本信息(从采购数据继承) - equipmentName: props.equipmentData.equipmentName, - equipmentModel: props.equipmentData.equipmentModel, - equipmentType: props.equipmentData.equipmentType, - equipmentSn: props.equipmentData.equipmentSn, - brand: props.equipmentData.brand, - specification: props.equipmentData.specification, - assetCode: props.equipmentData.assetCode, - - // 采购信息(从采购数据继承) - purchaseOrder: props.equipmentData.purchaseOrder, - supplierName: props.equipmentData.supplierName, - purchasePrice: props.equipmentData.purchasePrice, - purchaseTime: props.equipmentData.purchaseTime, - quantity: props.equipmentData.quantity, - unitPrice: props.equipmentData.unitPrice, - totalPrice: props.equipmentData.totalPrice, - - // 入库信息 - inStockTime: formData.receiptTime ? formatDateTime(formData.receiptTime) : formatDateTime(new Date()), - physicalLocation: formData.storageLocation, - locationStatus: 'in_stock', - responsiblePerson: formData.storageManager, - inventoryBarcode: props.equipmentData.inventoryBarcode || generateInventoryBarcode(), - - // 状态信息 + // 系统默认数据 equipmentStatus: 'normal', - useStatus: '0', - healthStatus: 'good', - receiptStatus: 'RECEIVED', - - // 其他管理信息 - depreciationMethod: props.equipmentData.depreciationMethod || 'straight_line', - depreciationYears: props.equipmentData.depreciationYears || 5, - salvageValue: props.equipmentData.salvageValue || 0, - currentNetValue: props.equipmentData.purchasePrice || 0, - - // 系统字段 - createTime: formatDateTime(new Date()), - updateTime: formatDateTime(new Date()) + useStatus: '0', // 空闲中 + locationStatus: 'in_stock', // 库存中 + healthStatus: 'excellent', + responsiblePerson: formData.storageManager, + physicalLocation: formData.storageLocation, + inStockTime: formData.receiptTime ? formatDateTime(formData.receiptTime) : formatDateTime(new Date()), + inventoryBarcode: `BC${Date.now()}${Math.random().toString(36).substr(2, 4).toUpperCase()}`, + depreciationMethod: 'straight_line', + warrantyExpireDate: procurementData.warrantyExpireDate, + assetRemark: `设备已收货入库,收货人:${formData.receiptPerson},入库时间:${formData.receiptTime}` } - - console.log('📦 构建的收货数据:', receiptData) - - // 调用收货API - await equipmentProcurementApi.receiveGoods( - props.equipmentData.equipmentId, - receiptData - ) - Message.success('收货成功,设备已自动入库') + console.log('📦 准备提交收货数据:', equipmentData) + + // 4. 调用收货API + await equipmentProcurementApi.receiveGoods(procurementData.equipmentId, equipmentData) + + Message.success('收货成功!设备已自动入库') emit('success') - emit('update:visible', false) + } catch (error: any) { console.error('收货失败:', error) - Message.error(error?.message || '收货失败,请检查表单信息') + Message.error(error?.message || '收货失败,请重试') } finally { loading.value = false } diff --git a/src/views/system-resource/device-management/procurement/index.vue b/src/views/system-resource/device-management/procurement/index.vue index 91f57f1..b1953c0 100644 --- a/src/views/system-resource/device-management/procurement/index.vue +++ b/src/views/system-resource/device-management/procurement/index.vue @@ -244,6 +244,18 @@ > 查看支付详情 + + + + + + 刷新 + { // 采购申请成功回调 const handleApplicationSuccess = async () => { applicationModalVisible.value = false - console.log('采购申请成功,准备刷新数据...') - // 延迟刷新数据,确保后端状态更新完成 + console.log('✅ 采购申请成功,准备更新本地数据...') + + // 立即更新本地数据,让申请采购按钮消失 + if (currentApplicationData.value) { + const equipmentId = currentApplicationData.value.equipmentId + + // 找到对应的记录并更新采购状态 + const recordIndex = tableData.value.findIndex(item => item.equipmentId === equipmentId) + if (recordIndex !== -1) { + // 立即更新本地状态为待审批 + tableData.value[recordIndex] = { + ...tableData.value[recordIndex], + procurementStatus: 'PENDING_APPROVAL' + } + + console.log('✅ 本地数据已更新,申请采购按钮应该消失') + console.log('🔍 更新后的记录:', tableData.value[recordIndex]) + + message.success('采购申请已提交,请等待审批') + } else { + console.warn('⚠️ 未找到对应的记录,无法更新本地状态') + message.warning('状态更新失败,请手动刷新页面') + } + } + + // 可选:延迟刷新数据以确保后端状态同步 setTimeout(async () => { - console.log('开始刷新数据...') - await loadData(currentSearchParams.value) - message.success('采购申请已提交,请等待审批') - }, 1000) + try { + console.log('🔄 延迟刷新数据,确保后端状态同步...') + await loadData(currentSearchParams.value) + console.log('✅ 后端数据同步完成') + } catch (error) { + console.error('❌ 后端数据同步失败:', error) + // 不显示错误提示,因为本地状态已经更新 + } + }, 1000) // 1秒后刷新 } // 刷新数据 @@ -993,17 +1034,37 @@ const getTotalAmount = () => { // 检查是否可以申请采购 const canApplyProcurement = (record: EquipmentResp) => { // 根据采购状态判断是否可以申请采购 - // 只有未开始、已拒绝、已完成的设备可以重新申请采购 - const allowedStatuses = ['NOT_STARTED', 'REJECTED', 'COMPLETED', null, undefined] + // 只有未开始、已拒绝的设备可以申请采购 + // 待审批、已通过、已完成等状态不能重复申请 + const allowedStatuses = ['NOT_STARTED', 'REJECTED', null, undefined] const canApply = allowedStatuses.includes(record.procurementStatus) - console.log(`设备 ${record.equipmentName} 采购状态: ${record.procurementStatus}, 可申请: ${canApply}`) + + // 添加详细的调试日志 + console.log(`🔍 申请采购按钮显示检查 - 设备: ${record.equipmentName}`) + console.log(`🔍 当前采购状态: ${record.procurementStatus}`) + console.log(`🔍 允许申请的状态: ${allowedStatuses.join(', ')}`) + console.log(`🔍 是否显示按钮: ${canApply}`) + console.log(`🔍 完整记录:`, record) + return canApply } // 检查是否可以收货 const canReceiveGoods = (record: EquipmentResp) => { - const receiptStatus = (record as any).receiptStatus - return receiptStatus === 'NOT_RECEIVED' || receiptStatus === 'PARTIALLY_RECEIVED' + // 只有在采购状态为已通过且收货状态为未收货时才显示确认收货按钮 + const procurementStatus = record.procurementStatus + const receiptStatus = record.receiptStatus + + console.log('🔍 canReceiveGoods 检查:', { + equipmentName: record.equipmentName, + procurementStatus, + receiptStatus, + canReceive: procurementStatus === 'APPROVED' && + (receiptStatus === 'NOT_RECEIVED' || receiptStatus === 'PARTIALLY_RECEIVED') + }) + + return procurementStatus === 'APPROVED' && + (receiptStatus === 'NOT_RECEIVED' || receiptStatus === 'PARTIALLY_RECEIVED') } // 收货操作 @@ -1021,7 +1082,10 @@ const handleViewReceipt = (record: EquipmentResp) => { // 收货成功回调 const handleReceiptSuccess = () => { receiptModalVisible.value = false + // 收货成功后,采购状态应该更新为已收货 + // 重新加载数据以显示最新状态 loadData(currentSearchParams.value) + message.success('收货成功!设备已自动入库') } // 检查是否可以付款 @@ -1072,6 +1136,30 @@ const getApprovalStatusText = (status: string) => { return textMap[status] || '未知' } +// 手动刷新单条记录 +const handleRefreshRecord = async (record: EquipmentResp) => { + console.log('🔄 手动刷新记录:', record.equipmentId) + try { + // 显示加载提示 + const loadingMessage = message.loading('正在刷新数据...') + + // 重新加载整个表格数据,确保获取最新状态 + await loadData(currentSearchParams.value) + + // 清除加载提示 + if (loadingMessage && typeof loadingMessage.close === 'function') { + loadingMessage.close() + } + message.success('记录状态已刷新') + + console.log('✅ 表格数据刷新完成') + + } catch (error: any) { + console.error('❌ 刷新失败:', error) + message.error(error?.message || '刷新失败') + } +} + onMounted(() => { loadData() }) From 092ab7eb2c21b8a803a8eb5e4463927316b1bae6 Mon Sep 17 00:00:00 2001 From: chabai <14799297+dhasjklhdfjkasfbhfasfj@user.noreply.gitee.com> Date: Thu, 14 Aug 2025 15:27:13 +0800 Subject: [PATCH 02/10] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E6=A8=A1=E5=9D=97=EF=BC=8C=E5=B0=86=E6=99=BA?= =?UTF-8?q?=E8=83=BD=E5=95=86=E5=8A=A1=E6=A8=A1=E5=9D=97=E4=B8=9A=E5=8A=A1?= =?UTF-8?q?copy=E5=88=B0=E6=95=B0=E6=8D=AE=E7=AE=A1=E7=90=86=E6=A8=A1?= =?UTF-8?q?=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/data/index.ts | 188 ++ src/apis/data/type.ts | 98 + src/apis/index.ts | 1 + src/router/route.ts | 22 +- src/types/components.d.ts | 63 + src/views/data/data.vue | 3787 +++++++++++++++++++++++++++++++++++++ 6 files changed, 4158 insertions(+), 1 deletion(-) create mode 100644 src/apis/data/index.ts create mode 100644 src/apis/data/type.ts create mode 100644 src/views/data/data.vue diff --git a/src/apis/data/index.ts b/src/apis/data/index.ts new file mode 100644 index 0000000..cec076f --- /dev/null +++ b/src/apis/data/index.ts @@ -0,0 +1,188 @@ +// @/apis/data/index.ts - 数据管理API +import http from '@/utils/http' +import type { + FolderInfo, + FileInfo, + FolderListParams, + FileListParams, + FolderListResponse, + FileListResponse, + CreateFolderParams, + RenameFolderParams, + DeleteFolderParams, + UploadFileParams, + DownloadFileParams, + DeleteFileParams, + PreviewFileParams, + RenameFileParams +} from './type' + +const { request, requestRaw } = http + +// 导出类型定义 +export type { + FolderInfo, + FileInfo, + FolderListParams, + FileListParams, + FolderListResponse, + FileListResponse, + CreateFolderParams, + RenameFolderParams, + DeleteFolderParams, + UploadFileParams, + DownloadFileParams, + DeleteFileParams, + PreviewFileParams, + RenameFileParams +} + +// 获取文件夹列表(分页) +export function getFolderListApi(params?: FolderListParams) { + return request({ + url: '/data/folder/list', + method: 'get', + params: { + page: params?.page || 1, + pageSize: params?.pageSize || 10, + folderName: params?.folderName + } + }) +} + +// 获取文件列表(分页) +export function getFilesApi(params?: FileListParams) { + return request({ + url: '/data/file/list', + method: 'get', + params: { + page: params?.page || 1, + pageSize: params?.pageSize || 10, + folderId: params?.folderId || '0', + fileName: params?.fileName, + sortField: params?.sortField, + sortOrder: params?.sortOrder + } + }) +} + +// 创建文件夹 +export function createFolderApi(data: CreateFolderParams) { + return request({ + url: '/data/folder/creatFolder', + method: 'post', + data: { + name: data.name, + parentId: data.parentId || '0' + } + }) +} + +// 重命名文件夹 +export function updateFolderApi(folderId: string, newName: string) { + return request({ + url: '/data/folder/rename', + method: 'put', + params: { + folderId: folderId, + newName: newName + } + }) +} + +// 删除文件夹 +export function deleteFolderApi(folderId: string) { + return request({ + url: '/data/folder/delete', + method: 'delete', + params: { + folderId: folderId + } + }) +} + +// 上传文件 +export function uploadFileApi( + file: File, + folderId: string, + onUploadProgress?: (progressEvent: any) => void, + cancelToken?: any +) { + const formData = new FormData() + formData.append('file', file) + + return requestRaw({ + url: '/data/file/add', + method: 'post', + params: { + folderId: folderId + }, + data: formData, + onUploadProgress, + cancelToken, + headers: { + 'Content-Type': 'multipart/form-data' + } + }).then(response => response.data) + .catch(error => { + // 确保错误不会抛出,而是返回一个错误对象 + console.error('上传文件API错误:', error) + return { + code: 500, + msg: error.message || '上传失败', + success: false + } + }) +} + +// 下载文件 +export function downloadFileApi(fileId: string) { + return request({ + url: '/data/file/download', + method: 'get', + params: { + fileId: fileId + }, + responseType: 'blob' + }) +} + +// 删除文件 +export function deleteFileApi(fileId: string) { + return request({ + url: '/data/file/delete', + method: 'delete', + params: { + fileId: fileId + } + }) +} + +// 预览文件 +export function previewFileApi(fileId: string) { + return request({ + url: '/data/file/preview', + method: 'get', + params: { + fileId: fileId + }, + responseType: 'blob' + }) +} + +// 重命名文件 +export function renameFileApi(fileId: string, newFileName: string) { + return request({ + url: '/data/file/rename', + method: 'put', + params: { + fileId: fileId, + newFileName: newFileName + } + }) +} + +// 重命名文件(兼容旧接口) +export function updateFileNameApi(fileId: string, data: RenameFileParams) { + return renameFileApi(fileId, data.newFileName) +} \ No newline at end of file diff --git a/src/apis/data/type.ts b/src/apis/data/type.ts new file mode 100644 index 0000000..b5aa836 --- /dev/null +++ b/src/apis/data/type.ts @@ -0,0 +1,98 @@ +/** 文件夹信息接口 */ +export interface FolderInfo { + folderId: string + name: string + parentId: string + createTime?: string + updateTime?: string + } + + /** 文件信息接口 */ + export interface FileInfo { + fileId: string + fileName: string + fileSize: number + fileType: string + folderId: string + createTime?: string + updateTime?: string + } + + /** 文件夹列表查询参数 */ + export interface FolderListParams { + page?: number + pageSize?: number + folderName?: string + } + + /** 文件列表查询参数 */ + export interface FileListParams { + page?: number + pageSize?: number + folderId?: string + fileName?: string + sortField?: string + sortOrder?: string + } + + /** 文件夹列表响应 */ + export interface FolderListResponse { + data: FolderInfo[] + total: number + current: number + size: number + } + + /** 文件列表响应 */ + export interface FileListResponse { + data: FileInfo[] + total: number + current: number + size: number + } + + /** 创建文件夹请求参数 */ + export interface CreateFolderParams { + name: string + parentId?: string + } + + /** 重命名文件夹请求参数 */ + export interface RenameFolderParams { + folderId: string + newName: string + } + + /** 删除文件夹请求参数 */ + export interface DeleteFolderParams { + folderId: string + } + + /** 上传文件请求参数 */ + export interface UploadFileParams { + file: File + folderId: string + onUploadProgress?: (progressEvent: any) => void + cancelToken?: any + } + + /** 下载文件请求参数 */ + export interface DownloadFileParams { + fileId: string + } + + /** 删除文件请求参数 */ + export interface DeleteFileParams { + fileId: string + } + + /** 预览文件请求参数 */ + export interface PreviewFileParams { + fileId: string + } + + /** 重命名文件请求参数 */ + export interface RenameFileParams { + fileId: string + newFileName: string + } \ No newline at end of file diff --git a/src/apis/index.ts b/src/apis/index.ts index 8218898..c39615e 100644 --- a/src/apis/index.ts +++ b/src/apis/index.ts @@ -20,6 +20,7 @@ export * as RegulationAPI from './regulation' export * as TrainingAPI from './training' export * as EquipmentAPI from './equipment' export * as BussinessAPI from './bussiness/bussiness' +export * as DataAPI from './data' export * from './area/type' export * from './auth/type' diff --git a/src/router/route.ts b/src/router/route.ts index 05536b6..ddc8ced 100644 --- a/src/router/route.ts +++ b/src/router/route.ts @@ -1184,7 +1184,7 @@ export const systemRoutes: RouteRecordRaw[] = [ name: 'bussinesskonwledge', component: Layout, redirect: '/bussiness-knowledge/data', - meta: { title: '商务资料知识库', icon: 'database', hidden: false, sort: 5.5 }, + meta: { title: '智能商务', icon: 'database', hidden: false, sort: 5.5 }, children: [ { path: '/bussiness-konwledge/data', @@ -1198,6 +1198,26 @@ export const systemRoutes: RouteRecordRaw[] = [ }, ], }, + // 数据管理模块 + { + path: '/data-management', + name: 'dataManagement', + component: Layout, + redirect: '/data-management/data', + meta: { title: '数据管理', icon: 'database', hidden: false, sort: 5.6 }, + children: [ + { + path: '/data-management/data', + name: 'data-management', + component: () => import('@/views/data/data.vue'), + meta: { + title: '数据管理', + icon: 'database', + hidden: false, + }, + }, + ], + }, { path: '/image-detection', name: 'ImageDetection', diff --git a/src/types/components.d.ts b/src/types/components.d.ts index 7fa6b1b..a427ece 100644 --- a/src/types/components.d.ts +++ b/src/types/components.d.ts @@ -7,7 +7,70 @@ export {} declare module 'vue' { export interface GlobalComponents { + ApprovalAssistant: typeof import('./../components/ApprovalAssistant/index.vue')['default'] + ApprovalMessageItem: typeof import('./../components/NotificationCenter/ApprovalMessageItem.vue')['default'] + Avatar: typeof import('./../components/Avatar/index.vue')['default'] + Breadcrumb: typeof import('./../components/Breadcrumb/index.vue')['default'] + CellCopy: typeof import('./../components/CellCopy/index.vue')['default'] + Chart: typeof import('./../components/Chart/index.vue')['default'] + CircularProgress: typeof import('./../components/CircularProgress/index.vue')['default'] + ColumnSetting: typeof import('./../components/GiTable/src/components/ColumnSetting.vue')['default'] + CronForm: typeof import('./../components/GenCron/CronForm/index.vue')['default'] + CronModal: typeof import('./../components/GenCron/CronModal/index.vue')['default'] + DateRangePicker: typeof import('./../components/DateRangePicker/index.vue')['default'] + DayForm: typeof import('./../components/GenCron/CronForm/component/day-form.vue')['default'] + FilePreview: typeof import('./../components/FilePreview/index.vue')['default'] + GiCellAvatar: typeof import('./../components/GiCell/GiCellAvatar.vue')['default'] + GiCellGender: typeof import('./../components/GiCell/GiCellGender.vue')['default'] + GiCellStatus: typeof import('./../components/GiCell/GiCellStatus.vue')['default'] + GiCellTag: typeof import('./../components/GiCell/GiCellTag.vue')['default'] + GiCellTags: typeof import('./../components/GiCell/GiCellTags.vue')['default'] + GiCodeView: typeof import('./../components/GiCodeView/index.vue')['default'] + GiDot: typeof import('./../components/GiDot/index.tsx')['default'] + GiEditTable: typeof import('./../components/GiEditTable/GiEditTable.vue')['default'] + GiFooter: typeof import('./../components/GiFooter/index.vue')['default'] + GiForm: typeof import('./../components/GiForm/src/GiForm.vue')['default'] + GiIconBox: typeof import('./../components/GiIconBox/index.vue')['default'] + GiIconSelector: typeof import('./../components/GiIconSelector/index.vue')['default'] + GiIframe: typeof import('./../components/GiIframe/index.vue')['default'] + GiOption: typeof import('./../components/GiOption/index.vue')['default'] + GiOptionItem: typeof import('./../components/GiOptionItem/index.vue')['default'] + GiPageLayout: typeof import('./../components/GiPageLayout/index.vue')['default'] + GiSpace: typeof import('./../components/GiSpace/index.vue')['default'] + GiSplitButton: typeof import('./../components/GiSplitButton/index.vue')['default'] + GiSplitPane: typeof import('./../components/GiSplitPane/index.vue')['default'] + GiSplitPaneFlexibleBox: typeof import('./../components/GiSplitPane/components/GiSplitPaneFlexibleBox.vue')['default'] + GiSvgIcon: typeof import('./../components/GiSvgIcon/index.vue')['default'] + GiTable: typeof import('./../components/GiTable/src/GiTable.vue')['default'] + GiTag: typeof import('./../components/GiTag/index.tsx')['default'] + GiThemeBtn: typeof import('./../components/GiThemeBtn/index.vue')['default'] + HourForm: typeof import('./../components/GenCron/CronForm/component/hour-form.vue')['default'] + Icon403: typeof import('./../components/icons/Icon403.vue')['default'] + Icon404: typeof import('./../components/icons/Icon404.vue')['default'] + Icon500: typeof import('./../components/icons/Icon500.vue')['default'] + IconBorders: typeof import('./../components/icons/IconBorders.vue')['default'] + 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'] + NotificationCenter: typeof import('./../components/NotificationCenter/index.vue')['default'] + ParentView: typeof import('./../components/ParentView/index.vue')['default'] RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] + SecondForm: typeof import('./../components/GenCron/CronForm/component/second-form.vue')['default'] + SplitPanel: typeof import('./../components/SplitPanel/index.vue')['default'] + TextCopy: typeof import('./../components/TextCopy/index.vue')['default'] + TurbineGrid: typeof import('./../components/TurbineGrid/index.vue')['default'] + UserSelect: typeof import('./../components/UserSelect/index.vue')['default'] + Verify: typeof import('./../components/Verify/index.vue')['default'] + VerifyPoints: typeof import('./../components/Verify/Verify/VerifyPoints.vue')['default'] + VerifySlide: typeof import('./../components/Verify/Verify/VerifySlide.vue')['default'] + WeekForm: typeof import('./../components/GenCron/CronForm/component/week-form.vue')['default'] + YearForm: typeof import('./../components/GenCron/CronForm/component/year-form.vue')['default'] } } diff --git a/src/views/data/data.vue b/src/views/data/data.vue new file mode 100644 index 0000000..d4d6c3a --- /dev/null +++ b/src/views/data/data.vue @@ -0,0 +1,3787 @@ + + + + + + + + + 新建文件夹 + + + + + + + + + + + + + + + + + + + + 搜索 "{{ searchKeyword }}" 的结果:共 {{ totalFolders }} 个文件夹 + + + + + + + + + + + + + + + + + + 重命名 + + + + 删除 + + + + + + + + + + + + + + + + + {{ item }} + + + + + + + + + + + + 上传文件 + + + + 新建文件夹 + + + + + + + + + + 文件列表 ({{ fileList.length }}) + + + + + + + + + + + + 请从左侧选择一个文件夹 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 文件名 + + + + + + + + + 类型 + + + + + + + + + 大小 + + + + + + + + + 修改时间 + + + + + + + 操作 + + + + + + + + + + {{ file.fileName || file.name }} + {{ file.fileName || file.name }} + + + + + + + {{ fileTypeText(getFileExtension(file.fileName || file.name)) }} + + + + + {{ formatFileListSize(file.fileSize || file.size) }} + + + + + {{ formatUploadTime(file.uploadTime || file.uploadTime) }} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 上传文件 + + + + + + + + + + + + + + + + + {{ node?.title || node?.name }} + + + + + + + + + + + + + + + + + 点击选择文件 + + + + + + 支持 {{ allowedFileTypesText }} 等格式,单个文件不超过 {{ maxFileSizeText }} + + + + + + + + + + {{ file.name }} + + {{ formatFileSize(file.size) }} + {{ file.error }} + + + + + + + + + + + + + + + + + + + + + + + + + + 根目录 + + {{ folder.name }} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 9e7cc674d486cc55d0c2bfe06ce21d72cd6bd30d Mon Sep 17 00:00:00 2001 From: "Mr.j" <2221464500@qq.com> Date: Thu, 14 Aug 2025 16:17:58 +0800 Subject: [PATCH 03/10] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=AE=BE=E5=A4=87?= =?UTF-8?q?=E9=87=87=E8=B4=AD=E6=A8=A1=E5=9D=97=E5=90=88=E5=90=8C=E5=92=8C?= =?UTF-8?q?=E5=8F=91=E7=A5=A8=E4=B8=8A=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/ContractInvoiceModal.vue | 534 ++++++++++++++++++ .../device-management/procurement/index.vue | 51 +- 2 files changed, 583 insertions(+), 2 deletions(-) create mode 100644 src/views/system-resource/device-management/procurement/components/ContractInvoiceModal.vue diff --git a/src/views/system-resource/device-management/procurement/components/ContractInvoiceModal.vue b/src/views/system-resource/device-management/procurement/components/ContractInvoiceModal.vue new file mode 100644 index 0000000..be0f7b3 --- /dev/null +++ b/src/views/system-resource/device-management/procurement/components/ContractInvoiceModal.vue @@ -0,0 +1,534 @@ + + + + + + + + {{ equipmentData?.equipmentName }} + + + {{ equipmentData?.equipmentModel }} + + + {{ equipmentData?.supplierName }} + + + ¥{{ formatPrice(equipmentData?.purchasePrice || 0) }} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 草稿 + 已签订 + 执行中 + 已完成 + 已终止 + + + + + + + + + + + 上传合同文件 + + + + + {{ file.name }} + + 删除 + + + + + + + + + + + + + + + + + + + + + + + + 增值税专用发票 + 增值税普通发票 + 电子发票 + 其他 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 上传发票文件 + + + + + {{ file.name }} + + 删除 + + + + + + + + + + + + + + + 取消 + + 保存 + + + 完成并进入收货阶段 + + + + + + + + + + diff --git a/src/views/system-resource/device-management/procurement/index.vue b/src/views/system-resource/device-management/procurement/index.vue index b1953c0..3f40bae 100644 --- a/src/views/system-resource/device-management/procurement/index.vue +++ b/src/views/system-resource/device-management/procurement/index.vue @@ -219,6 +219,15 @@ > 确认收货 + + + 管理合同发票 + + + + @@ -361,6 +377,7 @@ import ReceiptDetailModal from './components/ReceiptDetailModal.vue' import PaymentDetailModal from './components/PaymentDetailModal.vue' import ReceiptModal from './components/ReceiptModal.vue' import PaymentModal from './components/PaymentModal.vue' +import ContractInvoiceModal from './components/ContractInvoiceModal.vue' import { equipmentProcurementApi } from '@/apis/equipment/procurement' import { equipmentApprovalApi } from '@/apis/equipment/approval' import type { EquipmentListReq, EquipmentResp } from '@/apis/equipment/type' @@ -409,6 +426,10 @@ const currentPaymentData = ref(null) const receiptModalVisible = ref(false) const paymentModalVisible = ref(false) +// 合同发票管理弹窗控制 +const contractInvoiceModalVisible = ref(false) +const currentContractInvoiceData = ref(null) + // 表格选择 const selectedRowKeys = ref([]) const rowSelection = reactive({ @@ -1052,19 +1073,27 @@ const canApplyProcurement = (record: EquipmentResp) => { // 检查是否可以收货 const canReceiveGoods = (record: EquipmentResp) => { // 只有在采购状态为已通过且收货状态为未收货时才显示确认收货按钮 + // 同时需要确保合同发票信息已经完善 const procurementStatus = record.procurementStatus const receiptStatus = record.receiptStatus + // 检查是否有合同发票信息(这里可以根据实际业务逻辑调整) + // 暂时使用一个简单的判断,后续可以根据实际数据结构调整 + const hasContractInvoice = true // 暂时设为true,后续根据实际业务逻辑调整 + console.log('🔍 canReceiveGoods 检查:', { equipmentName: record.equipmentName, procurementStatus, receiptStatus, + hasContractInvoice, canReceive: procurementStatus === 'APPROVED' && - (receiptStatus === 'NOT_RECEIVED' || receiptStatus === 'PARTIALLY_RECEIVED') + (receiptStatus === 'NOT_RECEIVED' || receiptStatus === 'PARTIALLY_RECEIVED') && + hasContractInvoice }) return procurementStatus === 'APPROVED' && - (receiptStatus === 'NOT_RECEIVED' || receiptStatus === 'PARTIALLY_RECEIVED') + (receiptStatus === 'NOT_RECEIVED' || receiptStatus === 'PARTIALLY_RECEIVED') && + hasContractInvoice } // 收货操作 @@ -1160,6 +1189,24 @@ const handleRefreshRecord = async (record: EquipmentResp) => { } } +// 检查是否可以管理合同发票 +const canManageContractInvoice = (record: EquipmentResp) => { + // 只有在采购状态为已通过时才显示管理合同发票按钮 + return record.procurementStatus === 'APPROVED' +} + +// 管理合同发票操作 +const handleManageContractInvoice = (record: EquipmentResp) => { + currentContractInvoiceData.value = { ...record } + contractInvoiceModalVisible.value = true +} + +// 合同发票管理成功回调 +const handleContractInvoiceSuccess = () => { + contractInvoiceModalVisible.value = false + loadData(currentSearchParams.value) +} + onMounted(() => { loadData() }) From ef44f648613b11e7fda7a412845c84222c890f68 Mon Sep 17 00:00:00 2001 From: Maple <869445424@qq.com> Date: Thu, 14 Aug 2025 16:42:53 +0800 Subject: [PATCH 04/10] =?UTF-8?q?fix:=E6=96=BD=E5=B7=A5=E7=AB=8B=E9=A1=B9?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E5=86=85=E5=AE=B9=E4=B8=AD=EF=BC=8C=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E8=AF=A6=E6=83=85=E5=88=9D=E6=AD=A5=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=EF=BC=8C=E4=BD=86=E6=98=AF=E8=BF=98=E5=AD=98=E5=9C=A8=E4=B8=80?= =?UTF-8?q?=E4=BA=9B=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/types/auto-imports.d.ts | 2 +- src/views/project/TurbineCard.vue | 62 ++++++++++++------------ src/views/project/index.vue | 79 +++++++++++++++++++++++++++---- 3 files changed, 104 insertions(+), 39 deletions(-) diff --git a/src/types/auto-imports.d.ts b/src/types/auto-imports.d.ts index 369aad4..eab6be6 100644 --- a/src/types/auto-imports.d.ts +++ b/src/types/auto-imports.d.ts @@ -70,6 +70,6 @@ declare global { // for type re-export declare global { // @ts-ignore - export type { Component, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue' + export type { Component, ComponentPublicInstance, ComputedRef, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, VNode, WritableComputedRef } from 'vue' import('vue') } diff --git a/src/views/project/TurbineCard.vue b/src/views/project/TurbineCard.vue index 70764b9..bf02fef 100644 --- a/src/views/project/TurbineCard.vue +++ b/src/views/project/TurbineCard.vue @@ -3,22 +3,22 @@ import { computed } from 'vue' import WindTurbine from './icons/WindTurbine.vue' interface Turbine { - id: number - turbineNo: string - status: 0 | 1 | 2 // 0 待施工 1 施工中 2 已完成 - lat?: number - lng?: number + id: number + turbineNo: string + status: 0 | 1 | 2 // 0 待施工 1 施工中 2 已完成 + lat?: number + lng?: number } const props = defineProps<{ modelValue: Turbine }>() const emit = defineEmits<{ - (e: 'update:modelValue', v: Turbine): void - (e: 'map'): void + (e: 'update:modelValue', v: Turbine): void + (e: 'map'): void }>() const turbine = computed({ - get: () => props.modelValue, - set: v => emit('update:modelValue', v) + get: () => props.modelValue, + set: (v) => emit('update:modelValue', v), }) /* 状态文字 & 颜色 */ @@ -27,34 +27,36 @@ const statusColorMap = { 0: '#FF7D00', 1: '#165DFF', 2: '#00B42A' } /* 点击循环切换 */ function toggleStatus() { - const next = ((turbine.value.status + 1) % 3) as 0 | 1 | 2 - turbine.value = { ...turbine.value, status: next } + const next = ((turbine.value.status + 1) % 3) as 0 | 1 | 2 + turbine.value = { ...turbine.value, status: next } } function updateNo(val: string) { - turbine.value = { ...turbine.value, turbineNo: val } + turbine.value = { ...turbine.value, turbineNo: val } } - - - - {{ statusTextMap[turbine.status] }} - - - - - - - - - - - - + + + + {{ statusTextMap[turbine.status] }} + + + + + + + + + + + + \ No newline at end of file + diff --git a/src/views/project/index.vue b/src/views/project/index.vue index 3c7d76f..3cd052d 100644 --- a/src/views/project/index.vue +++ b/src/views/project/index.vue @@ -347,6 +347,53 @@ + + + + + + {{ detailData.projectName || '-' }} + {{ detailData.projectCode || '-' }} + + + {{ PROJECT_STATUS_MAP[detailData.status] || detailData.statusLabel || '-' }} + + + {{ detailData.projectCategory || '-' }} + + {{ detailData.inspectionUnit || '-' }} + {{ detailData.inspectionContact || '-' }} + {{ detailData.inspectionPhone || '-' }} + + {{ detailData.client || '-' }} + {{ detailData.clientContact || '-' }} + {{ detailData.clientPhone || '-' }} + + {{ detailData.farmName || '-' }} + {{ detailData.farmAddress || '-' }} + + {{ detailData.projectManagerName || '-' }} + {{ detailData.scale || detailData.projectScale || '-' }} + {{ detailData.turbineModel || '-' }} + + {{ detailData.startDate || '-' }} + {{ detailData.endDate || '-' }} + + + + {{ detailData.projectIntro || '-' }} + + + + + + @@ -412,6 +459,12 @@ const dataList = ref([]) const userLoading = ref(false) const userOptions = ref<{ label: string, value: string }[]>([]) + +// 详情弹窗状态 +const detailVisible = ref(false) +const detailLoading = ref(false) +const detailData = ref({}) + const searchForm = reactive>({ projectName: '', status: undefined, @@ -979,19 +1032,29 @@ const deleteItem = async (record: T.ProjectResp) => { } } -const viewDetail = (record: T.ProjectResp) => { +const viewDetail = async (record: T.ProjectResp) => { const projectId = record.id || record.projectId if (!projectId) { Message.error('项目ID不存在') return } - - router.push({ - name: 'ProjectDetail', - params: { - id: projectId.toString(), - }, - }) + detailVisible.value = true + detailLoading.value = true + try { + // /project/detail/{projectId} + const res = await getProjectDetail(projectId) + const data = (res as any).data || res || {} + // 若后端返回status为数字,补充状态文案 + if (typeof data.status === 'number' && !data.statusLabel) { + data.statusLabel = PROJECT_STATUS_MAP[data.status] + } + detailData.value = data + } catch (e) { + console.error('获取项目详情失败:', e) + Message.error('获取项目详情失败') + } finally { + detailLoading.value = false + } } const openImportModal = () => { From cce71885b844fc43b1944a95dfdd6aa1ceb70215 Mon Sep 17 00:00:00 2001 From: chabai <14799297+dhasjklhdfjkasfbhfasfj@user.noreply.gitee.com> Date: Thu, 14 Aug 2025 17:09:15 +0800 Subject: [PATCH 05/10] =?UTF-8?q?=E6=8C=89=E7=85=A7=E8=A6=81=E6=B1=82?= =?UTF-8?q?=E5=B0=86=E5=8E=9F=E6=9C=AC=E7=9A=84=E6=95=B0=E6=8D=AE=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E6=A8=A1=E5=9D=97=E6=94=BE=E5=88=B0=E2=80=9C=E6=88=91?= =?UTF-8?q?=E7=9A=84=E5=B7=A5=E4=BD=9C=E5=8F=B0=E2=80=9D=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E9=87=8C=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/router/route.ts | 102 ++++++++++++++++++++++---------------------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/src/router/route.ts b/src/router/route.ts index ddc8ced..c632539 100644 --- a/src/router/route.ts +++ b/src/router/route.ts @@ -906,12 +906,61 @@ export const systemRoutes: RouteRecordRaw[] = [ }, ], }, - // start + + { + path: '/construction-operation-platform', + name: 'ConstructionOperationPlatform', + component: Layout, + redirect: '/construction-operation-platform/implementation-workflow/field-construction', + meta: { title: '我的工作台', icon: 'tool', hidden: false, sort: 5 }, + children: [ + // { + // 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/data-processing/data-storage/attachment', + name: 'AttachmentManagement', + component: () => import('@/views/construction-operation-platform/implementation-workflow/data-processing/data-storage/index.vue'), + meta: { title: '附件管理', icon: 'attachment', hidden: false }, + }, + { + path: '/construction-operation-platform/implementation-workflow/data-processing/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/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 }, + }, + // start // 数据管理 { path: '/data-management', name: 'DataManagement', - component: Layout, redirect: '/data-management/project-management/project-template', meta: { title: '数据管理', icon: 'database', hidden: false, sort: 4 }, children: [ @@ -1027,55 +1076,6 @@ export const systemRoutes: RouteRecordRaw[] = [ ], }, // end - { - path: '/construction-operation-platform', - name: 'ConstructionOperationPlatform', - component: Layout, - redirect: '/construction-operation-platform/implementation-workflow/field-construction', - meta: { title: '我的工作台', icon: 'tool', hidden: false, sort: 5 }, - children: [ - // { - // 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/data-processing/data-storage/attachment', - name: 'AttachmentManagement', - component: () => import('@/views/construction-operation-platform/implementation-workflow/data-processing/data-storage/index.vue'), - meta: { title: '附件管理', icon: 'attachment', hidden: false }, - }, - { - path: '/construction-operation-platform/implementation-workflow/data-processing/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/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/project-delivery', name: 'ProjectDelivery', From 178878e02a95c0ccb8f10eaad2585491810ae136 Mon Sep 17 00:00:00 2001 From: "Mr.j" <2221464500@qq.com> Date: Thu, 14 Aug 2025 17:12:55 +0800 Subject: [PATCH 06/10] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E8=AE=BE=E5=A4=87?= =?UTF-8?q?=E9=87=87=E8=B4=AD=E7=8A=B6=E6=80=81=E6=8C=89=E9=92=AE=E5=92=8C?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E9=A1=BA=E5=BA=8F=EF=BC=8C=E6=94=AF=E4=BB=98?= =?UTF-8?q?=E5=BC=B9=E7=AA=97=E6=94=B9=E6=88=90=E9=9C=80=E8=A6=81=E7=9A=84?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=EF=BC=8C=E6=B7=BB=E5=8A=A0=E5=90=88=E5=90=8C?= =?UTF-8?q?=E5=92=8C=E5=8F=91=E7=A5=A8=E6=8C=89=E9=92=AE=E4=BB=A5=E5=8F=8A?= =?UTF-8?q?=E5=BC=B9=E7=AA=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/types/components.d.ts | 63 -- .../procurement/components/PaymentModal.vue | 804 ++++++++---------- .../device-management/procurement/index.vue | 106 ++- 3 files changed, 443 insertions(+), 530 deletions(-) diff --git a/src/types/components.d.ts b/src/types/components.d.ts index a427ece..7fa6b1b 100644 --- a/src/types/components.d.ts +++ b/src/types/components.d.ts @@ -7,70 +7,7 @@ export {} declare module 'vue' { export interface GlobalComponents { - ApprovalAssistant: typeof import('./../components/ApprovalAssistant/index.vue')['default'] - ApprovalMessageItem: typeof import('./../components/NotificationCenter/ApprovalMessageItem.vue')['default'] - Avatar: typeof import('./../components/Avatar/index.vue')['default'] - Breadcrumb: typeof import('./../components/Breadcrumb/index.vue')['default'] - CellCopy: typeof import('./../components/CellCopy/index.vue')['default'] - Chart: typeof import('./../components/Chart/index.vue')['default'] - CircularProgress: typeof import('./../components/CircularProgress/index.vue')['default'] - ColumnSetting: typeof import('./../components/GiTable/src/components/ColumnSetting.vue')['default'] - CronForm: typeof import('./../components/GenCron/CronForm/index.vue')['default'] - CronModal: typeof import('./../components/GenCron/CronModal/index.vue')['default'] - DateRangePicker: typeof import('./../components/DateRangePicker/index.vue')['default'] - DayForm: typeof import('./../components/GenCron/CronForm/component/day-form.vue')['default'] - FilePreview: typeof import('./../components/FilePreview/index.vue')['default'] - GiCellAvatar: typeof import('./../components/GiCell/GiCellAvatar.vue')['default'] - GiCellGender: typeof import('./../components/GiCell/GiCellGender.vue')['default'] - GiCellStatus: typeof import('./../components/GiCell/GiCellStatus.vue')['default'] - GiCellTag: typeof import('./../components/GiCell/GiCellTag.vue')['default'] - GiCellTags: typeof import('./../components/GiCell/GiCellTags.vue')['default'] - GiCodeView: typeof import('./../components/GiCodeView/index.vue')['default'] - GiDot: typeof import('./../components/GiDot/index.tsx')['default'] - GiEditTable: typeof import('./../components/GiEditTable/GiEditTable.vue')['default'] - GiFooter: typeof import('./../components/GiFooter/index.vue')['default'] - GiForm: typeof import('./../components/GiForm/src/GiForm.vue')['default'] - GiIconBox: typeof import('./../components/GiIconBox/index.vue')['default'] - GiIconSelector: typeof import('./../components/GiIconSelector/index.vue')['default'] - GiIframe: typeof import('./../components/GiIframe/index.vue')['default'] - GiOption: typeof import('./../components/GiOption/index.vue')['default'] - GiOptionItem: typeof import('./../components/GiOptionItem/index.vue')['default'] - GiPageLayout: typeof import('./../components/GiPageLayout/index.vue')['default'] - GiSpace: typeof import('./../components/GiSpace/index.vue')['default'] - GiSplitButton: typeof import('./../components/GiSplitButton/index.vue')['default'] - GiSplitPane: typeof import('./../components/GiSplitPane/index.vue')['default'] - GiSplitPaneFlexibleBox: typeof import('./../components/GiSplitPane/components/GiSplitPaneFlexibleBox.vue')['default'] - GiSvgIcon: typeof import('./../components/GiSvgIcon/index.vue')['default'] - GiTable: typeof import('./../components/GiTable/src/GiTable.vue')['default'] - GiTag: typeof import('./../components/GiTag/index.tsx')['default'] - GiThemeBtn: typeof import('./../components/GiThemeBtn/index.vue')['default'] - HourForm: typeof import('./../components/GenCron/CronForm/component/hour-form.vue')['default'] - Icon403: typeof import('./../components/icons/Icon403.vue')['default'] - Icon404: typeof import('./../components/icons/Icon404.vue')['default'] - Icon500: typeof import('./../components/icons/Icon500.vue')['default'] - IconBorders: typeof import('./../components/icons/IconBorders.vue')['default'] - 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'] - NotificationCenter: typeof import('./../components/NotificationCenter/index.vue')['default'] - ParentView: typeof import('./../components/ParentView/index.vue')['default'] RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] - SecondForm: typeof import('./../components/GenCron/CronForm/component/second-form.vue')['default'] - SplitPanel: typeof import('./../components/SplitPanel/index.vue')['default'] - TextCopy: typeof import('./../components/TextCopy/index.vue')['default'] - TurbineGrid: typeof import('./../components/TurbineGrid/index.vue')['default'] - UserSelect: typeof import('./../components/UserSelect/index.vue')['default'] - Verify: typeof import('./../components/Verify/index.vue')['default'] - VerifyPoints: typeof import('./../components/Verify/Verify/VerifyPoints.vue')['default'] - VerifySlide: typeof import('./../components/Verify/Verify/VerifySlide.vue')['default'] - WeekForm: typeof import('./../components/GenCron/CronForm/component/week-form.vue')['default'] - YearForm: typeof import('./../components/GenCron/CronForm/component/year-form.vue')['default'] } } diff --git a/src/views/system-resource/device-management/procurement/components/PaymentModal.vue b/src/views/system-resource/device-management/procurement/components/PaymentModal.vue index 81b7d52..8535ad2 100644 --- a/src/views/system-resource/device-management/procurement/components/PaymentModal.vue +++ b/src/views/system-resource/device-management/procurement/components/PaymentModal.vue @@ -1,474 +1,380 @@ - - - + + + - {{ equipmentData?.equipmentName || '-' }} - - - {{ equipmentData?.equipmentType || '-' }} + {{ equipmentData?.equipmentName }} - {{ equipmentData?.equipmentModel || '-' }} + {{ equipmentData?.equipmentModel }} - - - {{ equipmentData?.brand || '-' }} - - - {{ equipmentData?.supplierName || '-' }} - - - {{ equipmentData?.purchaseOrder || '-' }} + {{ equipmentData?.supplierName }} - ¥{{ equipmentData?.purchasePrice || '-' }} - - - {{ equipmentData?.quantity || '-' }} + ¥{{ formatPrice(equipmentData?.purchasePrice || 0) }} - - - - - - - 银行转账 - 现金 - 支票 - 信用卡 - 其他 - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + a.费用支出-交通费 + a.费用支出-住宿费 + a.费用支出-小工具 + a.费用支出-车辆保养 + b.采购支出-设备采购-无人机 + b.采购支出-设备采购-车 + b.采购支出-设备采购-计算机 + c.工资支出 + d.税款支出 + f.其他支出 + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 上传发票附件 + + + + + {{ file.name }} + + 删除 + + + + + + + + + + + + + + 上传银行付款凭证 + + + + + {{ file.name }} + + 删除 + + + + + + + + + + - - - - - - - 增值税专用发票 - 增值税普通发票 - 电子发票 - 其他 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + 取消 + + 提交付款申请 + + + + - diff --git a/src/views/system-resource/device-management/procurement/index.vue b/src/views/system-resource/device-management/procurement/index.vue index 3f40bae..2ed8c52 100644 --- a/src/views/system-resource/device-management/procurement/index.vue +++ b/src/views/system-resource/device-management/procurement/index.vue @@ -201,6 +201,8 @@ 编辑 + + 申请采购 - - - 确认收货 - + + 管理合同发票 - - 查看收货 - - + + + - 付款 + 申请付款 查看支付详情 - + + + + 确认收货 + + - - - - 刷新 + 查看收货 - + + + + + {{ getProcurementStatusText(record.procurementStatus) }} - - - {{ getApprovalStatusText(record.approvalStatus) }} + + + + 已完善 + + 待完善 + + + 未开始 + + + + + {{ getPaymentStatusText(record.paymentStatus) }} + + 未支付 + + + + {{ getReceiptStatusText(record.receiptStatus) }} + + 未收货 + { loadData(currentSearchParams.value) } +// 检查是否有合同发票信息 +const hasContractInvoiceInfo = (record: EquipmentResp) => { + // 这里可以根据实际业务逻辑调整判断条件 + // 暂时使用一个简单的判断,后续可以根据实际数据结构调整 + // 例如:检查是否有合同编号、发票号码等字段 + return record.procurementStatus === 'APPROVED' && + (record.receiptStatus === 'RECEIVED' || record.paymentStatus === 'PAID') +} + onMounted(() => { loadData() }) @@ -1393,6 +1437,8 @@ onMounted(() => { } } } + + } // 响应式设计 From 0f4c985a4b0a6847b72919115b3582a14bbbed20 Mon Sep 17 00:00:00 2001 From: Maple <869445424@qq.com> Date: Thu, 14 Aug 2025 17:14:41 +0800 Subject: [PATCH 07/10] =?UTF-8?q?fix:=E6=96=BD=E5=B7=A5=E7=AB=8B=E9=A1=B9?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E5=86=85=E5=AE=B9=E4=B8=AD=EF=BC=8C=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E4=BA=86=E9=A1=B9=E7=9B=AE=E8=AF=A6=E6=83=85=E7=9A=84?= =?UTF-8?q?=E6=9F=A5=E7=9C=8B=E4=BB=A5=E5=8F=8A=E9=A1=B9=E7=9B=AE=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E7=9A=84=E5=86=85=E5=AE=B9=EF=BC=8C=E5=9C=A8=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E8=AF=A6=E6=83=85=E7=9A=84=E5=92=8C=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E5=86=85=E5=AE=B9=E7=9A=84=E6=97=B6=E5=80=99?= =?UTF-8?q?=E9=83=BD=E5=8F=AF=E4=BB=A5=E7=9C=8B=E5=88=B0=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E4=B8=AD=E7=9A=84=E4=BB=BB=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/project/index.vue | 525 +++++++++++++++++++++++++++++++++--- 1 file changed, 488 insertions(+), 37 deletions(-) diff --git a/src/views/project/index.vue b/src/views/project/index.vue index 3cd052d..5200ecc 100644 --- a/src/views/project/index.vue +++ b/src/views/project/index.vue @@ -332,6 +332,249 @@ + + { editModalVisible.value = false }" + @ok="handleEditSubmit" + > + + 基本信息 + + + + + + + + + + + + + + + + + + + {{ user.label }} + + + + + + + + + + (editForm.farmName = val)" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 任务设置 + + + + 新增任务 + + + 暂无任务。 + + + + + 任务 {{ tIndex + 1 }} + + 新增子任务 + 删除 + + + + + + + + + + + + + + + + + + {{ u.label }} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 子任务 + + + + 子任务 {{ tIndex + 1 }}-{{ sIndex + 1 }} + 删除 + + + + + + + + + + + + + + + + + {{ u.label }} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{ option.label }} + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -391,6 +634,16 @@ + + 任务列表 + + @@ -398,6 +651,53 @@ + + \ No newline at end of file From 0809ab03dbd0cacc5e3a583370f5d8d3ff6efd94 Mon Sep 17 00:00:00 2001 From: crushing1111 <909171938@qq.com> Date: Thu, 14 Aug 2025 17:30:24 +0800 Subject: [PATCH 10/10] =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E5=AD=90=E8=B7=AF=E7=94=B1=E4=BA=BA=E5=8A=9B=E7=94=98=E7=89=B9?= =?UTF-8?q?=E5=9B=BE=E8=B7=AF=E7=94=B1=E6=B7=BB=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/router/route.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/router/route.ts b/src/router/route.ts index c632539..2ced11f 100644 --- a/src/router/route.ts +++ b/src/router/route.ts @@ -160,6 +160,18 @@ export const systemRoutes: RouteRecordRaw[] = [ sort: 3.5 } } + , + { + path: '/task/gantt', + name: 'TaskGantt', + component: () => import('@/views/task/task-gantt/TaskGantt.vue'), + meta: { + title: '人力甘特图', + icon: 'workload', // 进度相关图标 + hidden: false, + sort: 3.6 + } + } , { path: '/task/approval',