1. 修改代码生成器普通表格为虚拟滚动

(cherry picked from commit da3487a54d)
This commit is contained in:
chenbowen
2025-08-27 09:42:53 +08:00
committed by chenbowen
parent c8d582c600
commit a53105088d
25 changed files with 1795 additions and 167 deletions

View File

@@ -1,59 +0,0 @@
package cn.iocoder.yudao.module.infra.api.stdnms;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.infra.api.stdnms.dto.StdNmsRespDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.Collection;
import java.util.List;
@FeignClient(name = "stdnms-api") // 可根据实际服务名调整
@Tag(name = "RPC 服务 - 数据命名与简写标准")
public interface StdNmsApi {
String PREFIX = "/api/stdnms";
@DeleteMapping(PREFIX + "/delete")
@Operation(summary = "删除数据命名与简写标准")
@Parameters({
@Parameter(name = "id", description = "主键ID", example = "1001", required = true)
})
CommonResult<Boolean> deleteStdNms(@RequestParam("id") Long id);
@DeleteMapping(PREFIX + "/delete-batch")
@Operation(summary = "批量删除数据命名与简写标准")
@Parameters({
@Parameter(name = "ids", description = "主键ID集合", example = "[1001,1002]", required = true)
})
CommonResult<Boolean> deleteStdNmsList(@RequestParam("ids") List<Long> ids);
@GetMapping(PREFIX + "/get")
@Operation(summary = "根据主键获取数据命名与简写标准")
@Parameters({
@Parameter(name = "id", description = "主键ID", example = "1001", required = true)
})
CommonResult<StdNmsRespDTO> getStdNms(@RequestParam("id") Long id);
@GetMapping(PREFIX + "/get-by-abbr")
@Operation(summary = "根据缩写获取数据命名与简写标准")
@Parameters({
@Parameter(name = "abbr", description = "简写/缩写", example = "devNm", required = true)
})
CommonResult<StdNmsRespDTO> getStdNmsByAbbr(@RequestParam("abbr") String abbr);
@GetMapping(PREFIX + "/list-by-abbrs")
@Operation(summary = "根据缩写列表查询数据命名与简写标准")
@Parameters({
@Parameter(name = "abbrs", description = "简写/缩写集合", example = "[devNm,devType]", required = true)
})
CommonResult<List<StdNmsRespDTO>> getStdNmsListByAbbrs(@RequestParam("abbrs") Collection<String> abbrs);
}

View File

@@ -1,26 +0,0 @@
package cn.iocoder.yudao.module.infra.api.stdnms.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Schema(description = "数据命名与简写标准响应 DTO")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class StdNmsRespDTO implements Serializable {
@Schema(description = "主键ID", example = "1001")
private Long id;
@Schema(description = "名称", example = "设备名称")
private String name;
@Schema(description = "简写/缩写", example = "devNm")
private String abbr;
// 可根据实际需求补充其他字段
}

View File

