# @apigo.cc/base - AI 逻辑操作说明书 (示例驱动)

本库是基于 `@apigo.cc/state` 增强的 UI 原子库，提供遵循 Bootstrap 5.3 规范的高阶业务组件。

---

## 1. 快速集成 (Quick Start)

### CDN 集成 (自包含 UMD，锁定版本号，无需引入 Bootstrap CSS)
```html
<!-- 依赖核心库 -->
<script src="https://cdn.jsdelivr.net/npm/@apigo.cc/state@1.0.15/dist/state.min.js"></script>
<!-- Bootstrap 集成引擎 (自包含 CSS 注入) -->
<script src="https://cdn.jsdelivr.net/npm/@apigo.cc/bootstrap@1.0.5/dist/bootstrap.min.js"></script>
<!-- 本组件库 -->
<script src="https://cdn.jsdelivr.net/npm/@apigo.cc/base@1.0.10/dist/base.min.js"></script>
```

### ESM 模块引入
```javascript
import { HTTP, UI, AutoForm, State } from '@apigo.cc/base'
```

---

## 2. 组件超能力示例 (Mega Examples)

### 2.1 声明式数据组件 (`<API>`)
```html
<API id="userSearchApi" auto 
     $request='{
         "url": "/api/users/search", 
         "method": "POST", 
         "data": { "keyword": State.searchKey }
     }'
     $onresponse="console.log('加载成功，响应对象:', event.detail); State.userList = event.detail.result"
     $onerror="UI.toast('加载失败：' + event.detail.message, { type: 'danger' })">
</API>

<script>
  // 手动调用 API 示例 (适合动态触发/事后赋值场景)
  async function forceReload() {
      try {
          // do() 返回 Promise<ResponseObject>。传入 noui: true 屏蔽全局 UI 弹窗报错。
          const resp = await userSearchApi.do({ noui: true });
          console.log("手动加载完成，结果:", resp.result);
      } catch (err) {
          console.error("请求失败", err);
      }
  }
</script>
```
* **AI 核心要点**：
  * **请求响应结构 (ResponseObject)**：
    `{ ok: Boolean, status: Number, headers: Object, responseType: 'json'|'binary'|'text', result: Any, error: String|null }`
  * 深度监听 `request` 任何字段的改变自动触发请求（微任务防抖）。`response` 事件为 `bubbles: false`，`error` 为 `bubbles: true`。

---

### 2.2 万能表单与内嵌控件 (`<AutoForm>`)
```html
<script>
  // 1. 预先确定表单 Schema (合并了所有扩展控件配置)
  const employeeFormSchema = [
      { name: 'name', label: '姓名', type: 'text', setting: { required: true } },
      { 
          name: 'joinDate', 
          label: '入职周期', 
          type: 'DatePicker',                 // 内置日期范围选择控件
          setting: { rangeEnd: 'leaveDate' }   // 影子字段绑定为 leaveDate
      },
      { name: 'color', label: '工位颜色', type: 'ColorPicker' },       // 内置颜色控件
      { name: 'avatarIcon', label: '头像图标', type: 'IconPicker' },   // 内置图标控件
      { name: 'skills', label: '专业技能', type: 'TagsInput' },        // 内置多标签控件
      { 
          name: 'role', 
          label: '角色', 
          type: 'select', 
          options: [{ label: '管理员', value: 'admin' }, { label: '员工', value: 'staff' }],
          placeholder: '请选择角色...'
      },
      { 
          name: 'status', 
          label: '状态', 
          type: 'checkbox', 
          options: ['在职', '离职'], 
          if: "this.data.age > 18"            // 仅在 age > 18 时渲染，this 访问 AutoForm 实例
      },
      { name: 'notify', label: '启用通知', type: 'switch' }
  ];
</script>

<!-- 2. HTML 声明式属性绑定 schema 状态，且绑定接口 API 实例 -->
<AutoForm id="employeeForm" 
          vertical 
          $state.schema="employeeFormSchema"
          $api="saveEmployeeApi" 
          $onresponse="UI.toast('保存成功！')">
</AutoForm>

<script>
  // 3. 数据层回显/事后赋值操作 (使用 Object.assign 保证绑定的 Proxy 响应式链路不丢失)
  Object.assign(employeeForm.state.data, {
      name: '张三',
      joinDate: '2026-06-01',
      leaveDate: '2026-06-30',
      color: '#ff0000',
      avatarIcon: 'person',
      skills: ['Vue', 'React'],
      role: 'staff',
      notify: true
  });
</script>
```
* **AI 核心要点**：
  * 容器属性：`vertical` (垂直排列)、`inline` (无边框流式行内布局)、`nobutton` (隐藏底部默认按钮)。
  * **表单数据操作红线**：禁止对 `form.state.data` 或 `form.data` 执行覆盖式重新赋值，必须使用 `Object.assign`。

