# 客户管理功能完成指南

## ✅ 已完成内容

### 1. 数据结构和状态管理
- ✅ Customer 接口定义（第191-206行）
- ✅ CustomerPurchase 接口定义（第208-216行）
- ✅ 客户数据初始化（3个示例客户）
- ✅ 客户表单状态 customerFormData
- ✅ 编辑状态 editingCustomer

### 2. 业务逻辑函数
- ✅ handleSaveCustomer - 新增/编辑客户
- ✅ handleEditCustomer - 编辑客户
- ✅ handleDeleteCustomer - 删除客户  
- ✅ handleViewCustomer - 查看客户详情

### 3. UI组件
- ✅ 客户管理Tab（第2137-2333行）
- ✅ 客户列表展示
- ✅ 统计卡片
- ✅ 信用额度进度条
- ✅ 购买记录展示

## ⚠️ 需要完成的部分

### 1. 按钮事件绑定
客户列表中的三个按钮还没有绑定事件，需要在第2315-2326行修改：

**当前代码（第2315-2326行）：**
```tsx
<div className="flex gap-2">
  <Button size="sm" variant="outline">
    <Eye className="w-4 h-4 mr-2" />
    查看详情
  </Button>
  <Button size="sm" variant="outline">
    <Edit className="w-4 h-4" />
  </Button>
  <Button size="sm" variant="outline">
    <Trash2 className="w-4 h-4" />
  </Button>
</div>
```

**修改为：**
```tsx
<div className="flex gap-2">
  <Button size="sm" variant="outline" onClick={() => handleViewCustomer(customer)}>
    <Eye className="w-4 h-4 mr-2" />
    查看详情
  </Button>
  <Button size="sm" variant="outline" onClick={() => handleEditCustomer(customer)}>
    <Edit className="w-4 h-4" />
  </Button>
  <Button size="sm" variant="outline" onClick={() => handleDeleteCustomer(customer.id)}>
    <Trash2 className="w-4 h-4" />
  </Button>
</div>
```

### 2. 新增/编辑对话框
在文件末尾（第3934行之前）添加客户对话框，插入到 `</Dialog>` 和 `</div>` 之间：

