Browse Source

工具栏和版权配置

qpw 1 month ago
parent
commit
87af62fc7c
3 changed files with 337 additions and 135 deletions
  1. 297 127
      src/views/bpm/disbursement/detail.vue
  2. 23 8
      src/views/gislayer/gisform/GisFormForm.vue
  3. 17 0
      yarn.lock

+ 297 - 127
src/views/bpm/disbursement/detail.vue

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

+ 23 - 8
src/views/gislayer/gisform/GisFormForm.vue

@@ -7,23 +7,38 @@
       label-width="100px"
       v-loading="formLoading"
     >
-      <el-form-item label="图层类型" prop="type">
+    <el-form-item label="图层类型" prop="type">
         <el-select v-model="formData.type" placeholder="请选择图层数据类型">
           <el-option
             v-for="dict in getIntDictOptions(DICT_TYPE.LAYER_GISFROM_TYPE)"
             :key="dict.value"
             :label="dict.label"
             :value="dict.value"
-             />
+          />
         </el-select>
       </el-form-item>
-      <el-form-item v-if="[1,3,4,5,6].indexOf(formData.type) !=-1" label="导入的文件名" prop="shpName">
-        <el-input v-model="formData.shpName" placeholder="请输入矢量图形文件的系统名(导入的英文名)" />
 
+      <el-form-item v-if="formData.type === 1" label="导入的文件名" prop="shpName">
+        <el-input v-model="formData.shpName" placeholder="请输入矢量图形文件的系统名(导入的英文名)" />
       </el-form-item>
-      <el-form-item v-if="formData.type == 2" label="瓦片服务地址" prop="urlAddress">
-        <el-input v-model="formData.urlAddress"  placeholder="若为3dtile,请输入瓦片接口地址(后续会更新为上传/文件选择)" />
-      </el-form-item>
+
+      <template v-if="formData.type === 2">
+        <el-form-item label="导入的文件名" prop="shpName">
+          <el-input v-model="formData.shpName" placeholder="请输入三维模型文件的系统名(导入的英文名)" />
+        </el-form-item>
+        <el-form-item label="瓦片服务地址" prop="urlAddress">
+          <el-input v-model="formData.urlAddress" placeholder="若为3dtile,请输入瓦片接口地址(后续会更新为上传/文件选择)" />
+        </el-form-item>
+      </template>
+
+      <template v-if="formData.type === 3">
+        <el-form-item label="导入的文件名" prop="shpName">
+          <el-input v-model="formData.shpName" placeholder="请输入数据服务文件的系统名(导入的英文名)" />
+        </el-form-item>
+        <el-form-item label="数据服务地址" prop="urlAddress">
+          <el-input v-model="formData.urlAddress" placeholder="请输入数据服务接口地址" />
+        </el-form-item>
+      </template>
       <el-form-item label="图层名" prop="name">
         <el-input v-model="formData.name" placeholder="请输入孪生场景内,展示的图层中文名" />
       </el-form-item>
@@ -198,4 +213,4 @@ const getGisFormTree = async () => {
   root.children = handleTree(data, 'id', 'parentId')
   gisFormTree.value.push(root)
 }
-</script>
+</script>

+ 17 - 0
yarn.lock

@@ -1661,6 +1661,13 @@
     local-pkg "^0.5.0"
     mlly "^1.7.1"
 
+"@iconify/vue@^5.0.0":
+  version "5.0.0"
+  resolved "https://registry.npmmirror.com/@iconify/vue/-/vue-5.0.0.tgz#c47e4b3a225a64bbf28dce924934f23e54b061a4"
+  integrity sha512-C+KuEWIF5nSBrobFJhT//JS87OZ++QDORB6f2q2Wm6fl2mueSTpFBeBsveK0KW9hWiZ4mNiPjsh6Zs4jjdROSg==
+  dependencies:
+    "@iconify/types" "^2.0.0"
+
 "@intlify/bundle-utils@^7.4.0":
   version "7.5.1"
   resolved "https://registry.npmmirror.com/@intlify/bundle-utils/-/bundle-utils-7.5.1.tgz"
@@ -2203,6 +2210,11 @@
   resolved "https://registry.npmmirror.com/@types/semver/-/semver-7.5.8.tgz"
   integrity sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==
 
+"@types/spark-md5@^3.0.5":
+  version "3.0.5"
+  resolved "https://registry.npmmirror.com/@types/spark-md5/-/spark-md5-3.0.5.tgz#eddec8639217e518c26e9e221ff56bf5f5f5c900"
+  integrity sha512-lWf05dnD42DLVKQJZrDHtWFidcLrHuip01CtnC2/S6AMhX4t9ZlEUj4iuRlAnts0PQk7KESOqKxeGE/b6sIPGg==
+
 "@types/svgo@^2.6.1":
   version "2.6.4"
   resolved "https://registry.npmmirror.com/@types/svgo/-/svgo-2.6.4.tgz"
@@ -8006,6 +8018,11 @@ sourcemap-codec@^1.4.8:
   resolved "https://registry.npmmirror.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4"
   integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==
 
+spark-md5@^3.0.2:
+  version "3.0.2"
+  resolved "https://registry.npmmirror.com/spark-md5/-/spark-md5-3.0.2.tgz#7952c4a30784347abcee73268e473b9c0167e3fc"
+  integrity sha512-wcFzz9cDfbuqe0FZzfi2or1sgyIrsDwmPwfZC4hiNidPdPINjeUwNfv5kldczoEAcjl9Y1L3SM7Uz2PUEQzxQw==
+
 split-string@^3.0.1, split-string@^3.0.2:
   version "3.1.0"
   resolved "https://registry.npmmirror.com/split-string/-/split-string-3.1.0.tgz"