Jelajahi Sumber

Merge branch 'yunxing_record' of shuzhihua/pms-iot-vue into master

yanghao 1 Minggu lalu
induk
melakukan
39a40a69c0

+ 1 - 1
.env.local

@@ -4,7 +4,7 @@ NODE_ENV=development
 VITE_DEV=true
 
 # 请求路径  http://192.168.188.149:48080  https://iot.deepoil.cc
-VITE_BASE_URL='https://iot.deepoil.cc'
+VITE_BASE_URL='http://192.168.188.149:48080'
 
 # 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持 S3 服务
 VITE_UPLOAD_TYPE=server

+ 5 - 0
src/api/pms/device/index.ts

@@ -203,5 +203,10 @@ export const IotDeviceApi = {
   // 获取关联设备
   getIotDeviceSetRelation: async (params) => {
     return await request.get({ url: `/rq/iot-device-group/device/group`, params })
+  },
+
+  // 设备报表导出
+  exportDeviceReport: async (data) => {
+    return await request.post({ url: `/rq/report/export-excel`, data })
   }
 }

+ 1 - 1
src/views/report-statistics/costs.vue

@@ -70,7 +70,7 @@ const defaultStats: StatItem[] = [
   {
     key: 'repair',
     title: '内部维修成本',
-    type: '维修',
+    type: '内部维修',
     icon: 'i-material-symbols:home-repair-service-outline',
     class: {
       bg1: 'bg-[var(--el-color-success-light-7)]',

+ 256 - 7
src/views/report-statistics/device_book/index2.vue

@@ -78,7 +78,7 @@
                 >
               </el-form-item>
               <el-form-item>
-                <el-button type="success" plain
+                <el-button type="success" plain @click="handleExport"
                   ><Icon icon="ep:download" class="mr-3px" /> 导出</el-button
                 >
               </el-form-item>
@@ -125,12 +125,7 @@
             </template>
           </el-table-column>
           <el-table-column label="公司" align="center" prop="company" min-width="150" />
-          <el-table-column
-            :label="t('iotDevice.dept')"
-            align="center"
-            prop="deptName"
-            min-width="150"
-          />
+          <el-table-column label="部门名称" align="center" prop="deptName" min-width="150" />
           <el-table-column
             :label="t('iotDevice.status')"
             align="center"
@@ -232,6 +227,78 @@
           @pagination="getList"
         />
       </ContentWrap>
+
+      <!-- 在 template 中的 el-row 后面添加导出对话框 -->
+      <!-- <el-dialog
+        v-model="exportDialogVisible"
+        title="导出设置"
+        width="500px"
+        :close-on-click-modal="false"
+        :close-on-press-escape="false"
+      >
+        <div class="export-dialog-content">
+          <p class="mb-3">请选择要导出的列:</p>
+          <el-checkbox-group v-model="selectedColumns" class="grid grid-cols-2 gap-2 w-full">
+            <el-checkbox
+              v-for="column in availableColumns"
+              :key="column.prop"
+              :label="column.prop"
+              class="mb-2"
+            >
+              {{ column.label }}
+            </el-checkbox>
+          </el-checkbox-group>
+        </div>
+        <template #footer>
+          <div class="dialog-footer">
+            <el-button @click="exportDialogVisible = false">取消</el-button>
+            <el-button type="primary" @click="confirmExport">确认导出</el-button>
+          </div>
+        </template>
+      </el-dialog> -->
+      <el-dialog
+        v-model="exportDialogVisible"
+        title="导出设置"
+        width="600px"
+        :close-on-click-modal="false"
+        :close-on-press-escape="false"
+        class="export-dialog"
+      >
+        <div class="export-dialog-content">
+          <div class="export-header mb-4">
+            <p class="export-title">请选择要导出的列</p>
+            <p class="export-subtitle"
+              >已选择 {{ selectedColumns.length }} / {{ availableColumns.length }} 项</p
+            >
+          </div>
+
+          <div class="export-options-container">
+            <el-checkbox-group v-model="selectedColumns" class="export-checkbox-group">
+              <el-checkbox
+                v-for="column in availableColumns"
+                :key="column.prop"
+                :label="column.prop"
+                class="export-checkbox-item"
+              >
+                <span class="checkbox-text">{{ column.label }}</span>
+              </el-checkbox>
+            </el-checkbox-group>
+          </div>
+        </div>
+
+        <template #footer>
+          <div class="dialog-footer">
+            <el-button @click="exportDialogVisible = false">取消</el-button>
+            <el-button
+              type="primary"
+              @click="confirmExport"
+              :disabled="selectedColumns.length === 0"
+            >
+              确认导出 ({{ selectedColumns.length }})
+            </el-button>
+          </div>
+        </template>
+      </el-dialog>
     </el-col>
   </el-row>
 </template>
@@ -246,6 +313,7 @@ import Echart from '@/components/Echart/src/Echart.vue'
 import echarts from '@/plugins/echarts'
 import { formatDate } from '@/utils/formatTime'
 import { nextTick } from 'vue'
+import { axios } from 'axios'
 
 /** 设备台账 列表 */
 defineOptions({ name: 'IotDevicePms' })
@@ -297,6 +365,78 @@ const queryFormRef = ref(null) // 搜索的表单
 const contentSpan = ref(20)
 const treeShow = ref(true)
 
+const exportDialogVisible = ref(false) // 导出对话框显示状态
+const selectedColumns = ref([]) // 选中的列
+const availableColumns = ref<any>([]) // 可用的列选项
+
+// 获取表格列信息
+const getTableColumns = () => {
+  // 根据表格定义动态获取列信息
+  availableColumns.value = [
+    { prop: '设备编码', label: '设备编码', visible: true },
+    { prop: '设备名称', label: '设备名称', visible: true },
+    { prop: '公司', label: '公司', visible: true },
+    { prop: '部门名称', label: '部门名称', visible: true },
+    { prop: '设备状态', label: '设备状态', visible: true },
+    { prop: '资产性质', label: '资产性质', visible: true },
+    { prop: '资产类别', label: '资产类别', visible: true },
+    { prop: '生产厂家', label: '生产厂家', visible: true },
+    { prop: '生产日期', label: '生产日期', visible: true },
+    { prop: '投运日期', label: '投运日期', visible: true },
+    { prop: '品牌', label: '品牌', visible: true },
+    { prop: '规格型号', label: '规格型号', visible: true },
+    { prop: '责任人', label: '责任人', visible: true }
+  ]
+
+  // 默认选中所有列
+  selectedColumns.value = availableColumns.value.map((col) => col.prop)
+
+  // 全选功能
+  const selectAllColumns = () => {
+    selectedColumns.value = availableColumns.value.map((col) => col.prop)
+  }
+
+  // 清空选择
+  const clearAllColumns = () => {
+    selectedColumns.value = []
+  }
+}
+
+// 导出功能
+const handleExport = async () => {
+  exportDialogVisible.value = true
+  getTableColumns()
+}
+
+// 确认导出
+const confirmExport = async () => {
+  if (selectedColumns.value.length === 0) {
+    ElMessage.warning('请至少选择一列进行导出')
+    return
+  }
+
+  try {
+    // 构建导出参数
+    const exportParams = {
+      pageNo: queryParams.pageNo,
+      pageSize: queryParams.pageSize,
+      deviceCode: queryParams.deviceCode,
+      deviceName: queryParams.deviceName,
+
+      exportFields: JSON.stringify(selectedColumns.value)
+    }
+
+    // 调用后端导出接口
+    // const res = await IotDeviceApi.exportDeviceReport(exportParams)
+
+    // download.excel(res, '设备报表.xls')
+    exportDialogVisible.value = false
+  } catch (error) {
+    console.error('导出失败:', error)
+    ElMessage.error('导出失败,请重试')
+  }
+}
+
 const handleSortChange = (params: any) => {
   //console.log(`排序字段: ${prop}, 排序方式: ${order}`);
   queryParams.sortingFields = []
@@ -565,4 +705,113 @@ onMounted(async () => {
   top: 0px;
   z-index: 2000;
 }
+
+.export-dialog :deep(.el-dialog) {
+  border-radius: 12px;
+  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15);
+}
+
+.export-dialog-content {
+  padding: 0 10px;
+}
+
+.export-header {
+  text-align: center;
+}
+
+.export-title {
+  font-size: 16px;
+  font-weight: 600;
+  color: #303133;
+  margin: 0 0 4px 0;
+}
+
+.export-subtitle {
+  font-size: 14px;
+  color: #909399;
+  margin: 0;
+}
+
+.export-options-container {
+  max-height: 300px;
+  overflow-y: auto;
+  padding: 8px;
+  border: 1px solid #e4e7ed;
+  border-radius: 6px;
+  background-color: #fafafa;
+}
+
+.export-checkbox-group {
+  display: grid;
+  grid-template-columns: 1fr 1fr;
+  gap: 12px;
+  padding: 10px;
+}
+
+.export-checkbox-item {
+  margin-bottom: 8px;
+  padding: 8px 12px;
+  border-radius: 6px;
+  border: 1px solid #ebeef5;
+  transition: all 0.3s ease;
+  background-color: #fff;
+}
+
+.export-checkbox-item:hover {
+  background-color: #f5f7fa;
+  border-color: #dcdfe6;
+  transform: translateY(-1px);
+  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
+}
+
+.export-checkbox-item:deep(.el-checkbox__input.is-checked + .el-checkbox__label) {
+  color: #409eff;
+  font-weight: 500;
+}
+
+.checkbox-text {
+  font-size: 14px;
+  color: #606266;
+}
+
+.export-actions {
+  display: flex;
+  justify-content: center;
+  gap: 12px;
+}
+
+.dialog-footer {
+  display: flex;
+  justify-content: space-between;
+}
+
+/* 滚动条样式 */
+.export-options-container::-webkit-scrollbar {
+  width: 6px;
+}
+
+.export-options-container::-webkit-scrollbar-track {
+  background: #f1f1f1;
+  border-radius: 10px;
+}
+
+.export-options-container::-webkit-scrollbar-thumb {
+  background: #c1c1c1;
+  border-radius: 10px;
+}
+
+.export-options-container::-webkit-scrollbar-thumb:hover {
+  background: #a8a8a8;
+}
+
+/* 响应式调整 */
+@media (max-width: 768px) {
+  .export-checkbox-group {
+    grid-template-columns: 1fr;
+  }
+
+  .export-dialog {
+    width: 90% !important;
+  }
+}
 </style>