Compare commits

2 Commits

Author SHA1 Message Date
wangzhuo
f76757198c feat: 出差打卡 2025-09-19 13:42:31 +08:00
wangzhuo
74f4712e9d fix: 自定义弹窗组件支持内容居中 2025-09-19 13:41:02 +08:00
4 changed files with 278 additions and 252 deletions

View File

@@ -10,6 +10,14 @@ export function addStartMap(data) {
});
}
//出差打卡接口
export function businessTripClockIn(data) {
return request.post({
url: '/crm/app/appVisistMap/businessTripClockIn',
data
},{isTransformResponse:false});
}
//新增地图开始打卡接口
export function addStartMapForClockIn(data) {
return request.post({

View File

@@ -8,7 +8,7 @@
<view v-if="closeTip" style="color:rgba(255,255,255,0.15); letter-spacing: 5rpx; margin-top: 50%;text-align: center">{{closeTip}}</view>
<view class="model-con" @click.stop>
<view class="model-top" v-if="title">{{ title }}</view>
<view :class="{'model-middle': true,'m-height': !title}">
<view :class="{'model-middle': true,'m-height': !title, 'align-center': contentAlign==='center'}">
<view v-for="text in content.split('\n')">{{text}}</view>
</view>
<view class="model-bottom">
@@ -39,6 +39,9 @@ const props = defineProps({
content: {
type: String
},
contentAlign: {
type: String
},
cancelBtn: {
type: Boolean,
default: true
@@ -130,6 +133,10 @@ const handleConfirm = () => {
}
}
.align-center{
text-align: center;
}
.m-height {
padding-top: 28rpx;
}

View File

@@ -0,0 +1,22 @@
/**
* @description 定位API的配置
* @type {{URL: string, token: string}}
*/
export const MapApiConfig = {
/**
* @description API接口地址
*/
URL: 'https://tiles.geovisearth.com/geo/v1/geocode/regeo',
/**
* @description 接口鉴权Token
*/
token: '66c87c897f0251295afdc794e4fbf73046a070338a726fe04f06cece6cb1ffdf',
/**
* @description 打卡类型:西安办事处
*/
XI_AN_BAN: {latitude: 34.1360, longitude: 108.9126, typeName: '西安办事处位置打卡'},
/**
* @description 打卡类型:第三方维护
*/
OTHER: {typeName: '第三方维护打卡'}
}

View File

@@ -10,13 +10,28 @@
<!-- 正文内容 -->
<view class="white-bg">
<image src="../../../../static/images/business/btn-qd.png" class="btn-image" @click="handleCheckIn"/>
<image src="../../../../static/images/business/btn-dk.png" class="btn-image" @click="handleClockIn" />
<!-- <image src="../../../../static/images/business/btn-dk.png" class="btn-image" @click="handleClockIn"/>-->
<image src="../../../../static/images/business/btn-dk.png" class="btn-image" @click="handleClick"/>
<view class="check-desc">
业务人员可通过<text class="font-orange">签到</text><text
class="font-blue">打卡</text>进行行为记录该时间会和走访报告中的时间进行关联便于查看
业务人员可通过
<text class="font-orange">签到</text>
<text
class="font-blue">打卡
</text>
进行行为记录该时间会和走访报告中的时间进行关联便于查看
</view>
</view>
</view>
<closeable-modal v-model="modalVisible"
title="确认在此处打卡?"
:content="form.addressForStart"
closeTip="轻触空白处关闭"
cancelText="出差"
confirmText="打卡"
contentAlign="center"
@confirm="handleConfirm"
@cancel="handleCancel"/>
<!-- 打卡遮罩层 -->
<!-- <view class="check-con" v-if="checkFlag">
@@ -40,7 +55,9 @@
<script setup>
import {ref, onMounted, reactive} from 'vue'
import customHeader from '@/components/customHeader.vue'
import { addStartMapForClockIn } from '../../../../api/crm/activity/map';
import {addStartMapForClockIn, businessTripClockIn} from '../../../../api/crm/activity/map';
import CloseableModal from "@/components/closeableModal.vue";
import {MapApiConfig} from "../../../../constants/mapApiConstants";
let form = reactive({
addressForStart: null,
@@ -49,6 +66,7 @@ let form = reactive({
staffName: null,
visistCode: null,
visistId: null,
remark: null,
mapId: null
})
// 签到
@@ -58,25 +76,87 @@ let handleCheckIn = () => {
})
}
// 打卡
let handleClockIn = () => {
// let handleClockIn = () => {
// uni.getLocation({
// type: 'wgs84',
// success: (res) => {
// const latiude = res.latitude;
// const longitude = res.longitude;
// //进行解析
// inverseGeocoding(latiude, longitude);
// },
// fail: function (err) {
// console.log("获取地址失败" + err)
// }
// })
// }
let modalVisible = ref(false);
let handleClick = () => {
uni.getLocation({
type: 'wgs84',
success: (res) => {
const latiude = res.latitude;
const latitude = res.latitude;
const longitude = res.longitude;
//进行解析
inverseGeocoding(latiude, longitude);
console.log('纬度:',latitude,',经度:', longitude);
inverseGeocoding(latitude, longitude);
},
fail: function (err) {
console.log("获取地址失败" + err)
}
})
}
// 反馈提示
const feedback = (res, callback)=>{
if(res.code===200){
if(callback) callback();
uni.showToast({
title: MapApiConfig.OTHER.typeName === form.addressForStart ? MapApiConfig.OTHER.typeName : res.msg,
icon: 'success'
})
setTimeout(()=>{
uni.navigateBack(1);
}, 500)
}
else{
uni.showToast({
icon: 'none',
title: res.msg
})
}
}
// 出差
const handleCancel = () => {
businessTripClockIn(form).then(res=>{
feedback(res,()=>console.log('出差打卡成功'));
}).catch(e=>{
uni.showToast({
icon: 'none',
title: e
})
})
}
// 打卡
let handleConfirm = () => {
addStartMapForClockIn(form).then(res=>{
feedback(res, ()=>console.log('打卡成功'));
}).catch(e=>{
uni.showToast({
icon: 'none',
title: e
})
})
}
// 判定是否在范围内
function isWithinRange(lat, lon, centerLat, centerLon, rangeKm) {
const distance = haversineDistance(centerLat, centerLon, lat, lon);
return distance <= rangeKm;
}
function haversineDistance(lat1, lon1, lat2, lon2, radius = 6371) {
const dLat = degToRad(lat2 - lat1);
const dLon = degToRad(lon2 - lon1);
@@ -87,23 +167,25 @@ function haversineDistance(lat1, lon1, lat2, lon2, radius = 6371) {
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return radius * c; // 距离,单位:公里
}
// 角度转弧度
function degToRad(deg) {
return deg * (Math.PI / 180);
}
//解析地址
function inverseGeocoding(latiude, longitude) {
let points = longitude + ',' + latiude
const apiURL = 'https://tiles.geovisearth.com/geo/v1/geocode/regeo';
function inverseGeocoding(latitude, longitude) {
uni.showLoading();
const apiURL = MapApiConfig.URL;
const params = {
lat: latiude,
lat: latitude,
lng: longitude,
radius: 1000,
pageSize: 1,
currentPage: 1,
//classify: 220100
};
const token = '66c87c897f0251295afdc794e4fbf73046a070338a726fe04f06cece6cb1ffdf';
const token = MapApiConfig.token;
uni.request({
url: apiURL,
method: 'GET',
@@ -112,124 +194,31 @@ function inverseGeocoding(latiude, longitude) {
'Authorization': 'Bearer ' + token
},
success: (res) => {
console.log(res, "----")
if (res.statusCode == 200 && res.data.status == 200) {
modalVisible.value=true;
console.log(res, "经纬度解析成功")
if (res.statusCode === 200 && res.data.status === 200) {
let resdata = res.data.data.rows[0].address
if (resdata == null) {
console.log(resdata.srcLat)
const latiude1 = 34.1360;
const longitude1 = 108.9126;
if (isWithinRange(latiude1, longitude1, latiude, longitude, 1)) {
form.addressForStart = "西安办事处位置打卡"
uni.showModal({
title: '确定要在此处打卡吗',
content: form.addressForStart,
success: function (res) {
if (res.confirm) {
var data = {
mapId: form.mapId,
addressForStart: form.addressForStart,
cusName: form.cusName,
cusId: form.cusId,
remark: form.remark,
path: longitude1 + "," + latiude1
}
addStartMapForClockIn(data).then(res => {
if (res.code == 200) {
uni.showToast({
icon: 'success',
title: res.msg,
duration: 1500,
});
setTimeout(() => {
uni.navigateBack(1)
}, 500)
} else {
uni.showToast({
icon: 'none',
title: res.msg,
});
}
})
} else if (res.cancel) {
console.log('用户点击取消');
if (isWithinRange(latitude1, longitude1, latiude, longitude, 1)) {
form.addressForStart = MapApiConfig.XI_AN_BAN.typeName;
form.path = MapApiConfig.XI_AN_BAN.longitude + ',' + MapApiConfig.XI_AN_BAN.latitude ;
}
}
});
}
} else {
else {
form.addressForStart = resdata;
uni.showModal({
title: '确定要在此处打卡吗',
content: form.addressForStart,
success: function (res) {
if (res.confirm) {
var data = {
mapId: form.mapId,
addressForStart: form.addressForStart,
cusName: form.cusName,
cusId: form.cusId,
path: points
}
addStartMapForClockIn(data).then(res => {
if (res.code == 200) {
uni.showToast({
icon: 'success',
title: res.msg,
duration: 1500,
});
} else {
uni.showToast({
icon: 'none',
title: res.msg,
});
}
})
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
form.path = longitude + ',' + latitude; // 经度,纬度
}
} else {
form.addressForStart = "第三方维护打卡"
uni.showModal({
title: '确定要在此处打卡吗',
content: form.addressForStart,
success: function (res) {
if (res.confirm) {
var data = {
mapId: form.mapId,
addressForStart: form.addressForStart,
cusName: form.cusName,
cusId: form.cusId,
path: points
form.addressForStart = MapApiConfig.OTHER.typeName;
form.path = longitude + ',' + latitude; // 经度,纬度
}
addStartMapForClockIn(data).then(res => {
if (res.code == 200) {
uni.showToast({
icon: 'success',
title: '第三方维护打卡',
duration: 1500,
});
} else {
uni.showToast({
icon: 'none',
title: res.msg,
});
}
})
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
}
uni.hideLoading();
},
fail(e) {
console.log("获取位置失败", e)
}
uni.hideLoading();
},
})