sujunling 2 éve
szülő
commit
e63cec4e57

+ 50 - 4
src/views/assembly/item/AssemblyData.vue

@@ -24,14 +24,26 @@
             <p class="bottomBut">
               <span><a :href="[`../../mapview.html?onlineIde_${i.servicealiasname}`]" target="_blank"
                   rel="noopener noreferrer">浏览</a></span>
-              <span>详情</span>
-              <span>加入库</span>
-              <span>已入库</span>
+              <span @click="showDrawer(i)">详情</span>
+              <span v-if="i.consumetype == 0">加入库</span>
+              <span v-if="i.consumetype == 1">已入库</span>
             </p>
           </div>
         </div>
       </div>
     </div>
+    <a-drawer title="组件详情" width="400px" placement="right" :closable="false" v-model:visible="visible"
+      :after-visible-change="afterVisibleChange">
+      <p><b>资源名称:</b>&nbsp;&nbsp;<span>{{ action.servicename }}</span></p>
+      <p><b>资源别名:</b>&nbsp;&nbsp;<span>{{ action.servicealiasname }}</span></p>
+      <p><b>资源类型:</b>&nbsp;&nbsp;<span>{{ action.source }}</span></p>
+      <p><b>浏览资源:</b>&nbsp;&nbsp;<span><a :href="[`../../mapview.html?onlineIde_${action.servicealiasname}`]"
+            target="_blank" rel="noopener noreferrer">查看组件</a></span></p>
+      <p><b>资源描述:</b>&nbsp;&nbsp;<span>{{ action.description }}</span></p>
+      <div class="footer">
+        <a-button style="margin-right: 8px" @click="onClose">关闭</a-button>
+      </div>
+    </a-drawer>
     <AssemblyDrawer @register="registerModal" />
   </div>
 </template>
