zlwu il y a 1 an
Parent
commit
544162d8c6
2 fichiers modifiés avec 253 ajouts et 14 suppressions
  1. 243 3
      web/src/views/xg/xsjcxx/xsqj/dialog.vue
  2. 10 11
      web/src/views/xg/xsjcxx/xsqj/index.vue

+ 243 - 3
web/src/views/xg/xsjcxx/xsqj/dialog.vue

@@ -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
web/src/views/xg/xsjcxx/xsqj/index.vue

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