You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
 
 
 
 
 
 

144 lines
4.4 KiB

<script lang="ts" setup>
import { ref, unref } from 'vue'
import { Card, Tabs } from 'ant-design-vue'
import { useClipboard } from '@vueuse/core'
import { BasicTree } from '@/components/Tree'
import { BasicModal, useModalInner } from '@/components/Modal'
import { CodeEditor, MODE } from '@/components/CodeEditor'
import { previewCodegen } from '@/api/infra/codegen'
import type { CodegenPreviewVO } from '@/api/infra/codegen/types'
import { handleTree2 } from '@/utils/tree'
import { useMessage } from '@/hooks/web/useMessage'
defineOptions({ name: 'InfraPreviewModal' })
const { createMessage } = useMessage()
const fileTree = ref([])
const activeKey = ref('')
const modeValue = ref(MODE.JS)
const previewCodes = ref<CodegenPreviewVO[]>()
const [registerModal, { setModalProps }] = useModalInner(async (data) => {
setModalProps({ confirmLoading: false })
const res = await previewCodegen(data.record.id)
const file = handleFiles(res)
previewCodes.value = res
activeKey.value = res[0].filePath
fileTree.value = handleTree2(file, 'id', 'parentId', 'children', '/')
})
function handleSelect(keys) {
activeKey.value = keys[0]
}
/** 生成 files 目录 **/
interface filesType {
id: string
label: string
parentId: string
}
function handleFiles(datas) {
const exists = {} // key:file 的 id;value:true
const files: filesType[] = []
// 遍历每个元素
for (const data of datas) {
let paths = data.filePath.split('/')
let fullPath = '' // 从头开始的路径,用于生成 id
// 特殊处理 java 文件
if (paths[paths.length - 1].includes('.java')) {
const newPaths: string[] = []
for (let i = 0; i < paths.length; i++) {
let path = paths[i]
if (path !== 'java') {
newPaths.push(path)
continue
}
newPaths.push(path)
// 特殊处理中间的 package,进行合并
let tmp = ''
while (i < paths.length) {
path = paths[i + 1]
if (
path === 'controller'
|| path === 'convert'
|| path === 'dal'
|| path === 'enums'
|| path === 'service'
|| path === 'vo' // 下面三个,主要是兜底。可能考虑到有人改了包结构
|| path === 'mysql'
|| path === 'dataobject'
)
break
tmp = tmp ? `${tmp}.${path}` : path
i++
}
if (tmp)
newPaths.push(tmp)
}
paths = newPaths
}
// 遍历每个 path, 拼接成树
for (let i = 0; i < paths.length; i++) {
// 已经添加到 files 中,则跳过
const oldFullPath = fullPath
// 下面的 replaceAll 的原因,是因为上面包处理了,导致和 tabs 不匹配,所以 replaceAll 下
fullPath = fullPath.length === 0 ? paths[i] : `${fullPath.replaceAll('.', '/')}/${paths[i]}`
if (exists[fullPath])
continue
// 添加到 files 中
exists[fullPath] = true
files.push({
id: fullPath,
label: paths[i],
parentId: oldFullPath || '/', // "/" 为根节点
})
}
}
return files
}
/** 复制 **/
async function copy(text: string) {
const { copy, copied, isSupported } = useClipboard({ source: text })
if (!isSupported) {
createMessage.error('复制失败')
}
else {
await copy()
if (unref(copied))
createMessage.success('复制成功')
}
}
</script>
<template>
<BasicModal v-bind="$attrs" :default-fullscreen="true" title="预览代码" @register="registerModal">
<div class="flex">
<Card class="min-w-130 w-1/4">
<BasicTree
title="文件夹列表" toolbar :default-expand-all="true" tree-wrapper-class-name="h-[800px] overflow-auto"
:click-row-to-expand="false" :tree-data="fileTree" :field-names="{ key: 'id', title: 'label' }"
@select="handleSelect"
/>
</Card>
<Card class="w-3/4">
<Tabs v-model:activeKey="activeKey">
<Tabs.TabPane
v-for="item in previewCodes" :key="item.filePath"
:tab="item.filePath.substring(item.filePath.lastIndexOf('/') + 1)"
>
<a-button type="link" style="float: right; padding: 4px 60px;" @click="copy(item.code)">
复制
</a-button>
<CodeEditor class="max-h-200" :value="item.code" :mode="modeValue" :readonly="true" />
</Tabs.TabPane>
</Tabs>
</Card>
</div>
</BasicModal>
</template>