Browse Source

feat(warning): 预警联动处置系统菜单按钮授权

- 预警查询页"详情""流程"按钮添加 v-hasPermi 权限指令
- 预警发布页"查看"按钮添加权限控制
- 待处理预警页"查看详情"按钮添加权限控制及 JS 层校验
- 预警关联页根据权限控制关联状态列、统计数值及操作按钮的显隐
- 预警关联页"关联预警""查看预警""批量关联"等按钮分别绑定 query/edit 权限
- 各页面导入 auth 插件,在方法层增加 hasPermi 前置校验防止越权调用
- 更新 memory/index.md 会话记录索引
林仔 5 days ago
parent
commit
7bf06ea3ae

+ 1 - 0
memory/index.md

@@ -66,6 +66,7 @@ npm run dev       # 默认 http://localhost:80
 
 ## 会话记录
 
+- [2026-10-15:预警联动处置系统菜单按钮授权](sessions/2026-10-15.md)
 - [2026-10-14:故障通知筛选与两端核实命名、工单取消限制、本人登录日志、照片按组切换、性别单选、移动端接口分层及统一前缀](sessions/2026-10-14.md)
 - [2026-10-13:移动端工单管理、待办、详情与操作接入](sessions/2026-10-13.md)
 - [2026-10-12:工单派单增加核验人](sessions/2026-10-12.md)

+ 17 - 9
src/views/subSystem/lifeCompany/lAlertInformation/LCorrelation.vue

@@ -21,12 +21,12 @@
       </el-card>
       <el-card shadow="hover" class="summary-card success">
         <div class="summary-label">已关联</div>
-        <div class="summary-value">{{ stats.linkedCount }}</div>
+        <div class="summary-value">{{ canViewRelations ? stats.linkedCount : '-' }}</div>
         <div class="summary-desc">已建立报警与预警关联关系</div>
       </el-card>
       <el-card shadow="hover" class="summary-card warning">
         <div class="summary-label">未关联</div>
-        <div class="summary-value">{{ stats.unlinkedCount }}</div>
+        <div class="summary-value">{{ canViewRelations ? stats.unlinkedCount : '-' }}</div>
         <div class="summary-desc">仍待人工选择预警进行关联</div>
       </el-card>
       <el-card shadow="hover" class="summary-card info">
@@ -62,7 +62,7 @@
             <el-option label="已处理" :value="1" />
           </el-select>
         </el-form-item>
-        <el-form-item label="关联状态">
+        <el-form-item v-if="canViewRelations" label="关联状态">
           <el-select v-model="queryParams.associationStatus" placeholder="请选择关联状态" clearable style="width: 180px">
             <el-option label="已关联" value="linked" />
             <el-option label="未关联" value="unlinked" />
@@ -93,7 +93,8 @@
         </el-table-column>
         <el-table-column label="关联状态" width="100" align="center">
           <template #default="scope">
-            <el-tag :type="scope.row.linkedWarning ? 'success' : 'info'">
+            <span v-if="!canViewRelations" class="empty-text">无查看权限</span>
+            <el-tag v-else :type="scope.row.linkedWarning ? 'success' : 'info'">
               {{ scope.row.linkedWarning ? "已关联" : "未关联" }}
             </el-tag>
           </template>
@@ -102,6 +103,7 @@
           <template #default="scope">
             <span
               v-if="scope.row.linkedWarning"
+              v-hasPermi="['warning:warning:query']"
               class="warning-link"
               @click="openWarningDetail(scope.row.linkedWarning.warningId)"
             >
@@ -112,10 +114,10 @@
         </el-table-column>
         <el-table-column label="操作" fixed="right" width="220" align="center">
           <template #default="scope">
-            <el-button link type="primary" @click="openAssociationDialog(scope.row)" v-if="!scope.row.linkedWarning">
+            <el-button v-hasPermi="['warning:warning:edit']" link type="primary" @click="openAssociationDialog(scope.row)" v-if="!scope.row.linkedWarning && auth.hasPermi('warning:warning:query')">
               关联预警
             </el-button>
-            <el-button link type="success" @click="openWarningDetail(scope.row.linkedWarning.warningId)" v-if="scope.row.linkedWarning">
+            <el-button v-hasPermi="['warning:warning:query']" link type="success" @click="openWarningDetail(scope.row.linkedWarning.warningId)" v-if="scope.row.linkedWarning">
               查看预警
             </el-button>
             <el-button link type="info" @click="openAlarmDetail(scope.row)">报警详情</el-button>
