Compare commits

...

2 Commits

Author SHA1 Message Date
zhufu 034aa54aef Merge branch 'main' of http://123.132.248.154:10000/gitY/LinYeFangHuo 2026-01-27 17:02:44 +08:00
zhufu 52a310972c 站点管理模块 2026-01-27 16:55:12 +08:00
8 changed files with 177 additions and 52 deletions

View File

@ -66,12 +66,18 @@ enum Api {
GetCameraInfoPageList = '/api/FireManagement/GetCameraInfoPageList',
// 站点管理
LoadAllSite = '/api/FmFireSite/LoadAllSite',
AddSiteInfo = '/api/FmFireSite/AddSiteInfo',
GetSiteInfo = '/api/FmFireSite/GetSiteInfo',
EditSiteInfo = '/api/FmFireSite/EditSiteInfo',
AuditSite = '/api/FmFireSite/AuditSite',
ExportSite = '/api/FmFireSite/ExportSite',
// 进山登记
LoadInUser = '/api/FmFireSite/LoadInUser',
// 对讲设备
GetInterphoneInfo = '/api/FmInterPhone/GetInterphoneInfo',
DeleteInterphoneInfo = '/api/FmInterPhone/DeleteInterphoneInfo',
AddOrUpdateInterphoneInfo = '/api/FmInterPhone/AddOrUpdateInterphoneInfo',
}
export const getPositionsTree = (params?: AccountParams) =>
defHttp.get<AccountListGetResultModel>({ url: Api.PositionsTree, params });
@ -120,6 +126,27 @@ export function AddOrUpdateInterphoneInfo(params) {
});
}
export const AddSiteInfo = (params) =>
defHttp.post({ url: Api.AddSiteInfo, params });
export const EditSiteInfo = (params) =>
defHttp.post({ url: Api.EditSiteInfo, params });
export const GetSiteInfo = (params) =>
defHttp.get({ url: Api.GetSiteInfo, params });
export const AuditSite = (params: {siteId: number, state: number, content:string }) =>
defHttp.post({
url: `${Api.AuditSite}?siteId=${params.siteId}&state=${params.state}&content=${params.content}`,
});
export const ExportSite = (params) =>
defHttp.get({
url: Api.ExportSite,
params,
responseType:"blob"
});
export const getOrgPositonTree = (params?: DeptListItem) =>
defHttp.get<DeptListGetResultModel>({ url: Api.OrgPositonTree, params });

View File

