# 批量发品-子账号功能更新说明

## 更新时间
2025-01-10 (最后更新：2025-01-10 18:30)

## 功能描述
在批量发品功能中新增子账号选择功能。支持**同时选择多个主账号**，每个主账号可以**多选子账号**。系统会为每个商品×每个主账号×每个子账号创建发品任务。

## 前端修改

### 1. `ruoyi-vue/src/views/jarvis/batchPublish/index.vue`

#### 界面改动
- 将"目标账号"改为复选框（Checkbox），支持**同时选择多个主账号**
- 每个选中的主账号下方自动展开对应的**子账号多选下拉框**
- 子账号在首次展开或点击下拉框时自动加载
- 支持为不同主账号选择不同的子账号组合
- 添加加载状态提示和友好的错误提示

#### 数据改动
```javascript
// 修改后的数据结构
publishForm: {
  selectedMainAccounts: [],      // 选中的主账号列表 ['appid1', 'appid2']
  accountSubAccounts: {          // 每个主账号对应的子账号
    'appid1': ['子账号1', '子账号2'],
    'appid2': ['子账号3']
  }
}

// 子账号数据
subAccountsMap: {                // 每个主账号对应的子账号选项列表
  'appid1': [{value, label}],
  'appid2': [{value, label}]
}
loadingSubAccounts: {            // 每个主账号的加载状态
  'appid1': false,
  'appid2': true
}
```

#### 新增/修改方法
- `onMainAccountsChange(selectedAccounts)`: 主账号变化时触发，清理未选中账号的数据，为新选中账号初始化数据结构
- `loadSubAccountsForAccount(appid)`: 为指定主账号加载子账号列表（带防重复加载逻辑）

## 后端修改

### 1. `BatchPublishRequest.java`
```java
// 新增内部类
public static class AccountConfig {
    private String targetAccount;      // 目标ERP账号（appid）
    private List<String> subAccounts;  // 该账号下的子账号列表
}

// 修改后的字段
private List<AccountConfig> accountConfigs;  // 账号配置列表（多个主账号+子账号）
```

数据结构示例：
```json
{
  "accountConfigs": [
    {
      "targetAccount": "appid1",
      "subAccounts": ["子账号1", "子账号2"]
    },
    {
      "targetAccount": "appid2",
      "subAccounts": ["子账号3"]
    }
  ]
}
```

### 2. `BatchPublishItem.java`
新增字段：
```java
private String subAccount;  // 子账号（会员名）
```

### 3. `BatchPublishServiceImpl.java`
#### batchPublish方法
- 修改任务创建逻辑，支持多主账号配置
- 为**每个商品 × 每个主账号 × 每个子账号**创建一条发品记录
- 保存完整的账号配置信息到任务记录中

**处理逻辑：**
```java
for (ProductItem product : products) {
    for (AccountConfig config : accountConfigs) {
        String appid = config.getTargetAccount();
        for (String subAccount : config.getSubAccounts()) {
            // 创建一条发品记录
            // 记录包含：商品信息 + 主账号(appid) + 子账号(会员名)
        }
    }
}
```

**示例：**
- 2个商品 × 2个主账号 × (每个主账号2个子账号) = 8条发品记录

#### publishProduct方法
- 使用`item.getSubAccount()`作为会员名进行发品
- 如果子账号为空，则使用通用参数中的会员名作为备选

### 4. `BatchPublishItemMapper.xml`
#### 修改内容
- `resultMap`中添加`sub_account`字段映射
- `selectBatchPublishItemVo` SQL中添加`sub_account`字段
- `insertBatchPublishItem`中添加`sub_account`字段
- `batchInsertBatchPublishItem`批量插入中添加`sub_account`字段

## 数据库修改

### SQL迁移脚本
文件：`sql/add_sub_account_column.sql`

```sql
ALTER TABLE batch_publish_item 
ADD COLUMN sub_account VARCHAR(100) COMMENT '子账号（会员名）' AFTER account_remark;
```

## 使用流程

### 用户操作流程
1. 选择线报消息并解析商品
2. 选择要发品的商品
3. **勾选一个或多个主账号**（支持多选）
4. 系统自动为每个选中的主账号展开子账号下拉框
5. 在每个主账号下**选择一个或多个子账号**（支持多选）
6. 填写其他通用参数
7. 提交批量发品

**界面示例：**
```
☑ 海尔胡歌
  ↓ [子账号1, 子账号2, 子账号3] (多选下拉框)
  
☑ 方案小号  
  ↓ [子账号A, 子账号B] (多选下拉框)

☐ 其他账号
```

### 数据流转
1. 前端提交数据包含：
   ```javascript
   {
     accountConfigs: [
       { targetAccount: 'appid1', subAccounts: ['子账号1', '子账号2'] },
       { targetAccount: 'appid2', subAccounts: ['子账号A'] }
     ]
   }
   ```
   
2. 后端处理逻辑：
   - 对于每个商品 × 每个主账号配置 × 每个子账号，创建一条发品记录
   - 每条记录包含：`targetAccount`（appid）和 `subAccount`（会员名）
   
3. 发品时：
   - 使用`targetAccount`确定ERP账号（API密钥）
   - 使用`subAccount`作为发品时的会员名

**发品数量计算：**
- 假设选择：2个商品、2个主账号（每个主账号选2个子账号）
- 生成发品任务数：2 × 2 × 2 = **8条发品记录**

## 兼容性说明

### 向后兼容
- 如果`subAccount`字段为空，系统会使用通用参数中的`userName`作为备选
- 旧的发品记录不受影响，可以正常查询和显示

## 部署步骤

1. 执行数据库迁移脚本：
   ```sql
   source sql/add_sub_account_column.sql
   ```

2. 重新编译并部署后端服务：
   ```bash
   cd ruoyi-java
   mvn clean package
   ```

3. 部署前端：
   ```bash
   cd ruoyi-vue
   npm run build
   ```

4. 重启服务

## 测试要点

### 基础功能测试
1. **主账号多选**：勾选多个主账号，确认每个账号下都展开了子账号选择框
2. **子账号加载**：确认每个主账号的子账号列表正确加载，且互不干扰
3. **取消主账号**：取消勾选主账号时，对应的子账号数据被清理
4. **子账号多选**：每个主账号下可以独立选择多个子账号

### 数据验证测试
5. **必填验证**：未选择主账号时提示"请至少选择一个主账号"
6. **子账号验证**：选中主账号但未选子账号时，提示"请为账号XXX选择至少一个子账号"
7. **发品记录数量**：验证创建的发品记录数 = 商品数 × Σ(每个主账号的子账号数)

### 业务功能测试
8. **任务创建**：提交后正确创建任务，任务记录中保存完整的账号配置信息
9. **发品明细**：查看发品明细时，主账号和子账号信息都正确显示
10. **实际发品**：验证发品时使用了正确的主账号（API密钥）和子账号（会员名）

### 边界情况测试
11. **单主账号单子账号**：退化到最简单情况是否正常
12. **多主账号多子账号**：同时选择所有主账号，每个主账号选择多个子账号
13. **子账号为空**：某个主账号下没有子账号时的提示是否友好
14. **网络异常**：加载子账号失败时是否有正确的错误提示

## 注意事项

1. 子账号列表通过调用`/erp/product/usernames`接口获取
2. 该接口需要传递`appid`参数，即主账号的API Key
3. 确保ERP账号已正确授权，否则可能无法获取子账号列表
4. 建议在生产环境部署前，先在测试环境完整测试一遍流程

