chat.ts:
import { BaseService, Service } from '../../../base'
@Service({ namespace: 'chat', url: 'learn', prefix: 'pre' })
class chat extends BaseService {
handleLoginOut(data: any) {
console.log(1)
return this.request({
url: 'http://localhost:85/api/light/user/logout',
method: 'post',
data
})
}
}
export default chat
base.ts:
import axios from 'axios'
const request = (option: any) => {
return axios(option)
}
function Service(value: { namespace?: string; url?: string; prefix?: string }) {
return function (target: any) {
target.prototype.namespace = value.namespace
if (value.url) {
target.prototype.url = value.url
}
if (value.prefix) {
target.prototype.prefix = value.prefix
}
}
}
class BaseService {
constructor(
options = {} as {
namespace?: string
url?: string
prefix?: string
}
) {
if (options?.namespace) {
// @ts-ignore
this.namespace = options.namespace
// @ts-ignore
this.url = options.url
// @ts-ignore
this.prefix = options.prefix
}
}
request(options: any = {}) {
return request(options)
}
}
export {
BaseService,
Service,
}
config.ts:
import { isFunction } from 'lodash-es'
import { BaseService } from './base'
const files = import.meta.glob('./modules/**', {
eager: true
})
let service: any
const init = (app: any) => {
if (import.meta.hot) {
let hmrData: any = import.meta.hot?.data.getData?.() || {}
import.meta.hot.data.getData = () => {
return hmrData
}
const hmr = {
data: hmrData,
setData(key: string, value: any) {
hmrData[key] = value
},
getData(key: string, defaultValue?: any) {
if (defaultValue !== undefined && !hmrData[key]) {
this.setData(key, defaultValue)
}
return hmrData[key]
}
}
const list = hmr.getData('modules', [])
const module: any = {
list,
req: Promise.resolve(),
dirs: [],
get(name: string) {
return this.list.find((e: any) => e.name === name)
},
add(data: any): void {
this.list.push(data)
},
async wait(): Promise<void> {
await this.req
}
}
for (const key in files) {
const [, , name] = key.split('/')
console.log(name) //permision
// @ts-ignore
let FilesItem = files[key]?.default
let filesItemInstance = new FilesItem()
const m = module.get(name)
const d = m || {
name,
value: null,
services: [],
directives: []
}
if (filesItemInstance) {
d.services?.push({
path: filesItemInstance.namespace,
value: filesItemInstance
})
}
if (!m) {
module.add(d)
}
}
service = hmr.getData('service', {
request: new BaseService().request
})
function createModule(app: any) {
const list = module.list.map((e: any) => {
const d = isFunction(e.value) ? e.value(app) : e.value
if (d) {
Object.assign(e, d)
}
return e
})
return {
list,
async eventLoop() {
const events: any = {}
for (let i = 0; i < list.length; i++) {
if (list[i].onLoad) {
Object.assign(events, await list[i]?.onLoad?.(events))
}
}
}
}
}
const { list: listLight } = createModule(app)
function basename(path: string): string {
let index = path.lastIndexOf('/')
index = index > -1 ? index : path.lastIndexOf('\\')
if (index < 0) {
return path
}
return path.substring(index + 1)
}
function path2Obj(list: any[]) {
const data: any = {}
list.forEach(({ path, value }) => {
const arr: string[] = path.split('/')
const parents = arr.slice(0, arr.length - 1)
const name = basename(path).replace('.ts', '')
let curr = data
parents.forEach((k) => {
if (!curr[k]) {
curr[k] = {}
}
curr = curr[k]
})
curr[name] = value
})
return data
}
function deepMerge(a: any, b: any) {
let k
for (k in b) {
a[k] = a[k] && a[k].toString() === '[object Object]' ? deepMerge(a[k], b[k]) : (a[k] = b[k])
}
return a
}
function useService(modules: any[]) {
const s = path2Obj(
modules.reduce((a, b) => {
return a.concat(...((b.services as any[]) || []))
}, [])
)
const list: any[] = []
function deep(d: any) {
if (typeof d !== 'object') {
return
}
if (d.namespace) {
const api = Array.from(new Set([...Object.getOwnPropertyNames(d.constructor.prototype)]))
.filter((e) => !['constructor', 'namespace'].includes(e))
.map((e) => {
return {
path: e
}
})
list.push({
api,
module: d.namespace.split('/')[0],
name: d.constructor.name,
prefix: d.namespace
})
} else {
for (const i in d) {
deep(d[i])
}
}
}
deep(s)
console.log(s)
deepMerge(service, s)
}
useService(listLight)
}
}
const useSystem = () => {
return {
service
}
}
export { init, useSystem }
index.vue:
<script setup>
import { onMounted } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { useSystem } from './config'
import './index.css'
const router = useRouter()
const route = useRoute()
const handleJumpPath = (path) => {
router.push(path)
}
onMounted(() => {
const { service } = useSystem()
service.chat.handleLoginOut()
})
</script>
<template>
<div>
<button @click="() => handleJumpPath('/admin')">admin</button>
</div>
</template>
main.ts:
import './assets/main.css'
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import WujieVue from 'wujie-vue3'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue'
import router from './router'
import { init } from './views/index/config'
const app = createApp(App)
app.use(createPinia())
app.use(router)
app.use(WujieVue)
app.use(ElementPlus)
init(app)
app.mount('#app')
tsconfig.app.json:
{
"extends": "@vue/tsconfig/tsconfig.dom.json",
"include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
"exclude": ["src/**/__tests__/*"],
"compilerOptions": {
"noUnusedLocals": false,
"noUnusedParameters": false,
"experimentalDecorators": true,
"composite": true,
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
}
本人并不支持这种封装方式,仅仅是整理一下
人工智能学习网站