Browse Source

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

YunaiV 6 months ago
parent
commit
94a1c4636f

+ 2 - 2
yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngine.java

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

+ 9 - 10
yudao-module-infra/src/main/resources/codegen/vue3_admin_uniapp/api/api.ts.vm

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

+ 20 - 12
yudao-module-infra/src/main/resources/codegen/vue3_admin_uniapp/views/detail/index.vue.vm

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

+ 61 - 33
yudao-module-infra/src/main/resources/codegen/vue3_admin_uniapp/views/form/index.vue.vm

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