提交 1e443c8e authored 作者: zhuyongshuai's avatar zhuyongshuai

灭火2025/8/21

上级 80a23c4d
//建筑管理
import qs from 'qs'
import request from '@/utils/request'
import { he } from 'element-plus/es/locales.mjs'
/**
* 建筑添加接口
......@@ -70,3 +71,48 @@ export function buildingUpdateApi(data) {
data,
})
}
export function buildingGetBuildCodeListApi(data) {
return request({
url: '/build/getBuildCodeList',
method: 'post',
data,
headers: { // 请求头
'Content-Type': 'multipart/form-data'
}
})
}
export function buildingGetBuildListByBuildNameApi(data) {
return request({
url: '/build/getBuildListByBuildName',
method: 'post',
data,
headers: { // 请求头
'Content-Type': 'multipart/form-data'
}
})
}
export function buildingGetBuildNameListApi(data) {
return request({
url: '/build/getBuildNameList',
method: 'post',
data,
headers: { // 请求头
'Content-Type': 'multipart/form-data'
}
})
}
export function buildingGetTotalFloorNumListApi(data) {
return request({
url: '/build/getTotalFloorNumList',
method: 'post',
data,
headers: { // 请求头
'Content-Type': 'multipart/form-data'
}
})
}
\ No newline at end of file
......@@ -14,7 +14,7 @@ export function floorGetDownFloorSortAPI(data) {
return request({
url: '/build/floor/getDownFloorSort',
method: 'GET',
data,
params:data,
})
}
export function floorGetInfoAPI(data) {
......@@ -26,10 +26,12 @@ export function floorGetInfoAPI(data) {
}
export function floorGetUpFloorSortAPI(data) {
return request({
url: '/build/floor/getUpFloorSort',
method: 'GET',
data,
method: 'get',
params:data,
// query:data,
})
}
......@@ -59,3 +61,18 @@ export function floorUpdateAPI(data) {
data,
})
}
export function floorGetFloorNoListAPI(data) {
return request({
url: '/build/floor/getFloorNoList',
method: 'POST',
data,
headers: { // 请求头
'Content-Type': 'multipart/form-data'
}
})
}
......@@ -150,11 +150,12 @@ const menuList = ref([
{
name: '火情管理',
id: 'fire',
path: '/firesurveillance',
path: '/fireSurveillance',
icon: new URL('../static/image/huo.png', import.meta.url).href,
children: [
{ name: '当前火情', id: 'fireHistory', path: '/historyfire' },
{ name: '上报记录', id: 'fireRecord', path: '/recordfireinfo' },
{ name: '历史火情', id: 'fireMonitor', path: '/firesurveillance' },
]
},
......
......@@ -170,6 +170,13 @@ export const constantRoutes = [
meta: { title: '无人机管理', icon: 'dashboard', affix: true }
},
{
path: '/recordfireinfo',
component: () => import('../views/areafiremanage/firerecord/index.vue'),
name: 'recordFireInfo',
meta: { title: '火情记录管理', icon: 'dashboard', affix: true }
},
]
},
......
......@@ -20,7 +20,12 @@ const useAppStore = defineStore(
10:'超级管理员',
1:'巡检人员',
0:"管理员"
}
},
PUSHPARAMETER:{},
pageCountInfo:{
currentPageNum: 1,
currentPageSize: 10,
},
}),
actions: {
toggleSideBar(withoutAnimation) {
......@@ -70,12 +75,39 @@ const useAppStore = defineStore(
},
chackCurPersionOpition() {
try {
// console.log(this.userInfo,'********************************************');
// console.log(this.userInfo,this.userInfo.status,localStorage.getItem('user'),'****************************************************************************************');
if (this.userInfo.status===undefined) {
this.userInfo = JSON.parse(localStorage.getItem('user'))
}
return this.userInfo.status === 0 ? true : false;
} catch (error) {
ElMessage.error('this.userInfo.state is not valid');
}
},
setPushParameter(data){
console.log('setPushParameter',data)
if(data){
this.PUSHPARAMETER = data
}else{
ElMessage.error('setPushParameter data is not valid');
}
},
setPageCountInfoCurrentPageNumData (data) {
if(data){
this.pageCountInfo.currentPageNum = data
}else{
ElMessage.error('currentPageNum data is not valid');
}
},
setPageCountInfoCurrentPageSizeData (data) {
if(data){
this.pageCountInfo.CurrentPageSize = data
}else{
ElMessage.error('CurrentPageSize data is not valid');
}
}
}
})
......
......@@ -2,7 +2,7 @@
<div class="add-building-modal">
<!-- 标题栏 -->
<div class="modal-header">
<h2 class="title">新增建筑</h2>
<h2 class="title">{{form.isEdit ?"修改建筑信息": "新增建筑信息" }} </h2>
<el-icon class="close-icon" @click="handleClose" size="20">
<Close />
</el-icon>
......@@ -18,24 +18,18 @@
class="add-building-form"
status-icon
>
<!-- 建筑编号 -->
<el-form-item label="楼层类型" prop="buildingStye" class="form-item">
<el-radio-group v-model="form.buildingStye">
<el-radio-group :disabled="form.isEdit" v-model="form.floorSort" @change="changeBuildinGradioGroup" class="radio-group">
<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 label="楼层号" prop="floorNo" class="form-item">
<el-input v-model="form.floorNo" placeholder="楼层号" disabled style="width: 240px"></el-input>
</el-form-item>
<!-- 建筑层数 -->
......@@ -46,9 +40,9 @@
<!-- 是否有地下室 -->
<el-form-item label="航线绑定" prop="pathBinding" class="form-item">
<el-select v-model="form.pathBinding" placeholder="选择可绑定的航线" style="width: 240px">
<el-select v-model="form.airline" placeholder="选择可绑定的航线" style="width: 240px">
<el-option
v-for="item in form.pathBinding"
v-for="item in form.airline"
:key="item.value"
:label="item.label"
:value="item.value"
......@@ -86,30 +80,66 @@
</template>
<script setup>
import { ref, reactive } from 'vue';
import { ref, reactive, onMounted, watch } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import { Close } from '@element-plus/icons-vue';
import UpdataImg from '../../systemmanage/components/updataImg.vue';
import { floorGetUpFloorSortAPI,floorGetDownFloorSortAPI,floorAddInfoAPI,floorUpdateAPI } from '@/api/floor.js';
import { message } from 'ant-design-vue';
import { useRoute,useRouter } from 'vue-router';
import useAppStore from '../../../store/module/app';
const useAppStoreInstance = useAppStore();
const route = useRoute();
const props = defineProps(['rowData','isBuildingEditDrawer']);
const emit = defineEmits(['closeAddDrawer','tableDataRefresh']);
// 表单引用
const addBuildingFormRef = ref(null);
// 提交加载状态
const submitting = ref(false);
const emit = defineEmits(['closeAddDrawer']);
// 表单数据
const form = reactive({
buildingStye:'',
floorSort: '',
// 楼层编号初始的时候要获取,数据类型 buildingNo:{label: '1层', value: '1'}
buildingNo:'',
floorNo:'',
// 航线编号初始的时候要获取,数据类型floorPlan:{label: '航线1', value: '1'}
floorPlan:'',
pathBinding:'',
airline:'',
description:'',
description: "",
isEdit:false,
floorId:'',
});
const changeBuildinGradioGroup = () => {
console.log("改变了值", form.floorSort,useAppStoreInstance.PUSHPARAMETER);
try {
if (form.floorSort === 1) {
// 获取楼层编号
floorGetUpFloorSortAPI({buildId:useAppStoreInstance.PUSHPARAMETER.buildId}).then((res) => {
console.log("获取楼层编号", res);
form.floorNo = res.data+'层';
})
} else if (form.floorSort === 0) {
floorGetDownFloorSortAPI({buildId:useAppStoreInstance.PUSHPARAMETER.buildId}).then((res) => {
console.log("获取dixa楼层编号", res);
form.floorNo = extractAndFormatNumber(''+ res.data)+'层';
})
} else {
message.error('参数传递失败',form.floorSort)
}
} catch (error) {
console.log("自动获取新增序号失败", error);
}
// form.buildingStye = val;
};
const getfloorPlan = (url) => {
console.log(url,"const url = URL.createObjectURL(url);");
......@@ -122,27 +152,113 @@ const rules = reactive({
});
function getFloorNumberFromDisplay(floorStr) {
console.log(floorStr,"floorStr");
// 如果是B1、B2等地下室楼层,转换为负数
if (floorStr.startsWith('B')) {
const floorNumber = parseInt(floorStr.substring(1));
return 'B'+floorNumber;
}
// 如果是普通楼层(如1、2、13等),直接转换为数字
else {
return parseInt(floorStr);
}
}
function extractAndFormatNumber(str) {
// 使用正则表达式匹配数字(包括负号)
const match = str.match(/-?\d+/);
// console.log(parseInt( match[0]), "match");
if (parseInt( match[0])<0) {
if (match) {
// 获取匹配到的数字(包括负号)
const number = match[0];
// 去掉负号,加上"B"前缀
return "B" + Math.abs(parseInt(number));
}
// 如果没有匹配到数字,返回默认值
return "B0";
}else{
console.log( "match大于0");
return parseInt( match[0])
}
}
function convertFloorToNumber(floorStr) {
// 检查 floorStr 是否为 null 或 undefined
if (floorStr == null) {
console.warn("convertFloorToNumber: floorStr is null or undefined");
return 0; // 或者返回其他默认值
}
// 确保 floorStr 是字符串类型
floorStr = String(floorStr).trim();
// 如果是 B1、B2 等地下室楼层,转换为负数
if (floorStr.startsWith('B')) {
const floorNumber = parseInt(floorStr.substring(1)) || 0;
return -floorNumber;
}
// 如果是普通楼层(如 1、2、13 等),直接转换为数字
else {
return parseInt(floorStr) || 0;
}
}
// 提交表单
const handleSubmit = async () => {
const handleSubmit = () => {
try {
submitting.value = true;
const {airline,description,floorNo,floorPlan,floorId} = form;
console.log("提交参数",airline,description,floorNo,floorPlan);
// 准备提交数据
await addBuildingFormRef.value.validate();
// 准备提交数据
if (!form.isEdit) {
const submitData = {
...form,
airline,description,floorNo:getFloorNumberFromDisplay(floorNo),floorPlan,
floorSort:convertFloorToNumber(floorNo),
buildId:useAppStoreInstance.PUSHPARAMETER.buildId
};
console.log('提交新增建筑数据:', submitData);
await new Promise(resolve => setTimeout(resolve, 1000));
ElMessage.success('建筑信息新增成功!');
floorAddInfoAPI(submitData).then(res => {
console.log('新增建筑数据返回结果:', res);
if (res.code === 200) {
// ElMessage.success('建筑信息新增成功!');
emit('tableDataRefresh');
emit('closeAddDrawer');
addBuildingFormRef.value.resetFields();
floorUpdateloader.value.handleRemove()
}
}).catch(err => {
ElMessage.error('添加建筑错误',err);
});
}else {
console.log(emit, 'props.rowData');
const submitData = {
airline,description,floorNo:getFloorNumberFromDisplay(floorNo),floorPlan,
floorId
};
console.log('修改提交建筑数据:', submitData);
floorUpdateAPI(submitData).then(res => {
console.log('新增建筑数据返回结果:', res);
if (res.code === 200) {
ElMessage.success('建筑信息修改成功!');
emit('tableDataRefresh');
emit('closeAddDrawer');
addBuildingFormRef.value.resetFields();
floorUpdateloader.value.handleRemove()
}
}).catch(err => {
ElMessage.error('修改建筑错误',err);
});
}
} catch (error) {
console.error('表单验证失败:', error);
ElMessage.error('请完善表单信息后重试');
ElMessage.error('请完善表单信息后重试',error);
} finally {
submitting.value = false;
}
......@@ -161,8 +277,8 @@ const handleCancel = () => {
floorUpdateloader.value.handleRemove()
emit('closeAddDrawer');
}).catch(() => {
console.log('报错了');
}).catch((err) => {
console.log('报错了12',err);
});
};
......@@ -171,6 +287,30 @@ const handleClose = () => {
addBuildingFormRef.value.resetFields();
handleCancel();
};
const initFormData = () => {
console.log("初始化表单数据",props.rowData);
if (props.rowData) {
form.floorSort = props.rowData.floorSort>0 ?1: 0; // 如果 rowData.floorSort 是 null/undefined,则使用默认值 0
form.floorNo = props.rowData.floorNo ?? '';
form.floorPlan = props.rowData.floorPlan === null ? ' ' : props.rowData.floorPlan ?? '';
form.airline = props.rowData.airline ?? '';
form.description = props.rowData.description === null ? ' 暂无描述 ' : props.rowData.description ?? '';
form.isEdit = props.rowData.isEdit ?? false;
form.floorId = props.rowData.floorId ;
console.log('准备提交数据:',form);
}
};
// 监听变化
watch(() => props.isBuildingEditDrawer, (newVal, oldVal) => {
console.log('抽屉已打开,监听变化');
initFormData()
}, { immediate: true });
</script>
<style scoped lang="scss">
......
......@@ -194,9 +194,9 @@ const buildingInfo = reactive({
floor: ''
});
const searchShowData = ref([
{ label: '楼栋编号', placeholder: "请输入", type: 'input',content:'' },
{ label: '楼栋名称', placeholder: "请输入", type: 'input',content:'' },
{ label: '对应楼层', placeholder: "请输入", type: 'input',content:'' },
{ label: '楼栋编号', placeholder: "请输入", type: 'input',content:'' ,isShow: false},
{ label: '楼栋名称', placeholder: "请输入", type: 'input',content:'' ,isShow: false},
{ label: '对应楼层', placeholder: "请输入", type: 'input',content:'' ,isShow: false},
])
// 楼层平面图
......
......@@ -7,14 +7,14 @@
<div class="left-top">
<!-- 区域信息概览 -->
<div class="info-card region-overview">
<searchtop :searchShowData="searchShowData"></searchtop>
<searchtop :searchShowData="searchShowData" @commentGetList="getFloorGetFloorNoListFn"></searchtop>
</div>
</div>
<!-- 左侧下部分:统计区域 -->
<div class="info-card stats-alerts">
<div class="card-tabs">
<span class="title">建筑列表</span>
<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>
......@@ -24,7 +24,7 @@
</div>
</div>
<div class="card-table">
<tabledata :tableShowData="tableShowData"></tabledata>
<tabledata :tableShowData="tableShowData" @getPageCommonAPI="initTableDateFn"></tabledata>
</div>
</div>
</div>
......@@ -36,9 +36,9 @@
</el-drawer>
<!-- 修改建筑抽屉 -->
<el-drawer v-model="isBuildingEditDrawer" title="修改用户信息" :with-header="false" :before-close="beforeCloseAddBuildDrawer">
<el-drawer v-model="isBuildingEditDrawer" title="修改建筑信息" :with-header="false" :before-close="beforeCloseAddBuildDrawer">
<Flooraddbuilding :rowData="rowData" :isBuildingEditDrawer="isBuildingEditDrawer" @closeEditDrawer="closeBuildingEditDrawer" @tableDataRefresh="handleRefreshInfoFn"></Flooraddbuilding>
<Flooraddbuilding :rowData="rowData" :isBuildingEditDrawer="isBuildingEditDrawer" @closeAddDrawer="closeBuildingEditDrawer" @tableDataRefresh="handleRefreshInfoFn"></Flooraddbuilding>
</el-drawer>
<!-- 图片预览组件 -->
......@@ -53,25 +53,32 @@
</template>
<script setup>
import { reactive, computed, ref } from 'vue';
import { reactive, computed, ref, watch } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import searchtop from '../../commentcomponents/searchtop/index.vue';
import tabledata from '../../commentcomponents/tabledata/index.vue';
import useAppStore from '../../../store/module/app';
import router from '../../../router';
import Flooraddbuilding from './flooraddbuilding.vue';
import { useRoute,useRouter } from 'vue-router';
import { floorPageAPI,floorRemoveAPI,floorGetFloorNoListAPI} from '../../../api/floor';
const route = useRoute();
const useAppStoreInstance = useAppStore();
// 搜索栏配置
const searchShowData = ref([
{ label: '楼层描述', placeholder: "请输入", type: 'input', content: '' },
{ label: '楼层号', placeholder: "请选择", type: 'select', content: '', options: [
{label:'火灾', value:'烟雾'},
{label:'烟雾', value:'火灾'}
] },
{ label: '楼层描述', placeholder: "请输入", type: 'input', content: '',isShow: true },
{ label: '楼层号', placeholder: "请选择", type: 'autocomplete',click:"floorGetFloorNoListFn", content: '', options: [] ,isShow: true}
]);
const getFloorGetFloorNoListFn = () => {
floorGetFloorNoListAPI().then(res => {
});
};
// 布局配置
const layoutConfig = reactive({
containerMinHeight: '100vh',
......@@ -94,6 +101,7 @@ const handleAddInfoFn = () => {
const handleRefreshInfoFn = () => {
console.log("刷新数据");
initTableDateFn({currentPageNum:useAppStoreInstance.pageCountInfo.currentPageNum,currentPageSize:useAppStoreInstance.pageCountInfo.currentPageSize})
}
const closeAddDrawer = () => {
console.log("000000-------1-----0000000000",isAddDrawer.value)
......@@ -121,23 +129,28 @@ const oneBuildingDdeleteData = (data) => {
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
handleRefreshInfoFn()
console.log("删除", data.floorId,useAppStoreInstance.pageCountInfo.currentPageNum);
floorRemoveAPI({floorId:data.floorId}).then(res => {
console.log("删除成功", res);
})
initTableDateFn({currentPageNum:useAppStoreInstance.pageCountInfo.currentPageNum,currentPageSize:useAppStoreInstance.pageCountInfo.currentPageSize})
ElMessage.success('已删除');
}).catch(() => {
ElMessage.info('取消删除');
}).catch((err) => {
ElMessage.info('取消删除',err);
});
}
const oneResetBuildingShowInfo = (data) => {
console.log("000000----我执行了oneResetBuildingShowInfo",data)
isBuildingEditDrawer.value = true;
rowData.value = data;
rowData.value.isEdit = true;
}
const closeBuildingEditDrawer = () => {
isBuildingEditDrawer.value = false;
console.log("000000------------0000000000")
console.log("000000----我执行了closeBuildingEditDrawer--------0000000000")
}
// 图片预览状态
const previewVisible = ref(false);
......@@ -146,11 +159,11 @@ 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',]
if(data.floorPlan) {
previewVisibledialogDate.value = [data.floorPlan]
return;
}else {
previewVisibledialogDate.value = []
ElMessage.warning({
message: '该层暂无楼层平面图',
duration: 2000
......@@ -162,53 +175,55 @@ const seeBuildingFloorPlan = (data) => {
// 表格数据
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},
{label: '建筑编号', prop: 'buildCode'},
{label: '建筑名称', prop: 'buildName'},
{label: '建筑层数', prop: 'floorNo'},
{label: '楼层平面图', prop: 'floorPlanSee'},
{label: '更新时间', prop: 'updateTime'},
{label: '楼层描述', prop: 'description'},
{label: '操作', prop: 'Operation'}
],
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}
]},
]
tableBody: []
}]);
// 计算属性
const containerStyle = computed(() => ({
minHeight: layoutConfig.containerMinHeight,
'--card-spacing': layoutConfig.cardSpacing,
}));
const Operation = ref([
{label:'查看详情', type:'primary', icon:'Add', click: oneBuildingSeeDetails},
{label:'删除', type:'danger', icon:'Delete', click: oneBuildingDdeleteData},
{label:'修改', type:'primary', icon:'EditPen', click: oneResetBuildingShowInfo}
]);
const floorPlanSee = ref([ {label:'查看', type:'primary', icon:'EditPen', click: seeBuildingFloorPlan}, ]);
const initTableDateFn = (parameter) => {
let submitData = {currentPageNum: parameter.currentPageNum, currentPageSize: parameter.currentPageSize,...useAppStoreInstance.PUSHPARAMETER};
floorPageAPI(submitData).then(res => {
console.log('获取建筑列表数据返回结果:', res);
if (res.code === 200) {
tableShowData.value[0].tableBody = []
let { list, total } = res.data;
list = list.filter(element => {
return element.isDeleted === 0;
});
list.forEach(element => {
element.Operation = [...Operation.value]
element.floorPlanSee =[...floorPlanSee.value]
});
tableShowData.value[0].tableBody = list
tableShowData.value[0].total = total
console.log(tableShowData.value, '展示数据');
}
})
}
// 监听路由变化
watch(route, () => {
initTableDateFn({currentPageNum: 1, currentPageSize: 10})
console.log('新增组件已挂载',useAppStoreInstance.setParameter)
}, { immediate: true });
</script>
<style scoped>
......
......@@ -51,22 +51,21 @@ import tabledata from '../commentcomponents/tabledata/index.vue';
import showResetBuildingInfo from './components/showResetBuildingInfo.vue';
import Addbuild from './components/addbuild.vue';
import router from '../../router';
import { buildingPageApi,buildingRemoveApi } from '../../api/build';
import { buildingPageApi,buildingRemoveApi,buildingGetBuildCodeListApi } from '../../api/build';
import { useRoute,useRouter } from 'vue-router';
import useAppStore from '../../store/module/app';
const useAppStoreInstance = useAppStore();
const route = useRoute();
// 搜索栏配置
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:'火灾1', value:'烟雾1'},
{label:'烟雾1', value:'火灾1'}
] },
{ label: '功能描述', placeholder: "请输入", type: 'input', content: '',isShow: true },
{ label: '建筑编号', placeholder: "请选择", type: 'autocomplete', content: '',isShow: true, click:'buildingGetBuildCodeListApiFn', options: [] },
{ label: '建筑层数', placeholder: "请选择", type: 'autocomplete', content: '',isShow: true, click:'buildingGetTotalFloorNumListFn', options: [] },
{ label: '建筑名称', placeholder: "请选择", type: 'autocomplete', content: '',isShow: true, click:'buildingGetBuildNameListFn', options: [] },
]);
// 布局配置
const layoutConfig = reactive({
containerMinHeight: '100vh',
......@@ -103,8 +102,9 @@ const buildingSeeDetails = (data) => {
console.log("查看详情", data);
router.push({
path: '/buildingdetaildate',
params: { data: JSON.stringify(data) },
});
useAppStoreInstance.setPushParameter({buildId:data.buildId})
}
const buildingDdeleteData = (data) => {
......
......@@ -33,9 +33,9 @@ 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:'巡查员'}]},
{ label: '用户姓名', placeholder: "请输入", type: 'input',content:'' ,isShow: false },
{ label: '用户状态', placeholder: "请选择", type: 'select',content:'' ,isShow: false, options: [{label:'启用', value:'启用'}, {label:'禁用', value:'禁用'}] },
{ label: '用户角色', placeholder: "请选择", type: 'select', content:'' ,isShow: false,options: [{label:'管理员', value:'管理员'}, {label:'巡查员', value:'巡查员'}]},
])
// 响应式布局配置
const layoutConfig = reactive({
......
<template>
<div>
<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"
style="width: 100%"
@select="selectTableDateFn"
@select-all="selectTableDateFn" >
<el-table-column type="selection" width="55" />
<el-table-column label="火情编号" width="120">
<template #default="scope">{{ scope.row.id}}</template>
</el-table-column>
<el-table-column prop="name" label="建筑名称" width="120" />
<el-table-column prop="floorcount" label="火情楼层" width="120" />
<el-table-column prop="reporter" label="上报人" width="120" />
<el-table-column prop="updateTime" 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
label="详情查看"
show-overflow-tooltip
>
<template #default="scope">
<el-button @click="handleClick(scope.row)">图片查看</el-button>
<el-button @click="handleVideoDialogFn(scope.row)">视频查看</el-button>
</template>
</el-table-column>
<el-table-column
label="操作"
show-overflow-tooltip
>
<template #default="scope">
<el-button @click="taskSchedulingFn(scope.row)">任务调度</el-button>
</template>
</el-table-column>
</el-table> -->
<!-- 分页区域(固定在右下角) -->
<div class="card-tabs-footer" >
<div class="pagination-block">
<span class="page-text">每页显示</span>
<el-pagination
v-model:current-page="currentPage2"
v-model:page-size="pageSize2"
:page-sizes="[10, 50, 100]"
size="small"
background
layout="sizes, prev, pager, next"
:total="tableShowData.length"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</div>
<div v-if="showPreview">
<el-image-viewer
:url-list="srcList"
show-progress
ref="imageRef"
style="width: 100px; height: 100px"
fit="cover"
@close="showPreview = false"
/>
</div>
<el-dialog
v-model="isVideoDialogVisible"
width="800"
:before-close="handleClose"
>
<template #header>
<span>视频文件 <span style="margin-left: 1rem; color: chartreuse;">{{ videoSrcList.length }}</span></span>
</template>
<div class="video-container">
<div
v-for="(src, index) in videoSrcList"
:key="index"
class="video-wrapper"
>
<div class="video-title">视频 {{ index + 1 }}</div>
<video
:src="src"
controls
class="video-player"
></video>
</div>
</div>
</el-dialog>
<el-dialog
v-model="isTaskSchedulingDialogVisible"
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>
<!-- 底部按钮 -->
<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>
<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 props = defineProps({
tableShowData: {
type: Array,
default: () => []
},
})
const imageRef = ref(null)
const showPreview = ref(false)
const handleClick = (info) => {
showPreview.value = true
console.log("图片查看handleClick",info)
}
const srcList = ref([
'https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg',
'https://fuss10.elemecdn.com/1/34/19aa98b1fcb2781c4fba33d850549jpeg.jpeg',
'https://fuss10.elemecdn.com/0/6f/e35ff375812e6b0020b6b4e8f9583jpeg.jpeg',
'https://fuss10.elemecdn.com/9/bb/e27858e973f5d7d3904835f46abbdjpeg.jpeg',
'https://fuss10.elemecdn.com/d/e6/c4d93a3805b3ce3f323f7974e6f78jpeg.jpeg',
'https://fuss10.elemecdn.com/3/28/bbf893f792f03a54408b3b7a7ebf0jpeg.jpeg',
'https://fuss10.elemecdn.com/2/11/6535bcfb26e4c79b48ddde44f4b6fjpeg.jpeg',
])
// const srcList = ref([
// 'https://www.w3schools.com/html/mov_bbb.mp4',
// ])
const videoSrcList = ref([ 'https://www.w3schools.com/html/mov_bbb.mp4',
'https://www.w3schools.com/html/mov_bbb.mp4',
'https://www.w3schools.com/html/mov_bbb.mp4',
'https://www.w3schools.com/html/mov_bbb.mp4',]
)
const isVideoDialogVisible = ref(false)
const handleVideoDialogFn = (info) => {
isVideoDialogVisible.value = true
console.log("图片查看handleClick",info)
}
const isTaskSchedulingDialogVisible = ref(false)
const taskSchedulingFn = (info) => {
console.log("任务调度",info)
isTaskSchedulingDialogVisible.value = true
}
const tableRef = ref() // 确保这里声明了 tableRef
const selectTableDateFn = () => {
const $table = tableRef.value
if ($table) {
emit('archiveInfoDateBackcallFn',$table.getCheckboxRecords())
}else{
console.log('未找到表格实例')
message.error('未找到表格实例')
}
// console.log('selectTableDateFn选择的数据信息',tableRef.value)
// emit('archiveInfoDateBackcallFn',selectedRows)
}
// 分页数据
const currentPage2 = ref(1)
const pageSize2 = ref(10)
// 分页事件处理
const handleSizeChange = (val) => {
console.log(`每页 ${val} 条`);
// getNewTableData()//
};
const handleCurrentChange = (val) => {
console.log(`当前页 ${val} 条`);
// getNewTableData()
};
// const getNewTableData = () => {
// staffGetPageInfoApi({
// "currentPageNum": currentPage2.value,
// "currentPageSize": pageSize2.value,
// }).then(res => {
// if(res.code === 200){
// let tempData = res.data.list
// // console.log(props.Operation,"--11111111111111111111111---*****---999555555555555999999----")
// curTableShowData.value[0].tableBody = []
// //获取未逻辑删除的数据
// tempData = tempData.filter(element => {
// return element.isDeleted === 0;
// });
// tempData.forEach(element => {
// element.Operation = [...props.Operation]
// });
// curTableShowData.value[0].tableBody = tempData
// curTableShowData.value[0].total = res.data.total
// curTableShowData.value[0].pageSize = res.data.pageSize
// console.log(curTableShowData.value, '展示数据');
// }
// }).catch(err => {
// message.error(err.message)
// })
// };
</script>
<style scoped>
/* 分页区域固定在右下角 */
.card-tabs-footer {
position: absolute;
bottom: 0;
right: 0;
padding: 15px;
width: auto; /* 自适应宽度 */
}
/* 分页内部 Flex 布局 */
.pagination-block {
display: flex; /* 核心:启用 Flex 布局 */
align-items: center; /* 垂直居中对齐 */
gap: 12px; /* 文本与分页间距 */
}
/* 文本样式 */
.page-text {
color: #606266;
font-size: 14px;
white-space: nowrap; /* 防止文本换行 */
}
/* 穿透修改 Element Plus 分页样式 */
:deep(.el-pagination) {
display: flex; /* 确保分页组件水平排列 */
align-items: center;
margin: 0; /* 清除默认外边距 */
}
/* 表格行样式(全局样式需放在 scoped 外或使用 ::v-deep) */
:deep(.el-table .warning-row) {
--el-table-tr-bg-color: var(--el-color-warning-light-9);
}
:deep(.el-table .success-row) {
--el-table-tr-bg-color: var(--el-color-success-light-9);
}
.video-container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 1rem;
max-height: 70vh;
overflow-y: auto;
}
.video-wrapper {
border: 1px solid #eee;
border-radius: 4px;
padding: 0.5rem;
background: #f9f9f9;
}
.video-title {
font-weight: bold;
margin-bottom: 0.5rem;
color: #666;
}
.video-player {
width: 100%;
border-radius: 4px;
aspect-ratio: 16/9;
background: #000;
}
.dialog-header {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
}
.dialog-title {
font-size: 18px;
font-weight: 600;
color: #303133;
}
.status-indicator {
display: flex;
align-items: center;
color: #67c23a;
font-size: 14px;
}
.status-icon {
margin-right: 6px;
font-size: 16px;
}
.dialog-content {
padding: 0 20px;
height: 300px;
}
.notification-box {
display: flex;
align-items: center;
padding: 15px;
background-color: #f0f7ff;
border-radius: 4px;
margin-bottom: 20px;
}
.notification-icon {
color: #409eff;
font-size: 18px;
margin-right: 10px;
}
.notification-text {
color: #606266;
font-size: 15px;
}
.progress-section {
margin-bottom: 25px;
}
.progress-header {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
color: #606266;
font-size: 14px;
}
.progress-percent {
color: #409eff;
font-weight: 500;
}
.drone-info {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
.info-tag {
padding: 8px 12px;
font-size: 13px;
}
.dialog-footer {
width: 100%;
flex: 1;
display: flex;
justify-content: flex-end;
gap: 12px;
}
.action-button {
padding: 10px 16px;
flex: 0.21;
}
.cancel-button {
padding: 10px 16px;
color: #f56c6c;
border-color: #f56c6c;
}
.cancel-button:hover {
background-color: #fef0f0;
color: #f56c6c;
}
</style>
\ No newline at end of file
<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>
<el-button type="primary" @click="archiveHandleAddInfoFn">归档</el-button>
</div>
<div class="card-table">
<tableshow :tableShowData="tableShowData" @archiveInfoDateBackcallFn="archiveInfoDateBackcallFn"></tableshow>
</div>
</div>
</div>
</main>
<!-- 归档区域 -->
</div>
</template>
<script setup>
import { reactive, computed, ref, onMounted } from 'vue';
import searchtop from '../../commentcomponents/searchtop/index.vue';
// import tabledata from '../../commentcomponents/tabledata/index.vue';
import { ElMessage, ElMessageBox } from 'element-plus'
import { staffGetPageInfoApi } from "../../../api/staff.js";
import tableshow from './components/tableshow.vue';
const searchShowData = ref([
{ label: '火情描述', placeholder: "请输入", type: 'input', content: '',isShow: true },
{ label: '上报人', placeholder: "请输入", type: 'input', content: '' ,isShow: true},
{ label: '上报时间', placeholder: "请输入", type: 'datepicker', content: '',isShow: true },
{ label: '建筑名称', placeholder: "请选择", type: 'select', content: '',isShow: true, options: [{label: '启用', value: '启用'}, {label: '禁用', value: '禁用'}] },
{ label: '建筑楼层', placeholder: "请选择", type: 'select', content: '',isShow: true, options: [{label: '管理员', value: '管理员'}, {label: '巡查员', value: '巡查员'}]},
{ label: '火情等级', placeholder: "请选择", type: 'select', content: '',isShow: true, options: [{label: '一级火情', value: '1'}, {label: '二级火情', value: '2'}, {label: '三级火情', value: '3'}]},
]);
const layoutConfig = reactive({
containerMinHeight: '100vh',
cardSpacing: '1rem',
statsMinHeight: '300px'
});
const isAddDrawer = ref(false);
const isEditDrawer = ref(false);
const isUserInfoDialogVisible = ref(false);
const isResetPasswordDialogVisible = ref(false);
const rowData = ref([]);
const resetPasswordData = ref({});
const showuserinfodata = ref({});
const tableShowData = ref([
{id: 1, name: '背景', floorcount: 18, reporter: '张三', updateTime: '12345678901', discription: '打个人脸',fireLevel: '1'},
{id: 2, name: '背景', floorcount: 18, reporter: '张三', updateTime: '12345678901', discription: '说实在的',fireLevel: '1'},
{id: 3, name: '背景', floorcount: 18, reporter: '张三', updateTime: '12345678901', discription: '打个人脸',fireLevel: '1'},
{id: 4, name: '背景', floorcount: 18, reporter: '张三', updateTime: '12345678901', discription: '说实在的',fireLevel: '1'},
]);
const archiveInfoDateBackcallFn = (row) => {
console.log("archiveInfoFn需要归档的数据",row)
};
const archiveHandleAddInfoFn = (row) => {
// archiveInfoDate.value = null
// archiveInfoDate.value = row
console.log('archiveInfoFn需要归档的数据')
};
// const archiveInfoDate = ref(null)
// const archiveInfoDateBackcallFn = (row) => {
// archiveInfoDate.value = null
// archiveInfoDate.value = row
// console.log('archiveInfoFn需要归档的数据',archiveInfoDate.value)
// };
// const archiveInfoFn = () => {
// console.log('archiveInfoFn归档的数据',archiveInfoDate.value)
// };
const handleAddInfoFn = () => {
isAddDrawer.value = true;
}
const tableDataRefresh = () => {
initTableData();
}
const editData = (data) => {
isEditDrawer.value = true;
rowData.value = data;
}
const deleteData = (data) => {
ElMessageBox.confirm(
'删除操作不可逆,是否继续?',
'删除',
{
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
draggable: true,
}
).then(() => {
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) {
ElMessage({ type: 'error', message: '删除失败(网络错误)' });
}
}).catch(() => {
ElMessage({ type: 'info', message: '取消删除' });
});
}
const resetData = (data) => {
isResetPasswordDialogVisible.value = true;
resetPasswordData.value = data;
}
const userData = (data) => {
isUserInfoDialogVisible.value = true;
showuserinfodata.value = data;
}
const initTableData = () => {
// staffGetPageInfoApi({
// "currentPageNum": 1,
// "currentPageSize": 10,
// }).then(res => {
// if(res.code === 200) {
// let tempData = res.data.list
// tableShowData.value[0].tableBody = []
// tempData = tempData.filter(element => 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;
// }
// }).catch(err => {
// ElMessage.error(err.message);
// });
}
onMounted(() => {
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;
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: 90%;
}
.card-actions {
display: flex;
flex: 1;
justify-content: space-between;
align-items: center;
/* height: %; */
padding: 1.5rem;
}
.operation-button {
flex: 1;
display: flex;
justify-self: end;
}
.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
......@@ -48,11 +48,11 @@ import tableshow from './components/tableshow.vue';
const searchShowData = ref([
{ label: '火情描述', placeholder: "请输入", type: 'input', content: '' },
{ label: '上报人', placeholder: "请输入", type: 'input', content: '' },
{ 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: '巡查员'}]},
{ label: '火情描述', placeholder: "请输入", type: 'input', content: '' ,isShow: true},
{ label: '建筑编号', placeholder: "请选择", type: 'autocomplete',cliick:'', content: '',isShow: true, options: [{label: '启用', value: '启用'}, {label: '禁用', value: '禁用'}] },
{ label: '归档编号', placeholder: "请选择", type: 'autocomplete', content: '',isShow: true, options: [{label: '管理员', value: '管理员'}, {label: '巡查员', value: '巡查员'}]},
{ label: '归档时间', placeholder: "请选择", type: 'datepicker', content: '',isShow: true, options: [{label: '管理员', value: '管理员'}, {label: '巡查员', value: '巡查员'}]},
]);
const layoutConfig = reactive({
......
<template>
<div class="dashboard-container">
<div class="situation-list">
<!-- Fire situation items -->
<div
class="situation-item"
:class="[
index === 0 ? 'emergency' : '',
`fire${item.fireLevel === 0 ? 'over' : item.fireLevel === 1 ? 'warning' : 'emergency'}`
]"
v-for="(item, index) in currentFireData"
:key="index"
@click="currentFireDetailViewsFn(item)"
>
<div class="situation-content">
<p>
<img class="icon-fire" src="../../../../static/image/huo.png" alt="fire icon">
<span class="location">{{ item.location }}</span>
</p>
<p>
<img class="icon-fire" src="../../../../static/image/huo.png" alt="fire icon">
<span class="severity">{{ item.severity }}</span>
</p>
<p>
<img class="icon-fire" src="../../../../static/image/huo.png" alt="fire icon">
<span :class="item.isXFOk ? 'isXFOk' : 'isXFNotOk'">{{ item.status }}</span>
</p>
<p>
<img class="icon-fire" src="../../../../static/image/huo.png" alt="fire icon">
<span class="time">{{ item.time }}</span>
</p>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import { useRouter } from 'vue-router';
import * as echarts from 'echarts';
const router = useRouter();
const props = defineProps(["currentFireData"])
// Fire data with proper typing
let chartInstance = null;
const initFireHistoryChart = () => {
const chartDom = document.getElementById('historyChart');
if (!chartDom) return;
if (chartInstance) chartInstance.dispose();
chartInstance = echarts.init(chartDom);
const option = {
grid: {
left: '3%',
right: '3%',
bottom: '3%',
top: '3%',
containLabel: true
},
tooltip: {
trigger: 'axis',
formatter: (params) => {
return `${params[0].axisValue}日共发生<span style="color:red">${params[0].value}</span>起火灾<br />`;
}
},
xAxis: {
type: 'category',
boundaryGap: false,
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
axisLabel: { rotate: 45 }
},
yAxis: { type: 'value' },
series: [{
data: [820, 932, 901, 934, 1290, 1330, 1320],
type: 'line',
areaStyle: {}
}]
};
chartInstance.on('click', function(params) {
router.push({
path: '/fireManage',
query: { taskId: params.name }
});
});
chartInstance.setOption(option);
const resizeHandler = () => chartInstance.resize();
window.addEventListener('resize', resizeHandler);
onUnmounted(() => {
window.removeEventListener('resize', resizeHandler);
if (chartInstance) chartInstance.dispose();
});
};
onMounted(() => {
initFireHistoryChart();
});
const currentFireDetailViewsFn = (info) => {
console.log(info,"-----------------");
};
</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;
}
.situation-list {
display: flex;
flex-direction: column;
gap: 0.5rem;
overflow-y: auto;
padding-right: 5px;
}
.situation-item {
display: flex;
/* gap: 1.5rem; */
padding: 0.9rem;
margin-bottom: 0.5rem;
border-radius: 6px;
box-shadow: #7a7a7a 0 0 0.5rem;
background-color: #f9f9f9;
border-left: 4px solid transparent;
transition: transform 0.2s ease;
}
.situation-item:hover {
transform: translateX(4px);
}
.fireover {
border-left: #10b981 4px solid;
}
.fireemergency {
border-left: #fc0000 4px solid;
}
.firewarning {
border-left: #facc15 4px solid;
}
.isXFOk {
color: #10b981;
}
.isXFNotOk {
color: #144937;
}
.emergency {
position: sticky;
top: 0;
z-index: 100;
box-shadow: 0 2px 5px rgba(0,0,0,0.5);
}
.situation-content {
width: 100%;
}
.situation-content p {
margin: 0.2rem 0;
font-size: 1rem;
color: #444;
height: 1.5rem;
display: flex;
align-items: center;
}
.icon-fire {
height: 70%;
margin-right: 0.5rem;
}
.location {
font-weight: 500;
color: #1e40af;
}
.severity {
color: #ef4444;
}
/* Custom scrollbar */
::-webkit-scrollbar {
width: 6px;
height: 6px;
}
::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 10px;
}
::-webkit-scrollbar-thumb {
background: #bbb;
border-radius: 10px;
}
::-webkit-scrollbar-thumb:hover {
background: #999;
}
@media (max-width: 768px) {
.situation-item {
padding: 0.7rem;
gap: 0.7rem;
}
.situation-content p {
font-size: 0.85rem;
}
}
</style>
\ No newline at end of file
......@@ -86,9 +86,9 @@ const fireInfoDataImportFn = () => {
// 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:'巡查员'}]},
{ label: '用户姓名', placeholder: "请输入", type: 'input',content:'' ,isShow: true},
{ label: '用户状态', placeholder: "请选择", type: 'select',content:'' ,isShow: true, options: [{label:'启用', value:'启用'}, {label:'禁用', value:'禁用'}] },
{ label: '用户角色', placeholder: "请选择", type: 'select', content:'' ,isShow: true,options: [{label:'管理员', value:'管理员'}, {label:'巡查员', value:'巡查员'}]},
])
// 响应式布局配置
const layoutConfig = reactive({
......@@ -343,7 +343,7 @@ const containerStyle = computed(() => ({
.card-tabs {
display: flex;
/* border-bottom: 1px solid #8a8787; */
justify-content: space-between;
font-size: 1.2rem;
color: #000000;
padding: 1.3rem;
......@@ -361,14 +361,15 @@ const containerStyle = computed(() => ({
padding-top: 1rem ;
}
.title{
width: 90%;
/* width: 100%; */
/* background-color: #000000; */
}
.card-actions {
display: flex;
flex: 1;
justify-content: space-between;
/* flex: 1; */
justify-content: end;
align-items: center;
background-color: aqua;
height: 8%;
padding: 1.5rem;
......
<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-tong card-show" >
<currentFire :currentFireData="currentFireData" ></currentFire>
</div>
<div class="card-table">
<tableshow :tableShowData="tableShowData" @archiveInfoDateBackcallFn="archiveInfoDateBackcallFn"></tableshow>
<div class="card-tong" >
</div>
</div>
</div>
</main>
......@@ -27,136 +23,124 @@
</template>
<script setup>
import { reactive, computed, ref, onMounted } from 'vue';
import searchtop from '../../commentcomponents/searchtop/index.vue';
// import tabledata from '../../commentcomponents/tabledata/index.vue';
import { ElMessage, ElMessageBox } from 'element-plus'
import { staffGetPageInfoApi } from "../../../api/staff.js";
import tableshow from './components/tableshow.vue';
const searchShowData = ref([
{ label: '火情描述', placeholder: "请输入", type: 'input', content: '' },
{ label: '上报人', placeholder: "请输入", type: 'input', content: '' },
{ 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: '巡查员'}]},
import { reactive, computed, onMounted, watch } from 'vue';
// import { ChatDotSquare } from '@element-plus/icons-vue';
import currentFire from './components/currentFirecard.vue';
// import uav from '../components/uav.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();
// 定义一个ref变量,用于存储当前的火灾数据
const currentFireData = ref([
// 火灾数据1
{
location: "红色 四单元 七号搂 3楼",
severity: "四级 (大规模)",
status: "消防人员已到达现场",
time: "2025年8月7日 11:14 发现",
fireLevel: 0,
isXFOk: false
},
// 火灾数据2
{
location: "金色家园小区 三单元 七号搂 3楼",
severity: "三级 (大规模)",
status: "消防人员未到达现场",
time: "2025年8月5日 11:14 发现",
fireLevel: 1,
isXFOk: true
},
// 火灾数据3
{
location: "金色家园小区 四单元 七号搂 3楼",
severity: "四级 (大规模)",
status: "消防人员已到达现场",
time: "2025年8月7日 11:14 发现",
fireLevel: 0,
isXFOk: false
},
{
location: "金色家园小区 三单元 七号搂 3楼",
severity: "三级 (大规模)",
status: "消防人员未到达现场",
time: "2025年8月5日 11:14 发现",
fireLevel: 2,
isXFOk: true
},
{
location: "金色家园小区 四单元 七号搂 3楼",
severity: "四级 (大规模)",
status: "消防人员已到达现场",
time: "2025年8月7日 11:14 发现",
fireLevel: 0,
isXFOk: false
},
{
location: "金色家园小区 三单元 七号搂 3楼",
severity: "三级 (大规模)",
status: "消防人员未到达现场",
time: "2025年8月5日 11:14 发现",
fireLevel: 2,
isXFOk: true
}
]);
// 定义一个uavRepairData的ref,里面包含了多个无人机维修数据
const uavRepairData = ref([
// 第一个无人机维修数据,已经维修
{isRepaid: true, uavRepairSetailData:[{label:"无人机编号",value: '无人机1号'}, {label:"上报时间",value: '2025年8月7日 11:14'},{label:"型号",value: '小型无人机'},{label:"维护类型",value: '更换电池'}]},
// 第二个无人机维修数据,已经维修
{isRepaid: true, uavRepairSetailData:[{label:"无人机编号",value: '无人机1号'}, {label:"上报时间",value: '2025年8月7日 11:14'},{label:"型号",value: '小型无人机'},{label:"维护类型",value: '更换电池'}]},
// 第三个无人机维修数据,未维修
{isRepaid: false, uavRepairSetailData:[{label:"无人机编号",value: '无人机1号'}, {label:"上报时间",value: '2025年8月7日 11:14'},{label:"型号",value: '小型无人机'},{label:"维护类型",value: '更换电池'}]},
// 第四个无人机维修数据,已经维修
{isRepaid: true, uavRepairSetailData:[{label:"无人机编号",value: '无人机1号'}, {label:"上报时间",value: '2025年8月7日 11:14'},{label:"型号",value: '小型无人机'},{label:"维护类型",value: '更换电池'}]},
// 第五个无人机维修数据,未维修
{isRepaid: false, uavRepairSetailData:[{label:"无人机编号",value: '无人机1号'}, {label:"上报时间",value: '2025年8月7日 11:14'},{label:"型号",value: '小型无人机'},{label:"维护类型",value: '更换电池'}]},
// 第六个无人机维修数据,已经维修
{isRepaid: true, uavRepairSetailData:[{label:"无人机编号",value: '无人机1号'}, {label:"上报时间",value: '2025年8月7日 11:14'},{label:"型号",value: '小型无人机'},{label:"维护类型",value: '更换电池'}]},
])
const menuItems = ref([
{ 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: '/usermanage' },
{ 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: '/uavdispatch' },
{ 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: '/usermanage' }
]);
// 响应式配置
const layoutConfig = reactive({
containerMinHeight: '100vh',
cardSpacing: '1rem',
statsMinHeight: '300px'
});
const isAddDrawer = ref(false);
const isEditDrawer = ref(false);
const isUserInfoDialogVisible = ref(false);
const isResetPasswordDialogVisible = ref(false);
const rowData = ref([]);
const resetPasswordData = ref({});
const showuserinfodata = ref({});
const tableShowData = ref([
{id: 1, name: '背景', floorcount: 18, reporter: '张三', updateTime: '12345678901', discription: '打个人脸',fireLevel: '1'},
{id: 2, name: '背景', floorcount: 18, reporter: '张三', updateTime: '12345678901', discription: '说实在的',fireLevel: '1'},
{id: 3, name: '背景', floorcount: 18, reporter: '张三', updateTime: '12345678901', discription: '打个人脸',fireLevel: '1'},
{id: 4, name: '背景', floorcount: 18, reporter: '张三', updateTime: '12345678901', discription: '说实在的',fireLevel: '1'},
]);
// const archiveInfoDate = ref(null)
// const archiveInfoDateBackcallFn = (row) => {
// archiveInfoDate.value = null
// archiveInfoDate.value = row
// console.log('archiveInfoFn需要归档的数据',archiveInfoDate.value)
// };
// const archiveInfoFn = () => {
// console.log('archiveInfoFn归档的数据',archiveInfoDate.value)
// };
const handleAddInfoFn = () => {
isAddDrawer.value = true;
}
const tableDataRefresh = () => {
initTableData();
}
const editData = (data) => {
isEditDrawer.value = true;
rowData.value = data;
}
const deleteData = (data) => {
ElMessageBox.confirm(
'删除操作不可逆,是否继续?',
'删除',
{
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
draggable: true,
}
).then(() => {
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) {
ElMessage({ type: 'error', message: '删除失败(网络错误)' });
}
}).catch(() => {
ElMessage({ type: 'info', message: '取消删除' });
});
}
const resetData = (data) => {
isResetPasswordDialogVisible.value = true;
resetPasswordData.value = data;
}
const userData = (data) => {
isUserInfoDialogVisible.value = true;
showuserinfodata.value = data;
}
const initTableData = () => {
// staffGetPageInfoApi({
// "currentPageNum": 1,
// "currentPageSize": 10,
// }).then(res => {
// if(res.code === 200) {
// let tempData = res.data.list
// tableShowData.value[0].tableBody = []
// tempData = tempData.filter(element => 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;
// }
// }).catch(err => {
// ElMessage.error(err.message);
// });
}
onMounted(() => {
initTableData();
topCardHeight: '120px', // 固定顶部卡片高度
statsMinHeight: '300px' // 确保统计区域最小高度
});
// 计算容器样式
const containerStyle = computed(() => ({
minHeight: layoutConfig.containerMinHeight,
'--card-spacing': layoutConfig.cardSpacing,
}));
onMounted(() => {
nextTick (()=>{
useAppStoreInstance.initavatarUrlFn()
})
});
// 监听路由变化
watch(route, () => {
useAppStoreInstance.initavatarUrlFn()
}, { immediate: true });
</script>
<style scoped>
......@@ -183,74 +167,100 @@ const containerStyle = computed(() => ({
height: 100%;
}
/* 顶部卡片容器 */
.left-top {
height: auto;
display: flex;
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;
overflow: hidden;
}
/* 用户信息卡片 */
.region-overview {
flex: 1;
min-width: 200px;
min-width: 200px; /* 确保最小宽度 */
}
.stats-alerts {
/* 用户信息布局 */
.info-grid {
display: flex;
align-items: center;
gap: 0.8rem;
}
.info-item {
display: flex;
flex-direction: column;
gap: 1rem;
height: 67%;
padding: 0.5rem;
}
.card-tabs {
/* 待办事项卡片 */
.region-map {
flex: 0.5;
display: flex;
border-bottom: 1px solid #292828;
font-size: 1.2rem;
color: #000000;
height: 8%;
align-items: center;
width: 100%;
padding: 10px;
justify-content: center;
min-width: 150px; /* 确保最小宽度 */
background-color: rgba(100,149,237,0.30);
}
.title {
width: 90%;
.region-map:hover .menu_left-icon {
animation: infiniteRotate 1s linear infinite;
}
.card-actions {
display: flex;
flex: 1;
justify-content: space-between;
align-items: center;
/* height: %; */
padding: 1.5rem;
@keyframes infiniteRotate {
0% { transform: rotate(0deg); }
25% { transform: rotate(45deg); }
50% { transform: rotate(0deg); }
75% { transform: rotate(-45deg); }
100% { transform: rotate(0deg); }
}
.region-map span {
margin-left: 0.5rem;
font-weight: 500;
}
.operation-button {
flex: 1;
/* 统计区域卡片 */
.stats-alerts {
display: flex;
justify-self: end;
gap: 1rem;
border-radius: 8px;
height: 79.5%;
}
.card-table {
width: 100%;
/* 统计方块样式 */
.card-tong {
flex: 1;
overflow: hidden;
border-radius: 8px;
border-radius: 10px;
height: 100%;
box-shadow: 2px 0 rgba(0, 0, 0, 0.1);
overflow: auto;
}
.card-show{
flex: 0.5;
}
.card-tong-large {
flex: 2; /* 第三个方块宽度是其他两个的两倍 */
}
/* 响应式适配 */
@media (max-width: 1024px) {
.left-top {
flex-direction: column;
}
.region-overview {
.region-overview, .region-map {
width: 100%;
flex: none;
}
......@@ -260,5 +270,10 @@ const containerStyle = computed(() => ({
.stats-alerts {
flex-direction: column;
}
.card-tong-large {
flex: none;
height: 150px; /* 在移动端保持高度 */
}
}
</style>
\ No newline at end of file
......@@ -7,9 +7,10 @@
<el-input v-if="items.type === 'input'"
v-model="items.content"
clearable
:disabled="!isShow"
:placeholder="items.placeholder"
/>
<el-select v-else
<el-select v-else-if="items.type === 'select'"
v-model="items.content"
:placeholder="items.placeholder"
clearable
......@@ -21,10 +22,32 @@
:value="building.value"
/>
</el-select>
<el-autocomplete v-else-if="items.type === 'autocomplete'"
v-model="items.content"
:fetch-suggestions="querySearch"
:trigger-on-focus="false"
clearable
class="inline-input w-50"
placeholder="请输入"
@input="getAllListInfoFn(items)"
/>
<el-date-picker v-else
v-model="items.content"
type="daterange"
start-placeholder="开始日期"
end-placeholder="结束日期"
:default-value="defaultDateRange"
@change="getAllListInfoFn"
:disabled-date="disableFutureDates"
style="max-width: 220px;"
/>
</div>
</div>
<div class="operation-buttons">
<div class="operation-buttons" v-if="isShow">
<!-- 操作按钮组 -->
<div class="search-buttons">
<el-button
type="default"
......@@ -46,11 +69,154 @@
</template>
<script setup>
import { reactive, ref } from 'vue';
import { ElInput, ElSelect, ElOption, ElButton } from 'element-plus';
import { computed, reactive, ref, watch } from 'vue';
import { ElInput, ElSelect, ElOption, ElButton, ElMessage, dayjs } from 'element-plus';
import { buildingGetBuildCodeListApi,buildingGetBuildListByBuildNameApi,buildingGetTotalFloorNumListApi,buildingGetBuildNameListApi } from '../../../api/build'
import { floorGetFloorNoListAPI } from '../../../api/floor'
import useAppStore from '../../../store/module/app';
const useAppStoreInstance = useAppStore()
const props = defineProps(["searchShowData"])
const isShow = computed(() => {
console.log("按钮操作显示标识",props.searchShowData)
if (props.searchShowData.length > 0) {
return props.searchShowData[0].isShow
}else{
ElMessage.error('按钮操作显示标识错误')
}
})
const Year = dayjs(Date.now()).format('YYYY')
const Month = dayjs(Date.now()).format('MM')
const Day = dayjs(Date.now()).format('DD')
const items = ref({
content: []
})
// 默认值设置(本月第一天到今天)
const defaultDateRange = [
dayjs().startOf('month'), // 本月1号
dayjs() // 今天
]
// 禁用未来日期
const disableFutureDates = (current) => {
return current > dayjs().endOf('day')
}
const restaurants = ref([])
const querySearch = (queryString, cb) => {
console.log('queryString:', restaurants.value);
const results = queryString
? restaurants.value.filter(createFilter(queryString))
: restaurants.value
// call callback function to return suggestions
cb(results)
}
const createFilter = (queryString) => {
return (restaurant) => {
// 确保 restaurant 和 restaurant.value 存在
if (!restaurant?.value) return false;
// 确保 queryString 是字符串
const searchText = String(queryString || '').toLowerCase();
const itemText = String(restaurant.value).toLowerCase();
return itemText.includes(searchText); // 或 startsWith()
}
}
const handleSelect = (item) => {
console.log(item.click)
restaurants.value = item.options
}
const getAllListInfoFn = (item) => {
// console.log(item.click,'-*--*-*-*-*-*-')
switch (item.click) {
case 'buildingGetBuildListByBuildNameFn':
buildingGetBuildListByBuildNameFn(item)
break;
case 'buildingGetBuildCodeListApiFn':
buildingGetBuildCodeListApiFn(item)
break;
case 'buildingGetTotalFloorNumListFn':
buildingGetTotalFloorNumListFn(item)
break;
case 'buildingGetBuildNameListFn':
buildingGetBuildNameListFn(item)
break;
case 'floorGetFloorNoListFn':
floorGetFloorNoListFn(item)
break;
default:
console.log('没有匹配的api')
break;
}
}
const buildingGetBuildListByBuildNameFn = (item) => {
// console.log(item,'buildingGetBuildCodeListFn被触发')
buildingGetBuildListByBuildNameApi({buildName:item.content}).then(res => {
// console.log(res,'buildingGetBuildCodeListFn返回数据')
if(res.code == 200) {
restaurants.value = res.data
// console.log(restaurants.value,'buildingGetBuildCodeListFn8999999999999返回数据')
}
})
};
const buildCodeTraverse = (item)=>{
let buildCodeList = []
item.forEach(item => {
// console.log(item,'buildCodeTraverse被触发')
buildCodeList.push({value:item})
})
return buildCodeList
}
const buildingGetBuildCodeListApiFn = (item) => {
buildingGetBuildCodeListApi({buildCode:item.content}).then(res => {
// console.log(res,'buildingGetBuildCodeListFn返回数据')
if(res.code == 200) {
restaurants.value = buildCodeTraverse(res.data)
// console.log(restaurants.value,'buildingGetBuildCodeListFn8999999999999返回数据')
}
})
};
// 返回的数据不对应当[楼层数]不是【建筑名称】
const buildingGetTotalFloorNumListFn = (item) => {
buildingGetTotalFloorNumListApi({totalFloorNum:item.content}).then(res => {
console.log(res,'buildingGetTotalFloorNumListFn返回数据')
if(res.code == 200) {
restaurants.value = buildCodeTraverse(res.data)
console.log(restaurants.value,'buildingGetTotalFloorNumListFn8999999999999返回数据')
}
})
}
const buildingGetBuildNameListFn = (item) => {
buildingGetBuildNameListApi({buildName:item.content}).then(res => {
// console.log(res,'buildingGetBuildNameListFn返回数据')
if(res.code == 200) {
restaurants.value = buildCodeTraverse(res.data)
// console.log(restaurants.value,'buildingGetBuildNameListFn8999999999999返回数据')
}
})
}
const floorGetFloorNoListFn = (item) => {
floorGetFloorNoListAPI({buildId: useAppStoreInstance.PUSHPARAMETER.buildId,floorNo:item.content}).then(res => {
// console.log(res,'floorGetFloorNoListFn返回数据')
if(res.code == 200) {
restaurants.value = buildCodeTraverse(res.data)
// console.log(restaurants.value,'floorGetFloorNoListFn8999999999999返回数据')
}
})
}
// 监听变化
// watch(() => props.isBuildingEditDrawer, (newVal, oldVal) => {
// console.log('抽屉已打开,监听变化');
// initFormData()
// }, { immediate: true });
// 提交搜索
const submitSearch = () => {
......@@ -69,6 +235,8 @@ const resetSearchForm = () => {
</script>
<style scoped>
.fire-search-container {
background-color: #fff;
......
......@@ -90,11 +90,12 @@ 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 emits = defineEmits(["tableDataRefresh"])
const emits = defineEmits(["tableDataRefresh",'getPageCommonAPI'])
const curTableShowData = ref(props.tableShowData)
console.log("11111111111111111111111props.tableShowData-----------------",props.Operation)
......@@ -135,47 +136,81 @@ const handleButtonClick = (value, row) => {
// 分页事件处理
const handleSizeChange = (val) => {
console.log(`每页 ${val} 条`);
useAppStoreInstance.setPageCountInfoCurrentPageSizeData(val)
getNewTableData()
};
const handleCurrentChange = (val) => {
console.log(`当前页 ${val} 条`);
useAppStoreInstance.setPageCountInfoCurrentPageNumData(val)
getNewTableData()
};
const getNewTableData = () => {
staffGetPageInfoApi({
"currentPageNum": currentPage2.value,
"currentPageSize": pageSize2.value,
emits('getPageCommonAPI',{
currentPageNum: currentPage2.value,
currentPageSize: pageSize2.value,}
)
}).then(res => {
if(res.code === 200){
// .then(res => {
// if(res.code === 200){
// console.log(res.data, '展示数据');
// // let tempData = res.data.list
// // // console.log(props.Operation,"--11111111111111111111111---*****---999555555555555999999----")
// // curTableShowData.value[0].tableBody = []
// // //获取未逻辑删除的数据
// // tempData = tempData.filter(element => {
// // return element.isDeleted === 0;
// // });
let tempData = res.data.list
// console.log(props.Operation,"--11111111111111111111111---*****---999555555555555999999----")
curTableShowData.value[0].tableBody = []
//获取未逻辑删除的数据
tempData = tempData.filter(element => {
return element.isDeleted === 0;
});
// // tempData.forEach(element => {
// // element.Operation = [...props.Operation]
tempData.forEach(element => {
element.Operation = [...props.Operation]
// // });
// // curTableShowData.value[0].tableBody = tempData
});
curTableShowData.value[0].tableBody = tempData
// // curTableShowData.value[0].total = res.data.total
// // curTableShowData.value[0].pageSize = res.data.pageSize
// // console.log(curTableShowData.value, '展示数据');
curTableShowData.value[0].total = res.data.total
curTableShowData.value[0].pageSize = res.data.pageSize
console.log(curTableShowData.value, '展示数据');
// }
}
// }).catch(err => {
// message.error(err.message)
}).catch(err => {
message.error(err.message)
// })
// staffGetPageInfoApi({
// "currentPageNum": currentPage2.value,
// "currentPageSize": pageSize2.value,
})
// }).then(res => {
// if(res.code === 200){
// let tempData = res.data.list
// // console.log(props.Operation,"--11111111111111111111111---*****---999555555555555999999----")
// curTableShowData.value[0].tableBody = []
// //获取未逻辑删除的数据
// tempData = tempData.filter(element => {
// return element.isDeleted === 0;
// });
// tempData.forEach(element => {
// element.Operation = [...props.Operation]
// });
// curTableShowData.value[0].tableBody = tempData
// curTableShowData.value[0].total = res.data.total
// curTableShowData.value[0].pageSize = res.data.pageSize
// console.log(curTableShowData.value, '展示数据');
// }
// }).catch(err => {
// message.error(err.message)
// })
};
</script>
......
......@@ -19,8 +19,8 @@
<!-- 待办事项卡片 -->
<div class="info-card region-map">
<el-icon style="color: #6495ed;" size="20"><ChatDotSquare /></el-icon>
<span>{{ 12 }}待办事项</span>
<el-icon class="menu_left-icon" style="color: #6495ed;" size="20"><BellFilled /></el-icon>
<span>12 待办事项</span>
</div>
</div>
......@@ -234,9 +234,21 @@ watch(route, () => {
align-items: center;
justify-content: center;
min-width: 150px; /* 确保最小宽度 */
background-color: rgba(100,149,237,0.30)
background-color: rgba(100,149,237,0.30);
}
.region-map:hover .menu_left-icon {
animation: infiniteRotate 1s linear infinite;
}
@keyframes infiniteRotate {
0% { transform: rotate(0deg); }
25% { transform: rotate(45deg); }
50% { transform: rotate(0deg); }
75% { transform: rotate(-45deg); }
100% { transform: rotate(0deg); }
}
.region-map span {
margin-left: 0.5rem;
font-weight: 500;
......@@ -247,7 +259,7 @@ watch(route, () => {
display: flex;
gap: 1rem;
border-radius: 8px;
height: 67%;
height: 68.5%;
}
......
......@@ -232,13 +232,8 @@ const handleSubmit = () => {
...form,
avatar:form.avatar,
};
// console.log('提交新增用户数据:', submitData);
// 模拟API请求
// API请
console.log('提交新增用户数据:', submitData,form.avatar);
staffAddInfoApi(submitData).then(res => {
console.log('用户新增成功', res);
if (res.code === 200) {
......@@ -252,7 +247,7 @@ const handleSubmit = () => {
}
}).catch(err => {
ElMessage.error('用户新增失败');
ElMessage.error('用户新增失败',err);
});
......@@ -262,9 +257,11 @@ const handleSubmit = () => {
} catch (error) {
console.error('表单验证失败:', error);
} finally {
submitting.value = false;
}
finally{
submitting.value = false;
};
};
// 取消操作
......
......@@ -25,7 +25,7 @@
</div>
</div>
<div class="card-table">
<tabledata :tableShowData="tableShowData" :Operation="Operation" @tableDataRefresh="tableDataRefresh"></tabledata>
<tabledata :tableShowData="tableShowData" :Operation="Operation" @getPageCommonAPI="initTableData" @tableDataRefresh="tableDataRefresh"></tabledata>
</div>
</div>
......@@ -81,9 +81,9 @@ const route = useRoute()
// 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:'巡查员'}]},
{ label: '用户姓名', placeholder: "请输入", type: 'input',content:'' ,isShow: true},
{ label: '用户状态', placeholder: "请选择", type: 'select',content:'' ,isShow: true, options: [{label:'启用', value:'启用'}, {label:'禁用', value:'禁用'}] },
{ label: '用户角色', placeholder: "请选择", type: 'select', content:'',isShow: true ,options: [{label:'管理员', value:'管理员'}, {label:'巡查员', value:'巡查员'}]},
])
// 响应式布局配置
const layoutConfig = reactive({
......@@ -117,7 +117,11 @@ const beforCloseAddDrawer = () => {
* 当调用此方法时,会触发表格数据的重新加载
*/
const tableDataRefresh = () => {
initTableData()
initTableData({
currentPageNum: useAppStoreInstance.pageCountInfo.currentPageNum,
currentPageSize:useAppStoreInstance.pageCountInfo.currentPageSize,
})
console.log("000000-------2-----0000000000,这里获取到最新的数据")
}
......@@ -230,6 +234,7 @@ const resetData = (data) => {
ElMessage.error("不能重置自己的密码")
}else{
try {
console.log(useAppStoreInstance.chackCurPersionOpition(),"********useAppStoreInstance.chackCurPersionOpition()***************")
if(useAppStoreInstance.chackCurPersionOpition() ){
console.log("000000-----3-------0000000000",data)
isResetPasswordDialogVisible.value = true;
......@@ -271,10 +276,10 @@ const Operation = ref( [ { label: '编辑', type: 'primary', icon: 'EditPen', cl
{ label: '重置密码', type: 'primary', icon: 'EditPen', click: resetData }]
)
const initTableData = () => {
const initTableData = (parameter) => {
staffGetPageInfoApi({
"currentPageNum": 1,
"currentPageSize": 10,
currentPageNum: parameter.currentPageNum,
currentPageSize: parameter.currentPageSize,
}).then(res => {
if(res.code === 200){
......@@ -306,7 +311,11 @@ const initTableData = () => {
onMounted(() => {
// console.log(tableShowData.value, '错误');
initTableData()
initTableData({
currentPageNum: 1,
currentPageSize: 10,
})
})
......@@ -319,7 +328,10 @@ const containerStyle = computed(() => ({
// 监听路由变化
watch(route, () => {
useAppStoreInstance.initavatarUrlFn()
initTableData()
initTableData({
currentPageNum: 1,
currentPageSize: 10,
})
}, { immediate: true });
</script>
......
......@@ -96,11 +96,11 @@ const drones = ref([
// 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: 'input',content:'' },
{ label: '火情编号', placeholder: "请输入", type: 'input', content:'' },
{ label: '建筑名称', placeholder: "请选择", type: 'select',content:'' , options: [{label:'火灾', value:'烟雾'}, {label:'烟雾', value:'火灾'}, {label:'烟雾', value:'火灾'}] },
{ label: '建筑名称', placeholder: "请选择", type: 'select', content:'' ,options: [{label:'火灾1', value:'烟雾1'}, {label:'烟雾1', value:'火灾1'}, {label:'烟雾1', value:'火灾1'}] },
{ label: '火情描述', placeholder: "请输入", type: 'input',content:'' ,isShow: true},
{ label: '火情描述', placeholder: "请输入", type: 'input',content:'' ,isShow: true},
{ label: '火情编号', placeholder: "请输入", type: 'input', content:'' ,isShow: true},
{ label: '建筑名称', placeholder: "请选择", type: 'select',content:'' ,isShow: true, options: [{label:'火灾', value:'烟雾'}, {label:'烟雾', value:'火灾'}, {label:'烟雾', value:'火灾'}] },
{ label: '建筑名称', placeholder: "请选择", type: 'select', content:'' ,isShow: true,options: [{label:'火灾1', value:'烟雾1'}, {label:'烟雾1', value:'火灾1'}, {label:'烟雾1', value:'火灾1'}] },
])
// 响应式布局配置
const layoutConfig = reactive({
......
......@@ -48,9 +48,9 @@ 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:'巡查员'}]},
{ label: '用户姓名', placeholder: "请输入", type: 'input',content:'',isShow: true },
{ label: '用户状态', placeholder: "请选择", type: 'select',content:'' ,isShow: true, options: [{label:'启用', value:'启用'}, {label:'禁用', value:'禁用'}] },
{ label: '用户角色', placeholder: "请选择", type: 'select', content:'',isShow: true ,options: [{label:'管理员', value:'管理员'}, {label:'巡查员', value:'巡查员'}]},
])
// 响应式布局配置
const layoutConfig = reactive({
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论