# Swing SDK Web Vue3 — 模块参考

> 详细 API 参考文档。按模块组织，供 AI Agent 按需查阅。

---

## 目录

- [1. Core (`@swing/core-vue3`)](#1-core-core-vue3)
- [2. System (`@swing/system-vue3`)](#2-system-system-vue3)
- [3. Flow (`@swing/flow-vue3`)](#3-flow-flow-vue3)
- [4. GDS (`@swing/gds-vue3`)](#4-gds-gds-vue3)
- [5. Notice (`@swing/notice-vue3`)](#5-notice-notice-vue3)
- [6. OSS (`@swing/oss-vue3`)](#6-oss-oss-vue3)
- [7. IOT (`@swing/iot-vue3`)](#7-iot-iot-vue3)
- [8. Widget (`@swing/widget-vue3`)](#8-widget-widget-vue3)
- [9. 跨平台 HTTP 适配器](#9-跨平台-http-适配器)

---

## 1. Core (`core-vue3`)

### 导入

```typescript
import {
  ArrayUtils, BlobUtils, CommonUtils, DateTimeUtils, DateUtils,
  DomUtils, EnvUtils, ExcelUtils, FileUtils, NumberUtils,
  StringUtils, TreeUtils, TypeUtils, ObjectUtils, UrlUtils,
  TokenUtils, LocalStorageUtils, RequestUtils, KeyCodeUtils,
  ColorUtils, EnumUtils,
  withInstall, installAllComponents,
  // Hooks
  useCarousel, useDiffCarousel, useDataVScrollBoard,
  useScanCodeGun, useFetchPaging, useFetchList,
  // Types
  Model, DomainModel, RestResponse, QueryParameter, PageInfo,
  HookBaseOptions, MessageHandler, FormMode, TreeNode,
  FetchOptions, MessageData, FieldNames,
} from '@swing/core-vue3'
```

### 类型工具（`type.ts` — 18 个 TS 类型体操）

```typescript
import {
  GetOptional<T>, GetRequired<T>, ValueOf<T>, GetTupleValueUnion<T>,
  GetObjectKeyPath<T>, Data, CommonProps<T>,
  FocusEventHandler, MouseEventHandler, KeyboardEventHandler,
  CompositionEventHandler, ClipboardEventHandler, ChangeEventHandler,
  WheelEventHandler, ChangeEvent, CheckboxChangeEvent, EventHandler,
} from '@swing/core-vue3'
```

通用（无环境依赖），用于组件 Props 定义和类型推断。

### 工具函数（`utils/` — 22 个文件）

> 环境分类详见 SKILL.md → "Core 包环境约束"。

| 命名空间 | 主要函数 | 用途 | 环境 |
|----------|----------|------|
| 命名空间 | 主要函数 | 用途 | 环境 |
|----------|----------|------|------|
| `ArrayUtils` | `average`, `groupBy`, `toMap`, `arrayDistinct`, `deepCopy` | 数组操作 | 通用 |
| `BlobUtils` | `toWindowUrl` | Blob 转 URL | 浏览器 |
| `ColorUtils` | `stringToColor`, `getContrastColor` | 颜色处理 | 通用 |
| `CommonUtils` | `debounce`, `throttle`, `copyToClipboard`, `isDarkMode` | 通用工具 | 浏览器 |
| `DateTimeUtils` | `getTimeRange`, `getEarliestAndLatestDateTime` | 日期时间范围 | 通用 |
| `DateUtils` | `getDayChinese`, `getWeekOfYear`, `getDayInfo`, `getDayDiff` | 日期处理 | 通用 |
| `DomUtils` | `addClass`, `removeClass`, `observerDomResize` | DOM 操作 | 浏览器 |
| `EnvUtils` | `isPc`, `getUserAgentInfo`, `isBrowser`, `isNodeJs` | 环境检测 | 需适配器 |
| `EnumUtils` | `createEnumHelpers` | 枚举转 label/value | 通用 |
| `ExcelUtils` | `jsonToExcel` | 导出 Excel | 通用 |
| `FileUtils` | `fileDownload`, `dataURLtoBlob`, `blobToDataURL` | 文件操作 | 浏览器 |
| `KeyCodeUtils` | `KeyCode` 常量, `isCharacterKey` | 键盘码 | 浏览器 |
| `LocalStorageUtils` | `localGet`, `localSet`, `localClear` | 本地存储 | 浏览器 |
| `NumberUtils` | `numberToPercent`, `decimalAdjust` | 数字处理 | 通用 |
| `ObjectUtils` | `deepCopy`, `deepMerge`, `omit`, `flattenObject` | 对象操作 | 通用 |
| `RequestUtils` | `SwingRequest` 类 | HTTP 请求 | 需适配器 |
| `StringUtils` | `toCamelCase`, `toSnakeCase`, `parseTemplate` | 字符串处理 | 通用 |
| `TokenUtils` | `isValid`, `isExpired` | JWT Token | 浏览器 |
| `TreeUtils` | `arrayToTree`, `getFlatList`, `findParentNode` | 树形数据 | 通用 |
| `TypeUtils` | `isString`, `isNumber`, `isObject`, `isArray` | 类型判断 | 通用 |
| `UrlUtils` | `getUrlParams`, `isUrl` | URL 处理 | 浏览器 |

### Hooks 签名

```typescript
// 等间距轮播
useCarousel(milliseconds?: number, stateList?: any[]): { current: Ref<any> }

// 不等间距轮播
useDiffCarousel(stateList?: any[]): { current, previous, next, start, destroy }

// DataV 滚动高亮
useDataVScrollBoard(): { renderDataVScrollBoard: (data: any[], index: number) => any }

// 扫码枪
useScanCodeGun(options: { onChange: (code: string) => void }): void

// 分页查询（可直接传入 request 函数）
useFetchPaging<T, Q = any>(
  request: (params: QueryParameter & Q) => Promise<RestResponse<PageInfo<T>>>,
  context?: any,
  options?: FetchOptions<T, Q>
): { reset: () => void; reload: () => void; context: any }

// 列表查询
useFetchList<T, Q = any>(
  request: (params: QueryParameter & Q) => Promise<RestResponse<T[]>>,
  context?: any,
  options?: FetchOptions<T, Q>
): { clear: () => void; reload: () => void; context: any }

interface FetchOptions<T, Q> {
  onSuccess?: (result: T[]) => void
  onRequestError?: (e: Error) => void
  autoFetch?: boolean
  showInfo?: { success: (msg: MessageData) => void; error: (msg: MessageData) => void }
  onValidateParams?: (params: QueryParameter & Q, next: () => void) => Promise<any> | void
  convertData?: (result: T[]) => any[]
}
```

### SwingRequest

```typescript
// 创建实例
import { RequestUtils } from '@swing/core-vue3'
const request = new RequestUtils.SwingRequest(baseURL: string, prefix?: string)

// 通用请求方法
request.instancePromise<R>(config: AxiosRequestConfig): Promise<RestResponse<R>>

// 自动处理: JWT token 注入、401/403 跳转、blob 响应
```

### VuePlugin

```typescript
// 注册单个组件
import { withInstall } from '@swing/core-vue3'
export default withInstall(MyComponent)

// 注册全部 widget 组件到 Vue
import { installAllComponents } from '@swing/widget-vue3'
app.use(installAllComponents)
```

---

## 2. System (`system-vue3`)

### 导入

```typescript
import {
  // Services（命名空间，向后兼容）
  AccountService, OrganizationService, SiteService, UserService, RoleService,
  // Services（ES Module 直接具名导入，可混用）
  pagingAccount, createAccount, pagingUser, createUser, getOrganization,
  // Request
  systemRequest,
  // Hooks
  useUserList, useAccess, useAccountSaveOrUpdate,
  useOrganization, useOrganizationTree,
  useSiteList, useLabelDesignerFetch,
  // Types
  Organization, Action, Route, DynamicRoute, User, Role, Site, Account, Tenant,
} from '@swing/system-vue3'

// 两种风格等价：
AccountService.pagingAccount(params)
pagingAccount(params)
```

### Hooks

```typescript
// 用户列表
useUserList(options?: HookBaseOptions, queryParams?: QueryParameter & { siteId?: string; orgId?: string; roleId?: string })
// → { list, reload, data, loading }

// 权限控制
useAccess(initialState?: { permissions?: string[]; roles?: string[] }, config?: { mock?: boolean })
// → { isAdmin, routeFilter, hasTabPermission, hasButtonPermission, filterTabsPermission }

// 账户密码修改
useAccountSaveOrUpdate()
// → { modifyPassword(params: { oldPwd: string; newPwd: string }): Promise<RestResponse>, submitting }

// 组织列表
useOrganization(options?: HookBaseOptions)
// → { fetchList, data, loading }

// 组织树
useOrganizationTree(options?: HookBaseOptions, queryParams?: QueryParameter)
// → { fetchTreeNode, data, loading }

// 站点列表
useSiteList(options?: HookBaseOptions)
// → { list, data, loading }

// 标签设计器
useLabelDesignerFetch(options?: HookBaseOptions, queryParams?: QueryParameter)
// → { fetch, fetchCode, data, loading }
```

### Service API 方法表

| Service | 方法 | 说明 |
|---------|------|------|
| `AccountService` | `pagingAccount`, `listAccount`, `getAccount`, `createAccount`, `updateAccount`, `removeAccount`, `batchRemoveAccount`, `resetPassword`, `modifyPassword` | 账户 CRUD |
| `OrganizationService` | `pagingOrganization`, `listOrganization`, `getOrganization`, `getOrganizationAsTree`, `createOrganization`, `updateOrganization`, `removeOrganization`, `rebuildingRelationToUser`, `disassociateToUser`, `listRelatedUser` | 组织 CRUD |
| `UserService` | `pagingUser`, `listUser`, `getUser`, `createUser`, `updateUser`, `removeUser`, `batchRemoveUser`, `login`, `getPersonalInfo`, `getAuthorizedRoute`, `getAuthorizedRouteTree`, `getAllRouteTree`, `getAuthorizedAction`, `buildRelationToOrganization`, `listRelatedOrganization` | 用户 CRUD + 认证 |
| `SiteService` | `pagingSite`, `listSite`, `getSite`, `listRelatedUser` | 站点 CRUD |
| `RoleService` | `pagingRole`, `listRole`, `getRole`, `createRole`, `copyRole`, `updateRole`, `removeRole`, `batchRemoveRole`, `buildRelationToUser`, `buildRelationToAction`, `buildRelationToRoute`, `buildRelationToResource`, `listRelatedUser`, `listRelatedAction`, `listRelatedRoute`, `listRelatedResource` | 角色 CRUD + 权限分配 |

---

## 3. Flow (`flow-vue3`)

### 导入

```typescript
import {
  // Hooks
  useCategoryFetch, useCategoryList, useCategoryPagination,
  useCategoryRemove, useCategorySaveOrUpdate,
  useModelFetch, useModelList, useModelPagination,
  useModelRemove, useModelSaveOrUpdate, useModelRelease, useModelEnabled,
  useInstanceFetch, useInstanceList, useInstanceShowProgressList,
  useInstanceStatistics, useInstancePagination,
  useInstanceRemove, useInstanceSaveOrUpdate,
  useNodeInstanceFetch, useNodeInstanceList, useNodeInstanceSaveOrUpdate,
  useTaskComplete, useTaskRollback,
  // Services（命名空间 + 直接具名）
  CategoryService, pagingCategory, createCategory,
  ModelService, InstanceService, ApprovalRecordService, TaskService,
  // Enums（全部 18 个，也可按需导入）
  ModelTypeEnum, WorkflowStatusEnum, WorkflowNodeStatusEnum,
  CountersignModeEnum, AssignedTypeEnum, ConditionCompareEnum,
  // Types
  ProcessNode, Model, Instance, Category, ApprovalRecord, TaskInfo,
} from '@swing/flow-vue3'
```

### Hooks 签名

```typescript
// === Category ===
useCategoryFetch(options?: HookBaseOptions): { fetch(id: string): Promise<RestResponse>, data, loading }
useCategoryList(options?: HookBaseOptions, params?): { list, data, loading }
useCategoryPagination(options?: HookBaseOptions): { paging(params?), data, total, loading }
useCategoryRemove(): { remove(id: string): Promise<boolean>, submitting }
useCategorySaveOrUpdate(): { add(data): Promise<RestResponse>, update(id, data): Promise<RestResponse>, submitting }

// === Model ===
useModelFetch(options?: HookBaseOptions): { fetch(id: string), data, loading }
useModelList(options?, params?): { list, data, loading }
useModelPagination(options?): { paging(params?), data, total, loading }
useModelRemove(): { remove(id), batchRemove(ids), submitting }
useModelSaveOrUpdate(): { add(data), update(id, data), submitting }
useModelRelease(): { release(id: string): Promise<RestResponse>, submitting }
useModelEnabled(): { enabled(id: string): Promise<RestResponse>, submitting }

// === Instance ===
useInstanceFetch(options?): { fetch(id), data, loading }
useInstanceList(options?, params?): { list, data, loading }
useInstanceShowProgressList(options?): { list(params?), data, loading }
useInstanceStatistics(options?): { getStatistics(params?): Promise<any>, data, loading }
useInstancePagination(options?): { paging(params?), data, total, loading }
useInstanceRemove(): { remove(id), submitting }
useInstanceSaveOrUpdate(): { add(data), submitting }

// === ApprovalRecord (NodeInstance) ===
useNodeInstanceFetch(options?): { fetch(id?), data, loading }
useNodeInstanceList(options?): { list(params?), data, loading }
useNodeInstanceSaveOrUpdate(): { add(data), update(id, data), submitting }

// === Task ===
useTaskComplete(): { complete(taskId: string, data?): Promise<RestResponse>, submitting }
useTaskRollback(): { rollback(taskId: string): Promise<RestResponse>, submitting }
```

### 全部枚举（18 个，定义在 `enum.ts` 中）

| 枚举 | 说明 | 成员 |
|------|------|------|
| `LogicEnum` | 条件组逻辑 | `OR`, `AND` |
| `ConditionCompareEnum` | 字段比较方式 | `EQUAL`, `NOT_EQUAL`, `IS_NULL`, `LESS_THAN`, `GREATER_THAN`, `START_WITH`, `CONTAIN` 等 16 个 |
| `ModelTypeEnum` | 流程节点类型 | `ROOT`, `APPROVAL`, `CC`, `CONDITIONS`, `CONDITION`, `CONCURRENTS`, `CONCURRENT`, `DELAY`, `TRIGGER`, `END` |
| `WorkflowStatusEnum` | 流程实例状态 | `UNSUBMITTED`, `SUBMITTED`, `PROCESSING`, `REJECTED`, `PASSED` |
| `WorkflowNodeStatusEnum` | 流程节点状态 | `PASSED`, `REJECTED`, `PROCESSING`, `PENDING` |
| `CountersignModeEnum` | 多人审批方式 | `NEXT`（会签顺序）, `AND`（会签并行）, `OR`（或签） |
| `AssignedTypeEnum` | 审批人指定方式 | `ASSIGN_USER`, `SELF_SELECT`, `LEADER_TOP`, `LEADER`, `ROLE`, `SELF`, `FORM_USER`, `FORM_DEPARTMENT`, `DEPARTMENT` |
| `ApproverBumpPeopleEnum` | 审批人与提交人相同时 | `AUTOMATICALLY_PASS`, `SELF_APPROVAL` |
| `PreviousBumpPeopleEnum` | 审批人与上一节点相同时 | `AUTO_PASS`, `CONTINUE` |
| `RefuseTypeEnum` | 驳回策略 | `TO_END`, `TO_BEFORE`, `TO_NODE` |
| `NobodyHandlerEnum` | 审批人为空策略 | `TO_PASS`, `TO_REFUSE`, `TO_ADMIN`, `TO_USER` |
| `CommentTypeEnum` | 评论类型 | `NORMAL`, `REBACK`, `REJECT`, `DELEGATE`, `ASSIGN`, `STOP`, `AUTO_PASS`, `AUTO_REBACK`, `AUTO_REJECT` |
| `LeaderTopEndConditionEnum` | 主管截止条件 | `FIRST`, `LAST`, `SPECIFY` |
| `NotifierTypeEnum` | 抄送人类型 | `ONESELF`, `DESIGNATED_PERSON`, `SELF_SELECTION` |
| `NotifierMessageTypeEnum` | 抄送推送源 | `EMAIL`, `APPLICATION`, `SMS`, `MOBILE` |
| `OrganizationMatchRuleEnum` | 部门分配规则 | `LEADER`, `MEMBER` |
| `LeaderExtractRuleEnum` | 主管提取规则 | `UP`, `EMPTY` |
| `MultipleExtractRuleEnum` | 多部门提取规则 | `ALL`, `SPECIFY` |

---

## 4. GDS (`gds-vue3`)

### 导入

```typescript
import {
  AreaService, DictionaryService, CalendarService,
  DictionaryGroupService, EncodeRuleService,
  EncodeRuleConfigurationService, CodingGenerateService,
  gdsRequest,
  useDictionaryFetch, useDictionaryList, useDictionaryPagination,
  useDictionaryRemove, useDictionarySaveOrUpdate,
  useDictionaryGroupFetch, useDictionaryGroupList, useDictionaryGroupPagination,
  useDictionaryGroupRemove, useDictionaryGroupSaveOrUpdate,
  useCalendarFetch, useCalendarList, useCalendarPagination,
  useCalendarRemove, useCalendarSaveOrUpdate,
  useAreaFetch, useAreaSync,
  useEncodeRuleFetch, useEncodeRuleList, useEncodeRulePagination,
  useEncodeRuleRemove, useEncodeRuleCreateOrUpdate,
  useEncodeRuleConfigurationFetch, useEncodeRuleConfigurationList,
  useEncodeRuleConfigurationPagination, useEncodeRuleConfigurationRemove,
  useEncodeRuleConfigurationCreateOrUpdate,
  useCodingGenerate,
} from '@swing/gds-vue3'
```

### Hooks 签名

```typescript
// === Dictionary 数据字典 ===
useDictionaryFetch(options?: HookBaseOptions, code?: string)
// → { fetch(code: string), data: Dictionary, loading, dictMap, getDictItem(groupCode) }
// 典型用途: 根据字典 code 获取字典项列表

useDictionaryList(options?: HookBaseOptions)
// → { list(params?: DictionaryQueryParameter), item: Dictionary[], loading }
useDictionaryPagination(options?, params?): { paging, data, total, loading }
useDictionaryRemove(): { remove(code: string): Promise<boolean>, submitting }
useDictionarySaveOrUpdate(): { add(data), update(code, data), submitting }

// === DictionaryGroup 字典分组 ===
useDictionaryGroupFetch(options?: { cacheable?, deps: { guid? } })
// → { fetch(guid: string), reload, data, loading }

useDictionaryGroupList(options?): { list, items, reload, loading }
useDictionaryGroupPagination(options?, params?): { paging, data, total, loading }
useDictionaryGroupRemove(): { remove(guid), batchRemove(ids), submitting }
useDictionaryGroupSaveOrUpdate(): { add(data), batchAdd(data[]), update(guid, data), submitting }

// === Calendar 工作日历 ===
useCalendarFetch(options?): { fetch(date: string), data, loading }
useCalendarList(options?, params?): { list, loading }
useCalendarPagination(options?): { paging, data, total, loading }
useCalendarRemove(): { remove(date: string): Promise<boolean>, submitting }
useCalendarSaveOrUpdate(): { add(data), batchAdd(data[]), update(date, data), submitting }

// === Area 行政区划 ===
useAreaFetch(options?: HookBaseOptions): { fetch(), data: Area[], loading, reload }
useAreaSync(options?: { message?: MessageHandler }): { sync(): Promise<boolean> }

// === EncodeRule 编码规则 ===
useEncodeRuleFetch(options?): { fetch(id: string), data, loading }
useEncodeRuleList(options?, params?): { list, item, loading }
useEncodeRulePagination(options?, params?): { paging, data, total, loading }
useEncodeRuleRemove(): { remove(guid), batchRemove(ids), submitting }
useEncodeRuleCreateOrUpdate(options?): { add(data), batchAdd(data[]), update(id, data), submitting }

// === EncodeRuleConfiguration 编码规则配置 ===
useEncodeRuleConfigurationFetch(options?): { fetch(id), data, loading }
useEncodeRuleConfigurationList(options?, params?): { list, item, loading }
useEncodeRuleConfigurationPagination(options?, params?): { paging, data, total, loading }
useEncodeRuleConfigurationRemove(): { remove(guid), batchRemove(ids), submitting }
useEncodeRuleConfigurationCreateOrUpdate(options?): { add, batchAdd, update, submitting }

// === CodingGenerate 编码生成 ===
useCodingGenerate(options?: CodingRuleOptionType)
// → { getCodeRule(params?: EncodeRuleQueryParameter), reload, data: string, loading }
// 典型用途: 根据编码规则配置实时生成编码值
```

---

## 5. Notice (`notice-vue3`)

### 导入

```typescript
import {
  MessageService, MessageReceiveService,
  MessageSubjectService, MessageTemplateService,
  noticeRequest,
  useMessageCreateOrUpdate, useMessageFetch, useMessageList,
  useMessagePagination, useMessageRemove,
  useMessageReceiveFetch, useMessageReceiveList, useMessageReceivePagination,
  useMessageReceiveCreateOrUpdate, useMessageReceiveRemove,
  useMessageSubjectCreateOrUpdate, useMessageSubjectFetch,
  useMessageSubjectList, useMessageSubjectPagination, useMessageSubjectRemove,
  useMessageTemplateCreateOrUpdate, useMessageTemplateFetch,
  useMessageTemplateList, useMessageTemplatePagination, useMessageTemplateRemove,
  // Enums
  MessageType, MessageContentType, RecipientTypeEnum,
  // Types
  Message, MessageDTO, MessageVO, SendMessagePO,
  MessageReceive, MessageSubject, MessageTemplate,
} from '@swing/notice-vue3'
```

### Hooks 签名

```typescript
// === Message 消息内容 ===
useMessageCreateOrUpdate(options?: { message?: MessageHandler })
// → { add(data: MessageDTO), batchAdd(data[]), send(sendMessagePO), sendBatch(sendMessages[]), read(ids: string[]), submitting }
useMessageFetch(options?, messageId?): { fetch(id), contains(id), countMessage(params?), data, contain, count, loading }
useMessageList(options?): { list(params?), items, loading }
useMessagePagination(options?): { paging(params?), pageInfo, loading }
useMessageRemove(): { remove(guid), batchRemove(ids), submitting }

// === MessageReceive 消息接收 ===
useMessageReceiveFetch(options?, id?): { fetch(id), contains(id), countMessageReceive(params?), data, loading }
useMessageReceiveList(options?): { list(params?), items, loading }
useMessageReceivePagination(options?): { paging(params?), pageInfo, loading }
useMessageReceiveCreateOrUpdate(): { add(data), batchAdd(data[]), update(id, data), submitting }
useMessageReceiveRemove(): { remove(guid), batchRemove(ids), submitting }

// === MessageSubject 消息主题 ===
useMessageSubjectCreateOrUpdate(): { add(data), batchAdd(data[]), update(id, data), submitting }
useMessageSubjectFetch(options?): { fetch(id), subjectCodeExist(params?), data, loading }
useMessageSubjectList(options?): { list(params?), items, loading }
useMessageSubjectPagination(options?): { paging(params?), pageInfo, loading }
useMessageSubjectRemove(): { remove(guid), batchRemove(ids), submitting }

// === MessageTemplate 消息模板 ===
useMessageTemplateCreateOrUpdate(): { add(data), batchAdd(data[]), update(id, data), submitting }
useMessageTemplateFetch(options?): { fetch(id), templateCodeExist(params?), data, loading }
useMessageTemplateList(options?): { list(params?), items, loading }
useMessageTemplatePagination(options?): { paging(params?), pageInfo, loading }
useMessageTemplateRemove(): { remove(guid), batchRemove(ids), submitting }
```

### 枚举

```typescript
enum MessageType { EMAIL, APPLICATION, SMS, MOBILE }
// MessageTypeEnumMap = { EMAIL: { color: 'blue', text: '邮件' }, ... }
// MessageTypeOptions = [{ label: '邮件', value: 'EMAIL' }, ...]

enum MessageContentType { TEXT, HTML, JSON, XML, HYPERLINK }
enum RecipientTypeEnum { USER, ORG, ROLE, EMAIL, MOBILE }
```

---

## 6. OSS (`oss-vue3`)

### 导入

```typescript
import {
  useOss, useOnlyOffice, useOssTemplate,
  OssService, OnlyOfficeService, TemplateService,
  ossRequest,
  OssFile, FileUpload, FileInfo, FileDetailQuery,
  DownloadProgress, FillData, FillContent,
  DownloadStatus, FileType, DataSourceEnum, FillType,
} from '@swing/oss-vue3'
```

### Hooks

```typescript
// === useOss - 文件管理 ===
const oss = useOss(props?: { platform?: string; path?: string })
oss.upload(params: FileUpload): Promise<RestResponse>        // 上传文件
oss.remove(params: FileDetailQuery): Promise<boolean>        // 删除文件
oss.info(params: FileDetailQuery): Promise<RestResponse>     // 文件详情
oss.list(params: FileDetailQuery): Promise<RestResponse>     // 文件列表
oss.paging(params: FileDetailQuery): Promise<{ success, data, total }> // 分页列表
oss.preview(params: FileDetailQuery): Promise<RestResponse>  // 文件预览
oss.download(params: FileDetailQuery, fileName?: string)     // 普通下载
oss.startDownload(params: FileDetailQuery): Promise<RestResponse>       // 开始下载（返回下载任务id）
oss.downloadStream(downloadId: string, fileName?: string)    // 获取下载流
oss.downloadProgress(downloadId: string, headers?): { success, data: EventSource } // SSE进度推送

// === useOnlyOffice - OnlyOffice 文档编辑 ===
const onlyOffice = useOnlyOffice()
onlyOffice.getConfig(filePath: string): Promise<RestResponse<IConfig>>

// === useOssTemplate - 模板填充 ===
const template = useOssTemplate()
template.fillData(data: FillData): Promise<RestResponse>     // 填充 Office 模板数据
template.loading: Ref<boolean>
```

### OssFile 类型（替代 ant-design-vue 的 UploadFile）

```typescript
interface OssFile {
  originFileObj?: File
  name?: string
  url?: string
  uid?: string
  size?: number
  type?: string
}
```

### 枚举

```typescript
enum DownloadStatus { PENDING, DOWNLOADING, COMPLETED, FAILED }
enum FileType { /* 文件类型 */ }
enum DataSourceEnum { BODY, REMOTE }
enum FillType { MAP, LIST, MULTIPLE }
```

---

## 7. IOT (`iot-vue3`)

### 导入

```typescript
import {
  ActionService, ActionPointService,
  AlertListService, AlertRulesService,
  DeviceGroupService, DeviceListService,
  DevicePointService, DistributionListService,
  EndPointListService, EndPointRelDevicePointService,
  PointAlarmRulesService, PointManagerService,
  iotRequest,
  useDeviceData, useDevicePointList, useEndPointData,
} from '@swing/iot-vue3'
```

### Hooks

```typescript
// 设备数据（设备层级树）
useDeviceData(options?: HookBaseOptions): { fetch(params?), data, loading }
// data: 设备层级树结构

// 设备测点列表
useDevicePointList(options?: HookBaseOptions): { fetch(deviceId: string): Promise<RestResponse>, data, loading }

// 端点历史数据（用于 G2 图表）
useEndPointData(options?: HookBaseOptions): { fetch(params: EndPointHistoryQuery): Promise<RestResponse>, data, loading }
// 典型用途: 获取端点历史数据后传入 G2 图表渲染
```

### Service API 方法表

| Service | 方法 | 说明 |
|---------|------|------|
| `DeviceListService` | `pagingDeviceList`, `listDeviceList`, `getDeviceList`, `createDeviceList`, `updateDeviceList`, `removeDeviceList` | 设备 CRUD |
| `DeviceGroupService` | `pagingDeviceGroup`, `listDeviceGroup`, `getDeviceGroup`, `createDeviceGroup`, `updateDeviceGroup`, `removeDeviceGroup` | 设备分组 CRUD |
| `DevicePointService` | `pagingDevicePoint`, `listDevicePoint`, `getDevicePoint`, `createDevicePoint`, `updateDevicePoint`, `removeDevicePoint` | 设备测点 CRUD |
| `EndPointListService` | `pagingEndPointList`, `listEndPointList`, `getEndPointList`, `createEndPointList`, `updateEndPointList`, `removeEndPointList` | 端点 CRUD |
| `AlertListService` | `pagingAlertList`, `listAlertList`, `getAlertList` | 告警记录查询 |
| `AlertRulesService` | `pagingAlertRules`, `listAlertRules`, `getAlertRules`, `createAlertRules`, `updateAlertRules`, `removeAlertRules` | 告警规则 CRUD |
| `ActionService` | `pagingAction`, `listAction`, `getAction`, `createAction`, `updateAction`, `removeAction` | 动作 CRUD |
| `ActionPointService` | 类似 CRUD | 动作测点 |
| `PointManagerService` | 类似 CRUD | 测点管理 |
| `PointAlarmRulesService` | 类似 CRUD | 测点告警规则 |
| `DistributionListService` | 类似 CRUD | 配电列表 |
| `EndPointRelDevicePointService` | 类似 CRUD | 端点-设备测点关联 |

---

## 8. Widget (`widget-vue3`)

### 导入

```typescript
// 方式一：全局注册
import { installAllComponents } from '@swing/widget-vue3'
app.use(installAllComponents)

// 方式二：按需引入
import {
  SSelectDictionary, SEncodingGenerate,
  SUserAvatarWithOrg, SUserAssignmentModal,
  SSelectUserByModal, SSelectUser,
  SOrganizationCascader, SOrganizationTreeSelect,
  SMentionUser, SCommentList,
  SLabelPrinting,
  SIotPointSelect, SIotDeviceCascader, SIotMeasurementPointChart,
  SProcessStatus,
  SAppMessageTabCard, SNoticeOption, SNoticeList,
  SOnlyOfficeEditor, SFileDownloader,
  install, version,
} from '@swing/widget-vue3'

// 方式三：直接作为插件
import SwingWidget from '@swing/widget-vue3'
app.use(SwingWidget)
```

### 组件 Props 速查

#### System 域

| 组件 | Props 签名 | 说明 |
|------|-----------|------|
| `SSelectUser` | `value?`, `onChange?`, `placeholder?`, `disabled?` | 用户下拉选择 |
| `SSelectUserByModal` | `value?`, `onChange?`, `placeholder?` | 弹窗选择用户 |
| `SUserAvatarWithOrg` | `userId: string`, `orgId?`, `showOrg?: boolean` | 用户头像+组织 |
| `SUserAssignmentModal` | `visible`, `onClose`, `onSubmitted` | 调拨弹窗 |
| `SOrganizationCascader` | `value?`, `onChange?`, `placeholder?` | 组织级联选择 |
| `SOrganizationTreeSelect` | `value?`, `onChange?`, `placeholder?` | 组织树选择 |
| `SMentionUser` | `value`, `onChange`, `placeholder?` | @提及用户 |
| `SCommentList` | `targetType: string`, `targetId: string` | 评论列表 |
| `SAvatarDropdown` | `menuItems: array`, `onCommand` | 头像+下拉菜单 |
| `SLabelPrinting` | — | 标签打印工具 |

#### GDS 域

| 组件 | Props 签名 | 说明 |
|------|-----------|------|
| `SSelectDictionary` | `code: string`, `value?`, `onChange?` | 数据字典下拉 |
| `SEncodingGenerate` | `ruleCode: string`, `value?`, `onChange?` | 编码生成输入 |
| `SCitySelectCascader` | `value?`, `onChange?` | 行政区划级联 |
| `SCalendarDateTag` | `date: string` | 工作日历标签 |

#### Flow 域

| 组件 | Props 签名 | 说明 |
|------|-----------|------|
| `SProcessStatus` | `process: ProcessNode`, `instance?: Instance` | 工作流状态/审批人 |

#### IOT 域

| 组件 | Props 签名 | 说明 |
|------|-----------|------|
| `SIotPointSelect` | `deviceId: string`, `value?`, `onChange?` | 测点多选 |
| `SIotDeviceCascader` | `value?`, `onChange?` | 设备级联 |
| `SIotMeasurementPointChart` | `deviceId: string`, `pointIds: string[]` | G2 时序图表 |

#### Notice 域

| 组件 | Props 签名 | 说明 |
|------|-----------|------|
| `SAppMessageTabCard` | — | 标签式消息卡片 |
| `SNoticeList` | — | 消息列表 |
| `SNoticeOption` | — | 通知铃铛下拉 |

#### OSS 域

| 组件 | Props 签名 | 说明 |
|------|-----------|------|
| `SOnlyOfficeEditor` | `filePath: string`, `height?: string` | OnlyOffice 文档编辑器 |
| `SFileDownloader` | `fileId: string`, `fileName?: string` | 下载按钮+SSE进度 |

### 组件注册

```typescript
// @swing/widget-vue3 的 export default 是一个 Vue plugin
{
  install: (app: App) => void  // 注册所有 S 前缀组件
  version: string              // 版本号
}

// 所有组件带 withInstall 包装，支持 app.use(Component) 单独注册
```

---

## 附录：Service API 通用参数/返回值

### 通用请求参数

```typescript
import { QueryParameter, DomainModel, RestResponse, PageInfo } from '@swing/core-vue3'

// CRUD 方法统一返回 RestResponse<T>
// 分页方法额外封装:
return {
  success: response?.success,
  data: response?.data.list ?? [],
  total: response?.data.total ?? 0,
}
```

### MessageHandler 解耦模式

所有业务 Hook 支持 `options?.message?: MessageHandler` 参数：

```typescript
interface MessageHandler {
  success: (msg: string) => void
  error: (msg: string) => void
  warning?: (msg: string) => void
}

// 使用示例：传入 ant-design-vue 的 message
import { message } from 'ant-design-vue'
const { fetch } = useUserList({ message })  // 会自动显示 toast

// 不传则不显示，自行处理
const { fetch } = useUserList()  // 没有 toast
```

---

## 9. 跨平台 HTTP 适配器

### 说明

`@swing/core-vue3` 自 v0.2.1 起支持 **平台无关的 HTTP 适配器模式**，允许在 uni-app 等非浏览器环境复用整个 SDK。

- **默认行为**：使用 `axios` + `localStorage`，**老项目零影响**
- **自定义平台**：通过 `setAdapter()` 注入平台适配器，全局生效

### 注册方式

```typescript
import { RequestUtils } from '@swing/core-vue3'
const { setAdapter } = RequestUtils

// PC 浏览器：无需调用 setAdapter，自动使用 axios
// uni-app：在 main.ts 中注册一次
setAdapter({
  getToken(key) { return uni.getStorageSync(key) },
  setToken(key, value) { uni.setStorageSync(key, value) },
  removeToken(key) { uni.removeStorageSync(key) },
  navigate(url) { uni.redirectTo({ url }) },
  async request<R>(config) {
    return new Promise((resolve, reject) => {
      uni.request({
        url: config.url!, method: config.method as any,
        data: config.data, header: config.headers,
        success: (res) => resolve({
          data: res.data as R,
          headers: res.header || {},
          status: res.statusCode,
        }),
        fail: (err) => reject(err),
      })
    })
  },
})
```

### 核心接口

| 接口 | 文件 | 说明 |
|------|------|------|
| `HttpClient` | `core/src/interface.ts` | 适配器必须实现的接口 |
| `HttpRequestConfig` | `core/src/interface.ts` | 请求配置（平台无关） |
| `HttpResponse<R>` | `core/src/interface.ts` | 响应结构（平台无关） |
| `setAdapter()` | `core/src/utils/RequestUtil.ts` | 注册适配器（通过 `RequestUtils.setAdapter` 访问） |
| `SwingRequest` | `core/src/utils/RequestUtil.ts` | 内部自动判断走适配器或 axios |

### 适配器生命周期

```
项目入口
  ├── setAdapter(UniAdapter)   → 所有 request 走 uni.request
  └── 未调用 setAdapter()      → 向后兼容，走 axios + localStorage
```

### 注意事项

1. `setAdapter()` 只需在项目入口**调用一次**，所有包的 request 实例自动生效
2. 适配器仅接管 **HTTP 传输 + Token 读写**，不影响 `LsUtil`、`TokenUtil` 等工具
3. `HttpClient` 接口的所有方法均为可选（`?`），未提供的方法会回退到浏览器 API
4. 文件上传（`requestType: "form"`）需适配器自行处理 `uni.uploadFile`（参考 `UniAdapter` 示例）

---

> 本文档由 Swing SDK 源码自动生成。
> 最后更新: 2026-07-16
>
> ⚠️ `UrlUtils` 在模块级初始化时引用 `window.location`，SSR 下会崩溃，使用前请确认环境。
> ⚠️ 所有 SDK 包均支持双通道导出（命名空间 + 直接具名），core 包的工具函数除外（有同名冲突）。
