This commit is contained in:
zlwu committed 2025-08-11 06:15:18 +08:00
1 parent 4f489574c1
commit 544162d8c6
2 files changed
+253 -14

No files matched your search

+243 -3
View File
@@ -118,16 +118,25 @@
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12">
<el-col :span="8">
<el-form-item label="紧急联系人" prop="emergencyContact">
<el-input v-model="form.emergencyContact" placeholder="请输入紧急联系人" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-col :span="8">
<el-form-item label="紧急电话" prop="emergencyPhone">
<el-input v-model="form.emergencyPhone" placeholder="请输入紧急联系电话" />
</el-form-item>
</el-col>
<!-- <el-col :span="8">
<el-form-item label="请假位置" prop="leaveLocation">
<el-input v-model="form.leaveLocation" placeholder="请假位置" disabled>
<template #append>
<el-button type="primary" @click="openLocationMap" :icon="LocationFilled" title="地图定位"> 定位 </el-button>
</template>
</el-input>
</el-form-item>
</el-col> -->
</el-row>
<el-form-item label="请假原因" prop="leaveReason">
<el-input v-model="form.leaveReason" type="textarea" :rows="2" placeholder="请输入请假原因" />
@@ -224,6 +233,61 @@
</div>
</template>
</el-dialog>
<!-- 地图定位弹窗 -->
<el-dialog v-model="mapDialogVisible" title="请假位置" width="80%" top="5vh" :before-close="closeMapDialog">
<div class="map-container">
<div v-if="!form.leaveLocation || form.leaveLocation.trim() === ''" class="no-location-tip">
<el-empty description="暂无位置信息">
<el-button type="primary" @click="closeMapDialog">关闭</el-button>
</el-empty>
</div>
<div v-else class="location-info">
<div class="location-text">
<el-tag type="info" size="large">
<el-icon><LocationFilled /></el-icon>
{{ form.leaveLocation }}
</el-tag>
</div>
<div class="map-placeholder">
<div class="map-tips">
<el-alert
title="地图功能提示"
type="info"
:closable="false"
description="地图组件可集成百度地图、高德地图等第三方地图服务来显示具体位置。当前显示位置信息文本。"
>
</el-alert>
<div class="coordinates-display" v-if="parsedLocation">
<p><strong>位置解析:</strong></p>
<p v-if="parsedLocation.type === 'coordinates'">
<span>纬度:{{ parsedLocation.latitude }}</span
><br />
<span>经度:{{ parsedLocation.longitude }}</span>
</p>
<p v-else>
<span>位置描述:{{ parsedLocation.address }}</span>
</p>
</div>
<!-- 这里可以集成真实的地图组件 -->
<div class="mock-map">
<div class="map-icon">🗺️</div>
<p>地图显示区域</p>
<small>(可集成百度地图、高德地图等)</small>
</div>
</div>
</div>
</div>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeMapDialog">关闭</el-button>
<el-button type="primary" @click="openExternalMap" v-if="parsedLocation && parsedLocation.type === 'coordinates'">
在外部地图中查看
</el-button>
</div>
</template>
</el-dialog>
</div>
</div>
</template>
@@ -233,7 +297,7 @@ import { ref, computed, onMounted, reactive, toRefs, nextTick, getCurrentInstanc
import ElMessage from 'element-plus/es/components/message/index';
import ElMessageBox from 'element-plus/es/components/message-box/index';
import ElLoading from 'element-plus/es/components/loading/index';
import { UploadFilled, Document, Loading, Download, Delete } from '@element-plus/icons-vue';
import { UploadFilled, Document, Loading, Download, Delete, LocationFilled } from '@element-plus/icons-vue';
import { getToken } from '@/utils/auth';
import ImagePreview from '@/components/ImagePreview/index.vue';
import request from '@/utils/request';
@@ -362,6 +426,48 @@ const dialogVisible = reactive<DialogOption>({
title: '流程定义'
});
// 地图弹窗状态
const mapDialogVisible = ref(false);
// 解析后的位置信息
const parsedLocation = computed(() => {
if (!form.leaveLocation || form.leaveLocation.trim() === '') {
return null;
}
const location = form.leaveLocation.trim();
// 尝试解析经纬度格式: "纬度: xxx, 经度: xxx"
const coordsRegex = /纬度:\s*([\d.-]+),\s*经度:\s*([\d.-]+)/;
const coordsMatch = location.match(coordsRegex);
if (coordsMatch) {
return {
type: 'coordinates',
latitude: parseFloat(coordsMatch[1]),
longitude: parseFloat(coordsMatch[2])
};
}
// 尝试解析简单经纬度格式: "lat,lng" 或 "lat, lng"
const simpleRegex = /^([\d.-]+),\s*([\d.-]+)$/;
const simpleMatch = location.match(simpleRegex);
if (simpleMatch) {
return {
type: 'coordinates',
latitude: parseFloat(simpleMatch[1]),
longitude: parseFloat(simpleMatch[2])
};
}
// 其他情况当作地址处理
return {
type: 'address',
address: location
};
});
//提交组件
const submitVerifyRef = ref<InstanceType<typeof SubmitVerify>>();
//审批记录组件
@@ -988,6 +1094,51 @@ const cancel = () => {
emit('cancel');
};
// 打开地图定位弹窗
const openLocationMap = () => {
if (!form.leaveLocation || form.leaveLocation.trim() === '') {
ElMessage.warning('暂无位置信息可显示');
return;
}
mapDialogVisible.value = true;
};
// 关闭地图弹窗
const closeMapDialog = () => {
mapDialogVisible.value = false;
};
// 在外部地图中查看
const openExternalMap = () => {
if (!parsedLocation.value || parsedLocation.value.type !== 'coordinates') {
ElMessage.warning('无法获取有效的坐标信息');
return;
}
const { latitude, longitude } = parsedLocation.value;
// 提供多种地图选择
ElMessageBox.confirm('选择要使用的地图服务:', '打开外部地图', {
confirmButtonText: '百度地图',
cancelButtonText: '高德地图',
type: 'info',
distinguishCancelAndClose: true
})
.then(() => {
// 百度地图
const baiduUrl = `https://api.map.baidu.com/marker?location=${latitude},${longitude}&title=请假位置&content=${encodeURIComponent(form.leaveLocation)}&output=html&src=webapp`;
window.open(baiduUrl, '_blank');
})
.catch((action) => {
if (action === 'cancel') {
// 高德地图
const gaodeUrl = `https://uri.amap.com/marker?position=${longitude},${latitude}&name=请假位置&src=webapp`;
window.open(gaodeUrl, '_blank');
}
// 如果是 close,则不执行任何操作
});
};
// 监听 isLeaveSchool 字段变化,更新销假状态
// watch(
// () => form.isLeaveSchool,
@@ -1640,4 +1791,93 @@ onMounted(() => {
:deep(.el-card .el-card__header) {
border-bottom: 0px !important;
}
/* 地图弹窗样式 */
.map-container {
min-height: 500px;
max-height: 70vh;
overflow-y: auto;
}
.no-location-tip {
display: flex;
align-items: center;
justify-content: center;
min-height: 300px;
}
.location-info {
padding: 16px;
}
.location-text {
margin-bottom: 16px;
text-align: center;
}
.location-text .el-tag {
padding: 8px 16px;
font-size: 14px;
font-weight: 500;
}
.location-text .el-icon {
margin-right: 8px;
}
.map-placeholder {
margin-top: 16px;
}
.map-tips {
margin-bottom: 16px;
}
.coordinates-display {
margin: 16px 0;
padding: 12px;
background: #f8f9fa;
border-radius: 6px;
border-left: 4px solid #409eff;
}
.coordinates-display p {
margin: 8px 0;
line-height: 1.5;
}
.coordinates-display strong {
color: #303133;
font-weight: 600;
}
.mock-map {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 200px;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
border: 2px dashed #d0d7de;
border-radius: 8px;
color: #666;
text-align: center;
margin-top: 16px;
}
.map-icon {
font-size: 48px;
margin-bottom: 8px;
}
.mock-map p {
margin: 4px 0;
font-size: 16px;
font-weight: 500;
}
.mock-map small {
color: #999;
font-size: 12px;
}
</style>
+10 -11
View File
@@ -238,20 +238,18 @@
<el-table-column label="销假地理位置" align="center" prop="cancelLocation" />
<el-table-column label="销假照片OSS文件ID" align="center" prop="cancelPhotoOssIds" />
<el-table-column label="销假备注" align="center" prop="cancelRemark" /> -->
<el-table-column label="操作" align="center" width="150px" class-name="small-padding fixed-width" fixed="right">
<el-table-column label="操作" align="center" width="200px" class-name="small-padding fixed-width" fixed="right">
<template #default="scope">
<el-tooltip content="修改" placement="top">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['studentLeave:studentLeave:edit']"></el-button>
<el-tooltip :content="['draft', 'cancel', 'back'].includes(scope.row.approvalStatus) ? '修改' : '查看'" placement="top">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['studentLeave:studentLeave:edit']">
{{ ['draft', 'cancel', 'back'].includes(scope.row.approvalStatus) ? '修改' : '查看' }}
</el-button>
</el-tooltip>
<!-- 删除按钮:仅草稿状态可见 -->
<el-tooltip content="删除" placement="top" v-if="scope.row.approvalStatus === 'draft'">
<el-button
link
type="danger"
icon="Delete"
@click="handleDelete(scope.row)"
v-hasPermi="['studentLeave:studentLeave:remove']"
></el-button>
<el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['studentLeave:studentLeave:remove']"
>删除</el-button
>
</el-tooltip>
<!-- 销假按钮:仅已完成状态且需要销假时可见 -->
<el-tooltip content="销假" placement="top" v-if="scope.row.approvalStatus === 'finish' && scope.row.needCancel === '1'">
@@ -261,7 +259,8 @@
icon="CircleCheck"
@click="handleCancelLeave(scope.row)"
v-hasPermi="['studentLeave:studentLeave:cancel']"
></el-button>
>销假</el-button
>
</el-tooltip>
</template>
</el-table-column>