code review:vue2 主子表的生成
This commit is contained in:
parent
12bcee2a72
commit
df51a678eb
|
@ -63,7 +63,7 @@ export function export${simpleClassName}Excel(params) {
|
||||||
responseType: 'blob'
|
responseType: 'blob'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
## 特殊:主子表专属逻辑
|
## 特殊:主子表专属逻辑 TODO @puhui999:下面方法的【空格】不太对
|
||||||
#foreach ($subTable in $subTables)
|
#foreach ($subTable in $subTables)
|
||||||
#set ($index = $foreach.count - 1)
|
#set ($index = $foreach.count - 1)
|
||||||
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||||
|
|
|
@ -1,137 +1,137 @@
|
||||||
<template>
|
<template>
|
||||||
<Dialog :title="dialogTitle" v-model="dialogVisible">
|
<Dialog :title="dialogTitle" v-model="dialogVisible">
|
||||||
<el-form
|
<el-form
|
||||||
ref="formRef"
|
ref="formRef"
|
||||||
:model="formData"
|
:model="formData"
|
||||||
:rules="formRules"
|
:rules="formRules"
|
||||||
label-width="100px"
|
label-width="100px"
|
||||||
v-loading="formLoading"
|
v-loading="formLoading"
|
||||||
>
|
>
|
||||||
#foreach($column in $columns)
|
#foreach($column in $columns)
|
||||||
#if ($column.createOperation || $column.updateOperation)
|
#if ($column.createOperation || $column.updateOperation)
|
||||||
#set ($dictType = $column.dictType)
|
#set ($dictType = $column.dictType)
|
||||||
#set ($javaField = $column.javaField)
|
#set ($javaField = $column.javaField)
|
||||||
#set ($javaType = $column.javaType)
|
#set ($javaType = $column.javaType)
|
||||||
#set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
#set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||||
#set ($comment = $column.columnComment)
|
#set ($comment = $column.columnComment)
|
||||||
#set ($dictMethod = "getDictOptions")## 计算使用哪个 dict 字典方法
|
#set ($dictMethod = "getDictOptions")## 计算使用哪个 dict 字典方法
|
||||||
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
||||||
#set ($dictMethod = "getIntDictOptions")
|
#set ($dictMethod = "getIntDictOptions")
|
||||||
#elseif ($javaType == "String")
|
#elseif ($javaType == "String")
|
||||||
#set ($dictMethod = "getStrDictOptions")
|
#set ($dictMethod = "getStrDictOptions")
|
||||||
#elseif ($javaType == "Boolean")
|
#elseif ($javaType == "Boolean")
|
||||||
#set ($dictMethod = "getBoolDictOptions")
|
#set ($dictMethod = "getBoolDictOptions")
|
||||||
#end
|
|
||||||
#if ( $table.templateType == 2 && $column.id == $treeParentColumn.id )
|
|
||||||
<el-form-item label="${comment}" prop="${javaField}">
|
|
||||||
<el-tree-select
|
|
||||||
v-model="formData.${javaField}"
|
|
||||||
:data="${classNameVar}Tree"
|
|
||||||
#if ($treeNameColumn.javaField == "name")
|
|
||||||
:props="defaultProps"
|
|
||||||
#else
|
|
||||||
:props="{...defaultProps, label: '$treeNameColumn.javaField'}"
|
|
||||||
#end
|
|
||||||
check-strictly
|
|
||||||
default-expand-all
|
|
||||||
placeholder="请选择${comment}"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
#elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
|
|
||||||
<el-form-item label="${comment}" prop="${javaField}">
|
|
||||||
<el-input v-model="formData.${javaField}" placeholder="请输入${comment}" />
|
|
||||||
</el-form-item>
|
|
||||||
#elseif($column.htmlType == "imageUpload")## 图片上传
|
|
||||||
<el-form-item label="${comment}" prop="${javaField}">
|
|
||||||
<UploadImg v-model="formData.${javaField}" />
|
|
||||||
</el-form-item>
|
|
||||||
#elseif($column.htmlType == "fileUpload")## 文件上传
|
|
||||||
<el-form-item label="${comment}" prop="${javaField}">
|
|
||||||
<UploadFile v-model="formData.${javaField}" />
|
|
||||||
</el-form-item>
|
|
||||||
#elseif($column.htmlType == "editor")## 文本编辑器
|
|
||||||
<el-form-item label="${comment}" prop="${javaField}">
|
|
||||||
<Editor v-model="formData.${javaField}" height="150px" />
|
|
||||||
</el-form-item>
|
|
||||||
#elseif($column.htmlType == "select")## 下拉框
|
|
||||||
<el-form-item label="${comment}" prop="${javaField}">
|
|
||||||
<el-select v-model="formData.${javaField}" placeholder="请选择${comment}">
|
|
||||||
#if ("" != $dictType)## 有数据字典
|
|
||||||
<el-option
|
|
||||||
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
|
||||||
:key="dict.value"
|
|
||||||
:label="dict.label"
|
|
||||||
:value="dict.value"
|
|
||||||
/>
|
|
||||||
#else##没数据字典
|
|
||||||
<el-option label="请选择字典生成" value="" />
|
|
||||||
#end
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
#elseif($column.htmlType == "checkbox")## 多选框
|
|
||||||
<el-form-item label="${comment}" prop="${javaField}">
|
|
||||||
<el-checkbox-group v-model="formData.${javaField}">
|
|
||||||
#if ("" != $dictType)## 有数据字典
|
|
||||||
<el-checkbox
|
|
||||||
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
|
||||||
:key="dict.value"
|
|
||||||
:label="dict.value"
|
|
||||||
>
|
|
||||||
{{ dict.label }}
|
|
||||||
</el-checkbox>
|
|
||||||
#else##没数据字典
|
|
||||||
<el-checkbox>请选择字典生成</el-checkbox>
|
|
||||||
#end
|
|
||||||
</el-checkbox-group>
|
|
||||||
</el-form-item>
|
|
||||||
#elseif($column.htmlType == "radio")## 单选框
|
|
||||||
<el-form-item label="${comment}" prop="${javaField}">
|
|
||||||
<el-radio-group v-model="formData.${javaField}">
|
|
||||||
#if ("" != $dictType)## 有数据字典
|
|
||||||
<el-radio
|
|
||||||
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
|
||||||
:key="dict.value"
|
|
||||||
:label="dict.value"
|
|
||||||
>
|
|
||||||
{{ dict.label }}
|
|
||||||
</el-radio>
|
|
||||||
#else##没数据字典
|
|
||||||
<el-radio label="1">请选择字典生成</el-radio>
|
|
||||||
#end
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
#elseif($column.htmlType == "datetime")## 时间框
|
|
||||||
<el-form-item label="${comment}" prop="${javaField}">
|
|
||||||
<el-date-picker
|
|
||||||
v-model="formData.${javaField}"
|
|
||||||
type="date"
|
|
||||||
value-format="x"
|
|
||||||
placeholder="选择${comment}"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
#elseif($column.htmlType == "textarea")## 文本框
|
|
||||||
<el-form-item label="${comment}" prop="${javaField}">
|
|
||||||
<el-input v-model="formData.${javaField}" type="textarea" placeholder="请输入${comment}" />
|
|
||||||
</el-form-item>
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
#end
|
#end
|
||||||
|
#if ( $table.templateType == 2 && $column.id == $treeParentColumn.id )
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-tree-select
|
||||||
|
v-model="formData.${javaField}"
|
||||||
|
:data="${classNameVar}Tree"
|
||||||
|
#if ($treeNameColumn.javaField == "name")
|
||||||
|
:props="defaultProps"
|
||||||
|
#else
|
||||||
|
:props="{...defaultProps, label: '$treeNameColumn.javaField'}"
|
||||||
|
#end
|
||||||
|
check-strictly
|
||||||
|
default-expand-all
|
||||||
|
placeholder="请选择${comment}"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
#elseif ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-input v-model="formData.${javaField}" placeholder="请输入${comment}" />
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "imageUpload")## 图片上传
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<UploadImg v-model="formData.${javaField}" />
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "fileUpload")## 文件上传
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<UploadFile v-model="formData.${javaField}" />
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "editor")## 文本编辑器
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<Editor v-model="formData.${javaField}" height="150px" />
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "select")## 下拉框
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-select v-model="formData.${javaField}" placeholder="请选择${comment}">
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
<el-option
|
||||||
|
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
#else##没数据字典
|
||||||
|
<el-option label="请选择字典生成" value="" />
|
||||||
|
#end
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "checkbox")## 多选框
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-checkbox-group v-model="formData.${javaField}">
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
<el-checkbox
|
||||||
|
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.value"
|
||||||
|
>
|
||||||
|
{{ dict.label }}
|
||||||
|
</el-checkbox>
|
||||||
|
#else##没数据字典
|
||||||
|
<el-checkbox>请选择字典生成</el-checkbox>
|
||||||
|
#end
|
||||||
|
</el-checkbox-group>
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "radio")## 单选框
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-radio-group v-model="formData.${javaField}">
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
<el-radio
|
||||||
|
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.value"
|
||||||
|
>
|
||||||
|
{{ dict.label }}
|
||||||
|
</el-radio>
|
||||||
|
#else##没数据字典
|
||||||
|
<el-radio label="1">请选择字典生成</el-radio>
|
||||||
|
#end
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "datetime")## 时间框
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="formData.${javaField}"
|
||||||
|
type="date"
|
||||||
|
value-format="x"
|
||||||
|
placeholder="选择${comment}"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "textarea")## 文本框
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-input v-model="formData.${javaField}" type="textarea" placeholder="请输入${comment}" />
|
||||||
|
</el-form-item>
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
</el-form>
|
</el-form>
|
||||||
## 特殊:主子表专属逻辑
|
## 特殊:主子表专属逻辑
|
||||||
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||||
<!-- 子表的表单 -->
|
<!-- 子表的表单 -->
|
||||||
<el-tabs v-model="subTabsName">
|
<el-tabs v-model="subTabsName">
|
||||||
#foreach ($subTable in $subTables)
|
#foreach ($subTable in $subTables)
|
||||||
#set ($index = $foreach.count - 1)
|
#set ($index = $foreach.count - 1)
|
||||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||||
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||||
#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
|
#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
|
||||||
<el-tab-pane label="${subTable.classComment}" name="$subClassNameVar">
|
<el-tab-pane label="${subTable.classComment}" name="$subClassNameVar">
|
||||||
<${subSimpleClassName}Form ref="${subClassNameVar}FormRef" :${subJoinColumn_strikeCase}="formData.id" />
|
<${subSimpleClassName}Form ref="${subClassNameVar}FormRef" :${subJoinColumn_strikeCase}="formData.id" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
#end
|
#end
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
#end
|
#end
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
||||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
@ -139,160 +139,160 @@
|
||||||
</Dialog>
|
</Dialog>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
|
import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||||
import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}'
|
import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}'
|
||||||
## 特殊:树表专属逻辑
|
## 特殊:树表专属逻辑
|
||||||
#if ( $table.templateType == 2 )
|
#if ( $table.templateType == 2 )
|
||||||
import { defaultProps, handleTree } from '@/utils/tree'
|
import { defaultProps, handleTree } from '@/utils/tree'
|
||||||
#end
|
#end
|
||||||
## 特殊:主子表专属逻辑
|
## 特殊:主子表专属逻辑
|
||||||
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||||
#foreach ($subSimpleClassName in $subSimpleClassNames)
|
#foreach ($subSimpleClassName in $subSimpleClassNames)
|
||||||
import ${subSimpleClassName}Form from './components/${subSimpleClassName}Form.vue'
|
import ${subSimpleClassName}Form from './components/${subSimpleClassName}Form.vue'
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
|
||||||
const { t } = useI18n() // 国际化
|
const { t } = useI18n() // 国际化
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
const dialogVisible = ref(false) // 弹窗的是否展示
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
const dialogTitle = ref('') // 弹窗的标题
|
const dialogTitle = ref('') // 弹窗的标题
|
||||||
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||||
const formData = ref({
|
const formData = ref({
|
||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
#if ($column.createOperation || $column.updateOperation)
|
#if ($column.createOperation || $column.updateOperation)
|
||||||
#if ($column.htmlType == "checkbox")
|
#if ($column.htmlType == "checkbox")
|
||||||
$column.javaField: [],
|
$column.javaField: [],
|
||||||
#else
|
#else
|
||||||
$column.javaField: undefined,
|
$column.javaField: undefined,
|
||||||
#end
|
|
||||||
#end
|
|
||||||
#end
|
#end
|
||||||
})
|
#end
|
||||||
const formRules = reactive({
|
#end
|
||||||
#foreach ($column in $columns)
|
})
|
||||||
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
|
const formRules = reactive({
|
||||||
#set($comment=$column.columnComment)
|
#foreach ($column in $columns)
|
||||||
$column.javaField: [{ required: true, message: '${comment}不能为空', trigger: #if($column.htmlType == 'select')'change'#else'blur'#end }],
|
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
|
||||||
#end
|
#set($comment=$column.columnComment)
|
||||||
#end
|
$column.javaField: [{ required: true, message: '${comment}不能为空', trigger: #if($column.htmlType == 'select')'change'#else'blur'#end }],
|
||||||
})
|
#end
|
||||||
const formRef = ref() // 表单 Ref
|
#end
|
||||||
## 特殊:树表专属逻辑
|
})
|
||||||
#if ( $table.templateType == 2 )
|
const formRef = ref() // 表单 Ref
|
||||||
const ${classNameVar}Tree = ref() // 树形结构
|
## 特殊:树表专属逻辑
|
||||||
#end
|
#if ( $table.templateType == 2 )
|
||||||
## 特殊:主子表专属逻辑
|
const ${classNameVar}Tree = ref() // 树形结构
|
||||||
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
#end
|
||||||
#if ( $subTables && $subTables.size() > 0 )
|
## 特殊:主子表专属逻辑
|
||||||
|
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||||
|
#if ( $subTables && $subTables.size() > 0 )
|
||||||
|
|
||||||
/** 子表的表单 */
|
/** 子表的表单 */
|
||||||
const subTabsName = ref('$subClassNameVars.get(0)')
|
const subTabsName = ref('$subClassNameVars.get(0)')
|
||||||
#foreach ($subClassNameVar in $subClassNameVars)
|
#foreach ($subClassNameVar in $subClassNameVars)
|
||||||
const ${subClassNameVar}FormRef = ref()
|
const ${subClassNameVar}FormRef = ref()
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
|
||||||
/** 打开弹窗 */
|
/** 打开弹窗 */
|
||||||
const open = async (type: string, id?: number) => {
|
const open = async (type: string, id?: number) => {
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true
|
||||||
dialogTitle.value = t('action.' + type)
|
dialogTitle.value = t('action.' + type)
|
||||||
formType.value = type
|
formType.value = type
|
||||||
resetForm()
|
resetForm()
|
||||||
// 修改时,设置数据
|
// 修改时,设置数据
|
||||||
if (id) {
|
if (id) {
|
||||||
formLoading.value = true
|
|
||||||
try {
|
|
||||||
formData.value = await ${simpleClassName}Api.get${simpleClassName}(id)
|
|
||||||
} finally {
|
|
||||||
formLoading.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
## 特殊:树表专属逻辑
|
|
||||||
#if ( $table.templateType == 2 )
|
|
||||||
await get${simpleClassName}Tree()
|
|
||||||
#end
|
|
||||||
}
|
|
||||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
|
||||||
|
|
||||||
/** 提交表单 */
|
|
||||||
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
|
||||||
const submitForm = async () => {
|
|
||||||
// 校验表单
|
|
||||||
await formRef.value.validate()
|
|
||||||
## 特殊:主子表专属逻辑
|
|
||||||
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
|
||||||
#if ( $subTables && $subTables.size() > 0 )
|
|
||||||
// 校验子表单
|
|
||||||
#foreach ($subTable in $subTables)
|
|
||||||
#set ($index = $foreach.count - 1)
|
|
||||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
|
||||||
try {
|
|
||||||
await ${subClassNameVar}FormRef.value.validate()
|
|
||||||
} catch (e) {
|
|
||||||
subTabsName.value = '${subClassNameVar}'
|
|
||||||
return
|
|
||||||
}
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
// 提交请求
|
|
||||||
formLoading.value = true
|
formLoading.value = true
|
||||||
try {
|
try {
|
||||||
const data = formData.value as unknown as ${simpleClassName}Api.${simpleClassName}VO
|
formData.value = await ${simpleClassName}Api.get${simpleClassName}(id)
|
||||||
## 特殊:主子表专属逻辑
|
|
||||||
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
|
||||||
#if ( $subTables && $subTables.size() > 0 )
|
|
||||||
// 拼接子表的数据
|
|
||||||
#foreach ($subTable in $subTables)
|
|
||||||
#set ($index = $foreach.count - 1)
|
|
||||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
|
||||||
data.${subClassNameVar}#if ( $subTable.subJoinMany)s#end = ${subClassNameVar}FormRef.value.getData()
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
if (formType.value === 'create') {
|
|
||||||
await ${simpleClassName}Api.create${simpleClassName}(data)
|
|
||||||
message.success(t('common.createSuccess'))
|
|
||||||
} else {
|
|
||||||
await ${simpleClassName}Api.update${simpleClassName}(data)
|
|
||||||
message.success(t('common.updateSuccess'))
|
|
||||||
}
|
|
||||||
dialogVisible.value = false
|
|
||||||
// 发送操作成功的事件
|
|
||||||
emit('success')
|
|
||||||
} finally {
|
} finally {
|
||||||
formLoading.value = false
|
formLoading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
## 特殊:树表专属逻辑
|
||||||
|
#if ( $table.templateType == 2 )
|
||||||
|
await get${simpleClassName}Tree()
|
||||||
|
#end
|
||||||
|
}
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
/** 重置表单 */
|
/** 提交表单 */
|
||||||
const resetForm = () => {
|
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||||
formData.value = {
|
const submitForm = async () => {
|
||||||
#foreach ($column in $columns)
|
// 校验表单
|
||||||
#if ($column.createOperation || $column.updateOperation)
|
await formRef.value.validate()
|
||||||
#if ($column.htmlType == "checkbox")
|
## 特殊:主子表专属逻辑
|
||||||
$column.javaField: [],
|
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||||
#else
|
#if ( $subTables && $subTables.size() > 0 )
|
||||||
$column.javaField: undefined,
|
// 校验子表单
|
||||||
#end
|
#foreach ($subTable in $subTables)
|
||||||
#end
|
#set ($index = $foreach.count - 1)
|
||||||
#end
|
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||||
}
|
try {
|
||||||
formRef.value?.resetFields()
|
await ${subClassNameVar}FormRef.value.validate()
|
||||||
|
} catch (e) {
|
||||||
|
subTabsName.value = '${subClassNameVar}'
|
||||||
|
return
|
||||||
}
|
}
|
||||||
## 特殊:树表专属逻辑
|
#end
|
||||||
#if ( $table.templateType == 2 )
|
#end
|
||||||
|
#end
|
||||||
|
// 提交请求
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
const data = formData.value as unknown as ${simpleClassName}Api.${simpleClassName}VO
|
||||||
|
## 特殊:主子表专属逻辑
|
||||||
|
#if ( $table.templateType == 10 || $table.templateType == 12 )
|
||||||
|
#if ( $subTables && $subTables.size() > 0 )
|
||||||
|
// 拼接子表的数据
|
||||||
|
#foreach ($subTable in $subTables)
|
||||||
|
#set ($index = $foreach.count - 1)
|
||||||
|
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||||
|
data.${subClassNameVar}#if ( $subTable.subJoinMany)s#end = ${subClassNameVar}FormRef.value.getData()
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
if (formType.value === 'create') {
|
||||||
|
await ${simpleClassName}Api.create${simpleClassName}(data)
|
||||||
|
message.success(t('common.createSuccess'))
|
||||||
|
} else {
|
||||||
|
await ${simpleClassName}Api.update${simpleClassName}(data)
|
||||||
|
message.success(t('common.updateSuccess'))
|
||||||
|
}
|
||||||
|
dialogVisible.value = false
|
||||||
|
// 发送操作成功的事件
|
||||||
|
emit('success')
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** 获得${table.classComment}树 */
|
/** 重置表单 */
|
||||||
const get${simpleClassName}Tree = async () => {
|
const resetForm = () => {
|
||||||
${classNameVar}Tree.value = []
|
formData.value = {
|
||||||
const data = await ${simpleClassName}Api.get${simpleClassName}List()
|
#foreach ($column in $columns)
|
||||||
const root: Tree = { id: 0, name: '顶级${table.classComment}', children: [] }
|
#if ($column.createOperation || $column.updateOperation)
|
||||||
root.children = handleTree(data, 'id', '${treeParentColumn.javaField}')
|
#if ($column.htmlType == "checkbox")
|
||||||
${classNameVar}Tree.value.push(root)
|
$column.javaField: [],
|
||||||
}
|
#else
|
||||||
|
$column.javaField: undefined,
|
||||||
#end
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
}
|
||||||
|
formRef.value?.resetFields()
|
||||||
|
}
|
||||||
|
## 特殊:树表专属逻辑
|
||||||
|
#if ( $table.templateType == 2 )
|
||||||
|
|
||||||
|
/** 获得${table.classComment}树 */
|
||||||
|
const get${simpleClassName}Tree = async () => {
|
||||||
|
${classNameVar}Tree.value = []
|
||||||
|
const data = await ${simpleClassName}Api.get${simpleClassName}List()
|
||||||
|
const root: Tree = { id: 0, name: '顶级${table.classComment}', children: [] }
|
||||||
|
root.children = handleTree(data, 'id', '${treeParentColumn.javaField}')
|
||||||
|
${classNameVar}Tree.value.push(root)
|
||||||
|
}
|
||||||
|
#end
|
||||||
</script>
|
</script>
|
|
@ -2,375 +2,372 @@
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<!-- 搜索工作栏 -->
|
<!-- 搜索工作栏 -->
|
||||||
<el-form
|
<el-form
|
||||||
class="-mb-15px"
|
class="-mb-15px"
|
||||||
:model="queryParams"
|
:model="queryParams"
|
||||||
ref="queryFormRef"
|
ref="queryFormRef"
|
||||||
:inline="true"
|
:inline="true"
|
||||||
label-width="68px"
|
label-width="68px"
|
||||||
>
|
>
|
||||||
#foreach($column in $columns)
|
#foreach($column in $columns)
|
||||||
#if ($column.listOperation)
|
#if ($column.listOperation)
|
||||||
#set ($dictType = $column.dictType)
|
#set ($dictType = $column.dictType)
|
||||||
#set ($javaField = $column.javaField)
|
#set ($javaField = $column.javaField)
|
||||||
#set ($javaType = $column.javaType)
|
#set ($javaType = $column.javaType)
|
||||||
#set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
#set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||||
#set ($comment = $column.columnComment)
|
#set ($comment = $column.columnComment)
|
||||||
#set ($dictMethod = "getDictOptions")## 计算使用哪个 dict 字典方法
|
#set ($dictMethod = "getDictOptions")## 计算使用哪个 dict 字典方法
|
||||||
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
||||||
#set ($dictMethod = "getIntDictOptions")
|
#set ($dictMethod = "getIntDictOptions")
|
||||||
#elseif ($javaType == "String")
|
#elseif ($javaType == "String")
|
||||||
#set ($dictMethod = "getStrDictOptions")
|
#set ($dictMethod = "getStrDictOptions")
|
||||||
#elseif ($javaType == "Boolean")
|
#elseif ($javaType == "Boolean")
|
||||||
#set ($dictMethod = "getBoolDictOptions")
|
#set ($dictMethod = "getBoolDictOptions")
|
||||||
#end
|
|
||||||
#if ($column.htmlType == "input")
|
|
||||||
<el-form-item label="${comment}" prop="${javaField}">
|
|
||||||
<el-input
|
|
||||||
v-model="queryParams.${javaField}"
|
|
||||||
placeholder="请输入${comment}"
|
|
||||||
clearable
|
|
||||||
@keyup.enter="handleQuery"
|
|
||||||
class="!w-240px"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
#elseif ($column.htmlType == "select" || $column.htmlType == "radio")
|
|
||||||
<el-form-item label="${comment}" prop="${javaField}">
|
|
||||||
<el-select
|
|
||||||
v-model="queryParams.${javaField}"
|
|
||||||
placeholder="请选择${comment}"
|
|
||||||
clearable
|
|
||||||
class="!w-240px"
|
|
||||||
>
|
|
||||||
#if ("" != $dictType)## 设置了 dictType 数据字典的情况
|
|
||||||
<el-option
|
|
||||||
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
|
||||||
:key="dict.value"
|
|
||||||
:label="dict.label"
|
|
||||||
:value="dict.value"
|
|
||||||
/>
|
|
||||||
#else## 未设置 dictType 数据字典的情况
|
|
||||||
<el-option label="请选择字典生成" value="" />
|
|
||||||
#end
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
#elseif($column.htmlType == "datetime")
|
|
||||||
#if ($column.listOperationCondition != "BETWEEN")## 非范围
|
|
||||||
<el-form-item label="${comment}" prop="${javaField}">
|
|
||||||
<el-date-picker
|
|
||||||
v-model="queryParams.${javaField}"
|
|
||||||
value-format="YYYY-MM-DD"
|
|
||||||
type="date"
|
|
||||||
placeholder="选择${comment}"
|
|
||||||
clearable
|
|
||||||
class="!w-240px"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
#else## 范围
|
|
||||||
<el-form-item label="${comment}" prop="${javaField}">
|
|
||||||
<el-date-picker
|
|
||||||
v-model="queryParams.${javaField}"
|
|
||||||
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')]"
|
|
||||||
class="!w-240px"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
#end
|
#end
|
||||||
#end
|
#if ($column.htmlType == "input")
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.${javaField}"
|
||||||
|
placeholder="请输入${comment}"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
#elseif ($column.htmlType == "select" || $column.htmlType == "radio")
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-select
|
||||||
|
v-model="queryParams.${javaField}"
|
||||||
|
placeholder="请选择${comment}"
|
||||||
|
clearable
|
||||||
|
class="!w-240px"
|
||||||
|
>
|
||||||
|
#if ("" != $dictType)## 设置了 dictType 数据字典的情况
|
||||||
|
<el-option
|
||||||
|
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
#else## 未设置 dictType 数据字典的情况
|
||||||
|
<el-option label="请选择字典生成" value="" />
|
||||||
|
#end
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "datetime")
|
||||||
|
#if ($column.listOperationCondition != "BETWEEN")## 非范围
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="queryParams.${javaField}"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
type="date"
|
||||||
|
placeholder="选择${comment}"
|
||||||
|
clearable
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
#else## 范围
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="queryParams.${javaField}"
|
||||||
|
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')]"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
<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 @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
type="primary"
|
type="primary"
|
||||||
plain
|
plain
|
||||||
@click="openForm('create')"
|
@click="openForm('create')"
|
||||||
v-hasPermi="['${permissionPrefix}:create']"
|
v-hasPermi="['${permissionPrefix}:create']"
|
||||||
>
|
>
|
||||||
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
type="success"
|
type="success"
|
||||||
plain
|
plain
|
||||||
@click="handleExport"
|
@click="handleExport"
|
||||||
:loading="exportLoading"
|
:loading="exportLoading"
|
||||||
v-hasPermi="['${permissionPrefix}:export']"
|
v-hasPermi="['${permissionPrefix}:export']"
|
||||||
>
|
>
|
||||||
<Icon icon="ep:download" class="mr-5px" /> 导出
|
<Icon icon="ep:download" class="mr-5px" /> 导出
|
||||||
</el-button>
|
</el-button>
|
||||||
## 特殊:树表专属逻辑
|
## 特殊:树表专属逻辑
|
||||||
#if ( $table.templateType == 2 )
|
#if ( $table.templateType == 2 )
|
||||||
<el-button type="danger" plain @click="toggleExpandAll">
|
<el-button type="danger" plain @click="toggleExpandAll">
|
||||||
<Icon icon="ep:sort" class="mr-5px" /> 展开/折叠
|
<Icon icon="ep:sort" class="mr-5px" /> 展开/折叠
|
||||||
</el-button>
|
</el-button>
|
||||||
#end
|
#end
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
|
|
||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
## 特殊:主子表专属逻辑
|
## 特殊:主子表专属逻辑
|
||||||
#if ( $table.templateType == 11 && $subTables && $subTables.size() > 0 )
|
#if ( $table.templateType == 11 && $subTables && $subTables.size() > 0 )
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="loading"
|
v-loading="loading"
|
||||||
:data="list"
|
:data="list"
|
||||||
:stripe="true"
|
:stripe="true"
|
||||||
:show-overflow-tooltip="true"
|
:show-overflow-tooltip="true"
|
||||||
highlight-current-row
|
highlight-current-row
|
||||||
@current-change="handleCurrentChange"
|
@current-change="handleCurrentChange"
|
||||||
>
|
>
|
||||||
## 特殊:树表专属逻辑
|
## 特殊:树表专属逻辑
|
||||||
#elseif ( $table.templateType == 2 )
|
#elseif ( $table.templateType == 2 )
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="loading"
|
v-loading="loading"
|
||||||
:data="list"
|
:data="list"
|
||||||
:stripe="true"
|
:stripe="true"
|
||||||
:show-overflow-tooltip="true"
|
:show-overflow-tooltip="true"
|
||||||
row-key="id"
|
row-key="id"
|
||||||
:default-expand-all="isExpandAll"
|
:default-expand-all="isExpandAll"
|
||||||
v-if="refreshTable"
|
v-if="refreshTable"
|
||||||
>
|
>
|
||||||
#else
|
#else
|
||||||
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||||
#end
|
#end
|
||||||
## 特殊:主子表专属逻辑
|
## 特殊:主子表专属逻辑
|
||||||
#if ( $table.templateType == 12 && $subTables && $subTables.size() > 0 )
|
#if ( $table.templateType == 12 && $subTables && $subTables.size() > 0 )
|
||||||
<!-- 子表的列表 -->
|
<!-- 子表的列表 -->
|
||||||
<el-table-column type="expand">
|
<el-table-column type="expand">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tabs model-value="$subClassNameVars.get(0)">
|
<el-tabs model-value="$subClassNameVars.get(0)">
|
||||||
#foreach ($subTable in $subTables)
|
#foreach ($subTable in $subTables)
|
||||||
#set ($index = $foreach.count - 1)
|
#set ($index = $foreach.count - 1)
|
||||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||||
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||||
#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
|
#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
|
||||||
<el-tab-pane label="${subTable.classComment}" name="$subClassNameVar">
|
<el-tab-pane label="${subTable.classComment}" name="$subClassNameVar">
|
||||||
<${subSimpleClassName}List :${subJoinColumn_strikeCase}="scope.row.id" />
|
<${subSimpleClassName}List :${subJoinColumn_strikeCase}="scope.row.id" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
#end
|
#end
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
#end
|
#end
|
||||||
#foreach($column in $columns)
|
#foreach($column in $columns)
|
||||||
#if ($column.listOperationResult)
|
#if ($column.listOperationResult)
|
||||||
#set ($dictType=$column.dictType)
|
#set ($dictType=$column.dictType)
|
||||||
#set ($javaField = $column.javaField)
|
#set ($javaField = $column.javaField)
|
||||||
#set ($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
#set ($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||||
#set ($comment=$column.columnComment)
|
#set ($comment=$column.columnComment)
|
||||||
#if ($column.javaType == "LocalDateTime")## 时间类型
|
#if ($column.javaType == "LocalDateTime")## 时间类型
|
||||||
<el-table-column
|
<el-table-column
|
||||||
label="${comment}"
|
label="${comment}"
|
||||||
align="center"
|
align="center"
|
||||||
prop="${javaField}"
|
prop="${javaField}"
|
||||||
:formatter="dateFormatter"
|
:formatter="dateFormatter"
|
||||||
width="180px"
|
width="180px"
|
||||||
/>
|
/>
|
||||||
#elseif($column.dictType && "" != $column.dictType)## 数据字典
|
#elseif($column.dictType && "" != $column.dictType)## 数据字典
|
||||||
<el-table-column label="${comment}" align="center" prop="${javaField}">
|
<el-table-column label="${comment}" align="center" prop="${javaField}">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.${column.javaField}" />
|
<dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.${column.javaField}" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
#else
|
#else
|
||||||
<el-table-column label="${comment}" align="center" prop="${javaField}" />
|
<el-table-column label="${comment}" align="center" prop="${javaField}" />
|
||||||
#end
|
#end
|
||||||
#end
|
|
||||||
#end
|
#end
|
||||||
<el-table-column label="操作" align="center">
|
#end
|
||||||
<template #default="scope">
|
<el-table-column label="操作" align="center">
|
||||||
<el-button
|
<template #default="scope">
|
||||||
|
<el-button
|
||||||
link
|
link
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="openForm('update', scope.row.id)"
|
@click="openForm('update', scope.row.id)"
|
||||||
v-hasPermi="['${permissionPrefix}:update']"
|
v-hasPermi="['${permissionPrefix}:update']"
|
||||||
>
|
>
|
||||||
编辑
|
编辑
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
link
|
link
|
||||||
type="danger"
|
type="danger"
|
||||||
@click="handleDelete(scope.row.id)"
|
@click="handleDelete(scope.row.id)"
|
||||||
v-hasPermi="['${permissionPrefix}:delete']"
|
v-hasPermi="['${permissionPrefix}:delete']"
|
||||||
>
|
>
|
||||||
删除
|
删除
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
## 特殊:树表专属逻辑(树不需要分页)
|
|
||||||
#if ( $table.templateType != 2 )
|
|
||||||
<!-- 分页 -->
|
<!-- 分页 -->
|
||||||
<Pagination
|
<Pagination
|
||||||
:total="total"
|
:total="total"
|
||||||
v-model:page="queryParams.pageNo"
|
v-model:page="queryParams.pageNo"
|
||||||
v-model:limit="queryParams.pageSize"
|
v-model:limit="queryParams.pageSize"
|
||||||
@pagination="getList"
|
@pagination="getList"
|
||||||
/>
|
/>
|
||||||
#end
|
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
|
|
||||||
<!-- 表单弹窗:添加/修改 -->
|
<!-- 表单弹窗:添加/修改 -->
|
||||||
<${simpleClassName}Form ref="formRef" @success="getList" />
|
<${simpleClassName}Form ref="formRef" @success="getList" />
|
||||||
## 特殊:主子表专属逻辑
|
## 特殊:主子表专属逻辑
|
||||||
#if ( $table.templateType == 11 && $subTables && $subTables.size() > 0 )
|
#if ( $table.templateType == 11 && $subTables && $subTables.size() > 0 )
|
||||||
<!-- 子表的列表 -->
|
<!-- 子表的列表 -->
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<el-tabs model-value="$subClassNameVars.get(0)">
|
<el-tabs model-value="$subClassNameVars.get(0)">
|
||||||
#foreach ($subTable in $subTables)
|
#foreach ($subTable in $subTables)
|
||||||
#set ($index = $foreach.count - 1)
|
#set ($index = $foreach.count - 1)
|
||||||
#set ($subClassNameVar = $subClassNameVars.get($index))
|
#set ($subClassNameVar = $subClassNameVars.get($index))
|
||||||
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
#set ($subSimpleClassName = $subSimpleClassNames.get($index))
|
||||||
#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
|
#set ($subJoinColumn_strikeCase = $subJoinColumn_strikeCases.get($index))
|
||||||
<el-tab-pane label="${subTable.classComment}" name="$subClassNameVar">
|
<el-tab-pane label="${subTable.classComment}" name="$subClassNameVar">
|
||||||
<${subSimpleClassName}List :${subJoinColumn_strikeCase}="currentRow.id" />
|
<${subSimpleClassName}List :${subJoinColumn_strikeCase}="currentRow.id" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
#end
|
#end
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
#end
|
#end
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
|
import { getIntDictOptions, getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||||
import { dateFormatter } from '@/utils/formatTime'
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
## 特殊:树表专属逻辑
|
## 特殊:树表专属逻辑
|
||||||
#if ( $table.templateType == 2 )
|
#if ( $table.templateType == 2 )
|
||||||
import { handleTree } from '@/utils/tree'
|
import { handleTree } from '@/utils/tree'
|
||||||
#end
|
#end
|
||||||
import download from '@/utils/download'
|
import download from '@/utils/download'
|
||||||
import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}'
|
import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${table.businessName}'
|
||||||
import ${simpleClassName}Form from './${simpleClassName}Form.vue'
|
import ${simpleClassName}Form from './${simpleClassName}Form.vue'
|
||||||
## 特殊:主子表专属逻辑
|
## 特殊:主子表专属逻辑
|
||||||
#if ( $table.templateType != 10 )
|
#if ( $table.templateType != 10 )
|
||||||
#foreach ($subSimpleClassName in $subSimpleClassNames)
|
#foreach ($subSimpleClassName in $subSimpleClassNames)
|
||||||
import ${subSimpleClassName}List from './components/${subSimpleClassName}List.vue'
|
import ${subSimpleClassName}List from './components/${subSimpleClassName}List.vue'
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
|
||||||
defineOptions({ name: '${table.className}' })
|
defineOptions({ name: '${table.className}' })
|
||||||
|
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
const { t } = useI18n() // 国际化
|
const { t } = useI18n() // 国际化
|
||||||
|
|
||||||
const loading = ref(true) // 列表的加载中
|
const loading = ref(true) // 列表的加载中
|
||||||
const list = ref([]) // 列表的数据
|
const list = ref([]) // 列表的数据
|
||||||
## 特殊:树表专属逻辑(树不需要分页接口)
|
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||||
#if ( $table.templateType != 2 )
|
#if ( $table.templateType != 2 )
|
||||||
const total = ref(0) // 列表的总页数
|
const total = ref(0) // 列表的总页数
|
||||||
|
#end
|
||||||
|
const queryParams = reactive({
|
||||||
|
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||||
|
#if ( $table.templateType != 2 )
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
#end
|
||||||
|
#foreach ($column in $columns)
|
||||||
|
#if ($column.listOperation)
|
||||||
|
#if ($column.listOperationCondition != 'BETWEEN')
|
||||||
|
$column.javaField: null,
|
||||||
|
#end
|
||||||
|
#if ($column.htmlType == "datetime" || $column.listOperationCondition == "BETWEEN")
|
||||||
|
$column.javaField: [],
|
||||||
#end
|
#end
|
||||||
const queryParams = reactive({
|
#end
|
||||||
## 特殊:树表专属逻辑(树不需要分页接口)
|
#end
|
||||||
#if ( $table.templateType != 2 )
|
})
|
||||||
pageNo: 1,
|
const queryFormRef = ref() // 搜索的表单
|
||||||
pageSize: 10,
|
const exportLoading = ref(false) // 导出的加载中
|
||||||
#end
|
|
||||||
#foreach ($column in $columns)
|
|
||||||
#if ($column.listOperation)
|
|
||||||
#if ($column.listOperationCondition != 'BETWEEN')
|
|
||||||
$column.javaField: null,
|
|
||||||
#end
|
|
||||||
#if ($column.htmlType == "datetime" || $column.listOperationCondition == "BETWEEN")
|
|
||||||
$column.javaField: [],
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
})
|
|
||||||
const queryFormRef = ref() // 搜索的表单
|
|
||||||
const exportLoading = ref(false) // 导出的加载中
|
|
||||||
|
|
||||||
/** 查询列表 */
|
/** 查询列表 */
|
||||||
const getList = async () => {
|
const getList = async () => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
## 特殊:树表专属逻辑(树不需要分页接口)
|
## 特殊:树表专属逻辑(树不需要分页接口)
|
||||||
#if ( $table.templateType == 2 )
|
#if ( $table.templateType == 2 )
|
||||||
const data = await ${simpleClassName}Api.get${simpleClassName}List(queryParams)
|
const data = await ${simpleClassName}Api.get${simpleClassName}List(queryParams)
|
||||||
list.value = handleTree(data, 'id', '${treeParentColumn.javaField}')
|
list.value = handleTree(data, 'id', '${treeParentColumn.javaField}')
|
||||||
#else
|
#else
|
||||||
const data = await ${simpleClassName}Api.get${simpleClassName}Page(queryParams)
|
const data = await ${simpleClassName}Api.get${simpleClassName}Page(queryParams)
|
||||||
list.value = data.list
|
list.value = data.list
|
||||||
total.value = data.total
|
total.value = data.total
|
||||||
#end
|
#end
|
||||||
} finally {
|
} finally {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** 搜索按钮操作 */
|
/** 搜索按钮操作 */
|
||||||
const handleQuery = () => {
|
const handleQuery = () => {
|
||||||
queryParams.pageNo = 1
|
queryParams.pageNo = 1
|
||||||
getList()
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
const resetQuery = () => {
|
||||||
|
queryFormRef.value.resetFields()
|
||||||
|
handleQuery()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 添加/修改操作 */
|
||||||
|
const formRef = ref()
|
||||||
|
const openForm = (type: string, id?: number) => {
|
||||||
|
formRef.value.open(type, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
const handleDelete = async (id: number) => {
|
||||||
|
try {
|
||||||
|
// 删除的二次确认
|
||||||
|
await message.delConfirm()
|
||||||
|
// 发起删除
|
||||||
|
await ${simpleClassName}Api.delete${simpleClassName}(id)
|
||||||
|
message.success(t('common.delSuccess'))
|
||||||
|
// 刷新列表
|
||||||
|
await getList()
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
const handleExport = async () => {
|
||||||
|
try {
|
||||||
|
// 导出的二次确认
|
||||||
|
await message.exportConfirm()
|
||||||
|
// 发起导出
|
||||||
|
exportLoading.value = true
|
||||||
|
const data = await ${simpleClassName}Api.export${simpleClassName}(queryParams)
|
||||||
|
download.excel(data, '${table.classComment}.xls')
|
||||||
|
} catch {
|
||||||
|
} finally {
|
||||||
|
exportLoading.value = false
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
## 特殊:主子表专属逻辑
|
||||||
|
#if ( $table.templateType == 11 )
|
||||||
|
|
||||||
/** 重置按钮操作 */
|
/** 选中行操作 */
|
||||||
const resetQuery = () => {
|
const currentRow = ref({}) // 选中行
|
||||||
queryFormRef.value.resetFields()
|
const handleCurrentChange = (row) => {
|
||||||
handleQuery()
|
currentRow.value = row
|
||||||
}
|
}
|
||||||
|
#end
|
||||||
|
## 特殊:树表专属逻辑
|
||||||
|
#if ( $table.templateType == 2 )
|
||||||
|
|
||||||
/** 添加/修改操作 */
|
/** 展开/折叠操作 */
|
||||||
const formRef = ref()
|
const isExpandAll = ref(true) // 是否展开,默认全部展开
|
||||||
const openForm = (type: string, id?: number) => {
|
const refreshTable = ref(true) // 重新渲染表格状态
|
||||||
formRef.value.open(type, id)
|
const toggleExpandAll = async () => {
|
||||||
}
|
refreshTable.value = false
|
||||||
|
isExpandAll.value = !isExpandAll.value
|
||||||
|
await nextTick()
|
||||||
|
refreshTable.value = true
|
||||||
|
}
|
||||||
|
#end
|
||||||
|
|
||||||
/** 删除按钮操作 */
|
/** 初始化 **/
|
||||||
const handleDelete = async (id: number) => {
|
onMounted(() => {
|
||||||
try {
|
getList()
|
||||||
// 删除的二次确认
|
})
|
||||||
await message.delConfirm()
|
|
||||||
// 发起删除
|
|
||||||
await ${simpleClassName}Api.delete${simpleClassName}(id)
|
|
||||||
message.success(t('common.delSuccess'))
|
|
||||||
// 刷新列表
|
|
||||||
await getList()
|
|
||||||
} catch {}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 导出按钮操作 */
|
|
||||||
const handleExport = async () => {
|
|
||||||
try {
|
|
||||||
// 导出的二次确认
|
|
||||||
await message.exportConfirm()
|
|
||||||
// 发起导出
|
|
||||||
exportLoading.value = true
|
|
||||||
const data = await ${simpleClassName}Api.export${simpleClassName}(queryParams)
|
|
||||||
download.excel(data, '${table.classComment}.xls')
|
|
||||||
} catch {
|
|
||||||
} finally {
|
|
||||||
exportLoading.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
## 特殊:主子表专属逻辑
|
|
||||||
#if ( $table.templateType == 11 )
|
|
||||||
|
|
||||||
/** 选中行操作 */
|
|
||||||
const currentRow = ref({}) // 选中行
|
|
||||||
const handleCurrentChange = (row) => {
|
|
||||||
currentRow.value = row
|
|
||||||
}
|
|
||||||
#end
|
|
||||||
## 特殊:树表专属逻辑
|
|
||||||
#if ( $table.templateType == 2 )
|
|
||||||
|
|
||||||
/** 展开/折叠操作 */
|
|
||||||
const isExpandAll = ref(true) // 是否展开,默认全部展开
|
|
||||||
const refreshTable = ref(true) // 重新渲染表格状态
|
|
||||||
const toggleExpandAll = async () => {
|
|
||||||
refreshTable.value = false
|
|
||||||
isExpandAll.value = !isExpandAll.value
|
|
||||||
await nextTick()
|
|
||||||
refreshTable.value = true
|
|
||||||
}
|
|
||||||
#end
|
|
||||||
|
|
||||||
/** 初始化 **/
|
|
||||||
onMounted(() => {
|
|
||||||
getList()
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
|
@ -10,33 +10,32 @@ import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO;
|
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO;
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO;
|
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO;
|
||||||
import cn.iocoder.yudao.module.infra.enums.codegen.*;
|
|
||||||
import cn.iocoder.yudao.module.infra.framework.codegen.config.CodegenProperties;
|
import cn.iocoder.yudao.module.infra.framework.codegen.config.CodegenProperties;
|
||||||
import org.apache.ibatis.type.JdbcType;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
import org.mockito.Spy;
|
import org.mockito.Spy;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link CodegenEngine} 的单元测试
|
* {@link CodegenEngine} 的单元测试抽象基类
|
||||||
*
|
*
|
||||||
* @author 芋道源码
|
* @author 芋道源码
|
||||||
*/
|
*/
|
||||||
public class CodegenEngineTest extends BaseMockitoUnitTest {
|
public abstract class CodegenEngineAbstractTest extends BaseMockitoUnitTest {
|
||||||
|
|
||||||
@InjectMocks
|
@InjectMocks
|
||||||
private CodegenEngine codegenEngine;
|
protected CodegenEngine codegenEngine;
|
||||||
|
|
||||||
@Spy
|
@Spy
|
||||||
private CodegenProperties codegenProperties = new CodegenProperties()
|
protected CodegenProperties codegenProperties = new CodegenProperties()
|
||||||
.setBasePackage("cn.iocoder.yudao");
|
.setBasePackage("cn.iocoder.yudao");
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
|
@ -44,87 +43,12 @@ public class CodegenEngineTest extends BaseMockitoUnitTest {
|
||||||
codegenEngine.initGlobalBindingMap();
|
codegenEngine.initGlobalBindingMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
protected static CodegenTableDO getTable(String name) {
|
||||||
public void testExecute_vue3_one() {
|
|
||||||
// 准备参数
|
|
||||||
CodegenTableDO table = getTable("student")
|
|
||||||
.setFrontType(CodegenFrontTypeEnum.VUE3.getType())
|
|
||||||
.setTemplateType(CodegenTemplateTypeEnum.ONE.getType());
|
|
||||||
List<CodegenColumnDO> columns = getColumnList("student");
|
|
||||||
|
|
||||||
// 调用
|
|
||||||
Map<String, String> result = codegenEngine.execute(table, columns, null, null);
|
|
||||||
// 断言
|
|
||||||
assertResult(result, "codegen/vue3_one");
|
|
||||||
// writeResult(result, "/root/ruoyi-vue-pro/yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue3_one");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testExecute_vue3_tree() {
|
|
||||||
// 准备参数
|
|
||||||
CodegenTableDO table = getTable("category")
|
|
||||||
.setFrontType(CodegenFrontTypeEnum.VUE3.getType())
|
|
||||||
.setTemplateType(CodegenTemplateTypeEnum.TREE.getType());
|
|
||||||
List<CodegenColumnDO> columns = getColumnList("category");
|
|
||||||
|
|
||||||
// 调用
|
|
||||||
Map<String, String> result = codegenEngine.execute(table, columns, null, null);
|
|
||||||
// 断言
|
|
||||||
assertResult(result, "codegen/vue3_tree");
|
|
||||||
// writeResult(result, "/root/ruoyi-vue-pro/yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue3_tree");
|
|
||||||
// writeFile(result, "/Users/yunai/test/demo66.zip");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testExecute_vue3_master_normal() {
|
|
||||||
testExecute_vue3_master(CodegenTemplateTypeEnum.MASTER_NORMAL, "codegen/vue3_master_normal");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testExecute_vue3_master_erp() {
|
|
||||||
testExecute_vue3_master(CodegenTemplateTypeEnum.MASTER_ERP, "codegen/vue3_master_erp");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testExecute_vue3_master_inner() {
|
|
||||||
testExecute_vue3_master(CodegenTemplateTypeEnum.MASTER_INNER, "codegen/vue3_master_inner");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void testExecute_vue3_master(CodegenTemplateTypeEnum templateType,
|
|
||||||
String path) {
|
|
||||||
// 准备参数
|
|
||||||
CodegenTableDO table = getTable("student")
|
|
||||||
.setFrontType(CodegenFrontTypeEnum.VUE3.getType())
|
|
||||||
.setTemplateType(templateType.getType());
|
|
||||||
List<CodegenColumnDO> columns = getColumnList("student");
|
|
||||||
// 准备参数(子表)
|
|
||||||
CodegenTableDO contactTable = getTable("contact")
|
|
||||||
.setTemplateType(CodegenTemplateTypeEnum.SUB.getType())
|
|
||||||
.setFrontType(CodegenFrontTypeEnum.VUE3.getType())
|
|
||||||
.setSubJoinColumnId(100L).setSubJoinMany(true);
|
|
||||||
List<CodegenColumnDO> contactColumns = getColumnList("contact");
|
|
||||||
// 准备参数(班主任)
|
|
||||||
CodegenTableDO teacherTable = getTable("teacher")
|
|
||||||
.setTemplateType(CodegenTemplateTypeEnum.SUB.getType())
|
|
||||||
.setFrontType(CodegenFrontTypeEnum.VUE3.getType())
|
|
||||||
.setSubJoinColumnId(200L).setSubJoinMany(false);
|
|
||||||
List<CodegenColumnDO> teacherColumns = getColumnList("teacher");
|
|
||||||
|
|
||||||
// 调用
|
|
||||||
Map<String, String> result = codegenEngine.execute(table, columns,
|
|
||||||
Arrays.asList(contactTable, teacherTable), Arrays.asList(contactColumns, teacherColumns));
|
|
||||||
// 断言
|
|
||||||
assertResult(result, path);
|
|
||||||
// writeResult(result, "/root/ruoyi-vue-pro/yudao-module-infra/yudao-module-infra-biz/src/test/resources/" + path);
|
|
||||||
// writeFile(result, "/Users/yunai/test/demo11.zip");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static CodegenTableDO getTable(String name) {
|
|
||||||
String content = ResourceUtil.readUtf8Str("codegen/table/" + name + ".json");
|
String content = ResourceUtil.readUtf8Str("codegen/table/" + name + ".json");
|
||||||
return JsonUtils.parseObject(content, "table", CodegenTableDO.class);
|
return JsonUtils.parseObject(content, "table", CodegenTableDO.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<CodegenColumnDO> getColumnList(String name) {
|
protected static List<CodegenColumnDO> getColumnList(String name) {
|
||||||
String content = ResourceUtil.readUtf8Str("codegen/table/" + name + ".json");
|
String content = ResourceUtil.readUtf8Str("codegen/table/" + name + ".json");
|
||||||
List<CodegenColumnDO> list = JsonUtils.parseArray(content, "columns", CodegenColumnDO.class);
|
List<CodegenColumnDO> list = JsonUtils.parseArray(content, "columns", CodegenColumnDO.class);
|
||||||
list.forEach(column -> {
|
list.forEach(column -> {
|
||||||
|
@ -148,7 +72,7 @@ public class CodegenEngineTest extends BaseMockitoUnitTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
private static void assertResult(Map<String, String> result, String path) {
|
protected static void assertResult(Map<String, String> result, String path) {
|
||||||
String assertContent = ResourceUtil.readUtf8Str(path + "/assert.json");
|
String assertContent = ResourceUtil.readUtf8Str(path + "/assert.json");
|
||||||
List<HashMap> asserts = JsonUtils.parseArray(assertContent, HashMap.class);
|
List<HashMap> asserts = JsonUtils.parseArray(assertContent, HashMap.class);
|
||||||
assertEquals(asserts.size(), result.size());
|
assertEquals(asserts.size(), result.size());
|
||||||
|
@ -169,7 +93,7 @@ public class CodegenEngineTest extends BaseMockitoUnitTest {
|
||||||
* @param result 生成的代码
|
* @param result 生成的代码
|
||||||
* @param path 写入文件的路径
|
* @param path 写入文件的路径
|
||||||
*/
|
*/
|
||||||
private void writeFile(Map<String, String> result, String path) {
|
protected void writeFile(Map<String, String> result, String path) {
|
||||||
// 生成压缩包
|
// 生成压缩包
|
||||||
String[] paths = result.keySet().toArray(new String[0]);
|
String[] paths = result.keySet().toArray(new String[0]);
|
||||||
ByteArrayInputStream[] ins = result.values().stream().map(IoUtil::toUtf8Stream).toArray(ByteArrayInputStream[]::new);
|
ByteArrayInputStream[] ins = result.values().stream().map(IoUtil::toUtf8Stream).toArray(ByteArrayInputStream[]::new);
|
||||||
|
@ -185,7 +109,7 @@ public class CodegenEngineTest extends BaseMockitoUnitTest {
|
||||||
* @param result 生成的代码
|
* @param result 生成的代码
|
||||||
* @param basePath 写入文件的路径(绝对路径)
|
* @param basePath 写入文件的路径(绝对路径)
|
||||||
*/
|
*/
|
||||||
private void writeResult(Map<String, String> result, String basePath) {
|
protected void writeResult(Map<String, String> result, String basePath) {
|
||||||
// 写入文件内容
|
// 写入文件内容
|
||||||
List<Map<String, String>> asserts = new ArrayList<>();
|
List<Map<String, String>> asserts = new ArrayList<>();
|
||||||
result.forEach((filePath, fileContent) -> {
|
result.forEach((filePath, fileContent) -> {
|
|
@ -1,47 +1,21 @@
|
||||||
package cn.iocoder.yudao.module.infra.service.codegen.inner;
|
package cn.iocoder.yudao.module.infra.service.codegen.inner;
|
||||||
|
|
||||||
import cn.hutool.core.io.FileUtil;
|
|
||||||
import cn.hutool.core.io.IoUtil;
|
|
||||||
import cn.hutool.core.io.resource.ResourceUtil;
|
|
||||||
import cn.hutool.core.map.MapUtil;
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import cn.hutool.core.util.ZipUtil;
|
|
||||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
|
||||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO;
|
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO;
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO;
|
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO;
|
||||||
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenFrontTypeEnum;
|
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenFrontTypeEnum;
|
||||||
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenTemplateTypeEnum;
|
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenTemplateTypeEnum;
|
||||||
import cn.iocoder.yudao.module.infra.framework.codegen.config.CodegenProperties;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.mockito.InjectMocks;
|
|
||||||
import org.mockito.Spy;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.util.Arrays;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.util.List;
|
||||||
import java.util.*;
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link CodegenEngine} 的单元测试
|
* {@link CodegenEngine} 的 Vue2 + Element UI 单元测试
|
||||||
*
|
*
|
||||||
* @author 芋道源码
|
* @author 芋道源码
|
||||||
*/
|
*/
|
||||||
public class CodegenEngineVue2Test extends BaseMockitoUnitTest {
|
public class CodegenEngineVue2Test extends CodegenEngineAbstractTest {
|
||||||
|
|
||||||
@InjectMocks
|
|
||||||
private CodegenEngine codegenEngine;
|
|
||||||
|
|
||||||
@Spy
|
|
||||||
private CodegenProperties codegenProperties = new CodegenProperties()
|
|
||||||
.setBasePackage("cn.iocoder.yudao");
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
public void setUp() {
|
|
||||||
codegenEngine.initGlobalBindingMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExecute_vue2_one() {
|
public void testExecute_vue2_one() {
|
||||||
|
@ -118,85 +92,4 @@ public class CodegenEngineVue2Test extends BaseMockitoUnitTest {
|
||||||
// writeFile(result, "/Users/yunai/test/demo11.zip");
|
// writeFile(result, "/Users/yunai/test/demo11.zip");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static CodegenTableDO getTable(String name) {
|
|
||||||
String content = ResourceUtil.readUtf8Str("codegen/table/" + name + ".json");
|
|
||||||
return JsonUtils.parseObject(content, "table", CodegenTableDO.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<CodegenColumnDO> getColumnList(String name) {
|
|
||||||
String content = ResourceUtil.readUtf8Str("codegen/table/" + name + ".json");
|
|
||||||
List<CodegenColumnDO> list = JsonUtils.parseArray(content, "columns", CodegenColumnDO.class);
|
|
||||||
list.forEach(column -> {
|
|
||||||
if (column.getNullable() == null) {
|
|
||||||
column.setNullable(false);
|
|
||||||
}
|
|
||||||
if (column.getCreateOperation() == null) {
|
|
||||||
column.setCreateOperation(false);
|
|
||||||
}
|
|
||||||
if (column.getUpdateOperation() == null) {
|
|
||||||
column.setUpdateOperation(false);
|
|
||||||
}
|
|
||||||
if (column.getListOperation() == null) {
|
|
||||||
column.setListOperation(false);
|
|
||||||
}
|
|
||||||
if (column.getListOperationResult() == null) {
|
|
||||||
column.setListOperationResult(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("rawtypes")
|
|
||||||
private static void assertResult(Map<String, String> result, String path) {
|
|
||||||
String assertContent = ResourceUtil.readUtf8Str(path + "/assert.json");
|
|
||||||
List<HashMap> asserts = JsonUtils.parseArray(assertContent, HashMap.class);
|
|
||||||
assertEquals(asserts.size(), result.size());
|
|
||||||
// 校验每个文件
|
|
||||||
asserts.forEach(assertMap -> {
|
|
||||||
String contentPath = (String) assertMap.get("contentPath");
|
|
||||||
String filePath = (String) assertMap.get("filePath");
|
|
||||||
String content = ResourceUtil.readUtf8Str(path + "/" + contentPath);
|
|
||||||
assertEquals(content, result.get(filePath), filePath + ":不匹配");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==================== 调试专用 ====================
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【调试使用】将生成的代码,写入到文件
|
|
||||||
*
|
|
||||||
* @param result 生成的代码
|
|
||||||
* @param path 写入文件的路径
|
|
||||||
*/
|
|
||||||
private void writeFile(Map<String, String> result, String path) {
|
|
||||||
// 生成压缩包
|
|
||||||
String[] paths = result.keySet().toArray(new String[0]);
|
|
||||||
ByteArrayInputStream[] ins = result.values().stream().map(IoUtil::toUtf8Stream).toArray(ByteArrayInputStream[]::new);
|
|
||||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
|
||||||
ZipUtil.zip(outputStream, paths, ins);
|
|
||||||
// 写入文件
|
|
||||||
FileUtil.writeBytes(outputStream.toByteArray(), path);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 【调试使用】将生成的结果,写入到文件
|
|
||||||
*
|
|
||||||
* @param result 生成的代码
|
|
||||||
* @param basePath 写入文件的路径(绝对路径)
|
|
||||||
*/
|
|
||||||
private void writeResult(Map<String, String> result, String basePath) {
|
|
||||||
// 写入文件内容
|
|
||||||
List<Map<String, String>> asserts = new ArrayList<>();
|
|
||||||
result.forEach((filePath, fileContent) -> {
|
|
||||||
String lastFilePath = StrUtil.subAfter(filePath, '/', true);
|
|
||||||
String contentPath = StrUtil.subAfter(lastFilePath, '.', true)
|
|
||||||
+ '/' + StrUtil.subBefore(lastFilePath, '.', true);
|
|
||||||
asserts.add(MapUtil.<String, String>builder().put("filePath", filePath)
|
|
||||||
.put("contentPath", contentPath).build());
|
|
||||||
FileUtil.writeUtf8String(fileContent, basePath + "/" + contentPath);
|
|
||||||
});
|
|
||||||
// 写入 assert.json 文件
|
|
||||||
FileUtil.writeUtf8String(JsonUtils.toJsonPrettyString(asserts), basePath +"/assert.json");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
package cn.iocoder.yudao.module.infra.service.codegen.inner;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenFrontTypeEnum;
|
||||||
|
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenTemplateTypeEnum;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link CodegenEngine} 的 Vue2 + Element Plus 单元测试
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
public class CodegenEngineVue3Test extends CodegenEngineAbstractTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExecute_vue3_one() {
|
||||||
|
// 准备参数
|
||||||
|
CodegenTableDO table = getTable("student")
|
||||||
|
.setFrontType(CodegenFrontTypeEnum.VUE3.getType())
|
||||||
|
.setTemplateType(CodegenTemplateTypeEnum.ONE.getType());
|
||||||
|
List<CodegenColumnDO> columns = getColumnList("student");
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
Map<String, String> result = codegenEngine.execute(table, columns, null, null);
|
||||||
|
// 断言
|
||||||
|
assertResult(result, "codegen/vue3_one");
|
||||||
|
// writeResult(result, "/root/ruoyi-vue-pro/yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue3_one");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExecute_vue3_tree() {
|
||||||
|
// 准备参数
|
||||||
|
CodegenTableDO table = getTable("category")
|
||||||
|
.setFrontType(CodegenFrontTypeEnum.VUE3.getType())
|
||||||
|
.setTemplateType(CodegenTemplateTypeEnum.TREE.getType());
|
||||||
|
List<CodegenColumnDO> columns = getColumnList("category");
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
Map<String, String> result = codegenEngine.execute(table, columns, null, null);
|
||||||
|
// 断言
|
||||||
|
assertResult(result, "codegen/vue3_tree");
|
||||||
|
// writeResult(result, "/root/ruoyi-vue-pro/yudao-module-infra/yudao-module-infra-biz/src/test/resources/codegen/vue3_tree");
|
||||||
|
// writeFile(result, "/Users/yunai/test/demo66.zip");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExecute_vue3_master_normal() {
|
||||||
|
testExecute_vue3_master(CodegenTemplateTypeEnum.MASTER_NORMAL, "codegen/vue3_master_normal");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExecute_vue3_master_erp() {
|
||||||
|
testExecute_vue3_master(CodegenTemplateTypeEnum.MASTER_ERP, "codegen/vue3_master_erp");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExecute_vue3_master_inner() {
|
||||||
|
testExecute_vue3_master(CodegenTemplateTypeEnum.MASTER_INNER, "codegen/vue3_master_inner");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testExecute_vue3_master(CodegenTemplateTypeEnum templateType,
|
||||||
|
String path) {
|
||||||
|
// 准备参数
|
||||||
|
CodegenTableDO table = getTable("student")
|
||||||
|
.setFrontType(CodegenFrontTypeEnum.VUE3.getType())
|
||||||
|
.setTemplateType(templateType.getType());
|
||||||
|
List<CodegenColumnDO> columns = getColumnList("student");
|
||||||
|
// 准备参数(子表)
|
||||||
|
CodegenTableDO contactTable = getTable("contact")
|
||||||
|
.setTemplateType(CodegenTemplateTypeEnum.SUB.getType())
|
||||||
|
.setFrontType(CodegenFrontTypeEnum.VUE3.getType())
|
||||||
|
.setSubJoinColumnId(100L).setSubJoinMany(true);
|
||||||
|
List<CodegenColumnDO> contactColumns = getColumnList("contact");
|
||||||
|
// 准备参数(班主任)
|
||||||
|
CodegenTableDO teacherTable = getTable("teacher")
|
||||||
|
.setTemplateType(CodegenTemplateTypeEnum.SUB.getType())
|
||||||
|
.setFrontType(CodegenFrontTypeEnum.VUE3.getType())
|
||||||
|
.setSubJoinColumnId(200L).setSubJoinMany(false);
|
||||||
|
List<CodegenColumnDO> teacherColumns = getColumnList("teacher");
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
Map<String, String> result = codegenEngine.execute(table, columns,
|
||||||
|
Arrays.asList(contactTable, teacherTable), Arrays.asList(contactColumns, teacherColumns));
|
||||||
|
// 断言
|
||||||
|
assertResult(result, path);
|
||||||
|
// writeResult(result, "/root/ruoyi-vue-pro/yudao-module-infra/yudao-module-infra-biz/src/test/resources/" + path);
|
||||||
|
// writeFile(result, "/Users/yunai/test/demo11.zip");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue