fix: bug#19167
This commit is contained in:
parent
f2317db02d
commit
aa0ffab927
|
@ -25,7 +25,7 @@
|
||||||
"event-source-polyfill": "^1.0.31",
|
"event-source-polyfill": "^1.0.31",
|
||||||
"global": "^4.4.0",
|
"global": "^4.4.0",
|
||||||
"jetlinks-store": "^0.0.3",
|
"jetlinks-store": "^0.0.3",
|
||||||
"jetlinks-ui-components": "^1.0.34-2",
|
"jetlinks-ui-components": "^1.0.34-4",
|
||||||
"js-cookie": "^3.0.1",
|
"js-cookie": "^3.0.1",
|
||||||
"jsencrypt": "^3.3.2",
|
"jsencrypt": "^3.3.2",
|
||||||
"less": "^4.1.3",
|
"less": "^4.1.3",
|
||||||
|
|
|
@ -25,9 +25,11 @@
|
||||||
<UserInfo />
|
<UserInfo />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<router-view v-slot="{ Component }">
|
<slot>
|
||||||
<component :is="components || Component" />
|
<router-view v-slot="{ Component }">
|
||||||
</router-view>
|
<component :is="components || Component" />
|
||||||
|
</router-view>
|
||||||
|
</slot>
|
||||||
</j-pro-layout>
|
</j-pro-layout>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -40,6 +42,7 @@ import { clearMenuItem } from 'jetlinks-ui-components/es/ProLayout/util';
|
||||||
import { AccountMenu } from '@/router/menu'
|
import { AccountMenu } from '@/router/menu'
|
||||||
import { useSystem } from '@/store/system';
|
import { useSystem } from '@/store/system';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
|
import { useSlots } from 'vue'
|
||||||
|
|
||||||
type StateType = {
|
type StateType = {
|
||||||
collapsed: boolean;
|
collapsed: boolean;
|
||||||
|
@ -55,7 +58,7 @@ const menu = useMenuStore();
|
||||||
|
|
||||||
const system = useSystem();
|
const system = useSystem();
|
||||||
const {configInfo,layout, basicLayout} = storeToRefs(system);
|
const {configInfo,layout, basicLayout} = storeToRefs(system);
|
||||||
|
const slots = useSlots()
|
||||||
const layoutConf = reactive({
|
const layoutConf = reactive({
|
||||||
theme: DefaultSetting.layout.theme,
|
theme: DefaultSetting.layout.theme,
|
||||||
siderWidth: layout.value.siderWidth,
|
siderWidth: layout.value.siderWidth,
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './useRequest'
|
|
@ -0,0 +1,92 @@
|
||||||
|
import {onUnmounted, ref} from 'vue'
|
||||||
|
import type { Ref } from 'vue'
|
||||||
|
import {isFunction, get, isArray} from 'lodash-es'
|
||||||
|
import type { AxiosResponseRewrite } from '@/utils/request'
|
||||||
|
|
||||||
|
interface RequestOptions<T, S> {
|
||||||
|
immediate: boolean
|
||||||
|
/**
|
||||||
|
* 成功回调
|
||||||
|
* @param data
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
onSuccess: (data: AxiosResponseRewrite<S>) => S | void
|
||||||
|
/**
|
||||||
|
* 返回参数处理
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
formatName: string | [string]
|
||||||
|
onError: (e: any) => void
|
||||||
|
|
||||||
|
defaultParams: S | any | any[]
|
||||||
|
|
||||||
|
handleResponse: (data: any) => any
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultOptions: any = {
|
||||||
|
immediate: true,
|
||||||
|
formatName: 'result'
|
||||||
|
}
|
||||||
|
|
||||||
|
type Run = (...args: any[]) => void
|
||||||
|
|
||||||
|
export const useRequest = <T = any, S = any>(
|
||||||
|
request: (...args: any[]) => Promise<AxiosResponseRewrite<T>>,
|
||||||
|
options: Partial<RequestOptions<T, S>> = defaultOptions,
|
||||||
|
): {
|
||||||
|
data: Ref<S | undefined>,
|
||||||
|
loading: Ref<boolean>,
|
||||||
|
run: Run
|
||||||
|
} => {
|
||||||
|
const data = ref<S>()
|
||||||
|
const loading = ref(false)
|
||||||
|
const _options = {
|
||||||
|
...defaultOptions,
|
||||||
|
...options
|
||||||
|
}
|
||||||
|
|
||||||
|
async function run(...arg: any[]) {
|
||||||
|
if (request && isFunction(request)) {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
// @ts-ignore
|
||||||
|
const resp = await request.apply(this, arg)
|
||||||
|
|
||||||
|
loading.value = false
|
||||||
|
|
||||||
|
if (resp?.success) {
|
||||||
|
const successData = await _options.onSuccess?.(resp)
|
||||||
|
data.value = successData || get(resp, _options.formatName!)
|
||||||
|
// console.log(data.value)
|
||||||
|
} else {
|
||||||
|
_options.onError?.(resp)
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
loading.value = false
|
||||||
|
_options.onError?.(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_options.immediate) { // 主动触发
|
||||||
|
if (_options.defaultParams) {
|
||||||
|
isArray(_options.defaultParams) ? run(..._options.defaultParams) : run(_options.defaultParams)
|
||||||
|
} else {
|
||||||
|
run()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
// 销毁时,撤销该请求
|
||||||
|
if (request && isFunction(request)) {
|
||||||
|
|
||||||
|
}
|
||||||
|
// request()
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
data,
|
||||||
|
loading,
|
||||||
|
run
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,12 +24,12 @@ const defaultOwnParams = [
|
||||||
termType: 'eq',
|
termType: 'eq',
|
||||||
value: 'iot'
|
value: 'iot'
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
column: 'owner',
|
// column: 'owner',
|
||||||
termType: 'isnull',
|
// termType: 'isnull',
|
||||||
value: '1',
|
// value: '1',
|
||||||
type: 'or'
|
// type: 'or'
|
||||||
}
|
// }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { BlankLayoutPage, BasicLayoutPage } from 'components/Layout'
|
import { BlankLayoutPage, BasicLayoutPage } from 'components/Layout'
|
||||||
import { isNoCommunity } from '@/utils/utils'
|
import { isNoCommunity } from '@/utils/utils'
|
||||||
import Iframe from '../views/iframe/index.vue'
|
import Iframe from '../views/iframe/index.vue'
|
||||||
|
import { shallowRef, defineAsyncComponent } from 'vue'
|
||||||
|
|
||||||
const pagesComponent = import.meta.glob('../views/**/*.vue');
|
const pagesComponent = import.meta.glob('../views/**/*.vue');
|
||||||
|
|
||||||
|
@ -155,192 +156,6 @@ const extraRouteObj = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
|
||||||
// const resolveComponent = (name: any) => {
|
|
||||||
// const importPage = pagesComponent[`../views/${name}/index.vue`];
|
|
||||||
// console.log(importPage)
|
|
||||||
// if (!importPage) {
|
|
||||||
// return undefined
|
|
||||||
// } else {
|
|
||||||
// const res = () => importPage()
|
|
||||||
// return res
|
|
||||||
// }
|
|
||||||
// //@ts-ignore
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// const findChildrenRoute = (code: string, url: string, routes: any[] = []): MenuItem[] => {
|
|
||||||
// if (extraRouteObj[code]) {
|
|
||||||
// const extraRoutes = extraRouteObj[code].children.map((route: MenuItem) => {
|
|
||||||
// return {
|
|
||||||
// url: `${url}/${route.code}`,
|
|
||||||
// code: `${code}/${route.code}`,
|
|
||||||
// name: route.name,
|
|
||||||
// isShow: false
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// return [...routes, ...extraRoutes]
|
|
||||||
// }
|
|
||||||
// return routes
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// const findDetailRouteItem = (code: string, url: string): Partial<MenuItem> | null => {
|
|
||||||
// const detailComponent = resolveComponent(`${code}/Detail`)
|
|
||||||
// if (detailComponent) {
|
|
||||||
// return {
|
|
||||||
// url: `${url}/detail/:id`,
|
|
||||||
// code: `${code}/Detail`,
|
|
||||||
// component: detailComponent,
|
|
||||||
// name: '详情信息',
|
|
||||||
// isShow: false
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return null
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// const findDetailRoutes = (routes: any[]): any[] => {
|
|
||||||
// const newRoutes: any[] = []
|
|
||||||
// routes.forEach((route: any) => {
|
|
||||||
// newRoutes.push(route)
|
|
||||||
// const detail = findDetailRouteItem(route.code, route.url)
|
|
||||||
// if (detail) {
|
|
||||||
// newRoutes.push(detail)
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// return newRoutes
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// const filterMenus = ['device/DashBoard']
|
|
||||||
// export const filterCommunityMenus = (menuData: any[]) => {
|
|
||||||
// return menuData.filter(item => {
|
|
||||||
// if (item.children) {
|
|
||||||
// item.children = filterCommunityMenus(item.children)
|
|
||||||
// }
|
|
||||||
// return !filterMenus.includes(item.code)
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// export const findCodeRoute = (asyncRouterMap: any[]) => {
|
|
||||||
// const routeMeta = {}
|
|
||||||
//
|
|
||||||
// function getDetail(code: string, url: string) {
|
|
||||||
// const detail = findDetailRouteItem(code, url)
|
|
||||||
// if (!detail) return
|
|
||||||
//
|
|
||||||
// routeMeta[(detail as MenuItem).code] = {
|
|
||||||
// path: detail.url,
|
|
||||||
// title: detail.name,
|
|
||||||
// parentName: code,
|
|
||||||
// buttons: detail.buttons?.map((b: any) => b.id) || []
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// function findChildren(data: any[], code: string = '') {
|
|
||||||
// data.forEach(route => {
|
|
||||||
// routeMeta[route.code] = {
|
|
||||||
// path: route.url || route.path,
|
|
||||||
// title: route.meta?.title || route.name,
|
|
||||||
// parentName: code,
|
|
||||||
// buttons: route.buttons?.map((b: any) => b.id) || []
|
|
||||||
// }
|
|
||||||
// const otherRoutes = extraRouteObj[route.code]
|
|
||||||
//
|
|
||||||
// if (otherRoutes) {
|
|
||||||
// otherRoutes.children.map((item: any) => {
|
|
||||||
// const _code = `${route.code}/${item.code}`
|
|
||||||
// const url = `${route.url}/${item.code}`
|
|
||||||
// routeMeta[_code] = {
|
|
||||||
// path: `${route.url}/${item.code}`,
|
|
||||||
// title: item.name,
|
|
||||||
// parentName: route.code,
|
|
||||||
// buttons: item.buttons?.map((b: any) => b.id) || []
|
|
||||||
// }
|
|
||||||
// getDetail(_code, url)
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
// const _code = route.appId ? `/${route.appId}${route.url}` : route.code
|
|
||||||
// if (!route.appId) {
|
|
||||||
// getDetail(_code, route.url)
|
|
||||||
// } else {
|
|
||||||
// routeMeta[_code] = {
|
|
||||||
// path: `/${route.appId}${route.url}`,
|
|
||||||
// title: route.name,
|
|
||||||
// parentName: code,
|
|
||||||
// buttons: []
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (route.children) {
|
|
||||||
// findChildren(route.children, _code)
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// findChildren(asyncRouterMap)
|
|
||||||
//
|
|
||||||
// return routeMeta
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// export function filterAsyncRouter(asyncRouterMap: any, parentCode = '', level = 1): { menusData: any, silderMenus: any } {
|
|
||||||
// const _asyncRouterMap = cloneDeep(asyncRouterMap)
|
|
||||||
// const menusData: any[] = []
|
|
||||||
// const silderMenus: any[] = []
|
|
||||||
// _asyncRouterMap.forEach((route: any) => {
|
|
||||||
// const hasAppId = route.appId
|
|
||||||
// const _route: any = {
|
|
||||||
// path: hasAppId ? `/${route.appId}${route.url}` : `${route.url}`,
|
|
||||||
// name: hasAppId ? `/${route.appId}${route.url}` : route.code,
|
|
||||||
// url: hasAppId ? `/${route.appId}${route.url}` : route.url,
|
|
||||||
// meta: {
|
|
||||||
// icon: route.icon,
|
|
||||||
// title: route.name,
|
|
||||||
// hideInMenu: route.isShow === false,
|
|
||||||
// buttons: route.buttons?.map((b: any) => b.id) || [],
|
|
||||||
// isApp: hasAppId,
|
|
||||||
// },
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// const silder = { ..._route }
|
|
||||||
// // 查看是否有隐藏子路由
|
|
||||||
// route.children = findChildrenRoute(route.code, route.url, route.children)
|
|
||||||
// route.children = findDetailRoutes(route.children)
|
|
||||||
// if (route.children && route.children.length) {
|
|
||||||
// // TODO 查看是否具有详情页
|
|
||||||
// const { menusData: _menusData, silderMenus: _silderMenus } = filterAsyncRouter(route.children, `${parentCode}/${route.code}`, level + 1)
|
|
||||||
// _route.children = _menusData
|
|
||||||
// silder.children = _silderMenus
|
|
||||||
// const showChildren = _route.children.some((r: any) => !r.meta.hideInMenu)
|
|
||||||
//
|
|
||||||
// if (showChildren && _route.children.length) {
|
|
||||||
// _route.component = level === 1 ? BasicLayoutPage : BlankLayoutPage
|
|
||||||
// _route.redirect = _route.children[0].url
|
|
||||||
// } else {
|
|
||||||
// const myComponent = resolveComponent(route.code)
|
|
||||||
// // _route.component = myComponent ? myComponent : BlankLayoutPage;
|
|
||||||
// if (!!myComponent) {
|
|
||||||
// _route.component = myComponent;
|
|
||||||
// _route.children.map((r: any) => menusData.push(r))
|
|
||||||
// delete _route.children
|
|
||||||
// } else {
|
|
||||||
// _route.component = BlankLayoutPage
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// if (hasAppId) {
|
|
||||||
// _route.component = route.component || resolveComponent('iframe')
|
|
||||||
// } else {
|
|
||||||
// _route.component = route.component || resolveComponent(route.code) || BlankLayoutPage
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// menusData.push(_route)
|
|
||||||
// silderMenus.push(silder)
|
|
||||||
// })
|
|
||||||
// return {
|
|
||||||
// menusData,
|
|
||||||
// silderMenus,
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
import { shallowRef } from 'vue'
|
|
||||||
|
|
||||||
type Buttons = Array<{ id: string }>
|
type Buttons = Array<{ id: string }>
|
||||||
|
|
||||||
const hasAppID = (item: { appId?: string, url?: string }): { isApp: boolean, appUrl: string } => {
|
const hasAppID = (item: { appId?: string, url?: string }): { isApp: boolean, appUrl: string } => {
|
||||||
|
@ -367,6 +182,12 @@ const handleMeta = (item: MenuItem, isApp: boolean) => {
|
||||||
const findComponents = (code: string, level: number, isApp: boolean, components: any) => {
|
const findComponents = (code: string, level: number, isApp: boolean, components: any) => {
|
||||||
const myComponents = components[code]
|
const myComponents = components[code]
|
||||||
if (level === 1) { // BasicLayoutPage
|
if (level === 1) { // BasicLayoutPage
|
||||||
|
if (myComponents) {
|
||||||
|
return h(BasicLayoutPage, {}, () => [h(defineAsyncComponent(() => myComponents()), {})])
|
||||||
|
}
|
||||||
|
if (isApp) {
|
||||||
|
return h(BasicLayoutPage, {}, () => [h(Iframe, {})])
|
||||||
|
}
|
||||||
return myComponents ? () => myComponents() : BasicLayoutPage
|
return myComponents ? () => myComponents() : BasicLayoutPage
|
||||||
} else if (isApp){ // iframe
|
} else if (isApp){ // iframe
|
||||||
return Iframe
|
return Iframe
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { LoginPath } from '@/router/menu'
|
||||||
import { cleanToken, getToken, LocalStore } from '@/utils/comm'
|
import { cleanToken, getToken, LocalStore } from '@/utils/comm'
|
||||||
import type { AxiosInstance, AxiosResponse } from 'axios'
|
import type { AxiosInstance, AxiosResponse } from 'axios'
|
||||||
|
|
||||||
interface AxiosResponseRewrite<T = any[]> extends AxiosResponse<T, any> {
|
export interface AxiosResponseRewrite<T = any[]> extends AxiosResponse<T, any> {
|
||||||
result: T
|
result: T
|
||||||
success: boolean
|
success: boolean
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,19 +20,29 @@ const handle = async (appId: string, url: string) => {
|
||||||
const res = await getAppInfo_api(appId);
|
const res = await getAppInfo_api(appId);
|
||||||
let menuUrl: any = url;
|
let menuUrl: any = url;
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
if (res.result.page.routeType === 'hash') {
|
const result = res.result
|
||||||
menuUrl = `#${url}`;
|
if (result.page.routeType === 'hash') {
|
||||||
|
menuUrl = url.startsWith('/') ? `#${url}` : `#/${url}`;
|
||||||
}
|
}
|
||||||
if (res.result.provider === 'internal-standalone') {
|
|
||||||
const urlStandalone = `${res.result.page.baseUrl}/api/application/sso/${appId}/login?redirect=${menuUrl}?layout=false`;
|
if (result.page.parameters) {
|
||||||
|
const params = new URLSearchParams()
|
||||||
|
result.page.parameters.forEach((item: any) => {
|
||||||
|
params.set(item.key,item.value)
|
||||||
|
})
|
||||||
|
menuUrl += `?${params.toString()}`
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.provider === 'internal-standalone') {
|
||||||
|
const urlStandalone = `${result.page.baseUrl}/api/application/sso/${appId}/login?redirect=${menuUrl}?layout=false`;
|
||||||
iframeUrl.value = urlStandalone;
|
iframeUrl.value = urlStandalone;
|
||||||
} else if (res.result.provider === 'internal-integrated') {
|
} else if (result.provider === 'internal-integrated') {
|
||||||
const tokenUrl = `${
|
const tokenUrl = `${
|
||||||
res.result.page.baseUrl
|
result.page.baseUrl
|
||||||
}/${menuUrl}?layout=false&X-Access-Token=${LocalStore.get(TOKEN_KEY)}`;
|
}/${menuUrl}?layout=false&X-Access-Token=${LocalStore.get(TOKEN_KEY)}`;
|
||||||
iframeUrl.value = tokenUrl;
|
iframeUrl.value = tokenUrl;
|
||||||
} else {
|
} else {
|
||||||
const urlOther = `${res.result.page.baseUrl}/${menuUrl}`;
|
const urlOther = `${result.page.baseUrl}/${menuUrl}`;
|
||||||
iframeUrl.value = urlOther;
|
iframeUrl.value = urlOther;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,12 +144,7 @@
|
||||||
|
|
||||||
<RequestTable
|
<RequestTable
|
||||||
v-model:value="form.data.page.parameters"
|
v-model:value="form.data.page.parameters"
|
||||||
value-type="select"
|
value-type="input"
|
||||||
:value-options="[
|
|
||||||
{ label: '用户ID', value: '用户ID' },
|
|
||||||
{ label: '用户名', value: '用户名' },
|
|
||||||
{ label: 'token', value: 'token' },
|
|
||||||
]"
|
|
||||||
/>
|
/>
|
||||||
</j-form-item>
|
</j-form-item>
|
||||||
</template>
|
</template>
|
||||||
|
@ -1397,12 +1392,20 @@
|
||||||
|
|
||||||
<div class="dialog">
|
<div class="dialog">
|
||||||
<MenuDialog
|
<MenuDialog
|
||||||
v-if="dialog.visible"
|
v-if="dialog.visible && dialog.current.provider !== 'third-party'"
|
||||||
v-model:visible="dialog.visible"
|
v-model:visible="dialog.visible"
|
||||||
:data="dialog.current"
|
:data="dialog.current"
|
||||||
:mode="routeQuery.id ? 'edit' : 'add'"
|
:mode="routeQuery.id ? 'edit' : 'add'"
|
||||||
@refresh="menuStory.jumpPage('system/Apply')"
|
@refresh="menuStory.jumpPage('system/Apply')"
|
||||||
/>
|
/>
|
||||||
|
<ThirdMenu
|
||||||
|
v-if="dialog.visible && dialog.current.provider === 'third-party'"
|
||||||
|
:data="dialog.current"
|
||||||
|
:mode="routeQuery.id ? 'edit' : 'add'"
|
||||||
|
mode="add"
|
||||||
|
@cancel="dialog.visible = false"
|
||||||
|
@ok="menuStory.jumpPage('system/Apply')"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -1420,6 +1423,7 @@ import {
|
||||||
import FormLabel from './FormLabel.vue';
|
import FormLabel from './FormLabel.vue';
|
||||||
import RequestTable from './RequestTable.vue';
|
import RequestTable from './RequestTable.vue';
|
||||||
import MenuDialog from '../../componenets/MenuDialog.vue';
|
import MenuDialog from '../../componenets/MenuDialog.vue';
|
||||||
|
import ThirdMenu from '../../componenets/ThirdMenu.vue';
|
||||||
import { getImage, onlyMessage } from '@/utils/comm';
|
import { getImage, onlyMessage } from '@/utils/comm';
|
||||||
import type { formType, dictType, optionsType, applyType } from '../typing';
|
import type { formType, dictType, optionsType, applyType } from '../typing';
|
||||||
import { getRoleList_api } from '@/api/system/user';
|
import { getRoleList_api } from '@/api/system/user';
|
||||||
|
|
|
@ -0,0 +1,150 @@
|
||||||
|
<template>
|
||||||
|
<j-modal
|
||||||
|
:confirmLoading="loading"
|
||||||
|
class="edit-dialog-container"
|
||||||
|
title="集成菜单"
|
||||||
|
visible
|
||||||
|
width="600px"
|
||||||
|
@cancel="cancel"
|
||||||
|
@ok="handleOk"
|
||||||
|
>
|
||||||
|
<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
|
||||||
|
/>
|
||||||
|
</j-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script name="ThirdMenu" setup>
|
||||||
|
import {getMenuTree_api, queryOwnThree} from '@/api/system/menu';
|
||||||
|
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 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 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 getBindMenuData = () => {
|
||||||
|
const id = props.data.id
|
||||||
|
|
||||||
|
run({
|
||||||
|
terms: [
|
||||||
|
{
|
||||||
|
column: 'appId',
|
||||||
|
value: id,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props.data?.id) {
|
||||||
|
getBindMenuData()
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
|
@ -0,0 +1,27 @@
|
||||||
|
export const getCheckByTree = (data: any[]): string[] => {
|
||||||
|
let keys: string[] = []
|
||||||
|
if (data.length) {
|
||||||
|
data.forEach(item => {
|
||||||
|
if (item.children) {
|
||||||
|
keys = [...getCheckByTree(item.children), ...keys]
|
||||||
|
} else {
|
||||||
|
keys.push(item.code)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return keys
|
||||||
|
}
|
||||||
|
|
||||||
|
export const filterTree = (data: any[], ids: string[]) => {
|
||||||
|
return data?.filter(item => {
|
||||||
|
delete item.id
|
||||||
|
item.options = {show: true}
|
||||||
|
if (ids.includes(item.code)) {
|
||||||
|
return true
|
||||||
|
} else if (item.children) {
|
||||||
|
item.children = filterTree(item.children, ids)
|
||||||
|
return item.children.length >0
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}) || []
|
||||||
|
}
|
|
@ -183,12 +183,19 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="dialogs">
|
<div class="dialogs">
|
||||||
<MenuDialog
|
<MenuDialog
|
||||||
v-if="dialogVisible"
|
v-if="dialogVisible && current.provider !== 'third-party'"
|
||||||
v-model:visible="dialogVisible"
|
v-model:visible="dialogVisible"
|
||||||
mode="edit"
|
mode="edit"
|
||||||
:data="current"
|
:data="current"
|
||||||
@refresh="table.refresh"
|
@refresh="table.refresh"
|
||||||
/>
|
/>
|
||||||
|
<ThirdMenu
|
||||||
|
v-if="dialogVisible && current.provider === 'third-party'"
|
||||||
|
:data="current"
|
||||||
|
mode="edit"
|
||||||
|
@cancel="dialogVisible = false"
|
||||||
|
@ok="() => { dialogVisible = false; table.refresh}"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Add v-if="visible" @close="visible = false" />
|
<Add v-if="visible" @close="visible = false" />
|
||||||
</page-container>
|
</page-container>
|
||||||
|
@ -197,6 +204,7 @@
|
||||||
<script setup lang="ts" name="Apply">
|
<script setup lang="ts" name="Apply">
|
||||||
import PermissionButton from '@/components/PermissionButton/index.vue';
|
import PermissionButton from '@/components/PermissionButton/index.vue';
|
||||||
import MenuDialog from './componenets/MenuDialog.vue';
|
import MenuDialog from './componenets/MenuDialog.vue';
|
||||||
|
import ThirdMenu from './componenets/ThirdMenu.vue'
|
||||||
import {
|
import {
|
||||||
getApplyList_api,
|
getApplyList_api,
|
||||||
changeApplyStatus_api,
|
changeApplyStatus_api,
|
||||||
|
|
|
@ -129,6 +129,20 @@
|
||||||
/>
|
/>
|
||||||
</j-form-item>
|
</j-form-item>
|
||||||
</j-col>
|
</j-col>
|
||||||
|
<j-col :span="12">
|
||||||
|
<j-form-item
|
||||||
|
label="所属应用"
|
||||||
|
name="owner"
|
||||||
|
>
|
||||||
|
<j-select
|
||||||
|
v-model:value="form.data.owner"
|
||||||
|
:options="[{ label: 'Iot', value: 'iot' }]"
|
||||||
|
allowClear
|
||||||
|
placeholder="请选择所属应用"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</j-form-item>
|
||||||
|
</j-col>
|
||||||
</j-row>
|
</j-row>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -362,6 +376,8 @@ const form = reactive({
|
||||||
const accessSupportValue = form.data.accessSupport;
|
const accessSupportValue = form.data.accessSupport;
|
||||||
const params = {
|
const params = {
|
||||||
...form.data,
|
...form.data,
|
||||||
|
owner: form.data?.owner ?? null,
|
||||||
|
options: { show: true },
|
||||||
accessSupport: {
|
accessSupport: {
|
||||||
value: accessSupportValue,
|
value: accessSupportValue,
|
||||||
label:
|
label:
|
||||||
|
@ -371,7 +387,6 @@ const form = reactive({
|
||||||
? '支持'
|
? '支持'
|
||||||
: '间接控制',
|
: '间接控制',
|
||||||
},
|
},
|
||||||
owner: 'iot',
|
|
||||||
};
|
};
|
||||||
api(params)
|
api(params)
|
||||||
.then((resp: any) => {
|
.then((resp: any) => {
|
||||||
|
@ -442,7 +457,7 @@ type assetType = {
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 5px px;
|
top: 5px;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 4px;
|
width: 4px;
|
||||||
height: calc(100% - 10px);
|
height: calc(100% - 10px);
|
||||||
|
|
|
@ -179,21 +179,17 @@ const table = reactive({
|
||||||
//过滤非集成的菜单
|
//过滤非集成的菜单
|
||||||
const item = {
|
const item = {
|
||||||
terms: [
|
terms: [
|
||||||
{
|
{
|
||||||
terms: [
|
column: 'owner',
|
||||||
{
|
termType: 'eq',
|
||||||
column: 'owner',
|
value: 'iot',
|
||||||
termType: 'eq',
|
},
|
||||||
value: 'iot',
|
{
|
||||||
},
|
column: 'owner',
|
||||||
{
|
termType: 'isnull',
|
||||||
column: 'owner',
|
value: '1',
|
||||||
termType: 'isnull',
|
type: 'or',
|
||||||
value: '1',
|
},
|
||||||
type: 'or',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
const params = {
|
const params = {
|
||||||
|
|
|
@ -3738,10 +3738,10 @@ jetlinks-store@^0.0.3:
|
||||||
resolved "https://registry.npmjs.org/jetlinks-store/-/jetlinks-store-0.0.3.tgz"
|
resolved "https://registry.npmjs.org/jetlinks-store/-/jetlinks-store-0.0.3.tgz"
|
||||||
integrity sha512-AZf/soh1hmmwjBZ00fr1emuMEydeReaI6IBTGByQYhTmK1Zd5pQAxC7WLek2snRAn/HHDgJfVz2hjditKThl6Q==
|
integrity sha512-AZf/soh1hmmwjBZ00fr1emuMEydeReaI6IBTGByQYhTmK1Zd5pQAxC7WLek2snRAn/HHDgJfVz2hjditKThl6Q==
|
||||||
|
|
||||||
jetlinks-ui-components@^1.0.34-2:
|
jetlinks-ui-components@^1.0.34-4:
|
||||||
version "1.0.34-2"
|
version "1.0.34-4"
|
||||||
resolved "https://registry.npmjs.org/jetlinks-ui-components/-/jetlinks-ui-components-1.0.34-2.tgz#8acd9f5dd4e5baa89703391620c80545c60ea98d"
|
resolved "https://registry.npmjs.org/jetlinks-ui-components/-/jetlinks-ui-components-1.0.34-4.tgz#92cfc6be685988385a489f3e924383c4831f3ed5"
|
||||||
integrity sha512-Z8/TRoJut1CuGsXXkzUYwvmKdQ1FhvXc46uK308M76Ezv4iJIGphwt1ancqVst0+WRBWoG6ps2ZsBbqCSQB7Rg==
|
integrity sha512-td+RgaBC5lQxRuDsHkCg9UEzCcSy4XikufnabVGz5IxU+UmXu+PJUjz2wo9vDe8sPSctyk/5jQU+N6GBPlp8JA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@vueuse/core" "^9.12.0"
|
"@vueuse/core" "^9.12.0"
|
||||||
"@vueuse/router" "^9.13.0"
|
"@vueuse/router" "^9.13.0"
|
||||||
|
|
Loading…
Reference in New Issue