lvkun996 2 роки тому
батько
коміт
723082a027

+ 42 - 44
package-lock.json

@@ -3245,49 +3245,6 @@
         "webpack-merge": "^5.7.3",
         "webpack-virtual-modules": "^0.4.2",
         "whatwg-fetch": "^3.6.2"
-      },
-      "dependencies": {
-        "@vue/vue-loader-v15": {
-          "version": "npm:vue-loader@15.11.1",
-          "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.11.1.tgz",
-          "integrity": "sha512-0iw4VchYLePqJfJu9s62ACWUXeSqM30SQqlIftbYWM3C+jpPcEHKSPUZBLjSF9au4HTHQ/naF6OGnO3Q/qGR3Q==",
-          "dev": true,
-          "requires": {
-            "@vue/component-compiler-utils": "^3.1.0",
-            "hash-sum": "^1.0.2",
-            "loader-utils": "^1.1.0",
-            "vue-hot-reload-api": "^2.3.0",
-            "vue-style-loader": "^4.1.0"
-          },
-          "dependencies": {
-            "hash-sum": {
-              "version": "1.0.2",
-              "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz",
-              "integrity": "sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==",
-              "dev": true
-            }
-          }
-        },
-        "json5": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
-          "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
-          "dev": true,
-          "requires": {
-            "minimist": "^1.2.0"
-          }
-        },
-        "loader-utils": {
-          "version": "1.4.2",
-          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz",
-          "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==",
-          "dev": true,
-          "requires": {
-            "big.js": "^5.2.2",
-            "emojis-list": "^3.0.0",
-            "json5": "^1.0.1"
-          }
-        }
       }
     },
     "@vue/cli-shared-utils": {
@@ -3542,6 +3499,47 @@
       "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.3.4.tgz",
       "integrity": "sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ=="
     },
+    "@vue/vue-loader-v15": {
+      "version": "npm:vue-loader@15.11.1",
+      "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.11.1.tgz",
+      "integrity": "sha512-0iw4VchYLePqJfJu9s62ACWUXeSqM30SQqlIftbYWM3C+jpPcEHKSPUZBLjSF9au4HTHQ/naF6OGnO3Q/qGR3Q==",
+      "dev": true,
+      "requires": {
+        "@vue/component-compiler-utils": "^3.1.0",
+        "hash-sum": "^1.0.2",
+        "loader-utils": "^1.1.0",
+        "vue-hot-reload-api": "^2.3.0",
+        "vue-style-loader": "^4.1.0"
+      },
+      "dependencies": {
+        "hash-sum": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz",
+          "integrity": "sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==",
+          "dev": true
+        },
+        "json5": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
+          "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
+          "dev": true,
+          "requires": {
+            "minimist": "^1.2.0"
+          }
+        },
+        "loader-utils": {
+          "version": "1.4.2",
+          "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz",
+          "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==",
+          "dev": true,
+          "requires": {
+            "big.js": "^5.2.2",
+            "emojis-list": "^3.0.0",
+            "json5": "^1.0.1"
+          }
+        }
+      }
+    },
     "@vue/web-component-wrapper": {
       "version": "1.3.0",
       "resolved": "https://registry.npmmirror.com/@vue/web-component-wrapper/-/web-component-wrapper-1.3.0.tgz",
@@ -11550,7 +11548,7 @@
     },
     "vue-hot-reload-api": {
       "version": "2.3.4",
-      "resolved": "https://registry.npmmirror.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz",
+      "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz",
       "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==",
       "dev": true
     },

+ 3 - 3
package.json

