merge
commit
433d1efab7
|
|
@ -30,3 +30,10 @@ VITE_GLOB_APP_MANAGEMENT_UNIT = 管理单位:临沂市自然资源和规划局
|
|||
VITE_GLOB_APP_TECHINICAL_SUPPORT = 技术⽀持:山东慧创信息科技有限公司
|
||||
|
||||
VITE_GLOB_APP_VERSIONS = 系统版本:V1.0
|
||||
|
||||
VITE_GLOB_MQTT_URL = wrj.wisestcity.com
|
||||
VITE_GLOB_MQTT_PORT = 6010
|
||||
|
||||
VITE_GLOB_APP_RTMP_URL = rtmp://123.132.248.154:1935
|
||||
VITE_GLOB_APP_FLV_URL = http://123.132.248.154:1986
|
||||
VITE_GLOB_SRS_API_URL = http://123.132.248.154:1985
|
||||
|
|
|
|||
|
|
@ -167,7 +167,8 @@
|
|||
"vuedraggable": "^4.1.0",
|
||||
"vuex": "^4.1.0",
|
||||
"xe-utils": "^3.5.14",
|
||||
"xlsx": "^0.18.5"
|
||||
"xlsx": "^0.18.5",
|
||||
"@turf/helpers": "^7.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@amap/amap-jsapi-loader": "^1.0.1",
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ enum Api {
|
|||
AddPreventionplan = '/api/FmPreventionPlan/AddPreventionplan',
|
||||
// 删除预案
|
||||
DeletePreventionplan = '/api/FmPreventionPlan/DeletePreventionplan',
|
||||
// 根据坐标点获取预案
|
||||
LoadClueInfoByLngLat = '/api/FmPreventionPlan/LoadClueInfoByLngLat',
|
||||
}
|
||||
export function GetPreventionplanPageList(params) {
|
||||
return defHttp.get({
|
||||
|
|
@ -31,4 +33,10 @@ export function DeletePreventionplan(id) {
|
|||
return defHttp.post({
|
||||
url: `${Api.DeletePreventionplan}?id=${id}`,
|
||||
});
|
||||
}
|
||||
export function LoadClueInfoByLngLat(params) {
|
||||
return defHttp.get({
|
||||
url: Api.LoadClueInfoByLngLat,
|
||||
params
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import { defHttp } from '@/utils/http/axios';
|
||||
enum Api {
|
||||
LoadTimeSoltByUserId = '/api/FireManagement/LoadTimeSoltByUserId',
|
||||
AddOrUpdateTimeSolt = '/api/FireManagement/AddOrUpdateTimeSolt',
|
||||
}
|
||||
export const LoadTimeSoltByUserId = (params: { id:number }) => defHttp.get({ url: Api.LoadTimeSoltByUserId, params });
|
||||
|
||||
export const AddOrUpdateTimeSolt = (params) => defHttp.post({ url: Api.AddOrUpdateTimeSolt, params });
|
||||
|
|
@ -50,19 +50,20 @@
|
|||
<div class="add-plan-item">
|
||||
<div class="plan-label">预案名称</div>
|
||||
<div class="plan-content">
|
||||
<a-input class="add-plan-input" v-model:value="addPlanData['planName']" placeholder="请输入预案名称" />
|
||||
<a-input ref="planName" class="add-plan-input" v-model:value="addPlanData['planName']" placeholder="请输入预案名称" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="add-plan-item">
|
||||
<div class="plan-label">预案编号</div>
|
||||
<div class="plan-content">
|
||||
<a-input class="add-plan-input" v-model:value="addPlanData['planCode']" placeholder="请输入预案编号" />
|
||||
<a-input ref="planCode" class="add-plan-input" v-model:value="addPlanData['planCode']" placeholder="请输入预案编号" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="add-plan-item">
|
||||
<div class="plan-label">预案类别</div>
|
||||
<div class="plan-content">
|
||||
<a-select
|
||||
ref="planCategory"
|
||||
class="add-plan-select"
|
||||
popupClassName="add-plan-popup-select"
|
||||
v-model:value="addPlanData['planCategory']"
|
||||
|
|
@ -75,25 +76,26 @@
|
|||
<div class="add-plan-item">
|
||||
<div class="plan-label">管理级别</div>
|
||||
<div class="plan-content">
|
||||
<a-input class="add-plan-input" v-model:value="addPlanData['admLevel']" placeholder="请输入管理级别" />
|
||||
<a-input ref="admLevel" class="add-plan-input" v-model:value="addPlanData['admLevel']" placeholder="请输入管理级别" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="add-plan-item">
|
||||
<div class="plan-label">描述</div>
|
||||
<div class="plan-content">
|
||||
<a-input class="add-plan-input" v-model:value="addPlanData['description']" placeholder="请输入描述" />
|
||||
<a-input ref="description" class="add-plan-input" v-model:value="addPlanData['description']" placeholder="请输入描述" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="add-plan-item">
|
||||
<div class="plan-label">内容</div>
|
||||
<div class="plan-content">
|
||||
<a-input class="add-plan-input" v-model:value="addPlanData['content']" placeholder="请输入内容" />
|
||||
<a-input ref="content" class="add-plan-input" v-model:value="addPlanData['content']" placeholder="请输入内容" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="add-plan-item">
|
||||
<div class="plan-label">状态</div>
|
||||
<div class="plan-content">
|
||||
<a-select
|
||||
ref="status"
|
||||
class="add-plan-select"
|
||||
popupClassName="add-plan-popup-select"
|
||||
v-model:value="addPlanData['status']"
|
||||
|
|
@ -106,13 +108,14 @@
|
|||
<div class="add-plan-item">
|
||||
<div class="plan-label">写入单元</div>
|
||||
<div class="plan-content">
|
||||
<a-input class="add-plan-input" v-model:value="addPlanData['writeUnit']" placeholder="请输入写入单元" />
|
||||
<a-input ref="writeUnit" class="add-plan-input" v-model:value="addPlanData['writeUnit']" placeholder="请输入写入单元" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="add-plan-item">
|
||||
<div class="plan-label">生效日期</div>
|
||||
<div class="plan-content">
|
||||
<a-date-picker
|
||||
ref="effectiveDate"
|
||||
v-model:value="addPlanData['effectiveDate']"
|
||||
class="add-plan-date-picker"
|
||||
popupClassName="add-plan-date-picker-popup"
|
||||
|
|
@ -125,6 +128,7 @@
|
|||
<div class="plan-label">到期日期</div>
|
||||
<div class="plan-content">
|
||||
<a-date-picker
|
||||
ref="expiry_date"
|
||||
v-model:value="addPlanData['expiry_date']"
|
||||
class="add-plan-date-picker"
|
||||
popupClassName="add-plan-date-picker-popup"
|
||||
|
|
@ -136,13 +140,13 @@
|
|||
<div class="add-plan-item">
|
||||
<div class="plan-label">负责人</div>
|
||||
<div class="plan-content">
|
||||
<a-input class="add-plan-input" v-model:value="addPlanData['responsiblePerson']" placeholder="请输入负责人" />
|
||||
<a-input ref="responsiblePerson" class="add-plan-input" v-model:value="addPlanData['responsiblePerson']" placeholder="请输入负责人" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="add-plan-item">
|
||||
<div class="plan-label">联系方式</div>
|
||||
<div class="plan-content">
|
||||
<a-input class="add-plan-input" v-model:value="addPlanData['contact']" placeholder="联系方式" />
|
||||
<a-input ref="contact" class="add-plan-input" v-model:value="addPlanData['contact']" placeholder="联系方式" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="add-plan-item">
|
||||
|
|
@ -156,6 +160,9 @@
|
|||
<a-button class="add-plan-button">上传附件</a-button>
|
||||
</a-upload>
|
||||
</div>
|
||||
<div class="add-plan-item">
|
||||
<a-button ref="geom" class="add-plan-button" @click="getGeom()">设置预案范围</a-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="add-plan-footer">
|
||||
<div class="save-button" @click="save">保存</div>
|
||||
|
|
@ -178,6 +185,11 @@
|
|||
import { message } from 'ant-design-vue';
|
||||
import { uploadFile } from '@/api/demo/files'
|
||||
import { getAppEnvConfig } from '@/utils/env'
|
||||
import { point, polygon as trfPolygon } from '@turf/helpers';
|
||||
import { WktToGeojson, GeojsonToWkt } from '@/views/demo/layer/geometryHandler';
|
||||
import { contingencyPlanStore } from '@/store/modules/contingencyplan';
|
||||
|
||||
const contingencyPlanStoreVal = contingencyPlanStore();
|
||||
const chartEditStore = useChartEditStore();
|
||||
let { VITE_GLOB_API_URL } = getAppEnvConfig();
|
||||
const props = defineProps({
|
||||
|
|
@ -210,21 +222,38 @@
|
|||
{ label: '负责人', key: 'responsiblePerson' },
|
||||
{ label: '联系方式', key: 'contact' },
|
||||
]
|
||||
const planName = ref(null)
|
||||
const planCode = ref(null)
|
||||
const planCategory = ref(null)
|
||||
const admLevel = ref(null)
|
||||
const description = ref(null)
|
||||
const content = ref(null)
|
||||
const status = ref(null)
|
||||
const writeUnit = ref(null)
|
||||
const effectiveDate = ref(null)
|
||||
const expiry_date = ref(null)
|
||||
const responsiblePerson = ref(null)
|
||||
const contact = ref(null)
|
||||
const geom = ref(null)
|
||||
const addPlanItemList = [
|
||||
{ label: '预案名称', key: 'planName' },
|
||||
{ label: '预案编号', key: 'planCode' },
|
||||
{ label: '预案类别', key: 'planCategory' },
|
||||
{ label: '管理级别', key: 'admLevel' },
|
||||
{ label: '描述', key: 'description' },
|
||||
{ label: '内容', key: 'content' },
|
||||
{ label: '状态', key: 'status' },
|
||||
{ label: '写入单元', key: 'writeUnit' },
|
||||
{ label: '生效日期', key: 'effectiveDate' },
|
||||
{ label: '到期日期', key: 'expiry_date' },
|
||||
{ label: '负责人', key: 'responsiblePerson' },
|
||||
{ label: '联系方式', key: 'contact' },
|
||||
{ label: '预案名称', key: 'planName', dom: planName },
|
||||
{ label: '预案编号', key: 'planCode', dom: planCode },
|
||||
{ label: '预案类别', key: 'planCategory', dom: planCategory },
|
||||
{ label: '管理级别', key: 'admLevel', dom: admLevel },
|
||||
{ label: '描述', key: 'description', dom: description },
|
||||
{ label: '内容', key: 'content', dom: content },
|
||||
{ label: '状态', key: 'status', dom: status },
|
||||
{ label: '写入单元', key: 'writeUnit', dom: writeUnit },
|
||||
{ label: '生效日期', key: 'effectiveDate', dom: effectiveDate },
|
||||
{ label: '到期日期', key: 'expiry_date', dom: expiry_date },
|
||||
{ label: '负责人', key: 'responsiblePerson', dom: responsiblePerson },
|
||||
{ label: '联系方式', key: 'contact', dom: contact },
|
||||
{ label: '预案范围', key: 'geom', dom: geom },
|
||||
]
|
||||
let geojsonLayer: mars3d.layer.GeoJsonLayer
|
||||
let drawLayer;
|
||||
let graphic;
|
||||
const lastGraphics = ref<any>([])
|
||||
const { w, h } = toRefs(props.chartConfig.attr);
|
||||
const {
|
||||
dataset,
|
||||
|
|
@ -264,14 +293,10 @@
|
|||
})
|
||||
});
|
||||
const showInfo = async (item) => {
|
||||
if(!geojsonLayer){
|
||||
geojsonLayer = new mars3d.layer.GeoJsonLayer({
|
||||
name: 'fire-plan-layer',
|
||||
clampToGround: true
|
||||
})
|
||||
window.globalMap.addLayer(geojsonLayer);
|
||||
if(!contingencyPlanStoreVal.getLayer()){
|
||||
contingencyPlanStoreVal.setLayer()
|
||||
}else{
|
||||
geojsonLayer.clear()
|
||||
contingencyPlanStoreVal.clearData()
|
||||
}
|
||||
if(item.attachment){
|
||||
const res = await fetch(`${VITE_GLOB_API_URL}/${item.attachment}`)
|
||||
|
|
@ -280,12 +305,7 @@
|
|||
return
|
||||
}
|
||||
const data = await res.json()
|
||||
geojsonLayer.load({
|
||||
data: data
|
||||
})
|
||||
geojsonLayer.flyTo({
|
||||
scale: 1.5
|
||||
})
|
||||
contingencyPlanStoreVal.reloadData(data)
|
||||
}
|
||||
EventBus.emit('ContingencyPlanListToContingencyPlanInfo',item)
|
||||
}
|
||||
|
|
@ -299,6 +319,10 @@
|
|||
}
|
||||
const closeAddPlan = () => {
|
||||
addPlanDiv.value = false
|
||||
lastGraphics.value.forEach(item => {
|
||||
drawLayer && drawLayer.removeGraphic(item)
|
||||
})
|
||||
drawLayer && drawLayer.stopDraw()
|
||||
}
|
||||
const query = () => {
|
||||
let params = {
|
||||
|
|
@ -312,11 +336,33 @@
|
|||
}
|
||||
const save = () => {
|
||||
let isCheck = true
|
||||
addPlanData.value.geom = addAndUpdateWorkArea()
|
||||
addPlanItemList.forEach(item => {
|
||||
if(!(addPlanData.value[item.key])){
|
||||
isCheck = false
|
||||
message.warning(`${item.label}为空!`)
|
||||
return
|
||||
if(['planCategory', 'status'].includes(item.key)){
|
||||
const el = item.dom?.value?.$el
|
||||
const selector = el.querySelector('.ant-select-selector')
|
||||
selector.style.borderColor = '#ff3939'
|
||||
}else if(item.key == 'geom'){
|
||||
const el = item.dom?.value?.$el
|
||||
el.style.background = '#ff3939'
|
||||
}else{
|
||||
const el = item.dom?.value?.$el
|
||||
el.style.borderColor = '#ff3939'
|
||||
}
|
||||
}else{
|
||||
if(['planCategory', 'status'].includes(item.key)){
|
||||
const el = item.dom?.value?.$el
|
||||
const selector = el.querySelector('.ant-select-selector')
|
||||
selector.style.borderColor = '#00611A'
|
||||
}else if(item.key == 'geom'){
|
||||
const el = item.dom?.value?.$el
|
||||
el.style.background = '#00611A'
|
||||
}else{
|
||||
const el = item.dom?.value?.$el
|
||||
el.style.borderColor = '#00611A'
|
||||
}
|
||||
}
|
||||
})
|
||||
if(isCheck){
|
||||
|
|
@ -328,6 +374,10 @@
|
|||
message.success('预案添加成功')
|
||||
query()
|
||||
addPlanDiv.value = false
|
||||
lastGraphics.value.forEach(item => {
|
||||
drawLayer && drawLayer.removeGraphic(item)
|
||||
})
|
||||
drawLayer && drawLayer.stopDraw()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -358,6 +408,46 @@
|
|||
fileList.value = resFileList;
|
||||
})
|
||||
}
|
||||
const getGeom = async () => {
|
||||
lastGraphics.value.forEach(item => {
|
||||
drawLayer && drawLayer.removeGraphic(item)
|
||||
})
|
||||
if(!drawLayer){
|
||||
drawLayer = new mars3d.layer.GraphicLayer({
|
||||
isAutoEditing: true,
|
||||
});
|
||||
window.globalMap.addLayer(drawLayer)
|
||||
}
|
||||
graphic = await drawLayer.startDraw({
|
||||
type: 'polygon',
|
||||
style: {
|
||||
color: "#00B569",
|
||||
opacity: 0.2,
|
||||
outline: true,
|
||||
outlineColor: "#00B569",
|
||||
outlineWidth: 2,
|
||||
},
|
||||
});
|
||||
lastGraphics.value.push(graphic)
|
||||
console.log('draw',graphic)
|
||||
}
|
||||
function addAndUpdateWorkArea(addOrUpdate = 'add') {
|
||||
if(!graphic){
|
||||
return ''
|
||||
}
|
||||
let graphicJson = graphic.toJSON();
|
||||
let coordinates = graphicJson.position || graphicJson.positions;
|
||||
let polygonData: any = [];
|
||||
let geom = '';
|
||||
coordinates.push(coordinates[0]);
|
||||
if (addOrUpdate == 'add') {
|
||||
polygonData.push(coordinates);
|
||||
} else {
|
||||
polygonData = coordinates;
|
||||
}
|
||||
geom = GeojsonToWkt(trfPolygon(polygonData).geometry);
|
||||
return geom
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
/>
|
||||
<span class="text">{{ Weather }} °C</span>
|
||||
</div>
|
||||
<div class="wind-speed">
|
||||
<span style="margin-right: 25px;">{{`风速:${windPower}m/s`}}</span>{{`风向: ${winddirection}`}}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
@ -38,6 +40,8 @@
|
|||
|
||||
const currentTime = ref(dayjs().locale('zh-cn').format('YYYY年M月D日 dddd HH:mm:ss'));
|
||||
const Weather = ref('');
|
||||
const windPower = ref()
|
||||
const winddirection = ref()
|
||||
async function getWeather() {
|
||||
try {
|
||||
//高德天气查询
|
||||
|
|
@ -46,6 +50,8 @@
|
|||
url: `https://restapi.amap.com/v3/weather/weatherInfo?city=371300&key=ae4fb485fa25f5884b9cd7c1101687c4`,
|
||||
}).then((res) => {
|
||||
Weather.value = res.data.lives[0].temperature;
|
||||
windPower.value = res.data.lives[0].windpower;
|
||||
winddirection.value = res.data.lives[0].winddirection;
|
||||
if(res.data.lives[0].weather == '阴'){
|
||||
weatherIcon.value = "wi:cloud"
|
||||
}else if(res.data.lives[0].weather == '晴'){
|
||||
|
|
@ -116,5 +122,15 @@
|
|||
font-size: v-bind('textSize+"px"');
|
||||
}
|
||||
}
|
||||
.wind-speed{
|
||||
position: absolute;
|
||||
top: 45px;
|
||||
left: 30px;
|
||||
width: 400px;
|
||||
height: 42px;
|
||||
margin-left: 10px;
|
||||
color: v-bind('textColor');
|
||||
font-size: v-bind('textSize+"px"');
|
||||
}
|
||||
</style>
|
||||
|
||||
|
|
@ -113,7 +113,7 @@
|
|||
}, 5000);
|
||||
});
|
||||
|
||||
// <<<<<<< HEAD
|
||||
//
|
||||
// const navsClick = function(item,index){
|
||||
// navsIndex.value = index
|
||||
// props.chartConfig.request.requestSQLContent.sql = item.sql
|
||||
|
|
|
|||
|
|
@ -20,6 +20,9 @@
|
|||
import { option as configOption } from './config';
|
||||
import { eventHandlerHook } from '@/hooks/eventHandler.hook';
|
||||
import { EventBus } from '@/utils/eventBus';
|
||||
import { contingencyPlanStore } from '@/store/modules/contingencyplan';
|
||||
|
||||
const contingencyPlanStoreVal = contingencyPlanStore();
|
||||
|
||||
const chartEditStore = useChartEditStore();
|
||||
const props = defineProps({
|
||||
|
|
@ -58,6 +61,7 @@
|
|||
'click',
|
||||
val,
|
||||
);
|
||||
contingencyPlanStoreVal.clearData()
|
||||
};
|
||||
const dblclickBtn = (val) => {
|
||||
eventHandlerHook(
|
||||
|
|
|
|||
|
|
@ -425,6 +425,10 @@
|
|||
import {drcDownTopicReize,eventsTopicSubscribeReize,servicesTopicReize,services_replyTopicReize,} from '@/utils/debugging/events';
|
||||
import {getRedisUser,addOrUpdateRedisUser,getLockedClients,getTsgzProjectId,applyDroneControl} from '@/api/demo/airportMaintenance';
|
||||
import { airPortStore } from '@/store/modules/airport';
|
||||
import { LoadClueInfoByLngLat } from '@/api/demo/contingencyplan'
|
||||
import { contingencyPlanStore } from '@/store/modules/contingencyplan';
|
||||
|
||||
const contingencyPlanStoreVal = contingencyPlanStore();
|
||||
|
||||
const airPortStoreVal = airPortStore();
|
||||
|
||||
|
|
@ -1682,6 +1686,24 @@
|
|||
|
||||
hikversionShow.value = false;
|
||||
changeButton("应急响应")
|
||||
let params = {
|
||||
lng: clueInfo.value.lng,
|
||||
lat: clueInfo.value.lat,
|
||||
}
|
||||
LoadClueInfoByLngLat(params).then(async res => {
|
||||
if(res.length > 0){
|
||||
let resultData = res[0]
|
||||
if(resultData.Attachment){
|
||||
const res = await fetch(`${VITE_GLOB_API_URL}/${resultData.Attachment}`)
|
||||
if (!res.ok) {
|
||||
console.error('下载失败', res.status)
|
||||
return
|
||||
}
|
||||
const data = await res.json()
|
||||
contingencyPlanStoreVal.reloadData(data)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const changeButton = (type) => {
|
||||
|
|
|
|||
|
|
@ -68,6 +68,11 @@ const goflyaddress=(e)=>{
|
|||
})
|
||||
entityArr.value = []
|
||||
}
|
||||
if(e.state == '离线'){
|
||||
return message.warning('当前人员离线')
|
||||
}else if(e.lng == null || e.lat == null || e.lng == 0 || e.lat == 0){
|
||||
return message.warning('人员位置异常')
|
||||
}
|
||||
handlerAddEntity(e)
|
||||
}
|
||||
// 添加Entity
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
import { defineStore } from 'pinia';
|
||||
import { getAppEnvConfig } from '@/utils/env';
|
||||
const { VITE_GLOB_APP_RTMP_URL, VITE_GLOB_APP_FLV_URL, VITE_GLOB_SRS_API_URL } = getAppEnvConfig();
|
||||
|
||||
export const airPortStore = defineStore({
|
||||
id: 'airport',
|
||||
|
|
@ -17,8 +19,11 @@ export const airPortStore = defineStore({
|
|||
video_id: null,
|
||||
},
|
||||
liveInfo: {
|
||||
rtmp: 'rtmp://wrj.wisestcity.com:6019/live/',
|
||||
url: 'https://wrj.wisestcity.com:6012/live/',
|
||||
rtmp: `${VITE_GLOB_APP_RTMP_URL}/live/`,
|
||||
url: `${VITE_GLOB_APP_FLV_URL}/live/`,
|
||||
getUrl: `${VITE_GLOB_SRS_API_URL}/`,
|
||||
// rtmp: 'rtmp://175.27.168.120:6019/live/',
|
||||
// url: 'http://175.27.168.120:6012/live/',
|
||||
// rtmp: 'rtmp://box.wisestcity.com:1935/live/',
|
||||
// url: 'http://box.wisestcity.com:8081/live/',
|
||||
// rtmp: 'http://wrj.wisestcity.com:5005/rtc/v1/whip/?app=live&stream=',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
import { defineStore } from 'pinia';
|
||||
import * as mars3d from 'mars3d';
|
||||
|
||||
interface ContingencyPlanState {
|
||||
contingencyPlanLayer: mars3d.layer.GeoJsonLayer | null
|
||||
}
|
||||
export const contingencyPlanStore = defineStore({
|
||||
id: 'contingencyPlan',
|
||||
state: ():ContingencyPlanState => ({
|
||||
contingencyPlanLayer: null,
|
||||
}),
|
||||
actions: {
|
||||
setLayer() {
|
||||
this.contingencyPlanLayer = new mars3d.layer.GeoJsonLayer({
|
||||
name: 'fire-plan-layer',
|
||||
clampToGround: true
|
||||
})
|
||||
window.globalMap.addLayer(this.contingencyPlanLayer);
|
||||
},
|
||||
clearData(){
|
||||
this.contingencyPlanLayer?.clear()
|
||||
},
|
||||
reloadData(data){
|
||||
this.contingencyPlanLayer?.load({
|
||||
data: data
|
||||
})
|
||||
this.contingencyPlanLayer?.flyTo({
|
||||
scale: 1.5
|
||||
})
|
||||
},
|
||||
getLayer(){
|
||||
return this.contingencyPlanLayer
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
@ -40,6 +40,11 @@ export function getAppEnvConfig() {
|
|||
VITE_GLOB_APP_TECHINICAL_SUPPORT,
|
||||
VITE_GLOB_APP_VERSIONS,
|
||||
VITE_GLOB_API_URL_SITUATION,
|
||||
VITE_GLOB_MQTT_URL,
|
||||
VITE_GLOB_MQTT_PORT,
|
||||
VITE_GLOB_APP_RTMP_URL,
|
||||
VITE_GLOB_APP_FLV_URL,
|
||||
VITE_GLOB_SRS_API_URL,
|
||||
VITE_GLOB_FILE_PREVIEW,
|
||||
VITE_GLOB_GEOSERVER_BASE_URL,
|
||||
VITE_GLOB_COFFEE_API_URL,
|
||||
|
|
@ -63,6 +68,11 @@ export function getAppEnvConfig() {
|
|||
VITE_GLOB_FILE_PREVIEW,
|
||||
VITE_GLOB_GEOSERVER_BASE_URL,
|
||||
VITE_GLOB_COFFEE_API_URL,
|
||||
VITE_GLOB_MQTT_URL,
|
||||
VITE_GLOB_MQTT_PORT,
|
||||
VITE_GLOB_APP_RTMP_URL,
|
||||
VITE_GLOB_APP_FLV_URL,
|
||||
VITE_GLOB_SRS_API_URL,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ import { useMessage } from '@/hooks/web/useMessage';
|
|||
import { getRedisUser, addOrUpdateRedisUser } from '@/api/demo/airportMaintenance';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import { timestampToFormattedDate } from '@/utils/index';
|
||||
import { getAppEnvConfig } from '@/utils/env';
|
||||
const { VITE_GLOB_MQTT_URL, VITE_GLOB_MQTT_PORT } = getAppEnvConfig();
|
||||
|
||||
const userStore = useUserStore();
|
||||
const userInfo = userStore.getUserInfo;
|
||||
|
|
@ -12,9 +14,9 @@ const { createMessage } = useMessage();
|
|||
const seizeClientId = 'mqtt_client_1581F8HGX254V00A0BUY_seize';
|
||||
const connection = {
|
||||
protocol: 'ws',
|
||||
host: 'wrj.wisestcity.com',
|
||||
host: VITE_GLOB_MQTT_URL,
|
||||
// server less服务器只有两种协议:mqtts: 8883; wss: 8084
|
||||
port: 6010,
|
||||
port: VITE_GLOB_MQTT_PORT,
|
||||
endpoint: '/mqtt',
|
||||
// for more options, please refer to https://github.com/mqttjs/MQTT.js#mqttclientstreambuilder-options
|
||||
clean: true,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ export const columns: BasicColumn[] = [
|
|||
{
|
||||
title: '审核状态',
|
||||
dataIndex: 'state',
|
||||
width: 80,
|
||||
width: 90,
|
||||
customRender: ({ record }) => {
|
||||
const status = record.state;
|
||||
let color = '';
|
||||
|
|
@ -36,10 +36,12 @@ export const columns: BasicColumn[] = [
|
|||
{
|
||||
title: '负责人',
|
||||
dataIndex: 'director',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: '负责人电话',
|
||||
dataIndex: 'phone',
|
||||
width: 130,
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -1,35 +1,17 @@
|
|||
<template>
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" :title="getTitle" @ok="handleSubmit">
|
||||
<BasicModal v-bind="$attrs" @register="registerModal" title='编辑' @ok="handleSubmit">
|
||||
<BasicForm @register="registerForm">
|
||||
<template #areaId="{ model, field }">
|
||||
<a-tree-select
|
||||
show-search
|
||||
style="width: 100%"
|
||||
v-model:value="model[field]"
|
||||
:tree-data="treeData"
|
||||
:field-names="{ label: 'name', value: 'id' }"
|
||||
placeholder="请选择"
|
||||
allow-clear
|
||||
multiple
|
||||
/>
|
||||
</template>
|
||||
<template #time="{ model, field }">
|
||||
<div>
|
||||
<div class="flex mt-1" v-for="(item, index) in timeslot" :key="index">
|
||||
<a-time-picker
|
||||
placeholder="开始时间"
|
||||
@change="(time, timeString) => beginTimeChange(time, timeString, index)"
|
||||
v-model:value="item.beginTime"
|
||||
v-model:value="timeSlot.beginTime"
|
||||
/>
|
||||
~
|
||||
<a-time-picker
|
||||
placeholder="结束时间"
|
||||
@change="(time, timeString) => endTimeChange(time, timeString, index)"
|
||||
v-model:value="item.endTime"
|
||||
v-model:value="timeSlot.endTime"
|
||||
/>
|
||||
<CloseCircleOutlined style="margin-left: 10px" @click="delTime(index)" />
|
||||
</div>
|
||||
<a-button type="primary" style="margin-top: 10px" @click="addTime">添加打开时间</a-button>
|
||||
</div>
|
||||
</template>
|
||||
</BasicForm>
|
||||
|
|
@ -43,16 +25,19 @@
|
|||
import { CloseCircleOutlined } from '@ant-design/icons-vue';
|
||||
import { addRole, updateRole, getDeptList } from '@/api/demo/system';
|
||||
import { useMessage } from '@/hooks/web/useMessage';
|
||||
import moment from 'moment';
|
||||
import dayjs from 'dayjs';
|
||||
import { AddOrUpdateTimeSolt } from '@/api/demo/forestranger'
|
||||
import { message } from 'ant-design-vue';
|
||||
|
||||
const { createMessage } = useMessage();
|
||||
const treeData: any = ref([]);
|
||||
const timeslot: any = ref([]);
|
||||
const timeList: any = ref([]);
|
||||
const timeSlot: any = ref({
|
||||
beginTime: '',
|
||||
endTime: '',
|
||||
});
|
||||
const updateData = ref({})
|
||||
defineOptions({ name: 'DeptModal' });
|
||||
|
||||
onMounted(() => {
|
||||
getTreeList();
|
||||
});
|
||||
const emit = defineEmits(['success', 'register']);
|
||||
|
||||
|
|
@ -66,74 +51,53 @@
|
|||
});
|
||||
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
isUpdate.value = data.isUpdate
|
||||
updateData.value = data.data
|
||||
resetFields();
|
||||
setModalProps({ confirmLoading: false });
|
||||
isUpdate.value = !!data?.isUpdate;
|
||||
|
||||
if (unref(isUpdate)) {
|
||||
setFieldsValue({
|
||||
...data.record,
|
||||
});
|
||||
setFieldsValue({
|
||||
...data.data,
|
||||
});
|
||||
if(data.data.timeSlotData){
|
||||
let timeSlotList = data.data.timeSlotData.timeSlot.split('-')
|
||||
timeSlot.value.beginTime = dayjs(timeSlotList[0], 'HH:mm:ss')
|
||||
timeSlot.value.endTime = dayjs(timeSlotList[1], 'HH:mm:ss')
|
||||
}else{
|
||||
timeSlot.value.beginTime = null
|
||||
timeSlot.value.endTime = null
|
||||
}
|
||||
});
|
||||
|
||||
const getTitle = computed(() => (!unref(isUpdate) ? '新增角色' : '编辑角色'));
|
||||
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
const values = await validate();
|
||||
let query = values;
|
||||
// 调用接口
|
||||
if (!unref(isUpdate)) {
|
||||
const data = await addRole(query);
|
||||
if (data) {
|
||||
setModalProps({ confirmLoading: true });
|
||||
// TODO custom api
|
||||
closeModal();
|
||||
emit('success');
|
||||
return createMessage.success('新增成功');
|
||||
} else {
|
||||
return createMessage.error('新增失败');
|
||||
console.log('values',values)
|
||||
console.log('updateData.value',updateData.value)
|
||||
let query
|
||||
if(isUpdate.value){
|
||||
query = {
|
||||
id: updateData.value.timeSlotData.id,
|
||||
createId: updateData.value.id,
|
||||
timeSlot: `${dayjs(timeSlot.value.beginTime).format('HH:mm:ss')}-${dayjs(timeSlot.value.endTime).format('HH:mm:ss')}`
|
||||
}
|
||||
}else{
|
||||
query = {
|
||||
createId: updateData.value.id,
|
||||
timeSlot: `${dayjs(timeSlot.value.beginTime).format('HH:mm:ss')}-${dayjs(timeSlot.value.endTime).format('HH:mm:ss')}`
|
||||
}
|
||||
}
|
||||
const data = await AddOrUpdateTimeSolt(query);
|
||||
if (data) {
|
||||
setModalProps({ confirmLoading: true });
|
||||
closeModal();
|
||||
emit('success');
|
||||
return createMessage.success('编辑成功');
|
||||
} else {
|
||||
const data = await updateRole(query);
|
||||
if (data) {
|
||||
setModalProps({ confirmLoading: true });
|
||||
// TODO custom api
|
||||
closeModal();
|
||||
emit('success');
|
||||
return createMessage.success('编辑成功');
|
||||
} else {
|
||||
return createMessage.error('编辑失败');
|
||||
}
|
||||
return createMessage.error('编辑失败');
|
||||
}
|
||||
} finally {
|
||||
setModalProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
const getTreeList = async () => {
|
||||
getDeptList().then((res) => {
|
||||
treeData.value = res;
|
||||
});
|
||||
};
|
||||
const delTime = (index) => {
|
||||
timeslot.value.splice(index, 1);
|
||||
timeList.value.splice(index, 1);
|
||||
};
|
||||
const addTime = () => {
|
||||
timeslot.value.push({
|
||||
beginTime: '',
|
||||
endTime: '',
|
||||
});
|
||||
timeList.value.push({
|
||||
beginTime: '',
|
||||
endTime: '',
|
||||
});
|
||||
};
|
||||
const beginTimeChange = (time, timeString, index) => {
|
||||
timeList.value[index].beginTime = timeString;
|
||||
};
|
||||
const endTimeChange = (time, timeString, index) => {
|
||||
timeList.value[index].endTime = timeString;
|
||||
};
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -41,40 +41,19 @@ export const formSchema: FormSchema[] = [
|
|||
{
|
||||
field: 'name',
|
||||
label: '人员姓名',
|
||||
required: true,
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
disabled: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'account',
|
||||
label: '账号/手机号',
|
||||
required: true,
|
||||
component: 'Input',
|
||||
},
|
||||
{
|
||||
field: 'sex',
|
||||
component: 'RadioGroup',
|
||||
label: '人员性别',
|
||||
colProps: {
|
||||
span: 8,
|
||||
},
|
||||
componentProps: {
|
||||
options: [
|
||||
{
|
||||
label: '男',
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
label: '女',
|
||||
value: 1,
|
||||
},
|
||||
],
|
||||
disabled: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'areaId',
|
||||
label: '所属机构',
|
||||
slot: 'areaId',
|
||||
},
|
||||
{
|
||||
field: 'time',
|
||||
label: '打卡时间',
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
import { BasicTable, useTable } from '@/components/Table';
|
||||
import { getRoleListByPage, deleteRole } from '@/api/demo/system';
|
||||
import { LoadTimeSoltByUserId } from '@/api/demo/forestranger'
|
||||
|
||||
import { useMessage } from '@/hooks/web/useMessage';
|
||||
import { useModal } from '@/components/Modal';
|
||||
|
|
@ -72,15 +73,23 @@
|
|||
});
|
||||
}
|
||||
|
||||
function handleEdit() {
|
||||
async function handleEdit() {
|
||||
let rows = getSelectRows();
|
||||
if (rows.length == 0) {
|
||||
return createMessage.warn('请勾选一个角色进行编辑');
|
||||
}
|
||||
const record = rows[0];
|
||||
let params = {
|
||||
id: record.id
|
||||
}
|
||||
let result = await LoadTimeSoltByUserId(params)
|
||||
let data = {
|
||||
...record,
|
||||
timeSlotData: result
|
||||
}
|
||||
openRoleModal(true, {
|
||||
record,
|
||||
isUpdate: true,
|
||||
data,
|
||||
isUpdate: result? true: false,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@
|
|||
/>
|
||||
<div class="form-button">
|
||||
<a-button type="primary" @click="getTaskList">查询</a-button>
|
||||
<a-button type="primary" @click="toStatic">统计</a-button>
|
||||
<a-button type="primary" @click="toInspection">巡检</a-button>
|
||||
<!-- <a-button type="primary" @click="toStatic">统计</a-button>
|
||||
<a-button type="primary" @click="toInspection">巡检</a-button> -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-data">
|
||||
|
|
|
|||
|
|
@ -11,26 +11,17 @@
|
|||
<a-divider orientation="left">打卡点信息</a-divider>
|
||||
<a-descriptions class="margin-top" :column="1" :size="'mini'" border>
|
||||
<a-descriptions-item>
|
||||
<template v-slot:label>
|
||||
<BankOutlined />
|
||||
打卡点名称
|
||||
</template>
|
||||
{{ itemData.pointname }}
|
||||
<BankOutlined style="margin-right: 20px;"/>
|
||||
<span style="color: rgba(0,0,0,0.6);">{{ itemData.pointname }}</span>
|
||||
</a-descriptions-item>
|
||||
|
||||
<a-descriptions-item>
|
||||
<template v-slot:label>
|
||||
<HistoryOutlined />
|
||||
创建时间
|
||||
</template>
|
||||
{{ itemData.createtime }}
|
||||
<HistoryOutlined style="margin-right: 20px;"/>
|
||||
<span style="color: rgba(0,0,0,0.6);">{{ itemData.createtime }}</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item>
|
||||
<template v-slot:label>
|
||||
<EnvironmentOutlined />
|
||||
打卡点位置
|
||||
</template>
|
||||
{{ itemData.lng }},{{ itemData.lat }}
|
||||
<EnvironmentOutlined style="margin-right: 20px;"/>
|
||||
<span style="color: rgba(0,0,0,0.6);">{{ itemData.lng }}, {{ itemData.lat }}</span>
|
||||
<!-- <el-button type="primary" size="mini" round icon="el-icon-location-outline" @click="lookClockInfo(currentClockInfo)">定位</el-button> -->
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@
|
|||
import { useMessage } from '@/hooks/web/useMessage';
|
||||
import { getPatrolPointByTimeSubsection } from '@/api/firegrid/patrol';
|
||||
import { getDeptList } from '@/api/demo/system';
|
||||
import { message } from 'ant-design-vue';
|
||||
|
||||
const { createMessage } = useMessage();
|
||||
defineOptions({ name: 'DeptModal' });
|
||||
|
|
@ -92,7 +93,8 @@
|
|||
// 表格名称
|
||||
title: '巡检列表',
|
||||
// 获取数据的接口
|
||||
dataSource: [],
|
||||
api: getPointUserOnLine,
|
||||
// dataSource: [],
|
||||
// 表单列信息 BasicColumn[]
|
||||
columns: InspectionColumns,
|
||||
rowKey: 'id',
|
||||
|
|
@ -108,6 +110,17 @@
|
|||
handleSearchInfoFn(info) {
|
||||
return info;
|
||||
},
|
||||
beforeFetch: (params) => {
|
||||
return {
|
||||
...params,
|
||||
...formState
|
||||
}
|
||||
},
|
||||
afterFetch: (data) => {
|
||||
onlineInfo.online = data.online;
|
||||
onlineInfo.offline = data.offline;
|
||||
return data.userinfo
|
||||
},
|
||||
actionColumn: {
|
||||
width: 120,
|
||||
title: '操作',
|
||||
|
|
@ -117,6 +130,11 @@
|
|||
},
|
||||
});
|
||||
const toPosition = (row) => {
|
||||
if(row.state == '离线'){
|
||||
return message.warning('当前人员离线')
|
||||
}else if(row.lng == null || row.lat == null || row.lng == 0 || row.lat == 0){
|
||||
return message.warning('人员位置异常')
|
||||
}
|
||||
const lnglat = [row.lng, row.lat];
|
||||
EventBus.emit('inspectionMoldeMap', lnglat);
|
||||
};
|
||||
|
|
@ -185,18 +203,17 @@
|
|||
}
|
||||
const formState: FormState = reactive({
|
||||
isonline: '全部',
|
||||
page: 1,
|
||||
limit: 10,
|
||||
});
|
||||
const getLine = () => {
|
||||
getPointUserOnLine(formState).then((res) => {
|
||||
res.items.userinfo.forEach((item) => {
|
||||
item.onLineTime = friendlyDate(item.onLineTime);
|
||||
});
|
||||
onlineInfo.online = res.items.online;
|
||||
onlineInfo.offline = res.items.offline;
|
||||
setTableData(res.items.userinfo);
|
||||
});
|
||||
reload()
|
||||
// getPointUserOnLine(formState).then((res) => {
|
||||
// res.items.userinfo.forEach((item) => {
|
||||
// item.onLineTime = friendlyDate(item.onLineTime);
|
||||
// });
|
||||
// onlineInfo.online = res.items.online;
|
||||
// onlineInfo.offline = res.items.offline;
|
||||
// setTableData(res.items.userinfo);
|
||||
// });
|
||||
};
|
||||
const friendlyDate = (time) => {
|
||||
if (time > 60) {
|
||||
|
|
@ -206,7 +223,7 @@
|
|||
}
|
||||
};
|
||||
onMounted(() => {
|
||||
getLine();
|
||||
// getLine();
|
||||
getTree();
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
</div>
|
||||
<div class="count-item-title"> 全部巡查总数 </div>
|
||||
<div class="count-item-value">
|
||||
{{ allData.xunchazongshu? allData.xunchazongshu.toFixed(4): 0 }} <span class="unit">千米</span>
|
||||
{{ allData.xunchazongshu? allData.xunchazongshu.toFixed(2): 0 }} <span class="unit">千米</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue