> **前置条件** — 执行以下任何命令前，请先确认已完成认证。如未认证，参见 [`../../shb-shared/SKILL.md`](../../shb-shared/SKILL.md)。

# shb-cli task update

工单更新。`task update submit` 是写操作，直接调用编辑接口，**不经过审批检查流程**（与创建不同）。

## 安全规则

- 更新前确认用户明确要求"更新/修改/编辑工单"。
- **优先使用 `--data` 模式**：后端 edit 接口要求完整结构体（`customer`/`linkman`/`address` 需同时出现在顶层和 `task` 内部，还需要 `templateId`、`taskNo`、各数组字段等），`--data` 模式由调用方自行保证结构完整性，更可靠。
- 快捷 flags 模式（仅 `--task-id` + 改动 flags）会自动先拉取工单详情作为基础，适合只改少量字段的快速场景。
- `task.id` 必须是工单的系统 UUID，不是工单编号（taskNo）。

## 推荐方式：先查详情再用 `--data` 提交

> 这是最安全可靠的更新方式，适合所有场景。

```bash
# 第一步：获取当前工单完整数据
shb-cli task detail --id <taskId> -o raw > /tmp/task-detail.json

# 第二步：从详情中提取完整更新结构
jq '
  .initJson.task as $t |
  {
    address: ($t.taddress // {}),
    customer: {id: $t.customer.id},
    eventId: "",
    flow: "",
    linkman: {id: $t.tlmId, name: $t.tlmName, phone: $t.tlmPhone},
    task: {
      id: $t.id,
      taskNo: $t.taskNo,
      templateId: $t.templateId,
      description: $t.description,
      level: ($t.level // ""),
      serviceType: ($t.serviceType // ""),
      serviceContent: ($t.serviceContent // ""),
      planStartTime: $t.planStartTime,
      planEndTime: $t.planEndTime,
      serviceProviderQualification: ($t.serviceProviderQualification // ""),
      engineerQualification: ($t.engineerQualification // []),
      taskEstimatedMileage: ($t.taskEstimatedMileage // 0),
      attachment: ($t.attachment // []),
      products: ($t.products // []),
      cardForms: ($t.cardForms // []),
      attribute: ($t.attribute // {}),
      customer: {id: $t.customer.id},
      linkman: {id: $t.tlmId, name: $t.tlmName, phone: $t.tlmPhone},
      address: ($t.taddress // {}),
      tick: 0
    },
    tick: 0
  }
' /tmp/task-detail.json > /tmp/task-update.json

# 第三步：修改 /tmp/task-update.json 中要更改的字段（如 description、level 等）

# 第四步：提交
shb-cli task update submit --file /tmp/task-update.json
```

也可以在第二步提取时直接覆盖要修改的字段（省去手动编辑文件步骤）：

```bash
# 示例：只改描述，其余保持原值
jq '
  .initJson.task as $t |
  {
    address: ($t.taddress // {}),
    customer: {id: $t.customer.id},
    eventId: "", flow: "",
    linkman: {id: $t.tlmId, name: $t.tlmName, phone: $t.tlmPhone},
    task: {
      id: $t.id, taskNo: $t.taskNo, templateId: $t.templateId,
      description: "新的描述内容",
      level: ($t.level // ""), serviceType: ($t.serviceType // ""),
      serviceContent: ($t.serviceContent // ""),
      planStartTime: $t.planStartTime, planEndTime: $t.planEndTime,
      serviceProviderQualification: ($t.serviceProviderQualification // ""),
      engineerQualification: ($t.engineerQualification // []),
      taskEstimatedMileage: ($t.taskEstimatedMileage // 0),
      attachment: ($t.attachment // []), products: ($t.products // []),
      cardForms: ($t.cardForms // []), attribute: ($t.attribute // {}),
      customer: {id: $t.customer.id},
      linkman: {id: $t.tlmId, name: $t.tlmName, phone: $t.tlmPhone},
      address: ($t.taddress // {}), tick: 0
    },
    tick: 0
  }
' /tmp/task-detail.json | shb-cli task update submit --data "$(cat /dev/stdin)"
```

## 快捷 flags 模式

适合只改少量字段且不方便构造完整 JSON 的场景。CLI 会自动先拉取工单详情作为基础再提交，**但如果工单包含复杂自定义字段，仍建议使用 `--data` 模式**。

```bash
shb-cli task update submit \
  --task-id <taskId> \
  --description "新描述" \
  --level high
```

## 完整 JSON 结构说明

> ⚠️ **`task.attribute` 必须存在（可为空对象 `{}`）**，为 `null` 时后端返回 `500002 系统错误`。  
> ⚠️ `customer`/`linkman`/`address` 需同时出现在**顶层**和 **`task` 内部**，两处均需填写。  
> ⚠️ `planStartTime` / `planEndTime` 为毫秒时间戳（数字类型，非字符串）。

```json
{
  "address": {},
  "customer": { "id": "客户UUID" },
  "eventId": "",
  "flow": "",
  "linkman": { "id": "联系人UUID", "name": "姓名", "phone": "电话" },
  "task": {
    "id": "工单UUID",
    "taskNo": "TXR79326060030",
    "templateId": "工单类型UUID",
    "description": "工单描述",
    "level": "",
    "serviceType": "",
    "serviceContent": "",
    "planStartTime": 1782278040000,
    "planEndTime": 1782280800000,
    "serviceProviderQualification": "",
    "engineerQualification": [],
    "taskEstimatedMileage": 0,
    "attachment": [],
    "products": [],
    "cardForms": [],
    "attribute": {},
    "customer": { "id": "客户UUID" },
    "linkman": { "id": "联系人UUID", "name": "姓名", "phone": "电话" },
    "address": {},
    "tick": 0
  },
  "tick": 0
}
```

## 支持的快捷 flags

| 分类 | Flags |
|------|-------|
| 工单（必填） | `--task-id` |
| 工单 | `--level`, `--service-type`, `--service-content`, `--description`, `--plan-time`, `--plan-start-time`, `--plan-end-time`, `--engineer-qualification`, `--provider-qualification`, `--estimated-mileage` |
| 客户 | `--customer-id`, `--customer-name` |
| 地址 | `--country`, `--province`, `--city`, `--district`, `--detail-address`, `--latitude`, `--longitude` |
| 联系人 | `--linkman-id`, `--linkman-name`, `--linkman-phone` |
| 关联 | `--flow`, `--event-id`, `--event-no`, `--tick` |
| 自定义字段 | `--custom-fields`（JSON 字符串，合并进 `task.attribute`） |
| 输入（推荐） | `--data`（内联完整 JSON）, `--file`（本地 JSON 文件） |

## 注意

- **更新后必须回查核实**：命令无报错、或输出里的成功提示**都不代表字段真的变了**，后端可能接受请求却未改值（字段名写错、只读字段、值被静默丢弃、未传字段被清空等）。提交后用 `task detail --id <taskId>` 重新查询该工单，确认目标字段已是新值，再告诉用户完成；若仍是旧值或无法确认，如实说明实际当前值/未确认，不要声称成功。
- 如果有错误，请友好地提示错误信息，不要切换操作类型。
