下发任务 修改任务处理
This commit is contained in:
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# 默认忽略的文件
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# 基于编辑器的 HTTP 客户端请求
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
12
.idea/dy_app.iml
generated
Normal file
12
.idea/dy_app.iml
generated
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/dy_app.iml" filepath="$PROJECT_DIR$/.idea/dy_app.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
35
src/api/collectPage.js
Normal file
35
src/api/collectPage.js
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import {service} from "@/utils/request";
|
||||||
|
const api = "/mosty-yjzl"
|
||||||
|
|
||||||
|
// 查询分页
|
||||||
|
export function getSelectPage(params) {
|
||||||
|
return service({
|
||||||
|
url: `${api}/tbZdxlFgdwBdd/selectPage`,
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增数据
|
||||||
|
export function addSaveData(data) {
|
||||||
|
return service({
|
||||||
|
url: `${api}/tbZdxlFgdwBdd/save`,
|
||||||
|
method: 'POST',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取方格列表
|
||||||
|
export function getSelectAllList(params) {
|
||||||
|
return service({
|
||||||
|
url: `${api}/tbZdxlFgdw/selectAllList`,
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取方格列表
|
||||||
|
export function getSelectList(params) {
|
||||||
|
return service({
|
||||||
|
url: `${api}/tbZdxlFgdw/selectList`,
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
18
src/api/patrolList.js
Normal file
18
src/api/patrolList.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import {service} from "@/utils/request";
|
||||||
|
const api = `/mosty-yjzl`
|
||||||
|
|
||||||
|
// 获取巡逻列表
|
||||||
|
export function fetchPatrolList(params) {
|
||||||
|
return service({
|
||||||
|
url: `${api}/tbZdxlFgxlrw/selectRwPage`,
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function fetchSelectListByBddxlrwId(params) {
|
||||||
|
return service({
|
||||||
|
url: `${api}/tbZdxlFgdwBddxlrwJl/selectListByBddxlrwId`,
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
BIN
src/assets/home/bddcj.png
Normal file
BIN
src/assets/home/bddcj.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.0 KiB |
@ -93,6 +93,7 @@ onMounted(() => {
|
|||||||
})
|
})
|
||||||
// zoomTarget.value = map.mapboxGLMap.getZoom();
|
// zoomTarget.value = map.mapboxGLMap.getZoom();
|
||||||
});
|
});
|
||||||
|
|
||||||
mapUtil.value = new MapUtil(map);
|
mapUtil.value = new MapUtil(map);
|
||||||
// mapUtil.value.Drawplot(); //初始化加载绘制工具
|
// mapUtil.value.Drawplot(); //初始化加载绘制工具
|
||||||
|
|
||||||
@ -106,7 +107,6 @@ onMounted(() => {
|
|||||||
// 撒点
|
// 撒点
|
||||||
emitter.on("addPointArea", (obj) => {
|
emitter.on("addPointArea", (obj) => {
|
||||||
console.log(obj,'obj');
|
console.log(obj,'obj');
|
||||||
|
|
||||||
mapUtil.value.makerSki(obj);
|
mapUtil.value.makerSki(obj);
|
||||||
});
|
});
|
||||||
// 鼠标滑过提示文字的点位
|
// 鼠标滑过提示文字的点位
|
||||||
@ -162,6 +162,7 @@ onMounted(() => {
|
|||||||
});
|
});
|
||||||
// 聚合撒点
|
// 聚合撒点
|
||||||
emitter.on("addPoint", (obj) => {
|
emitter.on("addPoint", (obj) => {
|
||||||
|
console.log(obj, 'obj');
|
||||||
mapUtil.value.aggregateScatteringPoint(obj);
|
mapUtil.value.aggregateScatteringPoint(obj);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -198,6 +199,12 @@ onMounted(() => {
|
|||||||
let coords = [centerPoint.lng, centerPoint.lat];
|
let coords = [centerPoint.lng, centerPoint.lat];
|
||||||
emitter.emit("getcentercoord", coords);
|
emitter.emit("getcentercoord", coords);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 获取点击经纬度
|
||||||
|
emitter.on("getMapClickCoordinates", (res) => {
|
||||||
|
mapUtil.value.enableClickEvents()
|
||||||
|
console.log(res)
|
||||||
|
})
|
||||||
});
|
});
|
||||||
//切换地图底图
|
//切换地图底图
|
||||||
const onMapImageChange = (val) => {
|
const onMapImageChange = (val) => {
|
||||||
@ -278,6 +285,7 @@ onUnmounted(() => {
|
|||||||
emitter.off("diffusionCircle");
|
emitter.off("diffusionCircle");
|
||||||
emitter.off("SsCircle");
|
emitter.off("SsCircle");
|
||||||
emitter.off("ClearssCircle");
|
emitter.off("ClearssCircle");
|
||||||
|
emitter.off("getMapClickCoordinates");
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import emitter from "@/utils/eventBus.js";
|
import emitter from "@/utils/eventBus.js";
|
||||||
|
|
||||||
export function MapUtil(map) {
|
export function MapUtil(map) {
|
||||||
let _that = this;
|
let _that = this;
|
||||||
_that.mMap = map; //地图对象
|
_that.mMap = map; //地图对象
|
||||||
_that.heatmapOverlay = {}; //热力图层对象
|
_that.heatmapOverlay = {}; //热力图层对象
|
||||||
_that.markerClusterers = null; //聚合图层对象
|
_that.markerClusterers = null; //聚合图层对象
|
||||||
_that.flagSircle = []; //自定义HTML
|
_that.flagSircle = []; //自定义HTML
|
||||||
@ -24,7 +24,7 @@ export function MapUtil(map) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 撒点.鼠标滑动展示内容
|
* 撒点.鼠标滑动展示内容
|
||||||
* @param {*} coords 坐标 geojson
|
* @param {*} coords 坐标 geojson
|
||||||
* @param {*} icon 图标
|
* @param {*} icon 图标
|
||||||
* @param {*} flag 标识
|
* @param {*} flag 标识
|
||||||
@ -44,7 +44,7 @@ export function MapUtil(map) {
|
|||||||
}
|
}
|
||||||
if(it.jd && it.wd) return obj;
|
if(it.jd && it.wd) return obj;
|
||||||
});
|
});
|
||||||
|
|
||||||
const point = map.createdPoint(pointList,{
|
const point = map.createdPoint(pointList,{
|
||||||
image:icon,//对应上面的图片名称
|
image:icon,//对应上面的图片名称
|
||||||
scale:0.6,
|
scale:0.6,
|
||||||
@ -69,7 +69,7 @@ export function MapUtil(map) {
|
|||||||
/**
|
/**
|
||||||
* 撒点
|
* 撒点
|
||||||
* @param {*} coords 坐标 geojson
|
* @param {*} coords 坐标 geojson
|
||||||
* @param {*} icon 图标
|
* @param {*} icon 图标
|
||||||
* @param {*} flag 标识
|
* @param {*} flag 标识
|
||||||
* @param {*} isBounds 点击图标是否变大方法
|
* @param {*} isBounds 点击图标是否变大方法
|
||||||
* @param {*} showTitle 是否展示标题
|
* @param {*} showTitle 是否展示标题
|
||||||
@ -77,8 +77,8 @@ export function MapUtil(map) {
|
|||||||
|
|
||||||
MapUtil.prototype.makerSki = (res) => {
|
MapUtil.prototype.makerSki = (res) => {
|
||||||
console.log(res,'resres');
|
console.log(res,'resres');
|
||||||
|
|
||||||
let { coords,icon,flag, isBounds , showTitle} = res
|
let { coords,icon,flag, isBounds , showTitle, coordinates} = res
|
||||||
if (!coords) return;
|
if (!coords) return;
|
||||||
if(!_that._self[flag]) _that._self[flag] = []; //存储地图标识的容器
|
if(!_that._self[flag]) _that._self[flag] = []; //存储地图标识的容器
|
||||||
if(!_that.idsBox[flag]) _that.idsBox[flag] = []; //存储id的容器
|
if(!_that.idsBox[flag]) _that.idsBox[flag] = []; //存储id的容器
|
||||||
@ -158,8 +158,8 @@ export function MapUtil(map) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 装备图标
|
* 装备图标
|
||||||
* @param {点位数据} data
|
* @param {点位数据} data
|
||||||
* @param {点} point
|
* @param {点} point
|
||||||
*/
|
*/
|
||||||
MapUtil.prototype.shouIcon = (data, point) => {
|
MapUtil.prototype.shouIcon = (data, point) => {
|
||||||
if(!_that._self.gpsZb) _that._self.gpsZb = []
|
if(!_that._self.gpsZb) _that._self.gpsZb = []
|
||||||
@ -215,8 +215,8 @@ export function MapUtil(map) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 聚合撒点
|
* 聚合撒点
|
||||||
* @param {*} coords 点位数据 geojson lng lat
|
* @param {*} coords 点位数据 geojson lng lat
|
||||||
* @param {*} icon 点位图
|
* @param {*} icon 点位图
|
||||||
*/
|
*/
|
||||||
MapUtil.prototype.aggregateScatteringPoint = (obj) => {
|
MapUtil.prototype.aggregateScatteringPoint = (obj) => {
|
||||||
let { coords, icon, flag,isclear,scale } = obj;
|
let { coords, icon, flag,isclear,scale } = obj;
|
||||||
@ -245,11 +245,11 @@ export function MapUtil(map) {
|
|||||||
|
|
||||||
// 聚合的点击一个
|
// 聚合的点击一个
|
||||||
maker.addEventListener("click", (val) => {
|
maker.addEventListener("click", (val) => {
|
||||||
_that.openInfoDetail(flag,[val]) //点击打开详情
|
_that.openInfoDetail(flag,[val]) //点击打开详情
|
||||||
})
|
})
|
||||||
// 聚合的多个
|
// 聚合的多个
|
||||||
maker.addEventListener("clusterClick", (val) => {
|
maker.addEventListener("clusterClick", (val) => {
|
||||||
_that.openInfoDetail(flag,val) //点击打开详情
|
_that.openInfoDetail(flag,val) //点击打开详情
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -291,7 +291,7 @@ export function MapUtil(map) {
|
|||||||
})
|
})
|
||||||
_that.heatmapOverlay[flag] = []
|
_that.heatmapOverlay[flag] = []
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除图层要素
|
* 删除图层要素
|
||||||
* @param {*} layer 唯一标识
|
* @param {*} layer 唯一标识
|
||||||
@ -306,7 +306,7 @@ export function MapUtil(map) {
|
|||||||
_that._self.gpsZb[key] = []
|
_that._self.gpsZb[key] = []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 其他图层
|
// 其他图层
|
||||||
if (!_that._self[layer]) return false;
|
if (!_that._self[layer]) return false;
|
||||||
if(layer !== 'gpsZb'){
|
if(layer !== 'gpsZb'){
|
||||||
@ -315,7 +315,7 @@ export function MapUtil(map) {
|
|||||||
el.destroy()//destory()销毁 , show(false) false:隐藏 true :展示
|
el.destroy()//destory()销毁 , show(false) false:隐藏 true :展示
|
||||||
}
|
}
|
||||||
_that._self[layer] = [];
|
_that._self[layer] = [];
|
||||||
|
|
||||||
// d带标题的撒点
|
// d带标题的撒点
|
||||||
let flagT = layer+'Title';
|
let flagT = layer+'Title';
|
||||||
if (!_that._self[flagT]) return false;
|
if (!_that._self[flagT]) return false;
|
||||||
@ -360,7 +360,7 @@ export function MapUtil(map) {
|
|||||||
} catch (err) {}
|
} catch (err) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 绘制数据的初始化
|
// 绘制数据的初始化
|
||||||
MapUtil.prototype.Drawplot = (color) => {
|
MapUtil.prototype.Drawplot = (color) => {
|
||||||
const {point,line,polygon,circle,rectangle,geoJson,remove,enableEdit } = map.draw({
|
const {point,line,polygon,circle,rectangle,geoJson,remove,enableEdit } = map.draw({
|
||||||
@ -374,7 +374,7 @@ export function MapUtil(map) {
|
|||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 绘制工具
|
* 绘制工具
|
||||||
* @param {*} type 绘制形状
|
* @param {*} type 绘制形状
|
||||||
* (point 点, line 线, circle 圆, polygon 多边形, rectangle 矩形) ,
|
* (point 点, line 线, circle 圆, polygon 多边形, rectangle 矩形) ,
|
||||||
* geoJson:根据geojson回显图
|
* geoJson:根据geojson回显图
|
||||||
*/
|
*/
|
||||||
@ -452,8 +452,8 @@ export function MapUtil(map) {
|
|||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 创建线
|
* 创建线
|
||||||
* @param {*} type 回显形状
|
* @param {*} type 回显形状
|
||||||
* (solid 实线, dash 虚线, FlowColor 彩虹线, RoadLine 流线
|
* (solid 实线, dash 虚线, FlowColor 彩虹线, RoadLine 流线
|
||||||
*/
|
*/
|
||||||
MapUtil.prototype.createLine = (res) => {
|
MapUtil.prototype.createLine = (res) => {
|
||||||
let { type , coords , isclear ,flag ,color,width} = res;
|
let { type , coords , isclear ,flag ,color,width} = res;
|
||||||
@ -498,9 +498,9 @@ export function MapUtil(map) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 回显平面- 圆 - 多边形 - 矩形
|
* 回显平面- 圆 - 多边形 - 矩形
|
||||||
* @param {*} type 回显形状
|
* @param {*} type 回显形状
|
||||||
* type: 'polygon', 'rectangle
|
* type: 'polygon', 'rectangle
|
||||||
coords = [{
|
coords = [{
|
||||||
position:[[[jd,wd],[jd,wd] ---]], //三维数组
|
position:[[[jd,wd],[jd,wd] ---]], //三维数组
|
||||||
text,//展示的文字
|
text,//展示的文字
|
||||||
id, //唯一标识
|
id, //唯一标识
|
||||||
@ -508,10 +508,10 @@ export function MapUtil(map) {
|
|||||||
userData:{} //存储数据
|
userData:{} //存储数据
|
||||||
}]
|
}]
|
||||||
|
|
||||||
* type:circle
|
* type:circle
|
||||||
coords:[jd,wd] radius:半径
|
coords:[jd,wd] radius:半径
|
||||||
|
|
||||||
* @param {*} text 展示的文字
|
* @param {*} text 展示的文字
|
||||||
*/
|
*/
|
||||||
MapUtil.prototype.echoPlane = (res) => {
|
MapUtil.prototype.echoPlane = (res) => {
|
||||||
let { type , coords ,fontColor, text = '' ,radius = 0, isclear ,flag ,id = 1 , color , linecolor} = res;
|
let { type , coords ,fontColor, text = '' ,radius = 0, isclear ,flag ,id = 1 , color , linecolor} = res;
|
||||||
@ -535,7 +535,7 @@ export function MapUtil(map) {
|
|||||||
let maker ;
|
let maker ;
|
||||||
// 圆
|
// 圆
|
||||||
if(type == 'circle'){
|
if(type == 'circle'){
|
||||||
let params = [{ center:coords,radius, text, id }]
|
let params = [{ center:coords,radius, text, id }]
|
||||||
maker = map.createCircle(params,style);
|
maker = map.createCircle(params,style);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -544,7 +544,7 @@ export function MapUtil(map) {
|
|||||||
// 多边形
|
// 多边形
|
||||||
if(type == 'polygon') maker = map.createPolygon(coords,style);
|
if(type == 'polygon') maker = map.createPolygon(coords,style);
|
||||||
_that._self[flag].push(maker);
|
_that._self[flag].push(maker);
|
||||||
|
|
||||||
maker.addEventListener("click", (val) => {
|
maker.addEventListener("click", (val) => {
|
||||||
if( flag == 'xfq'){
|
if( flag == 'xfq'){
|
||||||
maker.highlight(val.id) //高亮展示
|
maker.highlight(val.id) //高亮展示
|
||||||
@ -557,7 +557,7 @@ export function MapUtil(map) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 分割线展示文字
|
// 分割线展示文字
|
||||||
MapUtil.prototype.gapText = (obj) => {
|
MapUtil.prototype.gapText = (obj) => {
|
||||||
let { points, text ,flag} = obj
|
let { points, text ,flag} = obj
|
||||||
@ -668,7 +668,7 @@ export function MapUtil(map) {
|
|||||||
_that.polygonGeo.destroy()
|
_that.polygonGeo.destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 打开详情弹窗
|
// 打开详情弹窗
|
||||||
MapUtil.prototype.openInfoDetail = (flag,data) => {
|
MapUtil.prototype.openInfoDetail = (flag,data) => {
|
||||||
switch (flag) {
|
switch (flag) {
|
||||||
case "rx":
|
case "rx":
|
||||||
@ -699,6 +699,31 @@ export function MapUtil(map) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 获取经纬度*/
|
||||||
|
MapUtil.prototype.enableClickEvents = function() {
|
||||||
|
const _that = this;
|
||||||
|
|
||||||
|
if (_that.clickEventHandler) {
|
||||||
|
console.log('点击事件已经启用');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加点击事件处理函数
|
||||||
|
_that.clickEventHandler = (e) => {
|
||||||
|
const lng = e.lngLat.lng;
|
||||||
|
const lat = e.lngLat.lat;
|
||||||
|
|
||||||
|
emitter.emit("mapClickCoordinates", {
|
||||||
|
lng,
|
||||||
|
lat,
|
||||||
|
coordinates: [lng, lat],
|
||||||
|
timestamp: new Date().getTime()
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
_that.mMap.mapboxGLMap.on('click', _that.clickEventHandler);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
// 获取uuid 作为边界图层ID
|
// 获取uuid 作为边界图层ID
|
||||||
function getUUid() {
|
function getUUid() {
|
||||||
|
97
src/pages/clockInPage/components/Timeline.vue
Normal file
97
src/pages/clockInPage/components/Timeline.vue
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
<template>
|
||||||
|
<div class="info-container">
|
||||||
|
<div class="item" v-for="(item, index) in data" :key="index">
|
||||||
|
<div class="point"></div>
|
||||||
|
<div class="line" v-if="index + 1 != data.length"></div>
|
||||||
|
<div class="info-right">
|
||||||
|
<div class="name">{{item.name}}</div>
|
||||||
|
<div class="time">打卡时间:<text>{{ item.time }}</text></div>
|
||||||
|
|
||||||
|
<div class="image">
|
||||||
|
<img src="../../../assets/home/bddcj.png" alt="">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="address">
|
||||||
|
<van-icon name="location-o" color="#1DB1FF" />
|
||||||
|
<div class="name">四川省成都市</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
const props = defineProps({
|
||||||
|
data: {
|
||||||
|
type: Array,
|
||||||
|
default: []
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.info-container {
|
||||||
|
padding: 0 2.67vw;
|
||||||
|
margin-top: 4vw;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
color: #666;
|
||||||
|
display: flex;
|
||||||
|
align-content: center;
|
||||||
|
position: relative;
|
||||||
|
height: auto;
|
||||||
|
border-left: 0.53vw dashed #1DB1FF;
|
||||||
|
max-height: 46.93vw;
|
||||||
|
padding-bottom: 2.67vw;
|
||||||
|
|
||||||
|
.point {
|
||||||
|
position: absolute;
|
||||||
|
width: 3.2vw;
|
||||||
|
height: 3.2vw;
|
||||||
|
background: #1DB1FF;
|
||||||
|
border-radius: 50%;
|
||||||
|
flex-shrink: 0;
|
||||||
|
left: -1.665vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-right {
|
||||||
|
margin-left: 5.33vw;
|
||||||
|
font-family: PingFang HK, PingFang HK;
|
||||||
|
.name {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 3.73vw;
|
||||||
|
color: #707070;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image {
|
||||||
|
margin-top: 2.13vw;
|
||||||
|
width: 33.87vw;
|
||||||
|
height: 18.67vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time {
|
||||||
|
margin-top: 2.13vw;
|
||||||
|
|
||||||
|
text {
|
||||||
|
color: #0386FB;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.address {
|
||||||
|
margin-top: 2.13vw;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
color: #75787F;
|
||||||
|
|
||||||
|
div {
|
||||||
|
font-size: 2.67vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name {
|
||||||
|
margin-left: 1.33vw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
305
src/pages/clockInPage/index.vue
Normal file
305
src/pages/clockInPage/index.vue
Normal file
@ -0,0 +1,305 @@
|
|||||||
|
<script setup>
|
||||||
|
import TopNav from "@/components/topNav.vue";
|
||||||
|
import {onMounted, reactive, ref} from "vue";
|
||||||
|
import { useRoute } from "vue-router";
|
||||||
|
import Timeline from "@/pages/clockInPage/components/Timeline.vue";
|
||||||
|
import {fetchSelectListByBddxlrwId} from "@/api/patrolList";
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
|
const activeName = ref("0")
|
||||||
|
const baseUrl = ref("")
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
tabsList: [],
|
||||||
|
info: []
|
||||||
|
})
|
||||||
|
const timeList = [
|
||||||
|
{
|
||||||
|
time:'09:24:34',
|
||||||
|
name: '第一次打卡 开始',
|
||||||
|
person:'李小明',
|
||||||
|
content:'签收订单, 订单状态变更为待回单, 签收备注为\'无\'',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
time:'2020-03-26 12:30:12',
|
||||||
|
name: '吾悦广场',
|
||||||
|
person:'李小明',
|
||||||
|
content:'创建了订单, 并添加了跟踪方式, 电子设备或快递单号: 854654875',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
time:'2020-03-26 12:30:12',
|
||||||
|
name: '吾悦广场',
|
||||||
|
person:'李小明',
|
||||||
|
content:'签收订单, 订单状态变更为待回单, 签收备注为\'无\'',
|
||||||
|
}
|
||||||
|
]
|
||||||
|
const clearImage = () => {}
|
||||||
|
|
||||||
|
const onClickImg = () => {}
|
||||||
|
|
||||||
|
const photoFn = () => {}
|
||||||
|
|
||||||
|
const count = (item) => {
|
||||||
|
if (!item || !item.dkSx) return undefined;
|
||||||
|
|
||||||
|
const numbers = ['一', '二', '三', '四'];
|
||||||
|
const index = item.dkSx - 1; // 假设 dkSx 是从1开始的数字
|
||||||
|
|
||||||
|
return numbers[index];
|
||||||
|
};
|
||||||
|
|
||||||
|
const getData = async (bddxlrwId = '') => {
|
||||||
|
const res = await fetchSelectListByBddxlrwId({ bddxlrwId })
|
||||||
|
if (res) {
|
||||||
|
data.info = res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (route.query.item) {
|
||||||
|
data.tabsList = JSON.parse(route.query.item)
|
||||||
|
console.log(data.tabsList)
|
||||||
|
}
|
||||||
|
|
||||||
|
getData(data.tabsList[0]?.id)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<top-nav navTitle="打卡" :showLeft="true" />
|
||||||
|
|
||||||
|
<div class="clockInWrapper">
|
||||||
|
<van-tabs v-model="activeName">
|
||||||
|
<template v-for="(item, index) in data.tabsList" :key="item?.id">
|
||||||
|
<van-tab :name="index" :title="item?.bddMc" />
|
||||||
|
</template>
|
||||||
|
</van-tabs>
|
||||||
|
|
||||||
|
<div class="clockInList">
|
||||||
|
<template v-for="(item, index) in data.info" :key="index">
|
||||||
|
<div class="clockInList_item">
|
||||||
|
<div class="label">{{ `第${count(item)}次打卡` }}</div>
|
||||||
|
<div class="dec">开始</div>
|
||||||
|
<div class="dec">离开</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<!-- <div class="clockInList_item">-->
|
||||||
|
<!-- <div class="label">第一次打卡</div>-->
|
||||||
|
<!-- <div class="dec">开始</div>-->
|
||||||
|
<!-- <div class="dec">离开</div>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<!-- <div class="clockInList_item">-->
|
||||||
|
<!-- <div class="label">第一次打卡</div>-->
|
||||||
|
<!-- <div class="dec">开始</div>-->
|
||||||
|
<!-- <div class="dec">离开</div>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="upload_box">
|
||||||
|
<div class="image_box" v-if="baseUrl">
|
||||||
|
<van-icon name="close" class="close_icon" @click="clearImage" color="#000" size="24px" />
|
||||||
|
<van-image :src="baseUrl" @click="onClickImg(baseUrl)" style="flex: 1">
|
||||||
|
<template v-slot:loading>
|
||||||
|
<van-loading type="spinner" size="20" />
|
||||||
|
</template>
|
||||||
|
</van-image>
|
||||||
|
</div>
|
||||||
|
<div class="upload_icon_box" v-else>
|
||||||
|
<van-icon @click="photoFn" color="#1DB1FF" name="plus" />
|
||||||
|
<span>点击拍照</span>
|
||||||
|
</div>
|
||||||
|
<!-- <van-uploader v-model="clockList" :max-count="1" :after-read="afterRead" capture="camera"
|
||||||
|
:before-read="beforeRead" accept="image/*" /> -->
|
||||||
|
<div class="upload_tip"><span style="color: red;">*</span>须拍摄实景图才可进行打卡</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="clockWrapper">
|
||||||
|
<div class="circleWrapper">
|
||||||
|
<div class="time">10:00:00后</div>
|
||||||
|
<div class="title">开始</div>
|
||||||
|
<div class="info">第一次打卡</div>
|
||||||
|
</div>
|
||||||
|
<div class="circleWrapperTip">
|
||||||
|
<van-icon name="success" color="#FFFFFF" />
|
||||||
|
<div>已进入考勤范围:打卡点1德阳市某某某</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<timeline :data="timeList" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.clockInWrapper {
|
||||||
|
margin-top: 13vw;
|
||||||
|
padding: 2vw;
|
||||||
|
|
||||||
|
.clockWrapper {
|
||||||
|
margin-top: 23.47vw;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.circleWrapperTip {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 7.2vw;
|
||||||
|
font-family: PingFang HK, PingFang HK;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 3.73vw;
|
||||||
|
color: #707070;
|
||||||
|
|
||||||
|
::v-deep {
|
||||||
|
.van-icon-success {
|
||||||
|
margin-right: 1.33vw;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 3.73vw;
|
||||||
|
height: 3.73vw;
|
||||||
|
background: #11AA66;
|
||||||
|
border-radius: 13.33vw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.circleWrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 42.67vw;
|
||||||
|
height: 42.67vw;
|
||||||
|
background: linear-gradient( 180deg, #1DB1FF 0%, #007DE9 100%);
|
||||||
|
border-radius: 26.67vw;
|
||||||
|
color: #fff;
|
||||||
|
font-family: PingFang HK, PingFang HK;
|
||||||
|
|
||||||
|
.time {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 4.8vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 4.8vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 3.73vw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload_box {
|
||||||
|
margin-top: 4vw;
|
||||||
|
display: flex;
|
||||||
|
padding-bottom: 4vw;
|
||||||
|
border-bottom: 0.27vw solid #D9D9D9;
|
||||||
|
|
||||||
|
.upload_tip {
|
||||||
|
color: #999999;
|
||||||
|
font-size: 2.67vw;
|
||||||
|
margin-left: 2.67vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image_box {
|
||||||
|
position: relative;
|
||||||
|
width: 42.67vw;
|
||||||
|
height: 26.67vw;
|
||||||
|
|
||||||
|
.close_icon {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
z-index: 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .van-image {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload_icon_box {
|
||||||
|
font-size: 3.2vw;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: #1DB1FF;
|
||||||
|
border: 0.27vw dashed #1DB1FF;
|
||||||
|
text-align: center;
|
||||||
|
width: 29.33vw;
|
||||||
|
height: 16.53vw;
|
||||||
|
border-radius: 2.67vw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.clockInList {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-top: 4vw;
|
||||||
|
|
||||||
|
.clockInList_item {
|
||||||
|
padding: 4vw 2vw;
|
||||||
|
width: 43vw;
|
||||||
|
height: 18vw;
|
||||||
|
background: #EDEDED;
|
||||||
|
border-radius: 2.67vw;
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 4.27vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dec {
|
||||||
|
color: #75787F;
|
||||||
|
font-size: 3.73vw;
|
||||||
|
margin-top: 1.33vw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep {
|
||||||
|
.van-tabs__nav--line {
|
||||||
|
padding-bottom: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.van-tabs__wrap {
|
||||||
|
height: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.van-tabs__line {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.van-tab {
|
||||||
|
flex: initial;
|
||||||
|
font-size: 4vw;
|
||||||
|
width: auto !important;
|
||||||
|
height: 9.33vw;
|
||||||
|
padding: 0 2.67vw;
|
||||||
|
border: 0.27vw solid #EDEDED;
|
||||||
|
color: #75787F;
|
||||||
|
flex-shrink: 0;
|
||||||
|
border-radius: 2vw;
|
||||||
|
margin-right: 2vw;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-right: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.van-tab--active {
|
||||||
|
background: rgba(62,110,232,0.2);
|
||||||
|
border: 0.27vw solid #3E6EE8;
|
||||||
|
color: #3E6EE8 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
172
src/pages/collectPage/collectAndAdd.vue
Normal file
172
src/pages/collectPage/collectAndAdd.vue
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
<script setup>
|
||||||
|
import emitter from "@/utils/eventBus";
|
||||||
|
import TopNav from "@/components/topNav.vue";
|
||||||
|
import {onMounted, ref} from "vue";
|
||||||
|
import CustomPopup from "@/pages/collectPage/copmonents/customPopup.vue";
|
||||||
|
import GdMap from "@/components/GdMap/index.vue"
|
||||||
|
import {addSaveData} from "@/api/collectPage";
|
||||||
|
import {hintToast} from "@/utils/tools";
|
||||||
|
import router from "@/router";
|
||||||
|
|
||||||
|
const loading = ref(false)
|
||||||
|
const disabled = ref(false)
|
||||||
|
const visible = ref(false)
|
||||||
|
const formData = ref({})
|
||||||
|
|
||||||
|
const onSubmit = async (data) => {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
const res = await addSaveData(formData.value)
|
||||||
|
if (res) {
|
||||||
|
hintToast(res?.msg || '新增成功')
|
||||||
|
|
||||||
|
setTimeout(async () => {
|
||||||
|
await router.push(`/collectPage`)
|
||||||
|
}, 500)
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
hintToast(error?.msg || "新增失败")
|
||||||
|
} finally {
|
||||||
|
setTimeout(() => {
|
||||||
|
loading.value = false
|
||||||
|
}, 1000)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取方格
|
||||||
|
const handleChange = (val) => {
|
||||||
|
formData.value.mc = val?.mc
|
||||||
|
formData.value.fgdwId = val?.id
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 获取经纬度
|
||||||
|
emitter.emit("getMapClickCoordinates");
|
||||||
|
|
||||||
|
// 更新地图标注位置
|
||||||
|
emitter.on("mapClickCoordinates", async (res) => {
|
||||||
|
emitter.emit("deletePointArea")
|
||||||
|
|
||||||
|
formData.value.jd = res.lng
|
||||||
|
formData.value.wd = res.lat
|
||||||
|
|
||||||
|
emitter.emit("addPointArea", {
|
||||||
|
coords: [{ jd: res.lng, wd: res.lat }],
|
||||||
|
coordinates: res?.coordinates,
|
||||||
|
icon: require("../../assets/lz/dw.png"),
|
||||||
|
sizeX: 30,
|
||||||
|
sizeY: 35
|
||||||
|
});
|
||||||
|
})
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<TopNav navTitle="必到点采集新增" :showLeft="true" />
|
||||||
|
|
||||||
|
<div class="formWrapper">
|
||||||
|
<van-form @submit="onSubmit" class="form" :disabled="disabled">
|
||||||
|
<!-- <van-field-->
|
||||||
|
<!-- v-model="formData.cjsbQk"-->
|
||||||
|
<!-- readonly-->
|
||||||
|
<!-- label="所属部门"-->
|
||||||
|
<!-- placeholder="请输入必到点名称"-->
|
||||||
|
<!-- />-->
|
||||||
|
<van-field
|
||||||
|
v-model="formData.bddMc"
|
||||||
|
name="bddMc"
|
||||||
|
required
|
||||||
|
label="必到点名称"
|
||||||
|
placeholder="请输入必到点名称"
|
||||||
|
:rules="[{ required: true, message: '请输入必到点名称' }]"
|
||||||
|
/>
|
||||||
|
<van-field
|
||||||
|
v-model="formData.mc"
|
||||||
|
name="mc"
|
||||||
|
required
|
||||||
|
is-link
|
||||||
|
readonly
|
||||||
|
label="所属方格"
|
||||||
|
placeholder="请输入必到点名称"
|
||||||
|
:rules="[{ required: true, message: '请输入必到点名称' }]"
|
||||||
|
@click="visible = true"
|
||||||
|
/>
|
||||||
|
<van-field
|
||||||
|
v-model="formData.bddDz"
|
||||||
|
name="bddDz"
|
||||||
|
required
|
||||||
|
label="地址"
|
||||||
|
placeholder="请输入必到点名称"
|
||||||
|
:rules="[{ required: true, message: '请输入必到点名称' }]"
|
||||||
|
/>
|
||||||
|
<van-field
|
||||||
|
v-model="formData.jd"
|
||||||
|
name="jd"
|
||||||
|
required
|
||||||
|
label="经度"
|
||||||
|
placeholder="请输入经度"
|
||||||
|
:rules="[{ required: true, message: '请输入经度' }]"
|
||||||
|
/>
|
||||||
|
<van-field
|
||||||
|
v-model="formData.wd"
|
||||||
|
name="wd"
|
||||||
|
required
|
||||||
|
label="纬度"
|
||||||
|
placeholder="请输入纬度"
|
||||||
|
:rules="[{ required: true, message: '请输入纬度' }]"
|
||||||
|
/>
|
||||||
|
<div class="mapWrapper">
|
||||||
|
<div class="label">地图选点</div>
|
||||||
|
<div style="height: 40vh; margin-top: 2vw">
|
||||||
|
<gd-map />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="btn">
|
||||||
|
<van-button
|
||||||
|
round
|
||||||
|
block
|
||||||
|
type="primary"
|
||||||
|
native-type="submit"
|
||||||
|
:loading="loading"
|
||||||
|
loading-type="spinner"
|
||||||
|
loading-text="保存中..."
|
||||||
|
>保存</van-button>
|
||||||
|
</div>
|
||||||
|
</van-form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<custom-popup v-model="visible" @change="handleChange" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.formWrapper {
|
||||||
|
margin-top: 13vw;
|
||||||
|
|
||||||
|
.mapWrapper {
|
||||||
|
padding: var(--van-cell-vertical-padding) var(--van-cell-horizontal-padding);
|
||||||
|
font-size: var(--van-cell-font-size);
|
||||||
|
color: var(--van-field-label-color);
|
||||||
|
|
||||||
|
.label {
|
||||||
|
margin-right: var(--van-field-label-margin-right);
|
||||||
|
width: var(--van-field-label-width);
|
||||||
|
}
|
||||||
|
|
||||||
|
.context {
|
||||||
|
margin-top: 2vw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
position: fixed;
|
||||||
|
padding: 2vw;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: calc(100% - 4vw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
96
src/pages/collectPage/copmonents/customPopup.vue
Normal file
96
src/pages/collectPage/copmonents/customPopup.vue
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
<script setup>
|
||||||
|
import {computed, onMounted, ref} from "vue";
|
||||||
|
import Search from "@/components/search.vue";
|
||||||
|
import {getSelectList} from "@/api/collectPage";
|
||||||
|
import emitter from "@/utils/eventBus";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
position: {
|
||||||
|
type: String,
|
||||||
|
default: 'bottom'
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const emits = defineEmits(["update:modelValue", "change"]);
|
||||||
|
const visible = computed({
|
||||||
|
get: function () {
|
||||||
|
return props.modelValue;
|
||||||
|
},
|
||||||
|
set: function (val) {
|
||||||
|
emits("update:modelValue", val)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const visibleEmpty = ref(false)
|
||||||
|
const searchValue = ref("")
|
||||||
|
const radioChecked = ref("")
|
||||||
|
const list = ref([])
|
||||||
|
|
||||||
|
const onSearch = (value) => {
|
||||||
|
list.value = []
|
||||||
|
getSelectListData(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const onRadionChange = (value) => {
|
||||||
|
emits('change', value)
|
||||||
|
|
||||||
|
const { x1, y1, x2, y2, id, zxX, zxY, mc } = value
|
||||||
|
const centerPoint = [zxX, zxY]
|
||||||
|
const position = [[Number(x1),Number(y1)],[Number(x2),Number(y2)]]
|
||||||
|
const text = mc
|
||||||
|
const obj = [{ position: position, text, id, userData: value}]
|
||||||
|
|
||||||
|
emitter.emit("echoPlane", { fontColor:'#12fdb8',coords: obj, type:'rectangle', flag:'zdxl_fzyc', color:'rgba(2,20,51,0.5)', linecolor:'#1C97FF'})
|
||||||
|
emitter.emit("setMapCenter", { location: centerPoint, zoomLevel: 14 });
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取数据
|
||||||
|
const getSelectListData = async (mc) => {
|
||||||
|
try {
|
||||||
|
const res = await getSelectList({ mc });
|
||||||
|
if (res?.length > 0) {
|
||||||
|
list.value = res || []
|
||||||
|
visibleEmpty.value = false
|
||||||
|
} else {
|
||||||
|
visibleEmpty.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
visibleEmpty.value = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getSelectListData()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<van-popup v-model:show="visible" :position="position">
|
||||||
|
<search placeholder="请输入方格名称" v-model="searchValue" @update:modelValue="onSearch" />
|
||||||
|
|
||||||
|
<div class="selectWrapper">
|
||||||
|
<van-radio-group v-model="radioChecked">
|
||||||
|
<van-cell-group>
|
||||||
|
<van-cell v-for="item in list" clickable :key="item" :title="item?.mc" :border="false">
|
||||||
|
<template #right-icon>
|
||||||
|
<van-radio :name="item?.id" @click="onRadionChange(item)" />
|
||||||
|
</template>
|
||||||
|
</van-cell>
|
||||||
|
</van-cell-group>
|
||||||
|
</van-radio-group>
|
||||||
|
<van-empty description="没有数据" image="default" v-if="list.length <= 0 && visibleEmpty" />
|
||||||
|
</div>
|
||||||
|
</van-popup>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.selectWrapper {
|
||||||
|
height: 80vw;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
</style>
|
52
src/pages/collectPage/copmonents/listItemWrapper.vue
Normal file
52
src/pages/collectPage/copmonents/listItemWrapper.vue
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<script setup>
|
||||||
|
const props = defineProps({
|
||||||
|
list: {
|
||||||
|
type: Array,
|
||||||
|
required: true,
|
||||||
|
default: () => []
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const emits = defineEmits(["onConfirm"]);
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="item-wrapper">
|
||||||
|
<template v-for="(item, index) in list" :key="index">
|
||||||
|
<div class="item">
|
||||||
|
<div class="title">{{ item.bddMc }}</div>
|
||||||
|
<div class="infoWrapper">
|
||||||
|
<!-- <div class="mt">所属部门:{{ item.sssgaj }}</div>-->
|
||||||
|
<div class="mt">所属方格:{{ item?.fgdwMc }}</div>
|
||||||
|
<div class="mt">地址:{{ item.bddDz }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.item-wrapper {
|
||||||
|
margin: 2vw;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
padding: 2vw;
|
||||||
|
border-top: 0.13333vw solid #f4f5f1;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mt {
|
||||||
|
margin-top: 2vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.infoWrapper {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #999999;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
129
src/pages/collectPage/index.vue
Normal file
129
src/pages/collectPage/index.vue
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
<script setup>
|
||||||
|
import TopNav from "@/components/topNav.vue";
|
||||||
|
import Search from "@/components/search.vue";
|
||||||
|
import {onMounted, reactive, ref} from "vue";
|
||||||
|
import ListItemWrapper from "@/pages/collectPage/copmonents/listItemWrapper.vue";
|
||||||
|
import router from "@/router";
|
||||||
|
import {getSelectPage} from "@/api/collectPage";
|
||||||
|
|
||||||
|
const finished = ref(false);
|
||||||
|
const loading = ref(false);
|
||||||
|
const loadingRefresh = ref(false);
|
||||||
|
const searchValue = ref("")
|
||||||
|
const pageData = reactive({
|
||||||
|
pageSize: 10,
|
||||||
|
pageCurrent: 1,
|
||||||
|
total: 0,
|
||||||
|
})
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
list: []
|
||||||
|
})
|
||||||
|
|
||||||
|
const onSearch = (value) => {
|
||||||
|
loading.value = true;
|
||||||
|
pageData.pageCurrent = 1;
|
||||||
|
data.list = []
|
||||||
|
getData()
|
||||||
|
}
|
||||||
|
|
||||||
|
const onRefresh = () => {
|
||||||
|
loading.value = false;
|
||||||
|
loadingRefresh.value = true;
|
||||||
|
finished.value = false;
|
||||||
|
pageData.pageCurrent = 1;
|
||||||
|
data.list = []
|
||||||
|
getData()
|
||||||
|
}
|
||||||
|
|
||||||
|
const getData = async () => {
|
||||||
|
try {
|
||||||
|
const { total, ...ret } = pageData
|
||||||
|
const res = await getSelectPage({ ...ret, bddMc: searchValue.value })
|
||||||
|
if (res?.records.length > 0) {
|
||||||
|
data.list = data.list.concat(res?.records) || []
|
||||||
|
pageData.total = res?.total
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
loadingRefresh.value = false;
|
||||||
|
} catch (error) {
|
||||||
|
loading.value = false;
|
||||||
|
loadingRefresh.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const onLoad = () => {
|
||||||
|
if (data.list.length >= pageData?.total) {
|
||||||
|
finished.value = true;
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
pageData.pageCurrent++
|
||||||
|
getData()
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
data.list = []
|
||||||
|
getData()
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleTo = () => {
|
||||||
|
router.push("/collectAndAdd")
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<TopNav navTitle="必到点采集列表" :showLeft="true" />
|
||||||
|
|
||||||
|
<van-sticky>
|
||||||
|
<div class="header">
|
||||||
|
<search placeholder="请输入部门、所属方格或必到点名称进行查询"
|
||||||
|
v-model="searchValue"
|
||||||
|
@update:modelValue="onSearch"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</van-sticky>
|
||||||
|
|
||||||
|
<div class="content">
|
||||||
|
<van-pull-refresh v-model="loadingRefresh" @refresh="onRefresh">
|
||||||
|
<van-list v-model:loading="loading" :finished="finished" finished-text="" @load="onLoad" offset="1" :immediate-check="false">
|
||||||
|
<list-item-wrapper :list="data.list" />
|
||||||
|
|
||||||
|
<van-empty description="暂无采集数据" image="default" v-if="data.list.length <= 0 && loadingRefresh === false" />
|
||||||
|
</van-list>
|
||||||
|
</van-pull-refresh>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="footer" @click="handleTo">
|
||||||
|
<van-button
|
||||||
|
round
|
||||||
|
native-type="submit"
|
||||||
|
block
|
||||||
|
type="primary"
|
||||||
|
>
|
||||||
|
新增必到点采集
|
||||||
|
</van-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
@import "@/assets/styles/mixin.scss";
|
||||||
|
|
||||||
|
.header {
|
||||||
|
margin-top: 13vw;
|
||||||
|
@include bg_color($background-color-theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
margin-bottom: 16vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
position: fixed;
|
||||||
|
padding: 2vw;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: calc(100% - 4vw);
|
||||||
|
}
|
||||||
|
</style>
|
@ -31,7 +31,7 @@ const listData = ref([
|
|||||||
text: '巡逻打卡',
|
text: '巡逻打卡',
|
||||||
imgUrl: require("@/assets/home/xldk.png"),
|
imgUrl: require("@/assets/home/xldk.png"),
|
||||||
type: 'xldk',
|
type: 'xldk',
|
||||||
path: '/clock'
|
path: '/patrolList'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: '信息交互',
|
text: '信息交互',
|
||||||
@ -39,6 +39,12 @@ const listData = ref([
|
|||||||
type: 'zllz',
|
type: 'zllz',
|
||||||
path: '/yyzx/zlzx/zlzxIndex'
|
path: '/yyzx/zlzx/zlzxIndex'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
text: '必到点采集',
|
||||||
|
imgUrl: require("@/assets/home/bddcj.png"),
|
||||||
|
type: 'bddcj',
|
||||||
|
path: '/collectPage'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
text: '处警报送',
|
text: '处警报送',
|
||||||
imgUrl: require("@/assets/home/dqwz.png"),
|
imgUrl: require("@/assets/home/dqwz.png"),
|
||||||
@ -59,6 +65,8 @@ const changeOpen = (val) => {
|
|||||||
case 'zllz':
|
case 'zllz':
|
||||||
case 'grxx':
|
case 'grxx':
|
||||||
case 'cjbs':
|
case 'cjbs':
|
||||||
|
case 'bddcj':
|
||||||
|
case 'clockIn':
|
||||||
router.push(val.path)
|
router.push(val.path)
|
||||||
break
|
break
|
||||||
case 'rcpc':
|
case 'rcpc':
|
||||||
@ -79,6 +87,7 @@ ul {
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
li {
|
li {
|
||||||
width: 48%;
|
width: 48%;
|
||||||
@ -91,4 +100,4 @@ ul {
|
|||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
76
src/pages/patrolList/copmonents/patrolWrapper.vue
Normal file
76
src/pages/patrolList/copmonents/patrolWrapper.vue
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
<script setup>
|
||||||
|
import router from "@/router";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
list: {
|
||||||
|
type: Array,
|
||||||
|
required: true,
|
||||||
|
default: () => []
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const emits = defineEmits(["onConfirm"]);
|
||||||
|
|
||||||
|
const handleClockInPage = (item) => {
|
||||||
|
router.push({ path: '/clockInPage', query: { item: JSON.stringify(item?.bddList), id: item.id } });
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="item-wrapper">
|
||||||
|
<template v-for="(item, index) in list" :key="index">
|
||||||
|
<div class="item" @click="handleClockInPage(item)">
|
||||||
|
<div class="rowWrapper">
|
||||||
|
<div class="title">{{ item?.fgMc }}</div>
|
||||||
|
<div class="progress">50%</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="rowWrapper mt co99 fz12">
|
||||||
|
<div>预警等级:{{ item?.fgYjdj }}</div>
|
||||||
|
<div>任务日期:{{ item?.rwRq }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="rowWrapper mt co99 fz12">
|
||||||
|
<div>高发类型:{{ item?.fgJqtjLx }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.item-wrapper {
|
||||||
|
margin: 2vw;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
padding: 2vw;
|
||||||
|
border-top: 0.13333vw solid #f4f5f1;
|
||||||
|
|
||||||
|
.rowWrapper {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
.title {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 3.73vw;
|
||||||
|
color: #3E6EE8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fz12 {
|
||||||
|
font-size: 3.2vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.co99 {
|
||||||
|
color: #999999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mt {
|
||||||
|
margin-top: 2vw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
136
src/pages/patrolList/index.vue
Normal file
136
src/pages/patrolList/index.vue
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
<script setup>
|
||||||
|
import { ref, reactive, onMounted } from "vue";
|
||||||
|
import TopNav from "@/components/topNav.vue";
|
||||||
|
import Search from "@/components/search.vue";
|
||||||
|
import PatrolWrapper from "@/pages/patrolList/copmonents/patrolWrapper.vue";
|
||||||
|
import {fetchPatrolList} from "@/api/patrolList";
|
||||||
|
|
||||||
|
const finished = ref(false);
|
||||||
|
const loading = ref(false);
|
||||||
|
const loadingRefresh = ref(false);
|
||||||
|
const searchValue = ref("")
|
||||||
|
|
||||||
|
const pageData = reactive({
|
||||||
|
pageSize: 10,
|
||||||
|
pageCurrent: 1,
|
||||||
|
total: 0,
|
||||||
|
})
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
list: []
|
||||||
|
})
|
||||||
|
|
||||||
|
const onSearch = () => {
|
||||||
|
loading.value = true;
|
||||||
|
pageData.pageCurrent = 1;
|
||||||
|
data.list = []
|
||||||
|
getData()
|
||||||
|
}
|
||||||
|
|
||||||
|
const onRefresh = () => {
|
||||||
|
loading.value = false;
|
||||||
|
loadingRefresh.value = true;
|
||||||
|
finished.value = false;
|
||||||
|
pageData.pageCurrent = 1;
|
||||||
|
data.list = []
|
||||||
|
getData()
|
||||||
|
}
|
||||||
|
|
||||||
|
const onLoad = () => {
|
||||||
|
if (data.list.length >= pageData?.total) {
|
||||||
|
finished.value = true;
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
pageData.pageCurrent++
|
||||||
|
getData()
|
||||||
|
}
|
||||||
|
|
||||||
|
const parseAndJoinLx = (jsonString, type = 'lx') => {
|
||||||
|
if (!jsonString) return '';
|
||||||
|
|
||||||
|
try {
|
||||||
|
let data = jsonString;
|
||||||
|
// 如果是字符串,尝试解析为JSON
|
||||||
|
if (typeof jsonString === 'string') {
|
||||||
|
data = JSON.parse(jsonString);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理数组情况
|
||||||
|
if (Array.isArray(data)) {
|
||||||
|
return data.map(item => item?.[type]).filter(Boolean).join(",");
|
||||||
|
}
|
||||||
|
// 处理对象情况
|
||||||
|
if (typeof data === 'object' && data !== null) {
|
||||||
|
return data?.[type] || '';
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('数据处理失败:', error);
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getData = async () => {
|
||||||
|
|
||||||
|
const { total, ...ret } = pageData
|
||||||
|
try {
|
||||||
|
const res = await fetchPatrolList({ ...ret, fgMc: searchValue.value })
|
||||||
|
if (res?.records.length > 0) {
|
||||||
|
data.list = data.list.concat(res?.records)?.map((item) => ({
|
||||||
|
...item,
|
||||||
|
fgJqtjLx: parseAndJoinLx(item?.fgJqtjLx, 'lx')
|
||||||
|
})) || []
|
||||||
|
pageData.total = res?.total
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
loadingRefresh.value = false;
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
loading.value = false;
|
||||||
|
loadingRefresh.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getData()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<TopNav nav-title="巡逻列表" show-left />
|
||||||
|
|
||||||
|
<van-sticky>
|
||||||
|
<div class="header">
|
||||||
|
<search
|
||||||
|
:isSx="true"
|
||||||
|
placeholder="请输入方格名称进行查询"
|
||||||
|
v-model="searchValue"
|
||||||
|
@update:modelValue="onSearch"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</van-sticky>
|
||||||
|
|
||||||
|
<div class="content">
|
||||||
|
<van-pull-refresh v-model="loadingRefresh" @refresh="onRefresh">
|
||||||
|
<van-list v-model:loading="loading" :finished="finished" finished-text="" @load="onLoad" offset="1" :immediate-check="false">
|
||||||
|
<patrol-wrapper :list="data?.list" />
|
||||||
|
|
||||||
|
<van-empty description="暂无采集数据" image="default" v-if="data.list.length <= 0 && loadingRefresh === false" />
|
||||||
|
</van-list>
|
||||||
|
</van-pull-refresh>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.header {
|
||||||
|
margin-top: 13vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
margin-bottom: 16vw;
|
||||||
|
}
|
||||||
|
</style>
|
@ -61,6 +61,26 @@ const routes = [{
|
|||||||
name: "my",
|
name: "my",
|
||||||
component: () => import("../pages/my/index"),
|
component: () => import("../pages/my/index"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/collectPage",
|
||||||
|
name: "collectPage",
|
||||||
|
component: () => import("../pages/collectPage/index"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/collectAndAdd",
|
||||||
|
name: "collectAndAdd",
|
||||||
|
component: () => import("../pages/collectPage/collectAndAdd"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/clockInPage",
|
||||||
|
name: "clockInPage",
|
||||||
|
component: () => import("../pages/clockInPage/index"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/patrolList",
|
||||||
|
name: "patrolList",
|
||||||
|
component: () => import("../pages/patrolList/index"),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: "/dqLocation",
|
path: "/dqLocation",
|
||||||
name: "dqLocation",
|
name: "dqLocation",
|
||||||
@ -499,4 +519,4 @@ const router = createRouter({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
@ -12,8 +12,8 @@ module.exports = {
|
|||||||
port: 9528,
|
port: 9528,
|
||||||
proxy: {
|
proxy: {
|
||||||
'/mosty-api': {
|
'/mosty-api': {
|
||||||
target: "http://118.122.165.45:35623",
|
// target: "http://118.122.165.45:35623",
|
||||||
// target: "http://172.20.19.54:8006",
|
target: "http://192.168.1.8:8006",
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -29,4 +29,4 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user