@@ -92,8 +104,27 @@ export default defineComponent({
       return url ? url : defUrl;
     }
 
+    const visible = ref<boolean>(false);
+    const action = ref({});
+    const afterVisibleChange = (bool: boolean) => {
+      console.log('visible', bool);
+    };
+
+    const showDrawer = (i) => {
+      console.log("i", i);
+      action.value = i;
+      visible.value = true;
+    };
+    const onClose = () => {
+      visible.value = false;
+    };
 
     return {
+      onClose,
+      action,
+      visible,
+      afterVisibleChange,
+      showDrawer,
       getImg,
       registerModal,
       list,
@@ -104,6 +135,18 @@ export default defineComponent({
 </script>
 
 <style scoped>
+.footer {
+  position: absolute;
+  bottom: 0px;
+  width: 100%;
+  border-top: 1px solid rgb(232, 232, 232);
+  padding: 10px 16px;
+  text-align: right;
+  left: 0px;
+  background: rgb(255, 255, 255);
+  border-radius: 0px 0px 4px 4px;
+}
+
 .bottomBut span:first-child,
 .bottomBut span:nth-child(2) {
   float: left;
@@ -115,9 +158,11 @@ export default defineComponent({
   color: #fff;
   background: #05B069;
 }
+
 .bottomBut span:nth-child(3) {
   margin-right: 0px;
 }
+
 .itemName {
   font-size: 16px;
   font-weight: 500;
@@ -161,4 +206,5 @@ export default defineComponent({
 .item img {
   width: 354px;
   height: 190px;
-}</style>
+}
+</style>

+ 20 - 2
src/views/assembly/item/child/Search.vue

@@ -1,6 +1,6 @@
 <template>
     <div class="wrapper">
-        <span class="sqrk">申请入库(1)</span>
+        <span class="sqrk"  @click="showModal">申请入库(1)</span>
         <span>
             <a-select ref="select" v-model:value="value" style="width: 200px" :options="options" @focus="focus"
                 @change="handleChange">
@@ -15,15 +15,20 @@
             <a-checkbox v-model:checked="checked3">测试数据2</a-checkbox>
             <a-checkbox v-model:checked="checked4">测试数据3</a-checkbox>
         </div>
+        <a-modal v-model:visible="visible" title="申请库" @ok="handleOk" width="1440px" height="980px">
+            <library></library>
+        </a-modal>
     </div>
 </template>
 
 
 <script lang="ts">
 import { defineComponent, ref, computed, unref } from 'vue';
+import library from "../../library/index.vue"
+
 export default defineComponent({
     name: 'Search',
-    components: {},
+    components: {library},
     setup() {
         const value = ref<string>('1');
         const key = ref<string>('');
@@ -51,7 +56,19 @@ export default defineComponent({
 
         }
 
+        const visible = ref<boolean>(false);
+        const showModal = () => {
+            visible.value = true;
+        };
+        const handleOk = (e: MouseEvent) => {
+            console.log(e);
+            visible.value = false;
+        };
+
         return {
+            visible,
+            showModal,
+            handleOk,
             options,
             value,
             key,
@@ -85,6 +102,7 @@ export default defineComponent({
 }
 
 .sqrk {
+    cursor: pointer;
     width: 94px;
     height: 32px;
     background: #0671DD;

+ 225 - 0
src/views/assembly/library/MapDrawer.vue

@@ -0,0 +1,225 @@
+<template>
+  <BasicDrawer v-bind="$attrs" @register="registerDrawer" showFooter :title="getTitle" width="500px" @ok="handleSubmit">
+    <BasicForm @register="registerForm">
+      <template #menu>
+        <Spin :spinning="spinning"></Spin>
+      </template>
+    </BasicForm>
+  </BasicDrawer>
+</template>
+<script lang="ts">
+import { defineComponent, ref, computed, unref, nextTick } from 'vue';
+import { BasicForm, useForm } from '/@/components/Form/index';
+import { formSchema, KeysTypeEnum, RoleMenuDictEnum } from './map.data';
+import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
+import { BasicTree, TreeItem } from '/@/components/Tree';
+import { useMessage } from '/@/hooks/web/useMessage';
+const { t } = useI18n(); //加载国际化
+// 加载菜单数据
+import { getMenuList } from '/@/api/sys/menu';
+import { useI18n } from '/@/hooks/web/useI18n';
+import { MenuRecord } from '/@/api/sys/model/menuModel';
+import { saveOrUpdateRoleInfoWithMenu } from '/@/api/system/system';
+import { findDictItemByCode } from '/@/api/system/dict';
+import { RoleEnum } from '/@/enums/roleEnum';
+import { Spin } from 'ant-design-vue';
+import { useUserStore } from '/@/store/modules/user';
+import { session } from '/@/utils/Memory';
+import { v4 as uuidv4 } from 'uuid';
+
+
+type TreeData = MenuRecord & TreeItem;
+
+export default defineComponent({
+  name: 'RoleDrawer',
+  components: { BasicDrawer, BasicForm, BasicTree, Spin },
+  emits: ['success', 'register'],
+  setup(_, { emit }) {
+    const isUpdate = ref<boolean>(true);
+    const treeData = ref<TreeData[]>([]);
+    const roleMenus = ref<string[]>([]);
+    const roleId = ref<string>('');
+    const checked = ref<string[]>([]); //需要选中的节点
+    const spinning = ref(false);
+    var nowRole = null;
+
+    const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
+      labelWidth: 100,
+      schemas: formSchema,
+      showActionButtonGroup: false,
+    });
+
+    const transformName = (data: TreeData[]) => {
+      return data.map((item) => {
+        item.name = t(item.name);
+        if (item.children && item.children.length) {
+          item.children = transformName(item.children as unknown as TreeData[]);
+        }
+        return item;
+      });
+    };
+
+    const userStore = useUserStore();
+    const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
+      resetFields();
+      roleId.value = '';
+      // 在打开弹窗时清除所有选择的菜单
+      isUpdate.value = data.isUpdate;
+      const roleType = data?.record?.roleType || userStore.getRoleList.at(0);
+
+      try {
+        spinning.value = true;
+        // 需要在setFieldsValue之前先填充treeData,否则Tree组件可能会报key not exist警告
+
+        if (!unref(treeData).length) {
+          // 获取全部的菜单
+          const menuListModel = await getMenuList();
+          treeData.value = transformName(menuListModel as unknown as TreeData[]);
+        }
+
+        const keys = await getPermissionByRole(roleType);
+        const { keyType } = RoleMenuDictEnum[roleType];
+        treeData.value = getPermissionTreeData(
+          unref(treeData) as unknown as TreeData[],
+          keys,
+          keyType
+        );
+        // 更新
+        if (unref(isUpdate)) {
+          checked.value = [];
+          roleId.value = data.record.id;
+          nowRole = data.record;
+          setFieldsValue(data.record);
+        } else {
+        }
+      } catch (error) {
+        throw error;
+      } finally {
+        spinning.value = false;
+      }
+    });
+
+    const getTitle = computed(() => (!unref(isUpdate) ? '新增角色' : '编辑角色'));
+
+    async function handleSubmit() {
+      setDrawerProps({ confirmLoading: true });
+      const { createMessage } = useMessage();
+      try {
+        const values = await validate();
+        const req = {
+          groupName: values.groupName,
+          sort: values.sort
+        };
+        if (unref(isUpdate)) {
+          if (nowRole) {
+            req.updateuser = session.getItem("userInfo").EMPLOYEE.EMPLOYEE_ID;
+            req.groupid = nowRole.groupid;
+          }
+        } else {
+          req.groupid = uuidv4()
+        }
+        saveOrUpdateRoleInfoWithMenu(req).then(() => {
+          closeDrawer();
+          emit('success');
+          nowRole = null;
+          createMessage.success(`${unref(isUpdate) ? '编辑' : '新增'}成功`);
+        });
+      } finally {
+        setTimeout(() => {
+          setDrawerProps({ confirmLoading: false });
+        }, 300);
+      }
+    }
+
+    const getPermissionByRole = async (roleType: RoleEnum) => {
+      try {
+        const { key } = RoleMenuDictEnum[roleType];
+        const res = await findDictItemByCode({ dictCode: key });
+        return res.map((item) => item.itemValue);
+      } catch (error) { }
+      return [];
+    };
+
+    const getPermissionTreeData = (
+      data: MenuRecord[],
+      permissionKeys: string[],
+      keysType: KeysTypeEnum
+    ) => {
+      const setDisabled = (data: MenuRecord[], flag: boolean) => {
+        return data.map((item) => {
+          item.name = t(item.name);
+          if (item.children && item.children.length) {
+            item.children = setDisabled(item.children, flag);
+          }
+          return {
+            ...item,
+            disabled: flag,
+            icon: item.meta.icon,
+          } as TreeData;
+        });
+      };
+
+      const permissionCompare = (
+        data: MenuRecord[],
+        permissionKeys: string[],
+        keysType: KeysTypeEnum
+      ) => {
+        return data.map((item) => {
+          item.name = t(item.name);
+          const findFlag = permissionKeys.includes(item.permission);
+          if (findFlag) item.isDictCompareDisabled = true;
+          const disabledFlag = keysType === KeysTypeEnum.DISABLED ? findFlag : !findFlag;
+          item.disabled = disabledFlag;
+
+          if (item.isDictCompareDisabled && item.children && item.children.length) {
+            setDisabled(item.children, disabledFlag);
+          } else {
+            if (item.children && item.children.length) {
+              item.children = permissionCompare(item.children, permissionKeys, keysType);
+              item.disabled = item.children.every((temp) => temp.disabled);
+            }
+          }
+          return {
+            ...item,
+            icon: item.meta.icon,
+          } as TreeData;
+        });
+      };
+
+      const result = permissionCompare(data, permissionKeys, keysType).map((item) => {
+        if (item.children && item.children.length) {
+          const rootDisabledFlag = item.children.every((temp) => temp.disabled);
+          item.disabled = rootDisabledFlag;
+        }
+        return item;
+      });
+
+      return result;
+    };
+
+    return {
+      spinning,
+      registerDrawer,
+      registerForm,
+      getTitle,
+      handleSubmit,
+      treeData,
+      roleMenus,
+    };
+  },
+});
+</script>
+
+<style scoped lang="less">
+:deep(.vben-basic-tree) {
+  width: 100% !important;
+}
+
+:deep(.is-unflod) {
+  display: none !important;
+}
+
+:deep(.is-flod) {
+  display: none !important;
+}
+</style>

+ 98 - 0
src/views/assembly/library/MapSourceModal.vue

@@ -0,0 +1,98 @@
+
+<template>
+  <BasicModal
+    width="1200px"
+    v-bind="$attrs"
+    @register="registerModal"
+    :title="getTitle"
+    @ok="handleSubmit"
+  >
+    <div style="height: 60vh" class="res-form-container">
+      <a-tabs v-model:activeKey="activeKey" class="res-a-tabs">
+        <a-tab-pane key="1" tab="地图资源信息">
+          <!-- <BasicForm @register="registerForm"></BasicForm> -->
+          <source-detail ref="refSourceDetail" @RtnMain="RtnMain" :formData="formData" :isUpdate="isUpdate"></source-detail>
+        </a-tab-pane>
+        <a-tab-pane key="2" tab="流程信息" force-render>
+          <div class="tab2"></div>
+        </a-tab-pane>
+      </a-tabs>
+    </div>
+  </BasicModal>
+</template>
+  <script lang="ts">
+import { defineComponent, ref, computed, unref, reactive, onMounted } from 'vue';
+import { BasicModal, useModalInner } from '/@/components/Modal';
+import { BasicForm, useForm } from '/@/components/Form/index';
+import { formSchema } from './map.data';
+import { BasicTree } from '/@/components/Tree';
+import { PlusOutlined } from '@ant-design/icons-vue';
+import SourceDetail from './SourceDetail.vue';
+
+export default defineComponent({
+  name: 'AccountModal',
+  components: {
+    BasicModal,
+    BasicForm,
+    BasicTree,
+    PlusOutlined,
+    SourceDetail,
+    VNodes: (_, { attrs }) => {
+      return attrs.vnodes;
+    },
+  },
+  emits: ['success', 'register'],
+  setup(_, { emit }) {
+    const data = reactive({
+      activeKey: '2',
+    });
+    const refSourceDetail = ref(null);
+    let formData = ref(null)
+    const isUpdate = ref(true);
+    const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
+      setModalProps({ confirmLoading: false });
+      isUpdate.value = !!data?.isUpdate;
+      if(isUpdate.value) formData.value = data.record
+    });
+    const getTitle = computed(() => (!unref(isUpdate) ? '新增组件资源' : '编辑组件资源'));
+
+    async function handleSubmit() {
+      refSourceDetail.value.submitForm();
+    }
+    const RtnMain = (status) => {
+      emit('success')
+    }
+
+    onMounted(() => {});
+    return {
+      ...ref(data),
+      registerModal,
+      handleSubmit,
+      getTitle,
+      refSourceDetail,
+      isUpdate,
+      formData,
+      RtnMain,
+    };
+  },
+});
+</script>
+  <style scoped lang="less">
+:deep(.vben-basic-tree) {
+  width: 100% !important;
+}
+
+:deep(.is-unflod) {
+  display: none !important;
+}
+
+:deep(.is-flod) {
+  display: none !important;
+}
+:deep(.res-form-container) {
+  .res-a-tabs {
+    margin-top: 61px !important;
+  }
+}
+</style>
+  

+ 430 - 0
src/views/assembly/library/SourceDetail.vue

@@ -0,0 +1,430 @@
+<!--
+ * @Author: tengmingxue 1473375109@qq.com
+ * @Date: 2023-08-15 22:08:21
+ * @LastEditors: tengmingxue 1473375109@qq.com
+ * @LastEditTime: 2023-08-17 15:59:13
+ * @FilePath: \xld-gis-admin\src\views\resource\map\SourceDetail.vue
+ * @Description: 地图资源明细界面
+-->
+<template>
+  <div class="source-detail">
+    <a-form ref="formRef" :model="formState" :rules="rules" style="width: 100%">
+      <div class="compontents">
+        <div class="title">基本信息</div>
+        <a-row class="form-container">
+          <a-col :span="12" class="form-col">
+            <a-form-item ref="servicename" label="资源名称" name="servicename" class="label-form-item">
+              <a-input v-model:value="formState.servicename" />
+            </a-form-item>
+          </a-col>
+
+          <a-col :span="12" class="form-col">
+            <a-form-item ref="servicealiasname" label="资源别名" name="servicealiasname" class="label-form-item">
+              <a-input v-model:value="formState.servicealiasname" />
+            </a-form-item>
+          </a-col>
+
+          <a-col :span="24" class="form-col">
+            <a-form-item ref="description" label="资源描述" name="description" class="label-form-item">
+              <a-textarea v-model:value="formState.description" :rows="2" />
+            </a-form-item>
+          </a-col>
+          <a-col :span="12" class="form-col">
+            <a-form-item ref="servicetype" label="资源类型" name="servicetype" class="label-form-item">
+              <a-select v-model:value="formState.servicetype">
+                <template v-for="(tag, index) in assemblyType" :key="index">
+                  <a-select-option :value="tag.value">{{ tag.value }}</a-select-option>
+                </template>
+              </a-select>
+            </a-form-item>
+          </a-col>
+          <a-col :span="12" class="form-col">
+            <a-form-item ref="thumbnail" label="缩略图" name="thumbnail" class="label-form-item">
+              <a-upload :custom-request="customUpload" v-model:file-list="fileList">
+                <a-button style="background-color: #0671dd; color: #fff; border-radius: 4px">
+                  <upload-outlined></upload-outlined>
+                  文件上传
+                </a-button>
+              </a-upload>
+            </a-form-item>
+          </a-col>
+        </a-row>
+      </div>
+
+      <div class="compontents">
+        <div class="title">描述信息</div>
+        <a-row class="form-container">
+
+
+
+
+
+
+
+          <a-col :span="12" class="form-col">
+            <a-form-item ref="source" label="发布日期" name="source" class="label-form-item">
+              <!-- <a-input v-model:value="formState.publishtime" disabled /> -->
+              <a-date-picker v-model:value="formState.publishtime" format="YYYY-MM-DD hh:mm:ss" style="width: 100%"
+                disabled show-time>
+                <template #renderExtraFooter>extra footer</template>
+              </a-date-picker>
+            </a-form-item>
+          </a-col>
+          <a-col :span="12" class="form-col">
+            <a-form-item ref="source" label="发布者" name="source" class="label-form-item">
+              <a-input v-model:value="formState.publisher" disabled />
+            </a-form-item>
+          </a-col>
+
+          <a-col :span="12" class="form-col">
+            <a-form-item ref="updatetype" label="更新方式" name="updatetype" class="label-form-item">
+              <a-input v-model:value="formState.updateType" />
+            </a-form-item>
+          </a-col>
+          <a-col :span="12" class="form-col">
+            <a-form-item ref="updatetime" label="更新时间" name="updatetime" class="label-form-item">
+              <a-date-picker v-model:value="formState.updatetime" format="YYYY-MM-DD hh:mm:ss" style="width: 100%"
+                disabled show-time>
+                <template #renderExtraFooter>extra footer</template>
+              </a-date-picker>
+            </a-form-item>
+          </a-col>
+
+
+          <a-col :span="6" class="form-col">
+            <a-form-item ref="public" label="是否公开" name="public" class="label-form-item">
+              <a-switch checked-children="" un-checked-children="" v-model:checked="formState.public" />
+            </a-form-item>
+          </a-col>
+          <a-col :span="6" class="form-col">
+            <a-form-item ref="share" label="是否共享" name="share" class="label-form-item">
+              <a-switch checked-children="" un-checked-children="" v-model:checked="formState.share" />
+            </a-form-item>
+          </a-col>
+          <a-col :span="6" class="form-col">
+            <a-form-item ref="externalApply" label="是否外部申请" name="externalApply" class="label-form-item">
+              <a-switch checked-children="" un-checked-children="" v-model:checked="formState.externalApply" />
+            </a-form-item>
+          </a-col>
+          <a-col :span="6" class="form-col">
+            <a-form-item ref="searched" label="是否展示" name="searched" class="label-form-item">
+              <a-switch checked-children="" un-checked-children="" v-model:checked="formState.searched" />
+            </a-form-item>
+          </a-col>
+        </a-row>
+      </div>
+    </a-form>
+  </div>
+</template>
+<script lang="ts">
+import {
+  defineComponent,
+  ref,
+  toRefs,
+  toRaw,
+  unref,
+  computed,
+  unref,
+  nextTick,
+  reactive,
+  UnwrapRef,
+  onMounted,
+  watch,
+} from 'vue';
+import { BasicForm, useForm } from '/@/components/Form/index';
+import { UploadOutlined } from '@ant-design/icons-vue';
+import { ValidateErrorEntity } from 'ant-design-vue/es/form/interface';
+import { useMessage } from '/@/hooks/web/useMessage';
+const { t } = useI18n(); //加载国际化
+// 加载菜单数据
+import { useI18n } from '/@/hooks/web/useI18n';
+import Moment from 'moment';
+import { insertService, updateService, update } from '/@/api/dataAdmin/assembly';
+import { session } from '/@/utils/Memory.js';
+
+const props = {
+  formData: { type: Object, default: ref(null) },
+  isUpdate: { type: Boolean, default: ref(false) },
+};
+interface FormState {
+  servicetype: string,
+  servicename: string;
+  mapingurl: string,
+  servicealiasname: string;
+  description: string;
+  publishtime: string;
+  publisher: string;
+  updateType: string;
+  updatetime: string;
+  public: boolean;
+  share: boolean;
+  searched: boolean;
+  externalApply: boolean;
+  date1: undefined;
+}
+export default defineComponent({
+  name: 'SourceDetail',
+  components: { BasicForm, UploadOutlined },
+  props,
+  setup(props, { emit }) {
+    const data = reactive({
+      detail: props.formData,
+      isUpdate: props.isUpdate,
+      fileList: [],
+    });
+    var assemblyType = ref([
+      { value: '地图基础功能' },
+      { value: '覆盖物' },
+      { value: '测量工具' },
+      { value: '绘制工具' },
+      { value: '空间分析' },
+      { value: '天气特效' },
+    ])
+
+    const formRef = ref();
+    const formState: UnwrapRef<FormState> = reactive({
+      mapingurl: '',
+      servicename: '',
+      servicealiasname: '',
+      servicetype: '',
+      description: '',
+      publishtime: '',
+      publisher: '',
+      updateType: '',
+      updatetime: '',
+      public: true,
+      share: true,
+      searched: true,
+      externalApply: true,
+      date1: undefined,
+    });
+    const moment = Moment;
+    const rules = {
+      // mapingurl: [{ required: true, message: '请输入服务地址', trigger: 'blur' }],
+      servicetype: [{ required: true, message: '请选择资源类型', trigger: 'change' }],
+
+      servicename: [
+        { required: true, message: '请填写资源名称', trigger: 'blur' },
+        { min: 3, max: 20, message: '长度必须在3到20个字符', trigger: 'blur' },
+      ],
+      servicealiasname: [
+        { required: true, message: '请输入资源别名', trigger: 'blur' },
+        { min: 3, max: 20, message: '长度必须在3到20个字符', trigger: 'blur' },
+      ],
+      systag: [{ required: true, message: '请选择系统标签', trigger: 'change' }],
+      date1: [{ required: true, message: 'Please pick a date', trigger: 'change', type: 'object' }],
+      type: [
+        {
+          type: 'array',
+          required: true,
+          message: 'Please select at least one activity type',
+          trigger: 'change',
+        },
+      ],
+      resource: [{ required: true, message: 'Please select activity resource', trigger: 'change' }],
+      desc: [{ required: true, message: 'Please input activity form', trigger: 'blur' }],
+    };
+    const { createMessage } = useMessage();
+    watch(
+      () => props.formData,
+      (obj) => {
+        data.detail = obj;
+        if (data.isUpdate) setFormData();
+      }
+    );
+    watch(
+      () => props.isUpdate,
+      (obj) => {
+        data.isUpdate = obj;
+      }
+    );
+    const submitForm = () => {
+      try {
+        formRef.value
+          .validate()
+          .then(async () => {
+            const params = setSubmitForm();
+            console.log(params);
+            if (params) {
+              if (data.isUpdate) {
+                params.servicebase.serviceid = data.detail.serviceid;
+                params.servicebase.id = data.detail.id;
+                if (!params.servicebase.mapingurl) params.servicebase.mapingurl = data.detail.mapingurl;
+
+                params.metadata.serviceid = data.detail.serviceid;
+                params.metadata.id = data.detail.id;
+                if (!params.metadata.mapingurl) params.metadata.mapingurl = data.detail.mapingurl;
+
+
+                const res = await updateService(params);
+                if (res && res?.status !== '-1') {
+                  createMessage.success('修改地图资源成功!');
+                  resetForm();
+                  emit('RtnMain', true);
+                } else createMessage.error('修改地图资源失败!,失败原因:' + res?.message, 1);
+              } else {
+                const res = await insertService(params);
+                if (res && res?.status !== '-1') {
+                  createMessage.success('新增地图资源成功!');
+                  resetForm();
+                  emit('RtnMain', true);
+                } else createMessage.error('新增地图资源失败!,失败原因:' + res?.message, 1);
+              }
+            }
+          })
+          .catch((error: ValidateErrorEntity<FormState>) => {
+            createMessage.error('请完成必填信息!', 1);
+            console.log('error', error);
+          });
+      } catch (ex) {
+        console.log(ex);
+      }
+    };
+    const resetForm = () => {
+      formRef.value.resetFields();
+    };
+
+    /**
+     * 设置提交数据
+     */
+    const setSubmitForm = () => {
+      const userinfo = session.getItem('userInfo');
+      return {
+        type: 'SR',
+        servicebase: {
+          publisher: userinfo?.EMPLOYEE?.NAME, //'系统管理员',
+          username: userinfo?.EMPLOYEE?.NAME, //'系统管理员',
+          userid: userinfo?.EMPLOYEE?.EMPLOYEE_ID, //'27AF004A-8BDN-885T-30FU-89DE3388762B',
+          servicealiasname: formState.servicealiasname, //资源别名
+          description: formState.description, //资源描述
+          ispublic: formState.public ? '1' : '0', //是否公开
+          searched: formState.searched ? '1' : '0', //是否展示
+          externalApply: formState.externalApply ? '1' : '0', //外部申请
+          servicename: formState.servicename, //资源名
+          otherService: '',
+          source: formState.servicetype, //资源类型
+          mapingurl: formState.mapingurl //服务地址
+        },
+        metadata: {
+          source: formState.servicetype, //资源类型
+          mapingurl: formState.mapingurl, //服务地址
+          name: formState.servicename, //资源名
+          servicealiasname: formState.servicealiasname, //资源别名
+          thumbnail: '',
+          description: formState.description,
+          updateType: formState.updateType, //更新方式
+          workSpace: '',
+          ishistory: '0',
+          shsqlc: 'ggdata',
+          urlInfo: '',
+          otherService: '',
+          bz: '',
+          ispublic: formState.public ? '1' : '0', //是否公开
+          searched: formState.searched ? '1' : '0', //是否展示
+          externalApply: formState.externalApply ? '1' : '0', //外部申请
+          isShow: formState.share ? '1' : '0',
+          publisher: userinfo?.EMPLOYEE?.NAME, //'系统管理员',
+          username: userinfo?.EMPLOYEE?.NAME, //'系统管理员',
+          userid: userinfo?.EMPLOYEE?.EMPLOYEE_ID, //'27AF004A-8BDN-885T-30FU-89DE3388762B',
+        }
+      };
+    };
+    /**
+     * 设置表单数据
+     */
+    const setFormData = () => {
+      formState.public = data.detail.ispublic === '1' ? true : false;
+      formState.servicename = data.detail?.servicename;
+      formState.publishtime = data.detail?.publishdate
+        ? moment(data.detail?.publishdate).format('YYYY-MM-DD HH:mm:ss')
+        : '';
+      formState.publisher = data.detail?.publisher;
+      formState.servicealiasname = data.detail?.servicealiasname;
+      formState.updatetime = data.detail?.updatedate
+        ? moment(data.detail?.updatedate).format('YYYY-MM-DD HH:mm:ss')
+        : '';
+      formState.searched = data.detail.searched === 0 ? false : true;
+    };
+
+    onMounted(() => {
+      resetForm();
+    });
+
+    function customUpload({ file, onSuccess, onError }) {
+      const formData = new FormData();
+      formData.append('file', file);
+      update(formData, session.getItem('sysFild').dirId).then(r => {
+        if (r && r.resp_code == 0 && r.resp_msg == "OK") {
+          formState.mapingurl = `${r.datas.id},${r.datas.dirId}`;
+          onSuccess()
+        } else {
+          onError()
+        }
+      })
+    }
+    return {
+      assemblyType,
+      customUpload,
+      ...toRefs(data),
+      formRef,
+      moment,
+      rules,
+      formState,
+      submitForm,
+      resetForm,
+      createMessage,
+      setSubmitForm,
+      setFormData,
+    };
+  },
+});
+</script>
+  
+<style scoped lang="less">
+.source-detail {
+  height: 100%;
+  width: 100%;
+  padding: 0 20px;
+
+  .compontents {
+    width: 100%;
+    height: auto;
+
+    .title {
+      height: 19px;
+      line-height: 18px;
+      padding-left: 6px;
+      margin-bottom: 20px;
+      border-left: 3px solid #0671dd;
+      font-family: Source Han Sans CN;
+      font-size: 16px;
+      font-weight: 350;
+      letter-spacing: 0px;
+    }
+
+    .form-container {
+      width: 100%;
+      height: auto;
+
+      .form-col {
+        height: 100%;
+      }
+
+      .form-col-left {
+        padding-right: 20px;
+      }
+    }
+  }
+}
+
+.label-form-item {
+  :deep(.ant-form-item-label) {
+    width: 90px;
+  }
+
+  :deep(.ant-form-item-control) {
+    width: calc(100% - 90px);
+  }
+}
+</style>
+  

+ 218 - 0
src/views/assembly/library/index.vue

@@ -0,0 +1,218 @@
+<template>
+  <div>
+    <BasicTable :rowSelection="{ type: 'checkbox' }" @register="registerTable" :clickToRowSelect="false">
+      <template #toolbar>
+        <Authority>
+          <a-button type="primary" @click="handleCreate">提交申请</a-button>
+        </Authority>
+        <Authority>
+          <Popconfirm title="您确定要批量删除数据" ok-text="确定" cancel-text="取消" @confirm="handleDeleteOrBatchDelete(null)">
+            <a-button type="primary" color="error" :disabled="hasBatchDelete"> 批量删除 </a-button>
+          </Popconfirm>
+        </Authority>
+      </template>
+      <!-- <template #status="{ record }">
+        <Switch :checked="record.status === 1" :loading="record.pendingStatus" checkedChildren="启用" unCheckedChildren="禁用"
+          @change="(checked: boolean) => statusChange(checked, record)" />
+      </template> -->
+      <template #action="{ record }">
+        <TableAction :actions="[
+          {
+            label: '浏览',
+            icon: '' /**clarity:note-edit-line*/,
+            // ifShow: record.servicealiasname,
+            // ifShow: ((action) => action.servicealiasname),
+            ifShow: record.servicealiasname,
+            onClick: see.bind(null, record),
+          },
+          {
+            label: '查看',
+            icon: '' /**clarity:note-edit-line*/,
+            onClick: handleEdit.bind(null, record),
+          },
+          {
+            label: '编辑',
+            icon: '' /**clarity:note-edit-line*/,
+            color: 'warning',
+            onClick: handleEdit.bind(null, record),
+          },
+          {
+            label: '删除',
+            icon: '' /**ant-design:delete-outlined'*/,
+            color: 'error',
+            ifShow: record.roleType != RoleEnum.SYS_ADMIN,
+            popConfirm: {
+              title: '是否确认删除',
+              confirm: handleDelete.bind(null, record),
+            },
+          },
+        ]" />
+      </template>
+      <template #pdate="{ record }">
+        <Tag :color="'red'">
+          {{
+            record.publishdate ? moment(record.publishdate).format('YYYY-MM-DD HH:mm:ss') : ''
+          }}
+        </Tag>
+      </template>
+      <template #status="{ record }">
+        <Tag :style="`color:${record.status === 3 || record.status === 3 ? 'red' : ''};`">
+          {{
+            record.status === 0 ? '待审核' : (record.status === 1 ? '审核通过' : (record.status === 2 ? '审核不通过' : (record.status
+              === 3 ? '被驳回' : '未提交')))
+          }}
+        </Tag>
+      </template>
+    </BasicTable>
+    <!-- <MapDrawer @register="registerDrawer" @success="handleSuccess" /> -->
+    <MapSourceModal @register="registerModal" @success="handleSuccess" />
+  </div>
+</template>
+<script lang="ts">
+import { defineComponent, nextTick, onBeforeMount } from 'vue';
+import { BasicTable, useTable, TableAction } from '/@/components/Table';
+import { delRole, getRoleListByPage, setRoleStatus } from '/@/api/system/system';
+// import { useDrawer } from '/@/components/Drawer';
+import { useModal } from '/@/components/Modal';
+import MapDrawer from './MapDrawer.vue';
+import MapSourceModal from './MapSourceModal.vue';
+import { columns, searchFormSchema } from './map.data';
+import { RoleEnum } from '/@/enums/roleEnum';
+import { Authority } from '/@/components/Authority';
+import { useBatchDelete } from '/@/hooks/web/useBatchDelete';
+import { useMessage } from '/@/hooks/web/useMessage';
+import { Switch, Popconfirm } from 'ant-design-vue';
+import { list, deleteService } from '/@/api/dataAdmin/assembly';
+import Moment from 'moment'
+
+export default defineComponent({
+  name: 'RoleManagement',
+  components: { BasicTable, MapDrawer, MapSourceModal, TableAction, Authority, Switch, Popconfirm },
+  setup() {
+    //const [registerDrawer, { openDrawer }] = useDrawer();
+    const [registerModal, { openModal }] = useModal();
+    const [registerTable, { setProps, reload, setSelectedRowKeys }] = useTable({
+      title: '地图资源列表',
+      api: list,
+      columns,
+      formConfig: {
+        labelWidth: 100,
+        schemas: searchFormSchema,
+      },
+      useSearchForm: true,
+      showTableSetting: true,
+      bordered: true,
+      showIndexColumn: true,
+      actionColumn: {
+        width: 200,
+        title: '操作',
+        dataIndex: 'action',
+        slots: { customRender: 'action' },
+        fixed: 'right',
+      },
+    });
+    const moment = Moment
+    const { createMessage } = useMessage();
+    const { hasBatchDelete, handleDeleteOrBatchDelete, selectionOptions, resetSelectedRowKeys } =
+      useBatchDelete(delRole, handleSuccess, setProps);
+    selectionOptions.rowSelection.getCheckboxProps = (record: Recordable) => {
+      // Demo:status为1的选择框禁用
+      if (record.status === 1) {
+        return { disabled: true };
+      } else {
+        return { disabled: false };
+      }
+    };
+    nextTick(() => {
+      setProps(selectionOptions);
+    });
+
+    function handleCreate() {
+      // openDrawer(true, {
+      //   isUpdate: false,
+      // });
+      openModal(true, {
+        isUpdate: false,
+      });
+    }
+
+    function handleEdit(record: Recordable) {
+      // openDrawer(true, {
+      //   record,
+      //   isUpdate: true,
+      // });
+      openModal(true, {
+        record,
+        isUpdate: true,
+      });
+    }
+
+    function see(e) {
+      console.log(e);
+      if (e.servicealiasname) window.open(`../../mapview.html?onlineIde_${e.servicealiasname}`, '_blank');
+    }
+
+    const handleDelete = async (record: Recordable) => {
+      if (record?.serviceid) {
+        const res = await deleteService(record?.serviceid)
+        if (res?.status !== '-1') {
+          reload();
+          createMessage.success('删除成功!', 1)
+        }
+        else {
+          createMessage.error('删除失败!失败原因:' + res?.message, 1)
+        }
+      }
+    }
+
+    function handleSuccess() {
+      openModal(false, {
+        isUpdate: false,
+      });
+      reload();
+    }
+
+    const statusChange = async (checked, record) => {
+      setProps({
+        loading: true,
+      });
+      setSelectedRowKeys([]);
+      resetSelectedRowKeys();
+      const newStatus = checked ? 1 : 0;
+      try {
+        await setRoleStatus(record.id, newStatus);
+        if (newStatus) {
+          createMessage.success(`启用成功`);
+        } else {
+          createMessage.success('禁用成功');
+        }
+      } finally {
+        setProps({
+          loading: false,
+        });
+        reload();
+      }
+    };
+    onBeforeMount(async () => {
+
+    })
+
+    return {
+      moment,
+      createMessage,
+      registerTable,
+      // registerDrawer,
+      registerModal,
+      handleCreate,
+      see,
+      handleEdit,
+      handleDelete,
+      handleSuccess,
+      RoleEnum,
+      hasBatchDelete,
+      handleDeleteOrBatchDelete,
+      statusChange,
+    };
+  },
+});
+</script>

+ 180 - 0
src/views/assembly/library/map.data.ts

@@ -0,0 +1,180 @@
+import { BasicColumn } from '/@/components/Table';
+import { FormSchema } from '/@/components/Table';
+import { RoleEnum } from '/@/enums/roleEnum';
+import { getServiceTypes,queryServiceTags,queryDicsByName,queryCoors } from '/@/api/resource/map';
+
+const resTag = await queryServiceTags()
+let listTag = []
+resTag.map(item => {
+  listTag.push({
+    label: item.name,
+    value: item.code
+  })
+})
+/**
+ * 密级字典
+*/
+export const secrets = await queryDicsByName('密级')
+/**
+ * 服务标签
+*/
+export const serviceTags = listTag;
+/**
+ * 坐标系列表
+*/
+export const sysCoors = await queryCoors()
+/**
+ * 服务类型
+*/
+export const serviceTypes = await getServiceTypes()
+/**
+ * 责任处室
+*/
+export const respDept = await queryDicsByName('责任处室')
+/**
+ * 保管单位
+*/
+export const collectDept = await queryDicsByName('保管单位')
+/**
+ * EPSG code
+*/
+export const EPSGCodes = await queryDicsByName('EPSG code')
+
+
+const checkStatus = [
+  { label: '未提交', value: 1 },
+  { label: '审核中', value: 2 },
+  { label: '审核不通过', value: 3 },
+  { label: '被驳回', value: 4 },
+  { label: '审核通过', value: 5 },
+]
+export enum KeysTypeEnum {
+  DISABLED = 'disabled',
+  ENABLED = 'enabled',
+}
+
+export const RoleMenuDictEnum: Recordable<{ key: string; keyType: KeysTypeEnum }> = {
+  [RoleEnum.PLATFORM_ADMIN]: { key: 'enabled_platform_admin_auth', keyType: KeysTypeEnum.ENABLED },
+  [RoleEnum.SYS_ADMIN]: { key: 'enabled_sysadmin_auth', keyType: KeysTypeEnum.ENABLED },
+  [RoleEnum.TENANT_ADMIN]: { key: 'disabled_tenant_auth', keyType: KeysTypeEnum.DISABLED },
+  [RoleEnum.CUSTOMER_USER]: { key: 'disabled_tenant_auth', keyType: KeysTypeEnum.DISABLED },
+};
+
+/**
+ * 查询条件
+*/
+export const searchFormSchema: FormSchema[] = [
+  {
+    field: 'resTag',
+    label: '资源标签',
+    component: 'Select',
+    componentProps: {
+      options: serviceTags,
+      // [
+      //   { label: '标签1', value: 1 },
+      //   { label: '标签2', value: 2 },
+      //   { label: '标签3', value: 3 },
+      // ],
+    },
+    colProps: { span: 5 },
+  },
+  {
+    field: 'resName',
+    label: '资源名称',
+    component: 'Input',
+    colProps: { span: 5 },
+    componentProps: {
+      maxLength: 255,
+    },
+  },
+  {
+    field: 'checkStatus',
+    label: '审核状态',
+    component: 'Select',
+    componentProps: {
+      options: checkStatus,
+    },
+    colProps: { span: 5 },
+  },
+];
+
+/**
+ * 列表显示信息
+*/
+export const columns: BasicColumn[] = [
+  {
+    title: '资源标签',
+    dataIndex: 'typename',
+    width: 120,
+  },
+  {
+    title: '资源名称',
+    dataIndex: 'servicename',
+    width: 160,
+  },
+  {
+    title: '应用系统',
+    dataIndex: 'servicename',
+    width: 160,
+  },
+  {
+    title: '申请单位',
+    dataIndex: 'servicename',
+    width: 160,
+  },
+  // {
+  //   title: '发布人',
+  //   dataIndex: 'publisher',
+  //   width: 120,
+  // },
+  // {
+  //   title: '发布时间',
+  //   dataIndex: 'publishdate',
+  //   width: 180,
+  //   slots: { customRender: 'pdate' },
+  // },
+  {
+    title: '申请时间',
+    dataIndex: 'checkTime',
+    width: 100,
+  },
+  {
+    title: '申请人',
+    dataIndex: 'curHandler',
+    width: 100,
+  },
+  {
+    title: '审核状态',
+    dataIndex: 'status',
+    width: 110,
+    slots: { customRender: 'status' },
+  },
+
+];
+
+
+
+/**
+ * 表单
+*/
+export const formSchema: FormSchema[] = [
+  {
+    field: 'groupName',
+    label: '角色名称',
+    required: true,
+    component: 'Input',
+    componentProps: {
+      maxLength: 255,
+      placeholder: '请输入角色名称',
+    },
+  },
+  {
+    label: '排序',
+    field: 'sort',
+    component: 'Input',
+    componentProps: {
+      maxLength: 255,
+      placeholder: '请输入排序',
+    },
+  }
+];

+ 12 - 3
src/views/interface/index.vue

@@ -5,7 +5,8 @@
         <p>通用接口</p>
       </div>
       <div class="ztree-container">
-        <p v-for="(i, k) in menu" :key="k">{{ i.name }}({{ i.num }})</p>
+        <p v-for="(i, k) in menu" :key="k" @click="scrollToSection(k)"
+          :class="[`${action == k ? 'action' : ''}`]">{{ i.name }}({{ i.num }})</p>
       </div>
     </div>
     <div class="datacenter-right">
@@ -27,7 +28,7 @@ export default defineComponent({
     AssemblyData,
   },
   setup() {
-
+    const action = ref(0)
     var menu = [
       { name: '数据分析', num: 10 },
       { name: '用户中心', num: 7 },
@@ -35,8 +36,12 @@ export default defineComponent({
       { name: '空间分析', num: 9 },
       { name: '专项接口', num: 6 }
     ]
-
+    function scrollToSection(index) {
+      action.value = index;
+    }
     return {
+      scrollToSection,
+      action,
       menu,
       prefixCls: 'account-center',
 
@@ -45,6 +50,10 @@ export default defineComponent({
 });
 </script>
 <style lang="less" scoped>
+.ztree-container p.action {
+  background: #0671DD;
+  color: #fff;
+}
 .account-center-bottom {
   background: #fff;
   height: calc(100vh - 110px);

+ 20 - 2
src/views/interface/item/child/Search.vue

@@ -1,6 +1,6 @@
 <template>
     <div class="wrapper">
-        <span class="sqrk">申请库(1)</span>
+        <span class="sqrk"  @click="showModal">申请库(1)</span>
         <span>
             <a-select ref="select" v-model:value="value" style="width: 200px" :options="options" @focus="focus"
                 @change="handleChange">
@@ -16,15 +16,20 @@
             <a-checkbox v-model:checked="checked4">测试数据3</a-checkbox> -->
             一共有6个通用接口
         </div>
+        <a-modal v-model:visible="visible" title="申请库" @ok="handleOk" width="1440px" height="980px">
+            <library></library>
+        </a-modal>
     </div>
 </template>
 
 
 <script lang="ts">
 import { defineComponent, ref, computed, unref } from 'vue';
+import library from "../../library/index.vue"
+
 export default defineComponent({
     name: 'Search',
-    components: {},
+    components: { library },
     setup() {
         const value = ref<string>('1');
         const key = ref<string>('');
@@ -52,7 +57,19 @@ export default defineComponent({
 
         }
 
+        const visible = ref<boolean>(false);
+        const showModal = () => {
+            visible.value = true;
+        };
+        const handleOk = (e: MouseEvent) => {
+            console.log(e);
+            visible.value = false;
+        };
+
         return {
+            visible,
+            showModal,
+            handleOk,
             options,
             value,
             key,
@@ -86,6 +103,7 @@ export default defineComponent({
 }
 
 .sqrk {
+    cursor: pointer;
     width: 94px;
     height: 32px;
     background: #0671DD;

+ 225 - 0
src/views/interface/library/MapDrawer.vue

@@ -0,0 +1,225 @@
+<template>
+  <BasicDrawer v-bind="$attrs" @register="registerDrawer" showFooter :title="getTitle" width="500px" @ok="handleSubmit">
+    <BasicForm @register="registerForm">
+      <template #menu>
+        <Spin :spinning="spinning"></Spin>
+      </template>
+    </BasicForm>
+  </BasicDrawer>
+</template>
+<script lang="ts">
+import { defineComponent, ref, computed, unref, nextTick } from 'vue';
+import { BasicForm, useForm } from '/@/components/Form/index';
+import { formSchema, KeysTypeEnum, RoleMenuDictEnum } from './map.data';
+import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
+import { BasicTree, TreeItem } from '/@/components/Tree';
+import { useMessage } from '/@/hooks/web/useMessage';
+const { t } = useI18n(); //加载国际化
+// 加载菜单数据
+import { getMenuList } from '/@/api/sys/menu';
+import { useI18n } from '/@/hooks/web/useI18n';
+import { MenuRecord } from '/@/api/sys/model/menuModel';
+import { saveOrUpdateRoleInfoWithMenu } from '/@/api/system/system';
+import { findDictItemByCode } from '/@/api/system/dict';
+import { RoleEnum } from '/@/enums/roleEnum';
+import { Spin } from 'ant-design-vue';
+import { useUserStore } from '/@/store/modules/user';
+import { session } from '/@/utils/Memory';
+import { v4 as uuidv4 } from 'uuid';
+
+
+type TreeData = MenuRecord & TreeItem;
+
+export default defineComponent({
+  name: 'RoleDrawer',
+  components: { BasicDrawer, BasicForm, BasicTree, Spin },
+  emits: ['success', 'register'],
+  setup(_, { emit }) {
+    const isUpdate = ref<boolean>(true);
+    const treeData = ref<TreeData[]>([]);
+    const roleMenus = ref<string[]>([]);
+    const roleId = ref<string>('');
+    const checked = ref<string[]>([]); //需要选中的节点
+    const spinning = ref(false);
+    var nowRole = null;
+
+    const [registerForm, { resetFields, setFieldsValue, validate }] = useForm({
+      labelWidth: 100,
+      schemas: formSchema,
+      showActionButtonGroup: false,
+    });
+
+    const transformName = (data: TreeData[]) => {
+      return data.map((item) => {
+        item.name = t(item.name);
+        if (item.children && item.children.length) {
+          item.children = transformName(item.children as unknown as TreeData[]);
+        }
+        return item;
+      });
+    };
+
+    const userStore = useUserStore();
+    const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
+      resetFields();
+      roleId.value = '';
+      // 在打开弹窗时清除所有选择的菜单
+      isUpdate.value = data.isUpdate;
+      const roleType = data?.record?.roleType || userStore.getRoleList.at(0);
+
+      try {
+        spinning.value = true;
+        // 需要在setFieldsValue之前先填充treeData,否则Tree组件可能会报key not exist警告
+
+        if (!unref(treeData).length) {
+          // 获取全部的菜单
+          const menuListModel = await getMenuList();
+          treeData.value = transformName(menuListModel as unknown as TreeData[]);
+        }
+
+        const keys = await getPermissionByRole(roleType);
+        const { keyType } = RoleMenuDictEnum[roleType];
+        treeData.value = getPermissionTreeData(
+          unref(treeData) as unknown as TreeData[],
+          keys,
+          keyType
+        );
+        // 更新
+        if (unref(isUpdate)) {
+          checked.value = [];
+          roleId.value = data.record.id;
+          nowRole = data.record;
+          setFieldsValue(data.record);
+        } else {
+        }
+      } catch (error) {
+        throw error;
+      } finally {
+        spinning.value = false;
+      }
+    });
+
+    const getTitle = computed(() => (!unref(isUpdate) ? '新增角色' : '编辑角色'));
+
+    async function handleSubmit() {
+      setDrawerProps({ confirmLoading: true });
+      const { createMessage } = useMessage();
+      try {
+        const values = await validate();
+        const req = {
+          groupName: values.groupName,
+          sort: values.sort
+        };
+        if (unref(isUpdate)) {
+          if (nowRole) {
+            req.updateuser = session.getItem("userInfo").EMPLOYEE.EMPLOYEE_ID;
+            req.groupid = nowRole.groupid;
+          }
+        } else {
+          req.groupid = uuidv4()
+        }
+        saveOrUpdateRoleInfoWithMenu(req).then(() => {
+          closeDrawer();
+          emit('success');
+          nowRole = null;
+          createMessage.success(`${unref(isUpdate) ? '编辑' : '新增'}成功`);
+        });
+      } finally {
+        setTimeout(() => {
+          setDrawerProps({ confirmLoading: false });
+        }, 300);
+      }
+    }
+
+    const getPermissionByRole = async (roleType: RoleEnum) => {
+      try {
+        const { key } = RoleMenuDictEnum[roleType];
+        const res = await findDictItemByCode({ dictCode: key });
+        return res.map((item) => item.itemValue);
+      } catch (error) { }
+      return [];
+    };
+
+    const getPermissionTreeData = (
+      data: MenuRecord[],
+      permissionKeys: string[],
+      keysType: KeysTypeEnum
+    ) => {
+      const setDisabled = (data: MenuRecord[], flag: boolean) => {
+        return data.map((item) => {
+          item.name = t(item.name);
+          if (item.children && item.children.length) {
+            item.children = setDisabled(item.children, flag);
+          }
+          return {
+            ...item,
+            disabled: flag,
+            icon: item.meta.icon,
+          } as TreeData;
+        });
+      };
+
+      const permissionCompare = (
+        data: MenuRecord[],
+        permissionKeys: string[],
+        keysType: KeysTypeEnum
+      ) => {
+        return data.map((item) => {
+          item.name = t(item.name);
+          const findFlag = permissionKeys.includes(item.permission);
+          if (findFlag) item.isDictCompareDisabled = true;
+          const disabledFlag = keysType === KeysTypeEnum.DISABLED ? findFlag : !findFlag;
+          item.disabled = disabledFlag;
+
+          if (item.isDictCompareDisabled && item.children && item.children.length) {
+            setDisabled(item.children, disabledFlag);
+          } else {
+            if (item.children && item.children.length) {
+              item.children = permissionCompare(item.children, permissionKeys, keysType);
+              item.disabled = item.children.every((temp) => temp.disabled);
+            }
+          }
+          return {
+            ...item,
+            icon: item.meta.icon,
+          } as TreeData;
+        });
+      };
+
+      const result = permissionCompare(data, permissionKeys, keysType).map((item) => {
+        if (item.children && item.children.length) {
+          const rootDisabledFlag = item.children.every((temp) => temp.disabled);
+          item.disabled = rootDisabledFlag;
+        }
+        return item;
+      });
+
+      return result;
+    };
+
+    return {
+      spinning,
+      registerDrawer,
+      registerForm,
+      getTitle,
+      handleSubmit,
+      treeData,
+      roleMenus,
+    };
+  },
+});
+</script>
+
+<style scoped lang="less">
+:deep(.vben-basic-tree) {
+  width: 100% !important;
+}
+
+:deep(.is-unflod) {
+  display: none !important;
+}
+
+:deep(.is-flod) {
+  display: none !important;
+}
+</style>

+ 98 - 0
src/views/interface/library/MapSourceModal.vue

@@ -0,0 +1,98 @@
+
+<template>
+  <BasicModal
+    width="1200px"
+    v-bind="$attrs"
+    @register="registerModal"
+    :title="getTitle"
+    @ok="handleSubmit"
+  >
+    <div style="height: 60vh" class="res-form-container">
+      <a-tabs v-model:activeKey="activeKey" class="res-a-tabs">
+        <a-tab-pane key="1" tab="地图资源信息">
+          <!-- <BasicForm @register="registerForm"></BasicForm> -->
+          <source-detail ref="refSourceDetail" @RtnMain="RtnMain" :formData="formData" :isUpdate="isUpdate"></source-detail>
+        </a-tab-pane>
+        <a-tab-pane key="2" tab="流程信息" force-render>
+          <div class="tab2"></div>
+        </a-tab-pane>
+      </a-tabs>
+    </div>
+  </BasicModal>
+</template>
+  <script lang="ts">
+import { defineComponent, ref, computed, unref, reactive, onMounted } from 'vue';
+import { BasicModal, useModalInner } from '/@/components/Modal';
+import { BasicForm, useForm } from '/@/components/Form/index';
+import { formSchema } from './map.data';
+import { BasicTree } from '/@/components/Tree';
+import { PlusOutlined } from '@ant-design/icons-vue';
+import SourceDetail from './SourceDetail.vue';
+
+export default defineComponent({
+  name: 'AccountModal',
+  components: {
+    BasicModal,
+    BasicForm,
+    BasicTree,
+    PlusOutlined,
+    SourceDetail,
+    VNodes: (_, { attrs }) => {
+      return attrs.vnodes;
+    },
+  },
+  emits: ['success', 'register'],
+  setup(_, { emit }) {
+    const data = reactive({
+      activeKey: '2',
+    });
+    const refSourceDetail = ref(null);
+    let formData = ref(null)
+    const isUpdate = ref(true);
+    const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
+      setModalProps({ confirmLoading: false });
+      isUpdate.value = !!data?.isUpdate;
+      if(isUpdate.value) formData.value = data.record
+    });
+    const getTitle = computed(() => (!unref(isUpdate) ? '新增组件资源' : '编辑组件资源'));
+
+    async function handleSubmit() {
+      refSourceDetail.value.submitForm();
+    }
+    const RtnMain = (status) => {
+      emit('success')
+    }
+
+    onMounted(() => {});
+    return {
+      ...ref(data),
+      registerModal,
+      handleSubmit,
+      getTitle,
+      refSourceDetail,
+      isUpdate,
+      formData,
+      RtnMain,
+    };
+  },
+});
+</script>
+  <style scoped lang="less">
+:deep(.vben-basic-tree) {
+  width: 100% !important;
+}
+
+:deep(.is-unflod) {
+  display: none !important;
+}
+
+:deep(.is-flod) {
+  display: none !important;
+}
+:deep(.res-form-container) {
+  .res-a-tabs {
+    margin-top: 61px !important;
+  }
+}
+</style>
+  

+ 430 - 0
src/views/interface/library/SourceDetail.vue

@@ -0,0 +1,430 @@
+<!--
+ * @Author: tengmingxue 1473375109@qq.com
+ * @Date: 2023-08-15 22:08:21
+ * @LastEditors: tengmingxue 1473375109@qq.com
+ * @LastEditTime: 2023-08-17 15:59:13
+ * @FilePath: \xld-gis-admin\src\views\resource\map\SourceDetail.vue
+ * @Description: 地图资源明细界面
+-->
+<template>
+  <div class="source-detail">
+    <a-form ref="formRef" :model="formState" :rules="rules" style="width: 100%">
+      <div class="compontents">
+        <div class="title">基本信息</div>
+        <a-row class="form-container">
+          <a-col :span="12" class="form-col">
+            <a-form-item ref="servicename" label="资源名称" name="servicename" class="label-form-item">
+              <a-input v-model:value="formState.servicename" />
+            </a-form-item>
+          </a-col>
+
+          <a-col :span="12" class="form-col">
+            <a-form-item ref="servicealiasname" label="资源别名" name="servicealiasname" class="label-form-item">
+              <a-input v-model:value="formState.servicealiasname" />
+            </a-form-item>
+          </a-col>
+
+          <a-col :span="24" class="form-col">
+            <a-form-item ref="description" label="资源描述" name="description" class="label-form-item">
+              <a-textarea v-model:value="formState.description" :rows="2" />
+            </a-form-item>
+          </a-col>
+          <a-col :span="12" class="form-col">
+            <a-form-item ref="servicetype" label="资源类型" name="servicetype" class="label-form-item">
+              <a-select v-model:value="formState.servicetype">
+                <template v-for="(tag, index) in assemblyType" :key="index">
+                  <a-select-option :value="tag.value">{{ tag.value }}</a-select-option>
+                </template>
+              </a-select>
+            </a-form-item>
+          </a-col>
+          <a-col :span="12" class="form-col">
+            <a-form-item ref="thumbnail" label="缩略图" name="thumbnail" class="label-form-item">
+              <a-upload :custom-request="customUpload" v-model:file-list="fileList">
+                <a-button style="background-color: #0671dd; color: #fff; border-radius: 4px">
+                  <upload-outlined></upload-outlined>
+                  文件上传
+                </a-button>
+              </a-upload>
+            </a-form-item>
+          </a-col>
+        </a-row>
+      </div>
+
+      <div class="compontents">
+        <div class="title">描述信息</div>
+        <a-row class="form-container">
+
+
+
+
+
+
+
+          <a-col :span="12" class="form-col">
+            <a-form-item ref="source" label="发布日期" name="source" class="label-form-item">
+              <!-- <a-input v-model:value="formState.publishtime" disabled /> -->
+              <a-date-picker v-model:value="formState.publishtime" format="YYYY-MM-DD hh:mm:ss" style="width: 100%"
+                disabled show-time>
+                <template #renderExtraFooter>extra footer</template>
+              </a-date-picker>
+            </a-form-item>
+          </a-col>
+          <a-col :span="12" class="form-col">
+            <a-form-item ref="source" label="发布者" name="source" class="label-form-item">
+              <a-input v-model:value="formState.publisher" disabled />
+            </a-form-item>
+          </a-col>
+
+          <a-col :span="12" class="form-col">
+            <a-form-item ref="updatetype" label="更新方式" name="updatetype" class="label-form-item">
+              <a-input v-model:value="formState.updateType" />
+            </a-form-item>
+          </a-col>
+          <a-col :span="12" class="form-col">
+            <a-form-item ref="updatetime" label="更新时间" name="updatetime" class="label-form-item">
+              <a-date-picker v-model:value="formState.updatetime" format="YYYY-MM-DD hh:mm:ss" style="width: 100%"
+                disabled show-time>
+                <template #renderExtraFooter>extra footer</template>
+              </a-date-picker>
+            </a-form-item>
+          </a-col>
+
+
+          <a-col :span="6" class="form-col">
+            <a-form-item ref="public" label="是否公开" name="public" class="label-form-item">
+              <a-switch checked-children="" un-checked-children="" v-model:checked="formState.public" />
+            </a-form-item>
+          </a-col>
+          <a-col :span="6" class="form-col">
+            <a-form-item ref="share" label="是否共享" name="share" class="label-form-item">
+              <a-switch checked-children="" un-checked-children="" v-model:checked="formState.share" />
+            </a-form-item>
+          </a-col>
+          <a-col :span="6" class="form-col">
+            <a-form-item ref="externalApply" label="是否外部申请" name="externalApply" class="label-form-item">
+              <a-switch checked-children="" un-checked-children="" v-model:checked="formState.externalApply" />
+            </a-form-item>
+          </a-col>
+          <a-col :span="6" class="form-col">
+            <a-form-item ref="searched" label="是否展示" name="searched" class="label-form-item">
+              <a-switch checked-children="" un-checked-children="" v-model:checked="formState.searched" />
+            </a-form-item>
+          </a-col>
+        </a-row>
+      </div>
+    </a-form>
+  </div>
+</template>
+<script lang="ts">
+import {
+  defineComponent,
+  ref,
+  toRefs,
+  toRaw,
+  unref,
+  computed,
+  unref,
+  nextTick,
+  reactive,
+  UnwrapRef,
+  onMounted,
+  watch,
+} from 'vue';
+import { BasicForm, useForm } from '/@/components/Form/index';
+import { UploadOutlined } from '@ant-design/icons-vue';
+import { ValidateErrorEntity } from 'ant-design-vue/es/form/interface';
+import { useMessage } from '/@/hooks/web/useMessage';
+const { t } = useI18n(); //加载国际化
+// 加载菜单数据
+import { useI18n } from '/@/hooks/web/useI18n';
+import Moment from 'moment';
+import { insertService, updateService, update } from '/@/api/dataAdmin/assembly';
+import { session } from '/@/utils/Memory.js';
+
+const props = {
+  formData: { type: Object, default: ref(null) },
+  isUpdate: { type: Boolean, default: ref(false) },
+};
+interface FormState {
+  servicetype: string,
+  servicename: string;
+  mapingurl: string,
+  servicealiasname: string;
+  description: string;
+  publishtime: string;
+  publisher: string;
+  updateType: string;
+  updatetime: string;
+  public: boolean;
+  share: boolean;
+  searched: boolean;
+  externalApply: boolean;
+  date1: undefined;
+}
+export default defineComponent({
+  name: 'SourceDetail',
+  components: { BasicForm, UploadOutlined },
+  props,
+  setup(props, { emit }) {
+    const data = reactive({
+      detail: props.formData,
+      isUpdate: props.isUpdate,
+      fileList: [],
+    });
+    var assemblyType = ref([
+      { value: '地图基础功能' },
+      { value: '覆盖物' },
+      { value: '测量工具' },
+      { value: '绘制工具' },
+      { value: '空间分析' },
+      { value: '天气特效' },
+    ])
+
+    const formRef = ref();
+    const formState: UnwrapRef<FormState> = reactive({
+      mapingurl: '',
+      servicename: '',
+      servicealiasname: '',
+      servicetype: '',
+      description: '',
+      publishtime: '',
+      publisher: '',
+      updateType: '',
+      updatetime: '',
+      public: true,
+      share: true,
+      searched: true,
+      externalApply: true,
+      date1: undefined,
+    });
+    const moment = Moment;
+    const rules = {
+      // mapingurl: [{ required: true, message: '请输入服务地址', trigger: 'blur' }],
+      servicetype: [{ required: true, message: '请选择资源类型', trigger: 'change' }],
+
+      servicename: [
+        { required: true, message: '请填写资源名称', trigger: 'blur' },
+        { min: 3, max: 20, message: '长度必须在3到20个字符', trigger: 'blur' },
+      ],
+      servicealiasname: [
+        { required: true, message: '请输入资源别名', trigger: 'blur' },
+        { min: 3, max: 20, message: '长度必须在3到20个字符', trigger: 'blur' },
+      ],
+      systag: [{ required: true, message: '请选择系统标签', trigger: 'change' }],
+      date1: [{ required: true, message: 'Please pick a date', trigger: 'change', type: 'object' }],
+      type: [
+        {
+          type: 'array',
+          required: true,
+          message: 'Please select at least one activity type',
+          trigger: 'change',
+        },
+      ],
+      resource: [{ required: true, message: 'Please select activity resource', trigger: 'change' }],
+      desc: [{ required: true, message: 'Please input activity form', trigger: 'blur' }],
+    };
+    const { createMessage } = useMessage();
+    watch(
+      () => props.formData,
+      (obj) => {
+        data.detail = obj;
+        if (data.isUpdate) setFormData();
+      }
+    );
+    watch(
+      () => props.isUpdate,
+      (obj) => {
+        data.isUpdate = obj;
+      }
+    );
+    const submitForm = () => {
+      try {
+        formRef.value
+          .validate()
+          .then(async () => {
+            const params = setSubmitForm();
+            console.log(params);
+            if (params) {
+              if (data.isUpdate) {
+                params.servicebase.serviceid = data.detail.serviceid;
+                params.servicebase.id = data.detail.id;
+                if (!params.servicebase.mapingurl) params.servicebase.mapingurl = data.detail.mapingurl;
+
+                params.metadata.serviceid = data.detail.serviceid;
+                params.metadata.id = data.detail.id;
+                if (!params.metadata.mapingurl) params.metadata.mapingurl = data.detail.mapingurl;
+
+
+                const res = await updateService(params);
+                if (res && res?.status !== '-1') {
+                  createMessage.success('修改地图资源成功!');
+                  resetForm();
+                  emit('RtnMain', true);
+                } else createMessage.error('修改地图资源失败!,失败原因:' + res?.message, 1);
+              } else {
+                const res = await insertService(params);
+                if (res && res?.status !== '-1') {
+                  createMessage.success('新增地图资源成功!');
+                  resetForm();
+                  emit('RtnMain', true);
+                } else createMessage.error('新增地图资源失败!,失败原因:' + res?.message, 1);
+              }
+            }
+          })
+          .catch((error: ValidateErrorEntity<FormState>) => {
+            createMessage.error('请完成必填信息!', 1);
+            console.log('error', error);
+          });
+      } catch (ex) {
+        console.log(ex);
+      }
+    };
+    const resetForm = () => {
+      formRef.value.resetFields();
+    };
+
+    /**
+     * 设置提交数据
+     */
+    const setSubmitForm = () => {
+      const userinfo = session.getItem('userInfo');
+      return {
+        type: 'SR',
+        servicebase: {
+          publisher: userinfo?.EMPLOYEE?.NAME, //'系统管理员',
+          username: userinfo?.EMPLOYEE?.NAME, //'系统管理员',
+          userid: userinfo?.EMPLOYEE?.EMPLOYEE_ID, //'27AF004A-8BDN-885T-30FU-89DE3388762B',
+          servicealiasname: formState.servicealiasname, //资源别名
+          description: formState.description, //资源描述
+          ispublic: formState.public ? '1' : '0', //是否公开
+          searched: formState.searched ? '1' : '0', //是否展示
+          externalApply: formState.externalApply ? '1' : '0', //外部申请
+          servicename: formState.servicename, //资源名
+          otherService: '',
+          source: formState.servicetype, //资源类型
+          mapingurl: formState.mapingurl //服务地址
+        },
+        metadata: {
+          source: formState.servicetype, //资源类型
+          mapingurl: formState.mapingurl, //服务地址
+          name: formState.servicename, //资源名
+          servicealiasname: formState.servicealiasname, //资源别名
+          thumbnail: '',
+          description: formState.description,
+          updateType: formState.updateType, //更新方式
+          workSpace: '',
+          ishistory: '0',
+          shsqlc: 'ggdata',
+          urlInfo: '',
+          otherService: '',
+          bz: '',
+          ispublic: formState.public ? '1' : '0', //是否公开
+          searched: formState.searched ? '1' : '0', //是否展示
+          externalApply: formState.externalApply ? '1' : '0', //外部申请
+          isShow: formState.share ? '1' : '0',
+          publisher: userinfo?.EMPLOYEE?.NAME, //'系统管理员',
+          username: userinfo?.EMPLOYEE?.NAME, //'系统管理员',
+          userid: userinfo?.EMPLOYEE?.EMPLOYEE_ID, //'27AF004A-8BDN-885T-30FU-89DE3388762B',
+        }
+      };
+    };
+    /**
+     * 设置表单数据
+     */
+    const setFormData = () => {
+      formState.public = data.detail.ispublic === '1' ? true : false;
+      formState.servicename = data.detail?.servicename;
+      formState.publishtime = data.detail?.publishdate
+        ? moment(data.detail?.publishdate).format('YYYY-MM-DD HH:mm:ss')
+        : '';
+      formState.publisher = data.detail?.publisher;
+      formState.servicealiasname = data.detail?.servicealiasname;
+      formState.updatetime = data.detail?.updatedate
+        ? moment(data.detail?.updatedate).format('YYYY-MM-DD HH:mm:ss')
+        : '';
+      formState.searched = data.detail.searched === 0 ? false : true;
+    };
+
+    onMounted(() => {
+      resetForm();
+    });
+
+    function customUpload({ file, onSuccess, onError }) {
+      const formData = new FormData();
+      formData.append('file', file);
+      update(formData, session.getItem('sysFild').dirId).then(r => {
+        if (r && r.resp_code == 0 && r.resp_msg == "OK") {
+          formState.mapingurl = `${r.datas.id},${r.datas.dirId}`;
+          onSuccess()
+        } else {
+          onError()
+        }
+      })
+    }
+    return {
+      assemblyType,
+      customUpload,
+      ...toRefs(data),
+      formRef,
+      moment,
+      rules,
+      formState,
+      submitForm,
+      resetForm,
+      createMessage,
+      setSubmitForm,
+      setFormData,
+    };
+  },
+});
+</script>
+  
+<style scoped lang="less">
+.source-detail {
+  height: 100%;
+  width: 100%;
+  padding: 0 20px;
+
+  .compontents {
+    width: 100%;
+    height: auto;
+
+    .title {
+      height: 19px;
+      line-height: 18px;
+      padding-left: 6px;
+      margin-bottom: 20px;
+      border-left: 3px solid #0671dd;
+      font-family: Source Han Sans CN;
+      font-size: 16px;
+      font-weight: 350;
+      letter-spacing: 0px;
+    }
+
+    .form-container {
+      width: 100%;
+      height: auto;
+
+      .form-col {
+        height: 100%;
+      }
+
+      .form-col-left {
+        padding-right: 20px;
+      }
+    }
+  }
+}
+
+.label-form-item {
+  :deep(.ant-form-item-label) {
+    width: 90px;
+  }
+
+  :deep(.ant-form-item-control) {
+    width: calc(100% - 90px);
+  }
+}
+</style>
+  

+ 218 - 0
src/views/interface/library/index.vue

@@ -0,0 +1,218 @@
+<template>
+  <div>
+    <BasicTable :rowSelection="{ type: 'checkbox' }" @register="registerTable" :clickToRowSelect="false">
+      <template #toolbar>
+        <Authority>
+          <a-button type="primary" @click="handleCreate">提交申请</a-button>
+        </Authority>
+        <Authority>
+          <Popconfirm title="您确定要批量删除数据" ok-text="确定" cancel-text="取消" @confirm="handleDeleteOrBatchDelete(null)">
+            <a-button type="primary" color="error" :disabled="hasBatchDelete"> 批量删除 </a-button>
+          </Popconfirm>
+        </Authority>
+      </template>
+      <!-- <template #status="{ record }">
+        <Switch :checked="record.status === 1" :loading="record.pendingStatus" checkedChildren="启用" unCheckedChildren="禁用"
+          @change="(checked: boolean) => statusChange(checked, record)" />
+      </template> -->
+      <template #action="{ record }">
+        <TableAction :actions="[
+          {
+            label: '浏览',
+            icon: '' /**clarity:note-edit-line*/,
+            // ifShow: record.servicealiasname,
+            // ifShow: ((action) => action.servicealiasname),
+            ifShow: record.servicealiasname,
+            onClick: see.bind(null, record),
+          },
+          {
+            label: '查看',
+            icon: '' /**clarity:note-edit-line*/,
+            onClick: handleEdit.bind(null, record),
+          },
+          {
+            label: '编辑',
+            icon: '' /**clarity:note-edit-line*/,
+            color: 'warning',
+            onClick: handleEdit.bind(null, record),
+          },
+          {
+            label: '删除',
+            icon: '' /**ant-design:delete-outlined'*/,
+            color: 'error',
+            ifShow: record.roleType != RoleEnum.SYS_ADMIN,
+            popConfirm: {
+              title: '是否确认删除',
+              confirm: handleDelete.bind(null, record),
+            },
+          },
+        ]" />
+      </template>
+      <template #pdate="{ record }">
+        <Tag :color="'red'">
+          {{
+            record.publishdate ? moment(record.publishdate).format('YYYY-MM-DD HH:mm:ss') : ''
+          }}
+        </Tag>
+      </template>
+      <template #status="{ record }">
+        <Tag :style="`color:${record.status === 3 || record.status === 3 ? 'red' : ''};`">
+          {{
+            record.status === 0 ? '待审核' : (record.status === 1 ? '审核通过' : (record.status === 2 ? '审核不通过' : (record.status
+              === 3 ? '被驳回' : '未提交')))
+          }}
+        </Tag>
+      </template>
+    </BasicTable>
+    <!-- <MapDrawer @register="registerDrawer" @success="handleSuccess" /> -->
+    <MapSourceModal @register="registerModal" @success="handleSuccess" />
+  </div>
+</template>
+<script lang="ts">
+import { defineComponent, nextTick, onBeforeMount } from 'vue';
+import { BasicTable, useTable, TableAction } from '/@/components/Table';
+import { delRole, getRoleListByPage, setRoleStatus } from '/@/api/system/system';
+// import { useDrawer } from '/@/components/Drawer';
+import { useModal } from '/@/components/Modal';
+import MapDrawer from './MapDrawer.vue';
+import MapSourceModal from './MapSourceModal.vue';
+import { columns, searchFormSchema } from './map.data';
+import { RoleEnum } from '/@/enums/roleEnum';
+import { Authority } from '/@/components/Authority';
+import { useBatchDelete } from '/@/hooks/web/useBatchDelete';
+import { useMessage } from '/@/hooks/web/useMessage';
+import { Switch, Popconfirm } from 'ant-design-vue';
+import { list, deleteService } from '/@/api/dataAdmin/assembly';
+import Moment from 'moment'
+
+export default defineComponent({
+  name: 'RoleManagement',
+  components: { BasicTable, MapDrawer, MapSourceModal, TableAction, Authority, Switch, Popconfirm },
+  setup() {
+    //const [registerDrawer, { openDrawer }] = useDrawer();
+    const [registerModal, { openModal }] = useModal();
+    const [registerTable, { setProps, reload, setSelectedRowKeys }] = useTable({
+      title: '地图资源列表',
+      api: list,
+      columns,
+      formConfig: {
+        labelWidth: 100,
+        schemas: searchFormSchema,
+      },
+      useSearchForm: true,
+      showTableSetting: true,
+      bordered: true,
+      showIndexColumn: true,
+      actionColumn: {
+        width: 200,
+        title: '操作',
+        dataIndex: 'action',
+        slots: { customRender: 'action' },
+        fixed: 'right',
+      },
+    });
+    const moment = Moment
+    const { createMessage } = useMessage();
+    const { hasBatchDelete, handleDeleteOrBatchDelete, selectionOptions, resetSelectedRowKeys } =
+      useBatchDelete(delRole, handleSuccess, setProps);
+    selectionOptions.rowSelection.getCheckboxProps = (record: Recordable) => {
+      // Demo:status为1的选择框禁用
+      if (record.status === 1) {
+        return { disabled: true };
+      } else {
+        return { disabled: false };
+      }
+    };
+    nextTick(() => {
+      setProps(selectionOptions);
+    });
+
+    function handleCreate() {
+      // openDrawer(true, {
+      //   isUpdate: false,
+      // });
+      openModal(true, {
+        isUpdate: false,
+      });
+    }
+
+    function handleEdit(record: Recordable) {
+      // openDrawer(true, {
+      //   record,
+      //   isUpdate: true,
+      // });
+      openModal(true, {
+        record,
+        isUpdate: true,
+      });
+    }
+
+    function see(e) {
+      console.log(e);
+      if (e.servicealiasname) window.open(`../../mapview.html?onlineIde_${e.servicealiasname}`, '_blank');
+    }
+
+    const handleDelete = async (record: Recordable) => {
+      if (record?.serviceid) {
+        const res = await deleteService(record?.serviceid)
+        if (res?.status !== '-1') {
+          reload();
+          createMessage.success('删除成功!', 1)
+        }
+        else {
+          createMessage.error('删除失败!失败原因:' + res?.message, 1)
+        }
+      }
+    }
+
+    function handleSuccess() {
+      openModal(false, {
+        isUpdate: false,
+      });
+      reload();
+    }
+
+    const statusChange = async (checked, record) => {
+      setProps({
+        loading: true,
+      });
+      setSelectedRowKeys([]);
+      resetSelectedRowKeys();
+      const newStatus = checked ? 1 : 0;
+      try {
+        await setRoleStatus(record.id, newStatus);
+        if (newStatus) {
+          createMessage.success(`启用成功`);
+        } else {
+          createMessage.success('禁用成功');
+        }
+      } finally {
+        setProps({
+          loading: false,
+        });
+        reload();
+      }
+    };
+    onBeforeMount(async () => {
+
+    })
+
+    return {
+      moment,
+      createMessage,
+      registerTable,
+      // registerDrawer,
+      registerModal,
+      handleCreate,
+      see,
+      handleEdit,
+      handleDelete,
+      handleSuccess,
+      RoleEnum,
+      hasBatchDelete,
+      handleDeleteOrBatchDelete,
+      statusChange,
+    };
+  },
+});
+</script>

+ 180 - 0
src/views/interface/library/map.data.ts

@@ -0,0 +1,180 @@
+import { BasicColumn } from '/@/components/Table';
+import { FormSchema } from '/@/components/Table';
+import { RoleEnum } from '/@/enums/roleEnum';
+import { getServiceTypes,queryServiceTags,queryDicsByName,queryCoors } from '/@/api/resource/map';
+
+const resTag = await queryServiceTags()
+let listTag = []
+resTag.map(item => {
+  listTag.push({
+    label: item.name,
+    value: item.code
+  })
+})
+/**
+ * 密级字典
+*/
+export const secrets = await queryDicsByName('密级')
+/**
+ * 服务标签
+*/
+export const serviceTags = listTag;
+/**
+ * 坐标系列表
+*/
+export const sysCoors = await queryCoors()
+/**
+ * 服务类型
+*/
+export const serviceTypes = await getServiceTypes()
+/**
+ * 责任处室
+*/
+export const respDept = await queryDicsByName('责任处室')
+/**
+ * 保管单位
+*/
+export const collectDept = await queryDicsByName('保管单位')
+/**
+ * EPSG code
+*/
+export const EPSGCodes = await queryDicsByName('EPSG code')
+
+
+const checkStatus = [
+  { label: '未提交', value: 1 },
+  { label: '审核中', value: 2 },
+  { label: '审核不通过', value: 3 },
+  { label: '被驳回', value: 4 },
+  { label: '审核通过', value: 5 },
+]
+export enum KeysTypeEnum {
+  DISABLED = 'disabled',
+  ENABLED = 'enabled',
+}
+
+export const RoleMenuDictEnum: Recordable<{ key: string; keyType: KeysTypeEnum }> = {
+  [RoleEnum.PLATFORM_ADMIN]: { key: 'enabled_platform_admin_auth', keyType: KeysTypeEnum.ENABLED },
+  [RoleEnum.SYS_ADMIN]: { key: 'enabled_sysadmin_auth', keyType: KeysTypeEnum.ENABLED },
+  [RoleEnum.TENANT_ADMIN]: { key: 'disabled_tenant_auth', keyType: KeysTypeEnum.DISABLED },
+  [RoleEnum.CUSTOMER_USER]: { key: 'disabled_tenant_auth', keyType: KeysTypeEnum.DISABLED },
+};
+
+/**
+ * 查询条件
+*/
+export const searchFormSchema: FormSchema[] = [
+  {
+    field: 'resTag',
+    label: '资源标签',
+    component: 'Select',
+    componentProps: {
+      options: serviceTags,
+      // [
+      //   { label: '标签1', value: 1 },
+      //   { label: '标签2', value: 2 },
+      //   { label: '标签3', value: 3 },
+      // ],
+    },
+    colProps: { span: 5 },
+  },
+  {
+    field: 'resName',
+    label: '资源名称',
+    component: 'Input',
+    colProps: { span: 5 },
+    componentProps: {
+      maxLength: 255,
+    },
+  },
+  {
+    field: 'checkStatus',
+    label: '审核状态',
+    component: 'Select',
+    componentProps: {
+      options: checkStatus,
+    },
+    colProps: { span: 5 },
+  },
+];
+
+/**
+ * 列表显示信息
+*/
+export const columns: BasicColumn[] = [
+  {
+    title: '资源标签',
+    dataIndex: 'typename',
+    width: 120,
+  },
+  {
+    title: '资源名称',
+    dataIndex: 'servicename',
+    width: 160,
+  },
+  {
+    title: '应用系统',
+    dataIndex: 'servicename',
+    width: 160,
+  },
+  {
+    title: '申请单位',
+    dataIndex: 'servicename',
+    width: 160,
+  },
+  // {
+  //   title: '发布人',
+  //   dataIndex: 'publisher',
+  //   width: 120,
+  // },
+  // {
+  //   title: '发布时间',
+  //   dataIndex: 'publishdate',
+  //   width: 180,
+  //   slots: { customRender: 'pdate' },
+  // },
+  {
+    title: '申请时间',
+    dataIndex: 'checkTime',
+    width: 100,
+  },
+  {
+    title: '申请人',
+    dataIndex: 'curHandler',
+    width: 100,
+  },
+  {
+    title: '审核状态',
+    dataIndex: 'status',
+    width: 110,
+    slots: { customRender: 'status' },
+  },
+
+];
+
+
+
+/**
+ * 表单
+*/
+export const formSchema: FormSchema[] = [
+  {
+    field: 'groupName',
+    label: '角色名称',
+    required: true,
+    component: 'Input',
+    componentProps: {
+      maxLength: 255,
+      placeholder: '请输入角色名称',
+    },
+  },
+  {
+    label: '排序',
+    field: 'sort',
+    component: 'Input',
+    componentProps: {
+      maxLength: 255,
+      placeholder: '请输入排序',
+    },
+  }
+];