# SelectMember 移动端选人组件

移动端选人弹层组件，支持选择平台**用户、组织、岗位、群组、角色、个人群组**等，并提供常用、定密、范围限制、已选回显等能力。适用于流程表单、业务表单中的「选人 / 选组织」字段。

---

## 目录结构

```
src/selectMember/
├── select.jsx      # 组件主文件
├── select.less     # 样式
├── utils.js        # 工具方法
├── index.js        # 导出
└── README.md
```

---

## 引入方式

```jsx
import SelectMember from 'fmui-base/lib/selectMember';
// 或工程内相对路径
import SelectMember from '../selectMember';
```

---

## 使用前准备

组件依赖全局登录上下文（`getLoginUserInfo()`），需保证页面已登录且可获取：

| 字段 | 说明 |
|------|------|
| `token` | 接口鉴权 Bearer Token |
| `context` | 接口根路径（如 `/dingisv`） |
| `orgId` | 当前用户组织 ID（可选，用于本组织等逻辑） |
| `baseCorpId` | 企业/单位 ID |

传统集成方式可在 `index.html` 中放置隐藏域，在 `getUser` 回调里写入（与旧版文档一致，**非必须**，以项目实际登录方式为准）：

```html
<input type="hidden" id="token" value="" />
<input type="hidden" id="baseContext" value="" />
```

```javascript
$("#token").val(result.token);
$("#baseContext").val(result.baseContext);
```

---

## 快速开始

```jsx
import React from 'react';
import SelectMember from 'fmui-base/lib/selectMember';

export default class DemoPage extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      selectValue: [],
      fieldDataValue: '',
      scopeTable: 'cmp_scope',
      fieldTable: 'oa_meeting_apply_record',
      fieldData: 'attend_user',
    };
  }

  render() {
    const t = this;
    return (
      <SelectMember
        ref="SelectMember"
        required
        readOnly={false}
        placeholder="请选择"
        label="参会人员"
        checkType="checkbox"
        code="common,user,org,station,group"
        chooseType="userAndOrg,userAndGroup"
        commonUsedData={[]}
        showType="list"
        isDelete
        includeDel="0"
        fieldDataValue={t.state.fieldDataValue}
        scopeTable={t.state.scopeTable}
        fieldTable={t.state.fieldTable}
        fieldData={t.state.fieldData}
        onChange={(value) => {
          t.setState({ selectValue: value });
        }}
      />
    );
  }
}
```

---

## Props

### 基础展示

| 属性 | 类型 | 默认值 | 必填 | 说明 |
|------|------|--------|------|------|
| `label` | string | - | 否 | 字段标题 |
| `required` | boolean | `false` | 否 | 是否显示必填标识 |
| `readOnly` | boolean | `false` | 否 | 只读；只读且超过 10 条时折叠展示 |
| `placeholder` | string | - | 否 | 未选择时的提示文案 |
| `showType` | string | - | **是** | 展示方式：`button` 按钮 / `text` 文本 / `list` 标签列表 |
| `isDelete` | boolean | - | `showType=list` 时必填 | 标签模式下是否显示删除按钮 |
| `checkType` | string | - | **是** | 单选 `radio` / 多选 `checkbox` |

### 选人场景

