refactor gen templates to freemarker

This commit is contained in:
疯狂的狮子Li 2026-06-18 15:32:30 +08:00
parent 6030831f55
commit 8716e1285d
8 changed files with 570 additions and 655 deletions

View File

@ -17,10 +17,10 @@ description: 在当前 plus-ui-new 前端项目中按真实 Vue 3 + TypeScript +
- 系统复杂页优先看 `src/views/system/user/index.vue`、`system/role`、`system/post`、`system/config`。 - 系统复杂页优先看 `src/views/system/user/index.vue`、`system/role`、`system/post`、`system/config`。
- workflow 业务页优先看 `src/views/workflow/*` 同类页面。 - workflow 业务页优先看 `src/views/workflow/*` 同类页面。
4. 新增标准页面前,对照项目内模板确认基础骨架: 4. 新增标准页面前,对照项目内模板确认基础骨架:
- API 模板:`gen/api.ts.vm` - API 模板:`gen/api.ts.ftl`
- types 模板:`gen/types.ts.vm` - types 模板:`gen/types.ts.ftl`
- 标准单表页模板:`gen/index.vue.vm` - 标准单表页模板:`gen/index.vue.ftl`
- 树表页模板:`gen/index-tree.vue.vm` - 树表页模板:`gen/index-tree.vue.ftl`
5. 新增代码时通常同步维护 `src/api/<module>/<business>/index.ts`、`types.ts`、`src/views/<module>/<business>/index.vue`。 5. 新增代码时通常同步维护 `src/api/<module>/<business>/index.ts`、`types.ts`、`src/views/<module>/<business>/index.vue`。
6. 增强已有页面时只做增量修改,保留原页面的树筛选、导入导出、列显隐、权限、字典、弹窗和路由跳转能力。 6. 增强已有页面时只做增量修改,保留原页面的树筛选、导入导出、列显隐、权限、字典、弹窗和路由跳转能力。
7. 修改完成后按影响范围运行验证:优先 `pnpm exec vue-tsc --noEmit`,改动页面或导入时再跑 `pnpm lint`,大范围变更再跑 `pnpm build` 7. 修改完成后按影响范围运行验证:优先 `pnpm exec vue-tsc --noEmit`,改动页面或导入时再跑 `pnpm lint`,大范围变更再跑 `pnpm build`
@ -85,7 +85,7 @@ description: 在当前 plus-ui-new 前端项目中按真实 Vue 3 + TypeScript +
### 1. 标准单表 CRUD ### 1. 标准单表 CRUD
`gen/index.vue.vm`、`gen/api.ts.vm`、`gen/types.ts.vm` 和 `src/views/demo/demo/index.vue` 为主要起点,补齐列表、搜索、分页、新增、编辑、删除、导出、权限、类型和验证。 `gen/index.vue.ftl`、`gen/api.ts.ftl`、`gen/types.ts.ftl` 和 `src/views/demo/demo/index.vue` 为主要起点,补齐列表、搜索、分页、新增、编辑、删除、导出、权限、类型和验证。
### 2. 树表 CRUD ### 2. 树表 CRUD

View File

@ -14,7 +14,7 @@
- 先看 `src/api/system/client/*``src/views/system/client/index.vue` 是否已存在。 - 先看 `src/api/system/client/*``src/views/system/client/index.vue` 是否已存在。
- 再看 `src/views/demo/demo/index.vue` 的标准 hooks 版 CRUD 骨架。 - 再看 `src/views/demo/demo/index.vue` 的标准 hooks 版 CRUD 骨架。
- 对照项目内 `gen/api.ts.vm`、`gen/types.ts.vm`、`gen/index.vue.vm`。 - 对照项目内 `gen/api.ts.ftl`、`gen/types.ts.ftl`、`gen/index.vue.ftl`。
- 生成或修改 `api/index.ts`、`types.ts`、`views/.../index.vue`。 - 生成或修改 `api/index.ts`、`types.ts`、`views/.../index.vue`。
- 使用 `AxiosPromise` from `@/utils/api-types`、`PageResult` from `@/api/types`、`useLoading`、`useFormDialog`、`useSearchReset`、`useTableSelection`。 - 使用 `AxiosPromise` from `@/utils/api-types`、`PageResult` from `@/api/types`、`useLoading`、`useFormDialog`、`useSearchReset`、`useTableSelection`。

View File

@ -10,10 +10,10 @@
- 监控页:`src/views/monitor/*`、`src/api/monitor/*`。 - 监控页:`src/views/monitor/*`、`src/api/monitor/*`。
- 公共 hooks`src/hooks/async/useLoading.ts`、`src/hooks/dialog/*`、`src/hooks/form/*`、`src/hooks/table/*`、`src/hooks/tree/*`。 - 公共 hooks`src/hooks/async/useLoading.ts`、`src/hooks/dialog/*`、`src/hooks/form/*`、`src/hooks/table/*`、`src/hooks/tree/*`。
- 项目内 generator 模板: - 项目内 generator 模板:
`gen/api.ts.vm` `gen/api.ts.ftl`
`gen/types.ts.vm` `gen/types.ts.ftl`
`gen/index.vue.vm` `gen/index.vue.ftl`
`gen/index-tree.vue.vm` `gen/index-tree.vue.ftl`
## 基础栈与格式 ## 基础栈与格式
@ -44,7 +44,7 @@
`changeXxxStatus` -> `PUT /<module>/<business>/changeStatus` `changeXxxStatus` -> `PUT /<module>/<business>/changeStatus`
- query string 用 `params`,请求体用 `data` - query string 用 `params`,请求体用 `data`
- 加密、防重复提交等 headers 直接写在请求配置里,例如用户重置密码中的 `isEncrypt`、`repeatSubmit`。 - 加密、防重复提交等 headers 直接写在请求配置里,例如用户重置密码中的 `isEncrypt`、`repeatSubmit`。
- 当前仓库有些 API 使用 `export const`,有些使用 `export function`;新增标准 CRUD 优先跟随 `gen/api.ts.vm` 和相邻模块。 - 当前仓库有些 API 使用 `export const`,有些使用 `export function`;新增标准 CRUD 优先跟随 `gen/api.ts.ftl` 和相邻模块。
- 只有相邻模块已有 `export default { ... }` 聚合时才新增默认导出。 - 只有相邻模块已有 `export default { ... }` 聚合时才新增默认导出。
## 类型文件规则 ## 类型文件规则
@ -128,8 +128,8 @@
## 与 gen 模板的关系 ## 与 gen 模板的关系
- `gen` 是当前前端项目内的生成模板,优先于外部后端工程拷贝的模板。 - `gen` 是当前前端项目内的生成模板,优先于外部后端工程拷贝的模板。
- 新增标准单表页面时读取 `gen/index.vue.vm`、`gen/api.ts.vm`、`gen/types.ts.vm`。 - 新增标准单表页面时读取 `gen/index.vue.ftl`、`gen/api.ts.ftl`、`gen/types.ts.ftl`。
- 新增树表页面时读取 `gen/index-tree.vue.vm`、`gen/api.ts.vm`、`gen/types.ts.vm`。 - 新增树表页面时读取 `gen/index-tree.vue.ftl`、`gen/api.ts.ftl`、`gen/types.ts.ftl`。
- `gen` 模板是标准骨架,不是最终答案;落地时仍要对照目标模块真实页面和公共 hooks。 - `gen` 模板是标准骨架,不是最终答案;落地时仍要对照目标模块真实页面和公共 hooks。
- 当前前端项目已经把生成页升级为 hooks 版:`useLoading`、`useFormDialog`、`useSearchReset`、`useTableSelection`、`useDateRangeQuery`。 - 当前前端项目已经把生成页升级为 hooks 版:`useLoading`、`useFormDialog`、`useSearchReset`、`useTableSelection`、`useDateRangeQuery`。
- 新增标准 CRUD 时,先从 `gen` 确认字段、权限、导出、状态切换、排序、日期范围等,再落成当前项目的实际页面壳。 - 新增标准 CRUD 时,先从 `gen` 确认字段、权限、导出、状态切换、排序、日期范围等,再落成当前项目的实际页面壳。

View File

