fix: 优化第三方应用菜单集成
* fix: 优化第三方应用菜单集成 * fix: bug#20731 * fix: 修改lodash依赖包 * fix: bug#20731
This commit is contained in:
parent
feb8dcddb9
commit
9ba07046e3
|
@ -25,7 +25,7 @@
|
|||
"event-source-polyfill": "^1.0.31",
|
||||
"global": "^4.4.0",
|
||||
"jetlinks-store": "^0.0.3",
|
||||
"jetlinks-ui-components": "^1.0.34-7",
|
||||
"jetlinks-ui-components": "^1.0.34-12",
|
||||
"js-cookie": "^3.0.1",
|
||||
"jsencrypt": "^3.3.2",
|
||||
"less": "^4.1.3",
|
||||
|
|
12
src/App.vue
12
src/App.vue
|
@ -10,11 +10,23 @@ import zhCN from 'jetlinks-ui-components/es/locale/zh_CN';
|
|||
import { storeToRefs } from 'pinia';
|
||||
import { useSystem } from './store/system';
|
||||
import DefaultSetting from '../config/config'
|
||||
import {LocalStore} from "@/utils/comm";
|
||||
import {TOKEN_KEY} from "@/utils/variable";
|
||||
|
||||
const system = useSystem();
|
||||
const {configInfo} = storeToRefs(system);
|
||||
|
||||
system.setDocumentTitle()
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
watch(() => JSON.stringify(route.query || {}), () => {
|
||||
if (route.query.token) {
|
||||
LocalStore.set(TOKEN_KEY, route.query.token);
|
||||
}
|
||||
}, { immediate: true })
|
||||
|
||||
|
||||
ConfigProvider.config({
|
||||
theme: {
|
||||
primaryColor: "#315efb"
|
||||
|
|
|
@ -21,5 +21,3 @@ export const saveMenuInfo_api = (data: object) => server.patch(`/menu`, data);
|
|||
export const addMenuInfo_api = (data: object) => server.post(`/menu`, data);
|
||||
// 删除菜单信息
|
||||
export const delMenuInfo_api = (id: string) => server.remove(`/menu/${id}`);
|
||||
//查询集成菜单
|
||||
export const queryApp = (data:any) => server.post('/application/_query/no-paging',data)
|
|
@ -4,8 +4,8 @@
|
|||
v-model:collapsed="basicLayout.collapsed"
|
||||
v-model:openKeys="basicLayout.openKeys"
|
||||
:selectedKeys="basicLayout.selectedKeys"
|
||||
:headerHeight='layout.headerHeight'
|
||||
:breadcrumb="{ routes: breadcrumbs }"
|
||||
:breadcrumb="basicLayout.pure ? undefined : { routes: breadcrumbs }"
|
||||
:headerHeight='basicLayout.pure ? 1 : layout.headerHeight'
|
||||
:pure="basicLayout.pure"
|
||||
@backClick='routerBack'
|
||||
>
|
||||
|
|
|
@ -159,11 +159,11 @@ const extraRouteObj = {
|
|||
type Buttons = Array<{ id: string }>
|
||||
|
||||
const hasAppID = (item: any): { isApp: boolean, appUrl: string } => {
|
||||
const isApp = !!item.appId
|
||||
const isApp = !!item.appId || item.options?.owner
|
||||
const isLowCode = !!item.options?.LowCode
|
||||
return {
|
||||
isApp: isApp || isLowCode,
|
||||
appUrl: isApp ? `/${item.appId}${item.url}` : item.url
|
||||
appUrl: isApp ? `/${item.appId || item.options?.owner}${item.url}` : item.url
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -149,7 +149,7 @@ import { StatusColorEnum, updateStatus } from './data';
|
|||
import { useMenuStore } from 'store/menu';
|
||||
import Save from './Save/index.vue';
|
||||
import { protocolList } from '@/utils/consts';
|
||||
import _ from 'lodash';
|
||||
import _ from 'lodash-es';
|
||||
|
||||
const menuStory = useMenuStore();
|
||||
const tableRef = ref<Record<string, any>>({});
|
||||
|
|
|
@ -87,7 +87,7 @@
|
|||
<script lang="ts" setup>
|
||||
import type { FormInstance } from 'ant-design-vue';
|
||||
import { savePointBatch } from '@/api/data-collect/collector';
|
||||
import { cloneDeep, isObject } from 'lodash';
|
||||
import { cloneDeep, isObject } from 'lodash-es';
|
||||
import { regOnlyNumber } from '../../../data';
|
||||
|
||||
const props = defineProps({
|
||||
|
|
|
@ -148,7 +148,7 @@ import {
|
|||
} from '@/api/data-collect/collector';
|
||||
import Save from './Save/index.vue';
|
||||
import { onlyMessage } from '@/utils/comm';
|
||||
import _ from 'lodash';
|
||||
import _ from 'lodash-es';
|
||||
import { colorMap } from '../data.ts';
|
||||
|
||||
const props = defineProps({
|
||||
|
|
|
@ -481,7 +481,7 @@ import {
|
|||
getAliyunProductsList,
|
||||
queryProductList,
|
||||
} from '@/api/northbound/alicloud';
|
||||
import _ from 'lodash';
|
||||
import _ from 'lodash-es';
|
||||
import { onlyMessage } from '@/utils/comm';
|
||||
import MSelect from '../../components/MSelect/index.vue';
|
||||
import { _deploy } from '@/api/device/product';
|
||||
|
|
|
@ -546,7 +546,7 @@ import {
|
|||
savePatch,
|
||||
detail,
|
||||
} from '@/api/northbound/dueros';
|
||||
import _, { cloneDeep } from 'lodash';
|
||||
import _, { cloneDeep } from 'lodash-es';
|
||||
import { useMenuStore } from '@/store/menu';
|
||||
import { onlyMessage } from '@/utils/comm';
|
||||
import MSelect from '../../components/MSelect/index.vue';
|
||||
|
|
|
@ -60,7 +60,6 @@ const queryTypeList = () => {
|
|||
if (!user.other.tabKey) {
|
||||
user.other.tabKey = arr?.[0]?.provider;
|
||||
}
|
||||
|
||||
tabs.value = arr;
|
||||
}
|
||||
});
|
||||
|
@ -70,6 +69,17 @@ watchEffect(() => {
|
|||
if (router.params.value?.other?.tabKey) {
|
||||
user.other.tabKey = router.params.value?.other?.tabKey
|
||||
}
|
||||
if(router.params?.value.row){
|
||||
if(['device-transparent-codec'].includes(router.params?.value.row.topicProvider)){
|
||||
user.other.tabKey = 'system-business'
|
||||
}
|
||||
if(['system-event'].includes(router.params?.value.row.topicProvider)){
|
||||
user.other.tabKey = 'system-monitor'
|
||||
}
|
||||
if(['workflow-task-cc','workflow-task-todo','workflow-task-reject', 'workflow-process-finish', 'workflow-process-repealed','workflow-task-transfer-todo'].includes(router.params?.value.row.topicProvider)){
|
||||
user.other.tabKey = 'workflow-notification'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
import type { ActionsType } from '@/components/Table/index';
|
||||
import { query, queryProduct, remove } from '@/api/device/firmware';
|
||||
import dayjs from 'dayjs';
|
||||
import _ from 'lodash';
|
||||
import _ from 'lodash-es';
|
||||
import Save from './Save/index.vue';
|
||||
import { useMenuStore } from 'store/menu';
|
||||
import type { FormDataType } from './type';
|
||||
|
|
|
@ -57,7 +57,7 @@ import { map } from 'rxjs/operators';
|
|||
import { useInstanceStore } from '@/store/instance';
|
||||
import { getWebSocket } from '@/utils/websocket';
|
||||
import { randomString } from '@/utils/utils';
|
||||
import _ from 'lodash';
|
||||
import _ from 'lodash-es';
|
||||
|
||||
const message = reactive<MessageType>({
|
||||
up: {
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
|
||||
<script lang="ts" setup>
|
||||
import { useInstanceStore } from '@/store/instance';
|
||||
import _ from 'lodash';
|
||||
import _ from 'lodash-es';
|
||||
import { saveTags, delTags } from '@/api/device/instance'
|
||||
import { onlyMessage } from '@/utils/comm';
|
||||
|
||||
|
|
|
@ -160,7 +160,7 @@ import {
|
|||
delDeviceCode, queryCodeTips, queryProductCodeTips,
|
||||
} from '@/api/device/instance';
|
||||
import { message } from 'jetlinks-ui-components';
|
||||
import { isBoolean } from 'lodash';
|
||||
import { isBoolean } from 'lodash-es';
|
||||
import { onlyMessage } from '@/utils/comm';
|
||||
|
||||
const defaultValue =
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
<script lang="ts" setup>
|
||||
import { useInstanceStore } from '@/store/instance';
|
||||
import _ from 'lodash';
|
||||
import _ from 'lodash-es';
|
||||
import Event from './Event/index.vue';
|
||||
import Property from './Property/index.vue';
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ import {
|
|||
testCode,
|
||||
saveProductCode, queryProductCodeTips,
|
||||
} from '@/api/device/instance';
|
||||
import { isBoolean } from 'lodash';
|
||||
import { isBoolean } from 'lodash-es';
|
||||
import { onlyMessage } from '@/utils/comm';
|
||||
|
||||
const defaultValue =
|
||||
|
|
|
@ -300,7 +300,7 @@ import 'driver.js/dist/driver.min.css';
|
|||
import { marked } from 'marked';
|
||||
import type { TableColumnType } from 'ant-design-vue';
|
||||
import { useMenuStore } from '@/store/menu';
|
||||
import _ from 'lodash';
|
||||
import _ from 'lodash-es';
|
||||
import { accessConfigTypeFilter } from '@/utils/setting';
|
||||
import AccessModal from './accessModal.vue'
|
||||
import MetaDataModal from './metadataModal.vue'
|
||||
|
|
|
@ -190,14 +190,13 @@ import {
|
|||
updateDevice,
|
||||
} from '@/api/device/product';
|
||||
import { isNoCommunity, downloadObject } from '@/utils/utils';
|
||||
import { omit } from 'lodash-es';
|
||||
import { omit , cloneDeep } from 'lodash-es';
|
||||
import { typeOptions } from '@/components/Search/util';
|
||||
import Save from './Save/index.vue';
|
||||
import { useMenuStore } from 'store/menu';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useRouterParams } from '@/utils/hooks/useParams';
|
||||
import { accessConfigTypeFilter } from '@/utils/setting';
|
||||
import {cloneDeep} from "lodash";
|
||||
/**
|
||||
* 表格数据
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<template>
|
||||
<j-data-table
|
||||
<j-data-table
|
||||
v-if="!heavyLoad"
|
||||
ref="tableRef"
|
||||
:data-source="dataSource"
|
||||
:columns="columns"
|
||||
|
@ -12,7 +13,7 @@
|
|||
@change="(data) => dataSourceCache = data"
|
||||
>
|
||||
<template #expand>
|
||||
<PermissionButton
|
||||
<!-- <PermissionButton
|
||||
type="primary"
|
||||
v-if="!showSave"
|
||||
:hasPermission="`${permission}:update`"
|
||||
|
@ -30,14 +31,12 @@
|
|||
placement="topRight"
|
||||
>
|
||||
新增
|
||||
</PermissionButton>
|
||||
</PermissionButton> -->
|
||||
<PermissionButton
|
||||
type="primary"
|
||||
:hasPermission="`${permission}:update`"
|
||||
key="update"
|
||||
v-else
|
||||
:loading="loading"
|
||||
|
||||
:disabled="hasOperate('add', type) || !editStatus"
|
||||
:tooltip="{
|
||||
title: hasOperate('add', type)
|
||||
|
@ -202,7 +201,27 @@
|
|||
</PermissionButton>
|
||||
</j-space>
|
||||
</template>
|
||||
</j-data-table>
|
||||
</j-data-table>
|
||||
<PermissionButton
|
||||
type="primary"
|
||||
block
|
||||
ghost
|
||||
:hasPermission="`${permission}:update`"
|
||||
key="add"
|
||||
:disabled="hasOperate('add', type)"
|
||||
:tooltip="{
|
||||
placement: hasOperate('add', type) ? 'topRight' : 'top',
|
||||
title: hasOperate('add', type)
|
||||
? '当前的存储方式不支持新增'
|
||||
: '新增',
|
||||
getPopupContainer: getPopupContainer,
|
||||
}"
|
||||
@click="handleAddClick()"
|
||||
placement="topRight"
|
||||
>
|
||||
<template #icon><AIcon type="PlusOutlined"/></template>
|
||||
新增行
|
||||
</PermissionButton>
|
||||
<PropertiesModal
|
||||
v-if="type === 'properties' && detailData.visible"
|
||||
:data="detailData.data"
|
||||
|
@ -250,16 +269,16 @@ import { asyncUpdateMetadata, updateMetadata } from '../metadata';
|
|||
import { useMetadataStore } from '@/store/metadata';
|
||||
import { DeviceInstance } from '@/views/device/Instance/typings';
|
||||
import { onlyMessage , LocalStore} from '@/utils/comm';
|
||||
import {omit} from "lodash-es";
|
||||
import { omit , cloneDeep} from "lodash-es";
|
||||
import { PropertiesModal, FunctionModal, EventModal, TagsModal } from './DetailModal'
|
||||
import { Modal } from 'jetlinks-ui-components'
|
||||
import {EventEmitter} from "@/utils/utils";
|
||||
import {computed, watch} from "vue";
|
||||
import {cloneDeep} from "lodash";
|
||||
import {useSystem} from "store/system";
|
||||
import {storeToRefs} from "pinia";
|
||||
import { FULL_CODE } from 'jetlinks-ui-components/es/DataTable'
|
||||
import { usePermissionStore } from '@/store/permission';
|
||||
import App from '@/App.vue';
|
||||
|
||||
const props = defineProps({
|
||||
target: {
|
||||
|
@ -278,6 +297,7 @@ const props = defineProps({
|
|||
|
||||
const _target = inject<'device' | 'product'>('_metadataType', props.target);
|
||||
|
||||
const tableContainer = ref()
|
||||
const system = useSystem();
|
||||
const {basicLayout} = storeToRefs(system);
|
||||
const router = useRouter()
|
||||
|
@ -303,7 +323,7 @@ const detailData = reactive({
|
|||
visible:false
|
||||
})
|
||||
|
||||
|
||||
const heavyLoad = ref<Boolean>(false)
|
||||
|
||||
const showSave = ref(metadata.value.length !== 0)
|
||||
|
||||
|
@ -402,6 +422,11 @@ const handleAddClick = async (_data?: any, index?: number) => {
|
|||
const newObject = _data || getDataByType()
|
||||
|
||||
const _addData = await tableRef.value.addItem(newObject, index)
|
||||
nextTick(()=>{
|
||||
if(tableContainer.value.classList.value === 'tableContainer'){
|
||||
tableContainer.value.classList.remove('tableContainer')
|
||||
}
|
||||
})
|
||||
// if (_addData.length === 1) {
|
||||
// showLastDelete.value = true
|
||||
// }
|
||||
|
@ -424,7 +449,6 @@ const removeItem = (index: number) => {
|
|||
// }
|
||||
if (_data.length === 0) {
|
||||
showSave.value = false
|
||||
|
||||
handleSaveClick()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ import { EventLevel, ExpandsTypeList } from '@/views/device/data';
|
|||
import { useMetadataStore } from '@/store/metadata';
|
||||
import { validateJson } from './validator';
|
||||
import { Rule } from 'ant-design-vue/es/form';
|
||||
import { debounce } from 'lodash';
|
||||
import { debounce } from 'lodash-es';
|
||||
|
||||
const props = defineProps({
|
||||
type: {
|
||||
|
|
|
@ -21,7 +21,7 @@ import { DeviceInstance } from '@/views/device/Instance/typings';
|
|||
import BaseForm from './BaseForm.vue';
|
||||
import { PropType } from 'vue';
|
||||
import { _deploy } from '@/api/device/product';
|
||||
import { cloneDeep } from 'lodash';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { onlyMessage } from '@/utils/comm';
|
||||
|
||||
const props = defineProps({
|
||||
|
|
|
@ -41,7 +41,7 @@ import { reactive } from 'vue';
|
|||
import type { PropType } from 'vue';
|
||||
import Item from './item.vue'
|
||||
import {Form} from "jetlinks-ui-components";
|
||||
import {cloneDeep} from "lodash";
|
||||
import { cloneDeep } from "lodash-es";
|
||||
import { FULL_CODE } from 'jetlinks-ui-components/es/DataTable'
|
||||
import dayjs from "dayjs";
|
||||
|
||||
|
|
|
@ -68,12 +68,11 @@
|
|||
<script setup lang="ts" name="OtherSetting">
|
||||
import Metrics from './Metrics/Metrics.vue'
|
||||
import {watch} from "vue";
|
||||
import {cloneDeep} from "lodash";
|
||||
import {useProductStore} from "store/product";
|
||||
import {useInstanceStore} from "store/instance";
|
||||
import {getMetadataConfig, getMetadataDeviceConfig} from "@/api/device/product";
|
||||
import ModelButton from '@/views/device/components/Metadata/Base/components/ModelButton.vue'
|
||||
import {omit} from "lodash-es";
|
||||
import { omit , cloneDeep} from "lodash-es";
|
||||
import { FULL_CODE } from 'jetlinks-ui-components/es/DataTable'
|
||||
|
||||
const props = defineProps({
|
||||
|
|
|
@ -33,8 +33,7 @@ import type { Key } from 'ant-design-vue/es/_util/type';
|
|||
import { convertMetadata, getCodecs, detail as productDetail } from '@/api/device/product';
|
||||
import { detail } from '@/api/device/instance'
|
||||
import { onlyMessage } from '@/utils/comm';
|
||||
import {cloneDeep} from "lodash";
|
||||
import {omit} from "lodash-es";
|
||||
import { omit , cloneDeep } from "lodash-es";
|
||||
|
||||
interface Props {
|
||||
visible: boolean;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<iframe
|
||||
v-if="loading"
|
||||
:src="iframeUrl"
|
||||
scrolling="no"
|
||||
scrolling="yes"
|
||||
frameBorder="0"
|
||||
style="width: 100%; height: 100%"
|
||||
></iframe>
|
||||
|
@ -48,17 +48,18 @@ const handle = async (appId: string, url: string) => {
|
|||
}
|
||||
}
|
||||
|
||||
const _url = menuUrl.startsWith('/') ? menuUrl : `/${menuUrl}`;
|
||||
|
||||
if (result.provider === 'internal-standalone') {
|
||||
const urlStandalone = `${result.page.baseUrl}/api/application/sso/${appId}/login?redirect=${menuUrl}?layout=false`;
|
||||
iframeUrl.value = urlStandalone;
|
||||
} else if (result.provider === 'internal-integrated') {
|
||||
const _url = menuUrl.startsWith('/') ? menuUrl : `/${menuUrl}`;
|
||||
const tokenUrl = `${
|
||||
result.page.baseUrl
|
||||
}${_url}?layout=false&X-Access-Token=${LocalStore.get(TOKEN_KEY)}`;
|
||||
iframeUrl.value = tokenUrl;
|
||||
} else {
|
||||
const urlOther = `${result.page.baseUrl}/${menuUrl}`;
|
||||
const urlOther = `${result.page.baseUrl}${_url}`;
|
||||
iframeUrl.value = urlOther;
|
||||
}
|
||||
}
|
||||
|
@ -106,6 +107,7 @@ watchEffect(() => {
|
|||
} else {
|
||||
loading.value = true
|
||||
const url = route.path.split('/').slice(2).join('/');
|
||||
console.log(route.path.split('/').slice(2))
|
||||
handle(params, url);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,9 +40,14 @@ const getProvidersFn = async () => {
|
|||
if (version ==='community') {
|
||||
return undefined
|
||||
} else {
|
||||
const res: any = await getProviders();
|
||||
const ids = res.result?.map?.(item => item.id) || []
|
||||
return protocolList.some(item => ids.includes(item.value))
|
||||
try {
|
||||
const res: any = await getProviders();
|
||||
const ids = res.result?.map?.(item => item.id) || []
|
||||
return protocolList.some(item => ids.includes(item.value))
|
||||
} catch (error) {
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -146,7 +146,7 @@ import { getImage } from '@/utils/comm';
|
|||
import { list, remove } from '@/api/link/protocol';
|
||||
import { onlyMessage } from '@/utils/comm';
|
||||
import Save from './Save/index.vue';
|
||||
import _ from 'lodash';
|
||||
import _ from 'lodash-es';
|
||||
|
||||
const tableRef = ref<Record<string, any>>({});
|
||||
const params = ref<Record<string, any>>({});
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { debounce } from 'lodash';
|
||||
import { debounce } from 'lodash-es';
|
||||
import ChannelApi from '@/api/media/channel';
|
||||
import DeviceApi from '@/api/media/device';
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ import Tag from './Tag.vue';
|
|||
import RelationSelect from './RelationSelect.vue';
|
||||
import { getParams } from '../../../util';
|
||||
import { handleParamsData } from '../../../components/Terms/util';
|
||||
import _ from 'lodash';
|
||||
import _ from 'lodash-es';
|
||||
|
||||
const props = defineProps({
|
||||
values: {
|
||||
|
|
|
@ -193,7 +193,7 @@ const handOptionByColumn = (option: any) => {
|
|||
]
|
||||
}
|
||||
} else if(option.type === 'enum') {
|
||||
valueOptions.value = _options?.map((item: any) => ({ ...item, label: item.name, value: item.id})) || []
|
||||
valueOptions.value = _options?.elements?.map((item: any) => ({ ...item, label: item.text, value: item.value})) || []
|
||||
} else{
|
||||
valueOptions.value = _options?.map((item: any) => ({ ...item, label: item.name, value: item.id})) || []
|
||||
}
|
||||
|
|
|
@ -127,7 +127,7 @@ const dropdownButtonClass = computed(() => ({
|
|||
const treeSelect = (v: any, option: any) => {
|
||||
const node = option.node
|
||||
visible.value = false
|
||||
label.value = node.fullname || node.name
|
||||
label.value = node.fullName || node.name
|
||||
selectValue.value = v[0]
|
||||
emit('update:value', node[props.valueName])
|
||||
emit('select', node)
|
||||
|
|
|
@ -82,8 +82,7 @@ import { ContextKey, arrayParamsKey, timeTypeKeys } from './util'
|
|||
import { useSceneStore } from 'store/scene'
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { Form } from 'jetlinks-ui-components'
|
||||
import {indexOf, isArray, isObject, isString, pick} from 'lodash-es'
|
||||
import {cloneDeep} from "lodash";
|
||||
import {indexOf, isArray, isObject, isString, pick , cloneDeep } from 'lodash-es'
|
||||
|
||||
const sceneStore = useSceneStore()
|
||||
const { data: formModel } = storeToRefs(sceneStore)
|
||||
|
|
|
@ -1428,7 +1428,7 @@ import { getImage, onlyMessage } from '@/utils/comm';
|
|||
import type { formType, dictType, optionsType, applyType } from '../typing';
|
||||
import { getRoleList_api } from '@/api/system/user';
|
||||
import { randomString } from '@/utils/utils';
|
||||
import { cloneDeep, difference } from 'lodash';
|
||||
import { cloneDeep, difference } from 'lodash-es';
|
||||
import { useMenuStore } from '@/store/menu';
|
||||
import { Rule } from 'ant-design-vue/lib/form';
|
||||
import ApplyList from './ApplyList/index.vue';
|
||||
|
|
|
@ -49,6 +49,7 @@ const handleOk = async () => {
|
|||
...form.checkedMenu,
|
||||
// ...form.half,
|
||||
]);
|
||||
dealMenu(items)
|
||||
console.log(items);
|
||||
if (form.checkedSystem) {
|
||||
if (items && items.length !== 0) {
|
||||
|
@ -169,6 +170,17 @@ function getSystemList(id: string) {
|
|||
});
|
||||
}
|
||||
|
||||
const dealMenu = (data:any)=>{
|
||||
data?.forEach((i:any)=>{
|
||||
i.options = {
|
||||
show:true
|
||||
}
|
||||
if(i.children){
|
||||
dealMenu(i.children)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
watch(() => props.data, (newVal: any) => {
|
||||
form.checkedSystem = newVal?.page.configuration?.checkedSystem
|
||||
if (form.checkedSystem) {
|
||||
|
|
|
@ -1,150 +1,456 @@
|
|||
<template>
|
||||
<j-modal
|
||||
:confirmLoading="loading"
|
||||
class="edit-dialog-container"
|
||||
title="集成菜单"
|
||||
visible
|
||||
width="600px"
|
||||
width="800px"
|
||||
:maskClosable="false"
|
||||
@cancel="cancel"
|
||||
@ok="handleOk"
|
||||
@ok="cancel"
|
||||
>
|
||||
<p>
|
||||
当前集成菜单
|
||||
</p>
|
||||
<j-tree
|
||||
v-if="menuTree.length"
|
||||
v-model:checkedKeys="menuState.checkedMenu"
|
||||
v-model:expandedKeys="menuState.expandedKeys"
|
||||
:fieldNames="{ key: 'code', title: 'name' }"
|
||||
:height="300"
|
||||
:tree-data="menuTree"
|
||||
checkable
|
||||
/>
|
||||
<j-empty
|
||||
v-else
|
||||
/>
|
||||
<div style="display: flex;">
|
||||
<div class="menuList" >
|
||||
菜单列表
|
||||
<div class="content">
|
||||
<PermissionButton
|
||||
type="link"
|
||||
:hasPermission="`${permission}:add`"
|
||||
@click="addMenu"
|
||||
>
|
||||
+ 新增菜单
|
||||
</PermissionButton>
|
||||
<div class="treeContainer">
|
||||
<j-tree
|
||||
:fieldNames="{
|
||||
title:'name',
|
||||
key:'id',
|
||||
children:'children'
|
||||
}"
|
||||
:treeData="treeData"
|
||||
>
|
||||
<template #title="data">
|
||||
<div class="tree-item">
|
||||
<div class="title">
|
||||
<j-ellipsis>{{ data.name }}</j-ellipsis>
|
||||
</div>
|
||||
<div class="menuControls">
|
||||
<PermissionButton
|
||||
v-if="data.options?.owner"
|
||||
type="link"
|
||||
:hasPermission="`${permission}:update`"
|
||||
tooltip="编辑"
|
||||
@click="()=>editMenu(data)"
|
||||
>
|
||||
<AIcon type="EditOutlined" />
|
||||
</PermissionButton>
|
||||
<PermissionButton
|
||||
type="link"
|
||||
:hasPermission="`${permission}:add`"
|
||||
:tooltip="{ title: data.level >= 3 ? '仅支持3级菜单' : '新增子菜单' }"
|
||||
:disabled="data.level >= 3 || data.options?.LowCode"
|
||||
@click="()=>addChildrenMenu(data)"
|
||||
>
|
||||
<AIcon type="PlusCircleOutlined" />
|
||||
</PermissionButton>
|
||||
<PermissionButton
|
||||
v-if="data.options?.owner"
|
||||
type="link"
|
||||
:hasPermission="`${permission}:delete`"
|
||||
tooltip="删除"
|
||||
:popConfirm="{
|
||||
title: `是否删除该菜单`,
|
||||
onConfirm: () => deleteMenu(data),
|
||||
}"
|
||||
>
|
||||
<AIcon type="DeleteOutlined" />
|
||||
</PermissionButton>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</j-tree>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="configuration" v-if="showControls">
|
||||
菜单配置
|
||||
<div class="content">
|
||||
<div class="saveBtn">
|
||||
<PermissionButton type="primary" :hasPermission="`${permission}:${ editType === 'add' ? 'add' : 'update'
|
||||
}`" :loading='saveLoading' @click="saveMenu">
|
||||
保存
|
||||
</PermissionButton>
|
||||
</div>
|
||||
<j-form ref="basicFormRef" :model="formData" class="basic-form" layout="vertical">
|
||||
<div class="row" style="display: flex">
|
||||
<j-form-item ref="uploadIcon" label="菜单图标" name="icon" :rules="[
|
||||
{
|
||||
required: true,
|
||||
message: '请上传图标',
|
||||
trigger: 'change',
|
||||
},
|
||||
]" style="flex: 0 0 186px">
|
||||
<div class="icon-upload has-icon" v-if="formData.icon">
|
||||
<AIcon :type="formData.icon" style="font-size: 90px" />
|
||||
<span class="mark" @click="dialogVisible = true">点击修改</span>
|
||||
</div>
|
||||
|
||||
<div v-else @click="dialogVisible = true" class="icon-upload no-icon">
|
||||
<span>
|
||||
<AIcon type="PlusOutlined" style="font-size: 30px" />
|
||||
<p>点击选择图标</p>
|
||||
</span>
|
||||
</div>
|
||||
</j-form-item>
|
||||
<j-row>
|
||||
<j-col :span="24">
|
||||
<j-form-item label="名称" name="name" :rules="[
|
||||
{
|
||||
required: true,
|
||||
message: '请输入名称',
|
||||
},
|
||||
{
|
||||
max: 64,
|
||||
message: '最多可输入64个字符',
|
||||
},
|
||||
]">
|
||||
<j-input v-model:value="formData.name" placeholder="请输入名称" />
|
||||
</j-form-item>
|
||||
</j-col>
|
||||
<j-col :span="24">
|
||||
<j-form-item label="编码" name="code" :validateFirst="true" :rules="[
|
||||
{
|
||||
required: true,
|
||||
message: '请输入编码',
|
||||
},
|
||||
{
|
||||
max: 64,
|
||||
message: '最多可输入64个字符',
|
||||
},
|
||||
{
|
||||
validator: checkCode,
|
||||
trigger: 'blur',
|
||||
},
|
||||
]">
|
||||
<j-input v-model:value="formData.code" placeholder="请输入编码" />
|
||||
</j-form-item>
|
||||
</j-col>
|
||||
|
||||
|
||||
<!-- <j-col :span="12">
|
||||
<j-form-item label="排序" name="sortIndex" :rules="[
|
||||
{
|
||||
pattern: /^[0-9]*[1-9][0-9]*$/,
|
||||
message: '请输入大于0的整数',
|
||||
},
|
||||
]">
|
||||
<j-input-number v-model:value="formData.sortIndex" placeholder="请输入排序"
|
||||
style="width: 100%" />
|
||||
</j-form-item>
|
||||
</j-col> -->
|
||||
</j-row>
|
||||
</div>
|
||||
<j-form-item label="页面地址" name="url" :validateFirst="true" :rules="[
|
||||
{
|
||||
required: true,
|
||||
message: '请输入页面地址',
|
||||
},
|
||||
{ max: 128, message: '最多可输入128个字符'},
|
||||
{ pattern: /^\//, message: '请正确填写地址,以/开头' },
|
||||
]">
|
||||
<j-input v-model:value="formData.url" placeholder="请输入页面地址" />
|
||||
</j-form-item>
|
||||
<!-- <j-form-item label="说明" name="describe">
|
||||
<j-textarea v-model:value="formData.describe" :rows="4" show-count :maxlength="200"
|
||||
placeholder="请输入说明" />
|
||||
</j-form-item> -->
|
||||
</j-form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ChooseIconDialog v-if="dialogVisible" v-model:visible="dialogVisible" :icon="formData.icon"
|
||||
@confirm="(typeStr: string) => choseIcon(typeStr)" />
|
||||
</j-modal>
|
||||
</template>
|
||||
|
||||
<script name="ThirdMenu" setup>
|
||||
import {getMenuTree_api, queryOwnThree} from '@/api/system/menu';
|
||||
<script name="ThirdMenu" setup lang="ts">
|
||||
import { getMenuTree_api , validCode_api , addMenuInfo_api ,saveMenuInfo_api , getMenuInfo_api , delMenuInfo_api} from '@/api/system/menu'
|
||||
import { USER_CENTER_MENU_CODE,messageSubscribe } from '@/utils/consts'
|
||||
import ChooseIconDialog from '../../Menu/components/ChooseIconDialog.vue'
|
||||
import { Rule } from 'ant-design-vue/lib/form';
|
||||
import { onlyMessage } from '@/utils/comm';
|
||||
import { useMenuStore } from '@/store/menu';
|
||||
import { useRequest } from '@/hook'
|
||||
import {filterTree, getCheckByTree} from "@/views/system/Apply/componenets/util";
|
||||
import {
|
||||
saveOwnerMenu_api,
|
||||
updateApp_api,
|
||||
} from '@/api/system/apply';
|
||||
|
||||
const props = defineProps({
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'add'
|
||||
},
|
||||
data: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
|
||||
const menuStory = useMenuStore();
|
||||
const loading = ref(false)
|
||||
const emit = defineEmits(['ok', 'cancel']);
|
||||
const menuState = reactive({
|
||||
checkedMenu: [],
|
||||
expandedKeys: [],
|
||||
menuTree: ''
|
||||
const emit = defineEmits(['cancel'])
|
||||
const permission = 'system/Menu';
|
||||
const basicFormRef = ref()
|
||||
const treeData = ref([])
|
||||
const formData = ref<any>({
|
||||
icon:'',
|
||||
name:'',
|
||||
code:'',
|
||||
url:'',
|
||||
sortIndex:0
|
||||
})
|
||||
|
||||
const menuTree = computed(() => {
|
||||
try {
|
||||
return JSON.parse(menuState.menuTree || '[]')
|
||||
} catch (e) {
|
||||
return []
|
||||
}
|
||||
})
|
||||
|
||||
useRequest(queryOwnThree,
|
||||
{
|
||||
defaultParams: { terms: [{ column: 'owner', termType: 'isnull', value: 0 }]},
|
||||
onSuccess(res) {
|
||||
menuState.menuTree = JSON.stringify(res.result)
|
||||
return res
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const { run } = useRequest(getMenuTree_api, {
|
||||
immediate: false,
|
||||
onSuccess(res) {
|
||||
menuState.checkedMenu = getCheckByTree(res.result)
|
||||
return res
|
||||
}
|
||||
}) // 获取应用绑定的菜单
|
||||
|
||||
const cancel = () => {
|
||||
if (props.mode === 'add') {
|
||||
menuStory.jumpPage('system/Apply/Save', {}, { id: props.data?.id })
|
||||
}
|
||||
emit('cancel')
|
||||
const sourceCode = ref()
|
||||
const dialogVisible = ref(false)
|
||||
const uploadIcon = ref()
|
||||
const showControls = ref(false)
|
||||
const editType = ref()
|
||||
const saveLoading = ref(false)
|
||||
const rootMenuTotal = ref<Number>(0)
|
||||
const queryParams = {
|
||||
sorts: [{ name: 'sortIndex', order: 'asc' }],
|
||||
paging: false,
|
||||
terms: [
|
||||
{
|
||||
terms: [
|
||||
{
|
||||
column: 'owner',
|
||||
termType: 'eq',
|
||||
value: 'iot',
|
||||
},
|
||||
{
|
||||
column: 'owner',
|
||||
termType: 'isnull',
|
||||
value: '1',
|
||||
type: 'or',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
terms:[
|
||||
{
|
||||
terms:[
|
||||
{
|
||||
value:"%show\":true%",
|
||||
termType:"like",
|
||||
column:"options",
|
||||
type:'and'
|
||||
},
|
||||
{
|
||||
value:"%owner\"%",
|
||||
termType:"nlike",
|
||||
column:"options",
|
||||
type:"and"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
terms:[
|
||||
{
|
||||
value:`%owner\":\"${props.data.id}%`,
|
||||
termType:"like",
|
||||
column:"options"
|
||||
}
|
||||
],
|
||||
type:"or"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
const handleOk = async () => {
|
||||
if (!menuState.checkedMenu.length) {
|
||||
onlyMessage('请勾选配置菜单', 'warning')
|
||||
return
|
||||
}
|
||||
const id = props.data.id
|
||||
const cloneData = JSON.parse(menuState.menuTree)
|
||||
const filterData = filterTree(cloneData, menuState.checkedMenu)
|
||||
|
||||
loading.value = true
|
||||
|
||||
try {
|
||||
const resp = await saveOwnerMenu_api('iot', id, filterData)
|
||||
await updateApp_api(id, {
|
||||
...props.data,
|
||||
integrationModes: props.data?.integrationModes?.map((item) => item?.value || item),
|
||||
page: {
|
||||
...props.data?.page,
|
||||
configuration: {
|
||||
checkedSystem: props.data?.page?.configuration?.checkedSystem
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
if (resp.success) {
|
||||
// 保存集成菜单
|
||||
onlyMessage('操作成功');
|
||||
emit('ok')
|
||||
}
|
||||
loading.value = false
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
loading.value = false
|
||||
}
|
||||
const addChildrenMenu = (data:any) =>{
|
||||
basicFormRef.value?.clearValidate()
|
||||
initFormData()
|
||||
showControls.value = true
|
||||
editType.value = 'add'
|
||||
formData.value.parentId = data?.id
|
||||
formData.value.url = data?.url
|
||||
formData.value.sortIndex = data?.children?.length + 1|| 0;
|
||||
}
|
||||
|
||||
const getBindMenuData = () => {
|
||||
const id = props.data.id
|
||||
|
||||
run({
|
||||
terms: [
|
||||
{
|
||||
column: 'appId',
|
||||
value: id,
|
||||
},
|
||||
],
|
||||
const addMenu = () =>{
|
||||
initFormData()
|
||||
formData.value.sortIndex = rootMenuTotal.value
|
||||
sourceCode.value = ''
|
||||
showControls.value = true
|
||||
editType.value = 'add'
|
||||
}
|
||||
const editMenu = (data:any) =>{
|
||||
basicFormRef.value?.clearValidate()
|
||||
initFormData()
|
||||
showControls.value = true
|
||||
editType.value = 'edit'
|
||||
getMenuInfo_api(data.id).then((res:any)=>{
|
||||
formData.value = res.result
|
||||
sourceCode.value = res.result?.code
|
||||
})
|
||||
}
|
||||
|
||||
if (props.data?.id) {
|
||||
getBindMenuData()
|
||||
const deleteMenu = (data:any) =>{
|
||||
delMenuInfo_api(data.id).then((resp: any) => {
|
||||
if (resp.status === 200) {
|
||||
onlyMessage('操作成功');
|
||||
queryMenu();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const initFormData = () =>{
|
||||
formData.value = {
|
||||
icon:'',
|
||||
name:'',
|
||||
code:'',
|
||||
url:'',
|
||||
}
|
||||
}
|
||||
const choseIcon = (typeStr: string) => {
|
||||
formData.value.icon = typeStr;
|
||||
uploadIcon.value?.clearValidate();
|
||||
}
|
||||
const saveMenu = () =>{
|
||||
basicFormRef.value.validate().then(()=>{
|
||||
const api = editType.value === 'add' ? addMenuInfo_api : saveMenuInfo_api
|
||||
saveLoading.value = true
|
||||
const params ={
|
||||
...formData.value,
|
||||
owner: 'iot',
|
||||
options: { show: true ,owner:props.data?.id },
|
||||
}
|
||||
api(params).then((res)=>{
|
||||
if(res.status === 200){
|
||||
onlyMessage('操作成功')
|
||||
queryMenu()
|
||||
}else{
|
||||
onlyMessage('操作失败')
|
||||
}
|
||||
}).finally(() => (saveLoading.value = false));
|
||||
})
|
||||
}
|
||||
const checkCode = async (_rule: Rule, value: string): Promise<any> => {
|
||||
if (!value) return Promise.reject('');
|
||||
else if (value.length > 64) return Promise.reject('最多可输入64个字符');
|
||||
// 编辑时不校验原本的编码
|
||||
else if (editType.value = 'edit' && value === sourceCode.value)
|
||||
return Promise.resolve('');
|
||||
else {
|
||||
const resp: any = await validCode_api({
|
||||
code: value,
|
||||
owner: 'iot',
|
||||
});
|
||||
if (resp.result.passed) return Promise.resolve();
|
||||
else return Promise.reject('该编码重复');
|
||||
}
|
||||
}
|
||||
const cancel = () =>{
|
||||
emit('cancel')
|
||||
}
|
||||
const queryMenu = () =>{
|
||||
getMenuTree_api(queryParams).then((res:any)=>{
|
||||
treeData.value = res.result?.filter((item: { code: string }) => ![USER_CENTER_MENU_CODE,messageSubscribe].includes(item.code))
|
||||
const lastItem = res.result[res.result.length - 1];
|
||||
rootMenuTotal.value = lastItem ? lastItem.sortIndex + 1 : 1;
|
||||
})
|
||||
}
|
||||
onMounted(()=>{
|
||||
queryMenu()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
<style lang="less" scoped>
|
||||
.menuList{
|
||||
width: 35%;
|
||||
margin-right: 20px;
|
||||
}
|
||||
.configuration{
|
||||
width: 60%;
|
||||
}
|
||||
.content{
|
||||
border: .3px solid rgb(220, 220, 220);
|
||||
position: relative;
|
||||
.saveBtn{
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
top: 10px;
|
||||
}
|
||||
.basic-form{
|
||||
height: 432px;
|
||||
padding: 32px 20px;
|
||||
:deep(.ant-form-item-control-input-content) {
|
||||
.icon-upload {
|
||||
width: 160px;
|
||||
height: 150px;
|
||||
border: 1px dashed #d9d9d9;
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
transition: 0.5s;
|
||||
|
||||
&:hover {
|
||||
border-color: #415ed1;
|
||||
}
|
||||
}
|
||||
|
||||
.has-icon {
|
||||
position: relative;
|
||||
text-align: center;
|
||||
|
||||
.mark {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
display: none;
|
||||
background-color: rgba(0, 0, 0, 0.35);
|
||||
color: #fff;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-size: 16px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
&:hover .mark {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
.no-icon {
|
||||
background-color: rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
}
|
||||
}
|
||||
.treeContainer{
|
||||
height: 400px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.tree-item{
|
||||
display: flex;
|
||||
position: relative;
|
||||
align-items: stretch;
|
||||
justify-content: space-around;
|
||||
.title {
|
||||
flex: 1;
|
||||
min-width: 80px;
|
||||
margin-right: 80px;
|
||||
}
|
||||
.menuControls {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
display: none;
|
||||
font-size: 14px;
|
||||
:deep(.ant-btn-link) {
|
||||
padding: 0 4px;
|
||||
height: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ant-tree-treenode) {
|
||||
width: 100%;
|
||||
.ant-tree-node-content-wrapper {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
.ant-tree-title {
|
||||
&:hover {
|
||||
.menuControls{
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -312,7 +312,8 @@ const tableRef = ref();
|
|||
const current = ref<any>({})
|
||||
const table = {
|
||||
refresh: () => {
|
||||
tableRef.value.reload(queryParams.value);
|
||||
// tableRef.value.reload(queryParams.value);
|
||||
window.location.reload()
|
||||
},
|
||||
toAdd: () => {
|
||||
visible.value = true
|
||||
|
|
|
@ -235,8 +235,7 @@ import { onlyMessage } from '@/utils/comm';
|
|||
import { randomString } from '@/utils/utils';
|
||||
import { FormInstance } from 'ant-design-vue';
|
||||
import { DataNode } from 'ant-design-vue/lib/tree';
|
||||
import _ from 'lodash';
|
||||
import { cloneDeep } from 'lodash';
|
||||
import _ , { cloneDeep } from 'lodash-es';
|
||||
import type { dbColumnType, dictItemType, sourceItemType } from '../typing';
|
||||
|
||||
const id = useRoute().query.id as string;
|
||||
|
|
|
@ -255,7 +255,6 @@ init();
|
|||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ant-tree-treenode) {
|
||||
width: 100%;
|
||||
.ant-tree-node-content-wrapper {
|
||||
|
@ -278,7 +277,7 @@ init();
|
|||
flex: 1 1 auto;
|
||||
.department-tree-item-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
align-items: stretch;
|
||||
|
||||
.title {
|
||||
flex: 1;
|
||||
|
|
|
@ -61,14 +61,14 @@
|
|||
</j-form-item>
|
||||
</j-col>
|
||||
<j-col :span="12">
|
||||
<j-form-item label="页面地址" name="url" :rules="[
|
||||
<j-form-item :rules="[
|
||||
{
|
||||
required: true,
|
||||
message: '请输入页面地址',
|
||||
},
|
||||
{ max: 128, message: '最多可输入128字符' },
|
||||
{ pattern: /^\//, message: '请正确填写地址,以/开头' },
|
||||
]">
|
||||
]" :validateFirst="true" label="页面地址" name="url">
|
||||
<j-input v-model:value="form.data.url" placeholder="请输入页面地址" />
|
||||
</j-form-item>
|
||||
</j-col>
|
||||
|
@ -83,12 +83,6 @@
|
|||
style="width: 100%" />
|
||||
</j-form-item>
|
||||
</j-col>
|
||||
<j-col :span="12" v-if="!isChildren">
|
||||
<j-form-item label="所属应用" name="appId">
|
||||
<j-select v-model:value="form.data.appId" :options="appOptions" :allowClear="!routeParams.id"
|
||||
placeholder="请选择所属应用" style="width: 100%" @change="selectApp"/>
|
||||
</j-form-item>
|
||||
</j-col>
|
||||
</j-row>
|
||||
</div>
|
||||
|
||||
|
@ -98,7 +92,7 @@
|
|||
</j-form-item>
|
||||
</j-form>
|
||||
</div>
|
||||
<div class="card" v-if="!form.data.appId && !isChildren">
|
||||
<div class="card" v-if="!form.data.appId">
|
||||
<h3>权限配置</h3>
|
||||
<j-form ref="permissFormRef" :model="form.data" class="basic-form permiss-form">
|
||||
<j-form-item name="accessSupport" required v-if="isNoCommunity">
|
||||
|
@ -172,12 +166,11 @@ import {
|
|||
saveMenuInfo_api,
|
||||
addMenuInfo_api,
|
||||
validCode_api,
|
||||
queryApp
|
||||
} from '@/api/system/menu';
|
||||
import { Rule } from 'ant-design-vue/lib/form';
|
||||
import { isNoCommunity } from '@/utils/utils';
|
||||
import { onlyMessage } from '@/utils/comm';
|
||||
import { applicationInfo } from '@/api/bind';
|
||||
|
||||
|
||||
const permission = 'system/Menu';
|
||||
// 路由
|
||||
|
@ -189,7 +182,6 @@ const routeParams = {
|
|||
url: route.query.basePath,
|
||||
parentId: route.query.pid,
|
||||
};
|
||||
const isChildren = route.query?.isChildren
|
||||
// 表单
|
||||
const basicFormRef = ref<FormInstance>();
|
||||
const permissFormRef = ref<FormInstance>();
|
||||
|
@ -207,8 +199,6 @@ const form = reactive({
|
|||
accessSupport: 'unsupported',
|
||||
assetType: undefined,
|
||||
indirectMenus: [],
|
||||
appId: '',
|
||||
application:'',
|
||||
...routeParams,
|
||||
} as formType,
|
||||
treeData: [], // 关联菜单
|
||||
|
@ -290,9 +280,6 @@ const form = reactive({
|
|||
: '间接控制',
|
||||
},
|
||||
};
|
||||
if(params?.isChildren){
|
||||
delete params.isChildren
|
||||
}
|
||||
api(params)
|
||||
.then((resp: any) => {
|
||||
if (resp.status === 200) {
|
||||
|
@ -320,32 +307,9 @@ const choseIcon = (typeStr: string) => {
|
|||
form.data.icon = typeStr;
|
||||
uploadIcon.value?.clearValidate();
|
||||
}
|
||||
|
||||
const selectApp = (value:string,options:any) =>{
|
||||
form.data.application = options?.label
|
||||
}
|
||||
// 弹窗
|
||||
const dialogVisible = ref(false);
|
||||
|
||||
onMounted(() => {
|
||||
queryApp({
|
||||
terms: [
|
||||
{
|
||||
"column": "integrationModes",
|
||||
"termType": "in$any",
|
||||
"value": "page"
|
||||
}
|
||||
],
|
||||
paging: false
|
||||
}).then((res:any)=>{
|
||||
appOptions.value = res.result?.map((i:any)=>{
|
||||
return {
|
||||
label:i.name,
|
||||
value:i.id
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
type formType = {
|
||||
id?: string;
|
||||
name: string;
|
||||
|
@ -359,8 +323,6 @@ type formType = {
|
|||
assetType: string | undefined;
|
||||
indirectMenus: any[];
|
||||
parentId?: string;
|
||||
appId:string,
|
||||
application:string
|
||||
};
|
||||
|
||||
type assetType = {
|
||||
|
@ -375,7 +337,7 @@ type assetType = {
|
|||
padding: 24px;
|
||||
.card {
|
||||
margin-bottom: 24px;
|
||||
|
||||
|
||||
h3 {
|
||||
position: relative;
|
||||
display: flex;
|
||||
|
|
|
@ -76,7 +76,7 @@ import {
|
|||
} from './utils';
|
||||
import BaseMenu from '@/views/init-home/data/baseMenu';
|
||||
import type { AntTreeNodeDropEvent } from 'ant-design-vue/es/tree';
|
||||
import { cloneDeep } from 'lodash';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { onlyMessage } from '@/utils/comm';
|
||||
import {
|
||||
USER_CENTER_MENU_CODE,
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
visible
|
||||
title="菜单图标"
|
||||
width="800px"
|
||||
:maskClosable="false"
|
||||
@cancel="emits('update:visible', false)"
|
||||
@ok="confirm"
|
||||
>
|
||||
|
|
|
@ -131,7 +131,7 @@ import { JsonViewer } from 'vue3-json-viewer';
|
|||
import 'vue3-json-viewer/dist/index.css';
|
||||
import type { apiDetailsType } from '../typing';
|
||||
import InputCard from './InputCard.vue';
|
||||
import { cloneDeep, toLower } from 'lodash';
|
||||
import { cloneDeep, toLower } from 'lodash-es';
|
||||
import { FormInstance } from 'ant-design-vue';
|
||||
import server from '@/utils/request';
|
||||
import { findData, getCodeText } from '../utils';
|
||||
|
|
|
@ -107,6 +107,7 @@ const columns = [
|
|||
ellipsis: true,
|
||||
fixed: 'left',
|
||||
search: {
|
||||
rename:'objectType',
|
||||
type: 'select',
|
||||
options: async () =>{
|
||||
const res:any = await getObjectList_api()
|
||||
|
|
|
@ -147,7 +147,10 @@
|
|||
{
|
||||
validator: form.rules.checkUserName,
|
||||
trigger: 'blur',
|
||||
},
|
||||
},{
|
||||
validator: form.rules.checkCh,
|
||||
trigger: 'change'
|
||||
}
|
||||
]"
|
||||
>
|
||||
<j-input
|
||||
|
@ -189,6 +192,9 @@
|
|||
validator: form.rules.checkAgainPassword,
|
||||
trigger: 'blur',
|
||||
},
|
||||
{
|
||||
|
||||
}
|
||||
]"
|
||||
>
|
||||
<j-input-password
|
||||
|
@ -261,10 +267,14 @@ const form = reactive({
|
|||
data: {} as formType,
|
||||
|
||||
rules: {
|
||||
checkCh: (_rule:Rule,value:string): Promise<any> =>
|
||||
new Promise((resolve,reject) => {
|
||||
if (/[\u4e00-\u9fa5]/.test(value)) return reject('用户名不能包含中文');
|
||||
else return resolve('')
|
||||
}),
|
||||
checkUserName: (_rule: Rule, value: string): Promise<any> =>
|
||||
new Promise((resolve, reject) => {
|
||||
if (props.type === 'edit') return resolve('');
|
||||
|
||||
if (!value) return reject('请输入用户名');
|
||||
else if (value.length > 64) return reject('最多可输入64个字符');
|
||||
validateField_api('username', value).then((resp: any): any => {
|
||||
|
|
|
@ -3738,10 +3738,10 @@ jetlinks-store@^0.0.3:
|
|||
resolved "https://registry.npmjs.org/jetlinks-store/-/jetlinks-store-0.0.3.tgz"
|
||||
integrity sha512-AZf/soh1hmmwjBZ00fr1emuMEydeReaI6IBTGByQYhTmK1Zd5pQAxC7WLek2snRAn/HHDgJfVz2hjditKThl6Q==
|
||||
|
||||
jetlinks-ui-components@^1.0.34-7:
|
||||
version "1.0.34-7"
|
||||
resolved "https://registry.npmjs.org/jetlinks-ui-components/-/jetlinks-ui-components-1.0.34-7.tgz#3a14e85edb4c5d11427d30f3925dc5f498478940"
|
||||
integrity sha512-Rgbjig3QYP8CDVHLbco20Cf7sArYralO8yWtH5E5zylYAN2lINLUsgOlIVf9aweszZR/Ps+z/NLP0CoRQf1Xtw==
|
||||
jetlinks-ui-components@^1.0.34-12:
|
||||
version "1.0.34-12"
|
||||
resolved "https://registry.npmjs.org/jetlinks-ui-components/-/jetlinks-ui-components-1.0.34-12.tgz#13e035bae1d16af957d81a175daaa3a2fe290406"
|
||||
integrity sha512-fxoncKov8IsScneXQYcaBwg+HnXrkJSaS7z9aV7uZK4/WxvTaAWozOPIOSkBwfDya+BuRpbJ9ZW3X9MtT6kLrQ==
|
||||
dependencies:
|
||||
"@vueuse/core" "^9.12.0"
|
||||
"@vueuse/router" "^9.13.0"
|
||||
|
|
Loading…
Reference in New Issue