From 71fa9d0eee805cc2a6445269b949dc65d4274b80 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期二, 27 一月 2026 11:23:01 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_New' into dev_New

---
 src/views/equipmentManagement/upkeep/index.vue           |  101 +++++++++++
 src/views/inventoryManagement/stockManagement/Import.vue |    2 
 src/views/inventoryManagement/stockReport/index.vue      |  334 +++++++++++++++---------------------
 src/api/inventoryManagement/stockInventory.js            |   16 +
 src/api/equipmentManagement/maintenanceTaskFile.js       |   28 +++
 5 files changed, 283 insertions(+), 198 deletions(-)

diff --git a/src/api/equipmentManagement/maintenanceTaskFile.js b/src/api/equipmentManagement/maintenanceTaskFile.js
new file mode 100644
index 0000000..8373ae3
--- /dev/null
+++ b/src/api/equipmentManagement/maintenanceTaskFile.js
@@ -0,0 +1,28 @@
+import request from "@/utils/request";
+
+// 鏌ヨ淇濆吇浠诲姟闄勪欢鍒楄〃
+export function listMaintenanceTaskFiles(query) {
+  return request({
+    url: "/maintenanceTaskFile/listPage",
+    method: "get",
+    params: query,
+  });
+}
+
+// 鏂板淇濆吇浠诲姟闄勪欢
+export function addMaintenanceTaskFile(data) {
+  return request({
+    url: "/maintenanceTaskFile/add",
+    method: "post",
+    data,
+  });
+}
+
+// 鍒犻櫎淇濆吇浠诲姟闄勪欢
+export function delMaintenanceTaskFile(id) {
+  return request({
+    url: "/maintenanceTaskFile/del",
+    method: "delete",
+    data: Array.isArray(id) ? id : [id],
+  });
+}
diff --git a/src/api/inventoryManagement/stockInventory.js b/src/api/inventoryManagement/stockInventory.js
index a50194a..15e1b3a 100644
--- a/src/api/inventoryManagement/stockInventory.js
+++ b/src/api/inventoryManagement/stockInventory.js
@@ -26,12 +26,18 @@
     });
 };
 
-export const exportStockInventory = (params) => {
+export const getStockInventoryReportList = (params) => {
     return request({
-        url: "/stockInventory/exportStockInventory",
-        method: "post",
-        data: params,
+        url: "/stockInventory/stockInventoryPage",
+        method: "get",
+        params,
     });
 };
 
-
+export const getStockInventoryInAndOutReportList = (params) => {
+    return request({
+        url: "/stockInventory/stockInAndOutRecord",
+        method: "get",
+        params,
+    });
+};
diff --git a/src/views/equipmentManagement/upkeep/index.vue b/src/views/equipmentManagement/upkeep/index.vue
index 046c0fa..543e37b 100644
--- a/src/views/equipmentManagement/upkeep/index.vue
+++ b/src/views/equipmentManagement/upkeep/index.vue
@@ -203,6 +203,13 @@
           >
             鍒犻櫎
           </el-button>
+          <el-button
+            type="primary"
+            link
+            @click="openFileDialog(row)"
+          >
+            闄勪欢
+          </el-button>
         </template>
       </PIMTable>
         </div>
@@ -211,6 +218,15 @@
     <PlanModal ref="planModalRef" @ok="getTableData" />
         <MaintenanceModal ref="maintainModalRef" @ok="getTableData" />
         <FormDia ref="formDiaRef" @closeDia="getScheduledTableData" />
+    <FileListDialog 
+      ref="fileListDialogRef"
+      v-model="fileDialogVisible"
+      :show-upload-button="true"
+      :show-delete-button="true"
+      :delete-method="handleAttachmentDelete"
+      :name-column-label="'闄勪欢鍚嶇О'"
+      :rulesRegulationsManagementId="currentMaintenanceTaskId"
+      @upload="handleAttachmentUpload" />
   </div>
 </template>
 
@@ -221,12 +237,18 @@
 import PlanModal from './Form/PlanModal.vue'
 import MaintenanceModal from './Form/MaintenanceModal.vue'
 import FormDia from './Form/formDia.vue'
+import FileListDialog from '@/components/Dialog/FileListDialog.vue'
 import {
   getUpkeepPage,
   delUpkeep,
   deviceMaintenanceTaskList,
   deviceMaintenanceTaskDel,
 } from '@/api/equipmentManagement/upkeep'
+import {
+  listMaintenanceTaskFiles,
+  addMaintenanceTaskFile,
+  delMaintenanceTaskFile,
+} from '@/api/equipmentManagement/maintenanceTaskFile'
 import dayjs from 'dayjs'
 
 const { proxy } = getCurrentInstance()
@@ -240,6 +262,10 @@
 const maintainModalRef = ref()
 // 瀹氭椂浠诲姟寮圭獥鎺у埗鍣�
 const formDiaRef = ref()
+// 闄勪欢寮圭獥
+const fileListDialogRef = ref(null)
+const fileDialogVisible = ref(false)
+const currentMaintenanceTaskId = ref(null)
 
 // 浠诲姟璁板綍tab锛堝師璁惧淇濆吇椤甸潰锛夌浉鍏冲彉閲�
 const filters = reactive({
@@ -385,7 +411,7 @@
 		dataType: "slot",
 		slot: "operation",
 		align: "center",
-		width: "300px",
+		width: "350px",
 	},
 ])
 
