mirror of
				https://gitee.com/hhyykk/ipms-sjy-ui.git
				synced 2025-11-04 12:18:43 +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