用了几周AI发现还挺爽的,记录一下
- 我们老板总是喜欢让我用ai开发东西,之前是买了lovable生成页面的,后面又给我弄了个cursor账号。
- 上班直接不用动脑子的感觉好爽。头发有救了。
本人学习记录。不一定准确仅供参考。
首先我写了一段sql让cursor帮我写一个方法处理行转列的动态列表,
SELECT
r.data_name,
r.data_type,
r.data_unit,
r.number_field,
r.text_field,
r.file_field,
r.count_setting,
r.remark,
t.write_org_ids,
s.org_name
FROM
`report_task_record` r
LEFT JOIN `report_task` t ON r.report_task_id = t.id
LEFT JOIN `sys_org` s ON s.id = t.write_org_ids
WHERE
r.report_template_id = '1942757082638307329'
AND r.data_name != ''
AND r.data_name IS NOT NULL
- java代码
/**
* 获取动态列表数据
* 根据data_type动态取值:1-数值字段,2-文本字段,3-文件字段
* @param reportTemplateId 报表模板ID
* @return 动态列表数据
*/
@ApiOperation(value="获取动态列表数据", notes="根据data_type动态取值返回列表")
@GetMapping(value = "/getDynamicList")
public Result<Map<String, Object>> getDynamicList(@RequestParam(name="reportTemplateId",required=true) String reportTemplateId) {
try {
// 查询获取数据
List<ReportTaskRecord> rawData = reportTaskRecordService.getDynamicList(reportTemplateId);
if (rawData == null || rawData.isEmpty()) {
Map<String, Object> emptyResult = new HashMap<>();
emptyResult.put("columns", new ArrayList<>());
emptyResult.put("data", new ArrayList<>());
emptyResult.put("fieldNames", new ArrayList<>());
return Result.OK(emptyResult);
}
// 获取所有唯一的字段名称(data_name)
Set<String> fieldNames = rawData.stream()
.map(ReportTaskRecord::getDataName)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
// 获取所有唯一的公司名称
Set<String> orgNames = rawData.stream()
.map(ReportTaskRecord::getOrgName)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
// 构建列信息
List<Map<String, String>> columns = new ArrayList<>();
// 第一列是公司名称
Map<String, String> orgColumn = new HashMap<>();
orgColumn.put("field", "org_name");
orgColumn.put("title", "公司名称");
orgColumn.put("dataIndex", "org_name");
orgColumn.put("dataType", null); // 或 0
columns.add(orgColumn);
// 动态添加字段列信息
int fieldIndex = 1;
for (String fieldName : fieldNames) {
Map<String, String> column = new HashMap<>();
String fieldKey = "field" + fieldIndex;
column.put("field", fieldKey);
column.put("title", fieldName);
column.put("dataIndex", fieldKey);
// 查找该字段的dataType
String dataType = rawData.stream()
.filter(r -> fieldName.equals(r.getDataName()))
.map(ReportTaskRecord::getDataType)
.findFirst()
.orElse(null);
column.put("dataType", dataType);
columns.add(column);
fieldIndex++;
}
// 构建动态列表数据
List<Map<String, Object>> resultList = new ArrayList<>();
for (String orgName : orgNames) {
Map<String, Object> rowData = new HashMap<>();
// 第一个字段是公司名称
rowData.put("org_name", orgName);
// 动态添加字段,根据data_type取值
fieldIndex = 1;
for (String fieldName : fieldNames) {
// 找到对应公司和字段的数据
ReportTaskRecord matchingData = rawData.stream()
.filter(row -> orgName.equals(row.getOrgName()) && fieldName.equals(row.getDataName()))
.findFirst()
.orElse(null);
if (matchingData != null) {
String dataType = matchingData.getDataType();
Object fieldValue = null;
// 根据data_type取值
switch (dataType) {
case "1": // 数值类型
fieldValue = matchingData.getNumberField();
break;
case "2": // 文本类型
fieldValue = matchingData.getTextField();
break;
case "3": // 文件类型
fieldValue = matchingData.getFileField();
break;
default:
fieldValue = "";
}
// 使用field1, field2, field3...作为字段名
rowData.put("field" + fieldIndex, fieldValue);
} else {
// 如果没有匹配的数据,设置为空值
rowData.put("field" + fieldIndex, "");
}
fieldIndex++;
}
resultList.add(rowData);
}
// 构建返回结果
Map<String, Object> result = new HashMap<>();
result.put("columns", columns);
result.put("data", resultList);
result.put("fieldNames", new ArrayList<>(fieldNames));
result.put("orgNames", new ArrayList<>(orgNames));
return Result.OK(result);
} catch (Exception e) {
log.error("获取动态列表数据失败", e);
return Result.error("获取动态列表数据失败:" + e.getMessage());
}
}
- vue代码
<template xmlns:v-slot="http://www.w3.org/1999/XSL/Transform">
<div>
<vxe-table :data="tableData" border stripe>
<vxe-table-column
v-for="col in tableColumns"
:key="col.field"
:field="col.field"
:title="col.title"
:min-width="100"
>
<template v-slot="{ row }">
<!-- 合计/平均行特殊显示 -->
<span v-if="row._rowType === 'sum' && col.field === 'org_name'">合计</span>
<span v-else-if="row._rowType === 'avg' && col.field === 'org_name'">平均</span>
<span v-else-if="row._rowType && col.dataType !== '1'"></span>
<span v-else-if="col.dataType === '1'">{{ row[col.field] }}</span>
<span v-else-if="col.dataType === '2'">{{ row[col.field] }}</span>
<uploadAddStrZm v-else-if="col.dataType === '3'" v-model="row[col.field]" :buttonVisible="false" :disabled="true"></uploadAddStrZm>
<span v-else>{{ row[col.field] }}</span>
</template>
</vxe-table-column>
</vxe-table>
</div>
</template>
<script>
import {httpAction, getAction,postAction} from '@/api/manage'
import uploadAddStrZm from '@/components/addtool/uploadAddStrZm';
export default {
components: {
uploadAddStrZm,
},
props:{
reportTaskId: {
type: String,
default: undefined,
required: false,
},
disableSubmit: {
type: Boolean,
default: false,
},
},
data() {
return {
tableColumns:{},
tableData:[],
url:{
getDynamicList:"yh/reportTemplate/getDynamicList"
},
}
},
methods: {
initData(val){
getAction(this.url.getDynamicList,{reportTemplateId:val}).then((res)=>{
if(res.success){
this.tableColumns = res.result.columns
let data = res.result.data
// 计算合计和平均
const numberFields = this.tableColumns
.filter(col => col.dataType === '1')
.map(col => col.field)
// 合计
const sumRow = { org_name: '合计', _rowType: 'sum' }
// 平均
const avgRow = { org_name: '平均', _rowType: 'avg' }
numberFields.forEach(field => {
const sum = data.reduce((acc, row) => acc + (parseFloat(row[field]) || 0), 0)
const avg = data.length ? (sum / data.length) : 0
sumRow[field] = sum
avgRow[field] = avg
})
// 其他字段置空
this.tableColumns.forEach(col => {
if (!numberFields.includes(col.field) && col.field !== 'org_name') {
sumRow[col.field] = ''
avgRow[col.field] = ''
}
})
// 插入到数据最后
this.tableData = [...data, sumRow, avgRow]
}else{
}
})
},
cancelDelete(){
},
}
}
</script>
- 最后效果
- 除了最后把上传附件组件替换了框架里的组件外都是他给我写的,
- 舒服,剩下时间刷沸点去咯
...