Commit f6b5ef06d9481d3d4141463c18ed26f278ef256b
1 parent
adbec22e
feat(codegen):uniapp 表单生成器对齐 @wot-ui/ui 2.x + 修测试快照撞名
form 模板全量对齐 2.x: - :rules/formRules → :schema/createFormSchema(2.x wd-form 只认 schema) - 字段统一包 wd-form-item;下拉字典 → yd-form-picker 独立;radio shape→type - 日期时间 → wd-form-item 触发 + wd-datetime-picker 弹层 + xxxVisible; LocalDateTime 用 formatDateTime、Date/LocalDate 用 formatDate(import 按需) - 图片/文件上传 → yd-upload-img/file(原误生成文本框);小数补 precision - 包名 wot-design-uni(未装)→ @wot-ui/ui(form + detail) search-form:日期范围 → yd-search-date-range;radio shape→type 字典 import 按实际用量门控(纯 select 不越界) writeResult:同名快照撞名补父目录 + 序号兜底,assert 路径不变
Showing
7 changed files
with
182 additions
and
220 deletions
yudao-module-infra/src/main/resources/codegen/vue3_admin_uniapp/components/search-form.vue.vm
| @@ -40,49 +40,13 @@ | @@ -40,49 +40,13 @@ | ||
| 40 | /> | 40 | /> |
| 41 | </view> | 41 | </view> |
| 42 | #elseif ($column.htmlType == "datetime" && $listOperationCondition == "BETWEEN") | 42 | #elseif ($column.htmlType == "datetime" && $listOperationCondition == "BETWEEN") |
| 43 | - #set ($AttrName = $javaField.substring(0,1).toUpperCase() + ${javaField.substring(1)}) | ||
| 44 | - <view class="yd-search-form-item"> | ||
| 45 | - <view class="yd-search-form-label"> | ||
| 46 | - ${comment} | ||
| 47 | - </view> | ||
| 48 | - <view class="yd-search-form-date-range-container"> | ||
| 49 | - <view @click="visible${AttrName}[0] = true"> | ||
| 50 | - <view class="yd-search-form-date-range-picker"> | ||
| 51 | - {{ formatDate(formData.${javaField}?.[0]) || '开始日期' }} | ||
| 52 | - </view> | ||
| 53 | - </view> | ||
| 54 | - - | ||
| 55 | - <view @click="visible${AttrName}[1] = true"> | ||
| 56 | - <view class="yd-search-form-date-range-picker"> | ||
| 57 | - {{ formatDate(formData.${javaField}?.[1]) || '结束日期' }} | ||
| 58 | - </view> | ||
| 59 | - </view> | ||
| 60 | - </view> | ||
| 61 | - <wd-datetime-picker-view v-if="visible${AttrName}[0]" v-model="temp${AttrName}[0]" type="date" /> | ||
| 62 | - <view v-if="visible${AttrName}[0]" class="yd-search-form-date-range-actions"> | ||
| 63 | - <wd-button size="small" plain @click="visible${AttrName}[0] = false"> | ||
| 64 | - 取消 | ||
| 65 | - </wd-button> | ||
| 66 | - <wd-button size="small" type="primary" @click="handle${AttrName}0Confirm"> | ||
| 67 | - 确定 | ||
| 68 | - </wd-button> | ||
| 69 | - </view> | ||
| 70 | - <wd-datetime-picker-view v-if="visible${AttrName}[1]" v-model="temp${AttrName}[1]" type="date" /> | ||
| 71 | - <view v-if="visible${AttrName}[1]" class="yd-search-form-date-range-actions"> | ||
| 72 | - <wd-button size="small" plain @click="visible${AttrName}[1] = false"> | ||
| 73 | - 取消 | ||
| 74 | - </wd-button> | ||
| 75 | - <wd-button size="small" type="primary" @click="handle${AttrName}1Confirm"> | ||
| 76 | - 确定 | ||
| 77 | - </wd-button> | ||
| 78 | - </view> | ||
| 79 | - </view> | 43 | + <yd-search-date-range v-model="formData.${javaField}" label="${comment}" /> |
| 80 | #elseif (($column.htmlType == "select" || $column.htmlType == "radio") && $dictType && "" != $dictType) | 44 | #elseif (($column.htmlType == "select" || $column.htmlType == "radio") && $dictType && "" != $dictType) |
| 81 | <view class="yd-search-form-item"> | 45 | <view class="yd-search-form-item"> |
| 82 | <view class="yd-search-form-label"> | 46 | <view class="yd-search-form-label"> |
| 83 | ${comment} | 47 | ${comment} |
| 84 | </view> | 48 | </view> |
| 85 | - <wd-radio-group v-model="formData.${javaField}" shape="button"> | 49 | + <wd-radio-group v-model="formData.${javaField}" type="button"> |
| 86 | <wd-radio :value="-1"> | 50 | <wd-radio :value="-1"> |
| 87 | 全部 | 51 | 全部 |
| 88 | </wd-radio> | 52 | </wd-radio> |
| @@ -236,29 +200,6 @@ const placeholder = computed(() => { | @@ -236,29 +200,6 @@ const placeholder = computed(() => { | ||
| 236 | return conditions.length > 0 ? conditions.join(' | ') : '搜索${table.classComment}' | 200 | return conditions.length > 0 ? conditions.join(' | ') : '搜索${table.classComment}' |
| 237 | }) | 201 | }) |
| 238 | 202 | ||
| 239 | -#if ($hasDateTimeBetween == 1) | ||
| 240 | -#foreach($column in $columns) | ||
| 241 | - #if ($column.listOperation && $column.htmlType == "datetime" && $column.listOperationCondition == "BETWEEN") | ||
| 242 | - #set ($javaField = $column.javaField) | ||
| 243 | - #set ($AttrName = $javaField.substring(0,1).toUpperCase() + ${javaField.substring(1)}) | ||
| 244 | -const visible${AttrName} = ref<[boolean, boolean]>([false, false]) // ${column.columnComment}选择器状态 | ||
| 245 | -const temp${AttrName} = ref<[number, number]>([Date.now(), Date.now()]) // ${column.columnComment}临时值 | ||
| 246 | - | ||
| 247 | -/** 确认${column.columnComment}开始日期 */ | ||
| 248 | -function handle${AttrName}0Confirm() { | ||
| 249 | - formData.${javaField} = [temp${AttrName}.value[0], formData.${javaField}?.[1]] | ||
| 250 | - visible${AttrName}.value[0] = false | ||
| 251 | -} | ||
| 252 | - | ||
| 253 | -/** 确认${column.columnComment}结束日期 */ | ||
| 254 | -function handle${AttrName}1Confirm() { | ||
| 255 | - formData.${javaField} = [formData.${javaField}?.[0], temp${AttrName}.value[1]] | ||
| 256 | - visible${AttrName}.value[1] = false | ||
| 257 | -} | ||
| 258 | - #end | ||
| 259 | -#end | ||
| 260 | -#end | ||
| 261 | - | ||
| 262 | /** 搜索按钮操作 */ | 203 | /** 搜索按钮操作 */ |
| 263 | function handleSearch() { | 204 | function handleSearch() { |
| 264 | visible.value = false | 205 | visible.value = false |
yudao-module-infra/src/main/resources/codegen/vue3_admin_uniapp/views/detail/index.vue.vm
| @@ -64,7 +64,7 @@ | @@ -64,7 +64,7 @@ | ||
| 64 | import type { ${simpleClassName} } from '@/api/${table.moduleName}/${table.businessName}' | 64 | import type { ${simpleClassName} } from '@/api/${table.moduleName}/${table.businessName}' |
| 65 | import { onUnload } from '@dcloudio/uni-app' | 65 | import { onUnload } from '@dcloudio/uni-app' |
| 66 | import { onMounted, ref } from 'vue' | 66 | import { onMounted, ref } from 'vue' |
| 67 | -import { useToast } from 'wot-design-uni' | 67 | +import { useToast } from '@wot-ui/ui/components/wd-toast' |
| 68 | import { delete${simpleClassName}, get${simpleClassName} } from '@/api/${table.moduleName}/${table.businessName}' | 68 | import { delete${simpleClassName}, get${simpleClassName} } from '@/api/${table.moduleName}/${table.businessName}' |
| 69 | import { useAccess } from '@/hooks/useAccess' | 69 | import { useAccess } from '@/hooks/useAccess' |
| 70 | import { navigateBackPlus } from '@/utils' | 70 | import { navigateBackPlus } from '@/utils' |
yudao-module-infra/src/main/resources/codegen/vue3_admin_uniapp/views/form/index.vue.vm
| @@ -9,7 +9,7 @@ | @@ -9,7 +9,7 @@ | ||
| 9 | 9 | ||
| 10 | <!-- 表单区域 --> | 10 | <!-- 表单区域 --> |
| 11 | <view> | 11 | <view> |
| 12 | - <wd-form ref="formRef" :model="formData" :rules="formRules"> | 12 | + <wd-form ref="formRef" :model="formData" :schema="formSchema"> |
| 13 | <wd-cell-group border> | 13 | <wd-cell-group border> |
| 14 | #foreach($column in $columns) | 14 | #foreach($column in $columns) |
| 15 | #if (($column.createOperation || $column.updateOperation) && !$column.primaryKey) | 15 | #if (($column.createOperation || $column.updateOperation) && !$column.primaryKey) |
| @@ -25,10 +25,23 @@ | @@ -25,10 +25,23 @@ | ||
| 25 | #elseif ($javaType == "Boolean") | 25 | #elseif ($javaType == "Boolean") |
| 26 | #set ($dictMethod = "getBoolDictOptions") | 26 | #set ($dictMethod = "getBoolDictOptions") |
| 27 | #end | 27 | #end |
| 28 | - ## 优先判断是否有字典,有字典则使用 radio-group | ||
| 29 | - #if (($column.htmlType == "select" || $column.htmlType == "radio") && $dictType && "" != $dictType) | ||
| 30 | - <wd-cell title="${comment}" title-width="180rpx" prop="${javaField}" center> | ||
| 31 | - <wd-radio-group v-model="formData.${javaField}" shape="button"> | 28 | + ## 下拉选择(字典)→ yd-form-picker,内部按 dictType 解析选项,适合选项较多 |
| 29 | + #if ($column.htmlType == "select" && $dictType && "" != $dictType) | ||
| 30 | + <yd-form-picker | ||
| 31 | + v-model="formData.${javaField}" | ||
| 32 | + label="${comment}" | ||
| 33 | + label-width="180rpx" | ||
| 34 | + prop="${javaField}" | ||
| 35 | + :dict-type="DICT_TYPE.${dictType.toUpperCase()}" | ||
| 36 | +#if ($javaType == "String") | ||
| 37 | + dict-kind="str" | ||
| 38 | +#end | ||
| 39 | + placeholder="请选择${comment}" | ||
| 40 | + /> | ||
| 41 | + ## 单选(字典)→ radio-group,适合选项较少 | ||
| 42 | + #elseif ($column.htmlType == "radio" && $dictType && "" != $dictType) | ||
| 43 | + <wd-form-item title="${comment}" title-width="180rpx" prop="${javaField}" center> | ||
| 44 | + <wd-radio-group v-model="formData.${javaField}" type="button"> | ||
| 32 | <wd-radio | 45 | <wd-radio |
| 33 | v-for="dict in $dictMethod(DICT_TYPE.${dictType.toUpperCase()})" | 46 | v-for="dict in $dictMethod(DICT_TYPE.${dictType.toUpperCase()})" |
| 34 | :key="dict.value" | 47 | :key="dict.value" |
| @@ -37,54 +50,78 @@ | @@ -37,54 +50,78 @@ | ||
| 37 | {{ dict.label }} | 50 | {{ dict.label }} |
| 38 | </wd-radio> | 51 | </wd-radio> |
| 39 | </wd-radio-group> | 52 | </wd-radio-group> |
| 40 | - </wd-cell> | 53 | + </wd-form-item> |
| 41 | ## 数字类型(无字典) | 54 | ## 数字类型(无字典) |
| 42 | #elseif (${javaType.toLowerCase()} == "long" || ${javaType.toLowerCase()} == "integer" || ${javaType.toLowerCase()} == "short" || ${javaType.toLowerCase()} == "double" || ${javaType.toLowerCase()} == "bigdecimal" || ${javaType.toLowerCase()} == "byte") | 55 | #elseif (${javaType.toLowerCase()} == "long" || ${javaType.toLowerCase()} == "integer" || ${javaType.toLowerCase()} == "short" || ${javaType.toLowerCase()} == "double" || ${javaType.toLowerCase()} == "bigdecimal" || ${javaType.toLowerCase()} == "byte") |
| 43 | - <wd-cell title="${comment}" title-width="180rpx" prop="${javaField}" center> | 56 | + <wd-form-item title="${comment}" title-width="180rpx" prop="${javaField}"> |
| 44 | <wd-input-number | 57 | <wd-input-number |
| 45 | v-model="formData.${javaField}" | 58 | v-model="formData.${javaField}" |
| 59 | +#if (${javaType.toLowerCase()} == "double" || ${javaType.toLowerCase()} == "bigdecimal") | ||
| 60 | + :precision="2" | ||
| 61 | + input-type="number" | ||
| 62 | +#end | ||
| 46 | :min="0" | 63 | :min="0" |
| 47 | /> | 64 | /> |
| 48 | - </wd-cell> | 65 | + </wd-form-item> |
| 49 | ## 布尔类型 | 66 | ## 布尔类型 |
| 50 | #elseif (${javaType.toLowerCase()} == "boolean") | 67 | #elseif (${javaType.toLowerCase()} == "boolean") |
| 51 | - <wd-cell title="${comment}" title-width="180rpx" prop="${javaField}" center> | 68 | + <wd-form-item title="${comment}" title-width="180rpx" prop="${javaField}" center> |
| 52 | <wd-switch v-model="formData.${javaField}" /> | 69 | <wd-switch v-model="formData.${javaField}" /> |
| 53 | - </wd-cell> | 70 | + </wd-form-item> |
| 54 | ## 日期时间类型 | 71 | ## 日期时间类型 |
| 55 | #elseif (${javaType.toLowerCase()} == "date" || ${javaType.toLowerCase()} == "localdate" || ${javaType.toLowerCase()} == "localdatetime") | 72 | #elseif (${javaType.toLowerCase()} == "date" || ${javaType.toLowerCase()} == "localdate" || ${javaType.toLowerCase()} == "localdatetime") |
| 56 | #set ($pickerType = "date") | 73 | #set ($pickerType = "date") |
| 57 | #if (${javaType.toLowerCase()} == "localdatetime") | 74 | #if (${javaType.toLowerCase()} == "localdatetime") |
| 58 | #set ($pickerType = "datetime") | 75 | #set ($pickerType = "datetime") |
| 59 | #end | 76 | #end |
| 77 | + <wd-form-item | ||
| 78 | + title="${comment}" | ||
| 79 | + title-width="180rpx" | ||
| 80 | + prop="${javaField}" | ||
| 81 | + is-link | ||
| 82 | +#if ($pickerType == "datetime") | ||
| 83 | + :value="formatDateTime(formData.${javaField})" | ||
| 84 | +#else | ||
| 85 | + :value="formatDate(formData.${javaField})" | ||
| 86 | +#end | ||
| 87 | + placeholder="请选择${comment}" | ||
| 88 | + @click="${javaField}Visible = true" | ||
| 89 | + /> | ||
| 60 | <wd-datetime-picker | 90 | <wd-datetime-picker |
| 61 | v-model="formData.${javaField}" | 91 | v-model="formData.${javaField}" |
| 92 | + v-model:visible="${javaField}Visible" | ||
| 62 | type="${pickerType}" | 93 | type="${pickerType}" |
| 63 | - label="${comment}" | ||
| 64 | - label-width="180rpx" | ||
| 65 | - prop="${javaField}" | ||
| 66 | /> | 94 | /> |
| 67 | ## 文本域 | 95 | ## 文本域 |
| 68 | #elseif ($column.htmlType == "textarea") | 96 | #elseif ($column.htmlType == "textarea") |
| 69 | - <wd-textarea | ||
| 70 | - v-model="formData.${javaField}" | ||
| 71 | - label="${comment}" | ||
| 72 | - label-width="180rpx" | ||
| 73 | - placeholder="请输入${comment}" | ||
| 74 | - :maxlength="200" | ||
| 75 | - show-word-limit | ||
| 76 | - clearable | ||
| 77 | - /> | 97 | + <wd-form-item title="${comment}" title-width="180rpx" prop="${javaField}"> |
| 98 | + <wd-textarea | ||
| 99 | + v-model="formData.${javaField}" | ||
| 100 | + clearable | ||
| 101 | + placeholder="请输入${comment}" | ||
| 102 | + :maxlength="200" | ||
| 103 | + show-word-limit | ||
| 104 | + /> | ||
| 105 | + </wd-form-item> | ||
| 106 | + ## 图片上传 → yd-upload-img(包 wd-form-item 才能注册到 wd-form 做校验/错误展示) | ||
| 107 | + #elseif ($column.htmlType == "imageUpload") | ||
| 108 | + <wd-form-item title="${comment}" title-width="180rpx" prop="${javaField}"> | ||
| 109 | + <yd-upload-img v-model="formData.${javaField}" directory="${table.moduleName}/${table.businessName}" /> | ||
| 110 | + </wd-form-item> | ||
| 111 | + ## 文件上传 → yd-upload-file | ||
| 112 | + #elseif ($column.htmlType == "fileUpload") | ||
| 113 | + <wd-form-item title="${comment}" title-width="180rpx" prop="${javaField}"> | ||
| 114 | + <yd-upload-file v-model="formData.${javaField}" directory="${table.moduleName}/${table.businessName}" /> | ||
| 115 | + </wd-form-item> | ||
| 78 | ## 默认:文本输入 | 116 | ## 默认:文本输入 |
| 79 | #else | 117 | #else |
| 80 | - <wd-input | ||
| 81 | - v-model="formData.${javaField}" | ||
| 82 | - label="${comment}" | ||
| 83 | - label-width="180rpx" | ||
| 84 | - prop="${javaField}" | ||
| 85 | - clearable | ||
| 86 | - placeholder="请输入${comment}" | ||
| 87 | - /> | 118 | + <wd-form-item title="${comment}" title-width="180rpx" prop="${javaField}"> |
| 119 | + <wd-input | ||
| 120 | + v-model="formData.${javaField}" | ||
| 121 | + clearable | ||
| 122 | + placeholder="请输入${comment}" | ||
| 123 | + /> | ||
| 124 | + </wd-form-item> | ||
| 88 | #end | 125 | #end |
| 89 | #end | 126 | #end |
| 90 | #end | 127 | #end |
| @@ -107,7 +144,7 @@ | @@ -107,7 +144,7 @@ | ||
| 107 | </template> | 144 | </template> |
| 108 | 145 | ||
| 109 | <script lang="ts" setup> | 146 | <script lang="ts" setup> |
| 110 | -import type { FormInstance } from 'wot-design-uni/components/wd-form/types' | 147 | +import type { FormInstance } from '@wot-ui/ui/components/wd-form/types' |
| 111 | #set ($primaryJavaType = $primaryColumn.javaType.toLowerCase()) | 148 | #set ($primaryJavaType = $primaryColumn.javaType.toLowerCase()) |
| 112 | #if(${primaryJavaType} == "long" || ${primaryJavaType} == "integer" || ${primaryJavaType} == "short" || ${primaryJavaType} == "double" || ${primaryJavaType} == "bigdecimal" || ${primaryJavaType} == "byte") | 149 | #if(${primaryJavaType} == "long" || ${primaryJavaType} == "integer" || ${primaryJavaType} == "short" || ${primaryJavaType} == "double" || ${primaryJavaType} == "bigdecimal" || ${primaryJavaType} == "byte") |
| 113 | #set ($primaryTsType = "number") | 150 | #set ($primaryTsType = "number") |
| @@ -115,6 +152,8 @@ import type { FormInstance } from 'wot-design-uni/components/wd-form/types' | @@ -115,6 +152,8 @@ import type { FormInstance } from 'wot-design-uni/components/wd-form/types' | ||
| 115 | #set ($primaryTsType = "string") | 152 | #set ($primaryTsType = "string") |
| 116 | #end | 153 | #end |
| 117 | #set ($hasDict = 0) | 154 | #set ($hasDict = 0) |
| 155 | +#set ($hasDate = 0) | ||
| 156 | +#set ($hasDateTime = 0) | ||
| 118 | #set ($hasGetDictOptions = 0) | 157 | #set ($hasGetDictOptions = 0) |
| 119 | #set ($hasGetIntDictOptions = 0) | 158 | #set ($hasGetIntDictOptions = 0) |
| 120 | #set ($hasGetStrDictOptions = 0) | 159 | #set ($hasGetStrDictOptions = 0) |
| @@ -124,22 +163,30 @@ import type { FormInstance } from 'wot-design-uni/components/wd-form/types' | @@ -124,22 +163,30 @@ import type { FormInstance } from 'wot-design-uni/components/wd-form/types' | ||
| 124 | && ($column.htmlType == "select" || $column.htmlType == "radio") | 163 | && ($column.htmlType == "select" || $column.htmlType == "radio") |
| 125 | && $column.dictType && "" != $column.dictType) | 164 | && $column.dictType && "" != $column.dictType) |
| 126 | #set ($hasDict = 1) | 165 | #set ($hasDict = 1) |
| 127 | - #if ($column.javaType == "Integer" || $column.javaType == "Long" || $column.javaType == "Byte" || $column.javaType == "Short") | 166 | + #if ($column.htmlType == "radio" && ($column.javaType == "Integer" || $column.javaType == "Long" || $column.javaType == "Byte" || $column.javaType == "Short")) |
| 128 | #set ($hasGetIntDictOptions = 1) | 167 | #set ($hasGetIntDictOptions = 1) |
| 129 | - #elseif ($column.javaType == "String") | 168 | + #elseif ($column.htmlType == "radio" && $column.javaType == "String") |
| 130 | #set ($hasGetStrDictOptions = 1) | 169 | #set ($hasGetStrDictOptions = 1) |
| 131 | - #elseif ($column.javaType == "Boolean") | 170 | + #elseif ($column.htmlType == "radio" && $column.javaType == "Boolean") |
| 132 | #set ($hasGetBoolDictOptions = 1) | 171 | #set ($hasGetBoolDictOptions = 1) |
| 133 | - #else | 172 | + #elseif ($column.htmlType == "radio") |
| 134 | #set ($hasGetDictOptions = 1) | 173 | #set ($hasGetDictOptions = 1) |
| 135 | #end | 174 | #end |
| 136 | #end | 175 | #end |
| 176 | + #if (($column.createOperation || $column.updateOperation) && !$column.primaryKey | ||
| 177 | + && (${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdate")) | ||
| 178 | + #set ($hasDate = 1) | ||
| 179 | + #end | ||
| 180 | + #if (($column.createOperation || $column.updateOperation) && !$column.primaryKey | ||
| 181 | + && ${column.javaType.toLowerCase()} == "localdatetime") | ||
| 182 | + #set ($hasDateTime = 1) | ||
| 183 | + #end | ||
| 137 | #end | 184 | #end |
| 138 | import type { ${simpleClassName} } from '@/api/${table.moduleName}/${table.businessName}' | 185 | import type { ${simpleClassName} } from '@/api/${table.moduleName}/${table.businessName}' |
| 139 | import { computed, onMounted, ref } from 'vue' | 186 | import { computed, onMounted, ref } from 'vue' |
| 140 | -import { useToast } from 'wot-design-uni' | 187 | +import { useToast } from '@wot-ui/ui/components/wd-toast' |
| 141 | import { create${simpleClassName}, get${simpleClassName}, update${simpleClassName} } from '@/api/${table.moduleName}/${table.businessName}' | 188 | import { create${simpleClassName}, get${simpleClassName}, update${simpleClassName} } from '@/api/${table.moduleName}/${table.businessName}' |
| 142 | -#if ($hasDict == 1) | 189 | +#if ($hasGetDictOptions == 1 || $hasGetIntDictOptions == 1 || $hasGetStrDictOptions == 1 || $hasGetBoolDictOptions == 1) |
| 143 | #set ($dictImportNames = "") | 190 | #set ($dictImportNames = "") |
| 144 | #if ($hasGetDictOptions == 1) | 191 | #if ($hasGetDictOptions == 1) |
| 145 | #set ($dictImportNames = "${dictImportNames}getDictOptions, ") | 192 | #set ($dictImportNames = "${dictImportNames}getDictOptions, ") |
| @@ -161,6 +208,19 @@ import { navigateBackPlus } from '@/utils' | @@ -161,6 +208,19 @@ import { navigateBackPlus } from '@/utils' | ||
| 161 | #if ($hasDict == 1) | 208 | #if ($hasDict == 1) |
| 162 | import { DICT_TYPE } from '@/utils/constants' | 209 | import { DICT_TYPE } from '@/utils/constants' |
| 163 | #end | 210 | #end |
| 211 | +#if ($hasDate == 1 || $hasDateTime == 1) | ||
| 212 | + #set ($dateImportNames = "") | ||
| 213 | + #if ($hasDate == 1) | ||
| 214 | + #set ($dateImportNames = "${dateImportNames}formatDate, ") | ||
| 215 | + #end | ||
| 216 | + #if ($hasDateTime == 1) | ||
| 217 | + #set ($dateImportNames = "${dateImportNames}formatDateTime, ") | ||
| 218 | + #end | ||
| 219 | + #set ($dateImportNames = $dateImportNames.trim()) | ||
| 220 | + #set ($dateImportNames = $dateImportNames.substring(0, $dateImportNames.length() - 1)) | ||
| 221 | +import { $dateImportNames } from '@/utils/date' | ||
| 222 | +#end | ||
| 223 | +import { createFormSchema } from '@/utils/wot' | ||
| 164 | 224 | ||
| 165 | const props = defineProps<{ | 225 | const props = defineProps<{ |
| 166 | id?: ${primaryTsType} | any | 226 | id?: ${primaryTsType} | any |
| @@ -196,7 +256,12 @@ const formData = ref<${simpleClassName}>({ | @@ -196,7 +256,12 @@ const formData = ref<${simpleClassName}>({ | ||
| 196 | #end | 256 | #end |
| 197 | #end | 257 | #end |
| 198 | }) // 表单数据 | 258 | }) // 表单数据 |
| 199 | -const formRules = { | 259 | +#foreach($column in $columns) |
| 260 | + #if (($column.createOperation || $column.updateOperation) && !$column.primaryKey && (${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdate" || ${column.javaType.toLowerCase()} == "localdatetime")) | ||
| 261 | +const ${column.javaField}Visible = ref(false) // ${column.columnComment}选择器状态 | ||
| 262 | + #end | ||
| 263 | +#end | ||
| 264 | +const formSchema = createFormSchema({ | ||
| 200 | #foreach($column in $columns) | 265 | #foreach($column in $columns) |
| 201 | #set ($javaFieldLower = $column.javaField.toLowerCase()) | 266 | #set ($javaFieldLower = $column.javaField.toLowerCase()) |
| 202 | #if (($column.createOperation || $column.updateOperation) && !$column.nullable && !$column.primaryKey | 267 | #if (($column.createOperation || $column.updateOperation) && !$column.nullable && !$column.primaryKey |
| @@ -204,7 +269,7 @@ const formRules = { | @@ -204,7 +269,7 @@ const formRules = { | ||
| 204 | ${column.javaField}: [{ required: true, message: '${column.columnComment}不能为空' }], | 269 | ${column.javaField}: [{ required: true, message: '${column.columnComment}不能为空' }], |
| 205 | #end | 270 | #end |
| 206 | #end | 271 | #end |
| 207 | -} // 表单校验规则 | 272 | +}) // 表单校验规则 |
| 208 | const formRef = ref<FormInstance>() // 表单组件引用 | 273 | const formRef = ref<FormInstance>() // 表单组件引用 |
| 209 | 274 | ||
| 210 | /** 返回上一页 */ | 275 | /** 返回上一页 */ |
yudao-module-infra/src/test/java/cn/iocoder/yudao/module/infra/service/codegen/inner/CodegenEngineAbstractTest.java
| @@ -152,10 +152,21 @@ public abstract class CodegenEngineAbstractTest extends BaseMockitoUnitTest { | @@ -152,10 +152,21 @@ public abstract class CodegenEngineAbstractTest extends BaseMockitoUnitTest { | ||
| 152 | protected void writeResult(Map<String, String> result, String basePath) { | 152 | protected void writeResult(Map<String, String> result, String basePath) { |
| 153 | // 写入文件内容 | 153 | // 写入文件内容 |
| 154 | List<Map<String, String>> asserts = new ArrayList<>(); | 154 | List<Map<String, String>> asserts = new ArrayList<>(); |
| 155 | + Set<String> usedContentPaths = new LinkedHashSet<>(); | ||
| 155 | result.forEach((filePath, fileContent) -> { | 156 | result.forEach((filePath, fileContent) -> { |
| 156 | String lastFilePath = StrUtil.subAfter(filePath, '/', true); | 157 | String lastFilePath = StrUtil.subAfter(filePath, '/', true); |
| 157 | - String contentPath = StrUtil.subAfter(lastFilePath, '.', true) | ||
| 158 | - + '/' + StrUtil.subBefore(lastFilePath, '.', true); | 158 | + String ext = StrUtil.subAfter(lastFilePath, '.', true); |
| 159 | + String name = StrUtil.subBefore(lastFilePath, '.', true); | ||
| 160 | + String contentPath = ext + '/' + name; | ||
| 161 | + // 同名文件(如 index.vue 同时出现在 列表/form/detail)会撞名,撞名时前缀补上级目录区分;仍撞则加序号兜底,避免快照互相覆盖 | ||
| 162 | + if (usedContentPaths.contains(contentPath)) { | ||
| 163 | + String parentDir = StrUtil.subAfter(StrUtil.subBefore(filePath, '/' + lastFilePath, true), '/', true); | ||
| 164 | + contentPath = ext + '/' + parentDir + '/' + name; | ||
| 165 | + for (int i = 2; usedContentPaths.contains(contentPath); i++) { | ||
| 166 | + contentPath = ext + '/' + parentDir + '/' + name + '-' + i; | ||
| 167 | + } | ||
| 168 | + } | ||
| 169 | + usedContentPaths.add(contentPath); | ||
| 159 | asserts.add(MapUtil.<String, String>builder().put("filePath", filePath) | 170 | asserts.add(MapUtil.<String, String>builder().put("filePath", filePath) |
| 160 | .put("contentPath", contentPath).build()); | 171 | .put("contentPath", contentPath).build()); |
| 161 | FileUtil.writeUtf8String(fileContent, basePath + "/" + contentPath); | 172 | FileUtil.writeUtf8String(fileContent, basePath + "/" + contentPath); |
yudao-module-infra/src/test/resources/codegen/vue3_admin_uniapp_one/vue/detail/index
| @@ -51,7 +51,7 @@ | @@ -51,7 +51,7 @@ | ||
| 51 | import type { Student } from '@/api/infra/demo' | 51 | import type { Student } from '@/api/infra/demo' |
| 52 | import { onUnload } from '@dcloudio/uni-app' | 52 | import { onUnload } from '@dcloudio/uni-app' |
| 53 | import { onMounted, ref } from 'vue' | 53 | import { onMounted, ref } from 'vue' |
| 54 | -import { useToast } from 'wot-design-uni' | 54 | +import { useToast } from '@wot-ui/ui/components/wd-toast' |
| 55 | import { deleteStudent, getStudent } from '@/api/infra/demo' | 55 | import { deleteStudent, getStudent } from '@/api/infra/demo' |
| 56 | import { useAccess } from '@/hooks/useAccess' | 56 | import { useAccess } from '@/hooks/useAccess' |
| 57 | import { navigateBackPlus } from '@/utils' | 57 | import { navigateBackPlus } from '@/utils' |
yudao-module-infra/src/test/resources/codegen/vue3_admin_uniapp_one/vue/form/index
| @@ -9,45 +9,48 @@ | @@ -9,45 +9,48 @@ | ||
| 9 | 9 | ||
| 10 | <!-- 表单区域 --> | 10 | <!-- 表单区域 --> |
| 11 | <view> | 11 | <view> |
| 12 | - <wd-form ref="formRef" :model="formData" :rules="formRules"> | 12 | + <wd-form ref="formRef" :model="formData" :schema="formSchema"> |
| 13 | <wd-cell-group border> | 13 | <wd-cell-group border> |
| 14 | - <wd-input | ||
| 15 | - v-model="formData.name" | ||
| 16 | - label="名字" | ||
| 17 | - label-width="180rpx" | ||
| 18 | - prop="name" | ||
| 19 | - clearable | ||
| 20 | - placeholder="请输入名字" | ||
| 21 | - /> | ||
| 22 | - <wd-textarea | ||
| 23 | - v-model="formData.description" | ||
| 24 | - label="简介" | ||
| 25 | - label-width="180rpx" | ||
| 26 | - placeholder="请输入简介" | ||
| 27 | - :maxlength="200" | ||
| 28 | - show-word-limit | ||
| 29 | - clearable | 14 | + <wd-form-item title="名字" title-width="180rpx" prop="name"> |
| 15 | + <wd-input | ||
| 16 | + v-model="formData.name" | ||
| 17 | + clearable | ||
| 18 | + placeholder="请输入名字" | ||
| 19 | + /> | ||
| 20 | + </wd-form-item> | ||
| 21 | + <wd-form-item title="简介" title-width="180rpx" prop="description"> | ||
| 22 | + <wd-textarea | ||
| 23 | + v-model="formData.description" | ||
| 24 | + clearable | ||
| 25 | + placeholder="请输入简介" | ||
| 26 | + :maxlength="200" | ||
| 27 | + show-word-limit | ||
| 28 | + /> | ||
| 29 | + </wd-form-item> | ||
| 30 | + <wd-form-item | ||
| 31 | + title="出生日期" | ||
| 32 | + title-width="180rpx" | ||
| 33 | + prop="birthday" | ||
| 34 | + is-link | ||
| 35 | + :value="formatDateTime(formData.birthday)" | ||
| 36 | + placeholder="请选择出生日期" | ||
| 37 | + @click="birthdayVisible = true" | ||
| 30 | /> | 38 | /> |
| 31 | - <wd-datetime-picker | 39 | + <wd-datetime-picker |
| 32 | v-model="formData.birthday" | 40 | v-model="formData.birthday" |
| 41 | + v-model:visible="birthdayVisible" | ||
| 33 | type="datetime" | 42 | type="datetime" |
| 34 | - label="出生日期" | 43 | + /> |
| 44 | + <yd-form-picker | ||
| 45 | + v-model="formData.sex" | ||
| 46 | + label="性别" | ||
| 35 | label-width="180rpx" | 47 | label-width="180rpx" |
| 36 | - prop="birthday" | 48 | + prop="sex" |
| 49 | + :dict-type="DICT_TYPE.SYSTEM_USER_SEX" | ||
| 50 | + placeholder="请选择性别" | ||
| 37 | /> | 51 | /> |
| 38 | - <wd-cell title="性别" title-width="180rpx" prop="sex" center> | ||
| 39 | - <wd-radio-group v-model="formData.sex" shape="button"> | ||
| 40 | - <wd-radio | ||
| 41 | - v-for="dict in getIntDictOptions(DICT_TYPE.SYSTEM_USER_SEX)" | ||
| 42 | - :key="dict.value" | ||
| 43 | - :value="dict.value" | ||
| 44 | - > | ||
| 45 | - {{ dict.label }} | ||
| 46 | - </wd-radio> | ||
| 47 | - </wd-radio-group> | ||
| 48 | - </wd-cell> | ||
| 49 | - <wd-cell title="是否有效" title-width="180rpx" prop="enabled" center> | ||
| 50 | - <wd-radio-group v-model="formData.enabled" shape="button"> | 52 | + <wd-form-item title="是否有效" title-width="180rpx" prop="enabled" center> |
| 53 | + <wd-radio-group v-model="formData.enabled" type="button"> | ||
| 51 | <wd-radio | 54 | <wd-radio |
| 52 | v-for="dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)" | 55 | v-for="dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)" |
| 53 | :key="dict.value" | 56 | :key="dict.value" |
| @@ -56,31 +59,20 @@ | @@ -56,31 +59,20 @@ | ||
| 56 | {{ dict.label }} | 59 | {{ dict.label }} |
| 57 | </wd-radio> | 60 | </wd-radio> |
| 58 | </wd-radio-group> | 61 | </wd-radio-group> |
| 59 | - </wd-cell> | ||
| 60 | - <wd-input | ||
| 61 | - v-model="formData.avatar" | ||
| 62 | - label="头像" | ||
| 63 | - label-width="180rpx" | ||
| 64 | - prop="avatar" | ||
| 65 | - clearable | ||
| 66 | - placeholder="请输入头像" | ||
| 67 | - /> | ||
| 68 | - <wd-input | ||
| 69 | - v-model="formData.video" | ||
| 70 | - label="附件" | ||
| 71 | - label-width="180rpx" | ||
| 72 | - prop="video" | ||
| 73 | - clearable | ||
| 74 | - placeholder="请输入附件" | ||
| 75 | - /> | ||
| 76 | - <wd-input | ||
| 77 | - v-model="formData.memo" | ||
| 78 | - label="备注" | ||
| 79 | - label-width="180rpx" | ||
| 80 | - prop="memo" | ||
| 81 | - clearable | ||
| 82 | - placeholder="请输入备注" | ||
| 83 | - /> | 62 | + </wd-form-item> |
| 63 | + <wd-form-item title="头像" title-width="180rpx" prop="avatar"> | ||
| 64 | + <yd-upload-img v-model="formData.avatar" directory="infra/demo" /> | ||
| 65 | + </wd-form-item> | ||
| 66 | + <wd-form-item title="附件" title-width="180rpx" prop="video"> | ||
| 67 | + <yd-upload-file v-model="formData.video" directory="infra/demo" /> | ||
| 68 | + </wd-form-item> | ||
| 69 | + <wd-form-item title="备注" title-width="180rpx" prop="memo"> | ||
| 70 | + <wd-input | ||
| 71 | + v-model="formData.memo" | ||
| 72 | + clearable | ||
| 73 | + placeholder="请输入备注" | ||
| 74 | + /> | ||
| 75 | + </wd-form-item> | ||
| 84 | </wd-cell-group> | 76 | </wd-cell-group> |
| 85 | </wd-form> | 77 | </wd-form> |
| 86 | </view> | 78 | </view> |
| @@ -100,14 +92,16 @@ | @@ -100,14 +92,16 @@ | ||
| 100 | </template> | 92 | </template> |
| 101 | 93 | ||
| 102 | <script lang="ts" setup> | 94 | <script lang="ts" setup> |
| 103 | -import type { FormInstance } from 'wot-design-uni/components/wd-form/types' | 95 | +import type { FormInstance } from '@wot-ui/ui/components/wd-form/types' |
| 104 | import type { Student } from '@/api/infra/demo' | 96 | import type { Student } from '@/api/infra/demo' |
| 105 | import { computed, onMounted, ref } from 'vue' | 97 | import { computed, onMounted, ref } from 'vue' |
| 106 | -import { useToast } from 'wot-design-uni' | 98 | +import { useToast } from '@wot-ui/ui/components/wd-toast' |
| 107 | import { createStudent, getStudent, updateStudent } from '@/api/infra/demo' | 99 | import { createStudent, getStudent, updateStudent } from '@/api/infra/demo' |
| 108 | -import { getIntDictOptions, getBoolDictOptions } from '@/hooks/useDict' | 100 | +import { getBoolDictOptions } from '@/hooks/useDict' |
| 109 | import { navigateBackPlus } from '@/utils' | 101 | import { navigateBackPlus } from '@/utils' |
| 110 | import { DICT_TYPE } from '@/utils/constants' | 102 | import { DICT_TYPE } from '@/utils/constants' |
| 103 | +import { formatDateTime } from '@/utils/date' | ||
| 104 | +import { createFormSchema } from '@/utils/wot' | ||
| 111 | 105 | ||
| 112 | const props = defineProps<{ | 106 | const props = defineProps<{ |
| 113 | id?: number | any | 107 | id?: number | any |
| @@ -134,7 +128,8 @@ const formData = ref<Student>({ | @@ -134,7 +128,8 @@ const formData = ref<Student>({ | ||
| 134 | video: '', | 128 | video: '', |
| 135 | memo: '', | 129 | memo: '', |
| 136 | }) // 表单数据 | 130 | }) // 表单数据 |
| 137 | -const formRules = { | 131 | +const birthdayVisible = ref(false) // 出生日期选择器状态 |
| 132 | +const formSchema = createFormSchema({ | ||
| 138 | name: [{ required: true, message: '名字不能为空' }], | 133 | name: [{ required: true, message: '名字不能为空' }], |
| 139 | description: [{ required: true, message: '简介不能为空' }], | 134 | description: [{ required: true, message: '简介不能为空' }], |
| 140 | birthday: [{ required: true, message: '出生日期不能为空' }], | 135 | birthday: [{ required: true, message: '出生日期不能为空' }], |
| @@ -143,7 +138,7 @@ const formRules = { | @@ -143,7 +138,7 @@ const formRules = { | ||
| 143 | avatar: [{ required: true, message: '头像不能为空' }], | 138 | avatar: [{ required: true, message: '头像不能为空' }], |
| 144 | video: [{ required: true, message: '附件不能为空' }], | 139 | video: [{ required: true, message: '附件不能为空' }], |
| 145 | memo: [{ required: true, message: '备注不能为空' }], | 140 | memo: [{ required: true, message: '备注不能为空' }], |
| 146 | -} // 表单校验规则 | 141 | +}) // 表单校验规则 |
| 147 | const formRef = ref<FormInstance>() // 表单组件引用 | 142 | const formRef = ref<FormInstance>() // 表单组件引用 |
| 148 | 143 | ||
| 149 | /** 返回上一页 */ | 144 | /** 返回上一页 */ |
yudao-module-infra/src/test/resources/codegen/vue3_admin_uniapp_one/vue/search-form
| @@ -31,7 +31,7 @@ | @@ -31,7 +31,7 @@ | ||
| 31 | <view class="yd-search-form-label"> | 31 | <view class="yd-search-form-label"> |
| 32 | 性别 | 32 | 性别 |
| 33 | </view> | 33 | </view> |
| 34 | - <wd-radio-group v-model="formData.sex" shape="button"> | 34 | + <wd-radio-group v-model="formData.sex" type="button"> |
| 35 | <wd-radio :value="-1"> | 35 | <wd-radio :value="-1"> |
| 36 | 全部 | 36 | 全部 |
| 37 | </wd-radio> | 37 | </wd-radio> |
| @@ -48,7 +48,7 @@ | @@ -48,7 +48,7 @@ | ||
| 48 | <view class="yd-search-form-label"> | 48 | <view class="yd-search-form-label"> |
| 49 | 是否有效 | 49 | 是否有效 |
| 50 | </view> | 50 | </view> |
| 51 | - <wd-radio-group v-model="formData.enabled" shape="button"> | 51 | + <wd-radio-group v-model="formData.enabled" type="button"> |
| 52 | <wd-radio :value="-1"> | 52 | <wd-radio :value="-1"> |
| 53 | 全部 | 53 | 全部 |
| 54 | </wd-radio> | 54 | </wd-radio> |
| @@ -61,42 +61,7 @@ | @@ -61,42 +61,7 @@ | ||
| 61 | </wd-radio> | 61 | </wd-radio> |
| 62 | </wd-radio-group> | 62 | </wd-radio-group> |
| 63 | </view> | 63 | </view> |
| 64 | - <view class="yd-search-form-item"> | ||
| 65 | - <view class="yd-search-form-label"> | ||
| 66 | - 创建时间 | ||
| 67 | - </view> | ||
| 68 | - <view class="yd-search-form-date-range-container"> | ||
| 69 | - <view @click="visibleCreateTime[0] = true"> | ||
| 70 | - <view class="yd-search-form-date-range-picker"> | ||
| 71 | - {{ formatDate(formData.createTime?.[0]) || '开始日期' }} | ||
| 72 | - </view> | ||
| 73 | - </view> | ||
| 74 | - - | ||
| 75 | - <view @click="visibleCreateTime[1] = true"> | ||
| 76 | - <view class="yd-search-form-date-range-picker"> | ||
| 77 | - {{ formatDate(formData.createTime?.[1]) || '结束日期' }} | ||
| 78 | - </view> | ||
| 79 | - </view> | ||
| 80 | - </view> | ||
| 81 | - <wd-datetime-picker-view v-if="visibleCreateTime[0]" v-model="tempCreateTime[0]" type="date" /> | ||
| 82 | - <view v-if="visibleCreateTime[0]" class="yd-search-form-date-range-actions"> | ||
| 83 | - <wd-button size="small" plain @click="visibleCreateTime[0] = false"> | ||
| 84 | - 取消 | ||
| 85 | - </wd-button> | ||
| 86 | - <wd-button size="small" type="primary" @click="handleCreateTime0Confirm"> | ||
| 87 | - 确定 | ||
| 88 | - </wd-button> | ||
| 89 | - </view> | ||
| 90 | - <wd-datetime-picker-view v-if="visibleCreateTime[1]" v-model="tempCreateTime[1]" type="date" /> | ||
| 91 | - <view v-if="visibleCreateTime[1]" class="yd-search-form-date-range-actions"> | ||
| 92 | - <wd-button size="small" plain @click="visibleCreateTime[1] = false"> | ||
| 93 | - 取消 | ||
| 94 | - </wd-button> | ||
| 95 | - <wd-button size="small" type="primary" @click="handleCreateTime1Confirm"> | ||
| 96 | - 确定 | ||
| 97 | - </wd-button> | ||
| 98 | - </view> | ||
| 99 | - </view> | 64 | + <yd-search-date-range v-model="formData.createTime" label="创建时间" /> |
| 100 | <view class="yd-search-form-actions"> | 65 | <view class="yd-search-form-actions"> |
| 101 | <wd-button class="flex-1" plain @click="handleReset"> | 66 | <wd-button class="flex-1" plain @click="handleReset"> |
| 102 | 重置 | 67 | 重置 |
| @@ -151,21 +116,6 @@ const placeholder = computed(() => { | @@ -151,21 +116,6 @@ const placeholder = computed(() => { | ||
| 151 | return conditions.length > 0 ? conditions.join(' | ') : '搜索学生' | 116 | return conditions.length > 0 ? conditions.join(' | ') : '搜索学生' |
| 152 | }) | 117 | }) |
| 153 | 118 | ||
| 154 | -const visibleCreateTime = ref<[boolean, boolean]>([false, false]) // 创建时间选择器状态 | ||
| 155 | -const tempCreateTime = ref<[number, number]>([Date.now(), Date.now()]) // 创建时间临时值 | ||
| 156 | - | ||
| 157 | -/** 确认创建时间开始日期 */ | ||
| 158 | -function handleCreateTime0Confirm() { | ||
| 159 | - formData.createTime = [tempCreateTime.value[0], formData.createTime?.[1]] | ||
| 160 | - visibleCreateTime.value[0] = false | ||
| 161 | -} | ||
| 162 | - | ||
| 163 | -/** 确认创建时间结束日期 */ | ||
| 164 | -function handleCreateTime1Confirm() { | ||
| 165 | - formData.createTime = [formData.createTime?.[0], tempCreateTime.value[1]] | ||
| 166 | - visibleCreateTime.value[1] = false | ||
| 167 | -} | ||
| 168 | - | ||
| 169 | /** 搜索按钮操作 */ | 119 | /** 搜索按钮操作 */ |
| 170 | function handleSearch() { | 120 | function handleSearch() { |
| 171 | visible.value = false | 121 | visible.value = false |