| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445 |
- <template>
- <view class="container">
- <!-- 时间日期信息 -->
- <view class="header">
- <text class="day">{{ currentDay }}</text>
- <text class="date">{{ currentDate }}</text>
- <text class="status">{{clockInStatus}}</text>
- </view>
- <!-- 打卡记录 -->
- <view class="record">
- <view class="record-item">
- <text class="ygoa-icon icon-goToWork"></text>
- <text class="title">上班</text>
- <text class="time">{{ signInTime ||'未打卡'}}</text>
- </view>
- <view class="record-item">
- <text class="ygoa-icon icon-afterWork"></text>
- <text class="title">下班</text>
- <text class="time">{{ signOutTime ||'未打卡'}}</text>
- </view>
- <view class="record-item" @click="getAddress">
- <text class="ygoa-icon icon-location"></text>
- <text class="title">当前位置</text>
- <text class="time">{{ address ||'点击获取定位'}}</text>
- </view>
- </view>
- <!-- 地图 -->
- <atl-map :mapKey="mapKey" :mapType="mapType" @confirm="confirm" :marker="marker" :polygons="polygons"
- :isPolygons="true">
- <template v-slot:content>
- <view style="position: absolute; bottom: 0; width: 100%; height: 24px; background-color: white">
- <view style="display: flex; align-items: center; justify-content: center">
- </view>
- </view>
- </template>
- </atl-map>
- <!-- 打卡按钮 -->
- <view class="footer">
- <button type="primary" @click="signIn">上班签到</button>
- <button type="default" @click="signOut">下班签退</button>
- </view>
- </view>
- </template>
- <script setup>
- import {
- onMounted,
- reactive,
- ref
- } from 'vue';
- // 导入地理位置相关函数
- import booleanPointInPolygon from "@turf/boolean-point-in-polygon";
- import {
- point,
- polygon
- } from "@turf/helpers";
- import {
- CheckAttendance
- } from '@/api/mine/checkIn';
- import {
- useUserStore
- } from '@/store/user';
- import {createAttendance} from '@/api/mine/clockIn.js'
- const userStore = useUserStore();
- const thisUser=ref();
- const userId = ref('')
- // 组件挂载后初始化当前日期与位置
- onMounted(() => {
- thisUser.value=userStore.user;
- console.log('thisUser',thisUser.value);
- userId.value = userStore.user.useId;
- dateInit();
- getlocation();
- });
- // 当前日期和时间相关信息
- const currentDate = ref('2023-04-01');
- const currentDay = ref('星期三');
- const clockInStatus = ref(''); // 打卡状态
- const weekArr = reactive(['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']); // 星期数组
- const signInTime = ref(''); // 上班签到时间
- const signOutTime = ref(''); // 下班签到时间
- // 初始化日期
- function dateInit() {
- const nowDate = new Date();
- const year = nowDate.getFullYear(); // 获取年份
- const month = nowDate.getMonth() + 1; // 获取月份
- const day = nowDate.getDate(); // 获取日期
- // 格式化月份和日期为两位数
- const formattedMonth = month < 10 ? '0' + month : month;
- const formattedDay = day < 10 ? '0' + day : day;
- currentDate.value = `${year}-${formattedMonth}-${formattedDay}`; // 设置当前日期
- const dayOfWeek = nowDate.getDay(); // 获取当前星期
- currentDay.value = weekArr[dayOfWeek]; // 设置当前星期
- getTodayAtt();
- }
- //获取今天考勤状态
- function getTodayAtt() {
-
- const params = {
- universalid: userId.value,
- rizi: currentDate.value
- }
- CheckAttendance(params).then(res => {
- if ("success" == res.returnMsg) {
- // console.log("kaoqin",res);
- const attList = res.returnParams.list;
- const time1 = attList.find(item => item.att_type_id === '1');
- const time2 = attList.find(item => item.att_type_id === '2');
- if (time1 !== undefined) {
- signInTime.value = time1.att_time.split(' ')[1];
- }
- if (time2 !== undefined) {
- signOutTime.value = time2.att_time.split(' ')[1];
- }
- }
- })
- }
- const attType=ref(0)
- // 上班签到
- function signIn() {
- const now = getNowTime();
- //判断打卡时间是否符合
- if (!isTimeInRange(now, '08:30:00', '10:00:00')) {
- uni.showToast({
- title: "不在签到时间8:30--10:00内",
- icon: 'none'
- });
- return;
- }
- attType.value=1;
-
- getAddress();
- clockIn(); // 执行打卡
- };
- // 下班签退
- function signOut() {
- const now = getNowTime();
- //判断打卡时间是否符合
- if (!isTimeInRange(now, '15:00:00', '20:00:00')) {
- uni.showToast({
- title: "不在签退时间15:00--20:00内",
- icon: 'none'
- });
- return;
- }
- attType.value=2;
- getAddress();
- clockIn(); // 执行打卡并获取结果
- };
- //获取当前时间
- function getNowTime() {
- var now = new Date();
- // 获取小时、分钟和秒
- var hours = now.getHours(); // 获取小时(0-23)
- var minutes = now.getMinutes(); // 获取分钟(0-59)
- var seconds = now.getSeconds(); // 获取秒(0-59)
- // 将小时、分钟或秒格式化为两位数
- hours = hours < 10 ? '0' + hours : hours;
- minutes = minutes < 10 ? '0' + minutes : minutes;
- seconds = seconds < 10 ? '0' + seconds : seconds;
- return `${hours}:${minutes}:${seconds}`;
- }
- //判断时间是否在区间内
- function isTimeInRange(time, startTime, endTime) {
- // 将时间字符串转换为Date对象
- var timeObj = new Date('1970-01-01T' + time + 'Z');
- var startObj = new Date('1970-01-01T' + startTime + 'Z');
- var endObj = new Date('1970-01-01T' + endTime + 'Z');
- // 比较时间
- return timeObj >= startObj && timeObj <= endObj;
- }
- // 地图配置信息
- const mapKey = ref('KJBBZ-5JCLZ-3NLXD-742CK-Y26UZ-X7BJN'); // 地图API密钥
- const mapType = ref('tmap'); // 地图类型
- const address = ref(''); // 初始化地址
- // 打卡定位信息
- const longitude = ref(0); // 经度
- const latitude = ref(0); // 纬度
- // 标记信息
- const marker = reactive({
- id: 1,
- latitude: 25.958812,
- longitude: 119.213036,
- width: 50, // 标记宽度
- height: 50, // 标记高度
- title: '宇光同行' // 标记标题
- });
- // 获取当前定位经纬度
- function getlocation() {
- wx.getLocation({
- // type: 'gcj02',
- success: (res) => {
- // console.log('当前位置的经度:' + JSON.stringify(res));
- // console.log('当前位置的经度:','gcj02' + JSON.stringify(res));
- console.log('当前位置的经度:' + res.longitude);
- console.log('当前位置的纬度:' + res.latitude);
- longitude.value = res.longitude; // 保存经度
- latitude.value = res.latitude; // 保存纬度
- },
- fail: (err) => {
- // 获取位置失败时提示用户打开权限
- uni.showModal({
- content: '检测到您没打开获取位置功能权限,是否去设置打开?',
- confirmText: "确认",
- cancelText: '取消',
- success: (res) => {
- if (res.confirm) {
- uni.openSetting({
- success: (res) => {
- uni.showToast({
- title: '授权后请重新打开此页面',
- icon: 'none'
- });
- },
- fail: (err) => {
- // console.log(err);
- }
- });
- } else {
- uni.showToast({
- title: '获取地理位置授权失败',
- icon: 'none',
- success: () => {
- // 返回上一页
- setTimeout(() => {
- uni.showToast({
- title: "返回上一页",
- icon: 'none'
- });
- }, 500);
- }
- });
- }
- }
- });
- },
- });
- }
- // 获取当前位置地址
- async function getAddress() {
- getlocation(); // 获取当前位置
- tranAddress(); // 执行地址转换
- }
- // 经纬度转地址
- function tranAddress() {
- let locationStr = latitude.value + ',' + longitude.value; // 组合经纬度
- uni.request({
- url: 'https://apis.map.qq.com/ws/geocoder/v1/?location=' + locationStr + '&key=' + mapKey.value +
- '&get_poi=1',
- method: 'GET',
- success: function(res) {
- console.log('请求成功', res.data);
- address.value = res.data.result.address; // 保存地址
- },
- fail: function(err) {
- console.error('请求失败', err); // 请求错误处理
- }
- });
- }
- // 多边形区域设置
- const polygons = reactive([{
- points: [{
- latitude: 25.9591401,
- longitude: 119.21292356
- },
- {
- latitude: 25.95828592,
- longitude: 119.21261955
- },
- {
- latitude: 25.9576709,
- longitude: 119.21458294
- },
- {
- latitude: 25.95845106,
- longitude: 119.21486162
- },
- {
- latitude: 25.9591401,
- longitude: 119.21292356
- }
- ],
- strokeWidth: 1, // 边框宽度
- strokeColor: "#ff000066", // 边框颜色
- fillColor: "#ff000016", // 填充颜色
- }]);
- // 打卡
- function clockIn() {
- //TODO: 发起打卡请求相关业务逻辑
- var now = new Date();
- // 使用toISOString()获取一个ISO格式的字符串,然后替换T为空格,并去除最后的Z(表示UTC时间)
- var formatted = now.toISOString().replace('T', ' ').replace('Z', '');
- var localString = new Date(formatted + '+08:00').toISOString().replace('T', ' ').replace('Z', '');
- const params = {
- user_name: thisUser.value.userName,
- user_id: thisUser.value.useId,
- kaoqin_type: attType.value,
- now_date: localString,
- longitude: longitude.value,
- latitude: latitude.value,
- address: address.value,
- unitId: thisUser.value.unitId
- };
- createAttendance(params).then(res=>{
- // console.log('createAttendance',res);
- if ("success"==res.returnMsg) {
- uni.showToast({
- title: "打卡成功",
- icon: 'none'
- });
- getTodayAtt(); //更新今日考勤数据
- } else {
- uni.showToast({
- title: "未在指定范围,打卡失败",
- icon: 'none'
- });
- }
- })
- // const _polygons = polygons.map((polygon) => {
- // return polygon.points.map((i) => [
- // Number(i.longitude),
- // Number(i.latitude),
- // ]);
- // });
- // const _point = point([longitude.value, latitude.value]); // 用当前坐标创建点
- // const _polygon = polygon(_polygons); // 创建多边形
- // const f = booleanPointInPolygon(_point, _polygon); // 判断点是否在多边形内
-
-
- }
- </script>
- <style>
- @import "@/static/font/ygoa/iconfont.css";
- .ygoa-icon {
- margin-right: 20rpx;
- font-size: 50rpx;
- }
- .container {
- display: flex;
- flex-direction: column;
- align-items: center;
- padding: 20rpx;
- }
- .header {
- width: 100%;
- height: 200rpx;
- background-color: #f8f8f8;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- }
- .day {
- font-size: 55rpx;
- font-weight: bold;
- }
- .date {
- font-size: 30rpx;
- color: #666;
- }
- .status {
- font-size: 24rpx;
- color: black;
- }
- .record {
- width: 100%;
- margin-top: 20rpx;
- border-top: 1px solid #ddd;
- border-bottom: 1px solid #ddd;
- padding: 0 15rpx;
- }
- .record-item {
- display: flex;
- align-items: center;
- height: 100rpx;
- border-bottom: 1px solid #eee;
- }
- .icon {
- width: 50rpx;
- height: 50rpx;
- margin-right: 10rpx;
- }
- .title {
- font-size: 28rpx;
- }
- .time {
- font-size: 24rpx;
- color: #999;
- margin-left: auto;
- }
- .map {
- width: 100%;
- height: 500rpx;
- margin-top: 20rpx;
- }
- .footer {
- width: 100%;
- margin-top: 20rpx;
- display: flex;
- justify-content: space-around;
- }
- button {
- width: 45%;
- }
- </style>
|