更新自动打卡
This commit is contained in:
16
src/App.vue
16
src/App.vue
@ -251,22 +251,6 @@ body {
|
|||||||
padding: 20vw 0 4vw 0;
|
padding: 20vw 0 4vw 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 首页头部banner和按钮 */
|
|
||||||
.leaderTop {
|
|
||||||
height: 45.33334vw;
|
|
||||||
background: url("./assets/images/new/banner.png") no-repeat;
|
|
||||||
background-size: 100% 100%;
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
top: -6vw;
|
|
||||||
margin-bottom: 7vw;
|
|
||||||
}
|
|
||||||
|
|
||||||
.isGq {
|
|
||||||
background: url("./assets/images/new/banner_gq.png") no-repeat;
|
|
||||||
background-size: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.welcome {
|
.welcome {
|
||||||
font-size: 4.26667vw;
|
font-size: 4.26667vw;
|
||||||
// padding: 14.46667vw 4.73334vw 0 5.73334vw;
|
// padding: 14.46667vw 4.73334vw 0 5.73334vw;
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 134 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 130 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 3.0 KiB |
@ -1,28 +1,78 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<top-nav navTitle="打卡" :showLeft="true" />
|
||||||
|
<div class="clockInWrapper">
|
||||||
|
<van-tabs v-model:active="active" @click="onChange">
|
||||||
|
<template v-for="(item, index) in data.patroObj?.bddList" :key="index">
|
||||||
|
<van-tab :title="item.bddMc" />
|
||||||
|
</template>
|
||||||
|
</van-tabs>
|
||||||
|
<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="label">{{ `第${item?.count}次打卡` }}</div>
|
||||||
|
<div class="dec">
|
||||||
|
<van-icon v-if="item?.dkKsSj" name="checked" color="#007DE9" />
|
||||||
|
<div>开始</div>
|
||||||
|
<div v-if="item?.dkKsSj" class="time">{{ item?.dkKsSj?.split(" ")[1] }}已打卡</div>
|
||||||
|
</div>
|
||||||
|
<div class="dec">
|
||||||
|
<van-icon v-if="item?.dkJsSj" name="checked" color="#007DE9" />
|
||||||
|
<div>离开</div>
|
||||||
|
<div v-if="item?.dkJsSj" class="time">{{ item?.dkJsSj?.split(" ")[1] }}已打卡</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</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 @click="handleClick" v-if="!infoData?.dkJsSj || !infoData?.dkKsSj" class="circleWrapper" :class="{ disabled: (!isExpired && expirationTime) || infoData?.dkJsSj }" >
|
||||||
|
<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 class="title">已结束</div>
|
||||||
|
</div>
|
||||||
|
<div class="circleWrapperTip">
|
||||||
|
<van-icon name="success" color="#FFFFFF" />
|
||||||
|
<div>已进入考勤范围:{{ activeInfoData?.bddMc }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<timeline v-if="data.info.length > 0" :data="[data.info?.[nextStep]]" />
|
||||||
|
<map-wrapper />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import TopNav from "@/components/topNav.vue";
|
import TopNav from "@/components/topNav.vue";
|
||||||
import {
|
import { onMounted, reactive, ref, computed, nextTick, onUnmounted } from "vue";
|
||||||
onMounted,
|
|
||||||
reactive,
|
|
||||||
ref,
|
|
||||||
computed,
|
|
||||||
nextTick,
|
|
||||||
onUnmounted,
|
|
||||||
watch,
|
|
||||||
} from "vue";
|
|
||||||
import { useRoute } from "vue-router";
|
import { useRoute } from "vue-router";
|
||||||
import Timeline from "@/pages/clockInPage/components/Timeline.vue";
|
import Timeline from "@/pages/clockInPage/components/Timeline.vue";
|
||||||
import {
|
import { selectByBBdId, fetchSelectByBddxlrwId, fetchSelectListByBddxlrwId, fetchTbZdxlFgdwBddxlrwJlClockIn } from "@/api/patrolList";
|
||||||
selectByBBdId,
|
|
||||||
fetchSelectByBddxlrwId,
|
|
||||||
fetchSelectListByBddxlrwId,
|
|
||||||
fetchTbZdxlFgdwBddxlrwJlClockIn,
|
|
||||||
} from "@/api/patrolList";
|
|
||||||
import { getBase64, hintToast } from "@/utils/tools";
|
import { getBase64, hintToast } from "@/utils/tools";
|
||||||
import { ImagePreview } from "vant";
|
import { ImagePreview } from "vant";
|
||||||
import { qcckPost, qcckGet } from "@/api/qcckApi";
|
import { qcckPost, qcckGet } from "@/api/qcckApi";
|
||||||
import MapWrapper from "@/pages/clockInPage/components/mapWrapper.vue";
|
import MapWrapper from "@/pages/clockInPage/components/mapWrapper.vue";
|
||||||
import emitter from "@/utils/eventBus";
|
import emitter from "@/utils/eventBus";
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const active = ref(0);
|
const active = ref(0);
|
||||||
const nextStep = ref(0);
|
const nextStep = ref(0);
|
||||||
@ -129,8 +179,7 @@ const infoData = computed(() => {
|
|||||||
return data.info?.[nextStep.value];
|
return data.info?.[nextStep.value];
|
||||||
});
|
});
|
||||||
const activeInfoData = computed(() => data.patroObj?.bddList?.[active.value]);
|
const activeInfoData = computed(() => data.patroObj?.bddList?.[active.value]);
|
||||||
const { formattedTime, isExpired, expirationTime, start, stop } =
|
const { formattedTime, isExpired, expirationTime, start, stop } = useCountdownFromTime();
|
||||||
useCountdownFromTime();
|
|
||||||
// 删除打卡图片
|
// 删除打卡图片
|
||||||
const clearImage = () => {
|
const clearImage = () => {
|
||||||
baseUrl.value = "";
|
baseUrl.value = "";
|
||||||
@ -183,20 +232,16 @@ const handleNext = (index) => {
|
|||||||
|
|
||||||
function setimage_base64(pzid, base64) {
|
function setimage_base64(pzid, base64) {
|
||||||
baseUrl.value = `data:image/jpeg;base64,${base64}`;
|
baseUrl.value = `data:image/jpeg;base64,${base64}`;
|
||||||
qcckPost({ base64: base64 }, "/mosty-base/minio/image/upload/base64").then(
|
qcckPost({ base64: base64 }, "/mosty-base/minio/image/upload/base64").then((res) => {
|
||||||
(res) => {
|
fileId.value = res;
|
||||||
fileId.value = res;
|
});
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const imageCache = new Map();
|
const imageCache = new Map();
|
||||||
const getImageUrl = async (fileId) => {
|
const getImageUrl = async (fileId) => {
|
||||||
if (!fileId) return null;
|
if (!fileId) return null;
|
||||||
// 检查缓存
|
// 检查缓存
|
||||||
if (imageCache.has(fileId)) {
|
if (imageCache.has(fileId)) return imageCache.get(fileId);
|
||||||
return imageCache.get(fileId);
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
const res = await qcckGet({}, `/mosty-base/minio/file/download/${fileId}`);
|
const res = await qcckGet({}, `/mosty-base/minio/file/download/${fileId}`);
|
||||||
if (res?.url) {
|
if (res?.url) {
|
||||||
@ -214,79 +259,64 @@ const getImageUrl = async (fileId) => {
|
|||||||
|
|
||||||
const getData = async () => {
|
const getData = async () => {
|
||||||
try {
|
try {
|
||||||
const res = await fetchSelectListByBddxlrwId({
|
const res = await fetchSelectListByBddxlrwId({ bddxlrwId: activeInfoData.value.id || "", });
|
||||||
bddxlrwId: activeInfoData.value.id || "",
|
let listArr = res || [];
|
||||||
|
// 获取所有唯一的图片ID
|
||||||
|
const uniqueImageIds = new Set();
|
||||||
|
listArr.forEach((item) => {
|
||||||
|
if (item?.dkJsFj) uniqueImageIds.add(item.dkJsFj);
|
||||||
|
if (item?.dkKsFj) uniqueImageIds.add(item.dkKsFj);
|
||||||
});
|
});
|
||||||
if (res && res?.length > 0) {
|
// 批量获取图片URL
|
||||||
// 获取所有唯一的图片ID
|
const imageEntries = await Promise.allSettled(
|
||||||
const uniqueImageIds = new Set();
|
Array.from(uniqueImageIds).map(async (id) => {
|
||||||
res?.forEach((item) => {
|
try {
|
||||||
if (item?.dkJsFj) uniqueImageIds.add(item.dkJsFj);
|
const url = await getImageUrl(id);
|
||||||
if (item?.dkKsFj) uniqueImageIds.add(item.dkKsFj);
|
return { id, url };
|
||||||
});
|
} catch (error) {
|
||||||
// 批量获取图片URL
|
return { id, url: null };
|
||||||
const imageEntries = await Promise.allSettled(
|
|
||||||
Array.from(uniqueImageIds).map(async (id) => {
|
|
||||||
try {
|
|
||||||
const url = await getImageUrl(id);
|
|
||||||
return { id, url };
|
|
||||||
} catch (error) {
|
|
||||||
return { id, url: null };
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
// 创建图片映射表
|
|
||||||
const imageMap = new Map();
|
|
||||||
imageEntries.forEach((entry) => {
|
|
||||||
if (entry.status === "fulfilled") {
|
|
||||||
imageMap.set(entry.value.id, entry.value.url);
|
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
);
|
||||||
|
// 创建图片映射表
|
||||||
|
const imageMap = new Map();
|
||||||
|
imageEntries.forEach((entry) => {
|
||||||
|
if (entry.status === "fulfilled") imageMap.set(entry.value.id, entry.value.url);
|
||||||
|
});
|
||||||
|
|
||||||
// 设置数据
|
// 设置数据
|
||||||
data.info = res.map((item, index) => ({
|
data.info = listArr.map((item, index) => ({
|
||||||
...item,
|
...item,
|
||||||
count: getChineseNumber(index + 1),
|
count: getChineseNumber(index + 1),
|
||||||
imgUrlDkJsFj: item?.dkJsFj ? imageMap.get(item.dkJsFj) : null,
|
imgUrlDkJsFj: item?.dkJsFj ? imageMap.get(item.dkJsFj) : null,
|
||||||
imgUrlDkKsFj: item?.dkKsFj ? imageMap.get(item.dkKsFj) : null,
|
imgUrlDkKsFj: item?.dkKsFj ? imageMap.get(item.dkKsFj) : null,
|
||||||
}));
|
}));
|
||||||
// 打卡结束经纬度
|
// 打卡结束经纬度
|
||||||
const dkJs = res?.map((i) => ({ jd: i?.dkJsJd, wd: i?.dkJsWd }));
|
const dkJs = listArr.map((i) => ({ jd: i.dkJsJd, wd: i.dkJsWd }));
|
||||||
// 打卡开始经纬度
|
// 打卡开始经纬度
|
||||||
const dkKs = res?.map((i) => ({ jd: i?.dkKsJd, wd: i?.dkKsWd }));
|
const dkKs = listArr.map((i) => ({ jd: i.dkKsJd, wd: i.dkKsWd }));
|
||||||
// 删除标注
|
|
||||||
emitter.emit("deletePointArea", "annotationDkKs");
|
emitter.emit("deletePointArea", "annotationDkKs");// 删除标注
|
||||||
//地图撒点然后移动
|
emitter.emit("addPointArea", { coords: [...dkJs, ...dkKs], icon: require("../../assets/images/11.png"), flag: "annotationDkKs", });//地图撒点然后移动
|
||||||
emitter.emit("addPointArea", {
|
|
||||||
coords: [...dkJs, ...dkKs],
|
|
||||||
icon: require("../../assets/images/11.png"),
|
|
||||||
flag: "annotationDkKs",
|
|
||||||
});
|
|
||||||
|
|
||||||
await nextTick(() => {
|
await nextTick(() => {
|
||||||
const firstItem = data.info[nextStep.value || 0];
|
const firstItem = data.info[nextStep.value || 0];
|
||||||
if (firstItem?.dkKsSj) {
|
if (firstItem?.dkKsSj) {
|
||||||
startTime.value = infoData?.value?.dkKsSj;
|
startTime.value = infoData?.value?.dkKsSj;
|
||||||
start(startTime.value, activeInfoData.value.dkjgsj);
|
start(startTime.value, activeInfoData.value.dkjgsj);
|
||||||
} else {
|
} else {
|
||||||
start("");
|
start("");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
if (activeInfoData.value) {
|
if (activeInfoData.value) {
|
||||||
const result = await fetchSelectByBddxlrwId(
|
const result = await fetchSelectByBddxlrwId(activeInfoData?.value?.id || "" );
|
||||||
activeInfoData?.value?.id || ""
|
|
||||||
);
|
|
||||||
if (result) {
|
if (result) {
|
||||||
const { jd, wd } = result;
|
const { jd, wd } = result;
|
||||||
// 删除标注
|
// 删除标注
|
||||||
emitter.emit("deletePointArea", "checkPoint");
|
emitter.emit("deletePointArea", "checkPoint");
|
||||||
//地图撒点然后移动
|
//地图撒点然后移动
|
||||||
emitter.emit("addPointArea", {
|
let icon = require("../../assets/pointIcon/peoplePolice.png")
|
||||||
coords: [{ jd, wd }],
|
emitter.emit("addPointArea", { coords: [{ jd, wd }], icon:icon , flag: "checkPoint" });
|
||||||
icon: require("../../assets/lz/peoplePolice.png"),
|
|
||||||
flag: "checkPoint",
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -300,14 +330,8 @@ function getUserLocation(sfdw) {
|
|||||||
if (lng && lat) {
|
if (lng && lat) {
|
||||||
emitter.emit("deletePointArea", "dw");
|
emitter.emit("deletePointArea", "dw");
|
||||||
//地图撒点然后移动
|
//地图撒点然后移动
|
||||||
emitter.emit("addPointArea", {
|
let icon = require("../../assets/images/dw.png")
|
||||||
coords: [{ jd: lng, wd: lat }],
|
emitter.emit("addPointArea", { coords: [{ jd: lng, wd: lat }], icon: icon, flag: "dw", sfdw: sfdw, sizeX: 30, sizeY: 35 });
|
||||||
icon: require("../../assets/lz/dw.png"),
|
|
||||||
flag: "dw",
|
|
||||||
sfdw: sfdw,
|
|
||||||
sizeX: 30,
|
|
||||||
sizeY: 35,
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
hintToast("暂无坐标信息");
|
hintToast("暂无坐标信息");
|
||||||
}
|
}
|
||||||
@ -323,22 +347,10 @@ const getPatrolList = async ({ id }) => {
|
|||||||
// 生成方格
|
// 生成方格
|
||||||
const { x1, y1, x2, y2, fgId, zxX, zxY, fgMc } = data.patroObj;
|
const { x1, y1, x2, y2, fgId, zxX, zxY, fgMc } = data.patroObj;
|
||||||
const centerPoint = [zxX, zxY];
|
const centerPoint = [zxX, zxY];
|
||||||
const position = [
|
const position = [[Number(x1), Number(y1)],[Number(x2), Number(y2)]];
|
||||||
[Number(x1), Number(y1)],
|
|
||||||
[Number(x2), Number(y2)],
|
|
||||||
];
|
|
||||||
const text = fgMc;
|
const text = fgMc;
|
||||||
const obj = [
|
const obj = [{ position: position, text, id: fgId, userData: activeInfoData?.value }];
|
||||||
{ position: position, text, id: fgId, userData: activeInfoData?.value },
|
emitter.emit("echoPlane", { fontColor: "#12fdb8", coords: obj, type: "rectangle", flag: "zdxl_fzyc", color: "rgba(2,20,51,0.5)", linecolor: "#1C97FF" });
|
||||||
];
|
|
||||||
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: 12 });
|
emitter.emit("setMapCenter", { location: centerPoint, zoomLevel: 12 });
|
||||||
await getData();
|
await getData();
|
||||||
}
|
}
|
||||||
@ -350,17 +362,15 @@ const addTenMinutes = (timeString) => {
|
|||||||
const date = new Date(timeString);
|
const date = new Date(timeString);
|
||||||
if (isNaN(date.getTime())) return "";
|
if (isNaN(date.getTime())) return "";
|
||||||
date.setMinutes(date.getMinutes() + 10);
|
date.setMinutes(date.getMinutes() + 10);
|
||||||
return date
|
return date.toLocaleString("zh-CN", {
|
||||||
.toLocaleString("zh-CN", {
|
year: "numeric",
|
||||||
year: "numeric",
|
month: "2-digit",
|
||||||
month: "2-digit",
|
day: "2-digit",
|
||||||
day: "2-digit",
|
hour: "2-digit",
|
||||||
hour: "2-digit",
|
minute: "2-digit",
|
||||||
minute: "2-digit",
|
second: "2-digit",
|
||||||
second: "2-digit",
|
hour12: false,
|
||||||
hour12: false,
|
}).replace(/\//g, "-");
|
||||||
})
|
|
||||||
.replace(/\//g, "-");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 判断是否超过10分钟
|
// 判断是否超过10分钟
|
||||||
@ -382,29 +392,17 @@ const isTenMinutesPassed = (startTime) => {
|
|||||||
|
|
||||||
// 打卡
|
// 打卡
|
||||||
const handleClick = async () => {
|
const handleClick = async () => {
|
||||||
if (data.info.length == 0) {
|
if (data.info.length == 0) return hintToast("此方格没有必打卡点位!");
|
||||||
hintToast("此方格没有必打卡点位!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const { id } = data.info?.[nextStep.value];
|
const { id } = data.info?.[nextStep.value];
|
||||||
if (!isTenMinutesPassed(infoData?.value.dkKsSj) && infoData?.value.dkKsSj) {
|
if (!isTenMinutesPassed(infoData?.value.dkKsSj) && infoData?.value.dkKsSj) {
|
||||||
const newTime = addTenMinutes(infoData?.value.dkKsSj);
|
const newTime = addTenMinutes(infoData?.value.dkKsSj);
|
||||||
hintToast(`请于${newTime.split(" ")[1]}后打卡`);
|
return hintToast(`请于${newTime.split(" ")[1]}后打卡`);
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (fileId.value === "") {
|
|
||||||
hintToast("请拍照再打卡");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
if (fileId.value === "") return hintToast("请拍照再打卡");
|
||||||
const { lng, lat } = getLocation();
|
const { lng, lat } = getLocation();
|
||||||
try {
|
try {
|
||||||
const res = await fetchTbZdxlFgdwBddxlrwJlClockIn({
|
const res = await fetchTbZdxlFgdwBddxlrwJlClockIn({ id, dkWd: lat, dkJd: lng, dkFj: fileId.value });
|
||||||
id,
|
|
||||||
dkWd: lat,
|
|
||||||
dkJd: lng,
|
|
||||||
dkFj: fileId.value,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
hintToast(`打卡成功`);
|
hintToast(`打卡成功`);
|
||||||
baseUrl.value = ""; //打卡成功需要把图片删除掉
|
baseUrl.value = ""; //打卡成功需要把图片删除掉
|
||||||
@ -428,78 +426,6 @@ onMounted(() => {
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<top-nav navTitle="打卡" :showLeft="true" />
|
|
||||||
<div class="clockInWrapper">
|
|
||||||
<van-tabs v-model:active="active" @click="onChange">
|
|
||||||
<template v-for="(item, index) in data.patroObj?.bddList" :key="index">
|
|
||||||
<van-tab :title="item.bddMc" />
|
|
||||||
</template>
|
|
||||||
</van-tabs>
|
|
||||||
<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="label">{{ `第${item?.count}次打卡` }}</div>
|
|
||||||
<div class="dec">
|
|
||||||
<van-icon v-if="item?.dkKsSj" name="checked" color="#007DE9" />
|
|
||||||
<div>开始</div>
|
|
||||||
<div v-if="item?.dkKsSj" class="time">
|
|
||||||
{{ item?.dkKsSj?.split(" ")[1] }}已打卡
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="dec">
|
|
||||||
<van-icon v-if="item?.dkJsSj" name="checked" color="#007DE9" />
|
|
||||||
<div>离开</div>
|
|
||||||
<div v-if="item?.dkJsSj" class="time">
|
|
||||||
{{ item?.dkJsSj?.split(" ")[1] }}已打卡
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</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 v-if="!infoData?.dkJsSj || !infoData?.dkKsSj" class="circleWrapper" :class="{
|
|
||||||
disabled: (!isExpired && expirationTime) || infoData?.dkJsSj,
|
|
||||||
}" @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 class="title">已结束</div>
|
|
||||||
</div>
|
|
||||||
<div class="circleWrapperTip">
|
|
||||||
<van-icon name="success" color="#FFFFFF" />
|
|
||||||
<div>已进入考勤范围:{{ activeInfoData?.bddMc }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<timeline v-if="data.info.length > 0" :data="[data.info?.[nextStep]]" />
|
|
||||||
<map-wrapper />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.clockInWrapper {
|
.clockInWrapper {
|
||||||
|
|||||||
Reference in New Issue
Block a user