184 lines
5.2 KiB
Markdown
184 lines
5.2 KiB
Markdown
# Permutation页面列表显示问题分析和修复方案
|
||
|
||
## 问题分析
|
||
|
||
经过代码分析,发现了以下几个可能导致列表不显示的问题:
|
||
|
||
### 1. API路径不匹配
|
||
前端代码中引用的API函数名与后端控制器中的路径不一致:
|
||
- 前端:`productcontrollerGetcategoriesall`、`productcontrollerGetcategoryattributes`、`productcontrollerGetproductlist`
|
||
- 后端实际的API路径:`/product/categories/all`、`/product/category/:id/attributes`、`/product/list`
|
||
|
||
### 2. 数据格式问题
|
||
- `getCategoryAttributes`返回的数据结构与前端期望的不匹配
|
||
- 属性值获取逻辑可能存在问题
|
||
|
||
### 3. 组合生成逻辑问题
|
||
- 在生成排列组合时,数据结构和键值对应可能不正确
|
||
|
||
## 修复方案
|
||
|
||
### 后端修复
|
||
|
||
1. **修改getCategoryAttributes方法** - 在`/Users/zksu/Developer/work/workcode/API/src/service/product.service.ts`中:
|
||
|
||
```typescript
|
||
// 获取分类下的属性配置
|
||
async getCategoryAttributes(categoryId: number): Promise<any[]> {
|
||
const category = await this.categoryModel.findOne({
|
||
where: { id: categoryId },
|
||
relations: ['attributes', 'attributes.attributeDict', 'attributes.attributeDict.items'],
|
||
});
|
||
|
||
if (!category) {
|
||
return [];
|
||
}
|
||
|
||
// 格式化返回,匹配前端期望的数据结构
|
||
return category.attributes.map(attr => ({
|
||
id: attr.id,
|
||
dictId: attr.attributeDict.id,
|
||
name: attr.attributeDict.name, // 用于generateKeyFromPermutation
|
||
title: attr.attributeDict.title, // 用于列标题
|
||
dict: {
|
||
id: attr.attributeDict.id,
|
||
name: attr.attributeDict.name,
|
||
title: attr.attributeDict.title,
|
||
items: attr.attributeDict.items || []
|
||
}
|
||
}));
|
||
}
|
||
```
|
||
|
||
2. **确保dict/items接口可用** - 检查字典项获取接口:
|
||
|
||
在`/Users/zksu/Developer/work/workcode/API/src/controller/dict.controller.ts`中添加或确认:
|
||
|
||
```typescript
|
||
@Get('/items')
|
||
async getDictItems(@Query('dictId') dictId: number) {
|
||
try {
|
||
const dict = await this.dictModel.findOne({
|
||
where: { id: dictId },
|
||
relations: ['items']
|
||
});
|
||
|
||
if (!dict) {
|
||
return [];
|
||
}
|
||
|
||
return dict.items || [];
|
||
} catch (error) {
|
||
return errorResponse(error?.message || error);
|
||
}
|
||
}
|
||
```
|
||
|
||
### 前端修复建议
|
||
|
||
1. **添加错误处理和调试信息**:
|
||
|
||
```typescript
|
||
// 在获取属性值的地方添加错误处理
|
||
const fetchData = async () => {
|
||
setLoading(true);
|
||
try {
|
||
// 1. Fetch Attributes
|
||
const attrRes = await productcontrollerGetcategoryattributes({
|
||
id: categoryId,
|
||
});
|
||
console.log('Attributes response:', attrRes); // 调试用
|
||
const attrs = Array.isArray(attrRes) ? attrRes : attrRes?.data || [];
|
||
setAttributes(attrs);
|
||
|
||
// 2. Fetch Attribute Values (Dict Items)
|
||
const valuesMap: Record<string, any[]> = {};
|
||
for (const attr of attrs) {
|
||
const dictId = attr.dict?.id || attr.dictId;
|
||
if (dictId) {
|
||
try {
|
||
const itemsRes = await request('/dict/items', {
|
||
params: { dictId },
|
||
});
|
||
console.log(`Dict items for ${attr.name}:`, itemsRes); // 调试用
|
||
valuesMap[attr.name] = itemsRes || [];
|
||
} catch (error) {
|
||
console.error(`Failed to fetch items for dict ${dictId}:`, error);
|
||
valuesMap[attr.name] = [];
|
||
}
|
||
}
|
||
}
|
||
setAttributeValues(valuesMap);
|
||
|
||
// 3. Fetch Existing Products
|
||
await fetchProducts(categoryId);
|
||
} catch (error) {
|
||
console.error('Error in fetchData:', error);
|
||
message.error('获取数据失败');
|
||
} finally {
|
||
setLoading(false);
|
||
}
|
||
};
|
||
```
|
||
|
||
2. **修复组合生成逻辑**:
|
||
|
||
```typescript
|
||
// 修改generateKeyFromPermutation函数
|
||
const generateKeyFromPermutation = (perm: any) => {
|
||
const parts = Object.keys(perm).map((attrName) => {
|
||
const valItem = perm[attrName];
|
||
const val = valItem.name || valItem.value; // 兼容不同的数据格式
|
||
return `${attrName}:${val}`;
|
||
});
|
||
return parts.sort().join('|');
|
||
};
|
||
|
||
// 修改generateAttributeKey函数
|
||
const generateAttributeKey = (attrs: any[]) => {
|
||
const parts = attrs.map((a) => {
|
||
const key = a.dict?.name || a.dictName || a.name;
|
||
const val = a.name || a.value;
|
||
return `${key}:${val}`;
|
||
});
|
||
return parts.sort().join('|');
|
||
};
|
||
```
|
||
|
||
3. **添加空状态处理**:
|
||
|
||
```typescript
|
||
// 在ProTable中添加空状态提示
|
||
<ProTable
|
||
// ... 其他属性
|
||
locale={{
|
||
emptyText: permutations.length === 0 && !loading ? '暂无数据,请检查分类属性配置' : '暂无数据'
|
||
}}
|
||
/>
|
||
```
|
||
|
||
## 调试步骤
|
||
|
||
1. **检查网络请求**:
|
||
- 打开浏览器开发者工具
|
||
- 检查 `/product/categories/all` 请求是否成功
|
||
- 检查 `/product/category/:id/attributes` 请求返回的数据格式
|
||
- 检查 `/dict/items?dictId=:id` 请求是否成功
|
||
- 检查 `/product/list` 请求是否成功
|
||
|
||
2. **检查控制台日志**:
|
||
- 查看属性数据是否正确加载
|
||
- 查看属性值是否正确获取
|
||
- 查看排列组合是否正确生成
|
||
|
||
3. **检查数据结构**:
|
||
- 确认 `attributes` 数组是否正确
|
||
- 确认 `attributeValues` 对象是否正确填充
|
||
- 确认 `permutations` 数组是否正确生成
|
||
|
||
## 测试验证
|
||
|
||
1. 选择一个有属性配置的分类
|
||
2. 确认属性有对应的字典项
|
||
3. 检查排列组合是否正确显示
|
||
4. 验证现有产品匹配是否正确 |