Browse Source

修改视频按顺序播放,修改标题和标签名称为当前站,修改导航,任务详情增加缺陷记录的跳转

master
douyage 1 week ago
parent
commit
8a175bb3a7
27 changed files with 277 additions and 72 deletions
  1. +1
    -1
      .env.development
  2. +1
    -1
      .env.htjc6
  3. +1
    -1
      .env.production
  4. +1
    -1
      .env.staging
  5. BIN
      public/aa-logo.png
  6. BIN
      public/favicon.ico
  7. +5
    -1
      src/App.vue
  8. BIN
      src/assets/images/header/baicaopo-title.png
  9. BIN
      src/assets/images/header/baiyangping-title.png
  10. BIN
      src/assets/images/header/quanping.png
  11. BIN
      src/assets/images/header/xiaogaoshan-title.png
  12. BIN
      src/assets/images/nav/menu-item-active-glow.png
  13. +19
    -0
      src/assets/styles/element-ui.scss
  14. +60
    -9
      src/assets/styles/sidebar.scss
  15. +16
    -1
      src/components/Screenfull/index.vue
  16. +3
    -2
      src/layout/components/Navbar.vue
  17. +1
    -1
      src/layout/components/Sidebar/Item.vue
  18. +1
    -1
      src/layout/components/Sidebar/SidebarItem.vue
  19. +2
    -2
      src/layout/components/Sidebar/index.vue
  20. +26
    -29
      src/layout/components/TagsView/index.vue
  21. +3
    -0
      src/main.js
  22. +55
    -0
      src/utils/stationTitle.js
  23. +32
    -2
      src/views/cards/defectRecord/index.vue
  24. +1
    -1
      src/views/cards/patrolReport/patrolReportDetail.vue
  25. +28
    -4
      src/views/cards/site_management/site_management.vue
  26. +15
    -0
      src/views/cards/taskSummary/newInspectionTaskDetail.vue
  27. +6
    -15
      src/views/video/LivePreview.vue

+ 1
- 1
.env.development View File

@ -1,5 +1,5 @@
# 页面标题
VUE_APP_TITLE = 智能巡检
VUE_APP_TITLE = 消防动环管理平台
# 开发环境配置
ENV = 'development'


+ 1
- 1
.env.htjc6 View File

@ -1,7 +1,7 @@
NODE_ENV = 'production'
ENV = 'production'
VUE_APP_TITLE = 智能巡检
VUE_APP_TITLE = 消防动环管理平台
VUE_APP_BASE_API = '/app/htjc6/api'
VUE_APP_NVR_API = '/nvr-api'


+ 1
- 1
.env.production View File

@ -1,5 +1,5 @@
# 页面标题
VUE_APP_TITLE = 智能巡检
VUE_APP_TITLE = 消防动环管理平台
# 生产环境配置
ENV = 'production'


+ 1
- 1
.env.staging View File

@ -1,5 +1,5 @@
# 页面标题
VUE_APP_TITLE = 智能巡检
VUE_APP_TITLE = 消防动环管理平台
BABEL_ENV = production


BIN
public/aa-logo.png View File

Before After
Width: 32  |  Height: 32  |  Size: 808 B Width: 256  |  Height: 256  |  Size: 33 KiB

BIN
public/favicon.ico View File

Before After
Width: 64  |  Height: 64  |  Size: 5.5 KiB

+ 5
- 1
src/App.vue View File

