Files
zhxg_app_v1.0/pages/applyleave/cancellationLeave.vue
2025-07-16 15:34:34 +08:00

390 lines
9.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>