mirror of
				https://gitee.com/hhyykk/ipms-sjy-ui.git
				synced 2025-10-31 02:08:45 +08:00 
			
		
		
		
	Vue3 重构:基础设施 -> 代码生成
This commit is contained in:
		| @@ -2,56 +2,56 @@ import request from '@/config/axios' | ||||
| import type { CodegenUpdateReqVO, CodegenCreateListReqVO } from './types' | ||||
|  | ||||
| // 查询列表代码生成表定义 | ||||
| export const getCodegenTablePageApi = (params) => { | ||||
| export const getCodegenTablePage = (params) => { | ||||
|   return request.get({ url: '/infra/codegen/table/page', params }) | ||||
| } | ||||
|  | ||||
| // 查询详情代码生成表定义 | ||||
| export const getCodegenTableApi = (id: number) => { | ||||
| export const getCodegenTable = (id: number) => { | ||||
|   return request.get({ url: '/infra/codegen/detail?tableId=' + id }) | ||||
| } | ||||
|  | ||||
| // 新增代码生成表定义 | ||||
| export const createCodegenTableApi = (data: CodegenCreateListReqVO) => { | ||||
| export const createCodegenTable = (data: CodegenCreateListReqVO) => { | ||||
|   return request.post({ url: '/infra/codegen/create', data }) | ||||
| } | ||||
|  | ||||
| // 修改代码生成表定义 | ||||
| export const updateCodegenTableApi = (data: CodegenUpdateReqVO) => { | ||||
| export const updateCodegenTable = (data: CodegenUpdateReqVO) => { | ||||
|   return request.put({ url: '/infra/codegen/update', data }) | ||||
| } | ||||
|  | ||||
| // 基于数据库的表结构,同步数据库的表和字段定义 | ||||
| export const syncCodegenFromDBApi = (id: number) => { | ||||
| export const syncCodegenFromDB = (id: number) => { | ||||
|   return request.put({ url: '/infra/codegen/sync-from-db?tableId=' + id }) | ||||
| } | ||||
|  | ||||
| // 基于 SQL 建表语句,同步数据库的表和字段定义 | ||||
| export const syncCodegenFromSQLApi = (id: number, sql: string) => { | ||||
| export const syncCodegenFromSQL = (id: number, sql: string) => { | ||||
|   return request.put({ url: '/infra/codegen/sync-from-sql?tableId=' + id + '&sql=' + sql }) | ||||
| } | ||||
|  | ||||
| // 预览生成代码 | ||||
| export const previewCodegenApi = (id: number) => { | ||||
| export const previewCodegen = (id: number) => { | ||||
|   return request.get({ url: '/infra/codegen/preview?tableId=' + id }) | ||||
| } | ||||
|  | ||||
| // 下载生成代码 | ||||
| export const downloadCodegenApi = (id: number) => { | ||||
| export const downloadCodegen = (id: number) => { | ||||
|   return request.download({ url: '/infra/codegen/download?tableId=' + id }) | ||||
| } | ||||
|  | ||||
| // 获得表定义 | ||||
| export const getSchemaTableListApi = (params) => { | ||||
| export const getSchemaTableList = (params) => { | ||||
|   return request.get({ url: '/infra/codegen/db/table/list', params }) | ||||
| } | ||||
|  | ||||
| // 基于数据库的表结构,创建代码生成器的表定义 | ||||
| export const createCodegenListApi = (data) => { | ||||
| export const createCodegenList = (data) => { | ||||
|   return request.post({ url: '/infra/codegen/create-list', data }) | ||||
| } | ||||
|  | ||||
| // 删除代码生成表定义 | ||||
| export const deleteCodegenTableApi = (id: number) => { | ||||
| export const deleteCodegenTable = (id: number) => { | ||||
|   return request.delete({ url: '/infra/codegen/delete?tableId=' + id }) | ||||
| } | ||||
|   | ||||
| @@ -52,7 +52,7 @@ export type CodegenPreviewVO = { | ||||
|   code: string | ||||
| } | ||||
| export type CodegenUpdateReqVO = { | ||||
|   table: CodegenTableVO | ||||
|   table: CodegenTableVO | any | ||||
|   columns: CodegenColumnVO[] | ||||
| } | ||||
| export type CodegenCreateListReqVO = { | ||||
|   | ||||
| @@ -298,7 +298,8 @@ export default { | ||||
|     typeUpdate: '字典类型编辑', | ||||
|     dataCreate: '字典数据新增', | ||||
|     dataUpdate: '字典数据编辑', | ||||
|     fileUpload: '上传文件' | ||||
|     fileUpload: '上传文件', | ||||
|     back: '返回' | ||||
|   }, | ||||
|   dialog: { | ||||
|     dialog: '弹窗', | ||||
|   | ||||
| @@ -1,67 +1,74 @@ | ||||
| <template> | ||||
|   <ContentWrap> | ||||
|     <ContentDetailWrap :title="title" @back="push('/infra/codegen')"> | ||||
|       <el-tabs v-model="activeName"> | ||||
|         <el-tab-pane label="基本信息" name="basicInfo"> | ||||
|           <BasicInfoForm ref="basicInfoRef" :basicInfo="tableCurrentRow" /> | ||||
|         </el-tab-pane> | ||||
|         <el-tab-pane label="字段信息" name="cloum"> | ||||
|           <CloumInfoForm ref="cloumInfoRef" :info="cloumCurrentRow" /> | ||||
|         </el-tab-pane> | ||||
|       </el-tabs> | ||||
|       <template #right> | ||||
|         <XButton | ||||
|           type="primary" | ||||
|           :title="t('action.save')" | ||||
|           :loading="loading" | ||||
|           @click="submitForm()" | ||||
|         /> | ||||
|       </template> | ||||
|     </ContentDetailWrap> | ||||
|   </ContentWrap> | ||||
|   <content-wrap v-loading="loading"> | ||||
|     <el-tabs v-model="activeName"> | ||||
|       <el-tab-pane label="基本信息" name="basicInfo"> | ||||
|         <basic-info-form ref="basicInfoRef" :table="formData.table" /> | ||||
|       </el-tab-pane> | ||||
|       <el-tab-pane label="字段信息" name="colum"> | ||||
|         <colum-info-form ref="columInfoRef" :columns="formData.columns" /> | ||||
|       </el-tab-pane> | ||||
|       <el-tab-pane label="生成信息" name="generateInfo"> | ||||
|         <generate-info-form ref="generateInfoRef" :table="formData.table" /> | ||||
|       </el-tab-pane> | ||||
|     </el-tabs> | ||||
|     <el-form label-width="100px"> | ||||
|       <el-form-item style="text-align: center; margin-left: -100px; margin-top: 10px"> | ||||
|         <el-button type="primary" @click="submitForm" :loading="submitLoading"> | ||||
|           {{ t('action.save') }} | ||||
|         </el-button> | ||||
|         <el-button @click="close">{{ t('action.back') }}</el-button> | ||||
|       </el-form-item> | ||||
|     </el-form> | ||||
|   </content-wrap> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| import { BasicInfoForm, CloumInfoForm } from './components' | ||||
| import { getCodegenTableApi, updateCodegenTableApi } from '@/api/infra/codegen' | ||||
| import { CodegenTableVO, CodegenColumnVO, CodegenUpdateReqVO } from '@/api/infra/codegen/types' | ||||
| import { BasicInfoForm, ColumInfoForm, GenerateInfoForm } from './components' | ||||
| import * as CodegenApi from '@/api/infra/codegen' | ||||
| import ContentWrap from '@/components/ContentWrap/src/ContentWrap.vue' | ||||
| import { useTagsViewStore } from '@/store/modules/tagsView' | ||||
| import { CodegenUpdateReqVO } from '@/api/infra/codegen/types' | ||||
|  | ||||
| const { t } = useI18n() // 国际化 | ||||
| const message = useMessage() // 消息弹窗 | ||||
| const { push } = useRouter() | ||||
| const { push, currentRoute } = useRouter() | ||||
| const { query } = useRoute() | ||||
| const { delView } = useTagsViewStore() | ||||
| const loading = ref(false) | ||||
| const title = ref('代码生成') | ||||
| const submitLoading = ref(false) | ||||
| const activeName = ref('basicInfo') | ||||
| const cloumInfoRef = ref(null) | ||||
| const tableCurrentRow = ref<CodegenTableVO>() | ||||
| const cloumCurrentRow = ref<CodegenColumnVO[]>([]) | ||||
| const basicInfoRef = ref<ComponentRef<typeof BasicInfoForm>>() | ||||
| const columInfoRef = ref<ComponentRef<typeof ColumInfoForm>>() | ||||
| const generateInfoRef = ref<ComponentRef<typeof GenerateInfoForm>>() | ||||
| const formData = ref<CodegenUpdateReqVO>({ | ||||
|   table: {}, | ||||
|   columns: [] | ||||
| }) | ||||
|  | ||||
| const getList = async () => { | ||||
| const getDetail = async () => { | ||||
|   const id = query.id as unknown as number | ||||
|   if (id) { | ||||
|     loading.value = true | ||||
|     // 获取表详细信息 | ||||
|     const res = await getCodegenTableApi(id) | ||||
|     title.value = '修改[ ' + res.table.tableName + ' ]生成配置' | ||||
|     tableCurrentRow.value = res.table | ||||
|     cloumCurrentRow.value = res.columns | ||||
|     formData.value = await CodegenApi.getCodegenTable(id) | ||||
|     loading.value = false | ||||
|   } | ||||
| } | ||||
| const submitForm = async () => { | ||||
|   const basicInfo = unref(basicInfoRef) | ||||
|   const basicForm = await basicInfo?.elFormRef?.validate()?.catch(() => {}) | ||||
|   if (basicForm) { | ||||
|     const basicInfoData = (await basicInfo?.getFormData()) as CodegenTableVO | ||||
|     const genTable: CodegenUpdateReqVO = { | ||||
|       table: basicInfoData, | ||||
|       columns: cloumCurrentRow.value | ||||
|     } | ||||
|     await updateCodegenTableApi(genTable) | ||||
|   if (!unref(formData)) return | ||||
|   try { | ||||
|     await unref(basicInfoRef)?.validate() | ||||
|     await unref(generateInfoRef)?.validate() | ||||
|     await CodegenApi.updateCodegenTable(unref(formData)) | ||||
|     message.success(t('common.updateSuccess')) | ||||
|     push('/infra/codegen') | ||||
|   } | ||||
|   } catch {} | ||||
| } | ||||
| /** 关闭按钮 */ | ||||
| const close = () => { | ||||
|   delView(unref(currentRoute)) | ||||
|   push('/infra/codegen') | ||||
| } | ||||
| onMounted(() => { | ||||
|   getList() | ||||
|   getDetail() | ||||
| }) | ||||
| </script> | ||||
|   | ||||
| @@ -1,183 +1,93 @@ | ||||
| <template> | ||||
|   <Form :rules="rules" @register="register" /> | ||||
|   <el-form ref="formRef" :model="formData" :rules="rules" label-width="120px"> | ||||
|     <el-row> | ||||
|       <el-col :span="12"> | ||||
|         <el-form-item label="表名称" prop="tableName"> | ||||
|           <el-input placeholder="请输入仓库名称" v-model="formData.tableName" /> | ||||
|         </el-form-item> | ||||
|       </el-col> | ||||
|       <el-col :span="12"> | ||||
|         <el-form-item label="表描述" prop="tableComment"> | ||||
|           <el-input placeholder="请输入" v-model="formData.tableComment" /> | ||||
|         </el-form-item> | ||||
|       </el-col> | ||||
|  | ||||
|       <el-col :span="12"> | ||||
|         <el-form-item prop="className"> | ||||
|           <template #label> | ||||
|             <span> | ||||
|               实体类名称 | ||||
|               <el-tooltip | ||||
|                 content="默认去除表名的前缀。如果存在重复,则需要手动添加前缀,避免 MyBatis 报 Alias 重复的问题。" | ||||
|                 placement="top" | ||||
|               > | ||||
|                 <Icon icon="ep:question-filled" class="" /> | ||||
|               </el-tooltip> | ||||
|             </span> | ||||
|           </template> | ||||
|  | ||||
|           <el-input placeholder="请输入" v-model="formData.className" /> | ||||
|         </el-form-item> | ||||
|       </el-col> | ||||
|       <el-col :span="12"> | ||||
|         <el-form-item label="作者" prop="author"> | ||||
|           <el-input placeholder="请输入" v-model="formData.author" /> | ||||
|         </el-form-item> | ||||
|       </el-col> | ||||
|       <el-col :span="24"> | ||||
|         <el-form-item label="备注" prop="remark"> | ||||
|           <el-input type="textarea" :rows="3" v-model="formData.remark" /> | ||||
|         </el-form-item> | ||||
|       </el-col> | ||||
|     </el-row> | ||||
|   </el-form> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| import { useForm } from '@/hooks/web/useForm' | ||||
| import { FormSchema } from '@/types/form' | ||||
| import { CodegenTableVO } from '@/api/infra/codegen/types' | ||||
| import { getIntDictOptions } from '@/utils/dict' | ||||
| import { listSimpleMenusApi } from '@/api/system/menu' | ||||
| import { handleTree, defaultProps } from '@/utils/tree' | ||||
| import { PropType } from 'vue' | ||||
|  | ||||
| const emits = defineEmits(['update:basicInfo']) | ||||
| const props = defineProps({ | ||||
|   basicInfo: { | ||||
|   table: { | ||||
|     type: Object as PropType<Nullable<CodegenTableVO>>, | ||||
|     default: () => null | ||||
|   } | ||||
| }) | ||||
|  | ||||
| const templateTypeOptions = getIntDictOptions(DICT_TYPE.INFRA_CODEGEN_TEMPLATE_TYPE) | ||||
| const sceneOptions = getIntDictOptions(DICT_TYPE.INFRA_CODEGEN_SCENE) | ||||
| const menuOptions = ref<any>([]) // 树形结构 | ||||
| const getTree = async () => { | ||||
|   const res = await listSimpleMenusApi() | ||||
|   menuOptions.value = handleTree(res) | ||||
| } | ||||
| const formRef = ref() | ||||
| const formData = ref({ | ||||
|   tableName: '', | ||||
|   tableComment: '', | ||||
|   className: '', | ||||
|   author: '', | ||||
|   remark: '' | ||||
| }) | ||||
|  | ||||
| const rules = reactive({ | ||||
|   tableName: [required], | ||||
|   tableComment: [required], | ||||
|   className: [required], | ||||
|   author: [required], | ||||
|   templateType: [required], | ||||
|   scene: [required], | ||||
|   moduleName: [required], | ||||
|   businessName: [required], | ||||
|   businessPackage: [required], | ||||
|   classComment: [required] | ||||
| }) | ||||
| const schema = reactive<FormSchema[]>([ | ||||
|   { | ||||
|     label: '上级菜单', | ||||
|     field: 'parentMenuId', | ||||
|     component: 'TreeSelect', | ||||
|     componentProps: { | ||||
|       data: menuOptions, | ||||
|       props: defaultProps, | ||||
|       checkStrictly: true, | ||||
|       nodeKey: 'id' | ||||
|     }, | ||||
|     labelMessage: '分配到指定菜单下,例如 系统管理', | ||||
|     colProps: { | ||||
|       span: 24 | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     label: '表名称', | ||||
|     field: 'tableName', | ||||
|     component: 'Input', | ||||
|     colProps: { | ||||
|       span: 12 | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     label: '表描述', | ||||
|     field: 'tableComment', | ||||
|     component: 'Input', | ||||
|     colProps: { | ||||
|       span: 12 | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     label: '实体类名称', | ||||
|     field: 'className', | ||||
|     component: 'Input', | ||||
|     colProps: { | ||||
|       span: 12 | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     label: '类名称', | ||||
|     field: 'className', | ||||
|     component: 'Input', | ||||
|     labelMessage: '类名称(首字母大写),例如SysUser、SysMenu、SysDictData 等等', | ||||
|     colProps: { | ||||
|       span: 12 | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     label: '生成模板', | ||||
|     field: 'templateType', | ||||
|     component: 'Select', | ||||
|     componentProps: { | ||||
|       options: templateTypeOptions | ||||
|     }, | ||||
|     colProps: { | ||||
|       span: 12 | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     label: '生成场景', | ||||
|     field: 'scene', | ||||
|     component: 'Select', | ||||
|     componentProps: { | ||||
|       options: sceneOptions | ||||
|     }, | ||||
|     colProps: { | ||||
|       span: 12 | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     label: '模块名', | ||||
|     field: 'moduleName', | ||||
|     component: 'Input', | ||||
|     labelMessage: '模块名,即一级目录,例如 system、infra、tool 等等', | ||||
|     colProps: { | ||||
|       span: 12 | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     label: '业务名', | ||||
|     field: 'businessName', | ||||
|     component: 'Input', | ||||
|     labelMessage: '业务名,即二级目录,例如 user、permission、dict 等等', | ||||
|     colProps: { | ||||
|       span: 12 | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     label: '类描述', | ||||
|     field: 'classComment', | ||||
|     component: 'Input', | ||||
|     labelMessage: '用作类描述,例如 用户', | ||||
|     colProps: { | ||||
|       span: 12 | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     label: '作者', | ||||
|     field: 'author', | ||||
|     component: 'Input', | ||||
|     colProps: { | ||||
|       span: 12 | ||||
|     } | ||||
|   }, | ||||
|   { | ||||
|     label: '备注', | ||||
|     field: 'remark', | ||||
|     component: 'Input', | ||||
|     componentProps: { | ||||
|       type: 'textarea', | ||||
|       rows: 4 | ||||
|     }, | ||||
|     colProps: { | ||||
|       span: 24 | ||||
|     } | ||||
|   } | ||||
| ]) | ||||
| const { register, methods, elFormRef } = useForm({ | ||||
|   schema | ||||
|   author: [required] | ||||
| }) | ||||
|  | ||||
| watch( | ||||
|   () => props.basicInfo, | ||||
|   (basicInfo) => { | ||||
|     if (!basicInfo) return | ||||
|     const { setValues } = methods | ||||
|     setValues(basicInfo) | ||||
|   () => props.table, | ||||
|   (table) => { | ||||
|     if (!table) return | ||||
|     formData.value = table | ||||
|   }, | ||||
|   { | ||||
|     deep: true, | ||||
|     immediate: true | ||||
|   } | ||||
| ) | ||||
| // ========== 初始化 ========== | ||||
| onMounted(async () => { | ||||
|   await getTree() | ||||
| }) | ||||
|  | ||||
| watch( | ||||
|   () => formData.value, | ||||
|   (val) => { | ||||
|     emits('update:basicInfo', val) | ||||
|   } | ||||
| ) | ||||
| defineExpose({ | ||||
|   elFormRef, | ||||
|   getFormData: methods.getFormData | ||||
|   validate: async () => unref(formRef)?.validate() | ||||
| }) | ||||
| </script> | ||||
|   | ||||
| @@ -1,137 +0,0 @@ | ||||
| <template> | ||||
|   <vxe-table | ||||
|     ref="dragTable" | ||||
|     border | ||||
|     :data="info" | ||||
|     max-height="600" | ||||
|     stripe | ||||
|     class="xtable-scrollbar" | ||||
|     :column-config="{ resizable: true }" | ||||
|   > | ||||
|     <vxe-column title="字段列名" field="columnName" fixed="left" width="10%" /> | ||||
|     <vxe-colgroup title="基础属性"> | ||||
|       <vxe-column title="字段描述" field="columnComment" width="10%"> | ||||
|         <template #default="{ row }"> | ||||
|           <vxe-input v-model="row.columnComment" placeholder="请输入字段描述" /> | ||||
|         </template> | ||||
|       </vxe-column> | ||||
|       <vxe-column title="物理类型" field="dataType" width="10%" /> | ||||
|       <vxe-column title="Java类型" width="10%" field="javaType"> | ||||
|         <template #default="{ row }"> | ||||
|           <vxe-select v-model="row.javaType" placeholder="请选择Java类型"> | ||||
|             <vxe-option label="Long" value="Long" /> | ||||
|             <vxe-option label="String" value="String" /> | ||||
|             <vxe-option label="Integer" value="Integer" /> | ||||
|             <vxe-option label="Double" value="Double" /> | ||||
|             <vxe-option label="BigDecimal" value="BigDecimal" /> | ||||
|             <vxe-option label="LocalDateTime" value="LocalDateTime" /> | ||||
|             <vxe-option label="Boolean" value="Boolean" /> | ||||
|           </vxe-select> | ||||
|         </template> | ||||
|       </vxe-column> | ||||
|       <vxe-column title="java属性" width="8%" field="javaField"> | ||||
|         <template #default="{ row }"> | ||||
|           <vxe-input v-model="row.javaField" placeholder="请输入java属性" /> | ||||
|         </template> | ||||
|       </vxe-column> | ||||
|     </vxe-colgroup> | ||||
|     <vxe-colgroup title="增删改查"> | ||||
|       <vxe-column title="插入" width="40px" field="createOperation"> | ||||
|         <template #default="{ row }"> | ||||
|           <vxe-checkbox true-label="true" false-label="false" v-model="row.createOperation" /> | ||||
|         </template> | ||||
|       </vxe-column> | ||||
|       <vxe-column title="编辑" width="40px" field="updateOperation"> | ||||
|         <template #default="{ row }"> | ||||
|           <vxe-checkbox true-label="true" false-label="false" v-model="row.updateOperation" /> | ||||
|         </template> | ||||
|       </vxe-column> | ||||
|       <vxe-column title="列表" width="40px" field="listOperationResult"> | ||||
|         <template #default="{ row }"> | ||||
|           <vxe-checkbox true-label="true" false-label="false" v-model="row.listOperationResult" /> | ||||
|         </template> | ||||
|       </vxe-column> | ||||
|       <vxe-column title="查询" width="40px" field="listOperation"> | ||||
|         <template #default="{ row }"> | ||||
|           <vxe-checkbox true-label="true" false-label="false" v-model="row.listOperation" /> | ||||
|         </template> | ||||
|       </vxe-column> | ||||
|       <vxe-column title="允许空" width="40px" field="nullable"> | ||||
|         <template #default="{ row }"> | ||||
|           <vxe-checkbox true-label="true" false-label="false" v-model="row.nullable" /> | ||||
|         </template> | ||||
|       </vxe-column> | ||||
|       <vxe-column title="查询方式" width="60px" field="listOperationCondition"> | ||||
|         <template #default="{ row }"> | ||||
|           <vxe-select v-model="row.listOperationCondition" placeholder="请选择查询方式"> | ||||
|             <vxe-option label="=" value="=" /> | ||||
|             <vxe-option label="!=" value="!=" /> | ||||
|             <vxe-option label=">" value=">" /> | ||||
|             <vxe-option label=">=" value=">=" /> | ||||
|             <vxe-option label="<" value="<>" /> | ||||
|             <vxe-option label="<=" value="<=" /> | ||||
|             <vxe-option label="LIKE" value="LIKE" /> | ||||
|             <vxe-option label="BETWEEN" value="BETWEEN" /> | ||||
|           </vxe-select> | ||||
|         </template> | ||||
|       </vxe-column> | ||||
|     </vxe-colgroup> | ||||
|     <vxe-column title="显示类型" width="10%" field="htmlType"> | ||||
|       <template #default="{ row }"> | ||||
|         <vxe-select v-model="row.htmlType" placeholder="请选择显示类型"> | ||||
|           <vxe-option label="文本框" value="input" /> | ||||
|           <vxe-option label="文本域" value="textarea" /> | ||||
|           <vxe-option label="下拉框" value="select" /> | ||||
|           <vxe-option label="单选框" value="radio" /> | ||||
|           <vxe-option label="复选框" value="checkbox" /> | ||||
|           <vxe-option label="日期控件" value="datetime" /> | ||||
|           <vxe-option label="图片上传" value="imageUpload" /> | ||||
|           <vxe-option label="文件上传" value="fileUpload" /> | ||||
|           <vxe-option label="富文本控件" value="editor" /> | ||||
|         </vxe-select> | ||||
|       </template> | ||||
|     </vxe-column> | ||||
|     <vxe-column title="字典类型" width="10%" field="dictType"> | ||||
|       <template #default="{ row }"> | ||||
|         <vxe-select v-model="row.dictType" clearable filterable placeholder="请选择字典类型"> | ||||
|           <vxe-option | ||||
|             v-for="dict in dictOptions" | ||||
|             :key="dict.id" | ||||
|             :label="dict.name" | ||||
|             :value="dict.type" | ||||
|           /> | ||||
|         </vxe-select> | ||||
|       </template> | ||||
|     </vxe-column> | ||||
|     <vxe-column title="示例" field="example"> | ||||
|       <template #default="{ row }"> | ||||
|         <vxe-input v-model="row.example" placeholder="请输入示例" /> | ||||
|       </template> | ||||
|     </vxe-column> | ||||
|   </vxe-table> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| import { PropType } from 'vue' | ||||
| import { DictTypeVO } from '@/api/system/dict/types' | ||||
| import { CodegenColumnVO } from '@/api/infra/codegen/types' | ||||
| import { listSimpleDictType } from '@/api/system/dict/dict.type' | ||||
|  | ||||
| const props = defineProps({ | ||||
|   info: { | ||||
|     type: Array as unknown as PropType<CodegenColumnVO[]>, | ||||
|     default: () => null | ||||
|   } | ||||
| }) | ||||
| /** 查询字典下拉列表 */ | ||||
| const dictOptions = ref<DictTypeVO[]>() | ||||
| const getDictOptions = async () => { | ||||
|   const res = await listSimpleDictType() | ||||
|   dictOptions.value = res | ||||
| } | ||||
| onMounted(async () => { | ||||
|   await getDictOptions() | ||||
| }) | ||||
| defineExpose({ | ||||
|   info: props.info | ||||
| }) | ||||
| </script> | ||||
							
								
								
									
										157
									
								
								src/views/infra/codegen/components/ColumInfoForm.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								src/views/infra/codegen/components/ColumInfoForm.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,157 @@ | ||||
| <template> | ||||
|   <el-table ref="dragTable" :data="formData" row-key="columnId" :max-height="tableHeight"> | ||||
|     <el-table-column | ||||
|       label="字段列名" | ||||
|       prop="columnName" | ||||
|       min-width="10%" | ||||
|       :show-overflow-tooltip="true" | ||||
|     /> | ||||
|     <el-table-column label="字段描述" min-width="10%"> | ||||
|       <template #default="scope"> | ||||
|         <el-input v-model="scope.row.columnComment" /> | ||||
|       </template> | ||||
|     </el-table-column> | ||||
|     <el-table-column | ||||
|       label="物理类型" | ||||
|       prop="dataType" | ||||
|       min-width="10%" | ||||
|       :show-overflow-tooltip="true" | ||||
|     /> | ||||
|     <el-table-column label="Java类型" min-width="11%"> | ||||
|       <template #default="scope"> | ||||
|         <el-select v-model="scope.row.javaType"> | ||||
|           <el-option label="Long" value="Long" /> | ||||
|           <el-option label="String" value="String" /> | ||||
|           <el-option label="Integer" value="Integer" /> | ||||
|           <el-option label="Double" value="Double" /> | ||||
|           <el-option label="BigDecimal" value="BigDecimal" /> | ||||
|           <el-option label="LocalDateTime" value="LocalDateTime" /> | ||||
|           <el-option label="Boolean" value="Boolean" /> | ||||
|         </el-select> | ||||
|       </template> | ||||
|     </el-table-column> | ||||
|     <el-table-column label="java属性" min-width="10%"> | ||||
|       <template #default="scope"> | ||||
|         <el-input v-model="scope.row.javaField" /> | ||||
|       </template> | ||||
|     </el-table-column> | ||||
|     <el-table-column label="插入" min-width="4%"> | ||||
|       <template #default="scope"> | ||||
|         <el-checkbox true-label="true" false-label="false" v-model="scope.row.createOperation" /> | ||||
|       </template> | ||||
|     </el-table-column> | ||||
|     <el-table-column label="编辑" min-width="4%"> | ||||
|       <template #default="scope"> | ||||
|         <el-checkbox true-label="true" false-label="false" v-model="scope.row.updateOperation" /> | ||||
|       </template> | ||||
|     </el-table-column> | ||||
|     <el-table-column label="列表" min-width="4%"> | ||||
|       <template #default="scope"> | ||||
|         <el-checkbox | ||||
|           true-label="true" | ||||
|           false-label="false" | ||||
|           v-model="scope.row.listOperationResult" | ||||
|         /> | ||||
|       </template> | ||||
|     </el-table-column> | ||||
|     <el-table-column label="查询" min-width="4%"> | ||||
|       <template #default="scope"> | ||||
|         <el-checkbox true-label="true" false-label="false" v-model="scope.row.listOperation" /> | ||||
|       </template> | ||||
|     </el-table-column> | ||||
|     <el-table-column label="查询方式" min-width="10%"> | ||||
|       <template #default="scope"> | ||||
|         <el-select v-model="scope.row.listOperationCondition"> | ||||
|           <el-option label="=" value="=" /> | ||||
|           <el-option label="!=" value="!=" /> | ||||
|           <el-option label=">" value=">" /> | ||||
|           <el-option label=">=" value=">=" /> | ||||
|           <el-option label="<" value="<>" /> | ||||
|           <el-option label="<=" value="<=" /> | ||||
|           <el-option label="LIKE" value="LIKE" /> | ||||
|           <el-option label="BETWEEN" value="BETWEEN" /> | ||||
|         </el-select> | ||||
|       </template> | ||||
|     </el-table-column> | ||||
|     <el-table-column label="允许空" min-width="5%"> | ||||
|       <template #default="scope"> | ||||
|         <el-checkbox true-label="true" false-label="false" v-model="scope.row.nullable" /> | ||||
|       </template> | ||||
|     </el-table-column> | ||||
|     <el-table-column label="显示类型" min-width="12%"> | ||||
|       <template #default="scope"> | ||||
|         <el-select v-model="scope.row.htmlType"> | ||||
|           <el-option label="文本框" value="input" /> | ||||
|           <el-option label="文本域" value="textarea" /> | ||||
|           <el-option label="下拉框" value="select" /> | ||||
|           <el-option label="单选框" value="radio" /> | ||||
|           <el-option label="复选框" value="checkbox" /> | ||||
|           <el-option label="日期控件" value="datetime" /> | ||||
|           <el-option label="图片上传" value="imageUpload" /> | ||||
|           <el-option label="文件上传" value="fileUpload" /> | ||||
|           <el-option label="富文本控件" value="editor" /> | ||||
|         </el-select> | ||||
|       </template> | ||||
|     </el-table-column> | ||||
|     <el-table-column label="字典类型" min-width="12%"> | ||||
|       <template #default="scope"> | ||||
|         <el-select v-model="scope.row.dictType" clearable filterable placeholder="请选择"> | ||||
|           <el-option | ||||
|             v-for="dict in dictOptions" | ||||
|             :key="dict.id" | ||||
|             :label="dict.name" | ||||
|             :value="dict.type" | ||||
|           /> | ||||
|         </el-select> | ||||
|       </template> | ||||
|     </el-table-column> | ||||
|     <el-table-column label="示例" min-width="10%"> | ||||
|       <template #default="scope"> | ||||
|         <el-input v-model="scope.row.example" /> | ||||
|       </template> | ||||
|     </el-table-column> | ||||
|   </el-table> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| import { PropType } from 'vue' | ||||
| import { CodegenColumnVO } from '@/api/infra/codegen/types' | ||||
| import { DictTypeVO, listSimpleDictType } from '@/api/system/dict/dict.type' | ||||
|  | ||||
| const emits = defineEmits(['update:columns']) | ||||
| const props = defineProps({ | ||||
|   columns: { | ||||
|     type: Array as unknown as PropType<CodegenColumnVO[]>, | ||||
|     default: () => null | ||||
|   } | ||||
| }) | ||||
|  | ||||
| const formData = ref<CodegenColumnVO[]>([]) | ||||
| const tableHeight = document.documentElement.scrollHeight - 350 + 'px' | ||||
|  | ||||
| /** 查询字典下拉列表 */ | ||||
| const dictOptions = ref<DictTypeVO[]>() | ||||
| const getDictOptions = async () => { | ||||
|   dictOptions.value = await listSimpleDictType() | ||||
| } | ||||
| onMounted(async () => { | ||||
|   await getDictOptions() | ||||
| }) | ||||
|  | ||||
| watch( | ||||
|   () => props.columns, | ||||
|   (columns) => { | ||||
|     if (!columns) return | ||||
|     formData.value = columns | ||||
|   }, | ||||
|   { | ||||
|     deep: true, | ||||
|     immediate: true | ||||
|   } | ||||
| ) | ||||
| watch( | ||||
|   () => formData.value, | ||||
|   (val) => { | ||||
|     emits('update:columns', val) | ||||
|   } | ||||
| ) | ||||
| </script> | ||||
							
								
								
									
										379
									
								
								src/views/infra/codegen/components/GenerateInfoForm.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										379
									
								
								src/views/infra/codegen/components/GenerateInfoForm.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,379 @@ | ||||
| <template> | ||||
|   <el-form ref="formRef" :model="formData" :rules="rules" label-width="150px"> | ||||
|     <el-row> | ||||
|       <el-col :span="12"> | ||||
|         <el-form-item prop="templateType" label="生成模板"> | ||||
|           <el-select v-model="formData.templateType" @change="tplSelectChange"> | ||||
|             <el-option | ||||
|               v-for="dict in getDictOptions(DICT_TYPE.INFRA_CODEGEN_TEMPLATE_TYPE)" | ||||
|               :key="parseInt(dict.value)" | ||||
|               :label="dict.label" | ||||
|               :value="parseInt(dict.value)" | ||||
|             /> | ||||
|           </el-select> | ||||
|         </el-form-item> | ||||
|       </el-col> | ||||
|       <el-col :span="12"> | ||||
|         <el-form-item prop="scene" label="生成场景"> | ||||
|           <el-select v-model="formData.scene"> | ||||
|             <el-option | ||||
|               v-for="dict in getDictOptions(DICT_TYPE.INFRA_CODEGEN_SCENE)" | ||||
|               :key="parseInt(dict.value)" | ||||
|               :label="dict.label" | ||||
|               :value="parseInt(dict.value)" | ||||
|             /> | ||||
|           </el-select> | ||||
|         </el-form-item> | ||||
|       </el-col> | ||||
|  | ||||
|       <!--      <el-col :span="12">--> | ||||
|       <!--        <el-form-item prop="packageName">--> | ||||
|       <!--          <span slot="label">--> | ||||
|       <!--            生成包路径--> | ||||
|       <!--            <el-tooltip content="生成在哪个java包下,例如 com.ruoyi.system" placement="top">--> | ||||
|       <!--              <i class="el-icon-question"></i>--> | ||||
|       <!--            </el-tooltip>--> | ||||
|       <!--          </span>--> | ||||
|       <!--          <el-input v-model="formData.packageName" />--> | ||||
|       <!--        </el-form-item>--> | ||||
|       <!--      </el-col>--> | ||||
|  | ||||
|       <el-col :span="12"> | ||||
|         <el-form-item prop="moduleName"> | ||||
|           <template #label> | ||||
|             <span> | ||||
|               模块名 | ||||
|               <el-tooltip | ||||
|                 content="模块名,即一级目录,例如 system、infra、tool 等等" | ||||
|                 placement="top" | ||||
|               > | ||||
|                 <Icon icon="ep:question-filled" /> | ||||
|               </el-tooltip> | ||||
|             </span> | ||||
|           </template> | ||||
|           <el-input v-model="formData.moduleName" /> | ||||
|         </el-form-item> | ||||
|       </el-col> | ||||
|  | ||||
|       <el-col :span="12"> | ||||
|         <el-form-item prop="businessName"> | ||||
|           <template #label> | ||||
|             <span> | ||||
|               业务名 | ||||
|               <el-tooltip | ||||
|                 content="业务名,即二级目录,例如 user、permission、dict 等等" | ||||
|                 placement="top" | ||||
|               > | ||||
|                 <Icon icon="ep:question-filled" /> | ||||
|               </el-tooltip> | ||||
|             </span> | ||||
|           </template> | ||||
|           <el-input v-model="formData.businessName" /> | ||||
|         </el-form-item> | ||||
|       </el-col> | ||||
|  | ||||
|       <!--      <el-col :span="12">--> | ||||
|       <!--        <el-form-item prop="businessPackage">--> | ||||
|       <!--          <span slot="label">--> | ||||
|       <!--            业务包--> | ||||
|       <!--            <el-tooltip content="业务包,自定义二级目录。例如说,我们希望将 dictType 和 dictData 归类成 dict 业务" placement="top">--> | ||||
|       <!--              <i class="el-icon-question"></i>--> | ||||
|       <!--            </el-tooltip>--> | ||||
|       <!--          </span>--> | ||||
|       <!--          <el-input v-model="formData.businessPackage" />--> | ||||
|       <!--        </el-form-item>--> | ||||
|       <!--      </el-col>--> | ||||
|  | ||||
|       <el-col :span="12"> | ||||
|         <el-form-item prop="className"> | ||||
|           <template #label> | ||||
|             <span> | ||||
|               类名称 | ||||
|               <el-tooltip | ||||
|                 content="类名称(首字母大写),例如SysUser、SysMenu、SysDictData 等等" | ||||
|                 placement="top" | ||||
|               > | ||||
|                 <Icon icon="ep:question-filled" /> | ||||
|               </el-tooltip> | ||||
|             </span> | ||||
|           </template> | ||||
|           <el-input v-model="formData.className" /> | ||||
|         </el-form-item> | ||||
|       </el-col> | ||||
|  | ||||
|       <el-col :span="12"> | ||||
|         <el-form-item prop="classComment"> | ||||
|           <template #label> | ||||
|             <span> | ||||
|               类描述 | ||||
|               <el-tooltip content="用作类描述,例如 用户" placement="top"> | ||||
|                 <Icon icon="ep:question-filled" /> | ||||
|               </el-tooltip> | ||||
|             </span> | ||||
|           </template> | ||||
|           <el-input v-model="formData.classComment" /> | ||||
|         </el-form-item> | ||||
|       </el-col> | ||||
|  | ||||
|       <el-col :span="12"> | ||||
|         <el-form-item> | ||||
|           <template #label> | ||||
|             <span> | ||||
|               上级菜单 | ||||
|               <el-tooltip content="分配到指定菜单下,例如 系统管理" placement="top"> | ||||
|                 <Icon icon="ep:question-filled" /> | ||||
|               </el-tooltip> | ||||
|             </span> | ||||
|           </template> | ||||
|           <el-tree-select | ||||
|             v-model="formData.parentMenuId" | ||||
|             placeholder="请选择系统菜单" | ||||
|             node-key="id" | ||||
|             check-strictly | ||||
|             :data="menus" | ||||
|             :props="menuTreeProps" | ||||
|           /> | ||||
|         </el-form-item> | ||||
|       </el-col> | ||||
|  | ||||
|       <el-col :span="24" v-if="formData.genType === '1'"> | ||||
|         <el-form-item prop="genPath"> | ||||
|           <template #label> | ||||
|             <span> | ||||
|               自定义路径 | ||||
|               <el-tooltip | ||||
|                 content="填写磁盘绝对路径,若不填写,则生成到当前Web项目下" | ||||
|                 placement="top" | ||||
|               > | ||||
|                 <Icon icon="ep:question-filled" /> | ||||
|               </el-tooltip> | ||||
|             </span> | ||||
|           </template> | ||||
|           <el-input v-model="formData.genPath"> | ||||
|             <template #append> | ||||
|               <el-dropdown> | ||||
|                 <el-button type="primary"> | ||||
|                   最近路径快速选择 | ||||
|                   <i class="el-icon-arrow-down el-icon--right"></i> | ||||
|                 </el-button> | ||||
|                 <template #dropdown> | ||||
|                   <el-dropdown-menu> | ||||
|                     <el-dropdown-item @click="formData.genPath = '/'"> | ||||
|                       恢复默认的生成基础路径 | ||||
|                     </el-dropdown-item> | ||||
|                   </el-dropdown-menu> | ||||
|                 </template> | ||||
|               </el-dropdown> | ||||
|             </template> | ||||
|           </el-input> | ||||
|         </el-form-item> | ||||
|       </el-col> | ||||
|     </el-row> | ||||
|  | ||||
|     <el-row v-show="formData.tplCategory === 'tree'"> | ||||
|       <h4 class="form-header">其他信息</h4> | ||||
|       <el-col :span="12"> | ||||
|         <el-form-item> | ||||
|           <template #label> | ||||
|             <span> | ||||
|               树编码字段 | ||||
|               <el-tooltip content="树显示的编码字段名, 如:dept_id" placement="top"> | ||||
|                 <Icon icon="ep:question-filled" /> | ||||
|               </el-tooltip> | ||||
|             </span> | ||||
|           </template> | ||||
|           <el-select v-model="formData.treeCode" placeholder="请选择"> | ||||
|             <el-option | ||||
|               v-for="(column, index) in formData.columns" | ||||
|               :key="index" | ||||
|               :label="column.columnName + ':' + column.columnComment" | ||||
|               :value="column.columnName" | ||||
|             /> | ||||
|           </el-select> | ||||
|         </el-form-item> | ||||
|       </el-col> | ||||
|       <el-col :span="12"> | ||||
|         <el-form-item> | ||||
|           <template #label> | ||||
|             <span> | ||||
|               树父编码字段 | ||||
|               <el-tooltip content="树显示的父编码字段名, 如:parent_Id" placement="top"> | ||||
|                 <Icon icon="ep:question-filled" /> | ||||
|               </el-tooltip> | ||||
|             </span> | ||||
|           </template> | ||||
|           <el-select v-model="formData.treeParentCode" placeholder="请选择"> | ||||
|             <el-option | ||||
|               v-for="(column, index) in formData.columns" | ||||
|               :key="index" | ||||
|               :label="column.columnName + ':' + column.columnComment" | ||||
|               :value="column.columnName" | ||||
|             /> | ||||
|           </el-select> | ||||
|         </el-form-item> | ||||
|       </el-col> | ||||
|       <el-col :span="12"> | ||||
|         <el-form-item> | ||||
|           <template #label> | ||||
|             <span> | ||||
|               树名称字段 | ||||
|               <el-tooltip content="树节点的显示名称字段名, 如:dept_name" placement="top"> | ||||
|                 <Icon icon="ep:question-filled" /> | ||||
|               </el-tooltip> | ||||
|             </span> | ||||
|           </template> | ||||
|  | ||||
|           <el-select v-model="formData.treeName" placeholder="请选择"> | ||||
|             <el-option | ||||
|               v-for="(column, index) in formData.columns" | ||||
|               :key="index" | ||||
|               :label="column.columnName + ':' + column.columnComment" | ||||
|               :value="column.columnName" | ||||
|             /> | ||||
|           </el-select> | ||||
|         </el-form-item> | ||||
|       </el-col> | ||||
|     </el-row> | ||||
|     <el-row v-show="formData.tplCategory === 'sub'"> | ||||
|       <h4 class="form-header">关联信息</h4> | ||||
|       <el-col :span="12"> | ||||
|         <el-form-item> | ||||
|           <template #label> | ||||
|             <span> | ||||
|               关联子表的表名 | ||||
|               <el-tooltip content="关联子表的表名, 如:sys_user" placement="top"> | ||||
|                 <Icon icon="ep:question-filled" /> | ||||
|               </el-tooltip> | ||||
|             </span> | ||||
|           </template> | ||||
|           <el-select v-model="formData.subTableName" placeholder="请选择" @change="subSelectChange"> | ||||
|             <el-option | ||||
|               v-for="(table0, index) in tables" | ||||
|               :key="index" | ||||
|               :label="table0.tableName + ':' + table0.tableComment" | ||||
|               :value="table0.tableName" | ||||
|             /> | ||||
|           </el-select> | ||||
|         </el-form-item> | ||||
|       </el-col> | ||||
|       <el-col :span="12"> | ||||
|         <el-form-item> | ||||
|           <template #label> | ||||
|             <span> | ||||
|               子表关联的外键名 | ||||
|               <el-tooltip content="子表关联的外键名, 如:user_id" placement="top"> | ||||
|                 <Icon icon="ep:question-filled" /> | ||||
|               </el-tooltip> | ||||
|             </span> | ||||
|           </template> | ||||
|           <el-select v-model="formData.subTableFkName" placeholder="请选择"> | ||||
|             <el-option | ||||
|               v-for="(column, index) in subColumns" | ||||
|               :key="index" | ||||
|               :label="column.columnName + ':' + column.columnComment" | ||||
|               :value="column.columnName" | ||||
|             /> | ||||
|           </el-select> | ||||
|         </el-form-item> | ||||
|       </el-col> | ||||
|     </el-row> | ||||
|   </el-form> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| import { CodegenTableVO } from '@/api/infra/codegen/types' | ||||
| import * as MenuApi from '@/api/system/menu' | ||||
| import { PropType } from 'vue' | ||||
| import { getDictOptions, DICT_TYPE } from '@/utils/dict' | ||||
| import { handleTree } from '@/utils/tree' | ||||
|  | ||||
| const message = useMessage() // 消息弹窗 | ||||
| const emits = defineEmits(['update:basicInfo']) | ||||
| const props = defineProps({ | ||||
|   table: { | ||||
|     type: Object as PropType<Nullable<CodegenTableVO>>, | ||||
|     default: () => null | ||||
|   } | ||||
| }) | ||||
|  | ||||
| const formRef = ref() | ||||
| const formData = ref({ | ||||
|   templateType: null, | ||||
|   scene: null, | ||||
|   moduleName: '', | ||||
|   businessName: '', | ||||
|   className: '', | ||||
|   classComment: '', | ||||
|   parentMenuId: null, | ||||
|   genPath: '', | ||||
|   treeCode: '', | ||||
|   treeParentCode: '', | ||||
|   treeName: '', | ||||
|   tplCategory: '', | ||||
|   subTableName: '', | ||||
|   subTableFkName: '', | ||||
|   genType: '' | ||||
| }) | ||||
|  | ||||
| const rules = reactive({ | ||||
|   templateType: [required], | ||||
|   scene: [required], | ||||
|   moduleName: [required], | ||||
|   businessName: [required], | ||||
|   businessPackage: [required], | ||||
|   className: [required], | ||||
|   classComment: [required] | ||||
| }) | ||||
|  | ||||
| const tables = ref([]) | ||||
| const subColumns = ref([]) | ||||
| const menus = ref<any[]>([]) | ||||
| const menuTreeProps = { | ||||
|   label: 'name' | ||||
| } | ||||
|  | ||||
| /** 选择子表名触发 */ | ||||
| const subSelectChange = () => { | ||||
|   formData.value.subTableFkName = '' | ||||
| } | ||||
| /** 选择生成模板触发 */ | ||||
| const tplSelectChange = (value) => { | ||||
|   if (value !== 1) { | ||||
|     // TODO 芋艿:暂时不考虑支持树形结构 | ||||
|     message.error( | ||||
|       '暂时不考虑支持【树形】和【主子表】的代码生成。原因是:导致 vm 模板过于复杂,不利于胖友二次开发' | ||||
|     ) | ||||
|     return false | ||||
|   } | ||||
|   if (value !== 'sub') { | ||||
|     formData.value.subTableName = '' | ||||
|     formData.value.subTableFkName = '' | ||||
|   } | ||||
| } | ||||
|  | ||||
| watch( | ||||
|   () => props.table, | ||||
|   (table) => { | ||||
|     if (!table) return | ||||
|     formData.value = table as any | ||||
|   }, | ||||
|   { | ||||
|     deep: true, | ||||
|     immediate: true | ||||
|   } | ||||
| ) | ||||
| watch( | ||||
|   () => formData.value, | ||||
|   (val) => { | ||||
|     emits('update:basicInfo', val) | ||||
|   } | ||||
| ) | ||||
| onMounted(async () => { | ||||
|   try { | ||||
|     const resp = await MenuApi.listSimpleMenusApi() | ||||
|     menus.value = handleTree(resp) | ||||
|   } catch {} | ||||
| }) | ||||
| defineExpose({ | ||||
|   validate: async () => unref(formRef)?.validate() | ||||
| }) | ||||
| </script> | ||||
| @@ -1,9 +1,8 @@ | ||||
| <template> | ||||
|   <!-- 导入表 --> | ||||
|   <XModal title="导入表" v-model="visible"> | ||||
|     <el-form :model="queryParams" ref="queryRef" :inline="true"> | ||||
|   <Dialog :title="modelTitle" v-model="modelVisible"> | ||||
|     <el-form :model="queryParams" ref="queryFormRef" :inline="true"> | ||||
|       <el-form-item label="数据源" prop="dataSourceConfigId"> | ||||
|         <el-select v-model="queryParams.dataSourceConfigId" placeholder="请选择数据源" clearable> | ||||
|         <el-select v-model="queryParams.dataSourceConfigId" placeholder="请选择数据源"> | ||||
|           <el-option | ||||
|             v-for="config in dataSourceConfigs" | ||||
|             :key="config.id" | ||||
| @@ -13,52 +12,64 @@ | ||||
|         </el-select> | ||||
|       </el-form-item> | ||||
|       <el-form-item label="表名称" prop="name"> | ||||
|         <el-input v-model="queryParams.name" placeholder="请输入表名称" clearable /> | ||||
|         <el-input | ||||
|           v-model="queryParams.name" | ||||
|           placeholder="请输入表名称" | ||||
|           clearable | ||||
|           @keyup.enter="handleQuery" | ||||
|         /> | ||||
|       </el-form-item> | ||||
|       <el-form-item label="表描述" prop="comment"> | ||||
|         <el-input v-model="queryParams.comment" placeholder="请输入表描述" clearable /> | ||||
|         <el-input | ||||
|           v-model="queryParams.comment" | ||||
|           placeholder="请输入表描述" | ||||
|           clearable | ||||
|           @keyup.enter="handleQuery" | ||||
|         /> | ||||
|       </el-form-item> | ||||
|       <el-form-item> | ||||
|         <XButton | ||||
|           type="primary" | ||||
|           preIcon="ep:search" | ||||
|           :title="t('common.query')" | ||||
|           @click="handleQuery()" | ||||
|         /> | ||||
|         <XButton preIcon="ep:refresh-right" :title="t('common.reset')" @click="resetQuery()" /> | ||||
|         <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button> | ||||
|         <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button> | ||||
|       </el-form-item> | ||||
|     </el-form> | ||||
|     <vxe-table | ||||
|       ref="xTable" | ||||
|       :data="dbTableList" | ||||
|       v-loading="dbLoading" | ||||
|       :checkbox-config="{ highlight: true, range: true }" | ||||
|       height="260px" | ||||
|       class="xtable-scrollbar" | ||||
|     > | ||||
|       <vxe-column type="checkbox" width="60" /> | ||||
|       <vxe-column field="name" title="表名称" /> | ||||
|       <vxe-column field="comment" title="表描述" /> | ||||
|     </vxe-table> | ||||
|  | ||||
|     <el-row> | ||||
|       <el-table | ||||
|         v-loading="dbLoading" | ||||
|         @row-click="clickRow" | ||||
|         ref="tableRef" | ||||
|         :data="dbTableList" | ||||
|         @selection-change="handleSelectionChange" | ||||
|         height="260px" | ||||
|       > | ||||
|         <el-table-column type="selection" width="55" /> | ||||
|         <el-table-column prop="name" label="表名称" :show-overflow-tooltip="true" /> | ||||
|         <el-table-column prop="comment" label="表描述" :show-overflow-tooltip="true" /> | ||||
|       </el-table> | ||||
|     </el-row> | ||||
|  | ||||
|     <template #footer> | ||||
|       <div class="dialog-footer"> | ||||
|         <XButton type="primary" :title="t('action.import')" @click="handleImportTable()" /> | ||||
|         <XButton :title="t('dialog.close')" @click="handleClose()" /> | ||||
|         <el-button @click="handleImportTable" type="primary" :disabled="tables.length === 0">{{ | ||||
|           t('action.import') | ||||
|         }}</el-button> | ||||
|         <el-button @click="handleClose">{{ t('dialog.close') }}</el-button> | ||||
|       </div> | ||||
|     </template> | ||||
|   </XModal> | ||||
|   </Dialog> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| import { VxeTableInstance } from 'vxe-table' | ||||
| import type { DatabaseTableVO } from '@/api/infra/codegen/types' | ||||
| import { getSchemaTableListApi, createCodegenListApi } from '@/api/infra/codegen' | ||||
| import { getDataSourceConfigListApi, DataSourceConfigVO } from '@/api/infra/dataSourceConfig' | ||||
| import * as CodegenApi from '@/api/infra/codegen' | ||||
| import { getDataSourceConfigList, DataSourceConfigVO } from '@/api/infra/dataSourceConfig' | ||||
| import { ElTable } from 'element-plus' | ||||
|  | ||||
| const { t } = useI18n() // 国际化 | ||||
| const message = useMessage() // 消息弹窗 | ||||
| const emit = defineEmits(['ok']) | ||||
| // ======== 显示页面 ======== | ||||
| const visible = ref(false) | ||||
|  | ||||
| const modelVisible = ref(false) // 弹窗的是否展示 | ||||
| const modelTitle = ref('导入表') // 弹窗的标题 | ||||
| const dbLoading = ref(true) | ||||
| const queryParams = reactive({ | ||||
|   name: undefined, | ||||
| @@ -67,10 +78,9 @@ const queryParams = reactive({ | ||||
| }) | ||||
| const dataSourceConfigs = ref<DataSourceConfigVO[]>([]) | ||||
| const show = async () => { | ||||
|   const res = await getDataSourceConfigListApi() | ||||
|   dataSourceConfigs.value = res | ||||
|   queryParams.dataSourceConfigId = dataSourceConfigs.value[0].id | ||||
|   visible.value = true | ||||
|   dataSourceConfigs.value = await getDataSourceConfigList() | ||||
|   queryParams.dataSourceConfigId = dataSourceConfigs.value[0].id as number | ||||
|   modelVisible.value = true | ||||
|   await getList() | ||||
| } | ||||
| /** 查询表数据 */ | ||||
| @@ -79,8 +89,7 @@ const dbTableList = ref<DatabaseTableVO[]>([]) | ||||
| /** 查询表数据 */ | ||||
| const getList = async () => { | ||||
|   dbLoading.value = true | ||||
|   const res = await getSchemaTableListApi(queryParams) | ||||
|   dbTableList.value = res | ||||
|   dbTableList.value = await CodegenApi.getSchemaTableList(queryParams) | ||||
|   dbLoading.value = false | ||||
| } | ||||
| // 查询操作 | ||||
| @@ -91,23 +100,22 @@ const handleQuery = async () => { | ||||
| const resetQuery = async () => { | ||||
|   queryParams.name = undefined | ||||
|   queryParams.comment = undefined | ||||
|   queryParams.dataSourceConfigId = 0 | ||||
|   queryParams.dataSourceConfigId = dataSourceConfigs.value[0].id as number | ||||
|   await getList() | ||||
| } | ||||
| const xTable = ref<VxeTableInstance>() | ||||
| const tableRef = ref<typeof ElTable>() | ||||
| /** 多选框选中数据 */ | ||||
| const tables = ref<string[]>([]) | ||||
|  | ||||
| const clickRow = (row) => { | ||||
|   unref(tableRef)?.toggleRowSelection(row) | ||||
| } | ||||
| // 多选框选中数据 | ||||
| const handleSelectionChange = (selection) => { | ||||
|   tables.value = selection.map((item) => item.name) | ||||
| } | ||||
| /** 导入按钮操作 */ | ||||
| const handleImportTable = async () => { | ||||
|   if (xTable.value?.getCheckboxRecords().length === 0) { | ||||
|     message.error('请选择要导入的表') | ||||
|     return | ||||
|   } | ||||
|   xTable.value?.getCheckboxRecords().forEach((item) => { | ||||
|     tables.value.push(item.name) | ||||
|   }) | ||||
|   await createCodegenListApi({ | ||||
|   await CodegenApi.createCodegenList({ | ||||
|     dataSourceConfigId: queryParams.dataSourceConfigId, | ||||
|     tableNames: tables.value | ||||
|   }) | ||||
| @@ -116,7 +124,7 @@ const handleImportTable = async () => { | ||||
|   handleClose() | ||||
| } | ||||
| const handleClose = () => { | ||||
|   visible.value = false | ||||
|   modelVisible.value = false | ||||
|   tables.value = [] | ||||
| } | ||||
| defineExpose({ | ||||
|   | ||||
| @@ -1,5 +1,11 @@ | ||||
| <template> | ||||
|   <XModal title="预览" v-model="preview.open"> | ||||
|   <Dialog | ||||
|     :title="modelTitle" | ||||
|     v-model="modelVisible" | ||||
|     align-center | ||||
|     width="60%" | ||||
|     class="app-infra-codegen-preview-container" | ||||
|   > | ||||
|     <div class="flex"> | ||||
|       <el-card class="w-1/4" :gutter="12" shadow="hover"> | ||||
|         <el-scrollbar height="calc(100vh - 88px - 40px - 50px)"> | ||||
| @@ -10,6 +16,7 @@ | ||||
|             :expand-on-click-node="false" | ||||
|             highlight-current | ||||
|             @node-click="handleNodeClick" | ||||
|             default-expand-all | ||||
|           /> | ||||
|         </el-scrollbar> | ||||
|       </el-card> | ||||
| @@ -21,38 +28,34 @@ | ||||
|             :name="item.filePath" | ||||
|             :key="item.filePath" | ||||
|           > | ||||
|             <XTextButton style="float: right" :title="t('common.copy')" @click="copy(item.code)" /> | ||||
|             <el-button text type="primary" class="float-right" @click="copy(item.code)"> | ||||
|               {{ t('common.copy') }} | ||||
|             </el-button> | ||||
|             <pre>{{ item.code }}</pre> | ||||
|           </el-tab-pane> | ||||
|         </el-tabs> | ||||
|       </el-card> | ||||
|     </div> | ||||
|   </XModal> | ||||
|   </Dialog> | ||||
| </template> | ||||
| <script setup lang="ts"> | ||||
| import { useClipboard } from '@vueuse/core' | ||||
| import { handleTree2 } from '@/utils/tree' | ||||
| import { previewCodegenApi } from '@/api/infra/codegen' | ||||
| import { CodegenTableVO, CodegenPreviewVO } from '@/api/infra/codegen/types' | ||||
| import * as CodegenApi from '@/api/infra/codegen' | ||||
| import { CodegenPreviewVO } from '@/api/infra/codegen/types' | ||||
|  | ||||
| const { t } = useI18n() // 国际化 | ||||
| const message = useMessage() // 消息弹窗 | ||||
|  | ||||
| const modelVisible = ref(false) // 弹窗的是否展示 | ||||
| const modelTitle = ref('代码预览') // 弹窗的标题 | ||||
| // ======== 显示页面 ======== | ||||
| const preview = reactive({ | ||||
|   open: false, | ||||
|   titel: '代码预览', | ||||
|   fileTree: [], | ||||
|   activeName: '' | ||||
| }) | ||||
| const previewCodegen = ref<CodegenPreviewVO[]>() | ||||
| const show = async (row: CodegenTableVO) => { | ||||
|   const res = await previewCodegenApi(row.id) | ||||
|   let file = handleFiles(res) | ||||
|   previewCodegen.value = res | ||||
|   preview.fileTree = handleTree2(file, 'id', 'parentId', 'children', '/') | ||||
|   preview.activeName = res[0].filePath | ||||
|   preview.open = true | ||||
| } | ||||
|  | ||||
| const handleNodeClick = async (data, node) => { | ||||
|   if (node && !node.isLeaf) { | ||||
|     return false | ||||
| @@ -132,14 +135,30 @@ const copy = async (text: string) => { | ||||
|   const { copy, copied, isSupported } = useClipboard({ source: text }) | ||||
|   if (!isSupported) { | ||||
|     message.error(t('common.copyError')) | ||||
|   } else { | ||||
|     await copy() | ||||
|     if (unref(copied)) { | ||||
|       message.success(t('common.copySuccess')) | ||||
|     } | ||||
|     return | ||||
|   } | ||||
|   await copy() | ||||
|   if (unref(copied)) { | ||||
|     message.success(t('common.copySuccess')) | ||||
|   } | ||||
| } | ||||
| defineExpose({ | ||||
|   show | ||||
| }) | ||||
|  | ||||
| /** 打开弹窗 */ | ||||
| const openModal = async (id: number) => { | ||||
|   modelVisible.value = true | ||||
|   const res = await CodegenApi.previewCodegen(id) | ||||
|   let file = handleFiles(res) | ||||
|   previewCodegen.value = res | ||||
|   preview.fileTree = handleTree2(file, 'id', 'parentId', 'children', '/') | ||||
|   preview.activeName = res[0].filePath | ||||
| } | ||||
| defineExpose({ openModal }) // 提供 openModal 方法,用于打开弹窗 | ||||
| </script> | ||||
| <style lang="scss"> | ||||
| .app-infra-codegen-preview-container { | ||||
|   .el-scrollbar .el-scrollbar__wrap .el-scrollbar__view { | ||||
|     white-space: nowrap; | ||||
|     display: inline-block; | ||||
|   } | ||||
| } | ||||
| </style> | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| import BasicInfoForm from './BasicInfoForm.vue' | ||||
| import CloumInfoForm from './CloumInfoForm.vue' | ||||
| import ColumInfoForm from './ColumInfoForm.vue' | ||||
| import GenerateInfoForm from './GenerateInfoForm.vue' | ||||
| import ImportTable from './ImportTable.vue' | ||||
| import Preview from './Preview.vue' | ||||
| export { BasicInfoForm, CloumInfoForm, ImportTable, Preview } | ||||
| export { BasicInfoForm, ColumInfoForm, GenerateInfoForm, ImportTable, Preview } | ||||
|   | ||||
| @@ -1,56 +1,124 @@ | ||||
| <template> | ||||
|   <ContentWrap> | ||||
|     <!-- 列表 --> | ||||
|     <XTable @register="registerTable"> | ||||
|       <template #toolbar_buttons> | ||||
|         <!-- 操作:导入 --> | ||||
|         <XButton | ||||
|           type="primary" | ||||
|           preIcon="ep:zoom-in" | ||||
|           :title="t('action.import')" | ||||
|           v-hasPermi="['infra:codegen:create']" | ||||
|           @click="openImportTable()" | ||||
|   <!-- 搜索 --> | ||||
|   <content-wrap> | ||||
|     <el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true"> | ||||
|       <el-form-item label="表名称" prop="tableName"> | ||||
|         <el-input | ||||
|           v-model="queryParams.tableName" | ||||
|           placeholder="请输入表名称" | ||||
|           clearable | ||||
|           @keyup.enter="handleQuery" | ||||
|         /> | ||||
|       </template> | ||||
|       <template #actionbtns_default="{ row }"> | ||||
|         <!-- 操作:预览 --> | ||||
|         <XTextButton | ||||
|           preIcon="ep:view" | ||||
|           :title="t('action.preview')" | ||||
|           v-hasPermi="['infra:codegen:query']" | ||||
|           @click="handlePreview(row)" | ||||
|       </el-form-item> | ||||
|       <el-form-item label="表描述" prop="tableComment"> | ||||
|         <el-input | ||||
|           v-model="queryParams.tableComment" | ||||
|           placeholder="请输入表描述" | ||||
|           clearable | ||||
|           @keyup.enter="handleQuery" | ||||
|         /> | ||||
|         <!-- 操作:编辑 --> | ||||
|         <XTextButton | ||||
|           preIcon="ep:edit" | ||||
|           :title="t('action.edit')" | ||||
|           v-hasPermi="['infra:codegen:update']" | ||||
|           @click="handleUpdate(row.id)" | ||||
|       </el-form-item> | ||||
|       <el-form-item label="创建时间" prop="createTime"> | ||||
|         <el-date-picker | ||||
|           v-model="queryParams.createTime" | ||||
|           value-format="yyyy-MM-dd HH:mm:ss" | ||||
|           type="daterange" | ||||
|           start-placeholder="开始日期" | ||||
|           end-placeholder="结束日期" | ||||
|           :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]" | ||||
|         /> | ||||
|         <!-- 操作:删除 --> | ||||
|         <XTextButton | ||||
|           preIcon="ep:delete" | ||||
|           :title="t('action.del')" | ||||
|           v-hasPermi="['infra:codegen:delete']" | ||||
|           @click="deleteData(row.id)" | ||||
|         /> | ||||
|         <!-- 操作:同步 --> | ||||
|         <XTextButton | ||||
|           preIcon="ep:refresh" | ||||
|           :title="t('action.sync')" | ||||
|           v-hasPermi="['infra:codegen:update']" | ||||
|           @click="handleSynchDb(row)" | ||||
|         /> | ||||
|         <!-- 操作:生成 --> | ||||
|         <XTextButton | ||||
|           preIcon="ep:download" | ||||
|           :title="t('action.generate')" | ||||
|           v-hasPermi="['infra:codegen:download']" | ||||
|           @click="handleGenTable(row)" | ||||
|         /> | ||||
|       </template> | ||||
|     </XTable> | ||||
|   </ContentWrap> | ||||
|       </el-form-item> | ||||
|       <el-form-item> | ||||
|         <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" />搜索</el-button> | ||||
|         <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" />重置</el-button> | ||||
|         <el-button type="primary" v-hasPermi="['infra:codegen:create']" @click="openImportTable()"> | ||||
|           <Icon icon="ep:zoom-in" class="mr-5px" />{{ t('action.import') }} | ||||
|         </el-button> | ||||
|       </el-form-item> | ||||
|     </el-form> | ||||
|   </content-wrap> | ||||
|  | ||||
|   <!-- 列表 --> | ||||
|   <content-wrap> | ||||
|     <el-table v-loading="loading" :data="list"> | ||||
|       <el-table-column label="数据源" align="center" :formatter="dataSourceConfigNameFormat" /> | ||||
|       <el-table-column label="表名称" align="center" prop="tableName" width="200" /> | ||||
|       <el-table-column | ||||
|         label="表描述" | ||||
|         align="center" | ||||
|         prop="tableComment" | ||||
|         :show-overflow-tooltip="true" | ||||
|         width="120" | ||||
|       /> | ||||
|       <el-table-column label="实体" align="center" prop="className" width="200" /> | ||||
|       <el-table-column | ||||
|         label="创建时间" | ||||
|         align="center" | ||||
|         prop="createTime" | ||||
|         width="180" | ||||
|         :formatter="dateFormatter" | ||||
|       /> | ||||
|       <el-table-column | ||||
|         label="更新时间" | ||||
|         align="center" | ||||
|         prop="createTime" | ||||
|         width="180" | ||||
|         :formatter="dateFormatter" | ||||
|       /> | ||||
|       <el-table-column | ||||
|         label="操作" | ||||
|         align="center" | ||||
|         width="300px" | ||||
|         class-name="small-padding fixed-width" | ||||
|       > | ||||
|         <template #default="scope"> | ||||
|           <el-button | ||||
|             link | ||||
|             type="primary" | ||||
|             @click="handlePreview(scope.row)" | ||||
|             v-hasPermi="['infra:codegen:preview']" | ||||
|             >预览</el-button | ||||
|           > | ||||
|           <el-button | ||||
|             link | ||||
|             type="primary" | ||||
|             @click="handleUpdate(scope.row.id)" | ||||
|             v-hasPermi="['infra:codegen:update']" | ||||
|             >编辑</el-button | ||||
|           > | ||||
|           <el-button | ||||
|             link | ||||
|             type="danger" | ||||
|             @click="handleDelete(scope.row.id)" | ||||
|             v-hasPermi="['infra:codegen:delete']" | ||||
|             >删除</el-button | ||||
|           > | ||||
|           <el-button | ||||
|             link | ||||
|             type="primary" | ||||
|             @click="handleSynchDb(scope.row)" | ||||
|             v-hasPermi="['infra:codegen:update']" | ||||
|             >同步</el-button | ||||
|           > | ||||
|           <el-button | ||||
|             link | ||||
|             type="primary" | ||||
|             @click="handleGenTable(scope.row)" | ||||
|             v-hasPermi="['infra:codegen:download']" | ||||
|             >生成代码</el-button | ||||
|           > | ||||
|         </template> | ||||
|       </el-table-column> | ||||
|     </el-table> | ||||
|     <pagination | ||||
|       v-show="total > 0" | ||||
|       :total="total" | ||||
|       v-model:page="queryParams.pageNo" | ||||
|       v-model:limit="queryParams.pageSize" | ||||
|       @pagination="getList" | ||||
|     /> | ||||
|   </content-wrap> | ||||
|  | ||||
|   <!-- 弹窗:导入表 --> | ||||
|   <ImportTable ref="importRef" @ok="reload()" /> | ||||
|   <!-- 弹窗:预览代码 --> | ||||
| @@ -59,19 +127,70 @@ | ||||
| <script setup lang="ts" name="Codegen"> | ||||
| import download from '@/utils/download' | ||||
| import * as CodegenApi from '@/api/infra/codegen' | ||||
| import * as DataSourceConfigApi from '@/api/infra/dataSourceConfig' | ||||
| import { CodegenTableVO } from '@/api/infra/codegen/types' | ||||
| import { allSchemas } from './codegen.data' | ||||
| import { ImportTable, Preview } from './components' | ||||
| import ContentWrap from '@/components/ContentWrap/src/ContentWrap.vue' | ||||
| import { DataSourceConfigVO } from '@/api/infra/dataSourceConfig' | ||||
| import { dateFormatter } from '@/utils/formatTime' | ||||
|  | ||||
| const { t } = useI18n() // 国际化 | ||||
| const message = useMessage() // 消息弹窗 | ||||
| const { t } = useI18n() // 国际化 | ||||
| const { push } = useRouter() // 路由跳转 | ||||
| // 列表相关的变量 | ||||
| const [registerTable, { reload, deleteData }] = useXTable({ | ||||
|   allSchemas: allSchemas, | ||||
|   getListApi: CodegenApi.getCodegenTablePageApi, | ||||
|   deleteApi: CodegenApi.deleteCodegenTableApi | ||||
|  | ||||
| const loading = ref(true) // 列表的加载中 | ||||
| const total = ref(0) // 列表的总页数 | ||||
| const list = ref([]) // 列表的数据 | ||||
| const queryParams = reactive({ | ||||
|   pageNo: 1, | ||||
|   pageSize: 10, | ||||
|   tableName: undefined, | ||||
|   tableComment: undefined, | ||||
|   createTime: [] | ||||
| }) | ||||
| const queryFormRef = ref() // 搜索的表单 | ||||
|  | ||||
| const dataSourceConfigs = ref<DataSourceConfigVO[]>([]) // 数据源列表 | ||||
|  | ||||
| /** 查询参数列表 */ | ||||
| const getList = async () => { | ||||
|   loading.value = true | ||||
|   try { | ||||
|     const data = await CodegenApi.getCodegenTablePage(queryParams) | ||||
|     list.value = data.list | ||||
|     total.value = data.total | ||||
|   } finally { | ||||
|     loading.value = false | ||||
|   } | ||||
| } | ||||
|  | ||||
| /** 搜索按钮操作 */ | ||||
| const handleQuery = () => { | ||||
|   queryParams.pageNo = 1 | ||||
|   getList() | ||||
| } | ||||
|  | ||||
| /** 重置按钮操作 */ | ||||
| const resetQuery = () => { | ||||
|   queryFormRef.value.resetFields() | ||||
|   handleQuery() | ||||
| } | ||||
|  | ||||
| /** 初始化 **/ | ||||
| onMounted(async () => { | ||||
|   getList() | ||||
|   dataSourceConfigs.value = await DataSourceConfigApi.getDataSourceConfigList() | ||||
| }) | ||||
|  | ||||
| // 数据源配置的名字 | ||||
| const dataSourceConfigNameFormat = (row) => { | ||||
|   for (const config of dataSourceConfigs.value) { | ||||
|     if (row.dataSourceConfigId === config.id) { | ||||
|       return config.name | ||||
|     } | ||||
|   } | ||||
|   return '未知【' + row.leaderUserId + '】' | ||||
| } | ||||
|  | ||||
| // 导入操作 | ||||
| const importRef = ref() | ||||
| @@ -81,27 +200,39 @@ const openImportTable = () => { | ||||
| // 预览操作 | ||||
| const previewRef = ref() | ||||
| const handlePreview = (row: CodegenTableVO) => { | ||||
|   previewRef.value.show(row) | ||||
|   previewRef.value.openModal(row.id) | ||||
| } | ||||
| // 编辑操作 | ||||
| const handleUpdate = (rowId: number) => { | ||||
|   push('/codegen/edit?id=' + rowId) | ||||
| } | ||||
|  | ||||
| /** 删除按钮操作 */ | ||||
| const handleDelete = async (id: number) => { | ||||
|   try { | ||||
|     // 删除的二次确认 | ||||
|     await message.delConfirm() | ||||
|     // 发起删除 | ||||
|     await CodegenApi.deleteCodegenTable(id) | ||||
|     message.success(t('common.delSuccess')) | ||||
|     // 刷新列表 | ||||
|     await getList() | ||||
|   } catch {} | ||||
| } | ||||
| // 同步操作 | ||||
| const handleSynchDb = (row: CodegenTableVO) => { | ||||
| const handleSynchDb = async (row: CodegenTableVO) => { | ||||
|   // 基于 DB 同步 | ||||
|   const tableName = row.tableName | ||||
|   message | ||||
|     .confirm('确认要强制同步' + tableName + '表结构吗?', t('common.reminder')) | ||||
|     .then(async () => { | ||||
|       await CodegenApi.syncCodegenFromDBApi(row.id) | ||||
|       message.success('同步成功') | ||||
|     }) | ||||
|   try { | ||||
|     await message.confirm('确认要强制同步' + tableName + '表结构吗?', t('common.reminder')) | ||||
|     await CodegenApi.syncCodegenFromDB(row.id) | ||||
|     message.success('同步成功') | ||||
|   } catch {} | ||||
| } | ||||
|  | ||||
| // 生成代码操作 | ||||
| const handleGenTable = async (row: CodegenTableVO) => { | ||||
|   const res = await CodegenApi.downloadCodegenApi(row.id) | ||||
|   const res = await CodegenApi.downloadCodegen(row.id) | ||||
|   download.zip(res, 'codegen-' + row.className + '.zip') | ||||
| } | ||||
| </script> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 dlarmor
					dlarmor