| 属性 | 类型 | 默认值 | 必填 | 说明 |
|------|------|--------|------|------|
| `code` | string | - | **是** | 场景编码，逗号分隔，见 [code 说明](#code-场景编码) |
| `chooseType` | string | - | **是** | 各 Tab 下可选范围，逗号分隔，见 [chooseType 说明](#choosetype-可选范围) |
| `chooseObj` | string | - | 否 | 与 `chooseType` 类似，用于扩展场景接口 `getSceneInfo` 时透传 |
| `commonUsedData` | array | `[]` | 否 | 「常用」Tab 预置可选数据（仅用户） |

**code 场景编码**

| 值 | 说明 |
|----|------|
| `common` | 常用 |
| `user` | 用户 |
| `org` | 组织（`inst`、`dep` 会映射为组织相关逻辑） |
| `station` | 岗位 |
| `group` | 群组 |
| `personalGroup` / `personGroup` | 个人群组 |
| `role` | 角色 |
| `duty` | 职务 |
| `politicalOutlook` | 政治面貌 |

示例：`code="common,user,org,station,group"`

**chooseType 可选范围**

组织 Tab（与 `user`、`org` 配合）：

| 值 | 说明 |
|----|------|
| `userAndOrg` | 组织与用户均可选（Tab 展示为组织树） |
| `userNotOrg` | 仅可选用户，不可选组织 |
| `org` | 仅可选组织 |

群组 Tab（与 `group` 配合）：

| 值 | 说明 |
|----|------|
| `userAndGroup` | 群组与用户均可选 |
| `userNotGroup` | 仅可选群组下用户 |
| `group` | 仅可选群组 |

个人群组 Tab（与 `personalGroup` / `personGroup` 配合）：

| 值 | 说明 |
|----|------|
| `userAndPersonalGroup` / `userAndPersonGroup` | 个人群组与用户均可选 |
| `userNotPersonalGroup` / `userNotPersonGroup` | 仅可选用户 |
| `personalGroup` / `personGroup` | 仅可选个人群组 |

多个 Tab 组合时用英文逗号连接，例如：`chooseType="userAndOrg,userAndGroup"`

### 已选数据回显（编辑 / 查看）

两种方式**二选一**：

#### 方式 A：scope 表（推荐，与后端一致）

| 属性 | 类型 | 默认值 | 必填 | 说明 |
|------|------|--------|------|------|
| `scopeTable` | string | `cmp_scope` | 编辑场景必填* | scope 存储表名 |
| `fieldTable` | string | - | 编辑场景必填* | 业务表表名 |
| `fieldData` | string | - | 编辑场景必填* | 业务表字段名 |
| `fieldDataValue` | string | - | 编辑场景必填* | 业务数据主键 / 关联值 |
| `includeDel` | string | 默认回显已删除 | 否 | `0` 不回显已删除用户 / `1` 回显 |

\* 与 `defaultValue` 二选一；需配合 `ref` 调用 `initSelectData()`。

#### 方式 B：defaultValue（自定义存储）

| 属性 | 类型 | 说明 |
|------|------|------|
| `defaultValue` | array | 已选数据 JSON 数组，格式见 [数据格式](#数据格式) |

未使用 scope 四元组时，在 `setState` 传入 `defaultValue` 或 `fieldDataValue`（数组）后调用 `initSelectData()`。

### 范围限制

| 属性 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `queryLimit` | string | 否 | `1` 自身及下级；`2` 仅自身；`3` 查询传入数据；`4` 自身及直接下级；`5` 自身及所有下级 |
| `limitData` | string | `queryLimit` 有值时必填 | 与 `queryLimit` 对应的 ID，逗号分隔 |
| `noSelectRoot` | string | 否 | `"1"` 时请求 `getPopuOrgInfo` 带 `noSelectRoot=1`，由接口返回的 `canUse` 控制是否可勾选 |

### 定密与其它

| 属性 | 类型 | 说明 |
|------|------|------|
| `showSecret` | boolean | 开启定密后仅可选用户（`code` 强制为 `user`） |
| `secretlevel` | string | 密级：`1` 绝密 / `2` 机密 / `3` 秘密 / `4` 非密 |
| `isShowInMyOrg` | boolean | 是否直接展示当前用户所在组织（可与系统参数 `selUserOurorg` 联动） |

---

## 事件

### onChange

选择变更或初始化回显完成后触发。

```jsx
onChange={(value, fieldDataValue) => {
  // value: 已选 scope 列表（数组）
  // fieldDataValue: 使用 scope 表初始化时，可能带回业务主键（第二参数，可选）
}}
```

**返回值示例：**

```json
[
  {
    "scopeType": "user",
    "scopeValue": "d5ced277574011e780b3000c29ee419e",
    "scopeName": "测试用户",
    "imageId": ""
  },
  {
    "scopeType": "org",
    "scopeValue": "d5ced277574011e780b3000c29ee412e",
    "scopeName": "测试部门"
  },
  {
    "scopeType": "station",
    "scopeValue": "d5ced277574011e780b3001c29ee412e",
    "scopeName": "测试岗位"
  },
  {
    "scopeType": "group",
    "scopeValue": "d5ced277534011e780b3001c29ee412e",
    "scopeName": "测试群组"
  }
]
```

| scopeType | 说明 |
|-----------|------|
| `user` | 用户 |
| `org` | 组织 |
| `station` | 岗位 |
| `group` | 群组 |
| `role` | 角色（按实际接口返回） |

`imageId`：钉钉等场景下用户头像 ID，常用 Tab / 用户类型建议返回。

---

## 实例方法（ref）

| 方法 | 参数 | 说明 |
|------|------|------|
| `initSelectData(bizSn?, fieldId?)` | 验签业务号、字段 DOM 类名（可选） | 根据 `scopeTable` 四元组或 `defaultValue` / `fieldDataValue` 拉取并回显已选数据 |
| `dialogClearItem(isShowDialog)` | `boolean` | 清空已选；`true` 时弹确认框 |

### initSelectData 示例（scope 表）

```jsx
this.setState({
  fieldDataValue: '5381b1a3cf41410194d385132cdc8442',
  scopeTable: 'oa_meeting_scope',
  fieldTable: 'oa_meeting_apply_record',
  fieldData: 'attend_user',
}, () => {
  this.refs.SelectMember.initSelectData();
});
```

### initSelectData 示例（defaultValue）

```jsx
this.setState({
  defaultValue: [
    { scopeType: 'user', scopeValue: 'xxx', scopeName: '张三', imageId: '' },
  ],
}, () => {
  this.refs.SelectMember.initSelectData();
});
```

### dialogClearItem 示例

```jsx
// 带确认框清空
this.refs.SelectMember.dialogClearItem(true);

// 直接清空
this.refs.SelectMember.dialogClearItem(false);
```

---

## 数据格式

### defaultValue / onChange 单项结构

```javascript
{
  scopeType: 'user',      // user | org | station | group | role 等
  scopeValue: 'id',       // 主键
  scopeName: '显示名称',
  imageId: ''             // 可选，用户头像（钉钉）
}
```

### commonUsedData（常用 Tab，仅用户）

```javascript
[
  {
    scopeType: 'user',
    scopeValue: 'd5ced277574011e780b3000c29ee419e',
    scopeName: '测试用户',
    imageId: '',
  },
]
```

---

## 相关接口

组件内部会调用平台选人接口（需登录 Token），主要包括：

| 接口 | 说明 |
|------|------|
| `GET {context}/api/m/cmp/popuser/mobile/getSceneInfo` | 扩展场景 Tab 配置 |
| `GET {context}/api/m/cmp/popuser/mobile/getOfficePopuser` | 按 scope 表回显已选数据 |

参数与 `scopeTable`、`fieldTable`、`fieldData`、`fieldDataValue`、`includeDel` 对应。

---

## 注意事项

1. **scope 四元组配套使用**：`scopeTable`、`fieldTable`、`fieldData`、`fieldDataValue` 需与后端存储一致；`scopeTable` 缺省为 `cmp_scope`。
2. **回显方式二选一**：scope 表 **或** `defaultValue` / 数组型 `fieldDataValue`，均需通过 `ref` 调用 `initSelectData()`。
3. **组织与用户合并**：`userAndOrg` 时组织 Tab 展示组织树，可同时选组织与用户。
4. **群组下选用户**：`chooseType` 需包含 `userAndGroup` 或 `userNotGroup`。
5. **showType=list** 时必须传 `isDelete`，控制标签是否可删。
6. **扩展 Tab**：`code` 含非内置类型时会请求 `getSceneInfo` 动态加载扩展页签（参见版本 2.2.38+ 扩展页签能力）。
7. **系统参数**：党员筛选（`selUserIsDJ`）、默认本组织（`selUserOurorg`）、隐藏 Tab（`selUserHideTag`）等由后台系统参数控制，无需在组件上重复配置。

---

## 完整示例（编辑场景）

```jsx
import React from 'react';
import SelectMember from 'fmui-base/lib/selectMember';

export default class MeetingForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      recordId: props.recordId || '',
      attendees: [],
    };
  }

  componentDidMount() {
    if (this.state.recordId) {
      this.initAttendees();
    }
  }

  initAttendees() {
    const t = this;
    t.setState({ fieldDataValue: t.state.recordId }, () => {
      t.refs.attendUser.initSelectData();
    });
  }

  render() {
    const t = this;
    return (
      <div>
        <SelectMember
          ref="attendUser"
          label="参会人"
          required
          checkType="checkbox"
          code="common,user,org"
          chooseType="userAndOrg"
          showType="list"
          isDelete
          scopeTable="oa_meeting_scope"
          fieldTable="oa_meeting_apply_record"
          fieldData="attend_user"
          fieldDataValue={t.state.fieldDataValue}
          includeDel="0"
          onChange={(value) => t.setState({ attendees: value })}
        />
      </div>
    );
  }
}
```

---

## 版本说明

- 选人组件能力随 `fmui-base` 版本迭代，详见根目录 `README.md` 更新日志（如：扩展页签、回显已删除用户、隐藏页签、`baseCorpId` 修复等）。