@ -52,13 +52,13 @@ export const update${BusinessName} = (data: ${BusinessName}Form) => {
}); });
}; };
#if($enableStatus) <#if enableStatus>
/** /**
* 修改${functionName}状态 * 修改${functionName}状态
* @param ${pkColumn.javaField} * @param ${pkColumn.javaField}
* @param status * @param status
*/ */
export const change${BusinessName}Status = (${pkColumn.javaField}: string | number, status: #if($statusColumn.javaType == 'String')string#else number#end) => { export const change${BusinessName}Status = (${pkColumn.javaField}: string | number, status: <#if statusColumn.javaType == 'Boolean'>boolean<#elseif statusColumn.javaType == 'String'>string<#else> number</#if>) => {
return request({ return request({
url: '/${moduleName}/${businessName}/changeStatus', url: '/${moduleName}/${businessName}/changeStatus',
method: 'put', method: 'put',
@ -68,15 +68,15 @@ export const change${BusinessName}Status = (${pkColumn.javaField}: string | numb
} }
}); });
}; };
#end </#if>
#if($enableSort) <#if enableSort>
/** /**
* 调整${functionName}排序 * 调整${functionName}排序
* @param ${pkColumn.javaField} * @param ${pkColumn.javaField}
* @param sortValue * @param sortValue
*/ */
export const update${BusinessName}Sort = (${pkColumn.javaField}: string | number, sortValue: #if($sortColumn.javaType == 'String' || $sortColumn.javaType == 'LocalDateTime')string#else number#end) => { export const update${BusinessName}Sort = (${pkColumn.javaField}: string | number, sortValue: <#if sortColumn.javaType == 'String' || sortColumn.javaType == 'LocalDateTime'>string<#else> number</#if>) => {
return request({ return request({
url: '/${moduleName}/${businessName}/updateSort', url: '/${moduleName}/${businessName}/updateSort',
method: 'put', method: 'put',
@ -86,7 +86,7 @@ export const update${BusinessName}Sort = (${pkColumn.javaField}: string | number
} }
}); });
}; };
#end </#if>
/** /**
* 删除${functionName} * 删除${functionName}
@ -98,3 +98,6 @@ export const del${BusinessName} = (${pkColumn.javaField}: string | number | Arra
method: 'delete' method: 'delete'
}); });
}; };

View File

@ -8,70 +8,62 @@
</div> </div>
</template> </template>
<el-form ref="queryFormRef" :model="queryParams" :inline="true" class="query-form"> <el-form ref="queryFormRef" :model="queryParams" :inline="true" class="query-form">
#foreach($column in $columns) <#list columns as column>
#if($column.query) <#if column.query>
#set($dictType=$column.dictType) <#if column.htmlType == "input" || column.htmlType == "textarea">
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
#set($parentheseIndex=$column.columnComment.indexOf("")) <el-input v-model="queryParams.${column.javaField}" placeholder="请输入${column.columnLabel}" clearable @keyup.enter="handleQuery" />
#if($parentheseIndex != -1)
#set($comment=$column.columnComment.substring(0, $parentheseIndex))
#else
#set($comment=$column.columnComment)
#end
#if($column.htmlType == "input" || $column.htmlType == "textarea")
<el-form-item label="${comment}" prop="${column.javaField}">
<el-input v-model="queryParams.${column.javaField}" placeholder="请输入${comment}" clearable @keyup.enter="handleQuery" />
</el-form-item> </el-form-item>
#elseif($column.htmlType == "inputNumber") <#elseif column.htmlType == "inputNumber">
<el-form-item label="${comment}" prop="${column.javaField}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<el-input-number v-model="queryParams.${column.javaField}" controls-position="right" /> <el-input-number v-model="queryParams.${column.javaField}" controls-position="right" />
</el-form-item> </el-form-item>
#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && "" != $dictType) <#elseif (column.htmlType == "select" || column.htmlType == "radio") && column.dictType?has_content>
<el-form-item label="${comment}" prop="${column.javaField}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable> <el-select v-model="queryParams.${column.javaField}" placeholder="请选择${column.columnLabel}" clearable>
<el-option v-for="dict in ${dictType}" :key="dict.value" :label="dict.label" :value="dict.value"/> <el-option v-for="dict in ${column.dictType}" :key="dict.value" :label="dict.label" :value="dict.value"/>
</el-select> </el-select>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "switch" && "" != $dictType) <#elseif column.htmlType == "switch" && column.dictType?has_content>
<el-form-item label="${comment}" prop="${column.javaField}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable> <el-select v-model="queryParams.${column.javaField}" placeholder="请选择${column.columnLabel}" clearable>
<el-option v-for="dict in ${dictType}" :key="dict.value" :label="dict.label" :value="dict.value"/> <el-option v-for="dict in ${column.dictType}" :key="dict.value" :label="dict.label" :value="dict.value"/>
</el-select> </el-select>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "switch") <#elseif column.htmlType == "switch">
<el-form-item label="${comment}" prop="${column.javaField}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable> <el-select v-model="queryParams.${column.javaField}" placeholder="请选择${column.columnLabel}" clearable>
#if($column.javaType == "Boolean") <#if column.javaType == "Boolean">
<el-option label="是" :value="true" /> <el-option label="是" :value="true" />
<el-option label="否" :value="false" /> <el-option label="否" :value="false" />
#elseif($column.javaType == "Integer" || $column.javaType == "Long") <#elseif column.javaType == "Integer" || column.javaType == "Long">
<el-option label="开启" :value="0" /> <el-option label="开启" :value="0" />
<el-option label="关闭" :value="1" /> <el-option label="关闭" :value="1" />
#else <#else>
<el-option label="开启" value="0" /> <el-option label="开启" value="0" />
<el-option label="关闭" value="1" /> <el-option label="关闭" value="1" />
#end </#if>
</el-select> </el-select>
</el-form-item> </el-form-item>
#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && $dictType) <#elseif (column.htmlType == "select" || column.htmlType == "radio") && column.dictType?has_content>
<el-form-item label="${comment}" prop="${column.javaField}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable> <el-select v-model="queryParams.${column.javaField}" placeholder="请选择${column.columnLabel}" clearable>
<el-option label="请选择字典生成" value="" /> <el-option label="请选择字典生成" value="" />
</el-select> </el-select>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "datetime" && $column.queryType != "BETWEEN") <#elseif column.htmlType == "datetime" && column.queryType != "BETWEEN">
<el-form-item label="${comment}" prop="${column.javaField}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<el-date-picker clearable <el-date-picker clearable
v-model="queryParams.${column.javaField}" v-model="queryParams.${column.javaField}"
type="date" type="date"
value-format="YYYY-MM-DD" value-format="YYYY-MM-DD"
placeholder="选择${comment}" placeholder="选择${column.columnLabel}"
/> />
</el-form-item> </el-form-item>
#elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN") <#elseif column.htmlType == "datetime" && column.queryType == "BETWEEN">
<el-form-item label="${comment}" style="width: 308px"> <el-form-item label="${column.columnLabel}" style="width: 308px">
<el-date-picker <el-date-picker
v-model="dateRange${AttrName}" v-model="dateRange${column.capJavaField}"
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
type="daterange" type="daterange"
range-separator="-" range-separator="-"
@ -80,9 +72,9 @@
:default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]" :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]"
/> />
</el-form-item> </el-form-item>
#end </#if>
#end </#if>
#end </#list>
<el-form-item> <el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button> <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button> <el-button icon="Refresh" @click="resetQuery">重置</el-button>
@ -100,9 +92,9 @@
<div class="toolbar-actions"> <div class="toolbar-actions">
<el-button type="primary" plain icon="Plus" @click="handleAdd()" v-hasPermi="['${moduleName}:${businessName}:add']">新增</el-button> <el-button type="primary" plain icon="Plus" @click="handleAdd()" v-hasPermi="['${moduleName}:${businessName}:add']">新增</el-button>
<el-button type="info" plain icon="Sort" @click="handleToggleExpandAll">展开/折叠</el-button> <el-button type="info" plain icon="Sort" @click="handleToggleExpandAll">展开/折叠</el-button>
#if($enableExport) <#if enableExport>
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['${moduleName}:${businessName}:export']">导出</el-button> <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['${moduleName}:${businessName}:export']">导出</el-button>
#end </#if>
<right-toolbar v-model:show-search="showSearch" :search="false" @query-table="getList"></right-toolbar> <right-toolbar v-model:show-search="showSearch" :search="false" @query-table="getList"></right-toolbar>
</div> </div>
</div> </div>
@ -117,122 +109,115 @@
:default-expand-all="isExpandAll" :default-expand-all="isExpandAll"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }" :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
> >
#set($firstTreeListField = "") <#assign firstTreeListField = "">
#foreach($tempColumn in $columns) <#list columns as tempColumn>
#if(!$tempColumn.pk && $tempColumn.list && "" != $tempColumn.javaField && $firstTreeListField == "") <#if !tempColumn.pk && tempColumn.list && "" != tempColumn.javaField && firstTreeListField == "">
#set($firstTreeListField = $tempColumn.javaField) <#assign firstTreeListField = tempColumn.javaField>
#end </#if>
#end </#list>
#foreach($column in $columns) <#list columns as column>
#set($javaField=$column.javaField) <#if column.pk>
#set($parentheseIndex=$column.columnComment.indexOf("")) <#elseif enableStatus && statusField == column.javaField>
#if($parentheseIndex != -1) <#if column.javaField == firstTreeListField>
#set($comment=$column.columnComment.substring(0, $parentheseIndex)) <el-table-column label="${column.columnLabel}" prop="${column.javaField}">
#else <#else>
#set($comment=$column.columnComment) <el-table-column label="${column.columnLabel}" align="center" prop="${column.javaField}">
#end </#if>
#if($column.pk)
#elseif($enableStatus && $statusField == $javaField)
#if($javaField == $firstTreeListField)
<el-table-column label="${comment}" prop="${javaField}">
#else
<el-table-column label="${comment}" align="center" prop="${javaField}">
#end
<template #default="scope"> <template #default="scope">
<el-switch <el-switch
v-model="scope.row.${javaField}" v-model="scope.row.${column.javaField}"
:active-value="${statusField}ActiveValue" :active-value="${statusField}ActiveValue"
:inactive-value="${statusField}InactiveValue" :inactive-value="${statusField}InactiveValue"
@change="handleStatusChange(scope.row)" @change="handleStatusChange(scope.row)"
/> />
</template> </template>
</el-table-column> </el-table-column>
#elseif($enableSort && $sortField == $javaField) <#elseif enableSort && sortField == column.javaField>
#if($javaField == $firstTreeListField) <#if column.javaField == firstTreeListField>
<el-table-column label="${comment}" prop="${javaField}" width="160"> <el-table-column label="${column.columnLabel}" prop="${column.javaField}" width="160">
#else <#else>
<el-table-column label="${comment}" align="center" prop="${javaField}" width="160"> <el-table-column label="${column.columnLabel}" align="center" prop="${column.javaField}" width="160">
#end </#if>
<template #default="scope"> <template #default="scope">
#if($column.javaType == "LocalDateTime") <#if column.javaType == "LocalDateTime">
<el-date-picker <el-date-picker
v-model="scope.row.${javaField}" v-model="scope.row.${column.javaField}"
type="datetime" type="datetime"
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
placeholder="选择${comment}" placeholder="选择${column.columnLabel}"
@change="handleSortChange(scope.row)" @change="handleSortChange(scope.row)"
/> />
#else <#else>
<el-input-number v-model="scope.row.${javaField}" controls-position="right" :min="0" @change="handleSortChange(scope.row)" /> <el-input-number v-model="scope.row.${column.javaField}" controls-position="right" :min="0" @change="handleSortChange(scope.row)" />
#end </#if>
</template> </template>
</el-table-column> </el-table-column>
#elseif($column.list && $column.htmlType == "switch") <#elseif column.list && column.htmlType == "switch">
#if($javaField == $firstTreeListField) <#if column.javaField == firstTreeListField>
<el-table-column label="${comment}" prop="${javaField}" width="120"> <el-table-column label="${column.columnLabel}" prop="${column.javaField}" width="120">
#else <#else>
<el-table-column label="${comment}" align="center" prop="${javaField}" width="120"> <el-table-column label="${column.columnLabel}" align="center" prop="${column.javaField}" width="120">
#end </#if>
<template #default="scope"> <template #default="scope">
<el-switch <el-switch
v-model="scope.row.${javaField}" v-model="scope.row.${column.javaField}"
#if($column.javaType == "Boolean") <#if column.javaType == "Boolean">
:active-value="true" :active-value="true"
:inactive-value="false" :inactive-value="false"
#elseif($column.javaType == "Integer" || $column.javaType == "Long") <#elseif column.javaType == "Integer" || column.javaType == "Long">
:active-value="0" :active-value="0"
:inactive-value="1" :inactive-value="1"
#else <#else>
active-value="0" active-value="0"
inactive-value="1" inactive-value="1"
#end </#if>
disabled disabled
/> />
</template> </template>
</el-table-column> </el-table-column>
#elseif($column.list && $column.htmlType == "datetime") <#elseif column.list && column.htmlType == "datetime">
#if($javaField == $firstTreeListField) <#if column.javaField == firstTreeListField>
<el-table-column label="${comment}" prop="${javaField}" width="180"> <el-table-column label="${column.columnLabel}" prop="${column.javaField}" width="180">
#else <#else>
<el-table-column label="${comment}" align="center" prop="${javaField}" width="180"> <el-table-column label="${column.columnLabel}" align="center" prop="${column.javaField}" width="180">
#end </#if>
<template #default="scope"> <template #default="scope">
<span>{{ parseTime(scope.row.${javaField}, '{y}-{m}-{d}') }}</span> <span>{{ parseTime(scope.row.${column.javaField}, '{y}-{m}-{d}') }}</span>
</template> </template>
</el-table-column> </el-table-column>
#elseif($column.list && $column.htmlType == "imageUpload") <#elseif column.list && column.htmlType == "imageUpload">
#if($javaField == $firstTreeListField) <#if column.javaField == firstTreeListField>
<el-table-column label="${comment}" prop="${javaField}Url" width="100"> <el-table-column label="${column.columnLabel}" prop="${column.javaField}Url" width="100">
#else <#else>
<el-table-column label="${comment}" align="center" prop="${javaField}Url" width="100"> <el-table-column label="${column.columnLabel}" align="center" prop="${column.javaField}Url" width="100">
#end </#if>
<template #default="scope"> <template #default="scope">
<image-preview :src="scope.row.${javaField}Url" :width="50" :height="50"/> <image-preview :src="scope.row.${column.javaField}Url" :width="50" :height="50"/>
</template> </template>
</el-table-column> </el-table-column>
#elseif($column.list && $column.dictColumn) <#elseif column.list && column.dictColumn>
#if($javaField == $firstTreeListField) <#if column.javaField == firstTreeListField>
<el-table-column label="${comment}" prop="${javaField}"> <el-table-column label="${column.columnLabel}" prop="${column.javaField}">
#else <#else>
<el-table-column label="${comment}" align="center" prop="${javaField}"> <el-table-column label="${column.columnLabel}" align="center" prop="${column.javaField}">
#end </#if>
<template #default="scope"> <template #default="scope">
#if($column.htmlType == "checkbox") <#if column.htmlType == "checkbox">
<dict-tag :options="${column.dictType}" :value="scope.row.${javaField} ? scope.row.${javaField}.split(',') : []"/> <dict-tag :options="${column.dictType}" :value="scope.row.${column.javaField} ? scope.row.${column.javaField}.split(',') : []"/>
#else <#else>
<dict-tag :options="${column.dictType}" :value="scope.row.${javaField}"/> <dict-tag :options="${column.dictType}" :value="scope.row.${column.javaField}"/>
#end </#if>
</template> </template>
</el-table-column> </el-table-column>
#elseif($column.list && "" != $javaField) <#elseif column.list && "" != column.javaField>
#if($javaField == $firstTreeListField) <#if column.javaField == firstTreeListField>
<el-table-column label="${comment}" prop="${javaField}" /> <el-table-column label="${column.columnLabel}" prop="${column.javaField}" />
#else <#else>
<el-table-column label="${comment}" align="center" prop="${javaField}" /> <el-table-column label="${column.columnLabel}" align="center" prop="${column.javaField}" />
#end </#if>
#end </#if>
#end </#list>
#if($enableStatus && !$statusColumn.list) <#if enableStatus && !statusColumn.list>
<el-table-column label="${statusColumn.columnComment}" align="center" prop="${statusField}"> <el-table-column label="${statusColumn.columnComment}" align="center" prop="${statusField}">
<template #default="scope"> <template #default="scope">
<el-switch <el-switch
@ -243,11 +228,11 @@
/> />
</template> </template>
</el-table-column> </el-table-column>
#end </#if>
#if($enableSort && !$sortColumn.list) <#if enableSort && !sortColumn.list>
<el-table-column label="${sortColumn.columnComment}" align="center" prop="${sortField}" width="160"> <el-table-column label="${sortColumn.columnComment}" align="center" prop="${sortField}" width="160">
<template #default="scope"> <template #default="scope">
#if($sortColumn.javaType == "LocalDateTime") <#if sortColumn.javaType == "LocalDateTime">
<el-date-picker <el-date-picker
v-model="scope.row.${sortField}" v-model="scope.row.${sortField}"
type="datetime" type="datetime"
@ -255,12 +240,12 @@
placeholder="选择${sortColumn.columnComment}" placeholder="选择${sortColumn.columnComment}"
@change="handleSortChange(scope.row)" @change="handleSortChange(scope.row)"
/> />
#else <#else>
<el-input-number v-model="scope.row.${sortField}" controls-position="right" :min="0" @change="handleSortChange(scope.row)" /> <el-input-number v-model="scope.row.${sortField}" controls-position="right" :min="0" @change="handleSortChange(scope.row)" />
#end </#if>
</template> </template>
</el-table-column> </el-table-column>
#end </#if>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope"> <template #default="scope">
<el-tooltip content="修改" placement="top"> <el-tooltip content="修改" placement="top">
@ -279,137 +264,129 @@
<!-- 添加或修改${functionName}对话框 --> <!-- 添加或修改${functionName}对话框 -->
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body> <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
<el-form ref="${businessName}FormRef" :model="form" :rules="rules" label-width="80px"> <el-form ref="${businessName}FormRef" :model="form" :rules="rules" label-width="80px">
#foreach($column in $columns) <#list columns as column>
#set($field=$column.javaField) <#if (column.insert || column.edit) && !column.pk>
#if(($column.insert || $column.edit) && !$column.pk) <#if "" != treeParentCode && column.javaField == treeParentCode>
#set($parentheseIndex=$column.columnComment.indexOf("")) <el-form-item label="${column.columnLabel}" prop="${treeParentCode}">
#if($parentheseIndex != -1)
#set($comment=$column.columnComment.substring(0, $parentheseIndex))
#else
#set($comment=$column.columnComment)
#end
#set($dictType=$column.dictType)
#if("" != $treeParentCode && $column.javaField == $treeParentCode)
<el-form-item label="${comment}" prop="${treeParentCode}">
<el-tree-select <el-tree-select
v-model="form.${treeParentCode}" v-model="form.${treeParentCode}"
:data="${businessName}Options" :data="${businessName}Options"
:props="{ value: '${treeCode}', label: '${treeName}', children: 'children' } as any" :props="{ value: '${treeCode}', label: '${treeName}', children: 'children' } as any"
value-key="${treeCode}" value-key="${treeCode}"
placeholder="请选择${comment}" placeholder="请选择${column.columnLabel}"
check-strictly check-strictly
/> />
</el-form-item> </el-form-item>
#elseif($column.htmlType == "input") <#elseif column.htmlType == "input">
<el-form-item label="${comment}" prop="${field}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<el-input v-model="form.${field}" placeholder="请输入${comment}" /> <el-input v-model="form.${column.javaField}" placeholder="请输入${column.columnLabel}" />
</el-form-item> </el-form-item>
#elseif($column.htmlType == "inputNumber") <#elseif column.htmlType == "inputNumber">
<el-form-item label="${comment}" prop="${field}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<el-input-number v-model="form.${field}" controls-position="right" /> <el-input-number v-model="form.${column.javaField}" controls-position="right" />
</el-form-item> </el-form-item>
#elseif($column.htmlType == "imageUpload") <#elseif column.htmlType == "imageUpload">
<el-form-item label="${comment}" prop="${field}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<image-upload v-model="form.${field}"/> <image-upload v-model="form.${column.javaField}"/>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "fileUpload") <#elseif column.htmlType == "fileUpload">
<el-form-item label="${comment}" prop="${field}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<file-upload v-model="form.${field}"/> <file-upload v-model="form.${column.javaField}"/>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "editor") <#elseif column.htmlType == "editor">
<el-form-item label="${comment}"> <el-form-item label="${column.columnLabel}">
<editor v-model="form.${field}" :min-height="192"/> <editor v-model="form.${column.javaField}" :min-height="192"/>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "select" && "" != $dictType) <#elseif column.htmlType == "select" && column.dictType?has_content>
<el-form-item label="${comment}" prop="${field}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<el-select v-model="form.${field}" placeholder="请选择${comment}"> <el-select v-model="form.${column.javaField}" placeholder="请选择${column.columnLabel}">
<el-option <el-option
v-for="dict in ${dictType}" v-for="dict in ${column.dictType}"
:key="dict.value" :key="dict.value"
:label="dict.label" :label="dict.label"
#if($column.javaType == "Integer" || $column.javaType == "Long") <#if column.javaType == "Integer" || column.javaType == "Long">
:value="parseInt(dict.value)" :value="parseInt(dict.value)"
#else <#else>
:value="dict.value" :value="dict.value"
#end </#if>
></el-option> ></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "select" && $dictType) <#elseif column.htmlType == "select" && column.dictType?has_content>
<el-form-item label="${comment}" prop="${field}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<el-select v-model="form.${field}" placeholder="请选择${comment}"> <el-select v-model="form.${column.javaField}" placeholder="请选择${column.columnLabel}">
<el-option label="请选择字典生成" value="" /> <el-option label="请选择字典生成" value="" />
</el-select> </el-select>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "checkbox" && "" != $dictType) <#elseif column.htmlType == "checkbox" && column.dictType?has_content>
<el-form-item label="${comment}" prop="${field}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<el-checkbox-group v-model="form.${field}"> <el-checkbox-group v-model="form.${column.javaField}">
<el-checkbox <el-checkbox
v-for="dict in ${dictType}" v-for="dict in ${column.dictType}"
:key="dict.value" :key="dict.value"
:label="dict.value"> :label="dict.value">
{{dict.label}} {{dict.label}}
</el-checkbox> </el-checkbox>
</el-checkbox-group> </el-checkbox-group>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "checkbox" && $dictType) <#elseif column.htmlType == "checkbox" && column.dictType?has_content>
<el-form-item label="${comment}" prop="${field}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<el-checkbox-group v-model="form.${field}"> <el-checkbox-group v-model="form.${column.javaField}">
<el-checkbox>请选择字典生成</el-checkbox> <el-checkbox>请选择字典生成</el-checkbox>
</el-checkbox-group> </el-checkbox-group>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "radio" && "" != $dictType) <#elseif column.htmlType == "radio" && column.dictType?has_content>
<el-form-item label="${comment}" prop="${field}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<el-radio-group v-model="form.${field}"> <el-radio-group v-model="form.${column.javaField}">
<el-radio <el-radio
v-for="dict in ${dictType}" v-for="dict in ${column.dictType}"
:key="dict.value" :key="dict.value"
#if($column.javaType == "Integer" || $column.javaType == "Long") <#if column.javaType == "Integer" || column.javaType == "Long">
:value="parseInt(dict.value)" :value="parseInt(dict.value)"
#else <#else>
:value="dict.value" :value="dict.value"
#end </#if>
>{{dict.label}}</el-radio> >{{dict.label}}</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "radio" && $dictType) <#elseif column.htmlType == "radio" && column.dictType?has_content>
<el-form-item label="${comment}" prop="${field}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<el-radio-group v-model="form.${field}"> <el-radio-group v-model="form.${column.javaField}">
<el-radio value="1">请选择字典生成</el-radio> <el-radio value="1">请选择字典生成</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "switch") <#elseif column.htmlType == "switch">
<el-form-item label="${comment}" prop="${field}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<el-switch <el-switch
v-model="form.${field}" v-model="form.${column.javaField}"
#if($column.javaType == "Boolean") <#if column.javaType == "Boolean">
:active-value="true" :active-value="true"
:inactive-value="false" :inactive-value="false"
#elseif($column.javaType == "Integer" || $column.javaType == "Long") <#elseif column.javaType == "Integer" || column.javaType == "Long">
:active-value="0" :active-value="0"
:inactive-value="1" :inactive-value="1"
#else <#else>
active-value="0" active-value="0"
inactive-value="1" inactive-value="1"
#end </#if>
/> />
</el-form-item> </el-form-item>
#elseif($column.htmlType == "datetime") <#elseif column.htmlType == "datetime">
<el-form-item label="${comment}" prop="${field}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<el-date-picker clearable <el-date-picker clearable
v-model="form.${field}" v-model="form.${column.javaField}"
type="datetime" type="datetime"
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
placeholder="选择${comment}" placeholder="选择${column.columnLabel}"
/> />
</el-form-item> </el-form-item>
#elseif($column.htmlType == "textarea") <#elseif column.htmlType == "textarea">
<el-form-item label="${comment}" prop="${field}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<el-input v-model="form.${field}" type="textarea" placeholder="请输入内容" /> <el-input v-model="form.${column.javaField}" type="textarea" placeholder="请输入内容" />
</el-form-item> </el-form-item>
#end </#if>
#end </#if>
#end </#list>
</el-form> </el-form>
<template #footer> <template #footer>
<div class="dialog-footer"> <div class="dialog-footer">
@ -421,56 +398,49 @@
</div> </div>
</template> </template>
#set($needAddDateRange = false)
#foreach ($column in $columns)
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
#set($needAddDateRange = true)
#end
#end
<script setup name="${BusinessName}" lang="ts"> <script setup name="${BusinessName}" lang="ts">
import { import {
add${BusinessName}, add${BusinessName},
#if($enableStatus) <#if enableStatus>
change${BusinessName}Status, change${BusinessName}Status,
#end </#if>
del${BusinessName}, del${BusinessName},
get${BusinessName}, get${BusinessName},
list${BusinessName}, list${BusinessName},
#if($enableSort) <#if enableSort>
update${BusinessName}Sort, update${BusinessName}Sort,
#end </#if>
update${BusinessName} update${BusinessName}
} from '@/api/${moduleName}/${businessName}'; } from '@/api/${moduleName}/${businessName}';
import { ${BusinessName}Form, ${BusinessName}Query, ${BusinessName}VO } from '@/api/${moduleName}/${businessName}/types'; import { ${BusinessName}Form, ${BusinessName}Query, ${BusinessName}VO } from '@/api/${moduleName}/${businessName}/types';
import { useLoading } from '@/hooks/async/useLoading'; import { useLoading } from '@/hooks/async/useLoading';
import { useFormDialog } from '@/hooks/dialog/useFormDialog'; import { useFormDialog } from '@/hooks/dialog/useFormDialog';
#if($needAddDateRange) <#if needAddDateRange>
import { useDateRangeQuery } from '@/hooks/form/useDateRangeQuery'; import { useDateRangeQuery } from '@/hooks/form/useDateRangeQuery';
#end </#if>
import { useSearchReset } from '@/hooks/form/useSearchReset'; import { useSearchReset } from '@/hooks/form/useSearchReset';
import { useSearchToggle } from '@/hooks/form/useSearchToggle'; import { useSearchToggle } from '@/hooks/form/useSearchToggle';
import { useTreeTableExpand } from '@/hooks/tree/useTreeTableExpand'; import { useTreeTableExpand } from '@/hooks/tree/useTreeTableExpand';
#if(${dicts} != '') <#if needDict>
import { useDict } from '@/utils/dict'; import { useDict } from '@/utils/dict';
#end </#if>
import modal from '@/plugins/modal'; import modal from '@/plugins/modal';
import { handleTree } from '@/utils/ruoyi'; import { handleTree } from '@/utils/ruoyi';
#if($enableExport) <#if enableExport>
import { download as requestDownload } from '@/utils/request'; import { download as requestDownload } from '@/utils/request';
#end </#if>
#if(${dicts} != '') <#if needDict>
#set($dictsNoSymbol=$dicts.replace("'", ""))
const { ${dictsNoSymbol} } = toRefs<any>(useDict(${dicts})); const { ${dictsNoSymbol} } = toRefs<any>(useDict(${dicts}));
#end </#if>
#if($enableStatus) <#if enableStatus>
const ${statusField}ActiveValue = #if($statusColumn.javaType == "Boolean")true#elseif($statusColumn.javaType == "Integer" || $statusColumn.javaType == "Long")0#else'0'#end; const ${statusField}ActiveValue = <#if statusColumn.javaType == "Boolean">true<#elseif statusColumn.javaType == "Integer" || statusColumn.javaType == "Long">0<#else>'0'</#if>;
const ${statusField}InactiveValue = #if($statusColumn.javaType == "Boolean")false#elseif($statusColumn.javaType == "Integer" || $statusColumn.javaType == "Long")1#else'1'#end; const ${statusField}InactiveValue = <#if statusColumn.javaType == "Boolean">false<#elseif statusColumn.javaType == "Integer" || statusColumn.javaType == "Long">1<#else>'1'</#if>;
#end </#if>
type ${BusinessName}Option = { type ${BusinessName}Option = {
${treeCode}: #if($treeParentColumn.javaType == 'String')string#else number#end; ${treeCode}: <#if treeParentColumn.javaType == 'String'>string<#else> number</#if>;
${treeName}: string; ${treeName}: string;
children?: ${BusinessName}Option[]; children?: ${BusinessName}Option[];
}; };
@ -490,65 +460,58 @@ const { isExpandAll, handleToggleExpandAll } = useTreeTableExpand<${BusinessName
data: ${businessName}List data: ${businessName}List
}); });
#foreach ($column in $columns) <#list columns as column>
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN") <#if column.htmlType == "datetime" && column.queryType == "BETWEEN">
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
const { const {
dateRange: dateRange${AttrName}, dateRange: dateRange${column.capJavaField},
applyDateRange: apply${AttrName}DateRange, applyDateRange: apply${column.capJavaField}DateRange,
resetDateRange: reset${AttrName}DateRange resetDateRange: reset${column.capJavaField}DateRange
} = useDateRangeQuery('${AttrName}'); } = useDateRangeQuery('${column.capJavaField}');
#end </#if>
#end </#list>
const initFormData: ${BusinessName}Form = { const initFormData: ${BusinessName}Form = {
#foreach ($column in $columns) <#list columns as column>
#if($column.insert || $column.edit) <#if column.insert || column.edit>
#if($column.htmlType == "checkbox") <#if column.htmlType == "checkbox">
$column.javaField: []#if($foreach.count != $columns.size()),#end ${column.javaField}: [],
#else <#else>
$column.javaField: undefined#if($foreach.count != $columns.size()),#end ${column.javaField}: undefined,
#end </#if>
#end </#if>
#end </#list>
} }
const data = reactive<PageData<${BusinessName}Form, ${BusinessName}Query>>({ const data = reactive<PageData<${BusinessName}Form, ${BusinessName}Query>>({
form: {...initFormData}, form: {...initFormData},
queryParams: { queryParams: {
#foreach ($column in $columns) <#list columns as column>
#if($column.query) <#if column.query>
#if($column.htmlType != "datetime" || $column.queryType != "BETWEEN") <#if column.htmlType != "datetime" || column.queryType != "BETWEEN">
$column.javaField: undefined, ${column.javaField}: undefined,
#end </#if>
#end </#if>
#end </#list>
params: { params: {
#foreach ($column in $columns) <#list columns as column>
#if($column.query) <#if column.query>
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN") <#if column.htmlType == "datetime" && column.queryType == "BETWEEN">
$column.javaField: undefined#if($foreach.count != $columns.size()),#end ${column.javaField}: undefined,
#end </#if>
#end </#if>
#end </#list>
} }
}, },
rules: { rules: {
#foreach ($column in $columns) <#list columns as column>
#if($column.insert || $column.edit) <#if column.insert || column.edit>
#if($column.required) <#if column.required>
#set($parentheseIndex=$column.columnComment.indexOf("")) ${column.javaField}: [
#if($parentheseIndex != -1) { required: true, message: "${column.columnLabel}不能为空", trigger: <#if column.htmlType == "select" || column.htmlType == "radio" || column.htmlType == "switch" || column.htmlType == "inputNumber">"change"<#else>"blur"</#if> }
#set($comment=$column.columnComment.substring(0, $parentheseIndex)) ],
#else </#if>
#set($comment=$column.columnComment) </#if>
#end </#list>
$column.javaField: [
{ required: true, message: "$comment不能为空", trigger: #if($column.htmlType == "select" || $column.htmlType == "radio" || $column.htmlType == "switch" || $column.htmlType == "inputNumber")"change"#else"blur"#end }
]#if($foreach.count != $columns.size()),#end
#end
#end
#end
} }
}); });
@ -562,18 +525,17 @@ const { dialog, resetForm: reset, openDialog, showDialog, closeDialog } = useFor
/** 查询${functionName}列表 */ /** 查询${functionName}列表 */
const getList = async () => { const getList = async () => {
await withLoading(async () => { await withLoading(async () => {
#if($needAddDateRange) <#if needAddDateRange>
let params = queryParams.value; let params = queryParams.value;
#foreach ($column in $columns) <#list columns as column>
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN") <#if column.htmlType == "datetime" && column.queryType == "BETWEEN">
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) params = apply${column.capJavaField}DateRange(params);
params = apply${AttrName}DateRange(params); </#if>
#end </#list>
#end
const res = await list${BusinessName}(params); const res = await list${BusinessName}(params);
#else <#else>
const res = await list${BusinessName}(queryParams.value); const res = await list${BusinessName}(queryParams.value);
#end </#if>
const data = handleTree<${BusinessName}VO>(res.data, '${treeCode}', '${treeParentCode}'); const data = handleTree<${BusinessName}VO>(res.data, '${treeCode}', '${treeParentCode}');
if (data) { if (data) {
${businessName}List.value = data; ${businessName}List.value = data;
@ -605,12 +567,11 @@ const { resetQuery } = useSearchReset({
queryFormRef, queryFormRef,
queryParams, queryParams,
resetExtras: () => { resetExtras: () => {
#foreach ($column in $columns) <#list columns as column>
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN") <#if column.htmlType == "datetime" && column.queryType == "BETWEEN">
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) reset${column.capJavaField}DateRange();
reset${AttrName}DateRange(); </#if>
#end </#list>
#end
}, },
afterReset: () => { afterReset: () => {
handleQuery(); handleQuery();
@ -637,11 +598,11 @@ const handleUpdate = async (row: Partial<${BusinessName}VO>) => {
} }
const res = await get${BusinessName}(row.${pkColumn.javaField}); const res = await get${BusinessName}(row.${pkColumn.javaField});
Object.assign(form.value, res.data); Object.assign(form.value, res.data);
#foreach ($column in $columns) <#list columns as column>
#if($column.htmlType == "checkbox") <#if column.htmlType == "checkbox">
form.value.$column.javaField = form.value.${column.javaField}.split(","); form.value.${column.javaField} = form.value.${column.javaField}.split(",");
#end </#if>
#end </#list>
showDialog('修改${functionName}'); showDialog('修改${functionName}');
}; };
@ -650,11 +611,11 @@ const submitForm = () => {
${businessName}FormRef.value?.validate(async (valid: boolean) => { ${businessName}FormRef.value?.validate(async (valid: boolean) => {
if (valid) { if (valid) {
buttonLoading.value = true; buttonLoading.value = true;
#foreach ($column in $columns) <#list columns as column>
#if($column.htmlType == "checkbox") <#if column.htmlType == "checkbox">
form.value.$column.javaField = form.value.${column.javaField}.join(","); form.value.${column.javaField} = form.value.${column.javaField}.join(",");
#end </#if>
#end </#list>
if (form.value.${pkColumn.javaField}) { if (form.value.${pkColumn.javaField}) {
await update${BusinessName}(form.value).finally(() => (buttonLoading.value = false)); await update${BusinessName}(form.value).finally(() => (buttonLoading.value = false));
} else { } else {
@ -685,7 +646,7 @@ const filterTreeOptions = (options: ${BusinessName}Option[], excludeId: string |
})); }));
}; };
#if($enableStatus) <#if enableStatus>
/** 状态修改 */ /** 状态修改 */
const handleStatusChange = async (row: Partial<${BusinessName}VO>) => { const handleStatusChange = async (row: Partial<${BusinessName}VO>) => {
const text = row.${statusField} === ${statusField}ActiveValue ? '启用' : '停用'; const text = row.${statusField} === ${statusField}ActiveValue ? '启用' : '停用';
@ -697,9 +658,9 @@ const handleStatusChange = async (row: Partial<${BusinessName}VO>) => {
row.${statusField} = row.${statusField} === ${statusField}ActiveValue ? ${statusField}InactiveValue : ${statusField}ActiveValue; row.${statusField} = row.${statusField} === ${statusField}ActiveValue ? ${statusField}InactiveValue : ${statusField}ActiveValue;
} }
}; };
#end </#if>
#if($enableSort) <#if enableSort>
/** 排序调整 */ /** 排序调整 */
const handleSortChange = async (row: Partial<${BusinessName}VO>) => { const handleSortChange = async (row: Partial<${BusinessName}VO>) => {
try { try {
@ -709,9 +670,9 @@ const handleSortChange = async (row: Partial<${BusinessName}VO>) => {
await getList(); await getList();
} }
}; };
#end </#if>
#if($enableExport) <#if enableExport>
/** 导出按钮操作 */ /** 导出按钮操作 */
const handleExport = () => { const handleExport = () => {
requestDownload( requestDownload(
@ -719,12 +680,13 @@ const handleExport = () => {
{ {
...queryParams.value ...queryParams.value
}, },
`${businessName}_#[[${new Date().getTime()}]]#.xlsx` `${businessName}_${r'${new Date().getTime()}'}.xlsx`
); );
}; };
#end </#if>
onMounted(() => { onMounted(() => {
getList(); getList();
}); });
</script> </script>

View File

@ -8,70 +8,62 @@
</div> </div>
</template> </template>
<el-form ref="queryFormRef" :model="queryParams" :inline="true" class="query-form"> <el-form ref="queryFormRef" :model="queryParams" :inline="true" class="query-form">
#foreach($column in $columns) <#list columns as column>
#if($column.query) <#if column.query>
#set($dictType=$column.dictType) <#if column.htmlType == "input" || column.htmlType == "textarea">
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
#set($parentheseIndex=$column.columnComment.indexOf("")) <el-input v-model="queryParams.${column.javaField}" placeholder="请输入${column.columnLabel}" clearable @keyup.enter="handleQuery" />
#if($parentheseIndex != -1)
#set($comment=$column.columnComment.substring(0, $parentheseIndex))
#else
#set($comment=$column.columnComment)
#end
#if($column.htmlType == "input" || $column.htmlType == "textarea")
<el-form-item label="${comment}" prop="${column.javaField}">
<el-input v-model="queryParams.${column.javaField}" placeholder="请输入${comment}" clearable @keyup.enter="handleQuery" />
</el-form-item> </el-form-item>
#elseif($column.htmlType == "inputNumber") <#elseif column.htmlType == "inputNumber">
<el-form-item label="${comment}" prop="${column.javaField}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<el-input-number v-model="queryParams.${column.javaField}" controls-position="right" /> <el-input-number v-model="queryParams.${column.javaField}" controls-position="right" />
</el-form-item> </el-form-item>
#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && "" != $dictType) <#elseif (column.htmlType == "select" || column.htmlType == "radio") && column.dictType?has_content>
<el-form-item label="${comment}" prop="${column.javaField}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable > <el-select v-model="queryParams.${column.javaField}" placeholder="请选择${column.columnLabel}" clearable >
<el-option v-for="dict in ${dictType}" :key="dict.value" :label="dict.label" :value="dict.value"/> <el-option v-for="dict in ${column.dictType}" :key="dict.value" :label="dict.label" :value="dict.value"/>
</el-select> </el-select>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "switch" && "" != $dictType) <#elseif column.htmlType == "switch" && column.dictType?has_content>
<el-form-item label="${comment}" prop="${column.javaField}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable > <el-select v-model="queryParams.${column.javaField}" placeholder="请选择${column.columnLabel}" clearable >
<el-option v-for="dict in ${dictType}" :key="dict.value" :label="dict.label" :value="dict.value"/> <el-option v-for="dict in ${column.dictType}" :key="dict.value" :label="dict.label" :value="dict.value"/>
</el-select> </el-select>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "switch") <#elseif column.htmlType == "switch">
<el-form-item label="${comment}" prop="${column.javaField}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable > <el-select v-model="queryParams.${column.javaField}" placeholder="请选择${column.columnLabel}" clearable >
#if($column.javaType == "Boolean") <#if column.javaType == "Boolean">
<el-option label="是" :value="true" /> <el-option label="是" :value="true" />
<el-option label="否" :value="false" /> <el-option label="否" :value="false" />
#elseif($column.javaType == "Integer" || $column.javaType == "Long") <#elseif column.javaType == "Integer" || column.javaType == "Long">
<el-option label="开启" :value="0" /> <el-option label="开启" :value="0" />
<el-option label="关闭" :value="1" /> <el-option label="关闭" :value="1" />
#else <#else>
<el-option label="开启" value="0" /> <el-option label="开启" value="0" />
<el-option label="关闭" value="1" /> <el-option label="关闭" value="1" />
#end </#if>
</el-select> </el-select>
</el-form-item> </el-form-item>
#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && $dictType) <#elseif (column.htmlType == "select" || column.htmlType == "radio") && column.dictType?has_content>
<el-form-item label="${comment}" prop="${column.javaField}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable > <el-select v-model="queryParams.${column.javaField}" placeholder="请选择${column.columnLabel}" clearable >
<el-option label="请选择字典生成" value="" /> <el-option label="请选择字典生成" value="" />
</el-select> </el-select>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "datetime" && $column.queryType != "BETWEEN") <#elseif column.htmlType == "datetime" && column.queryType != "BETWEEN">
<el-form-item label="${comment}" prop="${column.javaField}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<el-date-picker clearable <el-date-picker clearable
v-model="queryParams.${column.javaField}" v-model="queryParams.${column.javaField}"
type="date" type="date"
value-format="YYYY-MM-DD" value-format="YYYY-MM-DD"
placeholder="请选择${comment}" placeholder="请选择${column.columnLabel}"
/> />
</el-form-item> </el-form-item>
#elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN") <#elseif column.htmlType == "datetime" && column.queryType == "BETWEEN">
<el-form-item label="${comment}" style="width: 308px"> <el-form-item label="${column.columnLabel}" style="width: 308px">
<el-date-picker <el-date-picker
v-model="dateRange${AttrName}" v-model="dateRange${column.capJavaField}"
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
type="daterange" type="daterange"
range-separator="-" range-separator="-"
@ -80,9 +72,9 @@
:default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]" :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]"
/> />
</el-form-item> </el-form-item>
#end </#if>
#end </#if>
#end </#list>
<el-form-item> <el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button> <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button> <el-button icon="Refresh" @click="resetQuery">重置</el-button>
@ -101,9 +93,9 @@
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['${moduleName}:${businessName}:add']">新增</el-button> <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['${moduleName}:${businessName}:add']">新增</el-button>
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['${moduleName}:${businessName}:edit']">修改</el-button> <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['${moduleName}:${businessName}:edit']">修改</el-button>
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['${moduleName}:${businessName}:remove']">删除</el-button> <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['${moduleName}:${businessName}:remove']">删除</el-button>
#if($enableExport) <#if enableExport>
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['${moduleName}:${businessName}:export']">导出</el-button> <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['${moduleName}:${businessName}:export']">导出</el-button>
#end </#if>
<right-toolbar v-model:show-search="showSearch" :search="false" @query-table="getList"></right-toolbar> <right-toolbar v-model:show-search="showSearch" :search="false" @query-table="getList"></right-toolbar>
</div> </div>
</div> </div>
@ -111,112 +103,105 @@
<el-table v-loading="loading" border class="data-table" :data="${businessName}List" @selection-change="handleSelectionChange"> <el-table v-loading="loading" border class="data-table" :data="${businessName}List" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
#foreach($column in $columns) <#list columns as column>
#set($javaField=$column.javaField) <#if column.pk && column.list>
#set($parentheseIndex=$column.columnComment.indexOf("")) <el-table-column label="${column.columnLabel}" align="center" prop="${column.javaField}" />
#if($parentheseIndex != -1) <#elseif enableStatus && statusField == column.javaField>
#set($comment=$column.columnComment.substring(0, $parentheseIndex)) <el-table-column label="${column.columnLabel}" align="center" prop="${column.javaField}">
#else
#set($comment=$column.columnComment)
#end
#if($column.pk)
<el-table-column label="${comment}" align="center" prop="${javaField}" v-if="${column.list}" />
#elseif($enableStatus && $statusField == $javaField)
<el-table-column label="${comment}" align="center" prop="${javaField}">
<template #default="scope"> <template #default="scope">
<el-switch <el-switch
v-model="scope.row.${javaField}" v-model="scope.row.${column.javaField}"
:active-value="${statusField}ActiveValue" :active-value="${statusField}ActiveValue"
:inactive-value="${statusField}InactiveValue" :inactive-value="${statusField}InactiveValue"
@change="handleStatusChange(scope.row)" @change="handleStatusChange(scope.row)"
/> />
</template> </template>
</el-table-column> </el-table-column>
#elseif($enableSort && $sortField == $javaField) <#elseif enableSort && sortField == column.javaField>
<el-table-column label="${comment}" align="center" prop="${javaField}" width="160"> <el-table-column label="${column.columnLabel}" align="center" prop="${column.javaField}" width="160">
<template #default="scope"> <template #default="scope">
#if($column.javaType == "LocalDateTime") <#if column.javaType == "LocalDateTime">
<el-date-picker <el-date-picker
v-model="scope.row.${javaField}" v-model="scope.row.${column.javaField}"
type="datetime" type="datetime"
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
placeholder="选择${comment}" placeholder="选择${column.columnLabel}"
@change="handleSortChange(scope.row)" @change="handleSortChange(scope.row)"
/> />
#else <#else>
<el-input-number v-model="scope.row.${javaField}" controls-position="right" :min="0" @change="handleSortChange(scope.row)" /> <el-input-number v-model="scope.row.${column.javaField}" controls-position="right" :min="0" @change="handleSortChange(scope.row)" />
#end </#if>
</template> </template>
</el-table-column> </el-table-column>
#elseif($column.list && $column.htmlType == "switch") <#elseif column.list && column.htmlType == "switch">
<el-table-column label="${comment}" align="center" prop="${javaField}" width="120"> <el-table-column label="${column.columnLabel}" align="center" prop="${column.javaField}" width="120">
<template #default="scope"> <template #default="scope">
<el-switch <el-switch
v-model="scope.row.${javaField}" v-model="scope.row.${column.javaField}"
#if($column.javaType == "Boolean") <#if column.javaType == "Boolean">
:active-value="true" :active-value="true"
:inactive-value="false" :inactive-value="false"
#elseif($column.javaType == "Integer" || $column.javaType == "Long") <#elseif column.javaType == "Integer" || column.javaType == "Long">
:active-value="0" :active-value="0"
:inactive-value="1" :inactive-value="1"
#else <#else>
active-value="0" active-value="0"
inactive-value="1" inactive-value="1"
#end </#if>
disabled disabled
/> />
</template> </template>
</el-table-column> </el-table-column>
#elseif($column.list && $column.htmlType == "datetime") <#elseif column.list && column.htmlType == "datetime">
<el-table-column label="${comment}" align="center" prop="${javaField}" width="180"> <el-table-column label="${column.columnLabel}" align="center" prop="${column.javaField}" width="180">
<template #default="scope"> <template #default="scope">
<span>{{ parseTime(scope.row.${javaField}, '{y}-{m}-{d}') }}</span> <span>{{ parseTime(scope.row.${column.javaField}, '{y}-{m}-{d}') }}</span>
</template> </template>
</el-table-column> </el-table-column>
#elseif($column.list && $column.htmlType == "imageUpload") <#elseif column.list && column.htmlType == "imageUpload">
<el-table-column label="${comment}" align="center" prop="${javaField}Url" width="100"> <el-table-column label="${column.columnLabel}" align="center" prop="${column.javaField}Url" width="100">
<template #default="scope"> <template #default="scope">
<image-preview :src="scope.row.${javaField}Url" :width="50" :height="50"/> <image-preview :src="scope.row.${column.javaField}Url" :width="50" :height="50"/>
</template> </template>
</el-table-column> </el-table-column>
#elseif($column.list && $column.dictColumn) <#elseif column.list && column.dictColumn>
<el-table-column label="${comment}" align="center" prop="${javaField}"> <el-table-column label="${column.columnLabel}" align="center" prop="${column.javaField}">
<template #default="scope"> <template #default="scope">
#if($column.htmlType == "checkbox") <#if column.htmlType == "checkbox">
<dict-tag :options="${column.dictType}" :value="scope.row.${javaField} ? scope.row.${javaField}.split(',') : []"/> <dict-tag :options="${column.dictType}" :value="scope.row.${column.javaField} ? scope.row.${column.javaField}.split(',') : []"/>
#else <#else>
<dict-tag :options="${column.dictType}" :value="scope.row.${javaField}"/> <dict-tag :options="${column.dictType}" :value="scope.row.${column.javaField}"/>
#end </#if>
</template> </template>
</el-table-column> </el-table-column>
#elseif($column.list && "" != $javaField) <#elseif column.list && "" != column.javaField>
<el-table-column label="${comment}" align="center" prop="${javaField}" /> <el-table-column label="${column.columnLabel}" align="center" prop="${column.javaField}" />
#end </#if>
#end </#list>
#if($enableStatus && !$statusColumn.list) <#if enableStatus && !statusColumn.list>
<el-table-column label="${statusColumn.columnComment}" align="center" prop="${statusField}"> <el-table-column label="${statusColumn.columnComment}" align="center" prop="${statusField}">
<template #default="scope"> <template #default="scope">
<el-switch <el-switch
v-model="scope.row.${statusField}" v-model="scope.row.${statusField}"
#if($statusColumn.javaType == "Boolean") <#if statusColumn.javaType == "Boolean">
:active-value="true" :active-value="true"
:inactive-value="false" :inactive-value="false"
#elseif($statusColumn.javaType == "Integer" || $statusColumn.javaType == "Long") <#elseif statusColumn.javaType == "Integer" || statusColumn.javaType == "Long">
:active-value="0" :active-value="0"
:inactive-value="1" :inactive-value="1"
#else <#else>
active-value="0" active-value="0"
inactive-value="1" inactive-value="1"
#end </#if>
@change="handleStatusChange(scope.row)" @change="handleStatusChange(scope.row)"
/> />
</template> </template>
</el-table-column> </el-table-column>
#end </#if>
#if($enableSort && !$sortColumn.list) <#if enableSort && !sortColumn.list>
<el-table-column label="${sortColumn.columnComment}" align="center" prop="${sortField}" width="160"> <el-table-column label="${sortColumn.columnComment}" align="center" prop="${sortField}" width="160">
<template #default="scope"> <template #default="scope">
#if($sortColumn.javaType == "LocalDateTime") <#if sortColumn.javaType == "LocalDateTime">
<el-date-picker <el-date-picker
v-model="scope.row.${sortField}" v-model="scope.row.${sortField}"
type="datetime" type="datetime"
@ -224,12 +209,12 @@
placeholder="选择${sortColumn.columnComment}" placeholder="选择${sortColumn.columnComment}"
@change="handleSortChange(scope.row)" @change="handleSortChange(scope.row)"
/> />
#else <#else>
<el-input-number v-model="scope.row.${sortField}" controls-position="right" :min="0" @change="handleSortChange(scope.row)" /> <el-input-number v-model="scope.row.${sortField}" controls-position="right" :min="0" @change="handleSortChange(scope.row)" />
#end </#if>
</template> </template>
</el-table-column> </el-table-column>
#end </#if>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope"> <template #default="scope">
<el-tooltip content="修改" placement="top"> <el-tooltip content="修改" placement="top">
@ -247,126 +232,117 @@
<!-- 添加或修改${functionName}对话框 --> <!-- 添加或修改${functionName}对话框 -->
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body> <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
<el-form ref="${businessName}FormRef" :model="form" :rules="rules" label-width="80px"> <el-form ref="${businessName}FormRef" :model="form" :rules="rules" label-width="80px">
#foreach($column in $columns) <#list columns as column>
#set($field=$column.javaField) <#if (column.insert || column.edit) && !column.pk>`n<#if column.htmlType == "input">
#if(($column.insert || $column.edit) && !$column.pk) <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
#set($parentheseIndex=$column.columnComment.indexOf("")) <el-input v-model="form.${column.javaField}" placeholder="请输入${column.columnLabel}" />
#if($parentheseIndex != -1)
#set($comment=$column.columnComment.substring(0, $parentheseIndex))
#else
#set($comment=$column.columnComment)
#end
#set($dictType=$column.dictType)
#if($column.htmlType == "input")
<el-form-item label="${comment}" prop="${field}">
<el-input v-model="form.${field}" placeholder="请输入${comment}" />
</el-form-item> </el-form-item>
#elseif($column.htmlType == "inputNumber") <#elseif column.htmlType == "inputNumber">
<el-form-item label="${comment}" prop="${field}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<el-input-number v-model="form.${field}" controls-position="right" /> <el-input-number v-model="form.${column.javaField}" controls-position="right" />
</el-form-item> </el-form-item>
#elseif($column.htmlType == "imageUpload") <#elseif column.htmlType == "imageUpload">
<el-form-item label="${comment}" prop="${field}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<image-upload v-model="form.${field}"/> <image-upload v-model="form.${column.javaField}"/>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "fileUpload") <#elseif column.htmlType == "fileUpload">
<el-form-item label="${comment}" prop="${field}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<file-upload v-model="form.${field}"/> <file-upload v-model="form.${column.javaField}"/>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "editor") <#elseif column.htmlType == "editor">
<el-form-item label="${comment}"> <el-form-item label="${column.columnLabel}">
<editor v-model="form.${field}" :min-height="192"/> <editor v-model="form.${column.javaField}" :min-height="192"/>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "select" && "" != $dictType) <#elseif column.htmlType == "select" && column.dictType?has_content>
<el-form-item label="${comment}" prop="${field}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<el-select v-model="form.${field}" placeholder="请选择${comment}"> <el-select v-model="form.${column.javaField}" placeholder="请选择${column.columnLabel}">
<el-option <el-option
v-for="dict in ${dictType}" v-for="dict in ${column.dictType}"
:key="dict.value" :key="dict.value"
:label="dict.label" :label="dict.label"
#if($column.javaType == "Integer" || $column.javaType == "Long") <#if column.javaType == "Integer" || column.javaType == "Long">
:value="parseInt(dict.value)" :value="parseInt(dict.value)"
#else <#else>
:value="dict.value" :value="dict.value"
#end </#if>
></el-option> ></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "select" && $dictType) <#elseif column.htmlType == "select" && column.dictType?has_content>
<el-form-item label="${comment}" prop="${field}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<el-select v-model="form.${field}" placeholder="请选择${comment}"> <el-select v-model="form.${column.javaField}" placeholder="请选择${column.columnLabel}">
<el-option label="请选择字典生成" value="" /> <el-option label="请选择字典生成" value="" />
</el-select> </el-select>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "checkbox" && "" != $dictType) <#elseif column.htmlType == "checkbox" && column.dictType?has_content>
<el-form-item label="${comment}" prop="${field}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<el-checkbox-group v-model="form.${field}"> <el-checkbox-group v-model="form.${column.javaField}">
<el-checkbox <el-checkbox
v-for="dict in ${dictType}" v-for="dict in ${column.dictType}"
:key="dict.value" :key="dict.value"
:label="dict.value"> :label="dict.value">
{{dict.label}} {{dict.label}}
</el-checkbox> </el-checkbox>
</el-checkbox-group> </el-checkbox-group>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "checkbox" && $dictType) <#elseif column.htmlType == "checkbox" && column.dictType?has_content>
<el-form-item label="${comment}" prop="${field}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<el-checkbox-group v-model="form.${field}"> <el-checkbox-group v-model="form.${column.javaField}">
<el-checkbox>请选择字典生成</el-checkbox> <el-checkbox>请选择字典生成</el-checkbox>
</el-checkbox-group> </el-checkbox-group>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "radio" && "" != $dictType) <#elseif column.htmlType == "radio" && column.dictType?has_content>
<el-form-item label="${comment}" prop="${field}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<el-radio-group v-model="form.${field}"> <el-radio-group v-model="form.${column.javaField}">
<el-radio <el-radio
v-for="dict in ${dictType}" v-for="dict in ${column.dictType}"
:key="dict.value" :key="dict.value"
#if($column.javaType == "Integer" || $column.javaType == "Long") <#if column.javaType == "Integer" || column.javaType == "Long">
:value="parseInt(dict.value)" :value="parseInt(dict.value)"
#else <#else>
:value="dict.value" :value="dict.value"
#end </#if>
>{{dict.label}}</el-radio> >{{dict.label}}</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "radio" && $dictType) <#elseif column.htmlType == "radio" && column.dictType?has_content>
<el-form-item label="${comment}" prop="${field}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<el-radio-group v-model="form.${field}"> <el-radio-group v-model="form.${column.javaField}">
<el-radio value="1">请选择字典生成</el-radio> <el-radio value="1">请选择字典生成</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "switch") <#elseif column.htmlType == "switch">
<el-form-item label="${comment}" prop="${field}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<el-switch <el-switch
v-model="form.${field}" v-model="form.${column.javaField}"
#if($column.javaType == "Boolean") <#if column.javaType == "Boolean">
:active-value="true" :active-value="true"
:inactive-value="false" :inactive-value="false"
#elseif($column.javaType == "Integer" || $column.javaType == "Long") <#elseif column.javaType == "Integer" || column.javaType == "Long">
:active-value="0" :active-value="0"
:inactive-value="1" :inactive-value="1"
#else <#else>
active-value="0" active-value="0"
inactive-value="1" inactive-value="1"
#end </#if>
/> />
</el-form-item> </el-form-item>
#elseif($column.htmlType == "datetime") <#elseif column.htmlType == "datetime">
<el-form-item label="${comment}" prop="${field}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<el-date-picker clearable <el-date-picker clearable
v-model="form.${field}" v-model="form.${column.javaField}"
type="datetime" type="datetime"
value-format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"
placeholder="请选择${comment}"> placeholder="请选择${column.columnLabel}">
</el-date-picker> </el-date-picker>
</el-form-item> </el-form-item>
#elseif($column.htmlType == "textarea") <#elseif column.htmlType == "textarea">
<el-form-item label="${comment}" prop="${field}"> <el-form-item label="${column.columnLabel}" prop="${column.javaField}">
<el-input v-model="form.${field}" type="textarea" placeholder="请输入内容" /> <el-input v-model="form.${column.javaField}" type="textarea" placeholder="请输入内容" />
</el-form-item> </el-form-item>
#end </#if>
#end </#if>
#end </#list>
</el-form> </el-form>
<template #footer> <template #footer>
<div class="dialog-footer"> <div class="dialog-footer">
@ -378,121 +354,107 @@
</div> </div>
</template> </template>
#set($needAddDateRange = false)
#foreach ($column in $columns)
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
#set($needAddDateRange = true)
#end
#end
<script setup name="${BusinessName}" lang="ts"> <script setup name="${BusinessName}" lang="ts">
import { import {
add${BusinessName}, add${BusinessName},
#if($enableStatus) <#if enableStatus>
change${BusinessName}Status, change${BusinessName}Status,
#end </#if>
del${BusinessName}, del${BusinessName},
get${BusinessName}, get${BusinessName},
list${BusinessName}, list${BusinessName},
#if($enableSort) <#if enableSort>
update${BusinessName}Sort, update${BusinessName}Sort,
#end </#if>
update${BusinessName} update${BusinessName}
} from '@/api/${moduleName}/${businessName}'; } from '@/api/${moduleName}/${businessName}';
import { ${BusinessName}Form, ${BusinessName}Query, ${BusinessName}VO } from '@/api/${moduleName}/${businessName}/types'; import { ${BusinessName}Form, ${BusinessName}Query, ${BusinessName}VO } from '@/api/${moduleName}/${businessName}/types';
import { useLoading } from '@/hooks/async/useLoading'; import { useLoading } from '@/hooks/async/useLoading';
import { useFormDialog } from '@/hooks/dialog/useFormDialog'; import { useFormDialog } from '@/hooks/dialog/useFormDialog';
#if($needAddDateRange) <#if needAddDateRange>
import { useDateRangeQuery } from '@/hooks/form/useDateRangeQuery'; import { useDateRangeQuery } from '@/hooks/form/useDateRangeQuery';
#end </#if>
import { useSearchReset } from '@/hooks/form/useSearchReset'; import { useSearchReset } from '@/hooks/form/useSearchReset';
import { useSearchToggle } from '@/hooks/form/useSearchToggle'; import { useSearchToggle } from '@/hooks/form/useSearchToggle';
import { useTableSelection } from '@/hooks/table/useTableSelection'; import { useTableSelection } from '@/hooks/table/useTableSelection';
#if(${dicts} != '') <#if needDict>
import { useDict } from '@/utils/dict'; import { useDict } from '@/utils/dict';
#end </#if>
import modal from '@/plugins/modal'; import modal from '@/plugins/modal';
#if($enableExport) <#if enableExport>
import { download as requestDownload } from '@/utils/request'; import { download as requestDownload } from '@/utils/request';
#end </#if>
#if(${dicts} != '') <#if needDict>
#set($dictsNoSymbol=$dicts.replace("'", ""))
const { ${dictsNoSymbol} } = toRefs<any>(useDict(${dicts})); const { ${dictsNoSymbol} } = toRefs<any>(useDict(${dicts}));
#end </#if>
#if($enableStatus) <#if enableStatus>
const ${statusField}ActiveValue = #if($statusColumn.javaType == "Boolean")true#elseif($statusColumn.javaType == "Integer" || $statusColumn.javaType == "Long")0#else'0'#end; const ${statusField}ActiveValue = <#if statusColumn.javaType == "Boolean">true<#elseif statusColumn.javaType == "Integer" || statusColumn.javaType == "Long">0<#else>'0'</#if>;
const ${statusField}InactiveValue = #if($statusColumn.javaType == "Boolean")false#elseif($statusColumn.javaType == "Integer" || $statusColumn.javaType == "Long")1#else'1'#end; const ${statusField}InactiveValue = <#if statusColumn.javaType == "Boolean">false<#elseif statusColumn.javaType == "Integer" || statusColumn.javaType == "Long">1<#else>'1'</#if>;
#end </#if>
const ${businessName}List = ref<${BusinessName}VO[]>([]); const ${businessName}List = ref<${BusinessName}VO[]>([]);
const buttonLoading = ref(false); const buttonLoading = ref(false);
const { loading, withLoading } = useLoading(true); const { loading, withLoading } = useLoading(true);
const { showSearch } = useSearchToggle(); const { showSearch } = useSearchToggle();
const total = ref(0); const total = ref(0);
#foreach ($column in $columns) <#list columns as column>
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN") <#if column.htmlType == "datetime" && column.queryType == "BETWEEN">
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
const { const {
dateRange: dateRange${AttrName}, dateRange: dateRange${column.capJavaField},
applyDateRange: apply${AttrName}DateRange, applyDateRange: apply${column.capJavaField}DateRange,
resetDateRange: reset${AttrName}DateRange resetDateRange: reset${column.capJavaField}DateRange
} = useDateRangeQuery('${AttrName}'); } = useDateRangeQuery('${column.capJavaField}');
#end </#if>
#end </#list>
const queryFormRef = ref<ElFormInstance>(); const queryFormRef = ref<ElFormInstance>();
const ${businessName}FormRef = ref<ElFormInstance>(); const ${businessName}FormRef = ref<ElFormInstance>();
const initFormData: ${BusinessName}Form = { const initFormData: ${BusinessName}Form = {
#foreach ($column in $columns) <#list columns as column>
#if($column.insert || $column.edit) <#if column.insert || column.edit>
#if($column.htmlType == "checkbox") <#if column.htmlType == "checkbox">
$column.javaField: []#if($foreach.count != $columns.size()),#end ${column.javaField}: [],
#else <#else>
$column.javaField: undefined#if($foreach.count != $columns.size()),#end ${column.javaField}: undefined,
#end </#if>
#end </#if>
#end </#list>
} }
const data = reactive<PageData<${BusinessName}Form, ${BusinessName}Query>>({ const data = reactive<PageData<${BusinessName}Form, ${BusinessName}Query>>({
form: { ...initFormData }, form: { ...initFormData },
queryParams: { queryParams: {
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 10,
#foreach ($column in $columns) <#list columns as column>
#if($column.query) <#if column.query>
#if($column.htmlType != "datetime" || $column.queryType != "BETWEEN") <#if column.htmlType != "datetime" || column.queryType != "BETWEEN">
$column.javaField: undefined, ${column.javaField}: undefined,
#end </#if>
#end </#if>
#end </#list>
params: { params: {
#foreach ($column in $columns) <#list columns as column>
#if($column.query) <#if column.query>
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN") <#if column.htmlType == "datetime" && column.queryType == "BETWEEN">
$column.javaField: undefined#if($foreach.count != $columns.size()),#end ${column.javaField}: undefined,
#end </#if>
#end </#if>
#end </#list>
} }
}, },
rules: { rules: {
#foreach ($column in $columns) <#list columns as column>
#if($column.insert || $column.edit) <#if column.insert || column.edit>
#if($column.required) <#if column.required>
#set($parentheseIndex=$column.columnComment.indexOf("")) ${column.javaField}: [
#if($parentheseIndex != -1) { required: true, message: "${column.columnLabel}不能为空", trigger: <#if column.htmlType == "select" || column.htmlType == "radio" || column.htmlType == "switch" || column.htmlType == "inputNumber">"change"<#else>"blur"</#if> }
#set($comment=$column.columnComment.substring(0, $parentheseIndex)) ],
#else </#if>
#set($comment=$column.columnComment) </#if>
#end </#list>
$column.javaField: [
{ required: true, message: "$comment不能为空", trigger: #if($column.htmlType == "select" || $column.htmlType == "radio" || $column.htmlType == "switch" || $column.htmlType == "inputNumber")"change"#else"blur"#end }
]#if($foreach.count != $columns.size()),#end
#end
#end
#end
} }
}); });
@ -507,18 +469,17 @@ const { dialog, resetForm: reset, openDialog, showDialog, closeDialog } = useFor
/** 查询${functionName}列表 */ /** 查询${functionName}列表 */
const getList = async () => { const getList = async () => {
await withLoading(async () => { await withLoading(async () => {
#if($needAddDateRange) <#if needAddDateRange>
let params = queryParams.value; let params = queryParams.value;
#foreach ($column in $columns) <#list columns as column>
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN") <#if column.htmlType == "datetime" && column.queryType == "BETWEEN">
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) params = apply${column.capJavaField}DateRange(params);
params = apply${AttrName}DateRange(params); </#if>
#end </#list>
#end
const res = await list${BusinessName}(params); const res = await list${BusinessName}(params);
#else <#else>
const res = await list${BusinessName}(queryParams.value); const res = await list${BusinessName}(queryParams.value);
#end </#if>
${businessName}List.value = res.data?.rows; ${businessName}List.value = res.data?.rows;
total.value = res.data?.total; total.value = res.data?.total;
}); });
@ -543,12 +504,11 @@ const { resetQuery } = useSearchReset({
pageSizeKey: 'pageSize', pageSizeKey: 'pageSize',
initialPageSize: 10, initialPageSize: 10,
resetExtras: () => { resetExtras: () => {
#foreach ($column in $columns) <#list columns as column>
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN") <#if column.htmlType == "datetime" && column.queryType == "BETWEEN">
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) reset${column.capJavaField}DateRange();
reset${AttrName}DateRange(); </#if>
#end </#list>
#end
}, },
afterReset: () => { afterReset: () => {
handleQuery(); handleQuery();
@ -566,11 +526,11 @@ const handleUpdate = async (row?: Partial<${BusinessName}VO>) => {
const _${pkColumn.javaField} = row?.${pkColumn.javaField} || ids.value[0]; const _${pkColumn.javaField} = row?.${pkColumn.javaField} || ids.value[0];
const res = await get${BusinessName}(_${pkColumn.javaField}); const res = await get${BusinessName}(_${pkColumn.javaField});
Object.assign(form.value, res.data); Object.assign(form.value, res.data);
#foreach ($column in $columns) <#list columns as column>
#if($column.htmlType == "checkbox") <#if column.htmlType == "checkbox">
form.value.$column.javaField = form.value.${column.javaField}.split(","); form.value.${column.javaField} = form.value.${column.javaField}.split(",");
#end </#if>
#end </#list>
showDialog('修改${functionName}'); showDialog('修改${functionName}');
}; };
@ -579,11 +539,11 @@ const submitForm = () => {
${businessName}FormRef.value?.validate(async (valid: boolean) => { ${businessName}FormRef.value?.validate(async (valid: boolean) => {
if (valid) { if (valid) {
buttonLoading.value = true; buttonLoading.value = true;
#foreach ($column in $columns) <#list columns as column>
#if($column.htmlType == "checkbox") <#if column.htmlType == "checkbox">
form.value.$column.javaField = form.value.${column.javaField}.join(","); form.value.${column.javaField} = form.value.${column.javaField}.join(",");
#end </#if>
#end </#list>
if (form.value.${pkColumn.javaField}) { if (form.value.${pkColumn.javaField}) {
await update${BusinessName}(form.value).finally(() => (buttonLoading.value = false)); await update${BusinessName}(form.value).finally(() => (buttonLoading.value = false));
} else { } else {
@ -606,19 +566,19 @@ const handleDelete = async (row?: Partial<${BusinessName}VO>) => {
}; };
/** 导出按钮操作 */ /** 导出按钮操作 */
#if($enableExport) <#if enableExport>
const handleExport = () => { const handleExport = () => {
requestDownload( requestDownload(
'${moduleName}/${businessName}/export', '${moduleName}/${businessName}/export',
{ {
...queryParams.value ...queryParams.value
}, },
`${businessName}_#[[${new Date().getTime()}]]#.xlsx` `${businessName}_${r'${new Date().getTime()}'}.xlsx`
); );
}; };
#end </#if>
#if($enableStatus) <#if enableStatus>
/** 状态修改 */ /** 状态修改 */
const handleStatusChange = async (row: Partial<${BusinessName}VO>) => { const handleStatusChange = async (row: Partial<${BusinessName}VO>) => {
const text = row.${statusField} === ${statusField}ActiveValue ? '启用' : '停用'; const text = row.${statusField} === ${statusField}ActiveValue ? '启用' : '停用';
@ -630,9 +590,9 @@ const handleStatusChange = async (row: Partial<${BusinessName}VO>) => {
row.${statusField} = row.${statusField} === ${statusField}ActiveValue ? ${statusField}InactiveValue : ${statusField}ActiveValue; row.${statusField} = row.${statusField} === ${statusField}ActiveValue ? ${statusField}InactiveValue : ${statusField}ActiveValue;
} }
}; };
#end </#if>
#if($enableSort) <#if enableSort>
/** 排序调整 */ /** 排序调整 */
const handleSortChange = async (row: Partial<${BusinessName}VO>) => { const handleSortChange = async (row: Partial<${BusinessName}VO>) => {
try { try {
@ -642,9 +602,10 @@ const handleSortChange = async (row: Partial<${BusinessName}VO>) => {
await getList(); await getList();
} }
}; };
#end </#if>
onMounted(() => { onMounted(() => {
getList(); getList();
}); });
</script> </script>

50
gen/types.ts.ftl Normal file
View File

@ -0,0 +1,50 @@
import type { BaseEntity<#if !table.tree>, PageQuery</#if> } from '@/api/types';
export interface ${BusinessName}VO {
<#list columns as column>
<#if column.list>
/**
* ${column.columnComment}
*/
${column.javaField}: ${column.tsType};
<#if column.htmlType == "imageUpload">
/**
* ${column.columnComment}Url
*/
${column.javaField}Url: string;
</#if>
</#if>
</#list>
<#if table.tree>
/**
* 子对象
*/
children: ${BusinessName}VO[];
</#if>
}
export interface ${BusinessName}Form extends BaseEntity {
<#list columns as column>
<#if column.insert || column.edit>
/**
* ${column.columnComment}
*/
${column.javaField}?: ${column.tsType};
</#if>
</#list>
}
export interface ${BusinessName}Query<#if !table.tree> extends PageQuery</#if> {
<#list columns as column>
<#if column.query>
/**
* ${column.columnComment}
*/
${column.javaField}?: ${column.tsType};
</#if>
</#list>
/**
* 日期范围参数
*/
params?: any;
}

View File

@ -1,61 +0,0 @@
export interface ${BusinessName}VO {
#foreach ($column in $columns)
#if($column.list)
/**
* $column.columnComment
*/
$column.javaField:#if($column.javaField.indexOf("id") != -1 || $column.javaField.indexOf("Id") != -1) string | number;
#elseif($column.javaType == 'Long' || $column.javaType == 'Integer' || $column.javaType == 'Double' || $column.javaType == 'Float' || $column.javaType == 'BigDecimal') number;
#elseif($column.javaType == 'Boolean') boolean;
#else string;
#end
#if($column.htmlType == "imageUpload")
/**
* ${column.columnComment}Url
*/
${column.javaField}Url: string;
#end
#end
#end
#if ($table.tree)
/**
* 子对象
*/
children: ${BusinessName}VO[];
#end
}
export interface ${BusinessName}Form extends BaseEntity {
#foreach ($column in $columns)
#if($column.insert || $column.edit)
/**
* $column.columnComment
*/
$column.javaField?:#if($column.javaField.indexOf("id") != -1 || $column.javaField.indexOf("Id") != -1) string | number;
#elseif($column.javaType == 'Long' || $column.javaType == 'Integer' || $column.javaType == 'Double' || $column.javaType == 'Float' || $column.javaType == 'BigDecimal') number;
#elseif($column.javaType == 'Boolean') boolean;
#else string;
#end
#end
#end
}
export interface ${BusinessName}Query #if(!${treeCode})extends PageQuery #end{
#foreach ($column in $columns)
#if($column.query)
/**
* $column.columnComment
*/
$column.javaField?:#if($column.javaField.indexOf("id") != -1 || $column.javaField.indexOf("Id") != -1) string | number;
#elseif($column.javaType == 'Long' || $column.javaType == 'Integer' || $column.javaType == 'Double' || $column.javaType == 'Float' || $column.javaType == 'BigDecimal') number;
#elseif($column.javaType == 'Boolean') boolean;
#else string;
#end
#end
#end
/**
* 日期范围参数
*/
params?: any;
}