---

### 2.3 增强列表组件 (`<List>`)

列表有三类布局模式，分别有不同的数据结构关联，均推荐在 HTML 中声明绑定：

#### 模式一：普通扁平列表 (`mode="normal"`)
* **关联逻辑**：直接渲染一维数组项。
* **数据结构**：
  ```javascript
  const userList = [
      { id: '1', label: '小明', summary: '前端开发' },
      { id: '2', label: '小红', summary: '产品经理' }
  ];
  ```
* **HTML 写法**：
  ```html
  <List mode="normal" $list="userList" $onitemclick="console.log(event.detail.item)"></List>
  ```

#### 模式二：分组列表 (`mode="group"`)
* **关联逻辑**：`list` 的项通过 `group` 字段去匹配 `groups` 数组中的 `id` 字段。
* **数据结构**：
  ```javascript
  const deptGroups = [
      { id: 'devGroup', label: '研发中心', summary: '共 5 人' },
      { id: 'hrGroup', label: '人力资源', summary: '共 2 人' }
  ];
  const groupUserList = [
      { id: '1', label: '小明', group: 'devGroup' },
      { id: '2', label: '小红', group: 'hrGroup' }
  ];
  ```
* **HTML 写法**：
  ```html
  <List mode="group" $list="groupUserList" $state.groups="deptGroups"></List>
  ```

#### 模式三：树形可折叠列表 (`mode="tree"`) —— 超级示例
* **关联逻辑**：通过每项的 `parent` 关联父项的 `id` 属性，根项的 `parent` 设为空字符串 `''`。
* **数据结构**（内置 `_itemHeight` 优化虚拟滚动高度测量）：
  ```javascript
  const deptTreeList = [
      { id: '1', label: '总经办', parent: '', _itemHeight: 40 },
      { id: '2', label: '研发部', parent: '1', _itemHeight: 40 },
      { id: '3', label: '开发组', parent: '2', _itemHeight: 40 }
  ];
  ```
* **HTML 写法**：
  ```html
  <List id="orgTreeList" 
        mode="tree" 
        fast 
        collapsible 
        auto-select
        class="overflow-auto border"
        style="height: 400px;"
        $list="deptTreeList"
        $onitemclick="console.log('点击节点:', event.detail.item, '全局绝对索引:', event.detail.index)">
        
        <!-- 自定义单项右侧动作区域 -->
        <template slot-id="item">
            <span class="fw-semibold text-primary" $text="item.label"></span>
            <div slot-id="item-actions">
                <button class="btn btn-sm btn-link py-0 bi bi-plus-circle" onclick="addNode(item)"></button>
            </div>
        </template>
  </List>
  ```
* **AI 核心要点**：
  * **属性默认值**：当数据结构符合默认字段命名（`id`, `label`, `summary`, `parent`, `group`）时，**无须填写**任何映射属性（如 `idfield`, `labelfield`, `parentfield` 等），实际编写代码时应当将其省略。
  * 虚拟滚动 (`fast`) 强制容器必须声明为 `overflow-auto` 类。

---

### 2.4 导航组件 (`<Nav>`)
```html
<script>
  // 1. 预先确定品牌与菜单数据
  const myBrand = { icon: 'shield-lock', label: '安全控制台' };
  const myNavList = [
      { type: 'button', name: 'dashboard', label: '仪表盘', icon: 'speedometer' },
      { 
          type: 'dropdown', 
          name: 'settings', 
          label: '系统设置', 
          icon: 'gear',
          list: [
              { type: 'button', name: 'profile', label: '个人信息', icon: 'person' },
              { type: 'switch', name: 'darkMode', label: '暗黑模式', icon: 'moon', bind: LocalStorage, name: 'darkMode' }
          ]
      },
      { type: 'fill' },
      { type: 'button', name: 'logout', label: '退出登录', icon: 'box-arrow-right', noselect: true }
  ];
</script>

<!-- 2. HTML 声明式属性绑定 -->
<Nav id="sidebarNav" 
     vertical 
     $state.brand="myBrand" 
     $state.list="myNavList" 
     $onnav="console.log('导航点击:', event.detail.item)">
</Nav>
```
* **AI 核心要点**：
  * 常规导航项被点击时（且 `noselect` 不为 true），会自动更新全局 `Hash.nav = item.name`。