@ -46,7 +46,7 @@
{{ text }}
</div>
</template>
<template v-else-if="['account'].includes(column.dataIndex)">
<template v-else-if="['phone'].includes(column.dataIndex)">
<div>
{{ text }}
</div>
@ -73,16 +73,18 @@
@ok="handlePostionOk"
:destroyOnClose="true"
>
<Map ref="PostionRef" />
<Map ref="PostionRef" @getAddress="getAddress"/>
</a-modal>
</div>
</template>
<script lang="ts" setup>
import { SelectAccount } from './page';
import { reactive, ref, onMounted, watch, defineProps } from 'vue';
import { reactive, ref, onMounted } from 'vue';
import { Map } from './page';
import { useUserStore } from '@/store/modules/user'
const userStore = useUserStore()
const props = defineProps(['modalType', 'siteInfo'])
const labelCol = { span: 3 };
const wrapperCol = { span: 6 };
const SelectAccountRef = ref<any>();
@ -100,13 +102,18 @@
},
columns: [
{ title: '用户姓名', dataIndex: 'name' },
{ title: '联系电话', dataIndex: 'account' },
{ title: '联系电话', dataIndex: 'phone' },
{ title: '操作', dataIndex: 'operation' },
],
tableData: [],
});
const PostionRef = ref();
onMounted(() => {});
onMounted(() => {
if(props.modalType == 'update'){
addForm.value = props.siteInfo
accountList.value = props.siteInfo.siteUser
}
});
const addPerson = () => {
accountVisible.value = true;
};
@ -126,9 +133,11 @@
mapVisible.value = false;
};
const createSite = () => {
let id = userStore.getUserInfo.id
const params = {
...addForm.value,
accountList: accountList.value,
createuserid: id,
siteUser: accountList.value,
};
return params;
};
@ -143,6 +152,14 @@
return false;
});
}
const getAddress = (lng, lat, siteAddress) => {
addForm.value = {
...addForm.value,
lng,
lat,
siteAddress,
}
}
defineExpose({
createSite,
validateForm,

View File

@ -5,24 +5,24 @@
<a-descriptions-item label="站点状态">
<a-tag
:color="
detailInfo.state == '未审核'
detailInfo.state == '0'
? 'orange'
: detailInfo.state == '审核通过'
: detailInfo.state == '1'
? 'green'
: 'red'
"
size="mini"
>{{ detailInfo.state }}</a-tag
>{{ detailInfo.state == 0? '未审核': detailInfo.state == 1? "审核通过": '未通过' }}</a-tag
>
</a-descriptions-item>
<a-descriptions-item label="负责人">{{ detailInfo.director }}</a-descriptions-item>
<a-descriptions-item label="负责人电话"> {{ detailInfo.phone }}</a-descriptions-item>
<a-descriptions-item label="是否有人值守">
<a-tag size="mini" v-if="detailInfo.isonduty"></a-tag>
<a-tag size="mini" color="green" v-if="detailInfo.isonduty"></a-tag>
<a-tag size="mini" color="red" v-else></a-tag>
</a-descriptions-item>
<a-descriptions-item label="是否接收进山消息推送">
<a-tag size="mini" v-if="detailInfo.isreceive"></a-tag>
<a-tag size="mini" color="green" v-if="detailInfo.isreceive"></a-tag>
<a-tag size="mini" color="red" v-else></a-tag>
</a-descriptions-item>
<a-descriptions-item label="站点图片">{{ detailInfo.siteImg }}</a-descriptions-item>
@ -33,7 +33,7 @@
<a-table :dataSource="dataSource" :columns="columns" />
</a-descriptions-item>
</a-descriptions>
<div class="mt-4">
<div class="mt-4" style="padding-bottom: 20px;">
<a-input style="width: 50%" v-model:value="form.content" placeholder="审核说明" />
<a-button style="margin: 0 20px" type="primary" @click="examine(2)" danger>拒绝</a-button>
<a-button type="primary" @click="examine(1)"></a-button>
@ -41,8 +41,16 @@
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { ref, onMounted } from 'vue';
import { AuditSite } from '@/api/demo/system';
import { message } from 'ant-design-vue';
onMounted(() => {
detailInfo.value = props.showDetailInfo
dataSource.value = props.showDetailInfo.siteUser
})
const props = defineProps(['showDetailInfo'])
const emits = defineEmits(['close'])
const detailInfo: any = ref({});
const dataSource = ref([]);
const columns = ref([
@ -53,8 +61,8 @@
},
{
title: '手机号',
dataIndex: 'account',
key: 'account',
dataIndex: 'phone',
key: 'phone',
},
]);
const form = ref({
@ -63,8 +71,13 @@
const examine = (status: number) => {
const params = {
status,
siteId: detailInfo.value.id,
state: status,
content: form.value.content
};
console.log(params);
AuditSite(params).then(res => {
message.success('站点审核成功')
emits('close')
})
};
</script>

View File

@ -6,6 +6,7 @@
import { ref, onMounted } from 'vue';
import * as mars3d from 'mars3d';
const emits = defineEmits(['getAddress'])
let map: mars3d.Map; //
const vChartRef = ref<HTMLElement>();
onMounted(() => {
@ -244,35 +245,44 @@
isAutoEditing: false,
});
map.addLayer(pointLayer);
map.on(mars3d.EventType.click, function (event) {
console.log('click', event);
var point = mars3d.LngLatPoint.fromCartesian(event.cartesian); //
point.format(); //
pointData.value = point;
console.log('鼠标单击坐标', point);
console.log('经度:' + point.lng + '\n' + '纬度:' + point.lat + '\n' + '高度:' + point._alt);
if (idNum.value > 0) {
map.on(mars3d.EventType.click, async (event) => {
const cartesian = map.camera.pickEllipsoid(
event.position,
map.scene.globe.ellipsoid
);
if (!cartesian) return;
const point = mars3d.LngLatPoint.fromCartesian(cartesian);
point.format();
const { lng, lat } = point;
const address = await getAddressByLngLat(lng, lat);
emits('getAddress', lng, lat, address)
if (pointGraphic.value) {
pointLayer.removeGraphic(pointGraphic.value);
}
//
const coordinates = [point.lng, point.lat];
//
// Mars3D ()
pointGraphic.value = new mars3d.graphic.BillboardEntity({
position: coordinates,
attr: point,
position: [lng, lat, 10],
style: {
pixelSize: 100,
scale: 0.5,
image: '/positioning.png',
scale: 0.6,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
verticalOrigin: mars3d.Cesium.VerticalOrigin.BOTTOM,
},
});
//
pointLayer.addGraphic(pointGraphic.value);
idNum.value = idNum.value + 1;
});
};
async function getAddressByLngLat(lng: number, lat: number) {
const GAODE_KEY = "6af6a87038f44c8c793aa70331f2b7ca";
const url = `https://restapi.amap.com/v3/geocode/regeo?key=${GAODE_KEY}&location=${lng},${lat}&radius=1000&extensions=base`;
const res = await fetch(url);
const data = await res.json();
if (data.status === '1') {
return data.regeocode.formatted_address;
}
return '未知位置';
}
//
const handlerInitEntityLayer = () => {
if (graphicLayer == null) {

View File

@ -14,11 +14,11 @@
defineOptions({ name: 'AccountManagement' });
const searchInfo = reactive<Recordable>({});
const [registerTable, { reload, updateTableDataRecord, getSelectRows, clearSelectedRowKeys }] =
const [registerTable, { reload, updateTableDataRecord, getSelectRows, setSelectedRowKeys, clearSelectedRowKeys }] =
useTable({
title: '用户列表',
api: getAccountList,
rowKey: 'id',
rowKey: 'siteUserId',
columns: SelectColumns,
formConfig: {
labelWidth: 120,
@ -38,6 +38,16 @@
console.log('handleSearchInfoFn', info);
return info;
},
afterFetch: (res) => {
return res.map(item => {
return {
siteUserId: `${item.id}`,
userRole: 2,
name: item.name,
phone: item.account
}
})
}
});
function getRow() {

View File

@ -166,7 +166,7 @@ export const formSchema: FormSchema[] = [
export const SelectColumns: BasicColumn[] = [
{
title: '用户名',
dataIndex: 'account',
dataIndex: 'phone',
width: 120,
},
{

View File

@ -21,33 +21,36 @@
<a-modal
v-model:visible="addModelVisible"
title="站点信息"
wrap-class-name="full-modal"
width="80%"
wrap-class-name="inspection-full-modal"
width="100%"
:destroyOnClose="true"
@ok="handleOk"
>
<AddModal ref="AddModalRef" />
<AddModal ref="AddModalRef" :modalType="modalType" :siteInfo="siteInfo"/>
</a-modal>
<a-modal
v-model:visible="detailModelVisible"
title="站点信息"
wrap-class-name="full-modal"
wrap-class-name="inspection-full-modal"
width="80%"
:destroyOnClose="true"
:footer="null"
>
<Detail @close="closeDetail" />
<Detail @close="closeDetail" :showDetailInfo="showDetailInfo"/>
</a-modal>
</PageWrapper>
</template>
<script lang="ts" setup>
import { reactive, ref } from 'vue';
import { BasicTable, useTable, TableAction } from '@/components/Table';
import { LoadAllSite, deleteDept } from '@/api/demo/system';
import { LoadAllSite, AddSiteInfo, GetSiteInfo, EditSiteInfo, ExportSite } from '@/api/demo/system';
import { PageWrapper } from '@/components/Page';
import { useMessage } from '@/hooks/web/useMessage';
import { AddModal, Detail } from './page';
import { PermissionBtn } from '@/components/PermissionBtn/index';
import { columns, searchFormSchema } from './data';
import { message } from 'ant-design-vue';
defineOptions({ name: 'DeptManagement' });
const { createConfirm, createMessage } = useMessage();
@ -55,8 +58,11 @@
const searchInfo = reactive<Recordable>({});
const addModelVisible = ref(false);
const detailModelVisible = ref(false);
const modalType = ref()
const siteInfo = ref({})
const showDetailInfo = ref({})
const [registerTable, { reload, getSelectRows, clearSelectedRowKeys }] = useTable({
const [registerTable, { reload, getSelectRows, clearSelectedRowKeys, getForm }] = useTable({
//
title: '站点列表',
//
@ -109,6 +115,7 @@
const childRef = ref<any>();
function handleCreate() {
modalType.value = 'insert'
addModelVisible.value = true;
}
@ -118,7 +125,14 @@
return createMessage.warn('请选择一个站点进行编辑');
}
const record = rows[0];
addModelVisible.value = true;
GetSiteInfo({
siteId: record.id,
}).then(res => {
modalType.value = 'update'
siteInfo.value = res
addModelVisible.value = true;
})
}
function onBtnClicked(domId) {
switch (domId) {
@ -129,6 +143,7 @@
handleEdit();
break;
case 'btnExport':
handleExport()
break;
default:
break;
@ -143,25 +158,57 @@
AddModalRef.value.validateForm();
const params = AddModalRef.value.createSite();
console.log('params', params);
if(modalType.value == 'update'){
return EditSiteInfo(params).then(res => {
message.success('编辑站点成功!')
reload()
addModelVisible.value = false
})
}
return AddSiteInfo(params).then(res => {
message.success('添加站点成功!')
reload()
addModelVisible.value = false
})
};
const viewDetail = (record: any) => {
console.log('record', record);
detailModelVisible.value = true;
GetSiteInfo({
siteId: record.id,
}).then(res => {
showDetailInfo.value = res
detailModelVisible.value = true;
})
};
const closeDetail = () => {
detailModelVisible.value = false;
reload()
};
const handleExport = () => {
const params = getForm().getFieldsValue();
ExportSite(params).then(blob => {
const fileName = "站点统计导出" + new Date().getTime() + ".xls";
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = fileName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(url);
})
}
</script>
<style lang="less">
.full-modal {
.inspection-full-modal {
.ant-modal {
max-width: 80%;
}
.ant-modal-content {
height: calc(80vh);
}
// .ant-modal-content {
// height: calc(80vh);
// }
.ant-modal-body {
height: 100%;

View File

@ -656,5 +656,6 @@
font-size: 16px;
font-weight: 500;
background-color: rgba(0, 0, 0, 0.3);
z-index: 1;
}
</style>