@@ -571,6 +597,79 @@
   getTableData()
 }
 
+// 闄勪欢鐩稿叧鏂规硶
+// 鏌ヨ闄勪欢鍒楄〃
+const fetchMaintenanceTaskFiles = async (deviceMaintenanceId) => {
+  try {
+    const params = {
+      current: 1,
+      size: 100,
+      deviceMaintenanceId,
+      rulesRegulationsManagementId:deviceMaintenanceId
+    }
+    const res = await listMaintenanceTaskFiles(params)
+    const records = res?.data?.records || []
+    const mapped = records.map(item => ({
+      id: item.id,
+      name: item.fileName || item.name,
+      url: item.fileUrl || item.url,
+      raw: item,
+    }))
+    fileListDialogRef.value?.setList(mapped)
+  } catch (error) {
+    ElMessage.error('鑾峰彇闄勪欢鍒楄〃澶辫触')
+  }
+}
+
+// 鎵撳紑闄勪欢寮圭獥
+const openFileDialog = async (row) => {
+  currentMaintenanceTaskId.value = row.id
+  fileDialogVisible.value = true
+  await fetchMaintenanceTaskFiles(row.id)
+}
+
+// 鍒锋柊闄勪欢鍒楄〃
+const refreshFileList = async () => {
+  if (!currentMaintenanceTaskId.value) return
+  await fetchMaintenanceTaskFiles(currentMaintenanceTaskId.value)
+}
+
+// 涓婁紶闄勪欢
+const handleAttachmentUpload = async (filePayload) => {
+  if (!currentMaintenanceTaskId.value) return
+  try {
+    const payload = {
+      name: filePayload?.fileName || filePayload?.name,
+      url: filePayload?.fileUrl || filePayload?.url,
+      deviceMaintenanceId: currentMaintenanceTaskId.value,
+    }
+    await addMaintenanceTaskFile(payload)
+    ElMessage.success('鏂囦欢涓婁紶鎴愬姛')
+    await refreshFileList()
+  } catch (error) {
+    ElMessage.error('鏂囦欢涓婁紶澶辫触')
+  }
+}
+
+// 鍒犻櫎闄勪欢
+const handleAttachmentDelete = async (row) => {
+  if (!row?.id) return false
+  try {
+    await ElMessageBox.confirm('纭鍒犻櫎璇ラ檮浠讹紵', '鎻愮ず', { type: 'warning' })
+  } catch {
+    return false
+  }
+  try {
+    await delMaintenanceTaskFile(row.id)
+    ElMessage.success('鍒犻櫎鎴愬姛')
+    await refreshFileList()
+    return true
+  } catch (error) {
+    ElMessage.error('鍒犻櫎澶辫触')
+    return false
+  }
+}
+
 onMounted(() => {
   // 鏍规嵁榛樿婵�娲荤殑 Tab 璋冪敤瀵瑰簲鐨勬煡璇㈡帴鍙�
   if (activeTab.value === 'scheduled') {
diff --git a/src/views/inventoryManagement/stockManagement/Import.vue b/src/views/inventoryManagement/stockManagement/Import.vue
index 1dbce95..7d898e1 100644
--- a/src/views/inventoryManagement/stockManagement/Import.vue
+++ b/src/views/inventoryManagement/stockManagement/Import.vue
@@ -6,7 +6,7 @@
       :headers="upload.headers"
       :action="upload.url"
       :disabled="upload.isUploading"
-      :showTip="false"
+      :showTip="true"
       @success="handleFileSuccess"
     />
     <template #footer>
diff --git a/src/views/inventoryManagement/stockReport/index.vue b/src/views/inventoryManagement/stockReport/index.vue
index 354c775..0bbfac6 100644
--- a/src/views/inventoryManagement/stockReport/index.vue
+++ b/src/views/inventoryManagement/stockReport/index.vue
@@ -12,7 +12,6 @@
         >
           <el-option label="鏃ユ姤" value="daily" />
           <el-option label="鏈堟姤" value="monthly" />
-          <el-option label="浣滀笟鎶ヨ〃" value="work" />
           <el-option label="杩涘嚭瀛樻姤琛�" value="inout" />
         </el-select>
         
@@ -56,91 +55,91 @@
       </div>
       
       <div class="search_right">
-        <el-button type="success" @click="handleExport" icon="Download">
-          瀵煎嚭鎶ヨ〃
-        </el-button>
+<!--        <el-button type="success" @click="handleExport" icon="Download">-->
+<!--          瀵煎嚭鎶ヨ〃-->
+<!--        </el-button>-->
       </div>
     </div>
 
-    <!-- 缁熻鍗$墖 -->
-    <div class="stats_cards" v-if="reportData.summary">
-      <el-row :gutter="20">
-        <el-col :span="6">
-          <el-card class="stats_card">
-            <div class="stats_content">
-              <div class="stats_icon in">
-                <el-icon><TrendCharts /></el-icon>
-              </div>
-              <div class="stats_info">
-                <div class="stats_value">{{ reportData.summary.totalIn || 0 }}</div>
-                <div class="stats_label">鎬诲叆搴撻噺</div>
-              </div>
-            </div>
-          </el-card>
-        </el-col>
-        <el-col :span="6">
-          <el-card class="stats_card">
-            <div class="stats_content">
-              <div class="stats_icon out">
-                <el-icon><TrendCharts /></el-icon>
-              </div>
-              <div class="stats_info">
-                <div class="stats_value">{{ reportData.summary.totalOut || 0 }}</div>
-                <div class="stats_label">鎬诲嚭搴撻噺</div>
-              </div>
-            </div>
-          </el-card>
-        </el-col>
-        <el-col :span="6">
-          <el-card class="stats_card">
-            <div class="stats_content">
-              <div class="stats_icon stock">
-                <el-icon><Box /></el-icon>
-              </div>
-              <div class="stats_info">
-                <div class="stats_value">{{ reportData.summary.currentStock || 0 }}</div>
-                <div class="stats_label">褰撳墠搴撳瓨</div>
-              </div>
-            </div>
-          </el-card>
-        </el-col>
-        <el-col :span="6">
-          <el-card class="stats_card">
-            <div class="stats_content">
-              <div class="stats_icon turnover">
-                <el-icon><Refresh /></el-icon>
-              </div>
-              <div class="stats_info">
-                <div class="stats_value">{{ reportData.summary.turnoverRate || 0 }}%</div>
-                <div class="stats_label">鍛ㄨ浆鐜�</div>
-              </div>
-            </div>
-          </el-card>
-        </el-col>
-      </el-row>
-    </div>
+<!--    &lt;!&ndash; 缁熻鍗$墖 &ndash;&gt;-->
+<!--    <div class="stats_cards" v-if="reportData.summary">-->
+<!--      <el-row :gutter="20">-->
+<!--        <el-col :span="6">-->
+<!--          <el-card class="stats_card">-->
+<!--            <div class="stats_content">-->
+<!--              <div class="stats_icon in">-->
+<!--                <el-icon><TrendCharts /></el-icon>-->
+<!--              </div>-->
+<!--              <div class="stats_info">-->
+<!--                <div class="stats_value">{{ reportData.summary.totalIn || 0 }}</div>-->
+<!--                <div class="stats_label">鎬诲叆搴撻噺</div>-->
+<!--              </div>-->
+<!--            </div>-->
+<!--          </el-card>-->
+<!--        </el-col>-->
+<!--        <el-col :span="6">-->
+<!--          <el-card class="stats_card">-->
+<!--            <div class="stats_content">-->
+<!--              <div class="stats_icon out">-->
+<!--                <el-icon><TrendCharts /></el-icon>-->
+<!--              </div>-->
+<!--              <div class="stats_info">-->
+<!--                <div class="stats_value">{{ reportData.summary.totalOut || 0 }}</div>-->
+<!--                <div class="stats_label">鎬诲嚭搴撻噺</div>-->
+<!--              </div>-->
+<!--            </div>-->
+<!--          </el-card>-->
+<!--        </el-col>-->
+<!--        <el-col :span="6">-->
+<!--          <el-card class="stats_card">-->
+<!--            <div class="stats_content">-->
+<!--              <div class="stats_icon stock">-->
+<!--                <el-icon><Box /></el-icon>-->
+<!--              </div>-->
+<!--              <div class="stats_info">-->
+<!--                <div class="stats_value">{{ reportData.summary.currentStock || 0 }}</div>-->
+<!--                <div class="stats_label">褰撳墠搴撳瓨</div>-->
+<!--              </div>-->
+<!--            </div>-->
+<!--          </el-card>-->
+<!--        </el-col>-->
+<!--        <el-col :span="6">-->
+<!--          <el-card class="stats_card">-->
+<!--            <div class="stats_content">-->
+<!--              <div class="stats_icon turnover">-->
+<!--                <el-icon><Refresh /></el-icon>-->
+<!--              </div>-->
+<!--              <div class="stats_info">-->
+<!--                <div class="stats_value">{{ reportData.summary.turnoverRate || 0 }}%</div>-->
+<!--                <div class="stats_label">鍛ㄨ浆鐜�</div>-->
+<!--              </div>-->
+<!--            </div>-->
+<!--          </el-card>-->
+<!--        </el-col>-->
+<!--      </el-row>-->
+<!--    </div>-->
 
-    <!-- 鍥捐〃鍖哄煙 -->
-    <div class="chart_section" v-if="reportData.chartData">
-      <el-row :gutter="20">
-        <el-col :span="12">
-          <el-card>
-            <template #header>
-              <span>搴撳瓨瓒嬪娍鍥�</span>
-            </template>
-            <div ref="trendChart" style="height: 300px;"></div>
-          </el-card>
-        </el-col>
-        <el-col :span="12">
-          <el-card>
-            <template #header>
-              <span>杩涘嚭搴撳姣�</span>
-            </template>
-            <div ref="comparisonChart" style="height: 300px;"></div>
-          </el-card>
-        </el-col>
-      </el-row>
-    </div>
+<!--    &lt;!&ndash; 鍥捐〃鍖哄煙 &ndash;&gt;-->
+<!--    <div class="chart_section" v-if="reportData.chartData">-->
+<!--      <el-row :gutter="20">-->
+<!--        <el-col :span="12">-->
+<!--          <el-card>-->
+<!--            <template #header>-->
+<!--              <span>搴撳瓨瓒嬪娍鍥�</span>-->
+<!--            </template>-->
+<!--            <div ref="trendChart" style="height: 300px;"></div>-->
+<!--          </el-card>-->
+<!--        </el-col>-->
+<!--        <el-col :span="12">-->
+<!--          <el-card>-->
+<!--            <template #header>-->
+<!--              <span>杩涘嚭搴撳姣�</span>-->
+<!--            </template>-->
+<!--            <div ref="comparisonChart" style="height: 300px;"></div>-->
+<!--          </el-card>-->
+<!--        </el-col>-->
+<!--      </el-row>-->
+<!--    </div>-->
 
     <!-- 璇︾粏鏁版嵁琛ㄦ牸 -->
     <div class="table_section">
@@ -163,122 +162,71 @@
             width="60"
           />
            <el-table-column
-             v-if="searchForm.reportType === 'daily'"
-             label="鏃ユ湡"
-             prop="createTime"
-             width="100"
-             align="center"
-           />
-           <el-table-column
-             v-if="searchForm.reportType === 'monthly'"
-             label="鏈堜唤"
-             prop="createTime"
-             width="100"
-             align="center"
-           />
-           <el-table-column
              label="鍏ュ簱鏃堕棿"
              prop="createTime"
-             width="100"
+             width="200"
              show-overflow-tooltip
+             v-if="!searchForm.reportType === 'inout'"
            />
            <el-table-column
              label="鍏ュ簱鎵规"
              prop="inboundBatches"
-             width="160"
+             width="240"
              show-overflow-tooltip
-           />
-           <el-table-column
-             label="渚涘簲鍟嗗悕绉�"
-             prop="supplierName"
-             min-width="240"
-             show-overflow-tooltip
+             v-if="!searchForm.reportType === 'inout'"
            />
            <el-table-column
              label="浜у搧澶х被"
-             prop="productCategory"
-             width="100"
+             prop="productName"
              show-overflow-tooltip
            />
            <el-table-column
              label="瑙勬牸鍨嬪彿"
-             prop="specificationModel"
-             min-width="200"
+             prop="model"
              show-overflow-tooltip
            />
            <el-table-column
              label="鍗曚綅"
              prop="unit"
-             width="70"
              show-overflow-tooltip
            />
-           <!-- <el-table-column
-             label="鏈熷垵搴撳瓨"
-             prop="beginStock"
-             width="100"
-             align="center"
-           /> -->
            <el-table-column
              label="鍏ュ簱鏁伴噺"
-             prop="inboundNum"
+             prop="totalStockIn"
+             align="center"
+             v-if="searchForm.reportType === 'inout'"
+           />
+           <el-table-column
+               label="鍏ュ簱鏁伴噺"
+               prop="stockInNum"
+               align="center"
+               v-else
+           />
+           <el-table-column
+             label="鍑哄簱鏁伴噺"
+             prop="totalStockOut"
              width="100"
              align="center"
            />
-           <!-- <el-table-column
-             label="鍑哄簱鏁伴噺"
-             prop=""
-             width="100"
-             align="center"
-           /> -->
            <el-table-column
              label="鐜板湪搴撳瓨"
-             prop="inboundNum0"
-             width="100"
+             prop="currentStock"
              align="center"
            />
-           <el-table-column
-             label="鍚◣鍗曚环"
-             prop="taxInclusiveUnitPrice"
-             width="100"
-             show-overflow-tooltip
-           />
-           <el-table-column
-             label="鍚◣鎬讳环"
-             prop="taxInclusiveTotalPrice"
-             width="100"
-             show-overflow-tooltip
-           />
-           <el-table-column
-             label="绋庣巼(%)"
-             prop="taxRate"
-             width="80"
-             show-overflow-tooltip
-           />
-           <el-table-column
-             label="涓嶅惈绋庢�讳环"
-             prop="taxExclusiveTotalPrice"
-             width="100"
-             show-overflow-tooltip
-           />
+           <el-table-column label="鏉ユ簮"
+                            prop="recordType"
+                            v-if="!searchForm.reportType === 'inout'"
+                            show-overflow-tooltip>
+             <template #default="scope">
+               {{ getRecordType(scope.row.recordType) }}
+             </template>
+           </el-table-column>
            <el-table-column
              label="鍏ュ簱浜�"
              prop="createBy"
              width="80"
+             v-if="!searchForm.reportType === 'inout'"
              show-overflow-tooltip
-           />
-           <el-table-column
-             v-if="searchForm.reportType === 'work'"
-             label="鎿嶄綔浜哄憳"
-             prop="operator"
-             width="80"
-             align="center"
-           />
-           <el-table-column
-             v-if="searchForm.reportType === 'work'"
-             label="鎿嶄綔鏃堕棿"
-             prop="operateTime"
-             width="150"
-             align="center"
            />
         </el-table>
       </el-card>
@@ -291,12 +239,14 @@
 import { ElMessage } from 'element-plus'
 import * as echarts from 'echarts'
 import {
-  getStockDailyReport,
   getStockMonthlyReport,
-  getWorkReport,
   getStockInOutReport,
-  exportStockReport
 } from '@/api/inventoryManagement/stockReport'
+import {
+  getStockInventoryInAndOutReportList,
+  getStockInventoryReportList
+} from "@/api/inventoryManagement/stockInventory.js";
+import {findAllQualifiedStockRecordTypeOptions} from "@/api/basicData/enum.js";
 
 
 const { proxy } = getCurrentInstance()
@@ -318,12 +268,25 @@
   tableData: []
 })
 
+const stockRecordTypeOptions = ref([])
+
+const getRecordType = (recordType) => {
+  return stockRecordTypeOptions.value.find(item => item.value === recordType)?.label || ''
+}
+
+// 鑾峰彇鏉ユ簮绫诲瀷閫夐」
+const fetchStockRecordTypeOptions = () => {
+  findAllQualifiedStockRecordTypeOptions()
+      .then(res => {
+        stockRecordTypeOptions.value = res.data;
+      })
+}
+
 // 鑾峰彇琛ㄦ牸鏍囬
 const getTableTitle = () => {
   const typeMap = {
     daily: '鏃ユ姤璇︾粏鏁版嵁',
     monthly: '鏈堟姤璇︾粏鏁版嵁',
-    work: '浣滀笟鎶ヨ〃璇︾粏鏁版嵁',
     inout: '杩涘嚭瀛樻姤琛ㄨ缁嗘暟鎹�'
   }
   return typeMap[searchForm.reportType] || '鎶ヨ〃璇︾粏鏁版嵁'
@@ -348,32 +311,19 @@
   try {
     const params = getQueryParams()
     let response
-    
-    switch (searchForm.reportType) {
-      case 'daily':
-        response = await getStockDailyReport(params)
-        break
-      case 'monthly':
-        response = await getStockMonthlyReport(params)
-        break
-      case 'work':
-        response = await getWorkReport(params)
-        break
-      case 'inout':
-        response = await getStockInOutReport(params)
-        break
-      default:
-        throw new Error('鏈煡鐨勬姤琛ㄧ被鍨�')
+
+    if (searchForm.reportType === 'inout') {
+      response = await getStockInventoryInAndOutReportList(params)
+    } else {
+      response = await getStockInventoryReportList(params)
     }
-    
     if (response.code === 200) {
-      // generateMockData()
-      reportData.value.tableData = response.data.tableData
-      reportData.value.summary = response.data.summary
-      reportData.value.chartData = response.data.chartData
-      nextTick(() => {
-        initCharts()
-      })
+      reportData.value.tableData = response.data.records
+      // reportData.value.summary = response.data.summary
+      // reportData.value.chartData = response.data.chartData
+      // nextTick(() => {
+      //   initCharts()
+      // })
       
     }
   } catch (error) {
@@ -420,7 +370,7 @@
       ElMessage.warning('璇烽�夋嫨鏃ユ湡')
       return false
     }
-  } else if (searchForm.reportType === 'work' || searchForm.reportType === 'inout') {
+  } else if (searchForm.reportType === 'inout') {
     if (!searchForm.dateRange || searchForm.dateRange.length !== 2) {
       ElMessage.warning('璇烽�夋嫨鏃ユ湡鑼冨洿')
       return false
@@ -599,6 +549,8 @@
     yesterday.toISOString().split('T')[0],
     today.toISOString().split('T')[0]
   ]
+
+  fetchStockRecordTypeOptions()
 })
 </script>
 

--
Gitblit v1.9.3