```tsx
{/* 客户新增/编辑对话框 */}
<Dialog open={showCustomerDialog} onOpenChange={(open) => {
  setShowCustomerDialog(open);
  if (!open) {
    setEditingCustomer(null);
    setCustomerFormData({
      name: '',
      type: '',
      contactPerson: '',
      phone: '',
      email: '',
      address: '',
      creditLimit: '',
      notes: '',
    });
  }
}}>
  <DialogContent className="max-w-3xl max-h-[90vh] overflow-y-auto">
    <DialogHeader>
      <DialogTitle>{editingCustomer ? '编辑客户' : '新增客户'}</DialogTitle>
      <DialogDescription>
        填写客户基本信息和信用额度
      </DialogDescription>
    </DialogHeader>
    <div className="space-y-6">
      {/* 基本信息 */}
      <Card className="p-4">
        <h4 className="mb-4 flex items-center gap-2">
          <Users className="w-5 h-5 text-orange-600" />
          基本信息
        </h4>
        
        <div className="space-y-4">
          <div className="grid grid-cols-2 gap-4">
            <div>
              <label>客户名称 <span className="text-destructive">*</span></label>
              <Input
                placeholder="如：张三、绿源合作社"
                className="mt-2"
                value={customerFormData.name}
                onChange={(e) => setCustomerFormData({ ...customerFormData, name: e.target.value })}
              />
            </div>
            <div>
              <label>客户类型 <span className="text-destructive">*</span></label>
              <Select value={customerFormData.type} onValueChange={(value) => setCustomerFormData({ ...customerFormData, type: value as '农户' | '合作社' | '企业' })}>
                <SelectTrigger className="mt-2">
                  <SelectValue placeholder="选择类型" />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="农户">农户</SelectItem>
                  <SelectItem value="合作社">合作社</SelectItem>
                  <SelectItem value="企业">企业</SelectItem>
                </SelectContent>
              </Select>
            </div>
          </div>

          <div className="grid grid-cols-2 gap-4">
            <div>
              <label>联系人 <span className="text-destructive">*</span></label>
              <Input
                placeholder="如：张三"
                className="mt-2"
                value={customerFormData.contactPerson}
                onChange={(e) => setCustomerFormData({ ...customerFormData, contactPerson: e.target.value })}
              />
            </div>
            <div>
              <label>联系电话 <span className="text-destructive">*</span></label>
              <Input
                placeholder="如：13800001111"
                className="mt-2"
                value={customerFormData.phone}
                onChange={(e) => setCustomerFormData({ ...customerFormData, phone: e.target.value })}
              />
            </div>
          </div>

          <div className="grid grid-cols-2 gap-4">
            <div>
              <label>电子邮箱</label>
              <Input
                placeholder="如：customer@example.com"
                className="mt-2"
                type="email"
                value={customerFormData.email}
                onChange={(e) => setCustomerFormData({ ...customerFormData, email: e.target.value })}
              />
            </div>
            <div>
              <label>信用额度(元) <span className="text-destructive">*</span></label>
              <Input
                placeholder="如：50000"
                className="mt-2"
                type="number"
                value={customerFormData.creditLimit}
                onChange={(e) => setCustomerFormData({ ...customerFormData, creditLimit: e.target.value })}
              />
              <p className="text-xs text-muted-foreground mt-1">
                客户可使用的最大赊账额度
              </p>
            </div>
          </div>

          <div>
            <label>地址 <span className="text-destructive">*</span></label>
            <Input
              placeholder="如：浙江省杭州市余杭区XXX村"
              className="mt-2"
              value={customerFormData.address}
              onChange={(e) => setCustomerFormData({ ...customerFormData, address: e.target.value })}
            />
          </div>

          <div>
            <label>备注</label>
            <Textarea
              placeholder="备注信息"
              className="mt-2"
              rows={3}
              value={customerFormData.notes}
              onChange={(e) => setCustomerFormData({ ...customerFormData, notes: e.target.value })}
            />
          </div>
        </div>
      </Card>

      <div className="flex justify-end gap-2">
        <Button variant="outline" onClick={() => setShowCustomerDialog(false)}>
          取消
        </Button>
        <Button className="bg-green-600 hover:bg-green-700" onClick={handleSaveCustomer}>
          <Save className="w-4 h-4 mr-2" />
          {editingCustomer ? '保存' : '添加'}
        </Button>
      </div>
    </div>
  </DialogContent>
</Dialog>
```

### 3. 查看详情对话框支持
在查看详情对话框（第2667行开始）中添加客户详情显示。

在第2680行之后，添加客户详情显示逻辑：

