下发任务 修改任务处理
This commit is contained in:
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: '巡逻打卡',
|
||||
imgUrl: require("@/assets/home/xldk.png"),
|
||||
type: 'xldk',
|
||||
path: '/clock'
|
||||
path: '/patrolList'
|
||||
},
|
||||
{
|
||||
text: '信息交互',
|
||||
@ -39,6 +39,12 @@ const listData = ref([
|
||||
type: 'zllz',
|
||||
path: '/yyzx/zlzx/zlzxIndex'
|
||||
},
|
||||
{
|
||||
text: '必到点采集',
|
||||
imgUrl: require("@/assets/home/bddcj.png"),
|
||||
type: 'bddcj',
|
||||
path: '/collectPage'
|
||||
},
|
||||
{
|
||||
text: '处警报送',
|
||||
imgUrl: require("@/assets/home/dqwz.png"),
|
||||
@ -59,6 +65,8 @@ const changeOpen = (val) => {
|
||||
case 'zllz':
|
||||
case 'grxx':
|
||||
case 'cjbs':
|
||||
case 'bddcj':
|
||||
case 'clockIn':
|
||||
router.push(val.path)
|
||||
break
|
||||
case 'rcpc':
|
||||
@ -79,6 +87,7 @@ ul {
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
height: 100vh;
|
||||
overflow: auto;
|
||||
|
||||
li {
|
||||
width: 48%;
|
||||
@ -91,4 +100,4 @@ ul {
|
||||
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>
|
Reference in New Issue
Block a user