feat: 新增代码生成预览抽屉

This commit is contained in:
xlsea
2024-09-07 18:27:39 +08:00
parent 9a0df2e4f3
commit c0ad0e4e4f
22 changed files with 508 additions and 52 deletions

View File

@ -2,6 +2,7 @@
import { NButton, NPopconfirm, NTooltip } from 'naive-ui';
import { useBoolean } from '@sa/hooks';
import { ref } from 'vue';
import { jsonClone } from '@sa/utils';
import {
fetchBatchDeleteGenTable,
fetchGenCode,
@ -16,12 +17,14 @@ import ButtonIcon from '@/components/custom/button-icon.vue';
import SvgIcon from '@/components/custom/svg-icon.vue';
import { useDownload } from '@/hooks/business/download';
import GenTableSearch from './modules/gen-table-search.vue';
import TableImportDrawer from './modules/table-import-drawer.vue';
import GenTableImportDrawer from './modules/gen-table-import-drawer.vue';
import GenTableOperateDrawer from './modules/gen-table-operate-drawer.vue';
import GenTablePreviewDrawer from './modules/gen-table-preview-drawer.vue';
const appStore = useAppStore();
const { zip } = useDownload();
const { bool: importVisible, setTrue: openImportVisible } = useBoolean();
const { bool: previewVisible, setTrue: openPreviewVisible } = useBoolean();
const {
columns,
@ -101,7 +104,13 @@ const {
width: 180,
render: row => (
<div class="flex-center gap-16px">
<ButtonIcon type="primary" text icon="ep:view" tooltipContent="预览" onClick={() => edit(row.tableId!)} />
<ButtonIcon
type="primary"
text
icon="ep:view"
tooltipContent="预览"
onClick={() => handlePreview(row.tableId!)}
/>
<ButtonIcon
type="primary"
text
@ -191,6 +200,12 @@ function handleImport() {
openImportVisible();
}
function handlePreview(id: CommonType.IdType) {
const findItem = data.value.find(item => item.tableId === id) || null;
editingData.value = jsonClone(findItem);
openPreviewVisible();
}
async function handleGenCode(row?: Api.Tool.GenTable) {
const tableIds = row?.tableId || checkedRowKeys.value.join(',');
if (!tableIds || tableIds === '') {
@ -203,7 +218,7 @@ async function handleGenCode(row?: Api.Tool.GenTable) {
if (error) return;
window.$message?.success('生成成功');
} else {
await zip(`/tool/gen/batchGenCode?tableIdStr=${tableIds}`, `ruoyi-${new Date().getTime()}.zip`);
zip(`/tool/gen/batchGenCode?tableIdStr=${tableIds}`, `ruoyi-${new Date().getTime()}.zip`);
}
}
@ -219,7 +234,7 @@ getDataNames();
</script>
<template>
<div class="min-h-500px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
<div class="min-h-500px flex-col-stretch gap-12px overflow-hidden lt-sm:overflow-auto">
<GenTableSearch
v-model:model="searchParams"
:options="dataNameOptions"
@ -265,15 +280,20 @@ getDataNames();
:data="data"
size="small"
:flex-height="!appStore.isMobile"
:scroll-x="962"
:scroll-x="1200"
:loading="loading"
remote
:row-key="row => row.tableId"
:pagination="mobilePagination"
class="sm:h-full"
/>
<TableImportDrawer v-model:visible="importVisible" :options="dataNameOptions" @submitted="getDataByPage" />
<GenTableImportDrawer v-model:visible="importVisible" :options="dataNameOptions" @submitted="getDataByPage" />
<GenTableOperateDrawer v-model:visible="drawerVisible" :row-data="editingData" @submitted="getDataByPage" />
<GenTablePreviewDrawer
v-model:visible="previewVisible"
:row-data="editingData"
@submitted="() => handleGenCode(editingData!)"
/>
</NCard>
</div>
</template>

View File

@ -7,7 +7,7 @@ import { useTable, useTableOperate } from '@/hooks/common/table';
import GenTableDbSearch from './gen-table-db-search.vue';
defineOptions({
name: 'TableImportDrawer'
name: 'GenTableImportDrawer'
});
interface Props {

View File

@ -0,0 +1,150 @@
<script setup lang="ts">
import { useLoading } from '@sa/hooks';
import { ref, watch } from 'vue';
import { fetchGetGenPreview } from '@/service/api';
import MonacoEditor from '@/components/common/monaco-editor.vue';
defineOptions({
name: 'GenTablePreviewDrawer'
});
interface Props {
/** the edit row data */
rowData?: Api.Tool.GenTable | null;
}
const props = defineProps<Props>();
interface Emits {
(e: 'submitted'): void;
}
const emit = defineEmits<Emits>();
const visible = defineModel<boolean>('visible', {
default: false
});
const tab = ref('vm/java/domain.java.vm');
const previewData = ref<Api.Tool.GenTablePreview>({});
const { loading, startLoading, endLoading } = useLoading();
async function getGenPreview() {
if (!props.rowData?.tableId) return;
startLoading();
const { data, error } = await fetchGetGenPreview(props.rowData?.tableId);
if (error) {
endLoading();
closeDrawer();
return;
}
previewData.value = data;
endLoading();
}
function closeDrawer() {
visible.value = false;
}
async function handleSubmit() {
closeDrawer();
emit('submitted');
}
watch(visible, () => {
if (visible.value) {
previewData.value = {};
getGenPreview();
}
});
const genMap: Api.Tool.GenTablePreview = {
'vm/java/domain.java.vm': 'domain.java',
'vm/java/vo.java.vm': 'vo.java',
'vm/java/bo.java.vm': 'bo.java',
'vm/java/mapper.java.vm': 'mapper.java',
'vm/java/service.java.vm': 'service.java',
'vm/java/serviceImpl.java.vm': 'serviceImpl.java',
'vm/java/controller.java.vm': 'controller.java',
'vm/xml/mapper.xml.vm': 'mapper.xml',
'vm/sql/sql.vm': 'sql',
'vm/soybean/soy.api.ts.vm': 'api.ts',
'vm/soybean/typings/soy.api.d.ts.vm': 'type.d.ts',
'vm/soybean/soy.index.vue.vm': 'index.vue'
};
function getGenLanguage(name: string) {
if (name.endsWith('.java')) {
return 'java';
}
if (name.endsWith('.xml')) {
return 'xml';
}
if (name.endsWith('sql')) {
return 'sql';
}
if (name.endsWith('.ts')) {
return 'typescript';
}
if (name.endsWith('.vue')) {
return 'html';
}
return 'plaintext';
}
</script>
<template>
<NDrawer v-model:show="visible" display-directive="show" width="100%">
<NDrawerContent title="代码预览" :native-scrollbar="false" closable>
<NSpin :show="loading" class="h-full" content-class="h-full">
<div class="flex flex-row">
<NTabs v-model:value="tab" type="line" placement="left" class="h-full" pane-class="h-full">
<NTab v-for="(gen, index) in Object.keys(genMap)" :key="index" :name="gen" display-directive="show">
{{ genMap[gen] }}
</NTab>
</NTabs>
<MonacoEditor
v-model:value="previewData[tab]"
class="tab-pane"
read-only
:language="getGenLanguage(genMap[tab])"
height="calc(100vh - 162px)"
/>
</div>
</NSpin>
<template #footer>
<NSpace :size="16">
<NButton @click="closeDrawer">{{ $t('common.cancel') }}</NButton>
<NButton :disabled="loading" type="primary" @click="handleSubmit">生成代码</NButton>
</NSpace>
</template>
</NDrawerContent>
</NDrawer>
</template>
<style scoped>
:deep(.n-drawer-body-content-wrapper) {
height: 100%;
}
:deep(.n-tabs) {
width: unset !important;
}
:deep(.n-tabs.n-tabs--left .n-tabs-bar) {
width: 5px !important;
}
.tab-pane {
transition:
color 0.3s cubic-bezier(0.4, 0, 0.2, 1),
background-color 0.3s cubic-bezier(0.4, 0, 0.2, 1),
opacity 0.2s cubic-bezier(0.4, 0, 0.2, 1);
padding-left: 12px;
}
</style>