# 开发规范与问题记录

## 项目概述
本项目基于 Vue 3 + TypeScript + Element Plus + Vite 技术栈开发的管理系统。

## 已发现的问题与解决方案

### 1. 时间字段处理错误
**问题描述**：
创建道具卡时出现数据库错误：`Error 1292 (22007): Incorrect date value: '0000-00-00' for column 'valid_start' at row 1`

**问题原因**：
- 当用户没有选择有效期时，代码仍然尝试提交时间字段
- 时间数据格式不正确或包含无效值
- 后端数据库不接受'0000-00-00'这样的无效日期

**解决方案**：
```typescript
// 处理有效期 - 只有当时间范围有效时才添加时间字段
if (validTimeRange.value && validTimeRange.value.length === 2 && 
    validTimeRange.value[0] && validTimeRange.value[1]) {
  try {
    const startTime = new Date(validTimeRange.value[0]).getTime()
    const endTime = new Date(validTimeRange.value[1]).getTime()
    
    // 验证时间是否有效
    if (!isNaN(startTime) && !isNaN(endTime) && startTime > 0 && endTime > 0) {
      submitData.valid_start_unix = Math.floor(startTime / 1000)
      submitData.valid_end_unix = Math.floor(endTime / 1000)
    }
  } catch (error) {
    console.error('时间处理错误:', error)
  }
}
```

**开发规范**：
1. **时间字段处理**：
   - 必须验证时间数据的有效性
   - 使用`isNaN()`检查时间戳是否为有效数字
   - 确保时间值大于0
   - 添加try-catch处理可能的异常

2. **数据提交原则**：
   - 只提交有效和必要的数据字段
   - 避免提交null、undefined或无效的时间数据
   - 对可选字段进行严格的有效性检查

### 2. 价格字段数据类型错误
**问题描述**：
创建道具卡时出现错误：`json: cannot unmarshal null into Go struct field createItemCardRequest.price of type int64`

**解决方案**：
```typescript
// 确保价格字段存在且为数字类型
if (submitData.price === undefined || submitData.price === null) {
  submitData.price = 0
} else {
  submitData.price = Number(submitData.price)
}
```

### 3. 组件结构错误
**问题描述**：
道具卡管理页面按钮不显示，原因是错误的组件插槽使用

**解决方案**：
使用独立的按钮区域布局，避免错误的插槽使用：
```vue
<!-- 搜索栏 -->
<ArtSearchBar />

<!-- 表格头部和按钮 -->
<div class="table-header-wrapper">
  <div class="header-actions">
    <el-button type="primary" @click="handleCreate">
      新增道具卡
    </el-button>
  </div>
</div>

<!-- 数据表格 -->
<ArtTable />
```

### 4. 数据枚举显示问题
**问题描述**：
状态、类型、范围、效果等字段显示为数字而不是对应的文本标签

**解决方案**：
1. 增强枚举映射函数的空值处理
2. 完善状态字段的多状态判断
3. 添加数据类型检查

```typescript
// 增强的枚举映射函数
const getCardTypeLabel = (type: number) => cardTypeMap[type as keyof typeof cardTypeMap] || '未知'

// 完善的状态显示
{{ row.status === 1 ? '启用' : row.status === 2 ? '禁用' : '未知' }}

// 空值处理
{{ getCardTypeLabel(row.card_type || 0) }}
```

### 5. API路径404错误
**问题描述**：
优惠券API请求返回404错误：`admin/system_coupons` 路径不存在

**问题原因**：
后端API路径可能不存在或需要调整

**解决方案**：
1. 检查实际的API路径配置
2. 对比道具卡API路径确认一致性
3. 添加详细的请求调试信息
4. 检查代理配置是否正确

### 6. 数据枚举和操作按钮显示问题
**问题描述**：
道具卡管理页面中：
- 状态、类型、范围、效果等字段显示为数字而不是对应的文本标签
- 操作栏（编辑、删除按钮）不显示

**问题原因**：
1. 枚举映射函数没有正确处理空值
2. 使用了错误的按钮组件（原生的`el-button`而不是项目封装的`ArtButtonTable`）
3. 插槽模板语法正确但组件渲染有问题

**解决方案**：
1. **枚举显示修复**：
```vue
<template #status="{ row }">
  <el-tag :type="row.status === 1 ? 'success' : 'danger'">
    {{ row.status === 1 ? '启用' : row.status === 2 ? '禁用' : '未知' }}
  </el-tag>
</template>

<template #card_type="{ row }">
  <el-tag>{{ getCardTypeLabel(row.card_type || 0) }}</el-tag>
</template>
```

2. **操作按钮修复**：
```vue
<template #actions="{ row }">
  <ArtButtonTable type="edit" @click="handleEdit(row)" />
  <ArtButtonTable type="delete" @click="handleDelete(row)" />
</template>
```

3. **组件导入**：
```typescript
import ArtButtonTable from '@/components/core/forms/art-button-table/index.vue'
```

**开发规范**：
1. **组件使用规范**：
   - 优先使用项目封装的组件（如`ArtButtonTable`）而不是原生Element Plus组件
   - 保持与其他页面一致的UI风格和交互体验
   - 使用项目统一的图标和样式系统

2. **枚举显示规范**：
   - 所有状态字段必须提供完整的枚举映射
   - 处理空值和异常值情况，提供默认值
   - 使用统一的标签样式和颜色规范

3. **调试和日志**：
   - 添加详细的数据结构检查日志
   - 验证枚举映射函数的正确性
   - 检查组件渲染和插槽绑定的正确性

## 前端开发规范

### 1. 表单数据处理
- 提交前必须清理数据，移除undefined和null值
- 对数字类型字段进行类型转换和验证
- 时间字段必须验证有效性
- 可选字段需要条件判断

### 2. 错误处理
- 所有API调用必须添加try-catch异常处理
- 用户友好的错误提示信息
- 控制台记录详细错误信息便于调试

### 3. 代码结构
- 保持组件单一职责原则
- 复杂的表单处理逻辑抽取为独立函数
- 添加必要的注释说明业务逻辑

### 4. 数据验证
- 前端表单必须进行完整的验证
- 后端返回的错误需要友好处理
- 特殊字段（如时间、价格）需要额外验证

## 后端接口规范
- 明确字段类型要求（如int64）
- 提供清晰的错误信息和错误码
- 对无效数据给出具体的错误描述

## 数据库规范
- 不允许插入'0000-00-00'等无效日期
- 时间字段必须有默认值或允许为null
- 数字类型字段不能接收字符串类型

---

**最后更新**：2025年11月14日
**文档维护**：开发团队