```tsx
{/* 客户详情内容 */}
{selectedItem && selectedItem.creditLimit !== undefined && !(selectedItem as any).certifications && !(selectedItem as any).spec && (
  <div className="space-y-4">
    {/* 基本信息 */}
    <Card className="p-4 bg-orange-50">
      <div className="flex items-start justify-between mb-4">
        <div className="flex items-start gap-3">
          <div className={`p-3 rounded-lg ${\
            selectedItem.type === '农户' ? 'bg-green-100' :
            selectedItem.type === '合作社' ? 'bg-blue-100' :
            'bg-purple-100'
          }`}>
            <Users className={`w-6 h-6 ${\
              selectedItem.type === '农户' ? 'text-green-600' :
              selectedItem.type === '合作社' ? 'text-blue-600' :
              'text-purple-600'
            }`} />
          </div>
          <div>
            <h4 className="mb-1">{selectedItem.name}</h4>
            <div className="flex items-center gap-2 mb-2">
              <Badge variant="outline">{selectedItem.type}</Badge>
              <Badge className={
                selectedItem.totalPurchaseAmount >= 500000 ? 'bg-purple-100 text-purple-800' :
                selectedItem.totalPurchaseAmount >= 200000 ? 'bg-blue-100 text-blue-800' :
                'bg-gray-100 text-gray-800'
              }>
                {selectedItem.totalPurchaseAmount >= 500000 ? 'VIP客户' :
                 selectedItem.totalPurchaseAmount >= 200000 ? '优质客户' :
                 '普通客户'}
              </Badge>
            </div>
            <p className="text-sm text-muted-foreground">
              编码: {selectedItem.code} | 创建时间: {selectedItem.createdAt}
            </p>
          </div>
        </div>
      </div>

      <div className="grid grid-cols-4 gap-3">
        <div>
          <p className="text-xs text-muted-foreground mb-1">联系人</p>
          <p className="font-medium">{selectedItem.contactPerson}</p>
        </div>
        <div>
          <p className="text-xs text-muted-foreground mb-1">联系电话</p>
          <p className="font-medium">{selectedItem.phone}</p>
        </div>
        <div className="col-span-2">
          <p className="text-xs text-muted-foreground mb-1">地址</p>
          <p className="font-medium text-xs">{selectedItem.address}</p>
        </div>
      </div>
    </Card>

    {/* 信用额度信息 */}
    <Card className="p-4 bg-gradient-to-r from-blue-50 to-purple-50">
      <h4 className="mb-3 flex items-center gap-2">
        <DollarSign className="w-4 h-4 text-blue-600" />
        信用额度信息
      </h4>
      <div className="mb-3">
        <div className="flex items-center justify-between mb-2">
          <span className="text-sm">额度使用率</span>
          <span className="text-sm font-medium">
            {((selectedItem.usedCredit / selectedItem.creditLimit) * 100).toFixed(1)}%
          </span>
        </div>
        <Progress value={(selectedItem.usedCredit / selectedItem.creditLimit) * 100} className="h-2" />
      </div>
      <div className="grid grid-cols-3 gap-4">
        <div className="p-3 bg-white rounded-lg">
          <p className="text-xs text-muted-foreground mb-1">总额度</p>
          <p className="text-lg font-medium text-blue-600">
            ¥{selectedItem.creditLimit.toLocaleString()}
          </p>
        </div>
        <div className="p-3 bg-white rounded-lg">
          <p className="text-xs text-muted-foreground mb-1">已用额度</p>
          <p className="text-lg font-medium text-orange-600">
            ¥{selectedItem.usedCredit.toLocaleString()}
          </p>
        </div>
        <div className="p-3 bg-white rounded-lg">
          <p className="text-xs text-muted-foreground mb-1">剩余额度</p>
          <p className="text-lg font-medium text-green-600">
            ¥{(selectedItem.creditLimit - selectedItem.usedCredit).toLocaleString()}
          </p>
        </div>
      </div>
    </Card>

    {/* 统计信息 */}
    <div className="grid grid-cols-3 gap-4">
      <Card className="p-4 bg-green-50">
        <p className="text-xs text-muted-foreground flex items-center gap-1 mb-2">
          <DollarSign className="w-3 h-3" />
          累计购买金额
        </p>
        <p className="text-2xl font-medium text-green-600">
          ¥{(selectedItem.totalPurchaseAmount / 10000).toFixed(1)}万
        </p>
      </Card>
      <Card className="p-4 bg-blue-50">
        <p className="text-xs text-muted-foreground flex items-center gap-1 mb-2">
          <ShoppingCart className="w-3 h-3" />
          购买次数
        </p>
        <p className="text-2xl font-medium text-blue-600">
          {selectedItem.purchaseHistory.length} 次
        </p>
      </Card>
      <Card className="p-4 bg-orange-50">
        <p className="text-xs text-muted-foreground flex items-center gap-1 mb-2">
          <AlertCircle className="w-3 h-3" />
          待付款订单
        </p>
        <p className="text-2xl font-medium text-orange-600">
          {selectedItem.purchaseHistory.filter((p: CustomerPurchase) => p.status !== '已完成').length} 笔
        </p>
      </Card>
    </div>

    {/* 购买历史 */}
    {selectedItem.purchaseHistory.length > 0 && (
      <Card className="p-4">
        <h4 className="mb-3 flex items-center gap-2">
          <ShoppingCart className="w-4 h-4 text-blue-600" />
          购买历史 ({selectedItem.purchaseHistory.length}条)
        </h4>
        <div className="space-y-3">
          {selectedItem.purchaseHistory.map((record: CustomerPurchase) => (
            <div key={record.id} className="p-3 bg-blue-50 rounded-lg">
              <div className="flex items-center justify-between mb-2">
                <div className="flex items-center gap-2">
                  <span className="font-medium">{record.productName}</span>
                  <Badge variant="outline">{record.date}</Badge>
                </div>
                <span className="text-lg font-medium text-green-600">¥{record.amount.toLocaleString()}</span>
              </div>
              <div className="text-sm text-muted-foreground">
                <span>数量: {record.quantity}</span>
                <span className="mx-2">|</span>
                <span>已付: ¥{record.paid.toLocaleString()}</span>
                <span className="mx-2">|</span>
                <span className={
                  record.status === '已完成' ? 'text-green-600' :
                  record.status === '待付款' ? 'text-red-600' :
                  'text-orange-600'
                }>
                  {record.status}
                </span>
              </div>
            </div>
          ))}
        </div>
      </Card>
    )}

    {/* 备注 */}
    {selectedItem.notes && (
      <Card className="p-4 bg-yellow-50">
        <h4 className="mb-2 flex items-center gap-2">
          <FileText className="w-4 h-4 text-yellow-600" />
          备注
        </h4>
        <p className="text-sm">{selectedItem.notes}</p>
      </Card>
    )}

    <div className="flex justify-end gap-2">
      <Button variant="outline" onClick={() => setShowViewDialog(false)}>
        关闭
      </Button>
      <Button className="bg-green-600 hover:bg-green-700" onClick={() => {
        setShowViewDialog(false);
        handleEditCustomer(selectedItem as Customer);
      }}>
        <Edit className="w-4 h-4 mr-2" />
        编辑
      </Button>
    </div>
  </div>
)}
```

