# RepeatFrequency 重复频率

- 来源：[E10 UI 组件库](https://www.e-cology.com.cn/ui/repeat-frequency/freepass)
- 平台：PC
- 维护者：蒋贝贝
- 设计稿：http://pd.e-cology.com.cn/pd/E10/ly/10737/#id=6pibam&p=%E6%96%87%E6%A1%A3%E8%AF%B4%E6%98%8E&g=1

## 代码演示

### 基础用法

直接引入组件进行使用

```jsx
import React, { createRef } from "react";
import { RepeatFrequency, Button, Spin, Select } from "@weapp/ui";
import { data, timezoneList } from "../mock";

class Demo extends React.Component<any, any> {
  constructor(props: any) {
    super(props);
    this.state = {
      basicRule: "",
      restDayConfig: "",
      triggerPreview: [],
      playDayList: [],
      spinning: false,
      timezone: "GMT+8",
      frequencySelectVal: [],
      formData: data,
      definitionRule: "",
    };
  }

  repeatFrequency = createRef<any>();

  timezoneChange = (value: any) => {
    this.setState({ timezone: value });
  };

  getFormartData = () => {
    if (this.repeatFrequency && this.repeatFrequency.current) {
      const res = this.repeatFrequency.current.getFormData?.();
      if (res) {
        this.setState({
          basicRule: res.basicRule,
          restDayConfig: res.restDayConfig,
        });
      } else {
        this.setState({
          basicRule: "",
          restDayConfig: "",
        });
      }
    }
  };

  getcountData = async () => {
    if (this.repeatFrequency && this.repeatFrequency.current) {
      this.setState({ spinning: true });
      const data = await this.repeatFrequency.current.getCountData?.({
        timezone: this.state.timezone,
      });
      this.setState({
        triggerPreview: data.triggerPreview,
        playDayList: data.playDayList || [],
        spinning: false,
        definitionRule: data.definitionRule,
      });
    }
  };

  render() {
    const style = {
      width: "100%",
      background: "#fff",
      fontSize: "12px",
      margin: "10px 0",
      padding: "10px",
    };
    const {
      triggerPreview,
      playDayList,
      spinning,
      timezone,
      formData,
      definitionRule,
    } = this.state;
    return (
      <>
        <div style={style}>
          时区选择：
          <Select
           
            data={timezoneList}
            value={timezone}
            onChange={this.timezoneChange}
          />
        </div>
        <RepeatFrequency
         
          data={formData}
          ref={this.repeatFrequency}
        />
        <br />
        <Button
         
          onClick={this.getFormartData}
        >
          获取数据解析
        </Button>
        <div style={style}>
          <span>rule:</span>&nbsp;
          <span style={{ wordWrap: "break-word" }}>{this.state.basicRule}</span>
        </div>
        <div style={style}>
          <span>非工作日处理方式:</span>&nbsp;
          <span>{this.state.restDayConfig}</span>
        </div>
        <br />
        <Button
         
          onClick={this.getcountData}
        >
          获取数据
        </Button>
        <Spin spinning={spinning}>
          <div style={style}>
              <p>规则释义：{definitionRule}</p>
            </div>
          <div style={{ display: "flex", justifyContent: "space-between" }}>
            <div style={style}>
              <p>触发的时间节点数量：{triggerPreview.length}</p>
              <div style={{ maxHeight: "300px", overflowY: "auto" }}>
                {triggerPreview.map((item: any, index: number) => (
                  <p key={index}>{new Date(item).toLocaleString()}</p>
                ))}
              </div>
            </div>
            <div style={style}>
              <p>非工作日时间节点：</p>
              <div style={{ maxHeight: "300px", overflowY: "auto" }}>
                {playDayList.map((item: any, index: number) => (
                  <p key={index}>{item}</p>
                ))}
              </div>
            </div>
          </div>
        </Spin>
      </>
    );
  }
}

export default Demo;
```

### 全局禁用

禁用整个表单

```jsx
import React, { createRef } from "react";
import { RepeatFrequency, Button, Spin, Select } from "@weapp/ui";
import { data, timezoneList } from "../mock";

class Demo extends React.Component<any, any> {
  constructor(props: any) {
    super(props);
    this.state = {
      basicRule: "",
      restDayConfig: "",
      triggerPreview: [],
      playDayList: [],
      spinning: false,
      timezone: "GMT+8",
      frequencySelectVal: [],
      formData: data,
      definitionRule: "",
    };
  }

  repeatFrequency = createRef<any>();

  timezoneChange = (value: any) => {
    this.setState({ timezone: value });
  };

  getFormartData = () => {
    if (this.repeatFrequency && this.repeatFrequency.current) {
      const res = this.repeatFrequency.current.getFormData?.();
      if (res) {
        this.setState({
          basicRule: res.basicRule,
          restDayConfig: res.restDayConfig,
        });
      } else {
        this.setState({
          basicRule: "",
          restDayConfig: "",
        });
      }
    }
  };

  getcountData = async () => {
    if (this.repeatFrequency && this.repeatFrequency.current) {
      this.setState({ spinning: true });
      const data = await this.repeatFrequency.current.getCountData?.({
        timezone: this.state.timezone,
      });
      this.setState({
        triggerPreview: data.triggerPreview,
        playDayList: data.playDayList || [],
        spinning: false,
        definitionRule: data.definitionRule,
      });
    }
  };

  render() {
    const style = {
      width: "100%",
      background: "#fff",
      fontSize: "12px",
      margin: "10px 0",
      padding: "10px",
    };
    const {
      triggerPreview,
      playDayList,
      spinning,
      timezone,
      formData,
      definitionRule,
    } = this.state;
    return (
      <>
        <div style={style}>
          时区选择：
          <Select
           
            data={timezoneList}
            value={timezone}
            onChange={this.timezoneChange}
          />
        </div>
        <RepeatFrequency
         
          data={formData}
          ref={this.repeatFrequency}
          disabled
        />
        <br />
        <Button
         
          onClick={this.getFormartData}
        >
          获取数据解析
        </Button>
        <div style={style}>
          <span>rule:</span>&nbsp;
          <span style={{ wordWrap: "break-word" }}>{this.state.basicRule}</span>
        </div>
        <div style={style}>
          <span>非工作日处理方式:</span>&nbsp;
          <span>{this.state.restDayConfig}</span>
        </div>
        <br />
        <Button
         
          onClick={this.getcountData}
        >
          获取数据
        </Button>
        <Spin spinning={spinning}>
          <div style={style}>
              <p>规则释义：{definitionRule}</p>
            </div>
          <div style={{ display: "flex", justifyContent: "space-between" }}>
            <div style={style}>
              <p>触发的时间节点数量：{triggerPreview.length}</p>
              <div style={{ maxHeight: "300px", overflowY: "auto" }}>
                {triggerPreview.map((item: any, index: number) => (
                  <p key={index}>{new Date(item).toLocaleString()}</p>
                ))}
              </div>
            </div>
            <div style={style}>
              <p>非工作日时间节点：</p>
              <div style={{ maxHeight: "300px", overflowY: "auto" }}>
                {playDayList.map((item: any, index: number) => (
                  <p key={index}>{item}</p>
                ))}
              </div>
            </div>
          </div>
        </Spin>
      </>
    );
  }
}

export default Demo;
```

## API

### data参数说明如下：

| 参数 | 说明 | 类型 | 是否必填 | 默认值 |
| --- | --- | --- | --- | --- |
| startTime | 开始时间 | string | 否 |  |
| triggerTime | 触发时间 | string | 否 |  |
| frequency | 定时频率 | "byMinute" \| "byHour" \| "byDay" \| "byWeek" \| "byMonth" \| "byQuarter" \| "byYear" | 否 | byHour |
| showOverRepeat | 是否展示"结束重复" | boolean | 否 | false |
| overRepeatType | "结束重复"的配置项 | "never" \| "date" \|"times" | 否 | never |
| overRepeatDate | 结束日期 | string | 否 |  |
| overRepeatTimes | 结束次数 | number \| string | 否 | 2 |
| showRestDayConfig | 是否展示"非工作日处理方式" | boolean | 否 | false |
| frequencyRule | 具体的频率类型下表单数据的配置 | FrequencyRuleType | 否 |  |
| disabled | 全局禁用 | boolean | 否 | false |
### frequencyRule参数说明如下：

| 参数 | 说明 | 类型 | 是否必填 | 默认值 |
| --- | --- | --- | --- | --- |
| type | “固定”或“指定” | "regular" \| "appoint" | 是 | regular |
| regularRule | 固定规则 | RegularRuleType | 否 |  |
| appointRule | 指定规则 | AppointRuleType | 否 |  |
### RegularRuleType和AppointRuleType参数说明如下：

| 参数 | 说明 | 类型 | 是否必填 | 默认值 |
| --- | --- | --- | --- | --- |
| times | 次数 | number \| string | 是 |  |
| appointMonths | 指定的月份 | string[] | 否 |  |
| sortByDateOrWeek | 按“周” 或 “日期”进行排序 | "date" \| "week" | 否 | date |
| sort | 正序、降序、指定 | "head" \| "tail" \| "appoint" | 否 | head |
| appointWeeks | 指定的周 | string[] | 否 |  |
| appointDays | 指定的星期几 | string[] | 否 |  |
| appointMonthDays | 指定的月份对应的天数 | string[] | 否 |  |
| appointQuarters | 指定的季度 | string[] | 否 |  |
| appointQuarterDays | 指定的季度对应的天数 | string[] | 否 |  |
| appointTimesDatas | 指定触发的次数 \| 指定周几 | string[] | 否 |  |
| quarterMonth | 季度的月份 | string[] | 否 |  |
| appointHourDatas | 指定触发的小时次数 | string[] | 否 |  |
### 其他说明：

```typescript
1、重复频率组件实质上是个业务表单组件，所有的相关操作可以参考表单，可以通过绑定ref获取重复频率组件实例

2、重复频率支持时区选择，如果有时区的相关需求，需要在请求数据的时候手动传递给后端（详情参考demo）

3、重复频率的data没有受控，后续的data更新组件内部不会接收，可以通过当前的组件实例使用表单的更新方式去更新数据，以达到回显的功能
  this.repeatFrequency.current.formStore.updateDatas({
    frequency: 'byYear'
  })
4、 disabled为true时，会禁用整个组件，如果想要单独禁用表单内的某个组件，请参考表单，直接对FormItems进行操作
```