@@ -1,9 +1,9 @@
 {
-  "name": "jiaolongcloud",
+  "name": "cloudlink",
   "version": "0.1.0",
   "private": true,
   "main": "plugins/electron.js",
-  "description": "jiaolongcloud",
+  "description": "cloudlink",
   "scripts": {
     "serve": "vue-cli-service serve",
     "build": "vue-cli-service build",
@@ -16,7 +16,7 @@
   },
   "dependencies": {
     "@ant-design/icons-vue": "^6.1.0",
-    "@codemirror/lang-javascript": "^6.1.7",
+    "@codemirror/lang-javascript": "^6.1.7", 
     "@codemirror/lang-sql": "^6.5.4",
     "@codemirror/lang-vue": "^0.1.1",
     "@codemirror/theme-one-dark": "^6.1.2",

+ 1 - 1
public/index.html

@@ -34,7 +34,7 @@
       <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
     </noscript>
 
-    <div id="app">
+    <div id="cloudlink-ui">
     </div>
 
     <script>

+ 6 - 1
src/global.d.ts

@@ -1,7 +1,12 @@
-declare const window: Window & typeof globalThis & {flv: any}
+declare const window: Window & typeof globalThis & {flv: any, a: any}
 declare module '@vue-js-cron/ant'
 declare module 'flicker-vue-hooks'
 
+interface Window {
+  __POWERED_BY_QIANKUN__?: boolean;
+  __INJECTED_PUBLIC_PATH_BY_QIANKUN__?: any
+}
+
 interface Object {
  /**
   * @description  Map数据格式转为数组

+ 2 - 0
src/hooks/effect.ts

@@ -106,3 +106,5 @@ export const useModule = () => {
     path: route.matched[0].path
   }
 }
+
+export const useIsMicro = () => !!window.__POWERED_BY_QIANKUN__

+ 0 - 1
src/layout/components/Sidebar/SidebarItem.vue

@@ -50,7 +50,6 @@ const changeRoute = (route: ROUTER.RoutesProps) => {
     window.open(route.path)
   } else {
     console.log('route.path:', route.path)
-
     RootRouter.push(route.path)
   }
 }

+ 4 - 1
src/layout/components/Sidebar/index.vue

@@ -74,6 +74,7 @@ import { useDeviceType } from '@/hooks'
 import { RightOutlined } from '@ant-design/icons-vue'
 import { routes } from '@/router/index'
 import AppConfig from 'AppConfig'
+import { useIsMicro } from '@/hooks/effect'
 
 const designStore = useDesignStore()
 
@@ -97,10 +98,12 @@ const openKeys = ref<string[]>()
 
 const drawerVisible = ref<boolean>(false)
 
+const compatibleRoutes = !useIsMicro() ? router.getRoutes().filter(item => item.path !== '/cloudlink') : router.getRoutes()
+
 watch(
   () => route.path,
   () => {
-    sidebarRoute.value = isMobile ? routes : router.getRoutes().find(item => item.path === route.matched[0].path)?.children
+    sidebarRoute.value = isMobile ? routes : router.getRoutes().find(item => item.path === route.matched[useIsMicro() ? 1 : 0].path)?.children
     selectedKeys.value = [route.path]
     openKeys.value = [route.matched[1].path]
   },

+ 5 - 11
src/layout/layout.vue

@@ -1,14 +1,14 @@
 <template>
-    <a-layout class="a-layout" >
+  <RouterView v-if="isMicro" ></RouterView>
+    <a-layout class="a-layout" v-else  >
       <a-layout >
-
         <SiderBar />
         <span style="width: 100%;" >
           <Navbar />
           <div class="content" id="content"  >
             <!-- <RouterTravel /> -->
             <div class="router-view" >
-              <RouterView :key="useRouterTravel.keyCount" ></RouterView>
+              <RouterView ></RouterView>
             </div>
           </div>
         </span>
@@ -19,15 +19,9 @@
 <script  lang="ts" setup >
 import Navbar from './navbar.vue'
 import SiderBar from './components/Sidebar/index.vue'
-import RouterTravel from './routerTravel.vue'
-import { useRouterTravelStore } from '@/store'
-import { onMounted } from 'vue'
-
-const useRouterTravel = useRouterTravelStore()
-
-onMounted(() => {
+import { useIsMicro } from '@/hooks/effect'
 
-})
+const isMicro = useIsMicro()
 
 </script>
 

+ 2 - 1
src/layout/navbar.vue

@@ -66,6 +66,7 @@ import search from './components/search/index.vue'
 import { DesktopOutlined } from '@ant-design/icons-vue'
 import { message } from 'ant-design-vue'
 import AppConfig from 'AppConfig'
+import { useIsMicro } from '@/hooks/effect'
 
 const route = useRoute()
 
@@ -73,7 +74,7 @@ const router = useRouter()
 
 const appRouter = useAppRouter()
 
-const selectedKeys = ref<string[]>([route.matched[0].path])
+const selectedKeys = ref<string[]>([route.matched[useIsMicro() ? 1 : 0].path])
 
 const designStore = useDesignStore()
 

+ 40 - 5
src/main.ts

@@ -1,6 +1,7 @@
+import './public-path'
 import { createApp } from 'vue'
 import App from './App.vue'
-import router from './router'
+import router, { routes } from './router'
 import '@/router/before'
 import { createPinia } from 'pinia'
 import antd from 'ant-design-vue'
@@ -17,15 +18,15 @@ const pinia = createPinia()
 pinia.use(piniaPluginPersistedstate)
 
 const app = createApp(App)
-app
-  .use(router)
+app.use(router)
   .use(pinia)
   .use(antd)
   .use(UsePro)
   .use(cronAnt)
   .directive('keyboard', keyboard)
   .provide('useStaticImg', assets)
-  .mount('#app')
+  // .mount('#cloudlink-ui')
+  // .mount('#cloudlink-ui')
 
 // `trace` 是组件层级结构的追踪
 app.config.warnHandler = (msg, instance, trace) => {
@@ -47,7 +48,6 @@ window.Map.prototype.toArray = function () {
 window.Array.prototype.toMap = function (key: string, valueKey?: string): Map<string, any> {
   if (this && typeof this[0] !== 'object') throw new Error('仅支持Record<string, any>[]格式的数组')
   else if (this == null || this === undefined) return this
-
   const _map = new Map()
   this.forEach(item => {
     _map.set(item[key], valueKey ? item[valueKey] : item)
@@ -55,3 +55,38 @@ window.Array.prototype.toMap = function (key: string, valueKey?: string): Map<st
 
   return _map
 }
+
+let _router = router
+let instance
+
+const render = (props: any = {}) => {
+  const { container, data } = props
+
+  if (window.__POWERED_BY_QIANKUN__) {
+    console.log('父应用的data:', data.store.useJLYAppRouter().count)
+    data.store.useJLYAppRouter().setChildrenSiderRoutes(routes.map(item => item.children).filter(_ => !!_))
+  }
+
+  instance = app.mount(container ? container.querySelector('#cloudlink-ui') : '#cloudlink-ui') as any
+}
+
+/** eslint-disable */
+if (!window.__POWERED_BY_QIANKUN__) {
+  render()
+}
+
+export async function bootstrap () {
+  console.log('vue app bootstraped')
+}
+
+export async function mount (props) {
+  console.log('props from main framework', props.data)
+  render(props)
+}
+
+export async function unmount () {
+  instance.$destroy()
+  instance.$el.innerHTML = ''
+  instance = null
+  _router = null as any
+}

+ 6 - 0
src/public-path.ts

@@ -0,0 +1,6 @@
+/* eslint-disable camelcase */
+if (window.__POWERED_BY_QIANKUN__) {
+  /** eslint-disable */
+  // eslint-disable-next-line no-undef
+  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
+}

+ 25 - 13
src/router/index.ts

@@ -1,4 +1,5 @@
-import vueRouter, { NavigationFailure, RouteRecordRaw, createRouter, createWebHistory } from 'vue-router'
+import { useIsMicro } from '@/hooks/effect'
+import vueRouter, { NavigationFailure, RouteRecordRaw, createRouter, createWebHistory, RouterView } from 'vue-router'
 
 const iot = {
   path: '/iot',
@@ -428,7 +429,7 @@ const cvs = {
   ]
 }
 
-const _routes = [iot, cvs, view] as any
+const _routes = [iot, cvs] as any
 
 if (_routes[0].link) {
   window.open(_routes[0].path)
@@ -443,19 +444,30 @@ const redirectRoutes = {
   redirect: _routes[0].redirect
 }
 
-export const routes: Array<ROUTER.RoutesProps> = [redirectRoutes, ..._routes, login]
+export const routes: Array<ROUTER.RoutesProps> = [redirectRoutes, ..._routes, login].map(item => {
+  const _item = item.link
+    ? {
+        ...item,
+        path: '/' + item.path
+      }
+    : item
+  return _item
+})
+
+const microRouter = useIsMicro()
+  ? [
+      {
+        path: '/cloudlink',
+        name: 'cloudlink',
+        component: RouterView,
+        children: routes
+      }
+    ]
+  : routes
 
 const router = createRouter({
-  history: createWebHistory(process.env.BASE_URL),
-  routes: routes.map(item => {
-    const _item = item.link
-      ? {
-          ...item,
-          path: '/' + item.path
-        }
-      : item
-    return _item
-  })
+  history: createWebHistory(window.__POWERED_BY_QIANKUN__ ? '/cloudlink' : '/'),
+  routes: microRouter
 })
 
 export default router

+ 0 - 1
src/service/request.ts

@@ -32,7 +32,6 @@ const redirectUrl = () => {
 
 instance.interceptors.request.use(config => {
   config.headers.Authentication = useUserStore().userInfo.token
-
   return config
 }, function (error) {
   return Promise.reject(error)

+ 4 - 2
src/store/router.ts

@@ -19,8 +19,10 @@ const initAppRouterState: ROUTER.RouterRecords = {
 export const useAppRouter = defineStore(ConstantStore.ROUTER, () => {
   const appRouter = reactive<ROUTER.RouterRecords>(initAppRouterState)
 
+  const routes = window.__POWERED_BY_QIANKUN__ ? RootRouter.options.routes[0].children : RootRouter.options.routes
+
   const initAppRouter = () => {
-    appRouter.navbar.route = RootRouter.options.routes.map((route: any) => {
+    appRouter.navbar.route = routes!.map((route: any) => {
       return {
         path: route.link ? route.path.substr(1) : route.path,
         name: route.name,
@@ -29,7 +31,7 @@ export const useAppRouter = defineStore(ConstantStore.ROUTER, () => {
       }
     }).filter(_ => _.path !== '/login')
 
-    appRouter.sider.route = RootRouter.options.routes[1].children!
+    appRouter.sider.route = routes![1].children!
   }
 
   if (appRouter.navbar.route.length === 0) {

+ 1 - 1
tsconfig.json

@@ -37,7 +37,7 @@
     "src/**/*.tsx",
     "src/**/*.vue",
     "tests/**/*.ts",
-    "tests/**/*.tsx",
+    "tests/**/*.tsx", "src/public-path.ts",
     
   ],
   "exclude": [

+ 14 - 2
vue.config.js

@@ -3,11 +3,17 @@ const proxy = require('./config/proxy.ts')
 const path = require('path')
 const { resolve } = require('path')
 const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
+const packageName = require('./package.json').name
+
 module.exports = defineConfig({
   // publicPath: '',
   transpileDependencies: true,
   devServer: {
-    proxy: proxy.dev
+    proxy: proxy.dev,
+    headers: {
+      'Access-Control-Allow-Origin': '*'
+    },
+    port: 10800
   },
   pluginOptions: {
     'style-resources-loader': {
@@ -27,7 +33,13 @@ module.exports = defineConfig({
   configureWebpack: {
     plugins: [
       // new BundleAnalyzerPlugin()
-    ]
+    ],
+    output: {
+      library: `${packageName}`,
+      libraryTarget: 'umd',
+      // libraryTarget: 'window',
+      chunkLoadingGlobal: `webpackJsonp_${packageName}`
+    }
   },
   css: {
     loaderOptions: {