feat:【infra】移动端 admin uniapp 的代码生成的优化(api.ts、detail、form 的模版)

This commit is contained in:
YunaiV 2025-12-16 23:33:01 +08:00
parent 33fb112dfe
commit 94a1c4636f
4 changed files with 92 additions and 57 deletions

View File

@ -397,8 +397,8 @@ public class CodegenEngine {
* @return 格式化后的代码 * @return 格式化后的代码
*/ */
private String prettyCode(String content, String vmPath) { private String prettyCode(String content, String vmPath) {
// Vue 界面去除字段后面多余的 , 逗号解决前端的 Pretty 代码格式检查的报错需要排除 vben5 // Vue 界面去除字段后面多余的 , 逗号解决前端的 Pretty 代码格式检查的报错需要排除 vben5vue3_admin_uniapp
if (!StrUtil.contains(vmPath, "vben5")) { if (!StrUtil.containsAny(vmPath, "vben5", "vue3_admin_uniapp")) {
content = content.replaceAll(",\n}", "\n}").replaceAll(",\n }", "\n }"); content = content.replaceAll(",\n}", "\n}").replaceAll(",\n }", "\n }");
} }
// Vue 界面去除多的 dateFormatter只有一个的情况下说明没使用到 // Vue 界面去除多的 dateFormatter只有一个的情况下说明没使用到

View File

@ -1,10 +1,6 @@
import type { PageParam, PageResult } from '@/http/types' import type { PageParam, PageResult } from '@/http/types'
import { http } from '@/http/http' import { http } from '@/http/http'
// TODO @AI不使用 baseUrl而是参考之前的直接写在每个方法里。
#set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}")
const baseUrl = '${baseURL}'
#set ($primaryJavaType = $primaryColumn.javaType.toLowerCase()) #set ($primaryJavaType = $primaryColumn.javaType.toLowerCase())
#if(${primaryJavaType} == "long" || ${primaryJavaType} == "integer" || ${primaryJavaType} == "short" || ${primaryJavaType} == "double" || ${primaryJavaType} == "bigdecimal" || ${primaryJavaType} == "byte") #if(${primaryJavaType} == "long" || ${primaryJavaType} == "integer" || ${primaryJavaType} == "short" || ${primaryJavaType} == "double" || ${primaryJavaType} == "bigdecimal" || ${primaryJavaType} == "byte")
#set ($primaryTsType = "number") #set ($primaryTsType = "number")
@ -17,9 +13,12 @@ export interface ${simpleClassName} {
#foreach ($column in $columns) #foreach ($column in $columns)
#if ($column.primaryKey || $column.createOperation || $column.updateOperation || $column.listOperationResult) #if ($column.primaryKey || $column.createOperation || $column.updateOperation || $column.listOperationResult)
#set ($javaType = $column.javaType.toLowerCase()) #set ($javaType = $column.javaType.toLowerCase())
#set ($optional = $column.nullable || $column.primaryKey) #set ($javaFieldLower = $column.javaField.toLowerCase())
#set ($optional = $column.nullable || $column.primaryKey || $javaFieldLower == "createtime" || $javaFieldLower == "updatetime")
#if(${javaType} == "long" || ${javaType} == "integer" || ${javaType} == "short" || ${javaType} == "double" || ${javaType} == "bigdecimal" || ${javaType} == "byte") #if(${javaType} == "long" || ${javaType} == "integer" || ${javaType} == "short" || ${javaType} == "double" || ${javaType} == "bigdecimal" || ${javaType} == "byte")
${column.javaField}#if($optional)?#end: number ${column.javaField}#if($optional)?#end: number
#elseif(${javaType} == "date" || ${javaType} == "localdate" || ${javaType} == "localdatetime")
${column.javaField}#if($optional)?#end: Date
#elseif(${javaType} == "boolean") #elseif(${javaType} == "boolean")
${column.javaField}#if($optional)?#end: boolean ${column.javaField}#if($optional)?#end: boolean
#else #else
@ -31,25 +30,25 @@ export interface ${simpleClassName} {
/** 获取${table.classComment}分页列表 */ /** 获取${table.classComment}分页列表 */
export function get${simpleClassName}Page(params: PageParam) { export function get${simpleClassName}Page(params: PageParam) {
return http.get<PageResult<${simpleClassName}>>(baseUrl + '/page', params) return http.get<PageResult<${simpleClassName}>>('/${table.moduleName}/${simpleClassName_strikeCase}/page', params)
} }
/** 获取${table.classComment}详情 */ /** 获取${table.classComment}详情 */
export function get${simpleClassName}(id: ${primaryTsType}) { export function get${simpleClassName}(id: ${primaryTsType}) {
return http.get<${simpleClassName}>(baseUrl + '/get?id=' + id) return http.get<${simpleClassName}>('/${table.moduleName}/${simpleClassName_strikeCase}/get?id=' + id)
} }
/** 创建${table.classComment} */ /** 创建${table.classComment} */
export function create${simpleClassName}(data: ${simpleClassName}) { export function create${simpleClassName}(data: ${simpleClassName}) {
return http.post<number>(baseUrl + '/create', data) return http.post<number>('/${table.moduleName}/${simpleClassName_strikeCase}/create', data)
} }
/** 更新${table.classComment} */ /** 更新${table.classComment} */
export function update${simpleClassName}(data: ${simpleClassName}) { export function update${simpleClassName}(data: ${simpleClassName}) {
return http.put<boolean>(baseUrl + '/update', data) return http.put<boolean>('/${table.moduleName}/${simpleClassName_strikeCase}/update', data)
} }
/** 删除${table.classComment} */ /** 删除${table.classComment} */
export function delete${simpleClassName}(id: ${primaryTsType}) { export function delete${simpleClassName}(id: ${primaryTsType}) {
return http.delete<boolean>(baseUrl + '/delete?id=' + id) return http.delete<boolean>('/${table.moduleName}/${simpleClassName_strikeCase}/delete?id=' + id)
} }

View File

@ -1,11 +1,13 @@
<template> <template>
<view class="page-container"> <view class="page-container">
<!-- 顶部导航栏 -->
<wd-navbar <wd-navbar
title="${table.classComment}详情" title="${table.classComment}详情"
left-arrow placeholder safe-area-inset-top fixed left-arrow placeholder safe-area-inset-top fixed
@click-left="handleBack" @click-left="handleBack"
/> />
<!-- 详情内容 -->
<view> <view>
<wd-cell-group border> <wd-cell-group border>
#foreach($column in $columns) #foreach($column in $columns)
@ -26,6 +28,7 @@
</wd-cell-group> </wd-cell-group>
</view> </view>
<!-- 底部操作按钮 -->
<view class="fixed bottom-0 left-0 right-0 bg-white p-24rpx"> <view class="fixed bottom-0 left-0 right-0 bg-white p-24rpx">
<view class="w-full flex gap-24rpx"> <view class="w-full flex gap-24rpx">
<wd-button <wd-button
@ -46,27 +49,27 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import type { ${simpleClassName} } from '@/api/${table.moduleName}/${table.businessName}'
import { onMounted, ref } from 'vue'
import { useToast } from 'wot-design-uni'
import { delete${simpleClassName}, get${simpleClassName} } from '@/api/${table.moduleName}/${table.businessName}'
import { useAccess } from '@/hooks/useAccess'
import { navigateBackPlus } from '@/utils'
#set ($hasDict = 0) #set ($hasDict = 0)
#foreach($column in $columns) #foreach($column in $columns)
#if ($hasDict == 0 && $column.dictType && "" != $column.dictType) #if ($hasDict == 0 && $column.dictType && "" != $column.dictType)
#set ($hasDict = 1) #set ($hasDict = 1)
#end #end
#end #end
#if ($hasDict == 1)
import { DICT_TYPE } from '@/utils/constants'
#end
#set ($hasDateTime = 0) #set ($hasDateTime = 0)
#foreach($column in $columns) #foreach($column in $columns)
#if ($hasDateTime == 0 && $column.javaType == "LocalDateTime") #if ($hasDateTime == 0 && $column.javaType == "LocalDateTime")
#set ($hasDateTime = 1) #set ($hasDateTime = 1)
#end #end
#end #end
import type { ${simpleClassName} } from '@/api/${table.moduleName}/${table.businessName}'
import { onMounted, ref } from 'vue'
import { useToast } from 'wot-design-uni'
import { delete${simpleClassName}, get${simpleClassName} } from '@/api/${table.moduleName}/${table.businessName}'
import { useAccess } from '@/hooks/useAccess'
import { navigateBackPlus } from '@/utils'
#if ($hasDict == 1)
import { DICT_TYPE } from '@/utils/constants'
#end
#if ($hasDateTime == 1) #if ($hasDateTime == 1)
import { formatDateTime } from '@/utils/date' import { formatDateTime } from '@/utils/date'
#end #end
@ -84,13 +87,15 @@ definePage({
const { hasAccessByCodes } = useAccess() const { hasAccessByCodes } = useAccess()
const toast = useToast() const toast = useToast()
const formData = ref<${simpleClassName}>() const formData = ref<${simpleClassName}>() // 详情数据
const deleting = ref(false) const deleting = ref(false) // 删除中
/** 返回上一页 */
function handleBack() { function handleBack() {
navigateBackPlus('/pages-${table.moduleName}/${table.businessName}/index') navigateBackPlus('/pages-${table.moduleName}/${table.businessName}/index')
} }
/** 加载${table.classComment}详情 */
async function getDetail() { async function getDetail() {
if (!props.id) { if (!props.id) {
return return
@ -103,12 +108,14 @@ async function getDetail() {
} }
} }
/** 编辑${table.classComment} */
function handleEdit() { function handleEdit() {
uni.navigateTo({ uni.navigateTo({
url: '/pages-${table.moduleName}/${table.businessName}/form/index?id=' + props.id, url: `/pages-${table.moduleName}/${table.businessName}/form/index?id=\${props.id}`,
}) })
} }
/** 删除${table.classComment} */
function handleDelete() { function handleDelete() {
if (!props.id) { if (!props.id) {
return return
@ -134,6 +141,7 @@ function handleDelete() {
}) })
} }
/** 初始化 */
onMounted(() => { onMounted(() => {
getDetail() getDetail()
}) })

View File

@ -1,11 +1,13 @@
<template> <template>
<view class="page-container"> <view class="page-container">
<!-- 顶部导航栏 -->
<wd-navbar <wd-navbar
:title="getTitle" :title="getTitle"
left-arrow placeholder safe-area-inset-top fixed left-arrow placeholder safe-area-inset-top fixed
@click-left="handleBack" @click-left="handleBack"
/> />
<!-- 表单区域 -->
<view> <view>
<wd-form ref="formRef" :model="formData" :rules="formRules"> <wd-form ref="formRef" :model="formData" :rules="formRules">
<wd-cell-group border> <wd-cell-group border>
@ -23,18 +25,46 @@
#elseif ($javaType == "Boolean") #elseif ($javaType == "Boolean")
#set ($dictMethod = "getBoolDictOptions") #set ($dictMethod = "getBoolDictOptions")
#end #end
## 优先判断是否有字典,有字典则使用 radio-group
#if (${javaType.toLowerCase()} == "long" || ${javaType.toLowerCase()} == "integer" || ${javaType.toLowerCase()} == "short" || ${javaType.toLowerCase()} == "double" || ${javaType.toLowerCase()} == "bigdecimal" || ${javaType.toLowerCase()} == "byte") #if (($column.htmlType == "select" || $column.htmlType == "radio") && $dictType && "" != $dictType)
<wd-cell title="${comment}" title-width="180rpx" prop="${javaField}" center>
<wd-radio-group v-model="formData.${javaField}" shape="button" size="medium">
<wd-radio
v-for="dict in $dictMethod(DICT_TYPE.${dictType.toUpperCase()})"
:key="dict.value"
:value="dict.value"
>
{{ dict.label }}
</wd-radio>
</wd-radio-group>
</wd-cell>
## 数字类型(无字典)
#elseif (${javaType.toLowerCase()} == "long" || ${javaType.toLowerCase()} == "integer" || ${javaType.toLowerCase()} == "short" || ${javaType.toLowerCase()} == "double" || ${javaType.toLowerCase()} == "bigdecimal" || ${javaType.toLowerCase()} == "byte")
<wd-cell title="${comment}" title-width="180rpx" prop="${javaField}" center> <wd-cell title="${comment}" title-width="180rpx" prop="${javaField}" center>
<wd-input-number <wd-input-number
v-model="formData.${javaField}" v-model="formData.${javaField}"
:min="0" :min="0"
/> />
</wd-cell> </wd-cell>
## 布尔类型
#elseif (${javaType.toLowerCase()} == "boolean") #elseif (${javaType.toLowerCase()} == "boolean")
<wd-cell title="${comment}" title-width="180rpx" prop="${javaField}" center> <wd-cell title="${comment}" title-width="180rpx" prop="${javaField}" center>
<wd-switch v-model="formData.${javaField}" /> <wd-switch v-model="formData.${javaField}" />
</wd-cell> </wd-cell>
## 日期时间类型
#elseif (${javaType.toLowerCase()} == "date" || ${javaType.toLowerCase()} == "localdate" || ${javaType.toLowerCase()} == "localdatetime")
#set ($pickerType = "date")
#if (${javaType.toLowerCase()} == "localdatetime")
#set ($pickerType = "datetime")
#end
<wd-datetime-picker
v-model="formData.${javaField}"
type="${pickerType}"
label="${comment}"
label-width="180rpx"
prop="${javaField}"
/>
## 文本域
#elseif ($column.htmlType == "textarea") #elseif ($column.htmlType == "textarea")
<wd-textarea <wd-textarea
v-model="formData.${javaField}" v-model="formData.${javaField}"
@ -45,18 +75,7 @@
show-word-limit show-word-limit
clearable clearable
/> />
#elseif (($column.htmlType == "select" || $column.htmlType == "radio") && $dictType && "" != $dictType) ## 默认:文本输入
<wd-cell title="${comment}" title-width="180rpx" prop="${javaField}" center>
<wd-radio-group v-model="formData.${javaField}" shape="button" size="medium">
<wd-radio
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
:key="dict.value"
:value="dict.value"
>
{{ dict.label }}
</wd-radio>
</wd-radio-group>
</wd-cell>
#else #else
<wd-input <wd-input
v-model="formData.${javaField}" v-model="formData.${javaField}"
@ -73,6 +92,7 @@
</wd-form> </wd-form>
</view> </view>
<!-- 底部保存按钮 -->
<view class="fixed bottom-0 left-0 right-0 bg-white p-24rpx"> <view class="fixed bottom-0 left-0 right-0 bg-white p-24rpx">
<wd-button <wd-button
type="primary" type="primary"
@ -87,19 +107,12 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import type { ${simpleClassName} } from '@/api/${table.moduleName}/${table.businessName}'
import { computed, onMounted, ref } from 'vue'
import { useToast } from 'wot-design-uni'
import { create${simpleClassName}, get${simpleClassName}, update${simpleClassName} } from '@/api/${table.moduleName}/${table.businessName}'
import { navigateBackPlus } from '@/utils'
#set ($primaryJavaType = $primaryColumn.javaType.toLowerCase()) #set ($primaryJavaType = $primaryColumn.javaType.toLowerCase())
#if(${primaryJavaType} == "long" || ${primaryJavaType} == "integer" || ${primaryJavaType} == "short" || ${primaryJavaType} == "double" || ${primaryJavaType} == "bigdecimal" || ${primaryJavaType} == "byte") #if(${primaryJavaType} == "long" || ${primaryJavaType} == "integer" || ${primaryJavaType} == "short" || ${primaryJavaType} == "double" || ${primaryJavaType} == "bigdecimal" || ${primaryJavaType} == "byte")
#set ($primaryTsType = "number") #set ($primaryTsType = "number")
#else #else
#set ($primaryTsType = "string") #set ($primaryTsType = "string")
#end #end
#set ($hasDict = 0) #set ($hasDict = 0)
#set ($hasGetDictOptions = 0) #set ($hasGetDictOptions = 0)
#set ($hasGetIntDictOptions = 0) #set ($hasGetIntDictOptions = 0)
@ -121,22 +134,31 @@ import { navigateBackPlus } from '@/utils'
#end #end
#end #end
#end #end
import type { ${simpleClassName} } from '@/api/${table.moduleName}/${table.businessName}'
import { computed, onMounted, ref } from 'vue'
import { useToast } from 'wot-design-uni'
import { create${simpleClassName}, get${simpleClassName}, update${simpleClassName} } from '@/api/${table.moduleName}/${table.businessName}'
#if ($hasDict == 1) #if ($hasDict == 1)
import { DICT_TYPE } from '@/utils/constants' #set ($dictImportNames = "")
import {
#if ($hasGetDictOptions == 1) #if ($hasGetDictOptions == 1)
getDictOptions, #set ($dictImportNames = "${dictImportNames}getDictOptions, ")
#end #end
#if ($hasGetIntDictOptions == 1) #if ($hasGetIntDictOptions == 1)
getIntDictOptions, #set ($dictImportNames = "${dictImportNames}getIntDictOptions, ")
#end #end
#if ($hasGetStrDictOptions == 1) #if ($hasGetStrDictOptions == 1)
getStrDictOptions, #set ($dictImportNames = "${dictImportNames}getStrDictOptions, ")
#end #end
#if ($hasGetBoolDictOptions == 1) #if ($hasGetBoolDictOptions == 1)
getBoolDictOptions, #set ($dictImportNames = "${dictImportNames}getBoolDictOptions, ")
#end #end
} from '@/hooks/useDict' #set ($dictImportNames = $dictImportNames.trim())
#set ($dictImportNames = $dictImportNames.substring(0, $dictImportNames.length() - 1))
import { $dictImportNames } from '@/hooks/useDict'
#end
import { navigateBackPlus } from '@/utils'
#if ($hasDict == 1)
import { DICT_TYPE } from '@/utils/constants'
#end #end
const props = defineProps<{ const props = defineProps<{
@ -153,39 +175,43 @@ definePage({
const toast = useToast() const toast = useToast()
const getTitle = computed(() => props.id ? '编辑${table.classComment}' : '新增${table.classComment}') const getTitle = computed(() => props.id ? '编辑${table.classComment}' : '新增${table.classComment}')
const formLoading = ref(false) const formLoading = ref(false)
// TODO @AIdate + 时间范围,需要特殊处理;参考 /Users/yunai/Java/yudao-ui-admin-uniapp-next-v4/src/pages/message/components/search-form.vue 里的开始结束时间的处理注意index.vue.vm 也要调整;
const formData = ref<${simpleClassName}>({ const formData = ref<${simpleClassName}>({
#foreach($column in $columns) #foreach($column in $columns)
#if (($column.createOperation || $column.updateOperation) || $column.primaryKey) #if (($column.createOperation || $column.updateOperation) || $column.primaryKey)
#set ($javaType = $column.javaType.toLowerCase()) #set ($javaType = $column.javaType.toLowerCase())
#set ($javaFieldLower = $column.javaField.toLowerCase())
#set ($optional = $column.nullable || $column.primaryKey || $javaFieldLower == "createtime" || $javaFieldLower == "updatetime")
#if ($column.primaryKey) #if ($column.primaryKey)
${column.javaField}: undefined, ${column.javaField}: undefined,
#elseif(${javaType} == "long" || ${javaType} == "integer" || ${javaType} == "short" || ${javaType} == "double" || ${javaType} == "bigdecimal" || ${javaType} == "byte") #elseif(${javaType} == "long" || ${javaType} == "integer" || ${javaType} == "short" || ${javaType} == "double" || ${javaType} == "bigdecimal" || ${javaType} == "byte")
${column.javaField}: 0, ${column.javaField}: 0,
#elseif(${javaType} == "boolean") #elseif(${javaType} == "boolean")
${column.javaField}: false, ${column.javaField}: false,
#elseif(${javaType} == "date" || ${javaType} == "localdate" || ${javaType} == "localdatetime")
${column.javaField}: undefined,
#else #else
${column.javaField}: '', ${column.javaField}: '',
#end #end
#end #end
#end #end
}) })
const formRules = { const formRules = {
#foreach($column in $columns) #foreach($column in $columns)
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !$column.primaryKey) #set ($javaFieldLower = $column.javaField.toLowerCase())
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !$column.primaryKey
&& $javaFieldLower != "createtime" && $javaFieldLower != "updatetime")
${column.javaField}: [{ required: true, message: '${column.columnComment}不能为空' }], ${column.javaField}: [{ required: true, message: '${column.columnComment}不能为空' }],
#end #end
#end #end
} }
const formRef = ref() const formRef = ref()
/** 返回上一页 */
function handleBack() { function handleBack() {
navigateBackPlus('/pages-${table.moduleName}/${table.businessName}/index') navigateBackPlus('/pages-${table.moduleName}/${table.businessName}/index')
} }
/** 加载${table.classComment}详情 */
async function getDetail() { async function getDetail() {
if (!props.id) { if (!props.id) {
return return
@ -193,6 +219,7 @@ async function getDetail() {
formData.value = await get${simpleClassName}(props.id) formData.value = await get${simpleClassName}(props.id)
} }
/** 提交表单 */
async function handleSubmit() { async function handleSubmit() {
const { valid } = await formRef.value.validate() const { valid } = await formRef.value.validate()
if (!valid) { if (!valid) {
@ -216,6 +243,7 @@ async function handleSubmit() {
} }
} }
/** 初始化 */
onMounted(() => { onMounted(() => {
getDetail() getDetail()
}) })