wangrong
2026-08-30 761e5c5fa871959f60e15c971c8d83f2b53d0af5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
<script lang="ts" setup>
import noLic from './nolic.vue'
import { ref, useAttrs, onMounted } from 'vue'
import { execute, randomKey, formatArray } from './convert'
import { loadPluginApi, xpackModelApi } from '@/api/plugin'
import { useCache } from '@/hooks/web/useCache'
import { i18n } from '@/plugins/vue-i18n'
import * as Vue from 'vue'
import axios from 'axios'
import * as Pinia from 'pinia'
import router from '@/router'
import { useEmitt } from '@/hooks/web/useEmitt'
import request from '@/config/axios'
const { wsCache } = useCache()
import { isNull } from '@/utils/utils'
 
const plugin = ref()
 
const loading = ref(false)
 
const attrs = useAttrs()
 
const showNolic = () => {
  plugin.value = noLic
  loading.value = false
}
const generateRamStr = (len: number) => {
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
  let randomStr = ''
  for (var i = 0; i < len; i++) {
    randomStr += chars.charAt(Math.floor(Math.random() * chars.length))
  }
  return randomStr
}
 
const importProxy = (bytesArray: any[]) => {
  const promise = import(
    `../../../../../../../extensions/${formatArray(bytesArray[8])}/${formatArray(
      bytesArray[9]
    )}/${formatArray(bytesArray[10])}/${formatArray(bytesArray[11])}/${formatArray(
      bytesArray[12]
    )}.vue`
  )
  promise
    .then((res: any) => {
      plugin.value = res.default
    })
    .catch(e => {
      console.error(e)
      showNolic()
    })
}
 
const getModuleName = () => {
  const jsPath = window.atob(attrs.jsname.toString())
  return jsPath.split('/')[0]
}
const loadComponent = () => {
  const moduleName = getModuleName()
  loading.value = true
  const byteArray = wsCache.get(`de-plugin-proxy-${moduleName}`)
  if (byteArray) {
    importProxy(JSON.parse(byteArray))
    loading.value = false
    return
  }
  const key = generateRamStr(randomKey())
  const moduleNameKey = window.btoa(moduleName)
  const saltKey = `${key},${moduleNameKey}`
  loadPluginApi(saltKey)
    .then(response => {
      let code = response.data
      const byteArray = execute(code, key)
      storeCacheProxy(byteArray)
      importProxy(byteArray)
    })
    .catch(() => {
      emits('loadFail')
      showNolic()
    })
    .finally(() => {
      loading.value = false
    })
}
const storeCacheProxy = byteArray => {
  const result = []
  byteArray.forEach(item => {
    result.push([...item])
  })
  const moduleName = getModuleName()
  wsCache.set(`de-plugin-proxy-${moduleName}`, JSON.stringify(result))
}
const pluginProxy = ref(null)
const invokeMethod = param => {
  if (pluginProxy.value['invokeMethod']) {
    pluginProxy.value['invokeMethod'](param)
  } else {
    pluginProxy.value[param.methodName]?.(...param.args)
  }
}
 
onMounted(async () => {
  const key = 'xpack-model-distributed'
  let distributed = false
  if (wsCache.get(key) === null) {
    const res = await xpackModelApi()
    wsCache.set('xpack-model-distributed', isNull(res.data) ? 'null' : res.data)
    distributed = res.data
  } else {
    distributed = wsCache.get(key)
  }
  if (isNull(distributed)) {
    setTimeout(() => {
      emits('loadFail')
      loading.value = false
    }, 1000)
    return
  }
  if (distributed) {
    const moduleName = getModuleName()
    if (window[moduleName]) {
      const xpack = await window[moduleName].mapping[attrs.jsname]
      plugin.value = xpack.default
    } else {
      window['VueDe'] = Vue
      window['AxiosDe'] = axios
      window['PiniaDe'] = Pinia
      window['vueRouterDe'] = router
      window['MittAllDe'] = useEmitt().emitter.all
      window['I18nDe'] = i18n
      const url = `/xpackComponent/pluginStaticInfo/${moduleName}`
      request.get({ url }).then(async res => {
        new Function(res.data || res)()
        const xpack = await window[moduleName].mapping[attrs.jsname]
        plugin.value = xpack.default
      })
    }
  } else {
    loadComponent()
  }
})
 
const emits = defineEmits(['loadFail'])
defineExpose({
  invokeMethod
})
</script>
 
<template>
  <component
    :key="attrs.jsname"
    ref="pluginProxy"
    :is="plugin"
    v-loading="loading"
    v-bind="attrs"
  ></component>
</template>
 
<style lang="less" scoped></style>