Files
zhxg_app_v1.0/pages/applyleave/cancellationLeave.vue

390 lines
9.4 KiB
Vue
Raw Normal View History

2025-07-16 15:34:34 +08:00
<template>
<view class="cancel-leave">
<!-- 显示定位信息 -->
<view class="content">
<!-- 地图展示 -->
<map style="width: 100%; height: 300px;" :latitude="latitude" :longitude="longitude" :markers="covers"
show-location></map>
<!-- 重新定位按钮 -->
<button class="refresh-location" @tap="getLocation">重新获取定位</button>
</view>
<!-- 确定销假按钮 -->
<button class="confirm-cancel" @tap="confirm">确定销假</button>
</view>
</template>
<script>
import {
getLeaveApplicationByProcInsId,
complete,
reject
} from "@/api/task.js";
import {
editApply
} from "@/api/applyleave/applyleave.js";
import {
getWxConfig
} from "@/api/common/wechat";
import wx from "weixin-js-sdk"; // 引入微信 JS-SDK
import * as ww from '@wecom/jssdk'
export default {
data() {
return {
address: "", // 地址信息
latitude: 108.31019592285156, // 纬度
longitude: 22.90125274658203, // 经度
covers: [{
latitude: 108.31019592285156,
longitude: 22.90125274658203,
iconPath: '../../static/images/applyrelieve/location.png'
}],
distanceThreshold: 1000, // 距离阈值
isLeave: true, // 销假按钮状态
taskForm: {},
};
},
async onLoad(option) {
console.log(this.role)
let query = JSON.parse(option.query);
this.taskForm.deployId = query.deployId;
this.taskForm.instanceId = query.procInsId
this.taskForm.procInsId = query.procInsId
this.taskForm.executionId = query.executionId
this.taskForm.taskId = query.taskId
this.getTaskDetail();
await this.initWxConfig(); // 初始化微信配置
this.getLocation();
},
methods: {
async initWxConfig() {
let that = this;
let res = await that.getConfigSignature();
ww.register({
corpId: 'wx129e6bf0f36b8b3d', // 必填当前用户企业所属企业ID
agentId: 1000093, // 必填当前应用的AgentID
jsApiList: ["getLocation", "openLocation"], // 必填需要使用的JSAPI列表
// getAgentConfigSignature: that.getAgentConfigSignature, // 必填根据url生成应用签名的回调函数
getConfigSignature() {
return res
}
})
},
// 初始化微信 JS-SDK
async getConfigSignature() {
return new Promise((resolve, reject) => {
// 调用后端接口获取签名信息(需要后端支持)
getWxConfig("corpId").then(res => {
const {
timestamp,
nonceStr,
signature
} = res;
resolve({
timestamp,
nonceStr,
signature
});
}).catch(err => {
reject(err);
});
});
},
// 初始化微信 JS-SDK应用
async getAgentConfigSignature() {
return new Promise((resolve, reject) => {
// 调用后端接口获取签名信息(需要后端支持)
getWxConfig("agentId").then(res => {
const {
timestamp,
nonceStr,
signature
} = res;
resolve({
timestamp,
nonceStr,
signature
});
}).catch(err => {
reject(err);
});
});
},
// 获取当前位置
getLocation() {
let that = this;
ww.getLocation({
type: 'gcj02',
success(res) {
that.latitude = res.latitude
that.longitude = res.longitude
that.covers[0].latitude = res.latitude
that.covers[0].longitude = res.longitude
},
fail(err) {
uni.showToast({
title: "获取定位失败",
icon: 'fail'
})
}
});
},
openLocation() {
let that = this;
ww.openLocation({
latitude: that.latitude,
longitude: that.longitude,
name: 'name',
address: 'address',
scale: 1,
success(res) {},
fail(err) {
console.log('定位失败:', err)
},
complete(err) {
console.log('定位失败:', err)
}
})
},
// 通过经纬度反向解析地址(需要后端支持或使用第三方 API如高德地图 API
reverseGeocode(lat, lng) {
const amapKey = "your-amap-key"; // 替换为高德地图的 API Key
this.$http
.get(
`https://restapi.amap.com/v3/geocode/regeo?key=${amapKey}&location=${lng},${lat}`
)
.then(res => {
if (res.data.regeocode && res.data.regeocode.formatted_address) {
this.address = res.data.regeocode.formatted_address;
} else {
this.address = "未知地址";
}
})
.catch(err => {
console.error("反向地理编码失败", err);
this.address = "地址解析失败";
});
},
async checkIfNearCampus1() {
const campuses = [{
name: "长堽校区",
latitude: 22.835938,
longitude: 108.351728
},
{
name: "里建校区",
latitude: 23.206284,
longitude: 108.18664
}
];
let isNearby = false;
let res = false;
let campus = campuses[0];
let p1 = {
latitude: this.latitude,
longitude: this.longitude
}
let distance = this.getDistance(
p1.latitude, p1.longitude,
campus.latitude, campus.longitude
);
isNearby = distance < this.distanceThreshold;
if (isNearby) {
res = true;
}
campus = campuses[1];
distance = this.getDistance(
p1.latitude, p1.longitude,
campus.latitude, campus.longitude
);
isNearby = distance < this.distanceThreshold;
if (isNearby) {
res = true;
}
if (res) {
return true;
} else {
return false;
}
},
toRadians(degree) {
return degree * (Math.PI / 180);
},
// 计算两个经纬度之间的距离(近似计算,适用于小范围)
getDistance(lat1, lng1, lat2, lng2) {
const EARTH_RADIUS = 6378137; // 地球半径,单位:米
const dLat = this.toRadians(lat2 - lat1);
const dLng = this.toRadians(lng2 - lng1);
const a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(this.toRadians(lat1)) *
Math.cos(this.toRadians(lat2)) *
Math.sin(dLng / 2) *
Math.sin(dLng / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return EARTH_RADIUS * c;
},
// 检查是否在校区范围
checkIfNearCampus() {
const campuses = [{
name: "长堽校区",
latitude: 22.835938,
longitude: 108.351728
},
{
name: "里建校区",
latitude: 23.206284,
longitude: 108.18664
}
];
const isNearby = campuses.some(campus => {
const distance = this.calculateDistance(
this.latitude,
this.longitude,
campus.latitude,
campus.longitude
);
return distance < this.distanceThreshold;
});
if (isNearby) {
this.$toast("您在校区范围内,可以进行销假");
this.isLeave = false;
} else {
this.$toast("您不在校区范围内,无法销假");
this.isLeave = true;
}
},
// 计算两点之间的球面距离
calculateDistance(lat1, lng1, lat2, lng2) {
const R = 6371000; // 地球半径(单位:米)
const toRadians = degrees => (degrees * Math.PI) / 180;
const dLat = toRadians(lat2 - lat1);
const dLng = toRadians(lng2 - lng1);
const a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(toRadians(lat1)) *
Math.cos(toRadians(lat2)) *
Math.sin(dLng / 2) *
Math.sin(dLng / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return R * c;
},
// 获取销假详情
getTaskDetail() {
getLeaveApplicationByProcInsId(this.taskForm.procInsId).then(res => {
this.leaveApplicationId = res.data.leaveApplicationId;
this.address = res.data.destinationDetails;
});
},
// 销假操作
async confirm() {
if (await this.checkIfNearCampus1()) {
uni.showModal({
title: "提示",
content: "确定销假吗?",
confirmText: "确定",
cancelText: "取消",
success: (res) => {
if (res.confirm) {
this.taskForm.comment = '销假'
complete(this.taskForm).then(res => {
if (res.code == 200) {
const data = {
leaveApplicationId: this.leaveApplicationId,
};
editApply(data).then(() => {
uni.showToast({
title: "销假成功",
icon: "success",
duration: 1500
});
// 延时跳转确保用户看到提示
setTimeout(() => {
uni.redirectTo({
url: "/pages/Approval/index?tab=2"
});
}, 1600);
}).catch(err => {
uni.showToast({
title: "销假失败: " + err.message,
icon: "none"
});
});
}
})
}
}
});
} else {
uni.showToast({
title: "您不在学校附近",
icon: "error"
});
return;
}
}
}
};
</script>
<style scoped lang="scss">
.cancel-leave {
.content {
.location-info {
margin: 10px 0;
text-align: center;
.title {
font-size: 16px;
font-weight: bold;
}
.address {
font-size: 14px;
color: #666;
}
}
.refresh-location {
margin: 10px auto;
display: block;
width: 80%;
background-color: #007aff;
color: white;
text-align: center;
padding: 10px;
border-radius: 5px;
}
}
.confirm-cancel {
position: fixed;
bottom: 0;
width: 100%;
background-color: #1890ff;
color: white;
border-radius: 0;
padding: 10px;
font-size: 16px;
font-weight: bold;
&[disabled] {
opacity: 0.5;
}
}
}
</style>