@@ -132,7 +134,7 @@
       />
     </el-card>
 
-    <div class="batch-bar" v-if="selectedRows.length">
+    <div class="batch-bar" v-if="selectedRows.length && auth.hasPermi('warning:warning:query')" v-hasPermi="['warning:warning:edit']">
       <span>已选择 {{ selectedRows.length }} 条报警</span>
       <el-button type="primary" @click="openBatchAssociationDialog">批量关联预警</el-button>
       <el-button @click="selectedRows = []">清空选择</el-button>
@@ -168,7 +170,7 @@
       <template #footer>
         <div class="dialog-footer">
           <el-button @click="associationDialog.visible = false">取 消</el-button>
-          <el-button type="primary" :loading="submitLoading" @click="confirmAssociation">确 定</el-button>
+          <el-button v-hasPermi="['warning:warning:edit']" type="primary" :loading="submitLoading" @click="confirmAssociation">确 定</el-button>
         </div>
       </template>
     </el-dialog>
@@ -192,7 +194,7 @@
       <template #footer>
         <div class="dialog-footer">
           <el-button @click="batchDialog.visible = false">取 消</el-button>
-          <el-button type="primary" :loading="submitLoading" @click="confirmBatchAssociation">确 定</el-button>
+          <el-button v-hasPermi="['warning:warning:edit']" type="primary" :loading="submitLoading" @click="confirmBatchAssociation">确 定</el-button>
         </div>
       </template>
     </el-dialog>
@@ -238,6 +240,7 @@
 
 <script setup>
 import { computed, onMounted, reactive, ref } from "vue";
