Explorar el Código

添加了组件服务的菜单

sujunling hace 2 años
padre
commit
9368250057

+ 22 - 0
src/mock/menu.json

@@ -20,6 +20,28 @@
             "status": "0"
         }
     },
+    {
+        "id": "1dba6f56-4186-4df3-a845-349ec848719d",
+        "createTime": "2023-08-01 14:40:42",
+        "name": "组件服务",
+        "parentId": "aa827552-1277-4393-a9bf-1f57340d7d1b",
+        "children": [],
+        "path": "/assembly/server",
+        "type": "SYSADMIN",
+        "permission": "assembly:server",
+        "sort": 30,
+        "component": "/assembly/index",
+        "meta": {
+            "icon": "mdi:feature-search",
+            "title": "组件服务",
+            "isLink": false,
+            "menuType": "0",
+            "hideMenu": false,
+            "status": "0"
+        },
+        "menuSys": "2",
+        "menuOut": "1"
+    },
     {
         "id": "27ec1926-8369-4cca-bf8e-dbd25d70c6bb",
         "createTime": "2023-08-01 11:46:25",

+ 1 - 0
src/mock/menu_get_ids.json

@@ -9,6 +9,7 @@
     "83326dff-9f55-4930-abea-09e61306c2d5",
     "502c9897-4abe-44ad-92cf-a74d402f7fe3",
     "4ce99298-d100-4479-ac61-3f6762ade2c4",
+    "1dba6f56-4186-4df3-a845-349ec848719d",
     "60d370b3-edf7-4e1d-bfef-4538cc04f1b2",
     "50843259-c2de-442a-9da2-9a17f161a970",
     "d748df94-bf81-4a9a-8918-56a07e6ce61e",

+ 1 - 0
src/mock/role_me_permissions.json

@@ -4,6 +4,7 @@
     "api:yt:opinion:delete",
     "api:yt:platform:update:update",
     "api:yt:dictItem:delete",
+    "assembly:server",
     "resource:centre",
     "systemAdmin:system:menu",
     "api:dataresource:mapupload:maploadDelete",

+ 17 - 0
src/views/assembly/data.ts

@@ -0,0 +1,17 @@
+export interface TabItem {
+  key: string;
+  name: string;
+  component: string;
+}
+export const achieveList: TabItem[] = [
+  {
+    key: '1',
+    name: '地图资源(1)',
+    component: 'SmsLog',
+  },
+  {
+    key: '2',
+    name: '成果数据(2)',
+    component: 'EmailLog',
+  },
+];

+ 120 - 0
src/views/assembly/index.vue

@@ -0,0 +1,120 @@
+<template>
+  <div :class="[`${prefixCls}-bottom`, '!dark:bg-dark-900']">
+    <div class="datacenter-left">
+      <div class="page-name">
+        <p>组件目录</p>
+      </div>
+      <div class="ztree-container">
+        <p v-for="(i, k) in menu" :key="k">{{ i.name }}({{ i.num }})</p>
+      </div>
+    </div>
+    <div class="datacenter-right">
+      <AssemblyData></AssemblyData>
+    </div>
+  </div>
+</template>
+
+<script lang="ts">
+import { defineComponent, ref, watch } from 'vue';
+import AssemblyData from './item/AssemblyData.vue';
+import { onMounted } from 'vue';
+import { directoryTree, platList } from '/@/api/resource/plat';
+
+const prefixCls = 'account-center-bottom'
+
+export default defineComponent({
+  components: {
+    AssemblyData,
+  },
+  setup() {
+
+    var menu = [
+      { name: '地图基础功能', num: 10 },
+      { name: '地图覆盖物类', num: 7 },
+      { name: '基础测量工具', num: 8 },
+      { name: '空间分析', num: 9 },
+      { name: '天气效果', num: 6 }
+    ]
+
+    return {
+      menu,
+      prefixCls: 'account-center',
+
+    };
+  },
+});
+</script>
+<style lang="less" scoped>
+.account-center-bottom {
+  background: #fff;
+  height: calc(100vh - 110px);
+  overflow: hidden;
+}
+
+.datacenter-right {
+  float: left;
+  width: calc(100vw - 530px);
+}
+
+.ztree-container {
+  float: left;
+  overflow: auto;
+  width: 100%;
+  height: auto;
+  max-height: 976px;
+}
+
+.ztree-container p {
+  padding-left: 30px;
+  line-height: 40px;
+  margin-left: 9px;
+  width: 233px;
+  height: 40px;
+  text-align: left;
+  height: 40px;
+  background: #FFFFFF;
+  cursor: pointer;
+}
+
+.ztree-container p:hover {
+  background: #0671DD;
+  color: #fff;
+}
+
+.datacenter-left .page-name {
+  margin-bottom: 30px;
+  border-bottom: solid 1px #DEDEDE;
+}
+
+.datacenter-left .page-name p {
+  height: 42px;
+  line-height: 42px;
+  font-size: 16px;
+  font-family: PingFang SC;
+  font-weight: bold;
+  color: #333333;
+  text-align: center;
+  margin-bottom: 0px;
+}
+
+.datacenter-left {
+  float: left;
+  width: 250px;
+  height: auto;
+  margin-right: 16px;
+  border-top: none;
+  background: #F8F8F8;
+  overflow: auto;
+  height: calc(100% - 20px);
+  max-height: 1306px;
+}
+
+.account-center {
+  &-bottom {
+    padding: 10px;
+    margin: 16px;
+    // background-color: @component-background;
+    border-radius: 3px;
+  }
+}
+</style>

+ 308 - 0
src/views/assembly/item/AssemblyData.vue

@@ -0,0 +1,308 @@
+<template>
+  <Search></Search>
+  <div style="background-color: #f0f2f5" class="dark:bg-dark-900">
+    <div class="datacenter-right">
+      <div class="resource_list" id="map_list">
+        <div v-for="(i, n) in list" v-if="list.length" :key="n" data-permission="true" class="resource_item"
+          data-checking="false" data-searching="1" data-ispub="1">
+          <div class="mapItem-top-box">
+            <div class="item-top">
+              <div class="img_container" data-num="1">
+                <img class="tab-list-icon-img-MR00001936 img_mr MR00001936"
+                  :src="i.info && i.info.length && i.info[0].thumbnail" alt="">
+              </div>
+            </div>
+            <div class="item-title">
+              <span class="r_name">{{ i.SERVICENAME }}</span>
+              <span class="r-number" data-num="1" title="编目1次">1</span>
+            </div>
+            <div class="item-msg">
+              <div class="item-msg-val" style="font-weight:bold;font-size:12px;color: #000;">坐标系:{{ i.CRS }}</div>
+              <div class="item-msg-val">适用流程:国家秘密和工作秘密数据成果申请,</div>
+              <div class="item-msg-val">关键字:测试数据</div>
+              <div class="item-msg-val">服务类型:{{ i.TYPENAME }}</div>
+            </div>
+          </div>
+          <div class="operation-box">
+            <div class="operation-item browse-item-btn browse-item-MR00001936">
+              <a target="_blank" :href="`../../mapview.html?/iserver/services/map-16/rest/maps/LZS16envi1%4016.ijs`">
+                <span>浏览</span>
+              </a>
+            </div>
+
+            <div class="operation-item alone-apply-btn alone-apply-btn-MR00001936">
+              <span style="border-right: 1px #ccc solid;" onclick="cardApplyItem('mr')">
+                <span>申请</span>
+              </span>
+            </div>
+            <div class="operation-item" @click="handleQuery(i)">
+              <a href="javascript:void(0)" class="">
+                <span>详细</span>
+              </a>
+            </div>
+            <div class="operation-item" @click="applyWay(i)">
+              <a href="javascript:void(0)" class="">
+                <span>加入申请库</span>
+              </a>
+            </div>
+            <div class="operation-item operation-item-active" @click="handleQuery(i)">
+              <a href="javascript:void(0)" class="">
+                <span>已加入申请库</span>
+              </a>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <!-- <BasicTable @register="registerTable" class="dark:bg-dark-900">
+      <template #toolbar>
+        <Authority value="api:yt:smsLog:delete">
+          <Popconfirm title="您确定要批量删除数据" ok-text="确定" cancel-text="取消" @confirm="handleDeleteOrBatchDelete(null)">
+            <a-button type="primary" color="error" :disabled="hasBatchDelete"> 批量删除 </a-button>
+          </Popconfirm>
+        </Authority>
+      </template>
+      <template #remark="{ record }">
+        <Tooltip :title="record.remark">
+          <div class="truncate w-full">{{ record.remark }}</div>
+        </Tooltip>
+      </template>
+      <template #action="{ record }">
+        <TableAction :actions="[
+          {
+            label: '查看',
+            auth: 'api:yt:smsLog:get',
+            icon: 'ant-design:fund-view-outlined',
+            onClick: handleQuery.bind(null, record),
+          },
+          {
+            label: '删除',
+            auth: 'api:yt:smsLog:delete',
+            icon: 'ant-design:delete-outlined',
+            color: 'error',
+            popConfirm: {
+              title: '是否确认删除',
+              confirm: handleDeleteOrBatchDelete.bind(null, record),
+            },
+          },
+        ]" />
+      </template>
+    </BasicTable> -->
+    <!-- 弹出框 -->
+    <AssemblyDrawer @register="registerModal" />
+  </div>
+</template>
+<script lang="ts">
+import { defineComponent, nextTick, onMounted, ref, defineProps, watch } from 'vue';
+import { BasicTable, useTable, TableAction } from '/@/components/Table';
+import { columns, searchFormSchema } from './sms.data';
+import { Popconfirm, Tooltip } from 'ant-design-vue';
+import { Authority } from '/@/components/Authority';
+import { platList, img, apply } from '/@/api/resource/plat';
+import { message } from 'ant-design-vue';
+// 加载自定义侧边弹出框 组件
+import { useDrawer } from '/@/components/Drawer';
+// 导入子页面【新增、修改】
+import AssemblyDrawer from './AssemblyDrawer.vue';
+import Search from './child/Search.vue';
+import { session } from '/@/utils/Memory';
+
+
+export default defineComponent({
+  name: 'SmsLog',
+  components: { BasicTable, TableAction, Authority, Search, Popconfirm, Tooltip, AssemblyDrawer },
+  setup() {
+    const [registerModal, { openDrawer }] = useDrawer(); //使用右侧弹出框
+    const list = ref([]);
+    const props = defineProps({
+      listData: {
+        type: Array,
+        default: () => [],
+      }
+    })
+
+    // setInterval(() => {
+    //   console.log(props)
+    // }, 2000)
+    onMounted(() => {
+      platList().then((r) => {
+        if (r) {
+          list.value = r[0].items;
+          list.value.map(async (i) => i.info = await img(i.SERVICEID))
+        }
+      });
+    });
+
+    function handleQuery(record: Recordable) {
+      console.log("11111:", record)
+      openDrawer(true, {
+        record,
+      });
+    }
+
+    function applyWay(i) {
+      console.log(i)
+      apply({
+        addRes: [{
+          resDataType: "1",
+          resId: i.SERVICEID,
+          resName: `${i.SERVICENAME}(${i.CRS})`,
+          resType: 0,
+          workflowType: "MAP",
+        }],
+        userId: session.getItem('userId'),
+      }).then((r) => {
+        if (r.datas && r.resp_code == 0) {
+          message.success('申请成功');
+        }
+      })
+    }
+
+    return {
+      applyWay,
+      registerModal,
+      list,
+      handleQuery,
+    };
+  },
+});
+</script>
+
+<style scoped>
+.datacenter-right .resource_list .item-title .r_name {
+  color: #5e5d5e;
+  display: inline-block;
+  width: 190px;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+
+.datacenter-right .resource_list {
+  box-sizing: border-box;
+  width: 100%;
+  float: left;
+  clear: both;
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+}
+
+.datacenter-right .resource_list>div:not(:nth-of-type(4n + 4)) {
+  margin-right: 7px;
+}
+
+.resource_item {
+  height: 318px;
+  width: 224px;
+  margin-bottom: 14px;
+  border: 2px dashed transparent;
+
+  width: 386px;
+  height: 402px;
+  border-radius: 4px;
+  opacity: 1;
+  background: #FFFFFF;
+  border: 1px solid #DEDEDE;
+}
+
+.mapItem-top-box {
+  height: 350px;
+}
+
+.datacenter-right .resource_list .operation-box {
+  height: 42px;
+  display: flex;
+  margin-bottom: 10px;
+  margin-left: 20px;
+}
+
+.datacenter-right .resource_list .item-top {
+  padding: 13px;
+}
+
+.datacenter-right .resource_list .item-top img {
+  width: 360px;
+  height: 190px;
+  border: solid 1px #eeebeb;
+}
+
+.datacenter-right .resource_list .item-title {
+  font-size: 14px;
+  font-family: PingFang SC;
+  font-weight: bold;
+  color: #5e5d5e;
+  line-height: 16px;
+  padding: 0 0 0 14px;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+
+.datacenter-right .resource_list .item-msg {
+  padding: 0 13px 13px;
+}
+
+.img_container {
+  text-align: center;
+}
+
+.img_container {
+  width: 100%;
+  height: 100%;
+  background: #b7bed3;
+  border-radius: 4px;
+}
+
+.datacenter-right .resource_list .item-msg-val {
+  font-size: 12px;
+  font-family: PingFang SC;
+  font-weight: bold;
+  color: #5e5d5e;
+  line-height: 22px;
+  opacity: 0.5;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+
+.datacenter-right .resource_list .operation-item {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  min-width: 50px;
+  height: 34px;
+  opacity: 1;
+  margin-right: 22px;
+  padding: 0 10px;
+  background: #E8E8E8;
+}
+
+.datacenter-right .resource_list .operation-item:hover {
+  background: #0671DD;
+}
+
+.datacenter-right .resource_list .operation-item:hover a {
+  color: #fff;
+}
+
+.datacenter-right .resource_list .operation-item.alone-apply-btn {
+  display: none;
+}
+
+.operation-item-active {
+  background: #05B069 !important;
+}
+
+.operation-item-active a {
+  color: #fff !important;
+}
+
+.datacenter-right .resource_list .operation-item a {
+  font-size: 12px;
+  width: 100%;
+  text-align: center;
+  color: #5e5d5e;
+}
+</style>

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 789 - 0
src/views/assembly/item/AssemblyDrawer.vue


+ 221 - 0
src/views/assembly/item/assembly.data.ts

@@ -0,0 +1,221 @@
+import { BasicColumn } from '/@/components/Table';
+import { FormSchema } from '/@/components/Table';
+import { h } from 'vue';
+import { Tag } from 'ant-design-vue';
+import { Icon } from '/@/components/Icon';
+import { useI18n } from '/@/hooks/web/useI18n';
+const { t } = useI18n();
+
+//菜单管理页,所需的列 配置
+export const columns: BasicColumn[] = [
+  {
+    title: t('routes.common.system.tableTitleSystemMenuName'), //菜单名称
+    // title:'菜单名称',
+    dataIndex: 'meta.title',
+    width: 180,
+    align: 'left',
+    customRender: ({ record }) => {
+      record = t(record.title); //国际化处理
+      return record;
+    },
+  },
+  {
+    title: t('routes.common.system.tableTitleSystemPermissionTag'), //权限标识
+    // title:'权限标识',
+    dataIndex: 'permission',
+    width: 220,
+  },
+  {
+    title: t('routes.common.system.tableTitleSystemComponents'), //'组件'
+    // title:'组件',
+    width: 120,
+    // dataIndex: 'component',
+    dataIndex: 'url',
+  },
+  {
+    title: t('routes.common.system.tableTitleSystemSort'), //'排序'
+    // title:'排序',
+    dataIndex: 'sort',
+    width: 50,
+  },
+
+];
+
+const isDir = (type: string) => type === '0';
+const isMenu = (type: string) => type === '1';
+const isButton = (type: string) => type === '2';
+
+//----------------------------------新增、编辑----------------------------------------------------------
+export const formSchema: FormSchema[] = [
+  {
+    field: 'menuType',
+    label: t('routes.common.system.menuEditPagesMenuType'), //菜单类型
+    component: 'RadioButtonGroup',
+    defaultValue: '0',
+    componentProps: {
+      options: [
+        { label: t('routes.common.system.menuEditPagesDirectory'), value: '0' }, //目录
+        { label: t('routes.common.system.menuEditPagesMenu'), value: '1' }, //菜单
+        { label: t('routes.common.system.menuEditPagesButton'), value: '2' }, //按钮
+      ],
+    },
+    colProps: { lg: 24, md: 24 },
+  },
+  {
+    field: 'title',
+    label: t('routes.common.system.tableTitleSystemMenuName'), //菜单名称
+    component: 'Input',
+    required: true,
+    componentProps: {
+      maxLength: 255,
+    },
+  },
+
+  {
+    field: 'parentId',
+    label: t('routes.common.system.menuEditPagesParentMenu'), //上级菜单
+    component: 'TreeSelect',
+    componentProps: {
+      replaceFields: {
+        title: 'menuName',
+        key: 'id',
+        value: 'id',
+      },
+      getPopupContainer: () => document.body,
+    },
+  },
+
+  {
+    field: 'sort',
+    label: t('routes.common.system.tableTitleSystemSort'), //排序
+    component: 'InputNumber',
+    required: true,
+    componentProps: {
+      maxLength: 32,
+    },
+  },
+  {
+    field: 'icon',
+    label: t('routes.common.system.tableTitleSystemIcon'), //图标
+    component: 'IconPicker',
+    required: true,
+    ifShow: ({ values }) => !isButton(Reflect.get(values, 'menuType')),
+  },
+
+  {
+    field: 'path',
+    label: t('routes.common.system.menuEditPagesRouterAddress'), //路由地址
+    component: 'Input',
+    required: true,
+    ifShow: ({ values }) => !isButton(Reflect.get(values, 'menuType')),
+    componentProps: {
+      maxLength: 255,
+    },
+  },
+  {
+    field: 'permission',
+    label: '权限标识', //路由地址
+    component: 'Input',
+    // required: true,//是否必须
+    componentProps: {
+      maxLength: 255,
+    },
+  },
+  {
+    field: 'component',
+    label: t('routes.common.system.menuEditPagesComponentsPath'), //组件路径
+    component: 'Input',
+    ifShow: ({ values }) => isMenu(Reflect.get(values, 'menuType')),
+    componentProps: {
+      maxLength: 100,
+    },
+    dynamicRules: () => {
+      return [
+        {
+          required: false,
+          validator: (_, value) => {
+            if (String(value).length > 100) {
+              return Promise.reject('字数不超过100个字');
+            }
+            return Promise.resolve();
+          },
+        },
+      ];
+    },
+  },
+  {
+    field: 'permission',
+    label: t('routes.common.system.tableTitleSystemPermissionTag'), //权限标识
+    component: 'Input',
+    ifShow: ({ values }) => !isDir(Reflect.get(values, 'menuType')),
+    componentProps: {
+      maxLength: 100,
+    },
+    dynamicRules: () => {
+      return [
+        {
+          required: false,
+          validator: (_, value) => {
+            if (String(value).length > 100) {
+              return Promise.reject('字数不超过100个字');
+            }
+            return Promise.resolve();
+          },
+        },
+      ];
+    },
+  },
+  {
+    field: 'status',
+    label: t('routes.common.system.tableTitleSystemStatus'), //状态
+    component: 'RadioButtonGroup',
+    defaultValue: '0',
+    componentProps: {
+      options: [
+        { label: t('routes.common.system.tableTitleSystemEnable'), value: '0' }, //启用
+        { label: t('routes.common.system.tableTitleSystemStop'), value: '1' }, //禁用
+      ],
+    },
+  },
+  {
+    field: 'isLink',
+    label: t('routes.common.system.menuEditPagesIsExt'), //是否外链
+    component: 'RadioButtonGroup',
+    defaultValue: false,
+    componentProps: {
+      options: [
+        { label: t('routes.common.system.menuEditPagesYes'), value: true }, //是
+        { label: t('routes.common.system.menuEditPagesNo'), value: false }, //否
+      ],
+    },
+    ifShow: ({ values }) => !isButton(Reflect.get(values, 'menuType')),
+  },
+
+  {
+    field: 'ignoreKeepAlive',
+    label: t('routes.common.system.menuEditPagesIsKeepAlive'), //是否缓存
+    component: 'RadioButtonGroup',
+    defaultValue: false,
+    componentProps: {
+      options: [
+        { label: t('routes.common.system.menuEditPagesYes'), value: true }, //是
+        { label: t('routes.common.system.menuEditPagesNo'), value: false }, //否
+      ],
+    },
+    ifShow: ({ values }) => isMenu(Reflect.get(values, 'menuType')),
+  },
+
+  {
+    field: 'hideMenu',
+    label: t('routes.common.system.menuEditPagesIsHide'), //是否隐藏
+    component: 'RadioButtonGroup',
+    defaultValue: false,
+    componentProps: {
+      options: [
+        { label: t('routes.common.system.menuEditPagesYes'), value: true }, //是
+        { label: t('routes.common.system.menuEditPagesNo'), value: false }, //否
+      ],
+    },
+    ifShow: ({ values }) => !isButton(Reflect.get(values, 'menuType')),
+  },
+];

+ 97 - 0
src/views/assembly/item/child/Search.vue

@@ -0,0 +1,97 @@
+<template>
+    <div class="wrapper">
+        <span class="sqrk">申请入库(1)</span>
+        <span>
+            <a-select ref="select" v-model:value="value" style="width: 200px" :options="options" @focus="focus"
+                @change="handleChange">
+            </a-select>
+        </span>
+        <span>
+            <a-input-search v-model:value="key" placeholder="请输入搜索内容" style="width: 200px" @search="onSearch" />
+        </span>
+        <div>
+            <a-checkbox v-model:checked="checked1">全部</a-checkbox>
+            <a-checkbox v-model:checked="checked2">测试数据1</a-checkbox>
+            <a-checkbox v-model:checked="checked3">测试数据2</a-checkbox>
+            <a-checkbox v-model:checked="checked4">测试数据3</a-checkbox>
+        </div>
+    </div>
+</template>
+
+
+<script lang="ts">
+import { defineComponent, ref, computed, unref } from 'vue';
+export default defineComponent({
+    name: 'Search',
+    components: {},
+    setup() {
+        const value = ref<string>('1');
+        const key = ref<string>('');
+        const checked1 = ref<boolean>(false);
+        const checked2 = ref<boolean>(false);
+        const checked3 = ref<boolean>(false);
+        const checked4 = ref<boolean>(false);
+
+        const options = ref<SelectTypes['options']>([
+            {
+                value: '1',
+                label: '已审核',
+            },
+            {
+                value: '2',
+                label: '未审核',
+            },
+            {
+                value: '3',
+                label: '未通过',
+            },
+        ]);
+
+        function onSearch() {
+
+        }
+
+        return {
+            options,
+            value,
+            key,
+            onSearch,
+            checked1,
+            checked2,
+            checked3,
+            checked4,
+        };
+    },
+});
+</script>
+<style scoped>
+.wrapper>div {
+    float: right;
+    height: 32px;
+    padding: 5px 0;
+}
+
+.wrapper>span {
+    display: inline-block;
+    margin-right: 30px
+}
+
+.wrapper {
+    width: 100%;
+    height: 54px;
+    padding: 11px;
+    margin-bottom: 20px;
+    border-bottom: solid 1px #DEDEDE;
+}
+
+.sqrk {
+    width: 94px;
+    height: 32px;
+    background: #0671DD;
+    color: #fff;
+    line-height: 32px;
+    display: block;
+    text-align: center;
+    border-radius: 4px;
+}
+</style>