@ -7,15 +7,19 @@
<script>
import ThemePicker from "@/components/ThemePicker";
import { getStationConfig } from "@/utils/stationTitle";
export default {
name: "App",
components: { ThemePicker },
metaInfo() {
// 访 IP ""
// VUE_APP_TITLE
const stationName = getStationConfig().name;
return {
title: this.$store.state.settings.dynamicTitle && this.$store.state.settings.title,
titleTemplate: title => {
return title ? `${title} - ${process.env.VUE_APP_TITLE}` : process.env.VUE_APP_TITLE
return title ? `${title} - ${stationName}` : stationName
}
}
}


BIN
src/assets/images/header/baicaopo-title.png View File

Before After
Width: 1920  |  Height: 50  |  Size: 112 KiB

BIN
src/assets/images/header/baiyangping-title.png View File

Before After
Width: 1920  |  Height: 50  |  Size: 114 KiB

BIN
src/assets/images/header/quanping.png View File

Before After
Width: 19  |  Height: 18  |  Size: 626 B

BIN
src/assets/images/header/xiaogaoshan-title.png View File

Before After
Width: 1920  |  Height: 50  |  Size: 112 KiB

BIN
src/assets/images/nav/menu-item-active-glow.png View File

Before After
Width: 147  |  Height: 54  |  Size: 5.8 KiB

+ 19
- 0
src/assets/styles/element-ui.scss View File

@ -54,6 +54,25 @@
margin: 0 auto;
}
// 全局提示el-message固定高度内容垂直居中
// 个别接口返回的 msg 带换行/空行时消息框会被撑高文字挤到下半部分顶部多出一块空白
// 这里统一锁死高度并裁掉溢出保证提示条始终为单行高度
.el-message {
height: 48px !important;
box-sizing: border-box;
display: flex !important;
align-items: center !important;
padding-top: 0 !important;
padding-bottom: 0 !important;
overflow: hidden;
.el-message__content {
line-height: 18px !important;
max-height: 48px;
overflow: hidden;
}
}
// refine element ui upload
.upload-container {
.el-upload {


+ 60
- 9
src/assets/styles/sidebar.scss View File

@ -441,20 +441,71 @@
// the scroll bar appears when the subMenu is too long
>.el-menu--popup {
max-height: 100vh;
overflow-y: auto;
&::-webkit-scrollbar-track-piece {
background: #d3dce6;
}
// 设计稿样式横向标签条标签间竖线分隔选中项青色光效底图
// 弹框 append-to-bodyel-menu background-color/text-color 是内联样式覆盖需 !important
background-color: #0F124A !important;
border: 1px solid rgba(0, 168, 216, 0.45);
border-radius: 4px;
box-shadow: 0 0 14px rgba(0, 168, 216, 0.35);
display: flex;
flex-direction: row;
align-items: stretch;
width: max-content;
min-width: 0 !important;
max-width: calc(100vw - 180px);
padding: 0 !important;
overflow-x: auto;
overflow-y: hidden;
&::-webkit-scrollbar {
width: 6px;
height: 4px;
}
&::-webkit-scrollbar-thumb {
background: #99a9bf;
border-radius: 20px;
background: rgba(84, 255, 255, 0.35);
border-radius: 2px;
}
.el-menu-item {
position: relative;
height: 52px;
line-height: 52px;
margin: 0 !important;
padding: 0 26px !important;
border-radius: 0;
white-space: nowrap;
text-align: center;
color: #c0c5db !important;
background-color: transparent !important;
// 设计稿标签内不带图标
.svg-icon,
.menu-icon-img {
display: none;
}
// 标签之间短竖线分隔垂直居中不通高
& + .el-menu-item::before {
content: "";
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 1px;
height: 14px;
background: rgba(68, 180, 200, 0.85);
}
&:hover {
background-color: rgba(0, 168, 216, 0.15) !important;
color: #ffffff !important;
}
// 选中项青色文字 + 光效底图
&.is-active {
color: #54ffff !important;
background: url('~@/assets/images/nav/menu-item-active-glow.png') center / 100% 100% no-repeat !important;
}
}
}
}

+ 16
- 1
src/components/Screenfull/index.vue View File

@ -1,16 +1,25 @@
<template>
<div>
<svg-icon :icon-class="isFullscreen?'exit-fullscreen':'fullscreen'" @click="click" />
<!-- 非全屏态用设计稿提供的图片全屏态暂无对应切图沿用退出全屏 svg -->
<img
v-if="!isFullscreen"
class="screenfull-img"
:src="quanpingIcon"
@click="click"
>
<svg-icon v-else icon-class="exit-fullscreen" @click="click" />
</div>
</template>
<script>
import screenfull from 'screenfull'
import quanpingIcon from '@/assets/images/header/quanping.png'
export default {
name: 'Screenfull',
data() {
return {
quanpingIcon,
isFullscreen: false
}
},
@ -46,6 +55,12 @@ export default {
</script>
<style scoped>
.screenfull-img {
display: block;
cursor: pointer;
width: 19px;
height: 18px;
}
.screenfull-svg {
display: inline-block;
cursor: pointer;


+ 3
- 2
src/layout/components/Navbar.vue View File

@ -52,8 +52,8 @@ import { mapGetters } from "vuex";
import TopNav from "@/components/TopNav";
import Screenfull from "@/components/Screenfull";
import { getEmbeddedUser } from "@/utils/embeddedAuth";
import { getStationTitleImage } from "@/utils/stationTitle";
import headerLogo from "@/assets/images/header/logo.png";
import xfdhTitleNavbar from "@/assets/images/header/xfdh-title-navbar.png";
import xfdhBrand from "@/assets/images/header/xfdh-brand.png";
import loginAvatar from "@/assets/images/header/framework-avatar.png";
export default {
@ -64,7 +64,8 @@ export default {
data() {
return {
headerLogo,
xfdhTitleNavbar,
// 访 IP utils/stationTitle.js
xfdhTitleNavbar: getStationTitleImage(),
xfdhBrand,
loginAvatar,
frameworkUser: null,


+ 1
- 1
src/layout/components/Sidebar/Item.vue View File

@ -24,7 +24,7 @@ const navIconMap = {
'巡检任务管理': require('@/assets/images/nav/nav-task-management.png'),
'巡检任务': require('@/assets/images/nav/nav-task-management.png'),
'设备管理': require('@/assets/images/nav/nav-device.png'),
'点位管理(实施用)': require('@/assets/images/nav/nav-site-implementation.png'),
'点位配置': require('@/assets/images/nav/nav-site-implementation.png'),
'系统管理': require('@/assets/images/nav/nav-system.png'),
'区域管理': require('@/assets/images/nav/nav-area.png'),
'系统监控': require('@/assets/images/nav/nav-monitor.png'),


+ 1
- 1
src/layout/components/Sidebar/SidebarItem.vue View File

@ -167,7 +167,7 @@ export default {
this.basePath !== "/site-management" &&
this.basePath !== "/inspection-workspace/points"
) {
str = "点位管理(实施用)";
str = "点位配置";
}
return str;
}


+ 2
- 2
src/layout/components/Sidebar/index.vue View File

@ -66,7 +66,7 @@ export default {
"系统监控",
"基础数据",
]);
// () /site-management
// /site-management
// (/site-management)
const isImplementationPointsMenu = (route) => {
const title = String(route.meta && route.meta.title || "").split("|")[0];
@ -150,7 +150,7 @@ export default {
}] : [],
};
});
// ()
//
if (this.isAdminAccount) {
return [...workspaceMenus, ...visibleRoutes.filter(isImplementationPointsMenu)];
}


+ 26
- 29
src/layout/components/TagsView/index.vue View File

@ -364,6 +364,7 @@ export default {
height: 40px;
width: 100%;
position: relative;
//
background: url('~@/assets/images/module-title.png') center / 100% 100% no-repeat;
border: none;
box-shadow: none;
@ -496,46 +497,42 @@ export default {
display: inline-block;
position: relative;
cursor: pointer;
height: 26px;
line-height: 24px;
border: 1px solid rgba(72, 167, 255, 0.45);
color: #b9d8ff;
background: rgba(11, 36, 96, 0.85);
padding: 0 10px;
font-size: 12px;
margin-left: 8px;
margin-top: 6px;
height: 40px;
line-height: 40px;
border: 0;
color: #c0c5db;
background: transparent;
padding: 0 26px;
font-size: 14px;
margin: 0;
vertical-align: top;
box-sizing: border-box;
transition: color .2s, background-color .2s, border-color .2s, box-shadow .2s;
transition: color .2s, background-color .2s;
// 线稿线
& + .tags-view-item::after {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 1px;
height: 16px;
background: rgba(68, 180, 200, 0.85);
}
&:first-of-type {
margin-left: 0;
}
&:hover {
color: #54ffff;
border-color: rgba(84, 255, 255, 0.55);
color: #ffffff;
background: transparent;
}
&.active {
color: #ffffff;
background: linear-gradient(180deg, #1a7ad4 0%, #0f56a8 100%);
border-color: rgba(84, 255, 255, 0.65);
box-shadow: 0 0 8px rgba(23, 107, 194, 0.55);
&::before {
content: '';
background: #3ffffe;
display: inline-block;
width: 6px;
height: 6px;
border-radius: 50%;
position: relative;
margin-right: 5px;
vertical-align: 1px;
box-shadow: 0 0 4px rgba(63, 255, 254, 0.9);
}
color: #54ffff;
background: url('~@/assets/images/nav/menu-item-active-glow.png') center / 100% 100% no-repeat;
}
}
}


+ 3
- 0
src/main.js View File

@ -50,6 +50,9 @@ import 'video.js/dist/video-js.css'
import 'vue-video-player/src/custom-theme.css'
// 语言
import i18n from './lang'
// 站点配置:按访问 IP 切换标题头横幅与浏览器标签页站名
import { applyStationTitle } from '@/utils/stationTitle'
applyStationTitle()
// 全局方法挂载
Vue.prototype.getDicts = getDicts


+ 55
- 0
src/utils/stationTitle.js View File

@ -0,0 +1,55 @@
// 站点配置:按访问地址的 IP/域名(hostname)及端口切换导航栏标题头横幅和浏览器标签页站名。
// 后续接入新站点:把切图放到 src/assets/images/header/ 下,
// 在 stationConfigMap 里加一行 "<该站IP或域名>: { titleImage, name }" 即可;
// 同一 IP 不同端口是不同站点时,key 写成 "IP:端口"(如 "192.168.129.2:32799");
// 未匹配到的站点使用默认横幅和默认标题"消防动环管理平台"。
import defaultTitleImage from "@/assets/images/header/xfdh-title-navbar.png";
import baiyangpingTitleImage from "@/assets/images/header/baiyangping-title.png";
import baicaopoTitleImage from "@/assets/images/header/baicaopo-title.png";
import xiaogaoshanTitleImage from "@/assets/images/header/xiaogaoshan-title.png";
// 一个站点多个 IP 时逐个列出,指向同一份配置
const stationConfigMap = {
// 白杨坪站
"192.168.20.210": { titleImage: baiyangpingTitleImage, name: "白杨坪动环智能巡检系统" },
"192.168.134.10": { titleImage: baiyangpingTitleImage, name: "白杨坪动环智能巡检系统" },
"192.168.129.2:32799": { titleImage: baiyangpingTitleImage, name: "白杨坪动环智能巡检系统" },
// "192.168.1.90": { titleImage: xiaogaoshanTitleImage, name: "白杨坪智能巡检系统" },
// 白草坡站
"192.168.20.201": { titleImage: baicaopoTitleImage, name: "白草坡动环智能巡检系统" },
"192.168.147.13": { titleImage: baicaopoTitleImage, name: "白草坡动环智能巡检系统" },
"192.168.129.2:20001": { titleImage: baicaopoTitleImage, name: "白草坡动环智能巡检系统" },
// 小高山站
"192.168.20.222": { titleImage: xiaogaoshanTitleImage, name: "小高山动环智能巡检系统" },
"192.168.132.10": { titleImage: xiaogaoshanTitleImage, name: "小高山动环智能巡检系统" },
};
const defaultStationConfig = {
titleImage: defaultTitleImage,
// 默认站名(环境变量 VUE_APP_TITLE 是"智能巡检",与需求不符,故直接写死)
name: "消防动环管理平台",
};
export function getStationConfig() {
if (typeof window === "undefined") return defaultStationConfig;
const { hostname, port } = window.location;
// hostname 不含端口,端口要单独取;先按 "IP:端口" 精确匹配,再退回只按 IP 匹配
return (
(port && stationConfigMap[`${hostname}:${port}`]) ||
stationConfigMap[hostname] ||
defaultStationConfig
);
}
export function getStationTitleImage() {
return getStationConfig().titleImage;
}
// 应用启动时调用:按 IP 设置浏览器标签页标题(如"白杨坪智能巡检系统")
export function applyStationTitle() {
if (typeof document !== "undefined") {
document.title = getStationConfig().name;
}
}

+ 32
- 2
src/views/cards/defectRecord/index.vue View File

@ -111,7 +111,7 @@
:close-on-click-modal="false"
:close-on-press-escape="false"
:destroy-on-close="true"
custom-class="card-dialog card-page"
custom-class="card-dialog card-page defect-img-preview-dialog"
width="70%"
append-to-body
>
@ -227,7 +227,8 @@ export default {
this.imageLoadCount = 0;
this.expectedImageCount = 0;
defectRecordList({ pageNum: 1, pageSize: 9999 })
// 20
defectRecordList({ pageNum: 1, pageSize: 20 })
.then((res) => {
this.allDataList = res.rows || [];
this.applyFilters();
@ -530,3 +531,32 @@ export default {
background: #c8dcf5 !important;
}
</style>
<style lang="scss">
// append-to-body
// el-dialog body ImagePreview
.defect-img-preview-dialog {
height: 90vh;
margin-top: 5vh !important;
display: flex;
flex-direction: column;
overflow: hidden;
.el-dialog__header {
flex: 0 0 32px;
}
.el-dialog__body {
flex: 1 1 auto;
min-height: 0;
height: auto;
padding: 12px;
overflow: hidden;
> .card-page {
width: 100%;
height: 100%;
}
}
}
</style>

+ 1
- 1
src/views/cards/patrolReport/patrolReportDetail.vue View File

@ -308,7 +308,7 @@ export default {
getPointInfo() {
const headerInfoList = [
{
title1: "换流站",
title1: "升压站",
info1: this.reportInfo.stationName,
title2: "",
info2: "",


+ 28
- 4
src/views/cards/site_management/site_management.vue View File

@ -1357,6 +1357,10 @@ import ChooseAlg from "./components/chooseAlg.vue";
import Algorith from "@/views/cards/site_management/algorithm.vue";
import ImageAnnotation from "./components/ImageAnnotation.vue";
// key v2 localStorage
const DEFAULT_LEFT_PANEL_WIDTH = 200;
const LEFT_PANEL_WIDTH_STORAGE_KEY = "leftPanelWidthV2";
export default {
name: "site_management",
dicts: ["video_action_type", "point_impt_level", "system_type"],
@ -1584,7 +1588,7 @@ export default {
selectedDeviceTypeLabel: "", //
// -
leftPanelWidth: 260, //
leftPanelWidth: DEFAULT_LEFT_PANEL_WIDTH, //
minLeftWidth: 200, //
maxLeftWidth: 600, //
tableLayoutFrame: null,
@ -2357,7 +2361,7 @@ export default {
//
saveLeftPanelWidth() {
try {
localStorage.setItem("leftPanelWidth", this.leftPanelWidth);
localStorage.setItem(LEFT_PANEL_WIDTH_STORAGE_KEY, this.leftPanelWidth);
} catch (e) {
// console.warn(':', e);
}
@ -2366,7 +2370,7 @@ export default {
//
loadLeftPanelWidth() {
try {
const savedWidth = localStorage.getItem("leftPanelWidth");
const savedWidth = localStorage.getItem(LEFT_PANEL_WIDTH_STORAGE_KEY);
if (savedWidth) {
this.leftPanelWidth = parseInt(savedWidth, 10);
}
@ -2377,7 +2381,7 @@ export default {
//
resetLeftPanelWidth() {
this.leftPanelWidth = 260;
this.leftPanelWidth = DEFAULT_LEFT_PANEL_WIDTH;
this.saveLeftPanelWidth();
//
this.$nextTick(() => {
@ -5025,4 +5029,24 @@ export default {
min-height: 0;
}
}
/* /append-to-body
选择器带 .el-dialog 提高优先级覆盖全局 ruoyi.scss margin-top:6vh!important
element-ui.scss transform:none/left:0/position:relative */
.el-dialog.site-point-add-dialog:not(.is-fullscreen) {
display: flex;
flex-direction: column;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
margin: 0 !important;
max-height: calc(100vh - 40px);
overflow: hidden;
.el-dialog__body {
max-height: calc(100vh - 160px);
overflow-y: auto;
}
}
</style>

+ 15
- 0
src/views/cards/taskSummary/newInspectionTaskDetail.vue View File

@ -240,6 +240,13 @@
:loading="loading"
>导出</el-button
>
<el-button
type="primary"
icon="el-icon-document"
size="small"
@click="goDefectRecord"
>缺陷记录</el-button
>
</el-form-item>
</el-form>
</div>
@ -803,6 +810,14 @@ export default {
);
},
//
goDefectRecord() {
const path = this.$route.meta.patrolWorkspace
? "/inspection-workspace/defects"
: "/defect-record/index";
this.$router.push(path);
},
getPointList() {
this.loading = true;
taskInfoList(this.queryParams)


+ 6
- 15
src/views/video/LivePreview.vue View File

@ -287,7 +287,7 @@ export default {
this.$root.$emit('video-layout-updated', this.layout)
if (this.channels.length) {
this.streamsInitialized = true
this.populateRandomLayout()
this.populateDefaultLayout()
}
},
deactivated() {
@ -382,7 +382,7 @@ export default {
})
if (initializeStreams && this.pageActive && !this.streamsInitialized && this.channels.length) {
this.streamsInitialized = true
this.populateRandomLayout()
this.populateDefaultLayout()
}
},
isCameraCodeName(name) {
@ -399,19 +399,10 @@ export default {
if (treeCodes.size) this.channels = this.channels.filter(item => treeCodes.has(item.cameraCode))
this.setAvailableChannels(channels, true)
},
shuffleChannels() {
const channels = this.channels.slice()
for (let index = channels.length - 1; index > 0; index -= 1) {
const randomIndex = Math.floor(Math.random() * (index + 1))
const current = channels[index]
channels[index] = channels[randomIndex]
channels[randomIndex] = current
}
return channels
},
async populateRandomLayout() {
async populateDefaultLayout() {
if (!this.pageActive) return
const channels = this.shuffleChannels().slice(0, this.capacity)
//
const channels = this.channels.slice(0, this.capacity)
if (!channels.length) return
await Promise.all(this.slots.map((slot, index) => slot ? this.closeSlot(index, false) : null))
if (!this.pageActive) return
@ -535,7 +526,7 @@ export default {
if (layout === this.layout) return
this.layout = layout
this.$root.$emit('video-layout-updated', layout)
this.populateRandomLayout()
this.populateDefaultLayout()
},
changeControlPanel(expanded) {
this.controlPanelExpanded = Boolean(expanded)


Loading…
Cancel
Save