## 📝 完成步骤

1. **修改按钮事件**：在第2315-2326行添加onClick事件
2. **添加新增/编辑对话框**：在第3934行之前插入完整的客户对话框代码
3. **添加查看详情支持**：在第2680行之后添加客户详情显示代码

## 🎯 功能清单

完成后，客户管理将具备以下完整功能：

### 核心功能
- ✅ 客户列表展示（农户、合作社、企业）
- ✅ 新增客户
- ✅ 编辑客户
- ✅ 删除客户（带业务校验）
- ✅ 查看客户详情

### 业务功能
- ✅ 信用额度管理（总额度、已用、剩余）
- ✅ 购买历史记录
- ✅ 客户等级自动评估（VIP/优质/普通）
- ✅ 待付款订单统计
- ✅ 累计购买金额统计

### 数据展示
- ✅ 信用额度进度条
- ✅ 购买历史详情
- ✅ 统计卡片
- ✅ 客户分类图标和颜色

## 测试建议

1. **新增测试**：点击"新增客户"，填写完整信息后保存
2. **编辑测试**：点击客户卡片的"编辑"按钮，修改信息后保存
3. **删除测试**：
   - 删除无待付款订单的客户（成功）
   - 删除有待付款订单的客户（应提示无法删除）
4. **查看测试**：点击"查看详情"，检查所有信息是否完整显示
5. **数据验证**：检查信用额度、购买记录、客户等级等数据是否正确

## 注意事项

- 删除客户前会检查是否有未完成订单
- 客户等级根据累计购买金额自动评估
- 信用额度使用率实时计算并显示
- 所有必填字段都有*标记
