提交 80a23c4d authored 作者: zhuyongshuai's avatar zhuyongshuai

灭火2025/8/19

上级 7701ae0c
# # 页面标题 # # # 页面标题
VITE_APP_TITLE = '卫星仿真系统平台' # VITE_APP_TITLE = '卫星仿真系统平台'
# # 开发环境配置 # # # 开发环境配置
# VITE_APP_ENV = 'development' # # VITE_APP_ENV = 'development'
# # 若依管理系统/开发环境 # # # 若依管理系统/开发环境
# VITE_API_URL = '/dev-api' # # VITE_API_URL = '/dev-api'
# NODE_ENV="development" # # NODE_ENV="development"
# VITE_API_URL = http://211.149.190.82:18080 VITE_API_URL = http://211.149.190.82:18080
# ENV = development # 本地环境 # # ENV = development # 本地环境
# VITE_API_URL = http://localhost:8888/ # 本地环境接口地址 # # VITE_API_URL = http://localhost:8888/ # 本地环境接口地址
# 本地环境 # # 本地环境
MODE_ENV = development # MODE_ENV = development
# 本地环境接口地址 # # 本地环境接口地址
VITE_API_URL = /api VITE_API_URL = /api
\ No newline at end of file
...@@ -21,7 +21,9 @@ ...@@ -21,7 +21,9 @@
"qs": "^6.13.1", "qs": "^6.13.1",
"vue": "^3.5.13", "vue": "^3.5.13",
"vue-router": "^4.5.0", "vue-router": "^4.5.0",
"vuedraggable": "4.1.0" "vuedraggable": "4.1.0",
"vxe-pc-ui": "^4.8.20",
"vxe-table": "^4.15.9"
}, },
"devDependencies": { "devDependencies": {
"@vitejs/plugin-vue": "^5.2.1", "@vitejs/plugin-vue": "^5.2.1",
...@@ -1151,6 +1153,18 @@ ...@@ -1151,6 +1153,18 @@
} }
} }
}, },
"node_modules/@vxe-ui/core": {
"version": "4.2.11",
"resolved": "https://registry.npmmirror.com/@vxe-ui/core/-/core-4.2.11.tgz",
"integrity": "sha512-Cv0XKTGgFD+CD2MGixxM+k60Y3tFEJYErQj59tuPd0y0HuSFc7sQk0fuXdbcNgxZxtAi4zX3nsDk3kY+/HeAgQ==",
"dependencies": {
"dom-zindex": "^1.0.6",
"xe-utils": "^3.7.8"
},
"peerDependencies": {
"vue": "^3.2.0"
}
},
"node_modules/acorn": { "node_modules/acorn": {
"version": "8.14.1", "version": "8.14.1",
"resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.14.1.tgz", "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.14.1.tgz",
...@@ -2043,6 +2057,11 @@ ...@@ -2043,6 +2057,11 @@
"url": "https://github.com/fb55/entities?sponsor=1" "url": "https://github.com/fb55/entities?sponsor=1"
} }
}, },
"node_modules/dom-zindex": {
"version": "1.0.6",
"resolved": "https://registry.npmmirror.com/dom-zindex/-/dom-zindex-1.0.6.tgz",
"integrity": "sha512-FKWIhiU96bi3xpP9ewRMgANsoVmMUBnMnmpCT6dPMZOunVYJQmJhSRruoI0XSPoHeIif3kyEuiHbFrOJwEJaEA=="
},
"node_modules/domelementtype": { "node_modules/domelementtype": {
"version": "1.3.1", "version": "1.3.1",
"resolved": "https://registry.npmmirror.com/domelementtype/-/domelementtype-1.3.1.tgz", "resolved": "https://registry.npmmirror.com/domelementtype/-/domelementtype-1.3.1.tgz",
...@@ -6114,6 +6133,22 @@ ...@@ -6114,6 +6133,22 @@
"vue": "^3.0.1" "vue": "^3.0.1"
} }
}, },
"node_modules/vxe-pc-ui": {
"version": "4.8.20",
"resolved": "https://registry.npmmirror.com/vxe-pc-ui/-/vxe-pc-ui-4.8.20.tgz",
"integrity": "sha512-//Ixq6Q1iBPZua4ia8/DjF7ZoWG2rb10mr2PuQHTJHsbI3I0mXhq6PyouMnMehjfFBhSyLMl9nrQbtIh/lFFeg==",
"dependencies": {
"@vxe-ui/core": "^4.2.11"
}
},
"node_modules/vxe-table": {
"version": "4.15.9",
"resolved": "https://registry.npmmirror.com/vxe-table/-/vxe-table-4.15.9.tgz",
"integrity": "sha512-zWFyW3Oi4bXQ5J2oiaaa+lXDbo4EBzX2EyjQKagBQYS4zaL8V5mzV4fxG4xWiW8V86pojbubSIVaiSKSaMj4tg==",
"dependencies": {
"vxe-pc-ui": "^4.8.0"
}
},
"node_modules/warning": { "node_modules/warning": {
"version": "4.0.3", "version": "4.0.3",
"resolved": "https://registry.npmmirror.com/warning/-/warning-4.0.3.tgz", "resolved": "https://registry.npmmirror.com/warning/-/warning-4.0.3.tgz",
...@@ -6219,6 +6254,11 @@ ...@@ -6219,6 +6254,11 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/xe-utils": {
"version": "3.7.8",
"resolved": "https://registry.npmmirror.com/xe-utils/-/xe-utils-3.7.8.tgz",
"integrity": "sha512-V/k6B/ASYir6yLYhp62DnM17po9u1N9mou/rn4if5WoFCsAO49JpCiVpkDpwCv4zxGfWmhWgzmz4FytWF+pDVw=="
},
"node_modules/zrender": { "node_modules/zrender": {
"version": "5.6.0", "version": "5.6.0",
"resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.6.0.tgz", "resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.6.0.tgz",
......
...@@ -25,7 +25,9 @@ ...@@ -25,7 +25,9 @@
"qs": "^6.13.1", "qs": "^6.13.1",
"vue": "^3.5.13", "vue": "^3.5.13",
"vue-router": "^4.5.0", "vue-router": "^4.5.0",
"vuedraggable": "4.1.0" "vuedraggable": "4.1.0",
"vxe-pc-ui": "~4.8.20",
"vxe-table": "~4.15.9"
}, },
"devDependencies": { "devDependencies": {
"@vitejs/plugin-vue": "^5.2.1", "@vitejs/plugin-vue": "^5.2.1",
......
//建筑管理 //建筑管理
import qs from 'qs' import qs from 'qs'
import request from '@/utils/request' import request from '@/utils/request'
// 人员添加接口
export function staffAddApi(data) { /**
* 建筑添加接口
* @param {Object} data - 请求数据
* @returns {Promise} 返回请求结果
*/
export function buildingAddApi(data) {
return request({ return request({
url: '/user/add', url: '/build/add',
method: 'post', method: 'post',
data, data,
}) })
} }
// 人员修改
export function staffEditApi(data) { /**
* 获取建筑信息接口
* @param {Object} data - 请求数据
* @returns {Promise} 返回请求结果
*/
export function buildingGetInfoApi(data) {
return request({ return request({
url: '/user/update', url: '/build/getInfo',
method: 'post', method: 'post',
data, data,
}) })
} }
// 详情
export function staffDetailApi(data) {
return request({ /**
url: `/user/getInfo`, * 建筑分页查询接口
method: 'get', * @param {Object} data - 请求数据
params: data * @returns {Promise} 返回请求结果
}) */
} export function buildingPageApi(data) {
//分页
export function staffListApi(data) {
return request({ return request({
url: '/user/page', url: '/build/page',
method: 'post', method: 'post',
data, data,
}) })
} }
// 删除
export function staffDelApi(data) { /**
* 删除建筑接口
* @param {Object} data - 请求数据
* @returns {Promise} 返回请求结果
*/
export function buildingRemoveApi(data) {
return request({ return request({
url: `/user/remove`, url: '/build/remove',
method: 'get', method: 'post',
params: data data,
headers: { // 请求头
'Content-Type': 'multipart/form-data'
}
}) })
} }
export function staffAerialViewApi(data) { /**
* 更新建筑信息接口
* @param {Object} data - 请求数据
* @returns {Promise} 返回请求结果
*/
export function buildingUpdateApi(data) {
return request({ return request({
url: `/project/list`, url: '/build/update',
method: 'get', method: 'post',
params: data data,
}) })
} }
\ No newline at end of file
import qs from 'qs'
import request from '@/utils/request'
export function floorAddInfoAPI(data) {
return request({
url: '/build/floor/add',
method: 'post',
data,
})
}
export function floorGetDownFloorSortAPI(data) {
return request({
url: '/build/floor/getDownFloorSort',
method: 'GET',
data,
})
}
export function floorGetInfoAPI(data) {
return request({
url: '/build/floor/getInfo',
method: 'GET',
data,
})
}
export function floorGetUpFloorSortAPI(data) {
return request({
url: '/build/floor/getUpFloorSort',
method: 'GET',
data,
})
}
export function floorPageAPI(data) {
return request({
url: '/build/floor/page',
method: 'POST',
data,
})
}
export function floorRemoveAPI(data) {
return request({
url: '/build/floor/remove',
method: 'POST',
data,
headers: { // 请求头
'Content-Type': 'multipart/form-data'
}
})
}
export function floorUpdateAPI(data) {
return request({
url: '/build/floor/update',
method: 'POST',
data,
})
}
\ No newline at end of file
import qs from 'qs'
import request from '@/utils/request'
// 新增天线组
export function addcommonAntennaGroup(data) {
return request({
url: '/simu/commonAntenna',
method: 'post',
data,
})
}
// 修改
export function upcommonAntennaGroup(data) {
return request({
url: '/simu/commonAntenna',
method: 'put',
data,
})
}
// 详情
export function getantenna(data) {
return request({
url: `/simu/commonAntenna/${data.id}`,
method: 'get',
})
}
// 列表
export function getlist(data) {
return request({
url: `/simu/commonAntenna/list?${qs.stringify(data)}`,
method: 'get',
})
}
// 删除
export function deleantenna(data) {
return request({
url: `/simu/commonAntenna/${data.id}`,
method: 'delete',
})
}
\ No newline at end of file
//建筑管理
import axios from 'axios'
import request from '../../utils/request'
import qs from 'qs' import qs from 'qs'
import request from '@/utils/request'
export default { // 图片上传
// 保留请求取消 export function staffAvatorApi(data) {
cancels: {}, return request({
// 话务模型---------------------------------------------------------------------------------------------------------------- url: '/common/image/upload',
// 话务列表 method: 'post',
simu_voiceslist(params) { headers: { // 请求头
this.cancels['simu_voiceslist']?.() 'Content-Type': 'multipart/form-data;'
return request.get(
`/simu/voice/list?${qs.stringify(params)}`,
params,
{
cancelToken: new axios.CancelToken(c => {
this.cancels['simu_voiceslist'] = c
})
}
)
},
//新增话务
simu_voicesAdd(params) {
this.cancels['simu_voicesAdd']?.()
return request.post(
`/simu/voice`,
params,
{
cancelToken: new axios.CancelToken(c => {
this.cancels['simu_voicesAdd'] = c
})
}
)
},
//修改话务
simu_voicesput(params) {
this.cancels['simu_voicesput']?.()
return request.put(
`/simu/voice`,
params,
{
cancelToken: new axios.CancelToken(c => {
this.cancels['simu_voicesput'] = c
})
}
)
},
//删除话务
simu_voicesRemo(data) {
this.cancels['simu_voicesRemo']?.()
return request.delete(
`/simu/voice/${data.ids}`,
{
cancelToken: new axios.CancelToken(c => {
this.cancels['simu_voicesRemo'] = c
})
}
)
},
//话务详细信息
simu_voicesId(params) {
this.cancels['simu_voicesId']?.()
return request.get(
`/simu/voice/${params.id}`,
params,
{
cancelToken: new axios.CancelToken(c => {
this.cancels['simu_voicesId'] = c
})
}
)
},
// 话务模型结束----------------------------------------------------------------------------------------------------------------
// 业务模型----------------------------------------------------------------------------------------------------------------
// 业务列表
simu_businesslist(params) {
this.cancels['simu_businesslist']?.()
return request.get(
`/simu/business/list?${qs.stringify(params)}`,
params,
{
cancelToken: new axios.CancelToken(c => {
this.cancels['simu_businesslist'] = c
})
}
)
},
//新增业务
simu_businessAdd(params) {
this.cancels['simu_businessAdd']?.()
return request.post(
`/simu/business`,
params,
{
cancelToken: new axios.CancelToken(c => {
this.cancels['simu_businessAdd'] = c
})
}
)
},
//修改业务
simu_businessput(params) {
this.cancels['simu_businessput']?.()
return request.put(
`/simu/business`,
params,
{
cancelToken: new axios.CancelToken(c => {
this.cancels['simu_businessput'] = c
})
}
)
}, },
//删除业务 data,
simu_businessRemo(data) {
this.cancels['simu_businessRemo']?.()
return request.delete(
`/simu/business/${data.ids}`,
{
cancelToken: new axios.CancelToken(c => {
this.cancels['simu_businessRemo'] = c
}) })
}
)
},
//业务详细信息
simu_businessId(params) {
this.cancels['simu_businessId']?.()
return request.get(
`/simu/business/${params.id}`,
params,
{
cancelToken: new axios.CancelToken(c => {
this.cancels['simu_businessId'] = c
})
}
)
},
// 业务模型结束------------------------------------------------------------------------------------------------------------- ----
//接口调节-------------------------------------------------------------------------------------------------------------
simu_rdFileInsList(params) {
this.cancels['simu_rdFileInsList']?.()
return request.get(
`/simu/rdFileIns/list?${qs.stringify(params)}`,
params,
{
cancelToken: new axios.CancelToken(c => {
this.cancels['simu_rdFileInsList'] = c
})
}
)
},
} }
//人员管理 //人员管理
import qs from 'qs' import qs from 'qs'
import request from '@/utils/request' import request from '@/utils/request'
import { he } from 'element-plus/es/locales.mjs'
import { helper } from 'echarts'
// 人员添加接口 // 人员添加接口
export function staffAddApi(data) { export function staffAddApi(data) {
return request({ return request({
...@@ -78,7 +80,9 @@ export function staffAddInfoApi(data) { ...@@ -78,7 +80,9 @@ export function staffAddInfoApi(data) {
url: `/user/add`, // 请求的URL路径 url: `/user/add`, // 请求的URL路径
method: 'POST', // 请求方法为POST method: 'POST', // 请求方法为POST
data, // 请求携带的数据 data, // 请求携带的数据
}) })
} }
export function staffGetInfoApi(data) { export function staffGetInfoApi(data) {
return request({ // 调用request方法发送HTTP请求 return request({ // 调用request方法发送HTTP请求
...@@ -93,12 +97,27 @@ export function staffRemoveInfoApi(data) { ...@@ -93,12 +97,27 @@ export function staffRemoveInfoApi(data) {
url: `/user/remove`, // 请求的URL路径 url: `/user/remove`, // 请求的URL路径
method: 'POST', // 请求方法为POST method: 'POST', // 请求方法为POST
data, // 请求携带的数据 data, // 请求携带的数据
headers: { // 请求头
'Content-Type': 'multipart/form-data;'
}
}) })
} }
export function staffResetPasswordApi(data) { export function staffResetPasswordApi(data) {
return request({ // 调用request方法发送HTTP请求 return request({ // 调用request方法发送HTTP请求
url: `/user/resetPassword`, // 请求的URL路径 url: `/user/resetPassword`, // 请求的URL路径
method: 'POST', // 请求方法为POST method: 'POST', // 请求方法为POST
data, // 请求携带的数据 data
})
}
export function staffSetAbleApi(data) {
return request({ // 调用request方法发送HTTP请求
url: `/user/enable`, // 请求的URL路径
method: 'POST', // 请求方法为POST
data,
headers: { // 请求头
'Content-Type': 'multipart/form-data'
}
}) })
} }
\ No newline at end of file
差异被折叠。
...@@ -21,6 +21,10 @@ import store from './store/index.js' ...@@ -21,6 +21,10 @@ import store from './store/index.js'
import router from './router/index.js' import router from './router/index.js'
import SvgIcon from '@/components/SvgIcon/index.vue' // import SvgIcon from '@/components/SvgIcon/index.vue' //
import elementIcons from '@/components/SvgIcon/svgicon.js' import elementIcons from '@/components/SvgIcon/svgicon.js'
import VxeUIAll from 'vxe-pc-ui'
import 'vxe-pc-ui/es/style.css'
import VxeUITable from 'vxe-table'
import 'vxe-table/es/style.css'
import './permission' // 路由拦截和加载页面进度条 import './permission' // 路由拦截和加载页面进度条
// 全局配置组件 // 全局配置组件
...@@ -40,7 +44,7 @@ const app = createApp(App) ...@@ -40,7 +44,7 @@ const app = createApp(App)
const pinia = createPinia(); const pinia = createPinia();
// 全局方法挂载 // 全局方法挂载
app.config.globalProperties.useDict = useDict app.config.globalProperties.useDict = useDict
localStorage.setItem('lastValidMenuPath','/home')
// 全局组件挂载 // 全局组件挂载
...@@ -65,6 +69,6 @@ app.use(ElementPlus, { ...@@ -65,6 +69,6 @@ app.use(ElementPlus, {
size: Cookies.get('size') || 'default' size: Cookies.get('size') || 'default'
}) })
app.use(VxeUIAll).use(VxeUITable)
app.mount('#app') app.mount('#app')
import router from './router' import router from './router'
import { ElMessage } from 'element-plus'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css' import 'nprogress/nprogress.css'
import { getToken } from '@/utils/auth' import { getToken } from '@/utils/auth'
import useAppStore from './store/module/app' import useAppStore from './store/module/app'
...@@ -41,8 +40,8 @@ router.beforeEach((to, from, next) => { ...@@ -41,8 +40,8 @@ router.beforeEach((to, from, next) => {
} else { } else {
localStorage.clear()//清空所有本地储存 localStorage.clear()//清空所有本地储存
// 重定向到首页 // 重定向到首页
// next(`/login`) // 否则全部重定向到登录页 next(`/login`) // 否则全部重定向到登录页
next() // next()
} }
} }
......
...@@ -57,6 +57,7 @@ export const constantRoutes = [ ...@@ -57,6 +57,7 @@ export const constantRoutes = [
component: () => import('@/views/error/401.vue'), component: () => import('@/views/error/401.vue'),
hidden: true hidden: true
}, },
{ {
path: '', path: '',
component: Layout, component: Layout,
...@@ -135,25 +136,44 @@ export const constantRoutes = [ ...@@ -135,25 +136,44 @@ export const constantRoutes = [
path: '/firesurveillance', path: '/firesurveillance',
component: () => import('../views/areafiremanage/firesurveillance/index.vue'), component: () => import('../views/areafiremanage/firesurveillance/index.vue'),
name: 'fireSurveillance', name: 'fireSurveillance',
meta: { title: '当前火情', icon: 'dashboard', affix: true } meta: { title: '历史火情', icon: 'dashboard', affix: true }
}, },
{ {
path: '/historyfire', path: '/historyfire',
component: () => import('../views/areafiremanage/historyfire/index.vue'), component: () => import('../views/areafiremanage/historyfire/index.vue'),
name: 'historyFire', name: 'historyFire',
meta: { title: '历史火情', icon: 'dashboard', affix: true }, meta: { title: '当前火情', icon: 'dashboard', affix: true },
children:[
},
{ {
path: '/historyfire/floordetaildate', path: '/floordetaildate',
component: () => import('../views/areafiremanage/historyfire/components/floordetail.vue'), component: () => import('../views/areafiremanage/historyfire/components/floordetail.vue'),
name: 'floorDetailDate', name: 'floorDetailDate',
meta: { title: '详细楼层火情', icon: 'dashboard', affix: true } meta: { title: '详细楼层火情', icon: 'dashboard', affix: true }
}, },
] {
path: '/buildingdetaildate',
component: () => import('../views/areabuildmanage/components/showdetaildate.vue'),
name: 'buildingDetailDate',
meta: { title: '楼详细建筑数据', icon: 'dashboard', affix: true }
}, },
{
path: '/onefloorbuildingdetaildate',
component: () => import('../views/areabuildmanage/onefloor/index.vue'),
name: 'oneFloorBuildingDetailDate',
meta: { title: '层详细建筑数据', icon: 'dashboard', affix: true }
},
{
path: '/uavdetaildate',
component: () => import('../views/uavshowdate/uavmanage/index.vue'),
name: 'uavDetailDate',
meta: { title: '无人机管理', icon: 'dashboard', affix: true }
},
] ]
}, },
] ]
const router = createRouter({ const router = createRouter({
......
import Cookies from 'js-cookie' import Cookies from 'js-cookie'
import { ElMessage } from 'element-plus';
import { tr } from 'element-plus/es/locales.mjs';
const useAppStore = defineStore( const useAppStore = defineStore(
'app', 'app',
{ {
...@@ -12,7 +13,14 @@ const useAppStore = defineStore( ...@@ -12,7 +13,14 @@ const useAppStore = defineStore(
device: 'desktop', device: 'desktop',
size: Cookies.get('size') || 'default', size: Cookies.get('size') || 'default',
num:1, num:1,
isCurUserLogin: false isCurUserLogin: false,
userInfo: {},
showavatarUrl :'https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png',
position:{
10:'超级管理员',
1:'巡检人员',
0:"管理员"
}
}), }),
actions: { actions: {
toggleSideBar(withoutAnimation) { toggleSideBar(withoutAnimation) {
...@@ -43,7 +51,32 @@ const useAppStore = defineStore( ...@@ -43,7 +51,32 @@ const useAppStore = defineStore(
this.sidebar.hide = status this.sidebar.hide = status
}, },
initavatarUrlFn () {
try {
if (!(this.userInfo)) {
this.userInfo = JSON.parse(localStorage.getItem('user'))
console.log('initavatarUrlFn-----我是空------------',this.userInfo)
}else{
(this.userInfo).avatarUrl = (this.userInfo).avatarUrl ? (this.userInfo).avatarUrl : 'https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png';
console.log('initavatarUrlFn-----我不是空------------',this.userInfo)
}
} catch (error) {
ElMessage.error('avatarUrl is not valid',error);
}
},
chackCurPersionOpition() {
try {
// console.log(this.userInfo,'********************************************');
return this.userInfo.status === 0 ? true : false;
} catch (error) {
ElMessage.error('this.userInfo.state is not valid');
}
}
} }
}) })
......
...@@ -22,9 +22,8 @@ const service = axios.create({ ...@@ -22,9 +22,8 @@ const service = axios.create({
// request拦截器 // request拦截器
service.interceptors.request.use( service.interceptors.request.use(config => {
config => { console.log('--------------config', config)
console.log('--------------config', config.url)
// 是否需要设置 token // 是否需要设置 token
const isToken = (config.headers || {}).isToken === false const isToken = (config.headers || {}).isToken === false
console.log('--------------isToken', isToken) console.log('--------------isToken', isToken)
...@@ -42,6 +41,7 @@ service.interceptors.request.use( ...@@ -42,6 +41,7 @@ service.interceptors.request.use(
config.url = url; config.url = url;
} }
if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) { if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
const requestObj = { const requestObj = {
url: config.url, url: config.url,
data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data, data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
......
...@@ -19,9 +19,9 @@ ...@@ -19,9 +19,9 @@
status-icon status-icon
> >
<!-- 建筑编号 --> <!-- 建筑编号 -->
<el-form-item label="建筑编号" prop="buildingNo" class="form-item"> <el-form-item label="建筑编号" prop="buildCode" class="form-item">
<el-input <el-input
v-model="form.buildingNo" v-model="form.buildCode"
placeholder="请输入建筑编号" placeholder="请输入建筑编号"
class="input-field" class="input-field"
clearable clearable
...@@ -29,9 +29,9 @@ ...@@ -29,9 +29,9 @@
</el-form-item> </el-form-item>
<!-- 建筑名称 --> <!-- 建筑名称 -->
<el-form-item label="建筑名称" prop="buildingName" class="form-item"> <el-form-item label="建筑名称" prop="buildName" class="form-item">
<el-input <el-input
v-model="form.buildingName" v-model="form.buildName"
placeholder="请输入建筑名称" placeholder="请输入建筑名称"
class="input-field" class="input-field"
clearable clearable
...@@ -39,9 +39,9 @@ ...@@ -39,9 +39,9 @@
</el-form-item> </el-form-item>
<!-- 建筑层数 --> <!-- 建筑层数 -->
<el-form-item label="建筑层数(地上)" prop="floorCount" class="form-item"> <el-form-item label="建筑层数(地上)" prop="floorNum" class="form-item">
<el-input <el-input
v-model="form.floorCount" v-model="form.floorNum"
placeholder="请输入地上层数" placeholder="请输入地上层数"
type="number" type="number"
min="0" min="0"
...@@ -61,13 +61,13 @@ ...@@ -61,13 +61,13 @@
<!-- 地下室层数 --> <!-- 地下室层数 -->
<el-form-item <el-form-item
label="地下室层数" label="地下室层数"
prop="basementCount" prop="undergroundFloorNum"
class="form-item" class="form-item"
:rules="form.hasBasement === 1 ? rules.basementCount : []" :rules="form.hasBasement === 1 ? rules.basementCount : []"
> >
<el-input <el-input
v-model="form.basementCount" v-model="form.undergroundFloorNum"
placeholder="请输入地下室层数" :placeholder ="`${form.hasBasement === 1 ? '请输入地下室层数' : '无地下室'}`"
type="number" type="number"
min="0" min="0"
class="input-field" class="input-field"
...@@ -110,35 +110,35 @@ ...@@ -110,35 +110,35 @@
import { ref, reactive } from 'vue'; import { ref, reactive } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus'; import { ElMessage, ElMessageBox } from 'element-plus';
import { Close } from '@element-plus/icons-vue'; import { Close } from '@element-plus/icons-vue';
import { buildingAddApi } from '../../../api/build';
// 表单引用 // 表单引用
const addBuildingFormRef = ref(null); const addBuildingFormRef = ref(null);
// 提交加载状态 // 提交加载状态
const submitting = ref(false); const submitting = ref(false);
const emit = defineEmits(['closeAddDrawer']); const emit = defineEmits(['closeAddDrawer','handleRefreshInfoFn']);
// 表单数据 // 表单数据
const form = reactive({ const form = reactive({
buildingNo: '', // 建筑编号 buildCode: '', // 建筑编号
buildingName: '', // 建筑名称 buildName: '', // 建筑名称
floorCount: null, // 地上层数 floorNum: null, // 地上层数
hasBasement: 1, // 是否含有地下室 (1:是, 2:否) hasBasement: 1, // 是否含有地下室 (1:是, 2:否)
basementCount: null, // 地下室层数 undergroundFloorNum: null, // 地下室层数
description: '' // 建筑功能描述 description: '' // 建筑功能描述
}); });
// 表单验证规则 // 表单验证规则
const rules = reactive({ const rules = reactive({
buildingNo: [ buildCode: [
{ required: true, message: '请输入建筑编号', trigger: ['blur', 'change'] }, { required: true, message: '请输入建筑编号', trigger: ['blur', 'change'] },
{ min: 2, max: 20, message: '编号长度在2-20个字符之间', trigger: ['blur', 'change'] } { min: 2, max: 20, message: '编号长度在2-20个字符之间', trigger: ['blur', 'change'] }
], ],
buildingName: [ buildName: [
{ required: true, message: '请输入建筑名称', trigger: ['blur', 'change'] }, { required: true, message: '请输入建筑名称', trigger: ['blur', 'change'] },
{ message: '名称长度在2-50个字符之间', trigger: ['blur', 'change'] } { message: '名称长度在2-50个字符之间', trigger: ['blur', 'change'] }
], ],
floorCount: [ floorNum: [
{ required: true, message: '请输入地上层数', trigger: ['blur', 'change'] }, { required: true, message: '请输入地上层数', trigger: ['blur', 'change'] },
{ {
validator: (rule, value, callback) => { validator: (rule, value, callback) => {
...@@ -154,52 +154,39 @@ const rules = reactive({ ...@@ -154,52 +154,39 @@ const rules = reactive({
}, },
trigger: ['blur', 'change'] trigger: ['blur', 'change']
} }
], ]
basementCount: [
{ required: true, message: '请输入地下室层数', trigger: ['blur', 'change'] },
{
validator: (rule, value, callback) => {
if (form.hasBasement === 1) {
if (value === null || value === '') {
callback(new Error('请输入地下室层数'));
} else if (value < 0) {
callback(new Error('层数不能为负数'));
} else {
callback();
}
} else {
callback();
}
},
trigger: ['blur', 'change']
}
]
}); });
// 提交表单 // 提交表单
const handleSubmit = async () => { const handleSubmit = () => {
try { try {
submitting.value = true; submitting.value = true;
if (form.hasBasement === 2) { if (form.hasBasement === 2) {
rules.basementCount = []; rules.basementCount = [];
} }
await addBuildingFormRef.value.validate();
// 准备提交数据 // 准备提交数据
const submitData = { const submitData = {
...form, ...form,
hasBasement: form.hasBasement === 1 undergroundFloorNum:form.hasBasement === 1 ? form.undergroundFloorNum : 0
}; };
console.log('提交新增建筑数据:', submitData); console.log('提交新增建筑数据:', submitData);
await new Promise(resolve => setTimeout(resolve, 1000)); buildingAddApi(submitData).then(res => {
if (res.code === 200) {
ElMessage.success('建筑信息新增成功!'); ElMessage.success('建筑信息新增成功!');
addBuildingFormRef.value.resetFields(); addBuildingFormRef.value.resetFields();
emit('closeAddDrawer'); emit('closeAddDrawer');
emit('tableDataRefresh');
}else{
ElMessage.error('建筑信息新增响应代码错误!');
}
}).catch(err => {
ElMessage.error('添加建筑错误',err);
});
} catch (error) { } catch (error) {
console.error('表单验证失败:', error); console.error('表单验证失败:', error);
ElMessage.error('请完善表单信息后重试'); // ElMessage.error('请完善表单信息后重试');
} finally { } finally {
submitting.value = false; submitting.value = false;
} }
...@@ -213,8 +200,9 @@ const handleCancel = () => { ...@@ -213,8 +200,9 @@ const handleCancel = () => {
type: 'warning', type: 'warning',
center: true center: true
}).then(() => { }).then(() => {
addBuildingFormRef.value.resetFields();
emit('closeAddDrawer'); emit('closeAddDrawer');
addBuildingFormRef.value.resetFields();
}).catch(() => {}); }).catch(() => {});
}; };
......
<template>
<div class="add-building-modal">
<!-- 标题栏 -->
<div class="modal-header">
<h2 class="title">新增建筑</h2>
<el-icon class="close-icon" @click="handleClose" size="20">
<Close />
</el-icon>
</div>
<!-- 表单主体 -->
<el-form
ref="addBuildingFormRef"
:model="form"
:rules="rules"
label-width="120px"
label-position="left"
class="add-building-form"
status-icon
>
<!-- 建筑编号 -->
<el-form-item label="楼层类型" prop="buildingStye" class="form-item">
<el-radio-group v-model="form.buildingStye">
<el-radio :value="1">地上</el-radio>
<el-radio :value="0">地下</el-radio>
</el-radio-group>
</el-form-item>
<!-- 建筑名称 -->
<el-form-item label="楼层号" prop="buildingNo" class="form-item">
<el-select v-model="form.buildingNo" placeholder="选择楼层号" style="width: 240px">
<el-option
v-for="item in form.buildingNo"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<!-- 建筑层数 -->
<el-form-item label="楼层平面图" prop="floorPlan" class="form-item">
<!-- 上传图片 -->
<UpdataImg ref="floorUpdateloader" @getAvatar="getfloorPlan" :updataImageCount="1"></UpdataImg>
</el-form-item>
<!-- 是否有地下室 -->
<el-form-item label="航线绑定" prop="pathBinding" class="form-item">
<el-select v-model="form.pathBinding" placeholder="选择可绑定的航线" style="width: 240px">
<el-option
v-for="item in form.pathBinding"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<!-- 建筑功能描述 -->
<el-form-item label="楼层描述" prop="description" class="form-item">
<el-input
v-model="form.description"
type="textarea"
placeholder="请输入建筑功能描述"
:rows="3"
class="textarea-field"
show-word-limit
maxlength="200"
/>
</el-form-item>
</el-form>
<!-- 底部按钮 -->
<div class="modal-footer">
<el-button @click="handleCancel" class="cancel-btn" size="default">取消</el-button>
<el-button
@click="handleSubmit"
type="primary"
class="confirm-btn"
size="default"
:loading="submitting"
>
确认
</el-button>
</div>
</div>
</template>
<script setup>
import { ref, reactive } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import { Close } from '@element-plus/icons-vue';
import UpdataImg from '../../systemmanage/components/updataImg.vue';
// 表单引用
const addBuildingFormRef = ref(null);
// 提交加载状态
const submitting = ref(false);
const emit = defineEmits(['closeAddDrawer']);
// 表单数据
const form = reactive({
buildingStye:'',
// 楼层编号初始的时候要获取,数据类型 buildingNo:{label: '1层', value: '1'}
buildingNo:'',
// 航线编号初始的时候要获取,数据类型floorPlan:{label: '航线1', value: '1'}
floorPlan:'',
pathBinding:'',
description:'',
description: "",
});
const getfloorPlan = (url) => {
console.log(url,"const url = URL.createObjectURL(url);");
form.floorPlan = url;
};
// 表单验证规则
const rules = reactive({
});
// 提交表单
const handleSubmit = async () => {
try {
submitting.value = true;
await addBuildingFormRef.value.validate();
// 准备提交数据
const submitData = {
...form,
};
console.log('提交新增建筑数据:', submitData);
await new Promise(resolve => setTimeout(resolve, 1000));
ElMessage.success('建筑信息新增成功!');
addBuildingFormRef.value.resetFields();
emit('closeAddDrawer');
} catch (error) {
console.error('表单验证失败:', error);
ElMessage.error('请完善表单信息后重试');
} finally {
submitting.value = false;
}
};
const floorUpdateloader = ref(null);
// 取消操作
const handleCancel = () => {
ElMessageBox.confirm('确定要取消新增吗?已填写内容将不保存', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
center: true
}).then(() => {
console.log('取消新增');
addBuildingFormRef.value.resetFields();
floorUpdateloader.value.handleRemove()
emit('closeAddDrawer');
}).catch(() => {
console.log('报错了');
});
};
// 关闭弹窗
const handleClose = () => {
addBuildingFormRef.value.resetFields();
handleCancel();
};
</script>
<style scoped lang="scss">
.add-building-modal {
width: 100%;
max-width: 520px;
padding: 15px;
box-sizing: border-box;
background-color: #fff;
border-radius: 8px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
// 标题栏样式
.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
padding-bottom: 16px;
border-bottom: 1px solid #f0f0f0;
.title {
margin: 0;
font-size: 18px;
font-weight: 600;
color: #303133;
}
.close-icon {
cursor: pointer;
color: #909399;
transition: all 0.2s;
padding: 4px;
border-radius: 50%;
&:hover {
color: #f56c6c;
background-color: #fef0f0;
}
}
}
// 表单样式
.add-building-form {
.form-item {
margin-bottom: 18px;
:deep(.el-form-item__label) {
color: #606266;
font-weight: normal;
}
}
.input-field, .textarea-field {
width: 100%;
max-width: 380px;
:deep(.el-input__inner) {
height: 36px;
line-height: 36px;
border-radius: 4px;
}
:deep(.el-textarea__inner) {
min-height: 100px !important;
border-radius: 4px;
}
}
// 单选框样式
.radio-group {
display: flex;
gap: 20px;
.radio-btn {
margin: 0;
:deep(.el-radio__label) {
padding-left: 6px;
font-size: 14px;
}
}
}
}
// 底部按钮样式
.modal-footer {
display: flex;
justify-content: flex-end;
gap: 16px;
margin-top: 24px;
padding-top: 20px;
border-top: 1px solid #f0f0f0;
.cancel-btn {
width: 90px;
height: 36px;
border-radius: 4px;
color: #606266;
border-color: #dcdfe6;
&:hover {
color: #409eff;
border-color: #c6e2ff;
background-color: #ecf5ff;
}
}
.confirm-btn {
width: 90px;
height: 36px;
border-radius: 4px;
background-color: #409eff;
border-color: #409eff;
&:hover {
background-color: #66b1ff;
border-color: #66b1ff;
}
&:active {
background-color: #3a8ee6;
border-color: #3a8ee6;
}
}
}
// 响应式适配
@media (max-width: 768px) {
padding: 16px;
max-width: 100%;
.add-building-form {
.input-field, .textarea-field {
max-width: 100% !important;
}
.radio-group {
gap: 16px;
}
}
.modal-footer {
justify-content: center;
gap: 12px;
}
}
}
</style>
\ No newline at end of file
...@@ -19,9 +19,9 @@ ...@@ -19,9 +19,9 @@
status-icon status-icon
> >
<!-- 建筑编号 --> <!-- 建筑编号 -->
<el-form-item label="建筑编号" prop="buildingNo" class="form-item"> <el-form-item label="建筑编号" prop="buildCode" class="form-item">
<el-input <el-input
v-model="form.buildingNo" v-model="form.buildCode"
placeholder="请输入建筑编号" placeholder="请输入建筑编号"
class="input-field" class="input-field"
clearable clearable
...@@ -29,9 +29,9 @@ ...@@ -29,9 +29,9 @@
</el-form-item> </el-form-item>
<!-- 建筑名称 --> <!-- 建筑名称 -->
<el-form-item label="建筑名称" prop="buildingName" class="form-item"> <el-form-item label="建筑名称" prop="buildName" class="form-item">
<el-input <el-input
v-model="form.buildingName" v-model="form.buildName"
placeholder="请输入建筑名称" placeholder="请输入建筑名称"
class="input-field" class="input-field"
clearable clearable
...@@ -39,9 +39,9 @@ ...@@ -39,9 +39,9 @@
</el-form-item> </el-form-item>
<!-- 建筑层数 --> <!-- 建筑层数 -->
<el-form-item label="建筑层数(地上)" prop="buildingFloorCount" class="form-item"> <el-form-item label="建筑层数(地上)" prop="floorNum" class="form-item">
<el-input <el-input
v-model="form.buildingFloorCount" v-model="form.floorNum"
placeholder="请输入地上层数" placeholder="请输入地上层数"
type="number" type="number"
min="0" min="0"
...@@ -58,10 +58,10 @@ ...@@ -58,10 +58,10 @@
label="地下室层数" label="地下室层数"
prop="basementCount" prop="basementCount"
class="form-item" class="form-item"
:rules=" rules.buildingBasementCount "
> >
<el-input <el-input
v-model="form.buildingBasementCount" v-model="form.undergroundFloorNum"
placeholder="请输入地下室层数" placeholder="请输入地下室层数"
type="number" type="number"
min="0" min="0"
...@@ -72,9 +72,9 @@ ...@@ -72,9 +72,9 @@
</el-form-item> </el-form-item>
<!-- 建筑功能描述 --> <!-- 建筑功能描述 -->
<el-form-item label="建筑功能描述" prop="buildingDescribe" class="form-item"> <el-form-item label="建筑功能描述" prop="description" class="form-item">
<el-input <el-input
v-model="form.buildingDescribe" v-model="form.description"
type="textarea" type="textarea"
placeholder="请输入建筑功能描述" placeholder="请输入建筑功能描述"
:rows="3" :rows="3"
...@@ -105,7 +105,7 @@ ...@@ -105,7 +105,7 @@
import { ref, reactive, onMounted, onActivated } from 'vue'; import { ref, reactive, onMounted, onActivated } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus'; import { ElMessage, ElMessageBox } from 'element-plus';
import { Close } from '@element-plus/icons-vue'; import { Close } from '@element-plus/icons-vue';
import { buildingUpdateApi } from '@/api/build';
// 表单引用 // 表单引用
const addBuildingFormRef = ref(null); const addBuildingFormRef = ref(null);
// 提交加载状态 // 提交加载状态
...@@ -122,12 +122,12 @@ watch(() => props.isBuildingEditDrawer, (newVal) => { ...@@ -122,12 +122,12 @@ watch(() => props.isBuildingEditDrawer, (newVal) => {
}); });
// 表单数据 // 表单数据
const form = reactive({ const form = reactive({
buildingNo: '', // 建筑编号 buildCode: '', // 建筑编号
buildingName: '', // 建筑名称 buildName: '', // 建筑名称
buildingFloorCount: null, // 地上层数 floorNum: null, // 地上层数
buildingBasementCount: null, // 地下室层数 undergroundFloorNum: null, // 地下室层数
buildingDescribe: '' // 建筑功能描述 description: '' // 建筑功能描述
}); });
// 初始化表单数据 // 初始化表单数据
...@@ -146,11 +146,11 @@ const initFormData = () => { ...@@ -146,11 +146,11 @@ const initFormData = () => {
// 表单验证规则 // 表单验证规则
const rules = reactive({ const rules = reactive({
buildingNo: [ buildCode: [
{ required: true, message: '请输入建筑编号', trigger: ['blur', 'change'] }, { required: true, message: '请输入建筑编号', trigger: ['blur', 'change'] },
{ min: 2, max: 20, message: '编号长度在2-20个字符之间', trigger: ['blur', 'change'] } { min: 2, max: 20, message: '编号长度在2-20个字符之间', trigger: ['blur', 'change'] }
], ],
buildingName: [ buildName: [
{ required: true, message: '请输入建筑名称', trigger: ['blur', 'change'] }, { required: true, message: '请输入建筑名称', trigger: ['blur', 'change'] },
{ message: '名称长度在2-50个字符之间', trigger: ['blur', 'change'] } { message: '名称长度在2-50个字符之间', trigger: ['blur', 'change'] }
], ],
...@@ -193,27 +193,36 @@ const rules = reactive({ ...@@ -193,27 +193,36 @@ const rules = reactive({
}); });
// 提交表单 // 提交表单
const handleSubmit = async () => { const handleSubmit = () => {
try { try {
submitting.value = true; submitting.value = true;
if (form.hasBasement === 2) { if (form.hasBasement === 2) {
rules.basementCount = []; rules.basementCount = [];
} }
await addBuildingFormRef.value.validate(); const {buildCode,buildId, buildName,description} = form;
// 准备提交数据 // 准备提交数据
const submitData = { const submitData = {
...form, buildCode,buildId, buildName,description
hasBasement: form.hasBasement === 1
}; };
buildingUpdateApi(submitData).then(res => {
console.log('提交新增建筑数据:', submitData); if (res.code === 200) {
await new Promise(resolve => setTimeout(resolve, 1000)); ElMessage.success('建筑信息更新成功!');
ElMessage.success('建筑信息新增成功!');
// addBuildingFormRef.value.resetFields();
emit('closeEditDrawer'); emit('closeEditDrawer');
emit('tableDataRefresh'); emit('tableDataRefresh');
}else{
ElMessage.error('建筑信息更新响应代码错误!');
}
}).catch(err => {
})
// console.log('提交新增建筑数据:', submitData);
// ElMessage.success('建筑信息新增成功!');
// // addBuildingFormRef.value.resetFields();
// emit('closeEditDrawer');
// emit('tableDataRefresh');
} catch (error) { } catch (error) {
console.error('表单验证失败:', error); console.error('表单验证失败:', error);
ElMessage.error('请完善表单信息后重试'); ElMessage.error('请完善表单信息后重试');
......
<template>
<div class="dashboard-container" :style="containerStyle">
<main class="main-content">
<!-- 左侧区域 -->
<div class="left-section">
<!-- 左侧上部分 -->
<div class="left-top">
<!-- 区域信息概览 -->
<div class="info-card region-overview">
<searchtop :searchShowData="searchShowData"></searchtop>
</div>
</div>
<!-- 左侧下部分:统计区域 -->
<div class="info-card stats-alerts">
<div class="card-tabs">
<span class="title">建筑列表</span>
<div class="card-actions">
<el-button class="operation-button" type="primary" size="small">导入</el-button>
<el-button class="operation-button" type="primary" size="small">导出</el-button>
<el-button class="operation-button" type="primary" size="small" @click="handleAddInfoFn">新增建筑</el-button>
<el-button class="operation-button" type="primary" size="small" @click="handleRefreshInfoFn"><el-icon ><RefreshRight /></el-icon></el-button>
<el-button class="operation-button" type="primary" size="small"><el-icon><FullScreen /></el-icon></el-button>
</div>
</div>
<div class="card-table">
<tabledata :tableShowData="tableShowData"></tabledata>
</div>
</div>
</div>
</main>
<!-- 新增建筑抽屉 -->
<el-drawer v-model="isAddDrawer" title="添加建筑信息" :with-header="false" :before-close="beforeCloseAddBuildDrawer">
<Flooraddbuilding @closeAddDrawer="closeAddDrawer" @tableDataRefresh="handleRefreshInfoFn"></Flooraddbuilding>
</el-drawer>
<!-- 修改建筑抽屉 -->
<el-drawer v-model="isBuildingEditDrawer" title="修改用户信息" :with-header="false" :before-close="beforeCloseAddBuildDrawer">
<Flooraddbuilding :rowData="rowData" :isBuildingEditDrawer="isBuildingEditDrawer" @closeEditDrawer="closeBuildingEditDrawer" @tableDataRefresh="handleRefreshInfoFn"></Flooraddbuilding>
</el-drawer>
<!-- 图片预览组件 -->
<el-image-viewer
v-if="previewVisible && previewVisibledialogDate.length > 0"
:url-list="previewVisibledialogDate"
@close="previewVisible = false"
/>
</div>
</template>
<script setup>
import { reactive, computed, ref } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import searchtop from '../../commentcomponents/searchtop/index.vue';
import tabledata from '../../commentcomponents/tabledata/index.vue';
import router from '../../../router';
import Flooraddbuilding from './flooraddbuilding.vue';
import { useRoute,useRouter } from 'vue-router';
const route = useRoute();
// 搜索栏配置
const searchShowData = ref([
{ label: '楼层描述', placeholder: "请输入", type: 'input', content: '' },
{ label: '楼层号', placeholder: "请选择", type: 'select', content: '', options: [
{label:'火灾', value:'烟雾'},
{label:'烟雾', value:'火灾'}
] },
]);
// 布局配置
const layoutConfig = reactive({
containerMinHeight: '100vh',
cardSpacing: '1rem'
});
// 抽屉控制
const isAddDrawer = ref(false);
const isBuildingEditDrawer = ref(false);
const rowData = ref([]);
// 方法定义
const handleAddInfoFn = () => {
console.log("打开新增信息");
isAddDrawer.value = true;
}
const handleRefreshInfoFn = () => {
console.log("刷新数据");
}
const closeAddDrawer = () => {
console.log("000000-------1-----0000000000",isAddDrawer.value)
isAddDrawer.value = false;
}
const beforeCloseAddBuildDrawer = () => {
// 关闭前的处理逻辑
}
const oneBuildingSeeDetails = (data) => {
console.log("查看详情", data);
router.push({
path: '/onefloorbuildingdetaildate',
// params: { data: JSON.stringify(data) }
});
}
const oneBuildingDdeleteData = (data) => {
ElMessageBox.confirm('是否删除该建筑?此操作将无法撤销', '删除', {
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
handleRefreshInfoFn()
ElMessage.success('已删除');
}).catch(() => {
ElMessage.info('取消删除');
});
}
const oneResetBuildingShowInfo = (data) => {
isBuildingEditDrawer.value = true;
rowData.value = data;
}
const closeBuildingEditDrawer = () => {
isBuildingEditDrawer.value = false;
console.log("000000------------0000000000")
}
// 图片预览状态
const previewVisible = ref(false);
const previewVisibledialogDate = ref([]);
const seeBuildingFloorPlan = (data) => {
console.log("查看楼层平面图", data);
previewVisible.value = true;
if(data.buildingFloorPlan.length > 0) {
previewVisibledialogDate.value = ['https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg',
'https://fuss10.elemecdn.com/1/34/19aa98b1fcb2781c4fba33d850549jpeg.jpeg',]
return;
}else {
ElMessage.warning({
message: '该层暂无楼层平面图',
duration: 2000
})
}
}
// 表格数据
const tableShowData = ref([{
tableHeader: [
{label: '建筑编号', prop: 'buildingNo'},
{label: '建筑名称', prop: 'buildingName'},
{label: '建筑层数', prop: 'buildingFloorCount'},
{label: '楼层平面图', prop: 'buildingFloorPlan'},
{label: '更新时间', prop: 'buildingUpdataTime'},
{label: '楼层描述', prop: 'buildingDescription'},
{label: '操作', prop: 'buildingOperation'}
],
tableBody: [
{buildingNo: '张三', buildingName:"123456", buildingFloorCount: 11, buildingFloorPlan:
[
{label:'查看', type:'primary', icon:'EditPen', click: seeBuildingFloorPlan},
],
buildingUpdataTime: Date.now(),buildingDescription:' TEST ',
buildingOperation: [
{label:'查看详情', type:'primary', icon:'EditPen', click: oneBuildingSeeDetails},
{label:'删除', type:'danger', icon:'Delete', click: oneBuildingDdeleteData},
{label:'修改', type:'primary', icon:'EditPen', click: oneResetBuildingShowInfo}
]},
{buildingNo: '张89三', buildingName:"123456", buildingFloorCount: 11, buildingFloorPlan:
[
{label:'查看', type:'primary', icon:'EditPen', click: seeBuildingFloorPlan},
],
buildingUpdataTime: Date.now(),buildingDescription:' TEST ',
buildingOperation: [
{label:'查看详情', type:'primary', icon:'EditPen', click: oneBuildingSeeDetails},
{label:'删除', type:'danger', icon:'Delete', click: oneBuildingDdeleteData},
{label:'修改', type:'primary', icon:'EditPen', click: oneResetBuildingShowInfo}
]},
{buildingNo: '张45三', buildingName:"123456", buildingFloorCount: 11, buildingFloorPlan:
[
{label:'查看', type:'primary', icon:'EditPen', click: seeBuildingFloorPlan},
],
buildingUpdataTime: Date.now(),buildingDescription:' TEST ',
buildingOperation: [
{label:'查看详情', type:'primary', icon:'EditPen', click: oneBuildingSeeDetails},
{label:'删除', type:'danger', icon:'Delete', click: oneBuildingDdeleteData},
{label:'修改', type:'primary', icon:'EditPen', click: oneResetBuildingShowInfo}
]},
]
}]);
// 计算属性
const containerStyle = computed(() => ({
minHeight: layoutConfig.containerMinHeight,
'--card-spacing': layoutConfig.cardSpacing,
}));
</script>
<style scoped>
.dashboard-container {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: rgba(0, 0, 0, 0.05);
color: #333;
overflow: hidden;
}
.main-content {
display: flex;
gap: var(--card-spacing);
padding: 0.4rem;
height: 100vh;
box-sizing: border-box;
}
.left-section {
flex: 2;
display: flex;
flex-direction: column;
gap: var(--card-spacing);
height: 100%;
}
.left-top {
height: auto;
}
.info-card {
background-color: #fff;
padding: 1rem;
border-radius: 8px;
box-sizing: border-box;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
overflow: auto;
}
.region-overview {
flex: 1;
min-width: 200px;
}
.stats-alerts {
display: flex;
flex-direction: column;
gap: 1rem;
height: 67%;
}
.card-tabs {
display: flex;
border-bottom: 1px solid #292828;
font-size: 1.2rem;
color: #000000;
height: 8%;
align-items: center;
width: 100%;
padding: 10px;
}
.title {
width: 70%;
}
.card-actions {
display: flex;
flex: 1;
justify-content: space-between;
align-items: center;
height: 8%;
}
.operation-button {
width: 15%;
}
.card-table {
width: 100%;
flex:1;
overflow: hidden;
border-radius: 8px;
}
@media (max-width: 1024px) {
.left-top {
flex-direction: column;
}
.region-overview {
width: 100%;
flex: none;
}
}
@media (max-width: 768px) {
.stats-alerts {
flex-direction: column;
}
}
</style>
\ No newline at end of file
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
</div> </div>
</div> </div>
<div class="card-table"> <div class="card-table">
<tabledata :tableShowData="tableShowData"></tabledata> <tabledata :tableShowData="tableShowData" @tableDataRefresh="handleRefreshInfoFn"></tabledata>
</div> </div>
</div> </div>
</div> </div>
...@@ -44,13 +44,16 @@ ...@@ -44,13 +44,16 @@
</template> </template>
<script setup> <script setup>
import { reactive, computed, ref } from 'vue'; import { reactive, computed, ref, onMounted, watch } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus'; import { ElMessage, ElMessageBox } from 'element-plus';
import searchtop from '../commentcomponents/searchtop/index.vue'; import searchtop from '../commentcomponents/searchtop/index.vue';
import tabledata from '../commentcomponents/tabledata/index.vue'; import tabledata from '../commentcomponents/tabledata/index.vue';
import showResetBuildingInfo from './components/showResetBuildingInfo.vue'; import showResetBuildingInfo from './components/showResetBuildingInfo.vue';
import Addbuild from './components/addbuild.vue'; import Addbuild from './components/addbuild.vue';
import router from '../../router';
import { buildingPageApi,buildingRemoveApi } from '../../api/build';
import { useRoute,useRouter } from 'vue-router';
const route = useRoute();
// 搜索栏配置 // 搜索栏配置
const searchShowData = ref([ const searchShowData = ref([
{ label: '功能描述', placeholder: "请输入", type: 'input', content: '' }, { label: '功能描述', placeholder: "请输入", type: 'input', content: '' },
...@@ -84,6 +87,7 @@ const handleAddInfoFn = () => { ...@@ -84,6 +87,7 @@ const handleAddInfoFn = () => {
const handleRefreshInfoFn = () => { const handleRefreshInfoFn = () => {
console.log("刷新数据"); console.log("刷新数据");
initTableDateFn()
} }
const closeAddDrawer = () => { const closeAddDrawer = () => {
isAddDrawer.value = false; isAddDrawer.value = false;
...@@ -97,6 +101,10 @@ const beforeCloseAddBuildDrawer = () => { ...@@ -97,6 +101,10 @@ const beforeCloseAddBuildDrawer = () => {
const buildingSeeDetails = (data) => { const buildingSeeDetails = (data) => {
console.log("查看详情", data); console.log("查看详情", data);
router.push({
path: '/buildingdetaildate',
params: { data: JSON.stringify(data) },
});
} }
const buildingDdeleteData = (data) => { const buildingDdeleteData = (data) => {
...@@ -104,13 +112,34 @@ const buildingDdeleteData = (data) => { ...@@ -104,13 +112,34 @@ const buildingDdeleteData = (data) => {
confirmButtonText: '确认', confirmButtonText: '确认',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning', type: 'warning',
}).then(() => { })
handleRefreshInfoFn() .then(() => {
ElMessage.success('已删除'); try {
}).catch(() => { // 用户点击「确认」
ElMessage.info('取消删除'); const {buildId,buildName} = data;
buildingRemoveApi({ buildId: buildId })
.then(res => {
if (res.code === 200) {
ElMessage.success("`${buildName}已删除`");
handleRefreshInfoFn();
} else {
ElMessage.error(res.message || '删除失败'); // 更明确的错误提示
}
})
.catch(err => {
// API 请求失败
ElMessage.error(err?.message || '删除请求失败');
}); });
} } catch (error) {
console.error(error,'API 请求失败');
}
})
.catch(() => {
// 用户点击「取消」
ElMessage.info('已取消删除'); // 移除多余的 `err` 参数
});
};
const resetBuildingShowInfo = (data) => { const resetBuildingShowInfo = (data) => {
...@@ -121,31 +150,62 @@ const resetBuildingShowInfo = (data) => { ...@@ -121,31 +150,62 @@ const resetBuildingShowInfo = (data) => {
const closeBuildingEditDrawer = () => { const closeBuildingEditDrawer = () => {
isBuildingEditDrawer.value = false; isBuildingEditDrawer.value = false;
// console.log("000000------------0000000000",isBuildingEditDrawer.value)
} }
// 表格数据 // 表格数据
const tableShowData = ref([{ const tableShowData = ref([{
tableHeader: [ tableHeader: [
{label: '建筑编号', prop: 'buildingNo'}, {label: '建筑编号', prop: 'buildCode'},
{label: '建筑名称', prop: 'buildingName'}, {label: '建筑名称', prop: 'buildName'},
{label: '建筑层数', prop: 'buildingFloorCount'}, {label: '建筑层数', prop: 'totalFloorNum'},
{label: '火情次数', prop: 'buildingFireCount'}, {label: '火情次数', prop: 'fireNum'},
{label: '更新时间', prop: 'buildingUpdataTime'}, {label: '更新时间', prop: 'updateTime'},
{label: '操作', prop: 'buildingOperation'} {label: '操作', prop: 'Operation'}
], ],
tableBody: [ tableBody: []
{buildingNo: '张三', buildingName:"123456", buildingFloorCount: 11, buildingFireCount:3, buildingUpdataTime: Date.now(), buildingOperation: [
{label:'查看详情', type:'primary', icon:'EditPen', click: buildingSeeDetails},
{label:'删除', type:'danger', icon:'Delete', click: buildingDdeleteData},
{label:'修改', type:'primary', icon:'EditPen', click: resetBuildingShowInfo}
]},
{buildingNo: '张s三', buildingName:"123456", buildingFloorCount: 11, buildingFireCount:3, buildingUpdataTime: Date.now(), buildingOperation: [
{label:'查看详情', type:'primary', icon:'EditPen', click: buildingSeeDetails},
{label:'删除', type:'danger', icon:'Delete', click: buildingDdeleteData},
{label:'修改', type:'primary', icon:'EditPen', click: resetBuildingShowInfo}
]},
]
}]); }]);
const Operation = ref([
{ label: '查看详情', type: 'primary', icon: 'EditPen', click: buildingSeeDetails },
{ label: '删除', type: 'danger', icon: 'Delete', click: buildingDdeleteData },
{ label: '修改', type: 'primary', icon: 'EditPen', click: resetBuildingShowInfo }
]);
// onMounted(() => {
// initTableDateFn()
// });
const initTableDateFn = () => {
console.log('初始化数据');
buildingPageApi({currentPageNum: 1, currentPageSize: 10}).then(res => {
if(res.code === 200){
let {list ,total,pageSize} = res.data;
if(!list){
ElMessage.warning('建筑列表暂无数据,请先添加建筑数据');
}else{
tableShowData.value[0].tableBody = []
list = list.filter(element => {
return element.isDeleted === 0;
});
list.forEach(element => {
element.Operation = [...Operation.value]
});
tableShowData.value[0].tableBody = list
tableShowData.value[0].total = total
tableShowData.value[0].pageSize = pageSize
console.log(tableShowData.value, '展示数据');
}
}
}).catch(err => {
ElMessage.error(err?.message || "建筑列表请求失败")
})
};
// 监听路由变化
watch(route, () => {
initTableDateFn()
}, { immediate: true });
// 计算属性 // 计算属性
const containerStyle = computed(() => ({ const containerStyle = computed(() => ({
minHeight: layoutConfig.containerMinHeight, minHeight: layoutConfig.containerMinHeight,
......
<template>
<div class="dashboard-container" :style="containerStyle">
<main class="main-content">
<!-- 左侧区域 -->
<div class="left-section">
<!-- 左侧下部分:统计区域 -->
<div class="info-card stats-alerts">
<div class="card-table">
<onefloorbuildingdetaildate></onefloorbuildingdetaildate>
</div>
</div>
</div>
</main>
</div>
</template>
<script setup>
import { reactive, computed, ref, onMounted } from 'vue';
// import searchtop from '../../commentcomponents/searchtop/index.vue';
import onefloorbuildingdetaildate from '../components/onefloorbuildingdetaildate.vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { staffGetPageInfoApi } from "../../../api/staff.js"
import { message } from 'ant-design-vue';
// import Operation from 'ant-design-vue/es/transfer/operation';
// 定义一个名为searchShowData的ref变量,它是一个数组,数组中的每个元素都是一个对象,对象中包含了label、placeholder、type、content和options等属性
const searchShowData = ref([
{ label: '用户姓名', placeholder: "请输入", type: 'input',content:'' },
{ label: '用户状态', placeholder: "请选择", type: 'select',content:'' , options: [{label:'启用', value:'启用'}, {label:'禁用', value:'禁用'}] },
{ label: '用户角色', placeholder: "请选择", type: 'select', content:'' ,options: [{label:'管理员', value:'管理员'}, {label:'巡查员', value:'巡查员'}]},
])
// 响应式布局配置
const layoutConfig = reactive({
containerMinHeight: '100vh',
cardSpacing: '1rem',
statsMinHeight: '300px'
});
const isUserInfoDialogVisible = ref(false); // 控制用户信息弹窗的显示状态
/**
* 刷新表格数据的方法
* 当调用此方法时,会触发表格数据的重新加载
*/
const tableDataRefresh = () => {
initTableData()
console.log("000000-------2-----0000000000,这里获取到最新的数据")
}
/**
* 控制编辑抽屉的显示状态
* @type {Ref<boolean>} - 响应式布尔值,用于控制编辑抽屉的显示
*/
const isEditDrawer = ref(false)
/**
* 存储行数据
* @type {Ref<Array>} - 响应式数组,用于存储当前选中的行数据
*/
const rowData = ref([])
/**
* 编辑数据的方法
* @param {Object} data - 要编辑的数据对象
*/
const editData = (data) => {
// 打开编辑抽屉
isEditDrawer.value = true
// 设置要编辑的数据
rowData.value = data
console.log("000000-------1-----0000000000",data)
}
/**
* 删除数据的方法
* @param {Object} data - 要删除的数据对象
* 显示确认对话框,用户确认后执行删除操作
*/
const deleteData = (data) => {
console.log("000000---2---------0000000000",data)
ElMessageBox.confirm(
'删除操作不可逆,是否继续?',
'删除',
{
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
draggable: true,
}
)
.then(() => {
console.log("000000---1-456464564------0000000000","我是确认")
try {
const res = staffRemoveInfoApi({id:data.id});
if (res.code === 200) {
ElMessage({ type: 'success', message: '已删除' });
tableDataRefresh();
} else {
ElMessage({ type: 'error', message: '删除失败:' + res.msg });
}
} catch (err) {
// API 请求失败时在此捕获,不向上冒泡
ElMessage({ type: 'error', message: '删除失败(网络错误)' });
// console.error('删除接口失败:', err);
}
})
.catch(() => {
ElMessage({
type: 'info',
message: '取消删除',
})
})
}
// const deleteUserDate = (data) => {
// staffRemoveInfoApi(data).then((res) => {
// console.log(res,'--------------8--');
// if(res.code==200){
// ElMessage({
// type: 'success',
// message: '已删除',
// })
// tableDataRefresh()
// }
// }).catch(() => {
// ElMessage({
// type: 'info',
// message: '删除shibai',
// })
// })
// }
const isResetPasswordDialogVisible = ref(false); // 控制重置密码弹窗的显示状态
const resetPasswordData = ref({});
const resetData = (data) => {
console.log("000000-----3-------0000000000",data)
isResetPasswordDialogVisible.value = true;
resetPasswordData.value = data;
}
const showuserinfodata = ref({})
const userData = (data) => {
console.log("000000------4------0000000000",data)
isUserInfoDialogVisible.value = true
showuserinfodata.value = data
}
const tableShowData = ref([{
tableHeader:[
{label: '姓名', prop: 'name'},
{label: '电话', prop: 'phone'},
{label: '是否可用', prop: 'status'},
{label: '用户权限', prop: 'role'},
{label: '创建时间', prop: 'createTime'},
{label: '更新时间', prop: 'updateTime'},
{label: '操作', prop: 'Operation'}
],
tableBody:[
]
}
])
const Operation = ref( [ { label: '编辑', type: 'primary', icon: 'EditPen', click: editData },
{ label: '删除', type: 'danger', icon: 'Delete', click: deleteData },
{ label: '用户信息', type: 'primary', icon: 'EditPen', click: userData },
{ label: '重置密码', type: 'primary', icon: 'EditPen', click: resetData }]
)
const initTableData = () => {
staffGetPageInfoApi({
"currentPageNum": 1,
"currentPageSize": 10,
}).then(res => {
if(res.code === 200){
let tempData = res.data.list
tableShowData.value[0].tableBody = []
//获取未逻辑删除的数据
console.log(res.data,"--------999999999----")
tempData = tempData.filter(element => {
return element.isDeleted === 0;
});
tempData.forEach(element => {
element.Operation = [...Operation.value]
});
tableShowData.value[0].tableBody = tempData
tableShowData.value[0].total = res.data.total
tableShowData.value[0].pageSize = res.data.pageSize
console.log(tableShowData.value, '展示数据');
}
}).catch(err => {
ElMessage.error(err.message)
})
}
onMounted(() => {
// console.log(tableShowData.value, '错误');
initTableData()
})
// 计算容器样式
const containerStyle = computed(() => ({
minHeight: layoutConfig.containerMinHeight,
'--card-spacing': layoutConfig.cardSpacing,
}));
</script>
<style scoped>
.dashboard-container {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: rgba(0, 0, 0, 0.05);
color: #333;
}
.main-content {
display: flex;
gap: var(--card-spacing);
padding: 0.4rem;
height: 100vh;
box-sizing: border-box;
}
.left-section {
flex: 2;
display: flex;
flex-direction: column;
gap: var(--card-spacing);
height: 100%;
}
.left-top {
height: auto;
}
/* 通用卡片样式 */
.info-card {
background-color: #fff;
padding: 1rem;
border-radius: 8px;
box-sizing: border-box;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
overflow: auto;
}
.region-overview {
flex: 1;
min-width: 200px;
}
/* 统计区域 */
.stats-alerts {
display: flex;
flex-direction: column;
gap: 1rem;
height: 79.5%;
overflow: auto;
}
.card-tabs {
display: flex;
border-bottom: 1px solid #292828;
/* margin-bottom: 1rem; */
font-size: 1.2rem;
color: #000000;
/* background-color: #002aff; */
height: 8%;
display: flex;
align-items: center;
width: 100%;
padding: 10px;
}
.title{
width: 70%;
}
.card-actions {
display: flex;
flex: 1;
justify-content: space-between;
align-items: center;
/* margin-bottom: 1rem; */
height: 8%;
padding: 1.5rem;
}
.operation-button {
width: 15%;
}
.card-tabs-footer {
display: flex;
/* margin-bottom: 1rem; */
font-size: 1.2rem;
color: #000000;
/* background-color: #002aff; */
height: 8%;
align-items: center;
width: 100%;
padding: 10px 0;
justify-content: flex-end;
align-items: center;
}
/* 文本样式 */
.page-text {
color: #606266;
font-size: 14px;
white-space: nowrap; /* 防止文本换行 */
}
/* 修复 Element Plus 分页组件默认的块级布局问题 */
:deep .el-pagination {
display: flex;
align-items: center;
margin: 0; /* 清除默认外边距 */
}
.pagination-block{
height: 8%;
}
.card-table{
width: 100%;
/* display: flex; */
/* background-color: #000000; */
flex:1;
overflow: hidden;
border-radius: 8PX;
}
/* 响应式适配 */
@media (max-width: 1024px) {
.left-top {
flex-direction: column;
}
.region-overview {
width: 100%;
flex: none;
}
}
@media (max-width: 768px) {
.stats-alerts {
flex-direction: column;
}
}
</style>
\ No newline at end of file
<template> <template>
<div> <div>
<el-table <vxe-table
style="width: 100%;"
ref="tableRef"
@checkbox-change="selectTableDateFn"
@checkbox-all="selectTableDateFn"
@edit-closed="handleAfterEdit"
show-overflow
:edit-config="{trigger: 'click', mode: 'cell'}"
:data="tableShowData">
<vxe-column field="checkbox" type="checkbox" width="50"></vxe-column>
<vxe-column field="id" title="火情编号" min-width="80" ></vxe-column>
<vxe-column field="name" title="建筑名称" min-width="150" ></vxe-column>
<vxe-column field="floorcount" title="火情楼层" min-width="150" ></vxe-column>
<vxe-column field="reporter" title="上报人" min-width="150" ></vxe-column>
<vxe-column field="fireLevel" title="火情等级" width="150" :edit-render="fireLevelEditRender" ></vxe-column>
<vxe-column field="updateTime" title="上报时间" min-width="150" ></vxe-column>
<vxe-column field="discription" title="火情描述" :edit-render="fireDescripEditRender" min-width="150" ></vxe-column>
<vxe-column title="详情查看" min-width="220" >
<template #default="scope">
<el-button @click="handleClick(scope.row)">图片查看</el-button>
<el-button @click="handleVideoDialogFn(scope.row)">视频查看</el-button>
</template>
</vxe-column>
<vxe-column title="操作" min-width="220" >
<template #default="scope">
<el-button @click="taskSchedulingFn(scope.row)">任务调度</el-button>
</template>
</vxe-column>
</vxe-table>
</div>
<div>
<!-- <el-table
:data="tableShowData" :data="tableShowData"
style="width: 100%" style="width: 100%"
@select="selectTableDateFn" @select="selectTableDateFn"
...@@ -13,11 +55,21 @@ ...@@ -13,11 +55,21 @@
<el-table-column prop="floorcount" label="火情楼层" width="120" /> <el-table-column prop="floorcount" label="火情楼层" width="120" />
<el-table-column prop="reporter" label="上报人" width="120" /> <el-table-column prop="reporter" label="上报人" width="120" />
<el-table-column prop="updateTime" label="上报时间" width="220" /> <el-table-column prop="updateTime" label="上报时间" width="220" />
<el-table-column prop="fireLevel" label="火情等级" width="220" /> <el-table-column label="火情等级" width="220" >
<template #default="scope">
<el-select v-model="scope.row.fireLevel" placeholder="Select" >
<el-option
v-for="item in fireLevelOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column prop="discription" label="火情描述" /> <el-table-column prop="discription" label="火情描述" />
<el-table-column <el-table-column
label="详情查看" label="详情查看"
show-overflow-tooltip show-overflow-tooltip
> >
<template #default="scope"> <template #default="scope">
...@@ -37,7 +89,7 @@ ...@@ -37,7 +89,7 @@
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table> -->
<!-- 分页区域(固定在右下角) --> <!-- 分页区域(固定在右下角) -->
<div class="card-tabs-footer" > <div class="card-tabs-footer" >
<div class="pagination-block"> <div class="pagination-block">
...@@ -136,7 +188,46 @@ ...@@ -136,7 +188,46 @@
</template> </template>
<script setup> <script setup>
import { message } from 'ant-design-vue'
const fireLevelEditRender = reactive({
name: 'select',
options: [
{ label: '一级火情', value: '1' },
{ label: '二级火情', value: '2' },
{ label: '三级火情', value: '3' },
{ label: '四级火情', value: '4' },
]
})
const fireDescripEditRender = reactive({
name: 'input',
})
const handleAfterEdit = ({ row, column }) => {
console.log('编辑完成后的行数据:', row);
// 可以在这里提交数据或做其他操作
return true; // 返回 true 表示编辑成功,false 会阻止修改
};
const fireLevelOptions = [
{ label: '一级火情', value: '1' },
{ label: '二级火情', value: '2' },
{ label: '三级火情', value: '3' },
{ label: '四级火情', value: '4' },
{ label: '五级火情', value: '5' },
]
const emit = defineEmits(['archiveInfoDateBackcallFn']) const emit = defineEmits(['archiveInfoDateBackcallFn'])
const props = defineProps({ const props = defineProps({
tableShowData: { tableShowData: {
...@@ -185,9 +276,18 @@ const taskSchedulingFn = (info) => { ...@@ -185,9 +276,18 @@ const taskSchedulingFn = (info) => {
console.log("任务调度",info) console.log("任务调度",info)
isTaskSchedulingDialogVisible.value = true isTaskSchedulingDialogVisible.value = true
} }
const selectTableDateFn = (selectedRows) => { const tableRef = ref() // 确保这里声明了 tableRef
console.log('selectTableDateFn选择的数据信息',selectedRows) const selectTableDateFn = () => {
emit('archiveInfoDateBackcallFn',selectedRows)
const $table = tableRef.value
if ($table) {
emit('archiveInfoDateBackcallFn',$table.getCheckboxRecords())
}else{
console.log('未找到表格实例')
message.error('未找到表格实例')
}
// console.log('selectTableDateFn选择的数据信息',tableRef.value)
// emit('archiveInfoDateBackcallFn',selectedRows)
} }
// 分页数据 // 分页数据
......
...@@ -14,9 +14,10 @@ ...@@ -14,9 +14,10 @@
<!-- 左侧下部分:统计区域 --> <!-- 左侧下部分:统计区域 -->
<div class="info-card stats-alerts"> <div class="info-card stats-alerts">
<div class="card-tabs"> <div class="card-tabs">
<span class="title">当前火情</span> <span class="title">历史火情</span>
<div class="card-actions"> <div class="card-actions">
<el-button class="operation-button" type="primary" @cliick="archiveInfoFn" >归档</el-button> <el-button class="operation-button" type="primary" @cliick="archiveInfoFn" >归档</el-button>
<el-button class="operation-button" type="primary" @cliick="archiveInfoFn1" >归档1</el-button>
</div> </div>
</div> </div>
<div class="card-table"> <div class="card-table">
...@@ -25,6 +26,15 @@ ...@@ -25,6 +26,15 @@
</div> </div>
</div> </div>
</main> </main>
<!-- 归档窗口 -->
<el-drawer
v-model="archiveInfoDrawer"
direction="rtl"
:before-close="handleClose"
>
asdada
</el-drawer>
</div> </div>
</template> </template>
...@@ -73,11 +83,24 @@ const archiveInfoDateBackcallFn = (row) => { ...@@ -73,11 +83,24 @@ const archiveInfoDateBackcallFn = (row) => {
archiveInfoDate.value = row archiveInfoDate.value = row
console.log('archiveInfoFn需要归档的数据',archiveInfoDate.value) console.log('archiveInfoFn需要归档的数据',archiveInfoDate.value)
}; };
const archiveInfoDrawer = ref(false)
const archiveInfoFn = () => { const archiveInfoFn = () => {
if ( archiveInfoDate ===undefined ||archiveInfoDate.value===null || archiveInfoDate.value.length<=0 ) {
ElMessage.warning("没有勾选数据")
}else {
console.log('archiveInfoFn归档的数据',archiveInfoDate.value) console.log('archiveInfoFn归档的数据',archiveInfoDate.value)
}; // archiveInfoDrawer.value = true
fireInfoDataImport.value = null
}
}
const archiveInfoFn1 = () => {
ElMessage.warning("没有勾选数据")
}
const handleAddInfoFn = () => { const handleAddInfoFn = () => {
isAddDrawer.value = true; isAddDrawer.value = true;
} }
...@@ -166,7 +189,7 @@ const containerStyle = computed(() => ({ ...@@ -166,7 +189,7 @@ const containerStyle = computed(() => ({
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: rgba(0, 0, 0, 0.05); background-color: rgba(0, 0, 0, 0.05);
color: #333; color: #333;
overflow: hidden; /* overflow: hidden; */
} }
.main-content { .main-content {
...@@ -206,6 +229,7 @@ const containerStyle = computed(() => ({ ...@@ -206,6 +229,7 @@ const containerStyle = computed(() => ({
.stats-alerts { .stats-alerts {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
flex: 1;
gap: 1rem; gap: 1rem;
height: 67%; height: 67%;
} }
...@@ -218,6 +242,7 @@ const containerStyle = computed(() => ({ ...@@ -218,6 +242,7 @@ const containerStyle = computed(() => ({
height: 8%; height: 8%;
align-items: center; align-items: center;
width: 100%; width: 100%;
/* background-color: aqua; */
padding: 10px; padding: 10px;
} }
...@@ -243,7 +268,7 @@ const containerStyle = computed(() => ({ ...@@ -243,7 +268,7 @@ const containerStyle = computed(() => ({
.card-table { .card-table {
width: 100%; width: 100%;
flex: 1; flex: 1;
overflow: hidden; /* overflow: hidden; */
border-radius: 8px; border-radius: 8px;
} }
......
<template>
<div class="fire-report-detail">
<!-- 页面标题 -->
<div class="report-header">
<h2>火情上报详情</h2>
<span class="close-btn" @click="handleClose"> <el-icon><Close /></el-icon></span>
</div>
<!-- 表单内容 -->
<div class="report-content">
<!-- 基本信息区域 -->
<div class="info-section">
<div class="info-item">
<label class="info-label">上报人:</label>
<div class="info-value">
<input type="text" placeholder="请输入" class="info-value" disabled :value="`${userAppStoreInstance.userInfo.name}`">
</div>
</div>
<div class="info-item">
<label class="info-label">着火建筑:</label>
<div class="info-value"><input type="text" placeholder="请输入" class="info-value" ></div>
</div>
<div class="info-item">
<label class="info-label">着火楼层:</label>
<div class="info-value"><input type="text" placeholder="请输入" class="info-value" ></div>
</div>
</div>
<!-- 图片区域 -->
<div class="media-section">
<h3 class="section-title">现场图片</h3>
<div class="image-container">
<updataImg :updataImageCount="1"></updataImg>
</div>
</div>
<!-- 视频区域 -->
<div class="media-section">
<h3 class="section-title">现场视频</h3>
<div class="video-container">
<video src="" controls></video>
</div>
</div>
<!-- 描述区域 -->
<div class="description-section">
<h3 class="section-title">描述</h3>
<el-input
type="textarea"
placeholder="请输入"
class="description-input"
:rows="4"
/>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import useAppStore from '../../../../store/module/app';
import updataImg from '../../../systemmanage/components/updataImg.vue';
const userAppStoreInstance = useAppStore();
// 关闭按钮事件
const handleClose = () => {
// 这里可以添加关闭当前页面或弹窗的逻辑
console.log('关闭火情上报详情');
};
// 监听窗口大小变化,实现自适应
const handleResize = () => {
// 可以在这里添加需要响应式调整的逻辑
console.log('窗口大小变化');
};
onMounted(() => {
window.addEventListener('resize', handleResize);
});
onUnmounted(() => {
window.removeEventListener('resize', handleResize);
});
</script>
<style scoped lang="scss">
.fire-report-detail {
width: 100%;
height: 90%;
min-height: 100vh;
padding: 10px;
box-sizing: border-box;
background-color: #f9f9f9;
.report-header {
display: flex;
justify-content: space-between;
align-items: center;
// margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 1px solid #e0e0e0;
h2 {
margin: 0;
font-size: 1.5rem;
color: #333;
}
.close-btn {
padding: 5px 10px;
}
.close-btn:hover{
background-color: rgb(118, 143, 168,0.1);
cursor: pointer
}
}
.report-content {
max-width: 1200px;
margin: 0 auto;
}
.info-section {
display: flex;
flex-direction: column; /* 子元素竖直排列 */
gap: 16px; /* info-item 之间的间距(竖直方向) */
padding: 10px; /* 可选:整体内边距 */
.info-item {
display: flex; /* 内部元素水平排列 */
align-items: center; /* 垂直居中对齐 */
gap: 12px; /* label 和 value 之间的间距(水平方向) */
.info-label {
width: 80px; /* 固定宽度,确保所有 label 对齐 */
font-weight: 500; /* 可选:加粗标签文字 */
color: #666; /* 可选:标签文字颜色 */
}
.info-value {
flex: 1; /* 占满剩余宽度 */
padding: 0px 4px; /* 内边距,增强可读性 */
border-radius: 4px; /* 可选:圆角边框 */
min-height: 36px; /* 可选:固定高度,确保对齐 */
display: flex; /* 内容垂直居中 */
align-items: center;
}
}
}
.section-title {
font-size: 1.1rem;
color: #333;
margin-bottom: 15px;
padding-left: 5px;
border-left: 3px solid #409eff;
}
.media-section {
margin-bottom: 30px;
.image-container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 20px;
.image-item {
aspect-ratio: 4/3;
background-color: #f0f0f0;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
.placeholder-image {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
color: #999;
.image-icon {
font-size: 2rem;
}
}
}
}
.video-container {
width: 100%;
.video-placeholder {
width: 100%;
aspect-ratio: 16/9;
background: linear-gradient(to bottom, #444, #222);
border-radius: 4px;
position: relative;
overflow: hidden;
.video-overlay {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: #fff;
font-size: 1rem;
text-align: center;
}
.video-controls {
position: absolute;
bottom: 0;
left: 0;
right: 0;
padding: 10px;
background: linear-gradient(transparent, rgba(0,0,0,0.7));
color: #fff;
display: flex;
align-items: center;
gap: 15px;
.play-btn {
background: rgba(0,0,0,0.5);
color: #fff;
width: 36px;
height: 36px;
border-radius: 50%;
padding: 0;
display: flex;
align-items: center;
justify-content: center;
}
.video-time {
font-size: 0.8rem;
min-width: 80px;
}
.video-progress {
flex: 1;
height: 4px;
background-color: rgba(255,255,255,0.3);
border-radius: 2px;
position: relative;
.progress-bar {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 30%;
background-color: #409eff;
border-radius: 2px;
.progress-indicator {
position: absolute;
right: 0;
top: 50%;
transform: translate(50%, -50%);
width: 12px;
height: 12px;
background-color: #fff;
border-radius: 50%;
box-shadow: 0 0 5px rgba(0,0,0,0.3);
}
}
}
.volume-btn, .fullscreen-btn {
color: #fff;
background: transparent;
padding: 5px;
}
}
}
}
}
.description-section {
.description-input {
width: 100%;
min-height: 120px;
}
}
}
/* 响应式调整 */
@media (max-width: 768px) {
.fire-report-detail {
padding: 15px 10px;
.info-section {
grid-template-columns: 1fr;
}
.image-container {
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
}
.video-controls {
gap: 10px;
.video-time {
display: none;
}
}
}
}
</style>
\ No newline at end of file
...@@ -19,10 +19,12 @@ ...@@ -19,10 +19,12 @@
<!-- 左侧下部分:统计区域 --> <!-- 左侧下部分:统计区域 -->
<div class="info-card stats-alerts"> <div class="info-card stats-alerts">
<div class="card-tabs"> <div class="card-tabs">
<span class="title" >单次火情汇报列表</span> <span class="title" >火情汇报列表</span>
<div class="card-actions"> <div class="card-actions">
<el-button class="operation-button" type="primary" size="small" @click="fireInfoDataImportFn" >导入</el-button> <!-- <el-button type="danger" plain>Danger</el-button> -->
<el-button class="operation-button" type="danger" plain @click="fireInfoDataDeleteFn" >撤销归档</el-button>
<el-button class="operation-button" type="danger" plain @click="fireInfoDataDeleteFn" >删除</el-button>
<el-button class="operation-button" type="primary" @click="addFireInfoDataImportFn" >新增</el-button>
</div> </div>
</div> </div>
<div class="card-table"> <div class="card-table">
...@@ -33,8 +35,13 @@ ...@@ -33,8 +35,13 @@
</div> </div>
</div> </div>
</main> </main>
<!-- 新增添加框 -->
<el-drawer
v-model="addFireInfoDataImportFndrawer"
:with-header="false"
>
<addFireInfo></addFireInfo>
</el-drawer>
</div> </div>
</template> </template>
...@@ -45,21 +52,35 @@ import { reactive, computed, ref, onMounted } from 'vue'; ...@@ -45,21 +52,35 @@ import { reactive, computed, ref, onMounted } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import addFireInfo from './addFireInfo.vue';
import Tableshowdetail from './tableshowdetail.vue'; import Tableshowdetail from './tableshowdetail.vue';
const addFireInfoDataImportFndrawer = ref(false);
const addFireInfoDataImportFn = () => {
addFireInfoDataImportFndrawer.value = true
}
const fireInfoDataImport = ref(null); const fireInfoDataImport = ref(null);
const fireInfoDataImportBackcallFn = (info) => { const fireInfoDataImportBackcallFn = (info) => {
fireInfoDataImport.value = info fireInfoDataImport.value = info
} }
const fireInfoDataDeleteFn = () => {
if ( fireInfoDataImport ===undefined ||fireInfoDataImport.value===null || fireInfoDataImport.value.length<=0 ) {
ElMessage.warning("没有勾选数据")
}else {
console.log("删除数据",fireInfoDataImport.value)
fireInfoDataImport.value = null
}
}
const fireInfoDataImportFn = () => { const fireInfoDataImportFn = () => {
// if ( fireInfoDataImport.value===undefined ||fireInfoDataImport.value===null) { if ( fireInfoDataImport ===undefined ||fireInfoDataImport.value===null || fireInfoDataImport.value.length<=0 ) {
// ElMessage.warning("没有勾选数据") ElMessage.warning("没有勾选数据")
// } }else {
console.log("导入数据",fireInfoDataImport.value) console.log("导入数据",fireInfoDataImport.value)
fireInfoDataImport.value = null fireInfoDataImport.value = null
}
} }
// import Operation from 'ant-design-vue/es/transfer/operation'; // import Operation from 'ant-design-vue/es/transfer/operation';
...@@ -301,6 +322,7 @@ const containerStyle = computed(() => ({ ...@@ -301,6 +322,7 @@ const containerStyle = computed(() => ({
border-radius: 8px; border-radius: 8px;
box-sizing: border-box; box-sizing: border-box;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
/* overflow: auto; */ /* overflow: auto; */
} }
...@@ -320,11 +342,11 @@ const containerStyle = computed(() => ({ ...@@ -320,11 +342,11 @@ const containerStyle = computed(() => ({
.card-tabs { .card-tabs {
display: flex; display: flex;
border-bottom: 1px solid #8a8787; /* border-bottom: 1px solid #8a8787; */
font-size: 1.2rem; font-size: 1.2rem;
color: #000000; color: #000000;
padding: 1.3rem;
height: 8%; height: 8%;
display: flex; display: flex;
align-items: center; align-items: center;
......
...@@ -47,9 +47,48 @@ ...@@ -47,9 +47,48 @@
/> />
</div> </div>
</div> </div>
<!-- 火情模拟对话框 -->
<el-dialog
v-model="isFireSimulationDialogVisible"
width="800px"
:before-close="handleClose"
custom-class="task-scheduling-dialog"
>
<!-- 标题区域 -->
<template #header>
<div class="dialog-header">
<span class="dialog-title">火情模拟</span>
</div>
</template>
<!-- 内容区域 -->
<div class="dialog-content">
<div class="notification-box">
<el-icon class="notification-icon"><Bell /></el-icon>
<span class="notification-text">系统已开始进行火情模拟,点击跳转按钮可以进入大屏观察火情模拟</span>
</div>
</div> </div>
<!-- 底部按钮 -->
<template #footer>
<div class="dialog-footer">
<el-button type="primary" class="action-button">
<template #icon><VideoPlay /></template>
前往
</el-button>
<el-button class="action-button">
确认
</el-button>
</div>
</template>
</el-dialog>
</div>
</template> </template>
<script setup> <script setup>
...@@ -62,13 +101,14 @@ const props = defineProps({ ...@@ -62,13 +101,14 @@ const props = defineProps({
}, },
}) })
const isFireSimulationDialogVisible = ref(false)
const route = useRoute() const route = useRoute()
const router = useRouter() const router = useRouter()
const imageRef = ref(null) const imageRef = ref(null)
const showPreview = ref(false) const showPreview = ref(false)
const fireSimulationFn = (info) => { const fireSimulationFn = (info) => {
isFireSimulationDialogVisible.value = true
console.log("火情模拟",info) console.log("火情模拟",info)
} }
...@@ -81,7 +121,8 @@ const exportReportFn = (info) => { ...@@ -81,7 +121,8 @@ const exportReportFn = (info) => {
const detailViewsFn = (info) => { const detailViewsFn = (info) => {
console.log("详情查看",info,route) console.log("详情查看",info,route)
router.push({ router.push({
path: '/historyfire/floordetaildate', name: 'floorDetailDate',
}) })
......
...@@ -14,7 +14,18 @@ ...@@ -14,7 +14,18 @@
<el-table-column prop="reporter" label="上报人员" width="120" /> <el-table-column prop="reporter" label="上报人员" width="120" />
<el-table-column prop="updateTime" label="上报时间" width="120" /> <el-table-column prop="updateTime" label="上报时间" width="120" />
<el-table-column prop="discription" label="火情描述" width="220" show-overflow-tooltip/> <el-table-column prop="discription" label="火情描述" width="220" show-overflow-tooltip/>
<el-table-column prop="fireLevel" label="火情等级" width="120" /> <el-table-column prop="fireLevel" label="火情等级" width="120" show-overflow-tooltip>
<template #default="scope">
<el-select v-model="scope.row.fireLevel" >
<el-option
v-for="item in fireOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</template>
</el-table-column>
<el-table-column prop="firePoint" label="着火点" width="220" show-overflow-tooltip /> <el-table-column prop="firePoint" label="着火点" width="220" show-overflow-tooltip />
<el-table-column <el-table-column
label="详情查看" label="详情查看"
...@@ -98,7 +109,14 @@ const emit = defineEmits(['fireInfoDataImportBackcallFn']) ...@@ -98,7 +109,14 @@ const emit = defineEmits(['fireInfoDataImportBackcallFn'])
// const props = defineProps(['tableShowData']) // const props = defineProps(['tableShowData'])
const router = useRouter() const router = useRouter()
const route = useRoute() const route = useRoute()
const fireOptions = [
{ label: '一级火情', value: '1' },
{ label: '二级火情', value: '2' },
{ label: '三级火情', value: '3' },
{ label: '四级火情', value: '4' },
{ label: '五级火情', value: '5' },
{ label: '六级火情', value: '6' },
]
const tableShowData =[{ const tableShowData =[{
id: 1, id: 1,
fireNo:12, fireNo:12,
...@@ -108,7 +126,7 @@ const tableShowData =[{ ...@@ -108,7 +126,7 @@ const tableShowData =[{
reporter:"张三", reporter:"张三",
updateTime:"2022-05-04", updateTime:"2022-05-04",
discription: 'Lorem ipsum dolor sit ametisl nisl nisl nisl nisl nisl nisl nisl nis', discription: 'Lorem ipsum dolor sit ametisl nisl nisl nisl nisl nisl nisl nisl nis',
fireLevel: '1', fireLevel: '1',
firePoint: '厨房', firePoint: '厨房',
}, },
...@@ -121,7 +139,7 @@ const tableShowData =[{ ...@@ -121,7 +139,7 @@ const tableShowData =[{
reporter:"张三", reporter:"张三",
updateTime:"2022-05-04", updateTime:"2022-05-04",
discription: 'Lorem ipsum dolor sit ametisl nisl nisl nisl nisl nisl nisl nisl nis', discription: 'Lorem ipsum dolor sit ametisl nisl nisl nisl nisl nisl nisl nisl nis',
fireLevel: '1级', fireLevel: '2',
firePoint: '厨房', firePoint: '厨房',
}] }]
......
...@@ -14,11 +14,8 @@ ...@@ -14,11 +14,8 @@
<!-- 左侧下部分:统计区域 --> <!-- 左侧下部分:统计区域 -->
<div class="info-card stats-alerts"> <div class="info-card stats-alerts">
<div class="card-tabs"> <div class="card-tabs">
<span class="title">历史火情</span> <span class="title">当前火情</span>
<!-- <div class="card-actions">
<el-button class="operation-button" type="primary" @cliick="archiveInfoFn" >归档</el-button>
</div> -->
</div> </div>
<div class="card-table"> <div class="card-table">
<tableshow :tableShowData="tableShowData" @archiveInfoDateBackcallFn="archiveInfoDateBackcallFn"></tableshow> <tableshow :tableShowData="tableShowData" @archiveInfoDateBackcallFn="archiveInfoDateBackcallFn"></tableshow>
......
...@@ -167,7 +167,7 @@ ...@@ -167,7 +167,7 @@
:before-close="handleClose" :before-close="handleClose"
> >
<updataImgInfo :file="aerialViewUrl" @changeAerialView="changeAerialView" ></updataImgInfo> <updataImgInfo :file="aerialViewUrl" @changeAerialView="changeAerialView" :updataImageCount="1" ></updataImgInfo>
</el-dialog> </el-dialog>
<!-- 展示鸟瞰图 --> <!-- 展示鸟瞰图 -->
<el-dialog <el-dialog
......
...@@ -82,8 +82,9 @@ const resetSearchForm = () => { ...@@ -82,8 +82,9 @@ const resetSearchForm = () => {
.search-row { .search-row {
/* background-color: #606266; */ /* background-color: #606266; */
width: 80%;
display: flex; display: flex;
flex: 1;
align-items: center; align-items: center;
justify-items: center; justify-items: center;
justify-content: space-between; justify-content: space-between;
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
<el-table <el-table
:data="curTableShowData[0].tableBody" :data="curTableShowData[0].tableBody"
style="width: 100%;height: 100%;" style="width: 100%;height: 100%;"
fixed
@load="handleTableLoad"
> >
<template v-for="(items, index) in curTableShowData[0].tableHeader" :key="index"> <template v-for="(items, index) in curTableShowData[0].tableHeader" :key="index">
...@@ -33,23 +35,19 @@ ...@@ -33,23 +35,19 @@
<div v-else-if="items.prop == 'status'"> <div v-else-if="items.prop == 'status'">
<el-switch <el-switch
v-model="scope.row[items.prop]" v-model="scope.row[items.prop]"
active-color="#13ce66" class="mt-2"
inactive-color="#ff4949" style="margin-left: 24px"
disabled inline-prompt
:active-icon="Check"
:inactive-icon="Close"
@change="changeStatusFn(scope.row)"
/> />
</div> </div>
<div v-else-if="items.prop == 'role'"> <div v-else-if="items.prop == 'role'">
<span class="role-tag" :class="scope.row[items.prop]==='0'|| scope.row[items.prop] ==='10' ? 'admin' : 'inspector'" >
<span >{{ useAppStoreInstance.position[scope.row[items.prop]] }}</span>
</span>
<el-button
type="primary"
round
:style="{
backgroundColor: scope.row[items.prop] ==='0' ? '#67C23A' : '#F56C6C' // 0→绿色(管理员),1→红色(巡查人员)
}"
>
{{ scope.row[items.prop] === "0" ? "管理员" : "巡查人员" }} <!-- 文本逻辑不变 -->
</el-button>
</div> </div>
<div v-else> <div v-else>
...@@ -84,14 +82,19 @@ ...@@ -84,14 +82,19 @@
<script setup> <script setup>
import { onMounted, ref, toRef } from 'vue'; import { onMounted, ref, toRef } from 'vue';
import { staffGetPageInfoApi } from '../../../api/staff'; import { staffGetPageInfoApi ,staffSetAbleApi} from '../../../api/staff';
import { message } from 'ant-design-vue'; import { message } from 'ant-design-vue';
import { pa } from 'element-plus/es/locales.mjs'; import { pa } from 'element-plus/es/locales.mjs';
import { color } from 'echarts';
import { Check, Close } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus';
import useAppStore from '../../../store/module/app';
const useAppStoreInstance = useAppStore();
// const value = ref(true);
const props = defineProps(["tableShowData",'Operation']) const props = defineProps(["tableShowData",'Operation'])
const emits = defineEmits(["tableDataRefresh"])
const curTableShowData = ref(props.tableShowData) const curTableShowData = ref(props.tableShowData)
console.log("11111111111111111111111props.tableShowData-----------------",props.Operation) console.log("11111111111111111111111props.tableShowData-----------------",props.Operation)
...@@ -99,6 +102,25 @@ console.log("11111111111111111111111props.tableShowData-----------------",props. ...@@ -99,6 +102,25 @@ console.log("11111111111111111111111props.tableShowData-----------------",props.
const currentPage2 = ref(1) const currentPage2 = ref(1)
const pageSize2 = ref(10) const pageSize2 = ref(10)
const changeStatusFn = (info) => {
console.log("changeStatusFn-----------------",info)
const submitDate = {
"id":info.id,
"status": info.status?0:1
}
console.log("submitDate-----------------",submitDate)
if (submitDate.id ==='' || submitDate.status ==='') {
ElMessage.warning('缺少操作的行数据!')
}else {
(staffSetAbleApi(submitDate)) .then(res => {
emits('tableDataRefresh')
ElMessage.success(`${submitDate.status===1?'禁用':'启用'} 操作成功!`)
}).catch(err => {
ElMessage.error("changeStatusFn err",err.message)
})
}
}
// 处理按钮点击事件 // 处理按钮点击事件
const handleButtonClick = (value, row) => { const handleButtonClick = (value, row) => {
// console.log('点击了按钮:', value) // console.log('点击了按钮:', value)
...@@ -159,6 +181,29 @@ const getNewTableData = () => { ...@@ -159,6 +181,29 @@ const getNewTableData = () => {
</script> </script>
<style scoped> <style scoped>
.role-tag {
font-weight: 500;
}
.admin {
background-color: #ecf5ff;
color: #409eff;
}
/* 巡查员标签 */
.inspector {
background-color: #f0f9eb;
color: #67c23a;
}
.gradient-text {
background: linear-gradient(90deg, #ff3366, #ffcc00, #33cc33, #3399ff, #cc33ff);
-webkit-background-clip: text; /* 关键属性 */
background-clip: text;
color: transparent; /* 文字透明显露出背景 */
font-size: 1em;
font-weight: bold;
}
/* 容器样式 */ /* 容器样式 */
.table-container { .table-container {
position: relative; /* 为分页定位提供基准 */ position: relative; /* 为分页定位提供基准 */
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<div class="sidebar-container"> <div class="sidebar-container">
<div class="nav-grid"> <div class="nav-grid">
<!-- 首页 --> <!-- 首页 -->
<div class="nav-item" v-for="(items, index) in menuItems" :key="index" @click="handleNavClick(value)"> <div class="nav-item" v-for="(items, index) in menuItems" :key="index" @click="handleNavClick(items)">
<div class="nav-icon"> <div class="nav-icon">
<img style=" width:100%;" :src="items.icon"> <img style=" width:100%;" :src="items.icon">
</div> </div>
...@@ -17,29 +17,28 @@ ...@@ -17,29 +17,28 @@
</template> </template>
<script setup> <script setup>
import { message } from 'ant-design-vue';
import { it } from 'element-plus/es/locales.mjs'; import { it } from 'element-plus/es/locales.mjs';
import { ref } from 'vue'; import { ref } from 'vue';
import { useRouter } from 'vue-router'; import { useRouter, useRoute } from 'vue-router';
const router = useRouter(); const router = useRouter();
const route = useRoute();
const activeItem = ref('首页'); // 默认激活首页 const activeItem = ref('首页'); // 默认激活首页
const props = defineProps(['menuItems']); const props = defineProps(['menuItems']);
// 导航菜单数据
// const navItems = ref([
// { name: '首页', icon: 'home', path: '/' },
// { name: '系统管理', icon: 'settings', path: '/system' },
// { name: '建筑管理', icon: 'building', path: '/buildings' },
// { name: '无人机管理', icon: 'drone', path: '/drones' },
// { name: '火情管理', icon: 'fire', path: '/fires' },
// { name: '数字孪生管理', icon: 'digital-twin', path: '/digital-twin' },
// { name: '个人信息', icon: 'profile', path: '/profile' }
// ]);
// 导航点击处理 // 导航点击处理
const handleNavClick = (item) => { const handleNavClick = (item) => {
activeItem.value = item.name; console.log('点击了导航项:', item,route);
try {
router.push(item.path); router.push(item.path);
message.success('跳转:' + item.name);
} catch (error) {
console.log('导航项 错误 error', error);
}
}; };
</script> </script>
......
...@@ -9,10 +9,10 @@ ...@@ -9,10 +9,10 @@
<!-- 区域信息概览 --> <!-- 区域信息概览 -->
<div class="info-card region-overview"> <div class="info-card region-overview">
<div class="info-grid"> <div class="info-grid">
<el-avatar size="large" src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png"/> <el-avatar shape="square" size="large" :src="useAppStoreInstance.userInfo.avatar?useAppStoreInstance.userInfo.avatar: useAppStoreInstance.showavatarUrl"/>
<div class="info-item"> <div class="info-item">
<span>张明</span> <span>{{useAppStoreInstance.userInfo.name}}</span>
<span>高级产品经理</span> <span>{{useAppStoreInstance.position[useAppStoreInstance.userInfo.role]}}</span>
</div> </div>
</div> </div>
</div> </div>
...@@ -42,11 +42,25 @@ ...@@ -42,11 +42,25 @@
</template> </template>
<script setup> <script setup>
import { reactive, computed } from 'vue'; import { reactive, computed, onMounted, watch } from 'vue';
import { ChatDotSquare } from '@element-plus/icons-vue'; import { ChatDotSquare } from '@element-plus/icons-vue';
import currentFire from '../components/currentFire.vue'; import currentFire from '../components/currentFire.vue';
import uav from '../components/uav.vue'; import uav from '../components/uav.vue';
import meanList from '../components/menuList.vue'; import meanList from '../components/menuList.vue';
import useAppStore from '../../../store/module/app';
import { useRouter,useRoute } from 'vue-router';
const useAppStoreInstance = useAppStore();
const curruserInfo = computed(() => (useAppStoreInstance.userInfo));
const router = useRouter();
const route = useRoute();
// const initUserInfoFn = () => {
// return JSON.parse(curruserInfo).avatarUrl = JSON.parse(curruserInfo).avatarUrl?JSON.parse(curruserInfo).avatarUrl:"https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png";
// }
// console.log(curruserInfo.value,'89898989898989',);
// 定义一个ref变量,用于存储当前的火灾数据 // 定义一个ref变量,用于存储当前的火灾数据
const currentFireData = ref([ const currentFireData = ref([
// 火灾数据1 // 火灾数据1
...@@ -119,13 +133,13 @@ const uavRepairData = ref([ ...@@ -119,13 +133,13 @@ const uavRepairData = ref([
const menuItems = ref([ const menuItems = ref([
{ name: '首页', icon: new URL('../../../static/image/huo.png', import.meta.url), path: '/' }, { name: '首页', icon: new URL('../../../static/image/huo.png', import.meta.url), path: '/analysisPage' },
{ name: '系统管理', icon: new URL('../../../static/image/huo.png', import.meta.url), path: '/system' }, { name: '系统管理', icon: new URL('../../../static/image/huo.png', import.meta.url), path: '/usermanage' },
{ name: '建筑管理', icon: new URL('../../../static/image/huo.png', import.meta.url), path: '/buildings' }, { name: '建筑管理', icon: new URL('../../../static/image/huo.png', import.meta.url), path: '/areabuildmanage' },
{ name: '无人机管理', icon: new URL('../../../static/image/huo.png', import.meta.url), path: '/drones' }, { name: '无人机管理', icon: new URL('../../../static/image/huo.png', import.meta.url), path: '/uavdispatch' },
{ name: '火情管理', icon: new URL('../../../static/image/huo.png', import.meta.url), path: '/fires' }, { name: '火情管理', icon: new URL('../../../static/image/huo.png', import.meta.url), path: '/firesurveillance' },
{ name: '数字孪生管理', icon: new URL('../../../static/image/huo.png', import.meta.url), path: '/digital-twin' }, { name: '数字孪生管理', icon: new URL('../../../static/image/huo.png', import.meta.url), path: '/digital-twin' },
{ name: '个人信息', icon: new URL('../../../static/image/huo.png', import.meta.url), path: '/profile' } { name: '个人信息', icon: new URL('../../../static/image/huo.png', import.meta.url), path: '/usermanage' }
]); ]);
// 响应式配置 // 响应式配置
const layoutConfig = reactive({ const layoutConfig = reactive({
...@@ -140,6 +154,18 @@ const containerStyle = computed(() => ({ ...@@ -140,6 +154,18 @@ const containerStyle = computed(() => ({
minHeight: layoutConfig.containerMinHeight, minHeight: layoutConfig.containerMinHeight,
'--card-spacing': layoutConfig.cardSpacing, '--card-spacing': layoutConfig.cardSpacing,
})); }));
onMounted(() => {
nextTick (()=>{
useAppStoreInstance.initavatarUrlFn()
})
});
// 监听路由变化
watch(route, () => {
useAppStoreInstance.initavatarUrlFn()
}, { immediate: true });
</script> </script>
<style scoped> <style scoped>
......
差异被折叠。
差异被折叠。
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论