fix(other): 修复代码生成问题

This commit is contained in:
xlsea 2025-06-14 13:40:15 +08:00
parent cafee1dbd9
commit 1ec1099179
8 changed files with 134 additions and 94 deletions

View File

@ -52,7 +52,7 @@ function createDefaultModel(): Model {
return { return {
#foreach($column in $columns) #foreach($column in $columns)
#if($column.insert) #if($column.insert)
${column.javaField}:#if($column.javaType == 'String') ''#else null#end#if($foreach.hasNext),#end ${column.javaField}:#if($column.javaType == 'String' && $!column.dictType && $column.dictType == '') ''#else undefined#end#if($foreach.hasNext),#end
#end #end
#end #end
}; };
@ -91,16 +91,22 @@ function closeDrawer() {
async function handleSubmit() { async function handleSubmit() {
await validate(); await validate();
#set($operateColumns = [])
#foreach($column in $columns)#if($column.insert || $column.edit)#set($dummy = $operateColumns.add($column))#end#end
const { #foreach($column in $operateColumns)$column.javaField#if($foreach.hasNext), #end#end } = model;
// request // request
if (props.operateType === 'add') { if (props.operateType === 'add') {
const { #foreach($column in $columns)#if($column.insert)$column.javaField#if($foreach.hasNext), #end#end#end } = model; #set($addFields = [])
const { error } = await fetchCreate${BusinessName}({ #foreach($column in $columns)#if($column.insert)$column.javaField#if($foreach.hasNext), #end#end#end }); #foreach($column in $columns)#if($column.insert)#set($dummy = $addFields.add($column.javaField))#end#end
const { error } = await fetchCreate${BusinessName}({ #foreach($field in $addFields)$field#if($foreach.hasNext), #end#end });
if (error) return; if (error) return;
} }
if (props.operateType === 'edit') { if (props.operateType === 'edit') {
const { #foreach($column in $columns)#if($column.edit)$column.javaField#if($foreach.hasNext), #end#end#end } = model; #set($editFields = [])
const { error } = await fetchUpdate${BusinessName}({ #foreach($column in $columns)#if($column.edit)$column.javaField#if($foreach.hasNext), #end#end#end }); #foreach($column in $columns)#if($column.edit)#set($dummy = $editFields.add($column.javaField))#end#end
const { error } = await fetchUpdate${BusinessName}({ #foreach($field in $editFields)$field#if($foreach.hasNext), #end#end });
if (error) return; if (error) return;
} }
@ -170,13 +176,36 @@ watch(visible, () => {
<NRadio value="0" label="请选择字典生成" /> <NRadio value="0" label="请选择字典生成" />
</NSpace> </NSpace>
</NRadioGroup> </NRadioGroup>
#elseif($column.htmlType == "datetime") #elseif($column.htmlType == "checkbox" && "" != $dictType)
<NCheckboxGroup v-model:value="model.$column.javaField">
<NSpace>
<NCheckbox
v-for="option in ${column.dictType}Options"
:key="option.value"
:value="option.value"
:label="option.label"
/>
</NSpace>
</NCheckboxGroup>
#elseif($column.htmlType == "checkbox" && $dictType)
<NCheckboxGroup v-model:value="model.$column.javaField">
<NSpace>
<NCheckbox value="0" label="请选择字典生成" />
</NSpace>
</NCheckboxGroup>
#elseif($column.htmlType == 'datetime')
<NDatePicker <NDatePicker
v-model:formatted-value="model.$column.javaField" v-model:formatted-value="model.$column.javaField"
type="date" type="datetime"
value-format="yyyy-MM-dd HH:mm:ss" value-format="yyyy-MM-dd HH:mm:ss"
clearable clearable
/> />
#elseif($column.htmlType == "imageUpload")
<OssUpload v-model:value="model.$column.javaField" upload-type="image" />
#elseif($column.htmlType == "fileUpload")
<OssUpload v-model:value="model.$column.javaField" upload-type="file" />
#elseif($column.htmlType == "editor")
<TinymceEditor v-model:value="model.$column.javaField" />
#else <NInput v-model:value="model.$column.javaField" placeholder="请输入$column.columnComment" /> #else <NInput v-model:value="model.$column.javaField" placeholder="请输入$column.columnComment" />
#end #end
</NFormItem> </NFormItem>

View File

@ -75,35 +75,28 @@ async function search() {
#set($comment=$column.columnComment) #set($comment=$column.columnComment)
#end #end
<NFormItemGi span="24 s:12 m:6" label="$column.columnComment" path="$column.javaField" class="pr-24px"> <NFormItemGi span="24 s:12 m:6" label="$column.columnComment" path="$column.javaField" class="pr-24px">
#if(($column.htmlType == "select" || $column.htmlType == "radio") && "" != $dictType) #if(($tool.in($column.htmlType, "select", "radio", "checkbox")) && $dictType && "" != $dictType)
<NSelect <NSelect
v-model:value="model.$column.javaField" v-model:value="model.$column.javaField"
placeholder="请选择$column.columnComment" placeholder="请选择$column.columnComment"
:options="${column.dictType}Options" :options="${column.dictType}Options"
clearable clearable
/> />
#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && $dictType) #elseif($tool.in($column.htmlType, "select", "radio", "checkbox"))
<NSelect <NSelect
v-model:value="model.$column.javaField" v-model:value="model.$column.javaField"
placeholder="请选择$column.columnComment" placeholder="请选择$column.columnComment"
:options="[]" :options="[]"
clearable clearable
/> />
#elseif($column.htmlType.equals('select') || $column.htmlType.equals('radio')) #elseif($column.htmlType == 'datetime' && $column.queryType != "BETWEEN")
<NSelect
v-model:value="model.$column.javaField"
placeholder="请选择$column.columnComment"
:options="[]"
clearable
/>
#elseif($column.htmlType == "datetime" && $column.queryType != "BETWEEN")
<NDatePicker <NDatePicker
v-model:formatted-value="model.$column.javaField" v-model:formatted-value="model.$column.javaField"
type="date" type="datetime"
value-format="yyyy-MM-dd" value-format="yyyy-MM-dd HH:mm:ss"
clearable clearable
/> />
#elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN") #elseif($column.htmlType == 'datetime' && $column.queryType == "BETWEEN")
<NDatePicker <NDatePicker
v-model:formatted-value="dateRange${AttrName}" v-model:formatted-value="dateRange${AttrName}"
type="datetimerange" type="datetimerange"

View File

@ -127,55 +127,57 @@ async function handleRemove(file: UploadFileInfo) {
</script> </script>
<template> <template>
<NUpload <div class="w-full flex-col">
v-bind="attrs" <NUpload
v-model:file-list="fileList" v-bind="attrs"
:action="`${baseURL}${action}`" v-model:file-list="fileList"
:data="data" :action="`${baseURL}${action}`"
:headers="headers" :data="data"
:max="max" :headers="headers"
:accept="accept" :max="max"
:multiple="max > 1" :accept="accept"
directory-dnd :multiple="max > 1"
:default-upload="defaultUpload" directory-dnd
:list-type="uploadType === 'image' ? 'image-card' : 'text'" :default-upload="defaultUpload"
:is-error-state="isErrorState" :list-type="uploadType === 'image' ? 'image-card' : 'text'"
@finish="handleFinish" :is-error-state="isErrorState"
@error="handleError" @finish="handleFinish"
@before-upload="beforeUpload" @error="handleError"
@remove="({ file }) => handleRemove(file)" @before-upload="beforeUpload"
> @remove="({ file }) => handleRemove(file)"
<NUploadDragger v-if="uploadType === 'file'"> >
<div class="mb-12px flex-center"> <NUploadDragger v-if="uploadType === 'file'">
<SvgIcon icon="material-symbols:unarchive-outline" class="text-58px color-#d8d8db dark:color-#a1a1a2" /> <div class="mb-12px flex-center">
</div> <SvgIcon icon="material-symbols:unarchive-outline" class="text-58px color-#d8d8db dark:color-#a1a1a2" />
<NText class="text-16px">点击或者拖动文件到该区域来上传</NText> </div>
<NP v-if="showTip" depth="3" class="mt-8px text-center"> <NText class="text-16px">点击或者拖动文件到该区域来上传</NText>
请上传 <NP v-if="showTip" depth="3" class="mt-8px text-center">
<template v-if="fileSize"> 请上传
大小不超过 <template v-if="fileSize">
<b class="text-red-500">{{ fileSize }}MB</b> 大小不超过
</template> <b class="text-red-500">{{ fileSize }}MB</b>
<template v-if="accept"> </template>
且格式为 <template v-if="accept">
<b class="text-red-500">{{ accept.replaceAll(',', '/') }}</b> 且格式为
</template> <b class="text-red-500">{{ accept.replaceAll(',', '/') }}</b>
的文件 </template>
</NP> 的文件
</NUploadDragger> </NP>
</NUpload> </NUploadDragger>
<NP v-if="showTip && uploadType === 'image'" depth="3" class="mt-12px"> </NUpload>
请上传 <NP v-if="showTip && uploadType === 'image'" depth="3" class="mt-12px">
<template v-if="fileSize"> 请上传
大小不超过 <template v-if="fileSize">
<b class="text-red-500">{{ fileSize }}MB</b> 大小不超过
</template> <b class="text-red-500">{{ fileSize }}MB</b>
<template v-if="accept"> </template>
且格式为 <template v-if="accept">
<b class="text-red-500">{{ accept.replaceAll(',', '/') }}</b> 且格式为
</template> <b class="text-red-500">{{ accept.replaceAll(',', '/') }}</b>
的文件 </template>
</NP> 的文件
</NP>
</div>
</template> </template>
<style scoped></style> <style scoped></style>

View File

@ -34,7 +34,7 @@ async function handleFetchOssList(ossIds: string[]) {
watch( watch(
value, value,
async val => { async val => {
const ossIds = val.split(',')?.filter(item => isNotNull(item)); const ossIds = val?.split(',')?.filter(item => isNotNull(item)) || [];
const fileIds = new Set(fileList.value.filter(item => item.status === 'finished').map(item => item.id)); const fileIds = new Set(fileList.value.filter(item => item.status === 'finished').map(item => item.id));
if (ossIds.every(item => fileIds.has(item))) { if (ossIds.every(item => fileIds.has(item))) {
return; return;

View File

@ -0,0 +1,36 @@
<script setup lang="ts">
import { Tinymce } from '@sa/tinymce';
import { getToken } from '@/store/modules/auth/shared';
import { useAppStore } from '@/store/modules/app';
import { useThemeStore } from '@/store/modules/theme';
import { getServiceBaseURL } from '@/utils/service';
defineOptions({
name: 'TinymceEditor'
});
const value = defineModel<string | null>('value', { required: false, default: '' });
const appStore = useAppStore();
const themeStore = useThemeStore();
const isHttpProxy = import.meta.env.DEV && import.meta.env.VITE_HTTP_PROXY === 'Y';
const { baseURL } = getServiceBaseURL(import.meta.env, isHttpProxy);
const headers: Record<string, string> = {
Authorization: `Bearer ${getToken()}`,
clientid: import.meta.env.VITE_APP_CLIENT_ID!
};
</script>
<template>
<Tinymce
v-model="value"
:lang="appStore.locale"
:is-dark="themeStore.darkMode"
:upload-url="`${baseURL}/resource/oss/upload`"
:upload-headers="headers"
/>
</template>
<style scoped></style>

View File

@ -76,7 +76,7 @@ export const genHtmlTypeRecord: Record<Api.Tool.HtmlType, string> = {
select: '下拉框', select: '下拉框',
radio: '单选框', radio: '单选框',
checkbox: '复选框', checkbox: '复选框',
datetime: '日期控件', datetime: '日期时间控件',
imageUpload: '图片上传', imageUpload: '图片上传',
fileUpload: '文件上传', fileUpload: '文件上传',
editor: '富文本控件' editor: '富文本控件'

View File

@ -69,6 +69,7 @@ declare module 'vue' {
NButton: typeof import('naive-ui')['NButton'] NButton: typeof import('naive-ui')['NButton']
NCard: typeof import('naive-ui')['NCard'] NCard: typeof import('naive-ui')['NCard']
NCheckbox: typeof import('naive-ui')['NCheckbox'] NCheckbox: typeof import('naive-ui')['NCheckbox']
NCheckboxGroup: typeof import('naive-ui')['NCheckboxGroup']
NCode: typeof import('naive-ui')['NCode'] NCode: typeof import('naive-ui')['NCode']
NCollapse: typeof import('naive-ui')['NCollapse'] NCollapse: typeof import('naive-ui')['NCollapse']
NCollapseItem: typeof import('naive-ui')['NCollapseItem'] NCollapseItem: typeof import('naive-ui')['NCollapseItem']
@ -146,6 +147,7 @@ declare module 'vue' {
TableSiderLayout: typeof import('./../components/advanced/table-sider-layout.vue')['default'] TableSiderLayout: typeof import('./../components/advanced/table-sider-layout.vue')['default']
TenantSelect: typeof import('./../components/custom/tenant-select.vue')['default'] TenantSelect: typeof import('./../components/custom/tenant-select.vue')['default']
ThemeSchemaSwitch: typeof import('./../components/common/theme-schema-switch.vue')['default'] ThemeSchemaSwitch: typeof import('./../components/common/theme-schema-switch.vue')['default']
TinymceEditor: typeof import('./../components/custom/tinymce-editor.vue')['default']
UserSelect: typeof import('./../components/custom/user-select.vue')['default'] UserSelect: typeof import('./../components/custom/user-select.vue')['default']
WaveBg: typeof import('./../components/custom/wave-bg.vue')['default'] WaveBg: typeof import('./../components/custom/wave-bg.vue')['default']
} }

View File

@ -1,12 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, reactive, watch } from 'vue'; import { computed, reactive, watch } from 'vue';
import { Tinymce } from '@sa/tinymce';
import { fetchCreateNotice, fetchUpdateNotice } from '@/service/api/system/notice'; import { fetchCreateNotice, fetchUpdateNotice } from '@/service/api/system/notice';
import { getToken } from '@/store/modules/auth/shared';
import { useAppStore } from '@/store/modules/app';
import { useThemeStore } from '@/store/modules/theme';
import { useFormRules, useNaiveForm } from '@/hooks/common/form'; import { useFormRules, useNaiveForm } from '@/hooks/common/form';
import { getServiceBaseURL } from '@/utils/service';
import { $t } from '@/locales'; import { $t } from '@/locales';
defineOptions({ defineOptions({
@ -32,17 +27,6 @@ const visible = defineModel<boolean>('visible', {
default: false default: false
}); });
const appStore = useAppStore();
const themeStore = useThemeStore();
const isHttpProxy = import.meta.env.DEV && import.meta.env.VITE_HTTP_PROXY === 'Y';
const { baseURL } = getServiceBaseURL(import.meta.env, isHttpProxy);
const headers: Record<string, string> = {
Authorization: `Bearer ${getToken()}`,
clientid: import.meta.env.VITE_APP_CLIENT_ID!
};
const { formRef, validate, restoreValidation } = useNaiveForm(); const { formRef, validate, restoreValidation } = useNaiveForm();
const { createRequiredRule } = useFormRules(); const { createRequiredRule } = useFormRules();
@ -139,13 +123,7 @@ watch(visible, () => {
<DictRadio v-model:value="model.noticeType" dict-code="sys_notice_type" /> <DictRadio v-model:value="model.noticeType" dict-code="sys_notice_type" />
</NFormItem> </NFormItem>
<NFormItem label="公告内容" path="noticeContent"> <NFormItem label="公告内容" path="noticeContent">
<Tinymce <TinymceEditor v-model:value="model.noticeContent" />
v-model="model.noticeContent"
:lang="appStore.locale"
:is-dark="themeStore.darkMode"
:upload-url="`${baseURL}/resource/oss/upload`"
:upload-headers="headers"
/>
</NFormItem> </NFormItem>
<NFormItem label="公告状态" path="status"> <NFormItem label="公告状态" path="status">
<DictRadio v-model:value="model.status" dict-code="sys_normal_disable" /> <DictRadio v-model:value="model.status" dict-code="sys_normal_disable" />