@@ -24,6 +24,7 @@ import ${jakartaPackage}.servlet.http.*;
import java.util.*;
import java.io.IOException;
import ${basePackage}.framework.common.pojo.vo.BatchDeleteReqVO;
import ${PageParamClassName};
import ${PageResultClassName};
import ${CommonResultClassName};
@@ -111,8 +112,8 @@ public class ${sceneEnum.prefixClass}${table.className}Controller extends Abstra
#if ($sceneEnum.scene == 1)
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:delete')")
#end
public CommonResult<Boolean> delete${simpleClassName}List(@RequestParam("ids") List<${primaryColumn.javaType}> ids) {
${classNameVar}Service.delete${simpleClassName}ListByIds(ids);
public CommonResult<Boolean> delete${simpleClassName}List(@RequestBody BatchDeleteReqVO req) {
${classNameVar}Service.delete${simpleClassName}ListByIds(req.getIds());
return success(true);
}
#end

View File

@@ -60,6 +60,14 @@ export const ${simpleClassName}Api = {
return await request.delete({ url: `${baseURL}/delete?id=` + id })
},
// 批量删除${table.classComment}
delete${simpleClassName}List: async (ids: IdType[]) => {
return await request.delete({
url: `${baseURL}/delete-list`,
data: { ids }
})
},
// 导出${table.classComment} Excel
export${simpleClassName}: async (params) => {
return await request.download({ url: `${baseURL}/export-excel`, params })

View File

@@ -101,6 +101,17 @@
>
<Icon icon="ep:download" class="mr-5px" /> 导出
</el-button>
#if ( $table.templateType != 12 && $table.templateType != 11 && $table.templateType != 2 )
<el-button
type="danger"
plain
@click="handleBatchDelete"
:disabled="selectRecords.length === 0"
v-hasPermi="['template:demo-virtualized-table:delete']"
>
<Icon icon="ep:delete" class="mr-5px" /> 批量删除({{ selectRecords.length }})
</el-button>
#end
## 特殊:树表专属逻辑
#if ( $table.templateType == 2 )
<el-button type="danger" plain @click="toggleExpandAll">
@@ -134,8 +145,8 @@
:default-expand-all="isExpandAll"
v-if="refreshTable"
>
#else
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
###else
## <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
#end
## 特殊:主子表专属逻辑
#if ( $table.templateType == 12 && $subTables && $subTables.size() > 0 )
@@ -156,6 +167,8 @@
</template>
</el-table-column>
#end
## 特殊表格依然使用 element table
#if ( $table.templateType == 12 || $table.templateType == 11 || $table.templateType == 2 )
#foreach($column in $columns)
#if ($column.listOperationResult)
#set ($dictType=$column.dictType)
@@ -205,12 +218,43 @@
</template>
</el-table-column>
</el-table>
#else
## 普通表格使用 Vxe table 支持大数据量渲染
<vxe-grid
ref="gridRef"
v-bind="gridOptions"
@checkbox-change="onCheckboxChange"
>
<template #action="{ row }">
<el-button
link
type="primary"
@click="openForm('update', row.id)"
v-hasPermi="['${permissionPrefix}:update']"
>
编辑
</el-button>
<el-button
link
type="danger"
@click="handleDelete(row.id)"
v-hasPermi="['${permissionPrefix}:delete']"
>
删除
</el-button>
#if($isFileUpload && $isFileUpload == true)
<el-button link @click="openBusinessFile(row.id)">附件</el-button>
#end
</template>
</vxe-grid>
#end
<!-- 分页 -->
<Pagination
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
:page-sizes="[10, 20, 50, 100, 200, 500, 700,5000, 10000]"
/>
</ContentWrap>
@@ -242,6 +286,7 @@ import { dateFormatter } from '@/utils/formatTime'
#if ( $table.templateType == 2 )
import { handleTree } from '@/utils/tree'
#end
import { useVxeGrid } from '@/hooks/web/useVxeGrid'
import download from '@/utils/download'
import { ${simpleClassName}Api, ${simpleClassName}VO } from '@/api/${table.moduleName}/${table.businessName}'
import ${simpleClassName}Form from './${simpleClassName}Form.vue'
@@ -274,6 +319,8 @@ const list = ref<${simpleClassName}VO[]>([]) // 列表的数据
#if ( $table.templateType != 2 )
const total = ref(0) // 列表的总页数
#end
const gridRef = ref() // vxe-grid 的引用
const selectRecords = ref<${simpleClassName}VO[]>([]) // 选中的记录
const queryParams = reactive({
## 特殊:树表专属逻辑(树不需要分页接口)
#if ( $table.templateType != 2 )
@@ -294,6 +341,69 @@ const queryParams = reactive({
const queryFormRef = ref() // 搜索的表单
const exportLoading = ref(false) // 导出的加载中
#if ( $table.templateType != 12 && $table.templateType != 11 && $table.templateType != 2 )
/** vxe-grid 复选框事件 */
const onCheckboxChange = ({ records }) => {
selectRecords.value = records
}
// vxe-grid 配置 (兼容 VxeTable 4.6.25)
const { gridOptions } = useVxeGrid({
loading,
data: list,
columns: [
{
type: 'checkbox',
width: 50,
align: 'center',
fixed: 'left' // 固定在左侧
},
#foreach($column in $columns)
#if ($column.listOperationResult)
#set ($dictType=$column.dictType)
#set ($javaField = $column.javaField)
#set ($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
#set ($comment=$column.columnComment)
#if ($column.javaType == "LocalDateTime")## 时间类型
{
field: '${javaField}',
title: '${comment}',
width: 180,
align: 'center',
formatter: ({ cellValue }) => dateFormatter(null,null,cellValue)
},
#elseif($column.dictType && "" != $column.dictType)## 数据字典
{
field: '${javaField}',
title: '${comment}',
width: 120,
align: 'center',
formatter: ({ cellValue }) => {
const dict = getStrDictOptions(DICT_TYPE.${dictType.toUpperCase()}).find(item => item.value === cellValue)
return dict ? dict.label : cellValue
}
},
#else
{
field: '${javaField}',
title: '${comment}',
minWidth: 120,
align: 'center'
},
#end
#end
#end
{
title: '操作',
width: 200,
align: 'center',
fixed: 'right', // 固定在右侧
slots: { default: 'action' }
}
]
})
#end
/** 查询列表 */
const getList = async () => {
loading.value = true
@@ -343,6 +453,27 @@ const handleDelete = async (id: number) => {
} catch {}
}
/** 批量删除按钮操作 */
const handleBatchDelete = async () => {
try {
if (selectRecords.value.length === 0) {
message.warning('请至少选择一条记录')
return
}
// 删除的二次确认
await message.delConfirm(`确定要删除选中的 ${selectRecords.value.length} 条记录吗?`)
// 批量删除
const ids = selectRecords.value.map((record) => record.id)
await ${simpleClassName}Api.delete${simpleClassName}List(ids)
message.success(t('common.delSuccess'))
// 清空选中状态
gridRef.value?.clearCheckboxRow()
selectRecords.value = []
// 刷新列表
await getList()
} catch {}
}
/** 导出按钮操作 */
const handleExport = async () => {
try {