|
|
|
<template>
|
|
|
|
<BasicModal v-bind="$attrs" :defaultFullscreen="true" @register="registerModal" title="预览代码">
|
|
|
|
<div class="flex">
|
|
|
|
<Card class="w-1/4">
|
|
|
|
<BasicTree
|
|
|
|
title="文件夹列表"
|
|
|
|
toolbar
|
|
|
|
treeWrapperClassName="h-[calc(100%-35px)] overflow-auto"
|
|
|
|
:clickRowToExpand="false"
|
|
|
|
:treeData="fileTree"
|
|
|
|
:fieldNames="{ key: 'id', title: 'label' }"
|
|
|
|
@select="handleSelect"
|
|
|
|
/>
|
|
|
|
</Card>
|
|
|
|
<Card class="w-3/4">
|
|
|
|
<Tabs v-model:activeKey="activeKey">
|
|
|
|
<TabPane v-for="item in previewCodes" :key="item.filePath" :tab="item.filePath.substring(item.filePath.lastIndexOf('/') + 1)">
|
|
|
|
<a-button type="link" style="float: right" @click="copy(item.code)">复制</a-button>
|
|
|
|
<pre>{{ item.code }}</pre>
|
|
|
|
</TabPane>
|
|
|
|
</Tabs>
|
|
|
|
</Card>
|
|
|
|
</div>
|
|
|
|
</BasicModal>
|
|
|
|
</template>
|
|
|
|
<script lang="ts" setup name="PreviewModal">
|
|
|
|
import { ref, unref } from 'vue'
|
|
|
|
import { Card, Tabs } from 'ant-design-vue'
|
|
|
|
import { BasicTree } from '@/components/Tree'
|
|
|
|
import { BasicModal, useModalInner } from '@/components/Modal'
|
|
|
|
import { previewCodegen } from '@/api/infra/codegen'
|
|
|
|
import { CodegenPreviewVO } from '@/api/infra/codegen/types'
|
|
|
|
import { handleTree2 } from '@/utils/tree'
|
|
|
|
import { useClipboard } from '@vueuse/core'
|
|
|
|
import { useMessage } from '@/hooks/web/useMessage'
|
|
|
|
|
|
|
|
const TabPane = Tabs.TabPane
|
|
|
|
|
|
|
|
const { createMessage } = useMessage()
|
|
|
|
|
|
|
|
const fileTree = ref([])
|
|
|
|
const activeKey = ref('')
|
|
|
|
const previewCodes = ref<CodegenPreviewVO[]>()
|
|
|
|
|
|
|
|
const [registerModal, { setModalProps }] = useModalInner(async (data) => {
|
|
|
|
setModalProps({ confirmLoading: false })
|
|
|
|
|
|
|
|
const res = await previewCodegen(data.record.id)
|
|
|
|
let 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) {
|
|
|
|
let exists = {} // key:file 的 id;value:true
|
|
|
|
let files: filesType[] = []
|
|
|
|
// 遍历每个元素
|
|
|
|
for (const data of datas) {
|
|
|
|
let paths = data.filePath.split('/')
|
|
|
|
let fullPath = '' // 从头开始的路径,用于生成 id
|
|
|
|
// 特殊处理 java 文件
|
|
|
|
if (paths[paths.length - 1].indexOf('.java') >= 0) {
|
|
|
|
let 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 中,则跳过
|
|
|
|
let 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>
|