+import auth from '@/plugins/auth';
 import { ElMessage } from "element-plus";
 import {
   getAlarmPageData,
@@ -255,6 +258,7 @@ const availableWarnings = ref([]);
 const rawAlarmList = ref([]);
 const selectedRows = ref([]);
 const linkedAlarmMap = ref({});
+const canViewRelations = computed(() => auth.hasPermi('warning:warning:query'));
 
 const total = ref(0);
 const warningDetailVisible = ref(false);
@@ -399,6 +403,10 @@ async function loadWarnings() {
 }
 
 async function buildLinkedAlarmMap() {
+  if (!auth.hasPermi('warning:warning:query')) {
+    linkedAlarmMap.value = {};
+    return;
+  }
   const map = {};
   await Promise.all(
     availableWarnings.value.map(async (warning) => {

+ 1 - 1
src/views/subSystem/lifeCompany/lAlertInformation/LRelease.vue

@@ -96,7 +96,7 @@
         </el-table-column>
         <el-table-column label="操作" fixed="right" width="280" align="center">
           <template #default="scope">
-            <el-button link type="primary" @click="handleView(scope.row)">查看</el-button>
+            <el-button v-hasPermi="['warning:warning:query']" link type="primary" @click="handleView(scope.row)">查看</el-button>
             <el-button v-if="scope.row.status === 'DRAFT'" v-hasPermi="['warning:warning:edit']" link type="primary" @click="handleEdit(scope.row)">编辑</el-button>
             <el-button v-if="scope.row.status === 'DRAFT'" v-hasPermi="['warning:warning:publish']" link type="success" @click="handlePublish(scope.row)">发布</el-button>
             <el-button v-if="scope.row.status === 'DRAFT'" v-hasPermi="['warning:warning:remove']" link type="danger" @click="handleDelete(scope.row)">删除</el-button>

+ 3 - 1
src/views/subSystem/lifeCompany/lAlertInformation/LTobeHandled.vue

@@ -144,7 +144,7 @@
         </el-table-column>
         <el-table-column label="操作" fixed="right" width="300" align="center">
           <template #default="scope">
-            <el-button link type="primary" @click.stop="handleViewDetail(scope.row)">查看详情</el-button>
+            <el-button v-hasPermi="['warning:warning:query']" link type="primary" @click.stop="handleViewDetail(scope.row)">查看详情</el-button>
             <template v-if="activeTab === 'TODO'">
               <WarningWorkflowActions :row="scope.row" @changed="refreshLists" />
             </template>
@@ -270,6 +270,7 @@ import WarningDisposalReasons from '../components/WarningDisposalReasons.vue';
 import WarningAttachments from "../components/WarningAttachments.vue";
 import { attachmentsForDisposal, unlinkedWarningAttachments } from "../warningAttachments";
 import { computed, onMounted, reactive, ref } from "vue";
+import auth from '@/plugins/auth';
 import { ElMessage, ElMessageBox } from "element-plus";
 import { parseTime } from "@/utils/ruoyi";
 import WarningWorkflowActions from "../WarningWorkflowActions.vue";
@@ -530,6 +531,7 @@ async function refreshLists() {
 }
 
 async function handleViewDetail(row) {
+  if (!auth.hasPermi('warning:warning:query')) return;
   const res = await getWarningDetailData(row.warningId);
   detailData.value = res.data || {};
   selectedNotice.value = activeTab.value === "NOTICE" ? row.taskName : "";

+ 6 - 3
src/views/subSystem/lifeCompany/lwarningInfoCont/LAlertQuery.vue

@@ -114,8 +114,8 @@
         <el-table-column label="发布时间" prop="publishTime" width="180" />
         <el-table-column label="操作" width="150" fixed="right" align="center">
           <template #default="scope">
-            <el-button link type="primary" @click.stop="openDetail(scope.row)">详情</el-button>
-            <el-button link type="success" @click.stop="handleSelectWarning(scope.row)">流程</el-button>
+            <el-button v-hasPermi="['warning:warning:query']" link type="primary" @click.stop="openDetail(scope.row)">详情</el-button>
+            <el-button v-hasPermi="['warning:warning:query']" link type="success" @click.stop="handleSelectWarning(scope.row)">流程</el-button>
           </template>
         </el-table-column>
       </el-table>
@@ -275,6 +275,7 @@
 import { useWarningStatuses } from '@/views/subSystem/lifeCompany/warningWorkflow'
 const { warningStatusOptions, databaseStatusLabels } = useWarningStatuses()
 import { computed, onMounted, reactive, ref } from "vue";
+import auth from '@/plugins/auth';
 import { parseTime } from "@/utils/ruoyi";
 import WarningItemSummary from '../components/WarningItemSummary.vue';
 import WarningDisposalReasons from '../components/WarningDisposalReasons.vue';
@@ -504,7 +505,7 @@ async function loadTrackList() {
 }
 
 async function loadProcessData(warningId) {
-  if (!warningId) return;
+  if (!warningId || !auth.hasPermi('warning:warning:query')) return;
   processAttachments.value = [];
   const [processRes, statisticsRes, diagramRes, attachmentsRes] = await Promise.all([
     getWarningProcessData(warningId),
@@ -519,12 +520,14 @@ async function loadProcessData(warningId) {
 }
 
 async function openDetail(row) {
+  if (!auth.hasPermi('warning:warning:query')) return;
   const res = await getWarningDetailData(row.warningId);
   detailData.value = res.data || {};
   detailVisible.value = true;
 }
 
 async function handleSelectWarning(row) {
+  if (!auth.hasPermi('warning:warning:query')) return;
   selectedWarningId.value = row.warningId;
   selectedWarningRow.value = row;
   await loadProcessData(row.warningId);

+ 1 - 1
src/views/subSystem/lifeCompany/lwarningInfoCont/LwarningDisp.vue

@@ -97,7 +97,7 @@
         </el-table-column>
         <el-table-column label="操作" fixed="right" width="330" align="center">
           <template #default="scope">
-            <el-button link type="primary" @click="openDetail(scope.row)">详情</el-button>
+            <el-button v-hasPermi="['warning:warning:query']" link type="primary" @click="openDetail(scope.row)">详情</el-button>
             <el-button v-if="canReview(scope.row)" v-hasPermi="['warning:warning:handle']" link type="success" @click="openResolve(scope.row)">核查解除</el-button>
             <el-button v-if="canUpgrade(scope.row)" v-hasPermi="['warning:warning:handle']" link type="warning" @click="openUpgrade(scope.row)">升级</el-button>
             <el-button v-if="canManage(scope.row)" v-hasPermi="['warning:warning:supervision']" link type="primary" @click="openSupervision(scope.row)">督办</el-button>