修改打卡

This commit is contained in:
13684185576
2025-11-07 17:38:16 +08:00
parent b6dc821182
commit b08b634fe3
2 changed files with 38 additions and 84 deletions

View File

@ -8,7 +8,13 @@ export function fetchPatrolList(params) {
params
})
}
// 获取巡逻详情
export function selectByBBdId(params) {
return service({
url: `${api}/tbZdxlFgxlrw/selectByBBdId`,
params
})
}
export function fetchSelectListByBddxlrwId(params) {
return service({

View File

@ -12,7 +12,7 @@ import {
import { useRoute } from "vue-router";
import Timeline from "@/pages/clockInPage/components/Timeline.vue";
import {
fetchPatrolList,
selectByBBdId,
fetchSelectByBddxlrwId,
fetchSelectListByBddxlrwId,
fetchTbZdxlFgdwBddxlrwJlClockIn,
@ -29,27 +29,23 @@ const nextStep = ref(0);
const baseUrl = ref("");
const fileId = ref("");
const startTime = ref("2025-09-18 18:15:00");
const useCountdownFromTime = (minutes = 10) => {
const useCountdownFromTime = () => {
const timeLeft = ref(0); // 剩余毫秒数
const timer = ref(null);
const isRunning = ref(false); // 是否运行中
const isExpired = ref(false); // 是否过期
const expirationTime = ref(null); // 过期时间
// 计算过期时间
const calculateExpirationTime = (time) => {
const calculateExpirationTime = (time, minutes = 10) => {
if (!time) return null;
try {
const startDate = new Date(time);
if (isNaN(startDate.getTime())) return null;
return new Date(startDate.getTime() + minutes * 60000);
} catch {
return null;
}
};
// 更新倒计时
const update = () => {
if (!expirationTime.value) {
@ -57,10 +53,8 @@ const useCountdownFromTime = (minutes = 10) => {
isRunning.value = false;
return;
}
const now = new Date();
timeLeft.value = expirationTime.value - now;
if (timeLeft.value <= 0) {
timeLeft.value = 0;
isExpired.value = true;
@ -68,27 +62,23 @@ const useCountdownFromTime = (minutes = 10) => {
stop();
return;
}
if (timeLeft.value > 0) {
timer.value = setTimeout(update, 1000);
}
};
// 开始倒计时
const start = (startTime) => {
const start = (startTime, minutes) => {
stop();
expirationTime.value = calculateExpirationTime(startTime);
expirationTime.value = calculateExpirationTime(startTime, minutes);
if (!expirationTime.value) {
isExpired.value = true;
return;
}
isRunning.value = true;
isExpired.value = false;
update();
};
// 停止倒计时
const stop = () => {
if (timer.value) {
@ -97,34 +87,27 @@ const useCountdownFromTime = (minutes = 10) => {
}
isRunning.value = false;
};
// 格式化时间显示
const formattedTime = computed(() => {
if (timeLeft.value <= 0) return "00:00";
if (timeLeft.value <= 0) return '00:00';
const totalSeconds = Math.floor(timeLeft.value / 1000);
const mins = Math.floor(totalSeconds / 60);
const secs = totalSeconds % 60;
return `${mins.toString().padStart(2, "0")}:${secs
.toString()
.padStart(2, "0")}`;
return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
});
// 过期时间显示
const expirationTimeFormatted = computed(() => {
if (!expirationTime.value) return "";
return expirationTime.value.toLocaleTimeString("zh-CN", {
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
hour12: false,
if (!expirationTime.value) return '';
return expirationTime.value.toLocaleTimeString('zh-CN', {
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
});
});
// 自动清理
onUnmounted(stop);
return {
timeLeft,
formattedTime,
@ -132,7 +115,7 @@ const useCountdownFromTime = (minutes = 10) => {
isRunning,
isExpired,
start,
stop,
stop
};
};
@ -190,17 +173,16 @@ const onChange = (value) => {
nextStep.value = 0;
baseUrl.value = "";
fileId.value = "";
getPatrolList(data?.query);
getData();
};
const handleNext = (index) => {
stop();
nextStep.value = index;
start(infoData?.value?.dkKsSj);
start(infoData?.value?.dkKsSj,activeInfoData.value.dkjgsj);
};
function setimage_base64(pzid, base64) {
console.log(base64, "base64");
baseUrl.value = `data:image/jpeg;base64,${base64}`;
qcckPost({ base64: base64 }, "/mosty-base/minio/image/upload/base64").then(
(res) => {
@ -210,7 +192,6 @@ function setimage_base64(pzid, base64) {
}
const imageCache = new Map();
const getImageUrl = async (fileId) => {
if (!fileId) return null;
// 检查缓存
@ -235,7 +216,7 @@ const getImageUrl = async (fileId) => {
const getData = async () => {
try {
const res = await fetchSelectListByBddxlrwId({
bddxlrwId: activeInfoData?.value?.id || "",
bddxlrwId: activeInfoData.value.id || "",
});
if (res && res?.length > 0) {
// 获取所有唯一的图片ID
@ -290,7 +271,7 @@ const getData = async () => {
const firstItem = data.info[nextStep.value || 0];
if (firstItem?.dkKsSj) {
startTime.value = infoData?.value?.dkKsSj;
start(startTime.value);
start(startTime.value,activeInfoData.value.dkjgsj);
} else {
start("");
}
@ -336,11 +317,11 @@ function getUserLocation(sfdw) {
}
}
const getPatrolList = async ({ current, id }) => {
const res = await fetchPatrolList({ pageCurrent: current, pageSize: 10 });
if (res?.records.length > 0) {
const getPatrolList = async ({ id }) => {
const res = await selectByBBdId({ bbdId: id });
if (res) {
getUserLocation();
data.patroObj = res?.records?.find((item) => item.id === id) || {};
data.patroObj = res;
// 删除方格
emitter.emit("deletePointArea", "zdxl_fzyc");
// 生成方格
@ -370,12 +351,9 @@ const getPatrolList = async ({ current, id }) => {
// 简单的时间加法函数
const addTenMinutes = (timeString) => {
if (!timeString) return "";
const date = new Date(timeString);
if (isNaN(date.getTime())) return "";
date.setMinutes(date.getMinutes() + 10);
return date
.toLocaleString("zh-CN", {
year: "numeric",
@ -392,15 +370,12 @@ const addTenMinutes = (timeString) => {
// 判断是否超过10分钟
const isTenMinutesPassed = (startTime) => {
if (!startTime) return false;
try {
const startDate = new Date(startTime);
if (isNaN(startDate.getTime())) return false;
// 计算10分钟后的时间
const tenMinutesLater = new Date(startDate.getTime() + 10 * 60 * 1000);
const now = new Date();
// 判断当前时间是否超过10分钟后
return now > tenMinutesLater;
} catch (error) {
@ -416,18 +391,15 @@ const handleClick = async () => {
return;
}
const { id } = data.info?.[nextStep.value];
if (!isTenMinutesPassed(infoData?.value.dkKsSj) && infoData?.value.dkKsSj) {
const newTime = addTenMinutes(infoData?.value.dkKsSj);
hintToast(`请于${newTime.split(" ")[1]}后打卡`);
return;
}
if (fileId.value === "") {
hintToast("请拍照再打卡");
return;
}
const { lng, lat } = getLocation();
try {
const res = await fetchTbZdxlFgdwBddxlrwJlClockIn({
@ -456,7 +428,6 @@ onMounted(() => {
data.query = route?.query;
getPatrolList(route?.query);
}
window.setimagebase64 = setimage_base64;
});
</script>
@ -473,10 +444,7 @@ onMounted(() => {
<div class="clockInList">
<template v-for="(item, index) in data.info" :key="index">
<div
:class="['clockInList_item', { active: nextStep === index }]"
@click="handleNext(index)"
>
<div :class="['clockInList_item', { active: nextStep === index }]" @click="handleNext(index)">
<div class="label">{{ `${item?.count}次打卡` }}</div>
<div class="dec">
<van-icon v-if="item?.dkKsSj" name="checked" color="#007DE9" />
@ -498,18 +466,8 @@ onMounted(() => {
<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"
>
<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>
@ -527,29 +485,17 @@ onMounted(() => {
</div>
<div class="clockWrapper">
<div
v-if="!infoData?.dkJsSj || !infoData?.dkKsSj"
class="circleWrapper"
:class="{
<div v-if="!infoData?.dkJsSj || !infoData?.dkKsSj" class="circleWrapper" :class="{
disabled: (!isExpired && expirationTime) || infoData?.dkJsSj,
}"
@click="handleClick"
>
}" @click="handleClick">
<div v-if="!isExpired && expirationTime" class="time">
{{ formattedTime }}
</div>
<div class="title">{{ !infoData?.dkKsSj ? `开始` : `离开` }}</div>
<div class="info">{{ `${infoData?.count || ""}次打卡` }}</div>
</div>
<div
v-else
class="circleWrapper"
:class="{
disabled: (!isExpired && expirationTime) || infoData?.dkJsSj,
}"
>
<div v-else class="circleWrapper" :class="{ disabled: (!isExpired && expirationTime) || infoData?.dkJsSj,}">
<div class="title">已结束</div>
<!-- <div class="info">{{ `${infoData?.count || ''}次打卡` }}</div>-->
</div>
<div class="circleWrapperTip">
<van-icon name="success" color="#FFFFFF" />
@ -713,6 +659,7 @@ onMounted(() => {
.van-icon-checked {
margin-right: 1.33vw;
}
.time {
margin-left: 1.33vw;
}
@ -728,6 +675,7 @@ onMounted(() => {
.van-tabs__nav {
flex-wrap: wrap;
}
.van-tabs__nav--line {
padding-bottom: 0 !important;
}