Explorar el Código

Merge branch 'stable' of http://39.98.153.250:9080/yudao/yudao-admin-yiqun into stable

xuzhancheng hace 16 horas
padre
commit
0790cae439

+ 22 - 0
yudao-ui-admin-vue3/src/api/common/home.ts

@@ -6,3 +6,25 @@ export const getTodoList = () => {
 export const getAuditTodoList = () => {
   return request.get({ url: '/pressure2/boiler-task-order/index-page/getTaskOrderBpmCount' })
 }
+
+// ========== 首页风险预警 ==========
+
+// 锅炉 - 个人预警
+export const getBoilerMyAlert = () => {
+  return request.get({ url: '/pressure2/risk-alert/boiler/my' })
+}
+
+// 锅炉 - 部门预警
+export const getBoilerDeptAlert = (deptIds: string[]) => {
+  return request.post({ url: '/pressure2/risk-alert/boiler/dept', data: deptIds })
+}
+
+// 管道 - 个人预警
+export const getPipeMyAlert = () => {
+  return request.get({ url: '/pressure2/risk-alert/pipe/my' })
+}
+
+// 管道 - 部门预警
+export const getPipeDeptAlert = (deptIds: string[]) => {
+  return request.post({ url: '/pressure2/risk-alert/pipe/dept', data: deptIds })
+}

+ 267 - 87
yudao-ui-admin-vue3/src/views/Home/Index.vue

@@ -8,14 +8,18 @@
               <img :src="ywdbIcon" alt="" />
               待办
             </span>
-<!--            <el-button link type="default"-->
-<!--              >查看更多 <el-icon><ArrowRight /></el-icon-->
-<!--            ></el-button>-->
+            <!--            <el-button link type="default"-->
+            <!--              >查看更多 <el-icon><ArrowRight /></el-icon-->
+            <!--            ></el-button>-->
           </div>
         </template>
         <div v-if="showTodoList" class="audit-list">
           <template v-for="todo in todoList" :key="todo.title">
-            <div v-show="todo.task > 0" class="audit-item cursor-pointer" @click="() => handleRouteTo(todo)">
+            <div
+              v-show="todo.task > 0"
+              class="audit-item cursor-pointer"
+              @click="() => handleRouteTo(todo)"
+            >
               <img :src="todo.iconUrl" alt="" />
               <div>
                 <i v-if="typeof todo.task === 'number'">{{ todo.task }}</i>
@@ -37,9 +41,9 @@
               <img :src="ywdbIcon" alt="" />
               审批
             </span>
-<!--            <el-button link type="default"-->
-<!--              >查看更多 <el-icon><ArrowRight /></el-icon-->
-<!--            ></el-button>-->
+            <!--            <el-button link type="default"-->
+            <!--              >查看更多 <el-icon><ArrowRight /></el-icon-->
+            <!--            ></el-button>-->
           </div>
         </template>
         <div v-if="showAuditList" class="audit-list">
@@ -63,55 +67,6 @@
         </div>
         <el-empty v-else description="暂无审批数据" />
       </el-card>
-      <el-card class="box-card">
-        <template #header>
-          <div class="card-header">
-            <span>
-              <img :src="fxIcon" alt="" />
-              风险预警
-            </span>
-          </div>
-        </template>
-        <div class="todo-list">
-          <div
-            v-for="todo in riskTodoList"
-            :key="todo.title"
-            class="flex-1 items-center flex risk-todo-item cursor-pointer"
-            @click="() => handleRouteTo(todo)"
-          >
-            <img :src="todo.iconUrl" alt="" />
-            <div>
-              <span>{{ todo.title }}</span>
-              <i>{{ todo.task }}</i>
-            </div>
-          </div>
-        </div>
-      </el-card>
-    </el-col>
-    <el-col :span="8">
-      <el-card class="box-card">
-        <template #header>
-          <div class="card-header">
-            <span>
-              <img :src="kjrkIcon" alt="" />
-              快捷入口
-            </span>
-          </div>
-        </template>
-        <div class="todo-list quick-access-list">
-          <div
-            v-for="todo in quickAccessList"
-            :key="todo.title"
-            class="todo-item quick-access-item cursor-pointer"
-            @click="() => handleRouteTo(todo)"
-          >
-            <img :src="todo.iconUrl" alt="" />
-            <div>
-              <span>{{ todo.title }}</span>
-            </div>
-          </div>
-        </div>
-      </el-card>
       <el-card class="box-card">
         <template #header>
           <div class="card-header">
@@ -119,9 +74,9 @@
               <img :src="tzIcon" alt="" />
               通知公告
             </span>
-<!--            <el-button v-if="noticeList.length" link type="default" @click="toMoreNotice"-->
-<!--              >查看更多 <el-icon><ArrowRight /></el-icon-->
-<!--            ></el-button>-->
+            <!--            <el-button v-if="noticeList.length" link type="default" @click="toMoreNotice"-->
+            <!--              >查看更多 <el-icon><ArrowRight /></el-icon-->
+            <!--            ></el-button>-->
           </div>
         </template>
         <div class="todo-list">
@@ -160,14 +115,59 @@
         </div>
       </el-card>
     </el-col>
+    <el-col :span="8">
+      <div class="risk-alert-wrap">
+        <RiskAlertCard
+          equip-type="boiler"
+          :fetch-my="getBoilerMyAlert"
+          :fetch-dept="getBoilerDeptAlert"
+        />
+        <RiskAlertCard
+          equip-type="pipe"
+          :fetch-my="getPipeMyAlert"
+          :fetch-dept="getPipeDeptAlert"
+        />
+      </div>
+      <el-card class="box-card">
+        <template #header>
+          <div class="card-header">
+            <span>
+              <img :src="kjrkIcon" alt="" />
+              快捷入口
+            </span>
+          </div>
+        </template>
+        <div class="todo-list quick-access-list">
+          <div
+            v-for="todo in quickAccessList"
+            :key="todo.title"
+            class="todo-item quick-access-item cursor-pointer"
+            @click="() => handleRouteTo(todo)"
+          >
+            <img :src="todo.iconUrl" alt="" />
+            <div>
+              <span>{{ todo.title }}</span>
+            </div>
+          </div>
+        </div>
+      </el-card>
+    </el-col>
   </el-row>
 </template>
 <script lang="ts" setup>
 import { useUserStore } from '@/store/modules/user'
 import { useWatermark } from '@/hooks/web/useWatermark'
 import { ArrowRight, List } from '@element-plus/icons-vue'
-import { getTodoList, getAuditTodoList } from '@/api/common/home'
+import {
+  getTodoList,
+  getAuditTodoList,
+  getBoilerMyAlert,
+  getBoilerDeptAlert,
+  getPipeMyAlert,
+  getPipeDeptAlert
+} from '@/api/common/home'
 import { IndexTodoApi } from '@/api/pressure2/indextodo'
+import RiskAlertCard from './components/RiskAlertCard.vue'
 
 import yjIcon from '@/assets/imgs/index_imgs/约检@2x.png'
 import jhpqIcon from '@/assets/imgs/index_imgs/计划排期@2x.png'
@@ -202,41 +202,215 @@ const msgTypeMap = {
 
 // 业务待办列表(锅炉和管道分别显示)
 const todoList = ref([
-  { title: '计划表', key: 'boilerScheduleCount', equipType: 'boiler', iconUrl: zlfpIcon, task: 0, routerName: 'ScheduleBoiler' },
-  { title: '任务确认', key: 'boilerTaskOrderConfirmCount', equipType: 'boiler', iconUrl: jhpqIcon, task: 0, routerName: 'BoilerCheckerTaskList' },
-  { title: '检验录入', key: 'boilerMyTaskCount', equipType: 'boiler', iconUrl: jhdtIcon, task: 0, routerName: 'BoilerMyTask'},
-  { title: '报告编制', key: 'boilerPrepareReportCount', equipType: 'boiler', iconUrl: zlfpIcon, task: 0, routerName: 'BoilerReportPreparationList' },
-  { title: '计划表', key: 'pipeScheduleCount', equipType: 'pipe', iconUrl: zlfpIcon, task: 0, routerName: 'SchedulePipe' },
-  { title: '任务确认', key: 'pipeTaskOrderConfirmCount', equipType: 'pipe', iconUrl: jhpqIcon, task: 0, routerName: 'PipeCheckerTaskList' },
-  { title: '检验录入', key: 'pipeMyTaskCount', equipType: 'pipe', iconUrl: jhdtIcon, task: 0, routerName: 'PipeMyTask'},
-  { title: '报告编制', key: 'pipePrepareReportCount', equipType: 'pipe', iconUrl: zlfpIcon, task: 0, routerName: 'PipeReportPreparationList' },
+  {
+    title: '计划表',
+    key: 'boilerScheduleCount',
+    equipType: 'boiler',
+    iconUrl: zlfpIcon,
+    task: 0,
+    routerName: 'ScheduleBoiler'
+  },
+  {
+    title: '任务确认',
+    key: 'boilerTaskOrderConfirmCount',
+    equipType: 'boiler',
+    iconUrl: jhpqIcon,
+    task: 0,
+    routerName: 'BoilerCheckerTaskList'
+  },
+  {
+    title: '检验录入',
+    key: 'boilerMyTaskCount',
+    equipType: 'boiler',
+    iconUrl: jhdtIcon,
+    task: 0,
+    routerName: 'BoilerMyTask'
+  },
+  {
+    title: '报告编制',
+    key: 'boilerPrepareReportCount',
+    equipType: 'boiler',
+    iconUrl: zlfpIcon,
+    task: 0,
+    routerName: 'BoilerReportPreparationList'
+  },
+  {
+    title: '计划表',
+    key: 'pipeScheduleCount',
+    equipType: 'pipe',
+    iconUrl: zlfpIcon,
+    task: 0,
+    routerName: 'SchedulePipe'
+  },
+  {
+    title: '任务确认',
+    key: 'pipeTaskOrderConfirmCount',
+    equipType: 'pipe',
+    iconUrl: jhpqIcon,
+    task: 0,
+    routerName: 'PipeCheckerTaskList'
+  },
+  {
+    title: '检验录入',
+    key: 'pipeMyTaskCount',
+    equipType: 'pipe',
+    iconUrl: jhdtIcon,
+    task: 0,
+    routerName: 'PipeMyTask'
+  },
+  {
+    title: '报告编制',
+    key: 'pipePrepareReportCount',
+    equipType: 'pipe',
+    iconUrl: zlfpIcon,
+    task: 0,
+    routerName: 'PipeReportPreparationList'
+  }
 ])
 
 // 业务审批列表(锅炉和管道分别显示)
 const auditLoading = ref(false)
 const auditTodoList = ref([
-  { title: '模板审核', key: 'reportTemplateCount', iconUrl: bgspIcon, task: 0, routerName: 'TemplateAudit' },
-
-  { title: '记录校核', key: 'boilerRecheckOrderItemCount', equipType: 'boiler', iconUrl: jljhIcon, task: 0, routerName: 'BoilerCheckerRecordCheck' },
-  { title: '上报市局审核', key: 'boilerReportCityBureauCount', equipType: 'boiler', iconUrl: rwdshIcon, task: 0, routerName: 'appointmentconfirmorderCityBureauListPressure2' },
-  { title: '受理单审核', key: 'boilerAcceptOrderCount', equipType: 'boiler', iconUrl: jljhIcon, task: 0, routerName: 'AcceptOrderAuditBoiler' },
-  { title: '缴费单待校核', key: 'boilerPressureNonTaxCount', equipType: 'boiler', iconUrl: zlshIcon, task: 0, routerName: 'PaymentReceiptApprovePressure2' },
-  { title: '任务单修改审核', key: 'boilerTaskOrderCount', equipType: 'boiler', iconUrl: rwdshIcon, task: 0, routerName: 'TaskOrderReviewBoiler' },
-  { title: '检验意见通知书审核', key: 'boilerPressureInspectionOpinionNoticeCount', equipType: 'boiler', iconUrl: jljhIcon, task: 0, routerName: 'AuditInspectionCommentsNoticeBoiler' },
-  { title: '检验方案审核', key: 'boilerPressureInspectionSchemeCount', equipType: 'boiler', iconUrl: zlshIcon, task: 0, routerName: 'InspectionPlanAuditBoiler' },
-  { title: '操作指导书审核', key: 'boilerPressureWorkingInstructionCount', equipType: 'boiler', iconUrl: rwdshIcon, task: 0, routerName: 'WorkInstructionAuditBoiler' },
+  {
+    title: '模板审核',
+    key: 'reportTemplateCount',
+    iconUrl: bgspIcon,
+    task: 0,
+    routerName: 'TemplateAudit'
+  },
+
+  {
+    title: '记录校核',
+    key: 'boilerRecheckOrderItemCount',
+    equipType: 'boiler',
+    iconUrl: jljhIcon,
+    task: 0,
+    routerName: 'BoilerCheckerRecordCheck'
+  },
+  {
+    title: '上报市局审核',
+    key: 'boilerReportCityBureauCount',
+    equipType: 'boiler',
+    iconUrl: rwdshIcon,
+    task: 0,
+    routerName: 'appointmentconfirmorderCityBureauListPressure2'
+  },
+  {
+    title: '受理单审核',
+    key: 'boilerAcceptOrderCount',
+    equipType: 'boiler',
+    iconUrl: jljhIcon,
+    task: 0,
+    routerName: 'AcceptOrderAuditBoiler'
+  },
+  {
+    title: '缴费单待校核',
+    key: 'boilerPressureNonTaxCount',
+    equipType: 'boiler',
+    iconUrl: zlshIcon,
+    task: 0,
+    routerName: 'PaymentReceiptApprovePressure2'
+  },
+  {
+    title: '任务单修改审核',
+    key: 'boilerTaskOrderCount',
+    equipType: 'boiler',
+    iconUrl: rwdshIcon,
+    task: 0,
+    routerName: 'TaskOrderReviewBoiler'
+  },
+  {
+    title: '检验意见通知书审核',
+    key: 'boilerPressureInspectionOpinionNoticeCount',
+    equipType: 'boiler',
+    iconUrl: jljhIcon,
+    task: 0,
+    routerName: 'AuditInspectionCommentsNoticeBoiler'
+  },
+  {
+    title: '检验方案审核',
+    key: 'boilerPressureInspectionSchemeCount',
+    equipType: 'boiler',
+    iconUrl: zlshIcon,
+    task: 0,
+    routerName: 'InspectionPlanAuditBoiler'
+  },
+  {
+    title: '操作指导书审核',
+    key: 'boilerPressureWorkingInstructionCount',
+    equipType: 'boiler',
+    iconUrl: rwdshIcon,
+    task: 0,
+    routerName: 'WorkInstructionAuditBoiler'
+  },
   // OA流程:锅炉审核/审批
   { title: '锅炉审核', key: 'boilerCheckCount', equipType: 'boiler', iconUrl: bgspIcon, task: 0, routerPath: '/gljy/report-check-boiler', oaType: true },
   { title: '锅炉审批', key: 'boilerRatifyCount', equipType: 'boiler', iconUrl: bgspIcon, task: 0, routerPath: '/gljy/report-ratify-boiler', oaType: true },
 
-  { title: '记录校核', key: 'pipeRecheckOrderItemCount', equipType: 'pipe', iconUrl: jljhIcon, task: 0, routerName: 'PipeCheckerRecordCheck' },
-  { title: '上报市局审核', key: 'pipeReportCityBureauCount', equipType: 'pipe', iconUrl: rwdshIcon, task: 0, routerName: 'appointmentconfirmorderCityBureauListPressure2' },
-  { title: '受理单审核', key: 'pipeAcceptOrderCount', equipType: 'pipe', iconUrl: jljhIcon, task: 0, routerName: 'AcceptOrderAuditPipe' },
-  { title: '缴费单待校核', key: 'pipePressureNonTaxCount', equipType: 'pipe', iconUrl: zlshIcon, task: 0, routerName: 'PaymentReceiptApprovePressure2' },
-  { title: '任务单修改审核', key: 'pipeTaskOrderCount', equipType: 'pipe', iconUrl: rwdshIcon, task: 0, routerName: 'TaskOrderReviewPipe' },
-  { title: '检验意见通知书审核', key: 'pipePressureInspectionOpinionNoticeCount', equipType: 'pipe', iconUrl: jljhIcon, task: 0, routerName: 'AuditInspectionCommentsNoticePipe' },
-  { title: '检验方案审核', key: 'pipePressureInspectionSchemeCount', equipType: 'pipe', iconUrl: zlshIcon, task: 0, routerName: 'InspectionPlanAuditPipe' },
-  { title: '操作指导书审核', key: 'pipePressureWorkingInstructionCount', equipType: 'pipe', iconUrl: rwdshIcon, task: 0, routerName: 'WorkInstructionAuditPipe' },
+  {
+    title: '记录校核',
+    key: 'pipeRecheckOrderItemCount',
+    equipType: 'pipe',
+    iconUrl: jljhIcon,
+    task: 0,
+    routerName: 'PipeCheckerRecordCheck'
+  },
+  {
+    title: '上报市局审核',
+    key: 'pipeReportCityBureauCount',
+    equipType: 'pipe',
+    iconUrl: rwdshIcon,
+    task: 0,
+    routerName: 'appointmentconfirmorderCityBureauListPressure2'
+  },
+  {
+    title: '受理单审核',
+    key: 'pipeAcceptOrderCount',
+    equipType: 'pipe',
+    iconUrl: jljhIcon,
+    task: 0,
+    routerName: 'AcceptOrderAuditPipe'
+  },
+  {
+    title: '缴费单待校核',
+    key: 'pipePressureNonTaxCount',
+    equipType: 'pipe',
+    iconUrl: zlshIcon,
+    task: 0,
+    routerName: 'PaymentReceiptApprovePressure2'
+  },
+  {
+    title: '任务单修改审核',
+    key: 'pipeTaskOrderCount',
+    equipType: 'pipe',
+    iconUrl: rwdshIcon,
+    task: 0,
+    routerName: 'TaskOrderReviewPipe'
+  },
+  {
+    title: '检验意见通知书审核',
+    key: 'pipePressureInspectionOpinionNoticeCount',
+    equipType: 'pipe',
+    iconUrl: jljhIcon,
+    task: 0,
+    routerName: 'AuditInspectionCommentsNoticePipe'
+  },
+  {
+    title: '检验方案审核',
+    key: 'pipePressureInspectionSchemeCount',
+    equipType: 'pipe',
+    iconUrl: zlshIcon,
+    task: 0,
+    routerName: 'InspectionPlanAuditPipe'
+  },
+  {
+    title: '操作指导书审核',
+    key: 'pipePressureWorkingInstructionCount',
+    equipType: 'pipe',
+    iconUrl: rwdshIcon,
+    task: 0,
+    routerName: 'WorkInstructionAuditPipe'
+  },
   // OA流程:管道审核/审批
   { title: '管道审核', key: 'pipeCheckCount', equipType: 'pipe', iconUrl: bgspIcon, task: 0, routerPath: '/gdjy/report-check-pipe', oaType: true },
   { title: '管道审批', key: 'pipeRatifyCount', equipType: 'pipe', iconUrl: bgspIcon, task: 0, routerPath: '/gdjy/report-ratify-pipe', oaType: true },
@@ -355,7 +529,7 @@ const fetchOATodoCount = async () => {
 }
 
 // 旧逻辑保留(注释)
-// const fetchTodoList = ... 
+// const fetchTodoList = ...
 // const fetchAuditTodoList = ...
 
 // 通知公告
@@ -844,4 +1018,10 @@ selectNoticeList()
 .equip-tag-pipe {
   color: #67c23a !important;
 }
+.risk-alert-wrap {
+  display: flex;
+  flex-direction: column;
+  gap: 16px;
+  margin-bottom: 20px;
+}
 </style>

+ 340 - 0
yudao-ui-admin-vue3/src/views/Home/components/RiskAlertCard.vue

@@ -0,0 +1,340 @@
+<template>
+  <div>
+    <!-- 个人风险预警 -->
+    <el-card class="box-card risk-warning-sidebar-card">
+      <template #header>
+        <div class="card-header">
+          <span>
+            <img :src="fxIcon" alt="" />
+            <span v-if="props.equipType === 'boiler'" class="equip-tag-boiler">[锅]</span>
+            <span v-if="props.equipType === 'pipe'" class="equip-tag-pipe">[管]</span>
+            个人风险预警
+          </span>
+        </div>
+      </template>
+      <div class="risk-warning-new-list" v-loading="myLoading">
+        <div v-if="myTotal > 0" class="risk-warning-new-item">
+          <div class="item-row-1">
+            <div class="item-title-group">
+              <span class="item-title">我的临期报告</span>
+              <el-tooltip
+                effect="dark"
+                placement="top"
+                content="只统计任务单非审核中、已被认领的报告"
+              >
+                <el-icon class="warning-icon"><Warning /></el-icon>
+              </el-tooltip>
+            </div>
+            <span class="item-total-count">{{ myTotal }}</span>
+          </div>
+          <div class="item-row-2">
+            <div
+              v-for="item in myStats"
+              :key="item.checkType"
+              class="status-tag cursor-pointer"
+              @click.stop="handleClick(item.checkType, item.equipCodes)"
+            >
+              <span class="status-label">{{ item.checkTypeName }}</span>
+              <span class="status-count">{{ item.count }}</span>
+            </div>
+          </div>
+        </div>
+        <div v-else class="empty-text">暂无数据</div>
+      </div>
+    </el-card>
+
+    <!-- 部门风险预警 -->
+    <el-card class="box-card risk-warning-sidebar-card" style="margin-top: 16px">
+      <template #header>
+        <div class="card-header">
+          <span>
+            <img :src="fxIcon" alt="" />
+            <span v-if="props.equipType === 'boiler'" class="equip-tag-boiler">[锅]</span>
+            <span v-if="props.equipType === 'pipe'" class="equip-tag-pipe">[管]</span>
+            部门风险预警
+          </span>
+          <DeptSelect
+            v-model="deptId"
+            :multiple="false"
+            placeholder="请选择部门"
+            :clearable="true"
+            style="width: 200px"
+            @update:model-value="onDeptChange"
+          />
+        </div>
+      </template>
+      <div class="risk-warning-new-list" v-loading="deptLoading">
+        <template v-if="deptTotal > 0">
+          <template v-for="child in deptStats" :key="child.deptId">
+            <div class="risk-warning-new-item">
+              <div class="item-row-1">
+                <div class="item-title-group">
+                  <span class="item-title">{{ child.deptName }} 的临期报告</span>
+                </div>
+                <span class="item-total-count">{{ child.totalCount }}</span>
+              </div>
+              <div class="item-row-2">
+                <div
+                  v-for="item in child.checkTypeStats"
+                  :key="item.checkType"
+                  class="status-tag cursor-pointer"
+                  @click.stop="handleClick(item.checkType, item.equipCodes)"
+                >
+                  <span class="status-label">{{ item.checkTypeName }}</span>
+                  <span class="status-count">{{ item.count }}</span>
+                </div>
+              </div>
+            </div>
+          </template>
+        </template>
+        <div v-else class="empty-text">暂无数据</div>
+      </div>
+    </el-card>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref, computed, onMounted } from 'vue'
+import { useRouter } from 'vue-router'
+import { Warning } from '@element-plus/icons-vue'
+import { useUserStore } from '@/store/modules/user'
+import DeptSelect from '@/views/pressure2/planNew/components/DeptSelect.vue'
+import fxIcon from '@/assets/imgs/index_imgs/风险@2x.png'
+
+defineOptions({ name: 'RiskAlertCard' })
+
+interface Props {
+  equipType: string
+  fetchMy: () => Promise<any>
+  fetchDept: (deptIds: string[]) => Promise<any>
+}
+
+const props = defineProps<Props>()
+const router = useRouter()
+const userStore = useUserStore()
+
+const myLoading = ref(false)
+const deptLoading = ref(false)
+const myRaw = ref<any[]>([])
+const deptRaw = ref<any[]>([])
+const deptId = ref<string | null>(null)
+
+const myStats = computed(() => myRaw.value)
+const myTotal = computed(() => myStats.value.reduce((s: number, i: any) => s + i.count, 0))
+
+const deptStats = computed(() => deptRaw.value)
+const deptTotal = computed(() => deptStats.value.reduce((s: number, d: any) => s + d.totalCount, 0))
+
+const fetchMyData = async () => {
+  myLoading.value = true
+  try {
+    const res = await props.fetchMy()
+    myRaw.value = Array.isArray(res) ? res : res?.data || []
+  } finally {
+    myLoading.value = false
+  }
+}
+
+const fetchDeptData = async (ids: string[]) => {
+  if (!ids || ids.length === 0) {
+    deptRaw.value = []
+    return
+  }
+  deptLoading.value = true
+  try {
+    const res = await props.fetchDept(ids)
+    deptRaw.value = Array.isArray(res) ? res : res?.data || []
+  } finally {
+    deptLoading.value = false
+  }
+}
+
+const onDeptChange = (val: string | null) => {
+  if (val) {
+    fetchDeptData([val])
+  } else {
+    deptRaw.value = []
+  }
+}
+
+const handleClick = (checkType: number, equipCodes: string[]) => {
+  sessionStorage.setItem('riskAlertEquipCodes', JSON.stringify(equipCodes))
+  sessionStorage.setItem('riskAlertCheckType', String(checkType))
+  sessionStorage.setItem('riskAlertEquipType', props.equipType)
+  if (props.equipType === 'boiler') {
+    router.push({ name: 'BoilerMyTask', query: { from: 'riskAlert' } })
+  } else {
+    router.push({ name: 'PipeMyTask', query: { from: 'riskAlert' } })
+  }
+}
+
+onMounted(() => {
+  fetchMyData()
+  // 默认加载当前登录人所在部门
+  const userDeptId = userStore.user.deptId
+  if (userDeptId) {
+    deptId.value = String(userDeptId)
+    fetchDeptData([String(userDeptId)])
+  }
+})
+</script>
+
+<style scoped>
+.box-card {
+  margin-bottom: 0;
+  border-radius: 12px;
+  box-shadow: 0px 2px 14px 0px rgba(43, 99, 255, 0.1);
+  padding: 17px 22px 24px;
+}
+
+.box-card :deep(.el-card__header) {
+  padding: 0 0 8px 0;
+  border-bottom: none;
+}
+
+.box-card :deep(.el-card__body) {
+  padding: 0;
+  padding-top: 16px;
+}
+
+.card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.card-header span {
+  display: flex;
+  align-items: center;
+  font-size: 16px;
+  font-weight: 600;
+}
+
+.card-header span img {
+  width: 22px;
+  height: 22px;
+  margin-right: 6px;
+}
+
+.risk-warning-new-list {
+  display: flex;
+  flex-direction: column;
+  gap: 12px;
+}
+
+.risk-warning-new-item {
+  display: flex;
+  flex-direction: column;
+  padding: 12px 16px;
+  gap: 8px;
+  background: rgba(245, 108, 108, 0.05);
+  border: 1px solid rgba(245, 108, 108, 0.2);
+  border-radius: 8px;
+  transition: all 0.3s ease;
+  cursor: pointer;
+}
+
+.risk-warning-new-item:hover {
+  background: rgba(245, 108, 108, 0.1);
+  transform: translateY(-2px);
+  box-shadow: 0 4px 12px rgba(245, 108, 108, 0.15);
+  border-color: rgba(245, 108, 108, 0.3);
+}
+
+.item-row-1 {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+}
+
+.item-title-group {
+  display: flex;
+  align-items: center;
+  gap: 6px;
+}
+
+.item-title {
+  font-size: 14px;
+  font-weight: 600;
+  color: #1a1a1a;
+}
+
+.warning-icon {
+  font-size: 14px;
+  color: #f56c6c;
+  cursor: help;
+  flex-shrink: 0;
+  transition: all 0.2s ease;
+}
+
+.warning-icon:hover {
+  color: #dc2626;
+  transform: scale(1.1);
+}
+
+.item-total-count {
+  font-family: 'DIN Alternate', 'SF Pro Display', sans-serif;
+  font-size: 20px;
+  font-weight: 700;
+  color: #f56c6c;
+  background: linear-gradient(135deg, #f56c6c 0%, #dc2626 100%);
+  -webkit-background-clip: text;
+  -webkit-text-fill-color: transparent;
+  background-clip: text;
+}
+
+.item-row-2 {
+  display: flex;
+  flex-direction: row;
+  gap: 6px;
+  align-items: center;
+  flex-wrap: wrap;
+}
+
+.status-tag {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 4px 10px;
+  background: rgba(255, 255, 255, 0.95);
+  border: 1px solid rgba(245, 108, 108, 0.2);
+  border-radius: 6px;
+  min-width: 80px;
+  transition: all 0.2s ease;
+}
+
+.status-tag:hover {
+  background: #ffffff;
+  border-color: #f56c6c;
+}
+
+.status-label {
+  font-size: 12px;
+  color: #303133;
+  font-weight: 500;
+}
+
+.status-count {
+  font-family: 'DIN Alternate', 'SF Pro Display', sans-serif;
+  font-size: 14px;
+  font-weight: 700;
+  color: #f56c6c;
+}
+
+.cursor-pointer {
+  cursor: pointer;
+}
+
+.empty-text {
+  text-align: center;
+  color: #999;
+  font-size: 13px;
+  padding: 8px 0;
+}
+.equip-tag-boiler {
+  color: #f56c6c !important;
+}
+.equip-tag-pipe {
+  color: #67c23a !important;
+}
+</style>

+ 3 - 4
yudao-ui-admin-vue3/src/views/pressure2/qrReport/PipeQrReport.vue

@@ -13,18 +13,17 @@ defineOptions({ name: 'PipeQrReport' })
 
 const pipeFields: Record<string, string> = {
   typeName: '管道类别',
-  equipCode: '工程号',
-  equipName: '工程名称',
+  equipName: '管道名称',
+  equipCode: '管道代码',
   useRegisterNo: '使用登记证编号',
   useUnitName: '使用单位',
   // pipeLevel: '管道级别',
-  productNo: '产品编号',
   reportNo: '报告编号',
   mainConclusion: '检验结论',
   nextCheckDate: '下次定期检验日期',
   nextYearCheckDate: '下次年度检查日期',
   checkDate: '检验日期',
   // checkOrganization: '检验机构',
-  checkTypeName: '检验性质'
+  checkTypeName: '检验性质',
 }
 </script>

+ 1 - 1
yudao-ui-admin-vue3/src/views/pressure2/qrReport/QrReportView.vue

@@ -10,7 +10,7 @@
       <div v-else-if="formData" class="qr-report-table">
         <div class="table-row" v-for="(label, key) in displayFields" :key="key">
           <div class="table-cell table-label">{{ label }}:</div>
-          <div class="table-cell table-value">{{ formData[key] || '-' }}</div>
+          <div class="table-cell table-value">{{ formData[key] }}</div>
         </div>
       </div>
       <div v-else-if="!loading" class="qr-report-error">暂无报告数据</div>