Forráskód Böngészése

上传组件回显图片问题处理

zengy 1 napja
szülő
commit
914d2aa5d0

+ 1 - 0
src/components/ImageUpload/index.vue

@@ -98,6 +98,7 @@ function flushUploadBatch() {
       group.forEach(({ options, resolve }, i) => {
         const info = infos[i] || {};
         options.onSuccess({
+          code: 200,
           relativePath: info.relativePath || info.url,
           url: info.url,
           fileName: info.fileName,

+ 0 - 6
src/router/alarmMenuView.js

@@ -1,9 +1,3 @@
-/** 报警核实菜单兼容现有数据库名称,路由和权限不变。 */
-export function resolveAlarmMenuTitle(view, title) {
-  return ['subSystem/alarm/common/audit', 'subSystem/alarm/audit', 'subSystem/waterSupply/monitorAlarm/audit'].includes(view)
-    && title === '报警审核' ? '报警核实' : title
-}
-
 /** 按菜单的数据范围选择供水专属报警管理,不改数据库下发的 path/name。 */
 export function resolveAlarmMenuView(view, rawQuery) {
   let query = rawQuery || {}

+ 1 - 2
src/store/modules/permission.js

@@ -5,7 +5,7 @@ import Layout from '@/layout/index'
 import ParentView from '@/components/ParentView'
 import InnerLink from '@/layout/components/InnerLink'
 import { ensureUniqueSubsystemRouteNames } from '@/router/routeNameUtils'
-import { resolveAlarmMenuTitle, resolveAlarmMenuView } from '@/router/alarmMenuView'
+import { resolveAlarmMenuView } from '@/router/alarmMenuView'
 import { toNestedRoutePath } from '@/router/nestedRouteUtils'
 import { joinRoutePath } from '@/utils/ruoyi'
 
@@ -66,7 +66,6 @@ function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {
       route.children = filterChildren(route.children, false, route.path)
     }
     if (route.component) {
-      if (route.meta) route.meta.title = resolveAlarmMenuTitle(route.component, route.meta.title)
       // Layout ParentView 组件特殊处理
       if (route.component === 'Layout') {
         route.component = Layout

+ 1 - 1
src/views/subSystem/dispatch/disOnDuty/gzjc.vue

@@ -290,7 +290,7 @@ function gzjcFlushUploadBatch() {
       const infos = res.files || []
       group.forEach(({ options, resolve }, i) => {
         const info = infos[i] || {}
-        options.onSuccess(info)
+        options.onSuccess({ code: 200, ...info })
         resolve()
       })
     } else {

+ 1 - 1
src/views/subSystem/lifeCompany/components/WarningDetailDrawer.vue

@@ -71,7 +71,7 @@
           <el-descriptions :column="2" border>
             <el-descriptions-item label="发布人">{{ basic.publisherName || basic.publisher || '-' }}</el-descriptions-item>
             <el-descriptions-item label="处置人">{{ basic.handlerName || basic.handler || '-' }}</el-descriptions-item>
-            <el-descriptions-item label="核验人">{{ basic.reviewerName || basic.reviewer || basic.publisherName || basic.publisher || '-' }}</el-descriptions-item>
+            <el-descriptions-item label="核验人">{{ basic.reviewerName || basic.reviewer || '-' }}</el-descriptions-item>
           </el-descriptions>
         </section>
 

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

@@ -265,7 +265,7 @@ function enrichTodoRows(records) {
       warningLevelText: warningLevelLabelMap.value[warningLevel] || "-",
       ownershipUnit: item.ownership_unit || item.ownershipUnit || "",
       publishTime: item.publish_time || item.publishTime || "",
-      reviewer: item.reviewer || item.publisher || "",
+      reviewer: item.reviewer || "",
       alarmCodeList: String(item.alarm_numbers || item.alarmNumbers || "").split(",").filter(Boolean),
       availableActions: item.availableActions || [],
       todoType: item.todo_type || item.todoType,

+ 59 - 6
src/views/subSystem/pipeNetwork/pinteControl/PrealTimeShow.vue

@@ -135,7 +135,10 @@
                 <span class="alarm-dev">{{ a.deviceName || a.deviceCode }}<span class="alarm-code">{{ a.deviceCode }}</span></span>
                 <span class="alarm-level" :style="{ color: levelColor(a.alarmLevel) }">{{ levelName(a.alarmLevel) }}</span>
               </div>
-              <div class="alarm-time">{{ a.createTime }}</div>
+              <div class="alarm-time">
+                <span v-if="a.alarmNo" class="alarm-no">{{ a.alarmNo }}</span>
+                <span>{{ a.createTime }}</span>
+              </div>
               <div class="alarm-desc">{{ a.alarmContent || "—" }} <span v-if="a.actualValue != null">实测 {{ a.actualValue }}</span></div>
             </div>
             <el-empty v-if="!alarms.length" description="当前无未解除报警" :image-size="60" />
@@ -176,7 +179,7 @@
       append-to-body
       direction="rtl"
       @opened="startProfileTimer"
-      @closed="stopProfileTimer"
+      @closed="onDrawerClosed"
     >
       <template #header>
         <div class="drawer-title" v-if="profile.base">
@@ -207,11 +210,23 @@
                   v-for="c in recordViewColumns"
                   :key="c.key"
                   :label="c.label + (c.unit ? '(' + c.unit + ')' : '')"
-                  :min-width="c.key === 'create_time' ? 168 : 104"
-                  show-overflow-tooltip
+                  :min-width="c.key === 'create_time' ? 168 : (c.key === 'filepath' ? 180 : 104)"
                 >
-                  <template #default="{ row }">
+                  <template #default="{ row, $index }">
                     <span v-if="c.key === 'create_time'">{{ row.createTime || '—' }}</span>
+                    <span v-else-if="c.key === 'filepath'">
+                      <el-button
+                        v-if="valueOf(row, c.key) && valueOf(row, c.key) !== '—'"
+                        class="rec-play-btn"
+                        size="small"
+                        circle
+                        :type="isPlayingCell($index, c.key) ? 'primary' : 'default'"
+                        @click="toggleAudio($index, c.key, row)"
+                      >
+                        <el-icon><VideoPause v-if="isPlayingCell($index, c.key)" /><VideoPlay v-else /></el-icon>
+                      </el-button>
+                      <span v-else>—</span>
+                    </span>
                     <span v-else :class="{ 'cell-alarm': alarmOf(row, c.key) }">{{ valueOf(row, c.key) }}</span>
                   </template>
                 </el-table-column>
@@ -228,6 +243,7 @@
                 small
                 v-model:current-page="recordPage"
               />
+              <audio ref="recordAudio" class="rec-audio-single" @ended="onAudioEnded"></audio>
             </div>
           </div>
 
@@ -251,6 +267,7 @@ import {
   getAreaRank,
   getAlarmTypeDist
 } from "@/api/pipeNetwork/perception";
+import { buildMinioAttachmentUrl } from "@/utils/minioAttachment";
 
 const loading = ref(false);
 const stats = ref({});
@@ -387,6 +404,40 @@ function alarmOf(row, key) {
   return c ? !!c.alarm : false;
 }
 
+// 采集记录音频播放:单例 audio,一次只播一条
+const recordAudio = ref(null);
+const playingKey = ref("");
+
+function cellPlayKey(index, key) {
+  return index + ":" + key;
+}
+function isPlayingCell(index, key) {
+  return playingKey.value === cellPlayKey(index, key);
+}
+function toggleAudio(index, key, row) {
+  const el = recordAudio.value;
+  if (!el) return;
+  const k = cellPlayKey(index, key);
+  if (playingKey.value === k) {
+    el.pause();
+    playingKey.value = "";
+    return;
+  }
+  const v = valueOf(row, key);
+  if (!v || v === "—") return;
+  el.src = buildMinioAttachmentUrl(v);
+  el.play().catch(() => {});
+  playingKey.value = k;
+}
+function onAudioEnded() {
+  playingKey.value = "";
+}
+function onDrawerClosed() {
+  stopProfileTimer();
+  if (recordAudio.value) recordAudio.value.pause();
+  playingKey.value = "";
+}
+
 // 报警等级配色(与系统 alarm 模块保持一致:1红 2橙 3蓝 4绿)
 function levelColor(level) {
   return ({ 1: "#f56c6c", 2: "#e6a23c", 3: "#409eff", 4: "#67c23a" }[level] || "#909399");
@@ -705,7 +756,8 @@ onBeforeUnmount(() => {
 .alarm-item { padding: 11px 16px; border-bottom: 1px solid #eef2f7; border-left: 3px solid #ef4444; }
 .alarm-item:hover { background: #f8fbff; }
 .alarm-top { display: flex; justify-content: space-between; align-items: center; gap: 8px; margin-bottom: 4px; }
-.alarm-time { font-size: 12px; color: #97a3b7; font-variant-numeric: tabular-nums; margin-bottom: 4px; }
+.alarm-time { display: flex; justify-content: space-between; align-items: center; gap: 8px; font-size: 12px; color: #97a3b7; font-variant-numeric: tabular-nums; margin-bottom: 4px; }
+.alarm-no { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; color: #8a96a8; white-space: nowrap; }
 .alarm-dev { font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: flex; align-items: center; min-width: 0; }
 .alarm-code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 11px; font-weight: 600; color: #5e6d82; background: #f1f5f9; border: 1px solid #e3e9f2; border-radius: 4px; padding: 1px 5px; margin-left: 6px; flex: none; white-space: nowrap; }
 .alarm-level { font-size: 12px; font-weight: 600; flex: none; }
@@ -748,6 +800,7 @@ onBeforeUnmount(() => {
 .hist-wrap :deep(.el-table__inner-wrapper::after) { display: none; }
 .hist-wrap :deep(.el-table .el-table__row:last-child td.el-table__cell) { border-bottom: none; }
 .rec-empty { color: #9aa7b8; font-size: 12px; padding: 28px 0; }
+.rec-audio-single { display: none; }
 .rec-pager { margin-top: 10px; justify-content: flex-end; }
 
 @keyframes pulse {