|
|
@@ -25,51 +25,28 @@
|
|
|
/>
|
|
|
|
|
|
<div v-show="layersType === 'SHP'" class="shp-upload-container">
|
|
|
- <div class="shp-file-item">
|
|
|
- <span class="file-label">主文件(.shp):</span>
|
|
|
- <input
|
|
|
- type="file"
|
|
|
- ref="shpFileInput"
|
|
|
- accept=".shp"
|
|
|
- @change="handleShpFileChange"
|
|
|
- class="sm-input"
|
|
|
- style="width:100%"
|
|
|
- />
|
|
|
- </div>
|
|
|
- <div class="shp-file-item">
|
|
|
- <span class="file-label">索引文件(.shx):</span>
|
|
|
- <input
|
|
|
- type="file"
|
|
|
- ref="shxFileInput"
|
|
|
- accept=".shx"
|
|
|
- @change="handleShxFileChange"
|
|
|
- class="sm-input"
|
|
|
- style="width:100%"
|
|
|
- />
|
|
|
- </div>
|
|
|
- <div class="shp-file-item">
|
|
|
- <span class="file-label">属性文件(.dbf):</span>
|
|
|
- <input
|
|
|
- type="file"
|
|
|
- ref="dbfFileInput"
|
|
|
- accept=".dbf"
|
|
|
- @change="handleDbfFileChange"
|
|
|
- class="sm-input"
|
|
|
- style="width:100%"
|
|
|
- />
|
|
|
- </div>
|
|
|
- <div class="shp-file-item">
|
|
|
- <span class="file-label">坐标文件(.prj):</span>
|
|
|
- <input
|
|
|
- type="file"
|
|
|
- ref="prjFileInput"
|
|
|
- accept=".prj"
|
|
|
- @change="handlePrjFileChange"
|
|
|
- class="sm-input"
|
|
|
- style="width:100%"
|
|
|
- />
|
|
|
- </div>
|
|
|
- <div class="upload-tip">必须同时上传 .shp、.shx、.dbf、.prj 四个文件</div>
|
|
|
+ <el-upload
|
|
|
+ ref="shpUploadRef"
|
|
|
+ class="shp-upload"
|
|
|
+ :auto-upload="false"
|
|
|
+ :limit="5"
|
|
|
+ accept=".zip,.shp,.shx,.dbf,.prj"
|
|
|
+ :on-change="handleShpFileChange"
|
|
|
+ :on-exceed="handleShpExceed"
|
|
|
+ :on-remove="handleShpRemove"
|
|
|
+ multiple
|
|
|
+ drag
|
|
|
+ >
|
|
|
+ <el-icon class="el-icon--upload"><UploadFilled /></el-icon>
|
|
|
+ <div class="el-upload__text">
|
|
|
+ 拖拽文件到此处或 <em>点击上传</em>
|
|
|
+ </div>
|
|
|
+ <template #tip>
|
|
|
+ <div class="el-upload__tip">
|
|
|
+ 支持 .zip(包含.shp,.shx,.dbf,.prj) 或单独上传 .shp + .shx + .dbf + .prj 文件
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-upload>
|
|
|
</div>
|
|
|
|
|
|
<input
|
|
|
@@ -111,8 +88,11 @@ import layerManagement from "../../../js/common/layerManagement.js";
|
|
|
import tool from "../../../js/tool/tool.js";
|
|
|
import { watch, ref, reactive, toRefs, onBeforeUnmount, onMounted, getCurrentInstance } from "vue";
|
|
|
import { uploadShp, getGeoJsonList, getGeoJsonUrl } from "@/api/cesium/geojson.js";
|
|
|
+import { UploadFilled } from '@element-plus/icons-vue';
|
|
|
+import { ElMessage } from 'element-plus';
|
|
|
export default {
|
|
|
name: "Sm3dCustomService",
|
|
|
+ components: { UploadFilled },
|
|
|
props: {
|
|
|
//点击确定时回调
|
|
|
addCallback: {
|
|
|
@@ -137,16 +117,8 @@ export default {
|
|
|
}, 50);
|
|
|
});
|
|
|
|
|
|
- const shpFileInput = ref(null);
|
|
|
- const shxFileInput = ref(null);
|
|
|
- const dbfFileInput = ref(null);
|
|
|
- const prjFileInput = ref(null);
|
|
|
-
|
|
|
- const shpFile = ref(null);
|
|
|
- const shxFile = ref(null);
|
|
|
- const dbfFile = ref(null);
|
|
|
- const prjFile = ref(null);
|
|
|
-
|
|
|
+ const shpUploadRef = ref(null);
|
|
|
+ const uploadedFiles = ref([]);
|
|
|
const uploadProgress = ref(0);
|
|
|
const isUploading = ref(false);
|
|
|
|
|
|
@@ -161,91 +133,103 @@ export default {
|
|
|
isSct: false
|
|
|
});
|
|
|
|
|
|
- async function handleShpFileChange(event) {
|
|
|
- const file = event.target.files[0];
|
|
|
- if (!file) return;
|
|
|
-
|
|
|
- const fileName = file.name.toLowerCase();
|
|
|
- if (!fileName.endsWith('.shp')) {
|
|
|
- tool.Message.warnMsg("请上传 .shp 格式的文件");
|
|
|
- return;
|
|
|
- }
|
|
|
+ function handleShpFileChange(file, fileList) {
|
|
|
+ // 过滤出有效的文件类型
|
|
|
+ const validFiles = fileList.filter(f => {
|
|
|
+ const fileName = f.name.toLowerCase();
|
|
|
+ return fileName.endsWith('.shp') || fileName.endsWith('.shx') || fileName.endsWith('.dbf') || fileName.endsWith('.prj') || fileName.endsWith('.zip');
|
|
|
+ });
|
|
|
|
|
|
- shpFile.value = file;
|
|
|
- tool.Message.infoMsg("已选择主文件: " + file.name);
|
|
|
- }
|
|
|
-
|
|
|
- async function handleShxFileChange(event) {
|
|
|
- const file = event.target.files[0];
|
|
|
- if (!file) return;
|
|
|
+ uploadedFiles.value = validFiles.map(f => f.raw);
|
|
|
|
|
|
- const fileName = file.name.toLowerCase();
|
|
|
- if (!fileName.endsWith('.shx')) {
|
|
|
- tool.Message.warnMsg("请上传 .shx 格式的文件");
|
|
|
- return;
|
|
|
+ // 自动从第一个文件中推断服务名称
|
|
|
+ if (validFiles.length > 0 && !state.layerName) {
|
|
|
+ const fileName = validFiles[0].name;
|
|
|
+ state.layerName = fileName.replace(/\.(zip|shp|shx|dbf|prj)$/i, '');
|
|
|
}
|
|
|
|
|
|
- shxFile.value = file;
|
|
|
- tool.Message.infoMsg("已选择索引文件: " + file.name);
|
|
|
- }
|
|
|
-
|
|
|
- async function handleDbfFileChange(event) {
|
|
|
- const file = event.target.files[0];
|
|
|
- if (!file) return;
|
|
|
-
|
|
|
- const fileName = file.name.toLowerCase();
|
|
|
- if (!fileName.endsWith('.dbf')) {
|
|
|
- tool.Message.warnMsg("请上传 .dbf 格式的文件");
|
|
|
- return;
|
|
|
+ // 检查是否上传了所有必要的文件
|
|
|
+ if (validFiles.length > 1) {
|
|
|
+ const fileTypes = validFiles.map(f => f.name.toLowerCase().split('.').pop());
|
|
|
+ const hasShp = fileTypes.includes('shp');
|
|
|
+ const hasShx = fileTypes.includes('shx');
|
|
|
+ const hasDbf = fileTypes.includes('dbf');
|
|
|
+ const hasPrj = fileTypes.includes('prj');
|
|
|
+
|
|
|
+ if (!hasShp) {
|
|
|
+ ElMessage.warning('请上传 .shp 主文件');
|
|
|
+ } else if (!hasShx) {
|
|
|
+ ElMessage.warning('请上传 .shx 索引文件');
|
|
|
+ } else if (!hasDbf) {
|
|
|
+ ElMessage.warning('请上传 .dbf 属性文件');
|
|
|
+ } else if (!hasPrj) {
|
|
|
+ ElMessage.warning('请上传 .prj 坐标文件');
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
- dbfFile.value = file;
|
|
|
- tool.Message.infoMsg("已选择属性文件: " + file.name);
|
|
|
}
|
|
|
-
|
|
|
- async function handlePrjFileChange(event) {
|
|
|
- const file = event.target.files[0];
|
|
|
- if (!file) return;
|
|
|
-
|
|
|
- const fileName = file.name.toLowerCase();
|
|
|
- if (!fileName.endsWith('.prj')) {
|
|
|
- tool.Message.warnMsg("请上传 .prj 格式的文件");
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- prjFile.value = file;
|
|
|
- tool.Message.infoMsg("已选择坐标文件: " + file.name);
|
|
|
+
|
|
|
+ function handleShpExceed() {
|
|
|
+ ElMessage.warning('最多上传5个文件(.shp, .shx, .dbf, .prj 和可选的 .zip)');
|
|
|
+ }
|
|
|
+
|
|
|
+ function handleShpRemove() {
|
|
|
+ uploadedFiles.value = [];
|
|
|
}
|
|
|
|
|
|
async function uploadShpFile() {
|
|
|
- if (!shpFile.value) {
|
|
|
- tool.Message.warnMsg("请先选择SHP主文件");
|
|
|
+ const files = uploadedFiles.value;
|
|
|
+ if (files.length === 0) {
|
|
|
+ ElMessage.warning('请先选择SHP文件');
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
- if (!shxFile.value) {
|
|
|
- tool.Message.warnMsg("请选择SHX索引文件");
|
|
|
- return null;
|
|
|
- }
|
|
|
+ // 检查是否上传了所有必要的文件(非zip情况)
|
|
|
+ const fileTypes = files.map(f => f.name.toLowerCase().split('.').pop());
|
|
|
+ const hasZip = fileTypes.includes('zip');
|
|
|
+ const hasShp = fileTypes.includes('shp');
|
|
|
|
|
|
- if (!dbfFile.value) {
|
|
|
- tool.Message.warnMsg("请选择DBF属性文件");
|
|
|
+ if (!hasZip && !hasShp) {
|
|
|
+ ElMessage.error('请上传 .shp 主文件');
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
- if (!prjFile.value) {
|
|
|
- tool.Message.warnMsg("请选择PRJ坐标文件");
|
|
|
- return null;
|
|
|
+ if (!hasZip) {
|
|
|
+ const hasShx = fileTypes.includes('shx');
|
|
|
+ const hasDbf = fileTypes.includes('dbf');
|
|
|
+ const hasPrj = fileTypes.includes('prj');
|
|
|
+ if (!hasShx) {
|
|
|
+ ElMessage.error('请上传 .shx 索引文件');
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ if (!hasDbf) {
|
|
|
+ ElMessage.error('请上传 .dbf 属性文件');
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ if (!hasPrj) {
|
|
|
+ ElMessage.error('请上传 .prj 坐标文件');
|
|
|
+ return null;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
isUploading.value = true;
|
|
|
uploadProgress.value = 0;
|
|
|
|
|
|
const formData = new FormData();
|
|
|
- formData.append('file', shpFile.value);
|
|
|
- formData.append('shxFile', shxFile.value);
|
|
|
- formData.append('dbfFile', dbfFile.value);
|
|
|
- formData.append('prjFile', prjFile.value);
|
|
|
+ // 根据文件类型添加到对应的参数
|
|
|
+ files.forEach(file => {
|
|
|
+ const fileName = file.name.toLowerCase();
|
|
|
+ if (fileName.endsWith('.shp')) {
|
|
|
+ formData.append('file', file);
|
|
|
+ } else if (fileName.endsWith('.shx')) {
|
|
|
+ formData.append('shxFile', file);
|
|
|
+ } else if (fileName.endsWith('.dbf')) {
|
|
|
+ formData.append('dbfFile', file);
|
|
|
+ } else if (fileName.endsWith('.prj')) {
|
|
|
+ formData.append('prjFile', file);
|
|
|
+ } else if (fileName.endsWith('.zip')) {
|
|
|
+ formData.append('file', file);
|
|
|
+ }
|
|
|
+ });
|
|
|
if (state.layerName) {
|
|
|
formData.append('layerName', state.layerName);
|
|
|
}
|
|
|
@@ -256,23 +240,18 @@ export default {
|
|
|
uploadProgress.value = 100;
|
|
|
|
|
|
if (result.code === 200 && result.data) {
|
|
|
- tool.Message.successMsg("文件上传成功");
|
|
|
- shpFile.value = null;
|
|
|
- shxFile.value = null;
|
|
|
- dbfFile.value = null;
|
|
|
- prjFile.value = null;
|
|
|
- if (shpFileInput.value) shpFileInput.value.value = '';
|
|
|
- if (shxFileInput.value) shxFileInput.value.value = '';
|
|
|
- if (dbfFileInput.value) dbfFileInput.value.value = '';
|
|
|
- if (prjFileInput.value) prjFileInput.value.value = '';
|
|
|
+ ElMessage.success("文件上传成功");
|
|
|
+ uploadedFiles.value = [];
|
|
|
+ if (shpUploadRef.value) shpUploadRef.value.clearFiles();
|
|
|
return result.data;
|
|
|
} else {
|
|
|
- tool.Message.errorMsg(result.msg || "上传失败");
|
|
|
+ ElMessage.error(result.msg || "上传失败");
|
|
|
return null;
|
|
|
}
|
|
|
} catch (error) {
|
|
|
isUploading.value = false;
|
|
|
- tool.Message.errorMsg("上传失败: " + error.message);
|
|
|
+ const errorMsg = error.response?.data?.msg || error.response?.data?.message || error.message || '未知错误';
|
|
|
+ ElMessage.error("上传失败: " + errorMsg);
|
|
|
return null;
|
|
|
}
|
|
|
}
|
|
|
@@ -295,12 +274,17 @@ export default {
|
|
|
}
|
|
|
|
|
|
async function addShpLayer() {
|
|
|
- const geoJsonUrl = await uploadShpFile();
|
|
|
- if (!geoJsonUrl) return;
|
|
|
+ const uploadResult = await uploadShpFile();
|
|
|
+ if (!uploadResult) return;
|
|
|
+
|
|
|
+ const geoJsonUrl = typeof uploadResult === 'string' ? uploadResult : uploadResult.url;
|
|
|
+ const serviceId = typeof uploadResult === 'object' ? uploadResult.id : null;
|
|
|
|
|
|
const serviceInfo = {
|
|
|
url: geoJsonUrl,
|
|
|
- type: 'GEOJSON'
|
|
|
+ id: serviceId,
|
|
|
+ type: 'GEOJSON',
|
|
|
+ layerName: state.layerName || 'SHP_Data'
|
|
|
};
|
|
|
|
|
|
layerManagement.addGeoJsonLayer(geoJsonUrl, state.layerName || 'SHP_Data', (geoJsonLayer) => {
|
|
|
@@ -324,7 +308,7 @@ export default {
|
|
|
|
|
|
function check() {
|
|
|
if (state.layersType === 'SHP') {
|
|
|
- if (!shpFile.value) {
|
|
|
+ if (uploadedFiles.value.length === 0) {
|
|
|
tool.Message.warnMsg("请先选择SHP文件");
|
|
|
return false;
|
|
|
}
|
|
|
@@ -464,7 +448,10 @@ export default {
|
|
|
addLayer,
|
|
|
clear,
|
|
|
handleShpFileChange,
|
|
|
- shpFileInput,
|
|
|
+ handleShpExceed,
|
|
|
+ handleShpRemove,
|
|
|
+ shpUploadRef,
|
|
|
+ uploadedFiles,
|
|
|
uploadProgress,
|
|
|
isUploading
|
|
|
};
|
|
|
@@ -477,24 +464,4 @@ export default {
|
|
|
width: 100%;
|
|
|
margin-bottom: 10px;
|
|
|
}
|
|
|
-
|
|
|
-.shp-file-item {
|
|
|
- margin-bottom: 8px;
|
|
|
-}
|
|
|
-
|
|
|
-.file-label {
|
|
|
- display: block;
|
|
|
- font-size: 12px;
|
|
|
- color: #666;
|
|
|
- margin-bottom: 4px;
|
|
|
-}
|
|
|
-
|
|
|
-.upload-tip {
|
|
|
- font-size: 12px;
|
|
|
- color: #e6a23c;
|
|
|
- margin-top: 5px;
|
|
|
-}
|
|
|
</style>
|
|
|
-
|
|
|
-
|
|
|
-
|