|
@@ -1,91 +1,133 @@
|
|
|
<template>
|
|
|
<ContentWrap>
|
|
|
- <el-form
|
|
|
- ref="formRef"
|
|
|
- :model="formData"
|
|
|
- :rules="formRules"
|
|
|
- label-width="100px"
|
|
|
- v-loading="formLoading"
|
|
|
- >
|
|
|
+ <el-form ref="formRef" :model="formData" label-width="100px" v-loading="formLoading">
|
|
|
+ <el-card shadow="never" class="config-card">
|
|
|
+ <template #header>
|
|
|
+ <div class="card-header">
|
|
|
+ <span>基础地图配置</span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
<el-form-item label="天地图配置">
|
|
|
- <el-input v-for="(tdtitem,index) in tdtArray" :key="index" v-model="tdtArray[index]" >
|
|
|
+ <el-input v-for="(tdtitem, index) in tdtArray" :key="index" v-model="tdtArray[index]">
|
|
|
<template #append>
|
|
|
- <el-button @click="tdtArray.splice(index,1) ">删除</el-button>
|
|
|
+ <el-button @click="tdtArray.splice(index, 1)">删除</el-button>
|
|
|
</template>
|
|
|
</el-input>
|
|
|
- <el-button @click="tdtArray.push('') ">添加+</el-button>
|
|
|
+ <el-button @click="tdtArray.push('')">添加+</el-button>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="DEM配置">
|
|
|
+ <el-input v-model="formData.demFile" placeholder="请输入DEM文件地址" />
|
|
|
</el-form-item>
|
|
|
+ </el-card>
|
|
|
|
|
|
+ <el-card shadow="never" class="config-card">
|
|
|
+ <template #header>
|
|
|
+ <div class="card-header">
|
|
|
+ <span>场景初始状态</span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
<el-form-item label="地图初始位置">
|
|
|
- <div>
|
|
|
+ <div class="location-grid">
|
|
|
<el-input v-model="formData.itemZoomSet[0]">
|
|
|
- <template #prepend>
|
|
|
- 经度
|
|
|
- </template>
|
|
|
+ <template #prepend> 经度 </template>
|
|
|
</el-input>
|
|
|
<el-input v-model="formData.itemZoomSet[1]">
|
|
|
- <template #prepend>
|
|
|
- 维度
|
|
|
- </template>
|
|
|
+ <template #prepend> 维度 </template>
|
|
|
</el-input>
|
|
|
<el-input v-model="formData.itemZoomSet[2]">
|
|
|
- <template #prepend>
|
|
|
- 高度
|
|
|
- </template>
|
|
|
+ <template #prepend> 高度 </template>
|
|
|
</el-input>
|
|
|
<el-input v-model="formData.itemZoomSet[3]">
|
|
|
- <template #prepend>
|
|
|
- 倾角
|
|
|
- </template>
|
|
|
+ <template #prepend> 倾角 </template>
|
|
|
</el-input>
|
|
|
</div>
|
|
|
</el-form-item>
|
|
|
+ </el-card>
|
|
|
+
|
|
|
+ <el-card shadow="never" class="config-card">
|
|
|
+ <template #header>
|
|
|
+ <div class="card-header">
|
|
|
+ <span>工具栏配置</span>
|
|
|
+ <div>
|
|
|
+ <el-button type="primary" plain size="small" @click="enableAllTools">全部开启</el-button>
|
|
|
+ <el-button type="warning" plain size="small" @click="disableAllTools">全部关闭</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <div class="config-grid">
|
|
|
+ <div v-for="item in toolbarItems" :key="item.key">
|
|
|
+ <div v-if="item.key !== 'scaleBar'" class="config-item">
|
|
|
+ <span class="config-label">{{ item.label }}</span>
|
|
|
+ <el-switch v-model="toolbarConfObj[item.key]" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+
|
|
|
+ <el-card shadow="never" class="config-card">
|
|
|
+ <template #header>
|
|
|
+ <div class="card-header">
|
|
|
+ <span>状态栏配置</span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <el-form-item label="版权信息">
|
|
|
+ <el-input v-model="formData.copyright" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="比例尺">
|
|
|
+ <el-switch v-model="toolbarConfObj.scale" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-card>
|
|
|
|
|
|
+ <el-card shadow="never" class="config-card">
|
|
|
+ <template #header>
|
|
|
+ <div class="card-header">
|
|
|
+ <span>业务数据绑定</span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
<el-form-item label="数据绑定" prop="itemShp">
|
|
|
- <!-- <el-input v-model="formData.itemShp" placeholder="请输入项目相关shp上传(保存url,可null)" />
|
|
|
- -->
|
|
|
<el-select
|
|
|
- v-model="formData.itemShp"
|
|
|
- multiple
|
|
|
- filterable
|
|
|
- allow-create
|
|
|
- default-first-option
|
|
|
- placeholder="请选择项目相关图层">
|
|
|
+ v-model="formData.itemShp"
|
|
|
+ multiple
|
|
|
+ filterable
|
|
|
+ allow-create
|
|
|
+ default-first-option
|
|
|
+ placeholder="请选择项目相关图层"
|
|
|
+ >
|
|
|
<el-option
|
|
|
- v-for="dict in datagisname"
|
|
|
- :key="dict.id"
|
|
|
- :label="dict.shpName"
|
|
|
- :value="dict.shpName"
|
|
|
+ v-for="dict in datagisname"
|
|
|
+ :key="dict.id"
|
|
|
+ :label="dict.shpName"
|
|
|
+ :value="dict.shpName"
|
|
|
/>
|
|
|
</el-select>
|
|
|
</el-form-item>
|
|
|
- <el-form-item :label="item" v-for="(item) in formData.itemShp" :key="item" >
|
|
|
+ <el-form-item :label="item" v-for="item in formData.itemShp" :key="item">
|
|
|
图层属性配置:
|
|
|
<el-select
|
|
|
- v-model="shpItemSelected[item]"
|
|
|
- multiple
|
|
|
- filterable
|
|
|
- default-first-option
|
|
|
- placeholder="图层属性配置">
|
|
|
- <el-option
|
|
|
- v-for="dict in shpItemArr[item] "
|
|
|
- :key="dict"
|
|
|
- :label="dict"
|
|
|
- :value="dict"
|
|
|
- />
|
|
|
+ v-model="shpItemSelected[item]"
|
|
|
+ multiple
|
|
|
+ filterable
|
|
|
+ default-first-option
|
|
|
+ placeholder="图层属性配置"
|
|
|
+ >
|
|
|
+ <el-option v-for="dict in shpItemArr[item]" :key="dict" :label="dict" :value="dict" />
|
|
|
</el-select>
|
|
|
<el-button @click="fieldsConfig(item)">配置表单</el-button>
|
|
|
<div v-if="shpItemField[item] != null">
|
|
|
- <form-create :inFor="true" :rule="shpItemField[item]" v-model:api="fApi" :option="shpItemConf[item]"/>
|
|
|
+ <form-create
|
|
|
+ :inFor="true"
|
|
|
+ :rule="shpItemField[item]"
|
|
|
+ v-model:api="fApi"
|
|
|
+ :option="shpItemConf[item]"
|
|
|
+ />
|
|
|
</div>
|
|
|
-<!-- <div v-else-if="shpItemField[item] != null && shpItemConf[item] == null">-->
|
|
|
-<!-- <form-create :rule="shpItemField[item]" v-model:api="fApi" :option="options"/>-->
|
|
|
-<!-- </div>-->
|
|
|
</el-form-item>
|
|
|
- <el-form-item>
|
|
|
- <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
|
|
- </el-form-item>
|
|
|
- </el-form>
|
|
|
+ </el-card>
|
|
|
+
|
|
|
+ <el-form-item class="submit-button-container">
|
|
|
+ <el-button @click="submitForm" type="primary" :disabled="formLoading" size="large">确 定</el-button>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
</ContentWrap>
|
|
|
|
|
|
<!-- 表单弹窗:添加/修改 -->
|
|
@@ -106,6 +148,50 @@ const dialogVisible = ref(false) // 弹窗的是否展示
|
|
|
const dialogTitle = ref('') // 弹窗的标题
|
|
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
|
|
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
|
|
+const toolbarItems = ref([
|
|
|
+ { key: 'data', label: '数据管理' },
|
|
|
+ { key: 'analysis', label: '空间分析' },
|
|
|
+ { key: 'marking', label: '场景标绘' },
|
|
|
+ { key: 'annotation', label: '平面标注' },
|
|
|
+ { key: 'simulation', label: '仿真模型' },
|
|
|
+ { key: 'rendering', label: '场景渲染' },
|
|
|
+ { key: 'tools', label: '系统工具' },
|
|
|
+ { key: 'crowdfunding', label: '众筹管理' },
|
|
|
+ { key: 'supervision', label: '数字监管' },
|
|
|
+ { key: 'settings', label: '系统设置' },
|
|
|
+ // { key: 'scale', label: '比例尺' }
|
|
|
+]);
|
|
|
+
|
|
|
+// 定义默认工具栏配置对象
|
|
|
+const getDefaultToolbarConfObj = () => ({
|
|
|
+ data: true,
|
|
|
+ analysis: true,
|
|
|
+ marking: true,
|
|
|
+ annotation: true,
|
|
|
+ simulation: true,
|
|
|
+ rendering: true,
|
|
|
+ tools: true,
|
|
|
+ crowdfunding: true,
|
|
|
+ supervision: true,
|
|
|
+ settings: true,
|
|
|
+ scale: true
|
|
|
+});
|
|
|
+
|
|
|
+// 创建响应式工具栏配置对象
|
|
|
+const toolbarConfObj = ref(getDefaultToolbarConfObj())
|
|
|
+
|
|
|
+// ========== 新增:一键开启/关闭工具栏的函数 ==========
|
|
|
+const setAllToolsState = (state: boolean) => {
|
|
|
+ toolbarItems.value.forEach(item => {
|
|
|
+ if (item.key !== 'scaleBar') {
|
|
|
+ toolbarConfObj.value[item.key] = state;
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+const enableAllTools = () => setAllToolsState(true);
|
|
|
+const disableAllTools = () => setAllToolsState(false);
|
|
|
+
|
|
|
const formData = ref({
|
|
|
userId: undefined,
|
|
|
reason: undefined,
|
|
@@ -126,7 +212,10 @@ const formData = ref({
|
|
|
shpItemSelected: {},
|
|
|
itemZoomSet:[],
|
|
|
shpItemField:{},
|
|
|
- shpItemConf:{}
|
|
|
+ shpItemConf: {},
|
|
|
+ demFile: undefined,
|
|
|
+ toolbarConf: '', // 后端存储为字符串
|
|
|
+ copyright: '寰球孪生科技 版权所有@Copyright2025'
|
|
|
})
|
|
|
const options = ref( {
|
|
|
submitBtn: { show: false },
|
|
@@ -142,92 +231,97 @@ const tdtArray = ref([""]);
|
|
|
const twinEditorRef = ref()
|
|
|
const fApi = ref(null);
|
|
|
|
|
|
+// 监听工具栏对象变化,更新表单中的字符串
|
|
|
+watch(toolbarConfObj, (newValue) => {
|
|
|
+ formData.value.toolbarConf = JSON.stringify(newValue)
|
|
|
+}, { deep: true })
|
|
|
+
|
|
|
watch(() => formData.value.itemShp,
|
|
|
- async (newValue) => {
|
|
|
- // console.log("ltyWatching",newValue);
|
|
|
- if(newValue){
|
|
|
- (await newValue).forEach(element => {
|
|
|
- // console.log(element);
|
|
|
- getgisAttr(element).then((res)=> {
|
|
|
- // console.log("ltyWriting",[element,res])
|
|
|
- shpItemArr.value[element] = res
|
|
|
- if(!shpItemSelected.value[element] )
|
|
|
- shpItemSelected.value[element] = [] || shpItemSelected.value[element];
|
|
|
- });
|
|
|
+ async (newValue) => {
|
|
|
+ // console.log("ltyWatching",newValue);
|
|
|
+ if(newValue){
|
|
|
+ (await newValue).forEach(element => {
|
|
|
+ // console.log(element);
|
|
|
+ getgisAttr(element).then((res)=> {
|
|
|
+ // console.log("ltyWriting",[element,res])
|
|
|
+ shpItemArr.value[element] = res
|
|
|
+ if(!shpItemSelected.value[element] )
|
|
|
+ shpItemSelected.value[element] = [] || shpItemSelected.value[element];
|
|
|
});
|
|
|
- }
|
|
|
- },
|
|
|
- {
|
|
|
- deep:true,
|
|
|
- immediate:true
|
|
|
+ });
|
|
|
}
|
|
|
+ },
|
|
|
+ {
|
|
|
+ deep:true,
|
|
|
+ immediate:true
|
|
|
+ }
|
|
|
)
|
|
|
|
|
|
const newShpItemSelected = computed(() => {
|
|
|
return JSON.stringify(shpItemSelected.value)
|
|
|
})
|
|
|
watch(
|
|
|
- newShpItemSelected,
|
|
|
- async (newValue, oldValue) => {
|
|
|
- let newObj = JSON.parse(newValue);
|
|
|
- let oldObj = JSON.parse(oldValue);
|
|
|
-
|
|
|
- for (let shp in newObj) {
|
|
|
- if (shp) {
|
|
|
- let addedKeys: string[] = [];
|
|
|
- let removedKeys: string[] = [];
|
|
|
-
|
|
|
- if(!Array.isArray(shpItemConf.value[shp])){
|
|
|
- shpItemConf.value[shp] = options.value;
|
|
|
- }
|
|
|
- console.log(shpItemConf.value[shp])
|
|
|
- const newEntries = Array.isArray(newObj[shp]) ? newObj[shp] : [];
|
|
|
- const oldEntries = Array.isArray(oldObj[shp]) ? oldObj[shp] : [];
|
|
|
- // 找出新增的字段
|
|
|
- for (let newItem of newEntries) {
|
|
|
- if (!oldEntries.includes(newItem)) {
|
|
|
- addedKeys.push(newItem);
|
|
|
- }
|
|
|
- }
|
|
|
+ newShpItemSelected,
|
|
|
+ async (newValue, oldValue) => {
|
|
|
+ let newObj = JSON.parse(newValue);
|
|
|
+ let oldObj = JSON.parse(oldValue);
|
|
|
|
|
|
- // 找出减少的字段
|
|
|
- for (let oldItem of oldEntries) {
|
|
|
- if (!newEntries.includes(oldItem)) {
|
|
|
- removedKeys.push(oldItem);
|
|
|
- }
|
|
|
- }
|
|
|
+ for (let shp in newObj) {
|
|
|
+ if (shp) {
|
|
|
+ let addedKeys: string[] = [];
|
|
|
+ let removedKeys: string[] = [];
|
|
|
|
|
|
- if (!Array.isArray(shpItemField.value[shp])) {
|
|
|
- shpItemField.value[shp] = [];
|
|
|
- }
|
|
|
- if (addedKeys.length > 0) {
|
|
|
- addedKeys.forEach(addedKey => {
|
|
|
- const newItem = generateJsonTemplate([addedKey]);
|
|
|
- if (newItem) {
|
|
|
- const exists = shpItemField.value[shp].some(item => {
|
|
|
- return item["field"] === newItem[0]["field"]; // 假设“field”是用于比较的属性
|
|
|
- });
|
|
|
- // console.log(exists)
|
|
|
- if (!exists) {
|
|
|
- shpItemField.value[shp].push(newItem[0]);
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
+ if(!Array.isArray(shpItemConf.value[shp])){
|
|
|
+ shpItemConf.value[shp] = options.value;
|
|
|
+ }
|
|
|
+ console.log(shpItemConf.value[shp])
|
|
|
+ const newEntries = Array.isArray(newObj[shp]) ? newObj[shp] : [];
|
|
|
+ const oldEntries = Array.isArray(oldObj[shp]) ? oldObj[shp] : [];
|
|
|
+ // 找出新增的字段
|
|
|
+ for (let newItem of newEntries) {
|
|
|
+ if (!oldEntries.includes(newItem)) {
|
|
|
+ addedKeys.push(newItem);
|
|
|
}
|
|
|
- // 处理移除的字段
|
|
|
- for (let removedKey of removedKeys) {
|
|
|
- shpItemField.value[shp] = shpItemField.value[shp].filter(item => {
|
|
|
- return removedKey !== item["field"]; // 保留没有匹配的item
|
|
|
- });
|
|
|
+ }
|
|
|
+
|
|
|
+ // 找出减少的字段
|
|
|
+ for (let oldItem of oldEntries) {
|
|
|
+ if (!newEntries.includes(oldItem)) {
|
|
|
+ removedKeys.push(oldItem);
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
+ if (!Array.isArray(shpItemField.value[shp])) {
|
|
|
+ shpItemField.value[shp] = [];
|
|
|
+ }
|
|
|
+ if (addedKeys.length > 0) {
|
|
|
+ addedKeys.forEach(addedKey => {
|
|
|
+ const newItem = generateJsonTemplate([addedKey]);
|
|
|
+ if (newItem) {
|
|
|
+ const exists = shpItemField.value[shp].some(item => {
|
|
|
+ return item["field"] === newItem[0]["field"]; // 假设“field”是用于比较的属性
|
|
|
+ });
|
|
|
+ // console.log(exists)
|
|
|
+ if (!exists) {
|
|
|
+ shpItemField.value[shp].push(newItem[0]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ // 处理移除的字段
|
|
|
+ for (let removedKey of removedKeys) {
|
|
|
+ shpItemField.value[shp] = shpItemField.value[shp].filter(item => {
|
|
|
+ return removedKey !== item["field"]; // 保留没有匹配的item
|
|
|
+ });
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
- },
|
|
|
- {
|
|
|
- deep: true,
|
|
|
- immediate: false,
|
|
|
}
|
|
|
+ },
|
|
|
+ {
|
|
|
+ deep: true,
|
|
|
+ immediate: false,
|
|
|
+ }
|
|
|
);
|
|
|
const generateJsonTemplate = (fields ) => {
|
|
|
// 为每个不存在的字段生成新的对象
|
|
@@ -257,6 +351,24 @@ onMounted(async () => {
|
|
|
try {
|
|
|
formData.value = await DisbursementApi.getDisbursement(query.id)
|
|
|
console.log(formData.value)
|
|
|
+
|
|
|
+ // formData.value = response
|
|
|
+
|
|
|
+ // 解析工具栏配置字符串为对象
|
|
|
+ if (formData.value.toolbarConf) {
|
|
|
+ try {
|
|
|
+ toolbarConfObj.value = JSON.parse(formData.value.toolbarConf)
|
|
|
+ } catch (e) {
|
|
|
+ console.error('解析工具栏配置失败:', e)
|
|
|
+ toolbarConfObj.value = getDefaultToolbarConfObj()
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ toolbarConfObj.value = getDefaultToolbarConfObj()
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置版权信息
|
|
|
+ formData.value.copyright = formData.value.copyright || '寰球孪生科技 版权所有@Copyright2025'
|
|
|
+
|
|
|
tdtArray.value = formData.value.itemBaseLayer || [""];
|
|
|
formData.value.itemZoomSet = formData.value.itemZoomSet || [109.2,31.277,156777.64156853,0];
|
|
|
|
|
@@ -283,7 +395,6 @@ const fieldsConfig = ( item: any ) => {
|
|
|
}
|
|
|
|
|
|
const handleSubmitFiled = async (shpItem :any,fields : any , conf :any)=>{
|
|
|
-
|
|
|
shpItemField.value[shpItem] = fields;
|
|
|
shpItemConf.value[shpItem] = conf;
|
|
|
}
|
|
@@ -351,9 +462,68 @@ const resetForm = () => {
|
|
|
itemBaseLayer:undefined,
|
|
|
itemZoomSet:[],
|
|
|
shpItemField:{},
|
|
|
- shpItemConf:{}
|
|
|
+ shpItemConf: {},
|
|
|
+ demFile: undefined,
|
|
|
+ toolbarConf: JSON.stringify(getDefaultToolbarConfObj()), // 初始化为字符串
|
|
|
+ copyright: '寰球孪生科技 版权所有@Copyright2025'
|
|
|
}
|
|
|
+
|
|
|
+ // 重置工具栏对象
|
|
|
+ toolbarConfObj.value = getDefaultToolbarConfObj()
|
|
|
+
|
|
|
formRef.value?.resetFields()
|
|
|
gisnamedatalist()
|
|
|
}
|
|
|
</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.config-card {
|
|
|
+ margin-bottom: 22px;
|
|
|
+}
|
|
|
+
|
|
|
+.card-header {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ width: 100%;
|
|
|
+}
|
|
|
+
|
|
|
+.config-grid {
|
|
|
+ display: grid;
|
|
|
+ grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
|
|
|
+ gap: 18px;
|
|
|
+ width: 100%;
|
|
|
+}
|
|
|
+
|
|
|
+.location-grid {
|
|
|
+ display: grid;
|
|
|
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
|
|
+ gap: 15px;
|
|
|
+ width: 100%;
|
|
|
+}
|
|
|
+
|
|
|
+.config-item {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ padding: 8px 12px;
|
|
|
+ border: 1px solid #e4e7ed;
|
|
|
+ border-radius: 4px;
|
|
|
+ background-color: #f8f9fa;
|
|
|
+ transition: box-shadow 0.2s ease-in-out;
|
|
|
+}
|
|
|
+
|
|
|
+.config-item:hover {
|
|
|
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
|
+}
|
|
|
+
|
|
|
+.config-label {
|
|
|
+ margin-right: 10px;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #606266;
|
|
|
+}
|
|
|
+
|
|
|
+.submit-button-container {
|
|
|
+ margin-top: 30px;
|
|
|
+}
|
|
|
+</style>
|