---

### 2.5 拖拽改变大小组件 (`<Resizer>`)
```html
<div class="d-flex" style="height: 300px;">
    <div id="leftPanel" style="width: 200px;" class="bg-light">侧边栏</div>
    <!-- 拖拽调节器，默认 target 为前一个兄弟节点 -->
    <Resizer target="leftPanel" 
             min="100" 
             max="400"
             $onresizing="console.log('拖动尺寸:', event.detail.newSize)"
             $change="State.leftPanelWidth">
    </Resizer>
    <div class="flex-fill">内容区</div>
</div>
```
* **AI 核心要点**：
  * `resizing` 与 `resize` 事件的 `detail` 结构均为 `{ oldSize: Number, newSize: Number }`；`change` 事件的 `detail` 为 `newSize` 像素数字。

---

## 3. 网络与交互工具集 (`HTTP` & `UI`)

### 3.1 HTTP 请求工具 (`HTTP`)
```javascript
// 支持 HTTP.get, HTTP.post, HTTP.put, HTTP.delete, HTTP.head
const resp = await HTTP.post({
    url: '/api/user/save',
    data: { name: 'Alice', file: avatarFile },
    timeout: 5000
});
```
* **返回值 `ResponseObject` 结构**：
  * `ok` (Boolean): 状态码是否在 200-299。
  * `status` (Number): HTTP 状态码。
  * `headers` (Object): 响应头键值对。
  * `responseType` (String): `'json' | 'binary' | 'text'`。
  * `result` (Any): 成功后的解析结果。
  * `error` (String | null): 失败的错误描述。
* **数据自动转换**：若 `data` 内包含 `File`/`Blob`，自动转为 `FormData` 且清除 Content-Type；普通对象自动序列化为 JSON 并添加 `application/json`。

### 3.2 交互工具 (`UI`)
* **`UI.showDialog({ title, message, buttons, type })`**
  * **返回值**：`Promise<Number>`。点击按钮返回其索引值 (从 `1` 开始)，点击关闭或取消返回 `0`。
  * **参数**：`type` 可以为 `'primary'|'danger'|'warning'|'success'` 控制主题色；`message` 支持 HTML。
* **`UI.alert(message, options)`**
  * **返回值**：`Promise<Boolean>`（点击关闭按钮返回 `false`）。
* **`UI.confirm(message, options)`**
  * **返回值**：`Promise<Boolean>`。点击“确认”返回 `true`，点击“取消”或关闭返回 `false`。
* **`UI.toast(message, options)`**
  * **返回值**：`void`。`options.delay` 为自动消失延迟毫秒（`0` 代表不消失）。可以通过传入 `buttons: ['选项1']` 按钮提供交互，点击后在实例 `result` 上保存索引。
* **`UI.toastConfirm(message, options)`**
  * **返回值**：`Promise<Boolean>`。在 Toast 中提供单确认按钮，点击确认返回 `true`，否则返回 `false`。

---

## 4. 开发红线 (Constraints)

1. **表单数据操作红线**：严禁直接覆盖表单的 `state.data` 或 `data` 对象（如 `form.data = {}`）。这会切断与内部 Proxy 的响应式链路。必须使用 `Object.assign(form.state.data, newData)`。
2. **列表布局红线**：开启虚拟滚动（`fast`）时，容器必须包含 `overflow-auto` 类。
3. **指令 DOM 保护**：严禁使用原生 DOM API 直接修改由 `$each`、`$if` 或组件渲染指令生成的 DOM 节点。所有 DOM 状态的变化应当完全通过修改与之绑定的底层 `State` 属性驱动。
4. **退出拦截约束**：在全局配置有 `State.exitBlocks > 0` 时，框架将强行拦截并警告任何刷新/关闭页面的行为。
