text: const GlobalVar = require('../data/global_var');
  const { strToJson, log } = require('../utils');
  const { send } = require('./http');
  const API = require('./api.bili');
  
  class Line {
      /**
       * 智能线路切换
       * @typedef {boolean} iSwitch 是否切换
       * @typedef {string} Msg 信息说明
       * @typedef {[iSwitch, any, Msg]} ResResult
       * @param {string} line_name
       * @param {Array<(...arg) => Promise<ResResult | string>>} requests
       * @param {(responseText: string) => ResResult} [pub_handler]
       */
      constructor(line_name, requests, pub_handler) {
          this.line_name = line_name
          this.requests = requests
          this.valid_line = 0
          this.switch_times = 0
          if (pub_handler) this.pub_handler = pub_handler
          /**
           * @type {ResResult}
           */
          this.res_result = [false, null, '']
      }
  
      /**
       * 切换线路
       * @returns {boolean}
       */
      switchLine() {
          const { valid_line, requests: { length }, switch_times } = this
          this.valid_line = (valid_line + 1) % length
          this.switch_times += 1
          if (switch_times > length) {
              return false
          } else {
              return true
          }
      }
  
      /**
       * 存储当前有效线路
       * @param {number} line
       */
      storeLine(line) {
          this.valid_line = line
          this.switch_times = 0
      }
  
      /**
       * 启动
       * @param  {...any} args
       * @returns {Promise<any>}
       */
      async run(...args) {
          const
              { line_name, requests, valid_line } = this,
              resp = await requests[valid_line](...args);
          if (typeof resp === 'string') {
              this.res_result = this.pub_handler(resp)
          } else {
              this.res_result = resp
          }
          const [i_switch, value, msg] = this.res_result
          if (!i_switch) {
              log.info(line_name, msg)
              this.storeLine(valid_line)
              return value
          }
          if (this.switchLine()) {
              log.warn(line_name, msg)
              log.warn(line_name, `切换线路(${valid_line + 1}/${requests.length})`)
              return await this.run()
          } else {
              log.error(line_name, msg)
              log.error(line_name, '所有备用线路均连接失败')
              return value
          }
      }
  }
  
  /**
   * GET请求
   * @param {import('./http').RequestOptions} param0
   * @returns {Promise<string>}
   */
  function get({ url, config, contents, query }) {
      return new Promise((resolve) => {
          send({
              url,
              method: 'GET',
              config,
              headers: {
                  "accept": 'application/json, text/plain, */*',
                  "cookie": GlobalVar.get("cookie")
              },
              query,
              contents,
              success: res => resolve(res.body),
              failure: err => resolve(err)
          })
      })
  }
  
  /**
   * POST请求
   * @param {import('./http').RequestOptions} param0
   * @returns {Promise<string>}
   */
  function post({ url, config, contents, query }) {
      return new Promise((resolve) => {
          send({
              url,
              method: 'POST',
              config,
              headers: {
                  "accept": 'application/json, text/plain, */*',
                  "content-type": 'application/x-www-form-urlencoded; charset=utf-8',
                  "cookie": GlobalVar.get("cookie")
              },
              query,
              contents,
              success: res => resolve(res.body),
              failure: err => resolve(err)
          })
      })
  }
  
  /**
   * 网络请求
   */
  const bili_client = {
      /**
       * 判断是否成功登录
       * @returns {Promise<boolean>}
       */
      async getMyinfo() {
          const
              responseText = await get({
                  url: API.SPACE_MYINFO
              }),
              res = strToJson(responseText);
          if (res.code === 0) {
              return true;
          } else {
              return false;
          }
      },
      /**
       * 获取被at的信息
       * @typedef AtInfo
       * @property {number} at_time
       * @property {string} up_uname
       * @property {string} business
       * @property {string} source_content
       * @property {string} url
       * @returns {Promise<AtInfo[]>}
       */
      async getMyAtInfo() {
          const
              responseText = await get({
                  url: API.MSGFEED_AT
              }),
              res = strToJson(responseText);
          let atInfo = [];
          if (res.code === 0) {
              const items = res.data.items;
              if (items.length !== 0) {
                  items.forEach(i => {
                      const { at_time, item, user } = i, { nickname: up_uname } = user, { business, uri: url, source_content } = item;
                      atInfo.push({
                          at_time,
                          up_uname,
                          business,
                          source_content,
                          url
                      });
                  });
              }
              return atInfo;
          } else {
              return atInfo;
          }
      },
      /**
       * 获取未读@
       * @returns {Promise<number>}
       */
      async getUnreadAtNum() {
          const
              responseText = await get({
                  url: API.MSGFEED_UNREAD
              }),
              res = strToJson(responseText);
          if (res.code === 0) {
              const { at } = res.data;
              log.info('获取未读@', `成功 数量: ${at}`);
              return at;
          } else {
              log.error('获取未读@', `失败\n${responseText}`);
              return -1;
          }
      },
      /**
       * 获取一页私信
       * @typedef SessionData
       * @property {string} session_ts
       * @property {number} timestamp
       * @property {number} unread_count
       * @property {number} sender_uid
       * @property {number} talker_id
       * @property {number} msg_seqno
       * 
       * @typedef SessionInfo
       * @property {number} has_more
       * @property {SessionData[]} data
       * 
       * @param {number} session_type 1 已关注 2 未关注 3 应援团
       * @param {string} [ts_16]
       * @returns {Promise<SessionInfo>}
       */
      async getSessionInfo(session_type, ts_16 = '') {
          const
              responseText = await get({
                  url: API.SESSION_SVR_GET_SESSIONS,
                  query: {
                      session_type,
                      end_ts: ts_16,
                  }
              }),
              res = strToJson(responseText);
          if (res.code === 0) {
              log.info('获取一页私信(20)', '成功 ' + (ts_16 ? 'end_ts->' + ts_16 : '第一页'));
              /**@type {Array} */
              const
                  sessions = res.data.session_list || [],
                  has_more = res.data.has_more,
                  data = sessions.map(session => {
                      const
                          { session_ts, last_msg, unread_count, talker_id } = session,
                          { timestamp = 0, sender_uid = 0, msg_seqno } = last_msg || {};
                      return { session_ts, timestamp, sender_uid, unread_count, talker_id, msg_seqno };
                  });
              return { has_more, data };
          } else if (res.code === 2) {
              log.error('获取私信', `API抽风...请再次尝试`);
              return { has_more: 0, data: [] };
          } else {
              log.error('获取私信', `失败\n${responseText}`);
              return { has_more: 0, data: [] };
          }
      },
      /**
       * 获取私信细节
       * @param {number} talker_id
       * @param {number} size
       */
      async fetch_session_msgs(talker_id, size) {
          const
              responseText = await get({
                  url: API.FETCH_SESSION_MSGS,
                  query: {
                      talker_id,
                      session_type: 1,
                      size
                  }
              }),
              res = strToJson(responseText);
          if (res.code === 0) {
              const msgs = res.data.messages
              if (msgs instanceof Array) {
                  log.info('私信细节', `${talker_id}有${size}条未读私信`)
                  return msgs.map(it => it.content).join('\n')
              } else {
                  log.warn('私信细节', `${talker_id}无私信`)
              }
          }
          log.error('私信细节', `获取失败`)
          return ''
      },
      /**
       * 获取未读私信数量
       * @returns {Promise<{ unfollow_unread: number, follow_unread: number }>}
       */
      async getUnreadSessionNum() {
          const
              responseText = await get({
                  url: API.SESSION_SVR_SINGLE_UNREAD
              }),
              res = strToJson(responseText);
          if (res.code === 0) {
              const { unfollow_unread = 0, follow_unread = 0 } = res.data;
              log.info('获取未读私信', `成功 已关注未读数: ${follow_unread}, 未关注未读数 ${unfollow_unread}`);
              return { unfollow_unread, follow_unread };
          } else {
              log.error('获取未读私信', `失败\n${responseText}`);
              return null;
          }
      },
      /**
       * 私信已读
       * @param {number} talker_id
       * @param {number} session_type
       * @param {number} msg_seqno
       */
      async updateSessionStatus(talker_id, session_type, msg_seqno) {
          const
              responseText = await post({
                  url: API.SESSION_SVR_UPDATE_ACK,
                  config: {
                      retry: false
                  },
                  contents: {
                      talker_id,
                      session_type,
                      ack_seqno: msg_seqno,
                      csrf_token: GlobalVar.get("csrf"),
                      csrf: GlobalVar.get("csrf")
                  }
              }),
              res = strToJson(responseText);
          if (res.code === 0) {
              log.info('私信已读', `成功 -> talker_id: ${talker_id}`);
          } else {
              log.error('私信已读', `失败 -> talker_id: ${talker_id}\n${responseText}`);
          }
      },
      /**
       * 获取关注列表
       * @param {number} uid
       * @returns {Promise<string | null>}
       */
      async getAttentionList(uid) {
          const
              responseText = await get({
                  url: API.FEED_GET_ATTENTION_LIST,
                  query: {
                      uid
                  }
              }),
              res = strToJson(responseText);
          if (res.code === 0) {
              log.info('获取关注列表', '成功');
              return res.data.list.toString();
          } else {
              log.error('获取关注列表', `失败\n${responseText}`);
              return null;
          }
      },
      /**
       * 获取一个动态的细节
       * @param {string} dynamic_id
       * @return {Promise<JSON>} 失败返回undefined
       */
      async getOneDynamicByDyid(dynamic_id) {
          const
              responseText = await get({
                  url: API.DYNAMIC_SVR_GET_DYNAMIC_DETAIL,
                  query: {
                      dynamic_id
                  }
              }),
              { code, data } = strToJson(responseText),
              { card } = data || {};
          if (code !== 0) {
              log.error('获取一个动态的细节', `获取动态(${dynamic_id})数据出错:\n${responseText}`);
              return;
          }
          if (!card) {
              log.warn('获取一个动态的细节', `动态(${dynamic_id})不存在`);
              return;
          }
          log.info('获取一个动态的细节', `动态id(${dynamic_id})`);
          return card;
      },
      /**
       * 获取一组动态的信息
       * @param {number} host_uid 被查看者的uid
       * @param {string} offset_dynamic_id 此动态偏移量 初始为 0
       * @returns {Promise<string>}
       */
      getOneDynamicInfoByUID(host_uid, offset_dynamic_id) {
          /* 鉴别工作交由modifyDynamicRes完成 */
          return get({
              url: API.DYNAMIC_SVR_SPACE_HISTORY,
              query: {
                  visitor_uid: GlobalVar.get("myUID"),
                  host_uid,
                  offset_dynamic_id,
              },
              config: {
                  retry: false
              }
          })
      },
      /**
       * 通过tag名获取tag的id
       * @param {string} tag_name
       * tag名
       * @returns {Promise<number | -1>}
       * 正确:tag_ID
       * 错误:-1
       */
      async getTagIDByTagName(tag_name) {
          const
              responseText = await get({
                  url: API.TAG_INFO,
                  query: {
                      tag_name
                  }
              }),
              res = strToJson(responseText);
          if (res.code !== 0) {
              log.error('获取TagID', '失败');
              return -1;
          } else {
              return res.data.tag_id;
          }
      },
      /**
       * 获取tag下的热门动态以及一条最新动态
       * @param {number} tagid
       * @returns {Promise<string>}
       */
      getHotDynamicInfoByTagID(tagid) {
          return get({
              url: API.TOPIC_SVR_TOPIC_NEW,
              query: {
                  topic_id: tagid
              }
          })
      },
      /**
       * 获取tag下的最新动态
       * @param {string} tagname
       * @param {string} offset
       * @returns {Promise<string>}
       */
      getOneDynamicInfoByTag(tagname, offset) {
          return get({
              url: API.TOPIC_SVR_TOPIC_HISTORY,
              query: {
                  topic_name: tagname,
                  offset_dynamic_id: offset
              },
              config: {
                  retry: false
              }
          })
      },
      /**
       * 搜索专栏
       * @param {string} keyword
       * @return {Promise<Array<{pub_time: number, id: number}>>}
       */
      async searchArticlesByKeyword(keyword) {
          const
              responseText = await get({
                  url: API.WEB_INTERFACE_SEARCH_TYPE,
                  query: {
                      keyword,
                      page: 1,
                      order: 'pubdate',
                      search_type: 'article'
                  }
              }),
              res = JSON.parse(responseText);
          if (res.code === 0) {
              let cv_arr = [];
              try {
                  log.info('搜索专栏', '成功 关键词: ' + keyword);
                  cv_arr = res.data.result.map(it => {
                      return {
                          pub_time: it.pub_time,
                          id: it.id
                      }
                  });
              } catch (error) {
                  log.error('搜索专栏', '失败 原因:\n' + responseText);
                  cv_arr = [];
              }
              return cv_arr;
          } else {
              log.error('搜索专栏', '失败 原因:\n' + responseText);
              return [];
          }
      },
      /**
       * 获取专栏内容
       * @param {number} cv
       * @returns {Promise<string>}
       */
      getOneArticleByCv(cv) {
          return get({
              url: API.READ_CV.replace('{{cv}}', cv)
          })
      },
      /**
       * 获取粉丝数的所有有效方式
       */
      _getUserInfo: new Line('获取粉丝数', [
          /**
           * 线路一
           * @param {number} uid
           * @returns {Promise<string>}
           */
          (uid) => get({
              url: API.WEB_INTERFACE_CARD,
              query: {
                  mid: uid,
                  photo: false
              },
              config: {
                  retry: false
              }
          }),
          /**
           * 线路二
           * @param {number} uid
           * @returns {Promise<string>}
           */
          (uid) => get({
              url: API.RELATION_STAT,
              query: {
                  vmid: uid
              }
          }),
          /**
           * 线路三
           * @param {number} uid
           * @returns {Promise<string>}
           */
          (uid) => get({
              url: "https://tenapi.cn/bilibilifo/",
              query: {
                  uid
              }
          })
      ], responseText => {
          const res = strToJson(responseText);
          if (res.code === 0) {
              return [false, res.data.follower, 'ok'];
          } else {
              return [true, 1, `出错 可能是访问过频繁\n${responseText}`]
          }
      }),
      /**
       * 获取粉丝数
       * @param {number} uid
       * @returns {Promise<number | -1>}
       */
      getUserInfo(uid) {
          return this._getUserInfo.run(uid)
      },
      /**
       * 获取开奖信息
       * @param {string} dyid
       * 动态id
       * @typedef LotteryNotice
       * @property {number | -1} ts
       * @returns {Promise<LotteryNotice>} 开奖时间
       */
      async getLotteryNotice(dyid) {
          const
              responseText = await get({
                  url: API.LOTTERY_SVR_LOTTERY_NOTICE,
                  query: {
                      dynamic_id: dyid
                  }
              }),
              res = strToJson(responseText);
          if (res.code === 0) {
              return {
                  ts: res.data.lottery_time
              };
          } else {
              log.error('获取开奖信息', `失败\n${responseText}`);
              return {
                  ts: -1
              };
          }
      },
      _autoAttention: new Line('自动关注', [
          (uid) => post({
              url: API.RELATION_MODIFY,
              config: {
                  retry: false
              },
              contents: {
                  fid: uid,
                  act: 1,
                  re_src: 0,
                  csrf: GlobalVar.get("csrf")
              }
          }),
          (uid) => post({
              url: API.FEED_SETUSERFOLLOW,
              contents: {
                  type: 1,
                  follow: uid,
                  csrf: GlobalVar.get("csrf")
              }
          }),
          (uid) => post({
              url: API.RELATION_BATCH_MODIFY,
              contents: {
                  fid: uid,
                  act: 1,
                  re_src: 0,
                  csrf: GlobalVar.get("csrf")
              }
          })
      ], responseText => {
          const res = strToJson(responseText);
          switch (res.code) {
              case 0:
                  return [false, 0, '关注+1']
              case 22002:
                  return [false, 2, '您已被对方拉入黑名单']
              case 22003:
                  return [false, 3, '黑名单用户无法关注']
              case 22015:
                  return [false, 4, '账号异常']
              case 22009:
                  return [false, 5, '关注已达上限']
              default:
                  return [true, 1, `未知错误\n${responseText}`]
          }
      }),
      /**
       * 之前不检查是否重复关注
       * 自动关注
       * 并转移分组
       * @param {Number} uid
       * 被关注者的UID
       * @returns {Promise<number>}
       * - 成功 0  
       * - 未知错误 1  
       * - 您已被对方拉入黑名单 2  
       * - 黑名单用户无法关注 3  
       * - 账号异常 4  
       * - 关注已达上限 5  
       */
      autoAttention(uid) {
          return this._autoAttention.run(uid)
      },
      /**
       * 移动分区
       * @param {number} uid
       * @param {number} tagid 关注分区的ID
       * @returns {Promise<number>}
       * - 成功 0  
       * - 失败 1  
       */
      async movePartition(uid, tagid) {
          const responseText = await post({
              url: API.RELATION_TAGS_ADDUSERS,
              contents: {
                  fids: uid,
                  tagids: tagid,
                  csrf: GlobalVar.get("csrf")
              }
          });
          /* 重复移动code also equal 0 */
          if (/^{"code":0/.test(responseText)) {
              log.info('移动分区', 'up主分区移动成功');
              return 0;
          } else {
              log.error('移动分区', `up主分区移动失败\n${responseText}`);
              return 1;
          }
      },
      /**
       * 取消关注
       * @param {number} uid
       * @returns {Promise<boolean>}
       */
      async cancelAttention(uid) {
          const
              responseText = await post({
                  url: API.RELATION_MODIFY,
                  config: {
                      retry: false
                  },
                  contents: {
                      fid: uid,
                      act: 2,
                      re_src: 0,
                      csrf: GlobalVar.get("csrf")
                  }
              }),
              res = strToJson(responseText);
          if (res.code === 0) {
              log.info('自动取关', `取关成功(${uid})`);
              return true;
          } else {
              log.error('自动取关', `取关失败(${uid})\n${responseText}`);
              return false;
          }
      },
      /**
       * 动态自动点赞
       * @param {string} dyid
       * @returns {Promise<number>}
       * - 成功 0  
       * - 未知错误 1  
       * - 点赞异常 2  
       * - 点赞频繁 3  
       */
      async autolike(dyid) {
          const
              responseText = await post({
                  url: API.DYNAMIC_LIKE_THUMB,
                  contents: {
                      uid: GlobalVar.get("myUID"),
                      dynamic_id: dyid,
                      up: 1,
                      csrf: GlobalVar.get("csrf")
                  }
              }),
              res = strToJson(responseText);
          switch (res.code) {
              case 0:
                  log.info('自动点赞', '点赞成功');
                  return 0;
              case 1000113:
                  log.warn('自动点赞', '点赞异常');
                  return 2;
              case 1000001:
                  log.warn('自动点赞', '点赞频繁');
                  return 3;
              default:
                  log.error('自动点赞', `未知错误\n${responseText}`);
                  return 1;
          }
      },
      /**
       * 转发前应查看是否重复转发
       * 自动转发
       * @param {Number} uid
       * 自己的UID
       * @param {string} dyid
       * @param {string} [msg]
       * 动态的ID
       * @returns {Promise<number>}
       * - 成功 0  
       * - 未知错误 1  
       * - 该动态不能转发分享 2  
       * - 请求数据发生错误，请刷新或稍后重试 3  
       * - 操作太频繁了，请稍后重试 4  
       */
      async autoRelay(uid, dyid, msg = '转发动态', ctrl = '[]') {
          const len = msg.length;
          if (len > 233) {
              msg = msg.slice(0, 233 - len)
          }
          const
              responseText = await post({
                  url: API.DYNAMIC_REPOST_REPOST,
                  config: {
                      retry: false
                  },
                  contents: {
                      uid: `${uid}`,
                      dynamic_id: dyid,
                      content: msg,
                      ctrl,
                      csrf: GlobalVar.get("csrf")
                  }
              }),
              res = strToJson(responseText);
          switch (res.code) {
              case 0:
                  log.info('转发动态', '成功转发一条动态');
                  return 0;
              case 1101004:
                  log.warn('转发动态', '该动态不能转发分享');
                  return 2;
              case 2201116:
                  log.warn('转发动态', '请求数据发生错误，请刷新或稍后重试');
                  return 3;
              case 1101008:
                  log.warn('转发动态', '操作太频繁了，请稍后重试');
                  return 4;
              default:
                  log.error('转发动态', `未知错误\n${responseText}`);
                  return 1;
          }
      },
      /**
       * @typedef Picture
       * @property {string} img_src
       * @property {number} img_width
       * @property {number} img_height
       * 发布一条动态
       * @param { string | Picture[] } content
       * @return {Promise<boolean>} isError true
       */
      async createDynamic(content) {
          let
              contents = {
                  csrf: GlobalVar.get("csrf"),
                  extension: '{"emoji_type":1,"from":{"emoji_type":1},"flag_cfg":{}}'
              },
              url = '';
          if (content instanceof Array) {
              url = API.DYNAMIC_SVR_CREATE_DRAW
              contents = {
                  ...contents,
                  biz: 3,
                  category: 3,
                  pictures: JSON.stringify(content)
              }
          } else {
              url = API.DYNAMIC_SVR_CREATE
              contents = {
                  ...contents,
                  content,
              }
          }
          const responseText = await post({
              url,
              contents,
          });
          if (/^{"code":0/.test(responseText)) {
              log.info('发布动态', `成功创建一条随机内容的动态\n${JSON.stringify(content)}\n`);
              return false
          } else {
              log.error('发布动态', `发布动态失败\n${JSON.stringify(content)}\n${responseText}`);
              return true
          }
      },
      /**
       * 获取推荐
       * @returns {Promise<Array<[number, number]>>}
       */
      async getTopRcmd() {
          const
              responseText = await get(
                  {
                      url: API.TOP_RCMD,
                  }
              ),
              res = strToJson(responseText);
          if (res.code === 0) {
              log.info('获取推荐', `成功`);
              return res.data.item.map(it => {
                  return [it.owner.mid, it.id];
              });
          } else {
              log.error('获取推荐', `获取推荐失败\n${responseText}`);
              return [];
          }
      },
      /**
       * 分享视频
       * @param {number} uid
       * @param {number} aid
       * @return {boolean} isError true
       */
      async shareVideo(uid, aid) {
          const responseText = await post({
              url: API.DYNAMIC_REPOST_SHARE,
              contents: {
                  platform: "pc",
                  uid,
                  type: 8,
                  content: "分享视频",
                  repost_code: 20000,
                  rid: aid,
                  csrf_token: GlobalVar.get("csrf")
              }
          });
          if (/^{"code":0/.test(responseText)) {
              log.info('转发视频', `成功转发视频(av${aid})`);
              return false
          } else {
              log.error('转发视频', `转发失败\n${responseText}`);
              return true
          }
      },
      /**
       * 移除动态
       * @param {string} dyid
       * @returns {Promise<boolean>}
       */
      async rmDynamic(dyid) {
          const responseText = await post({
              url: API.DYNAMIC_SVR_RM_DYNAMIC,
              contents: {
                  dynamic_id: dyid,
                  csrf: GlobalVar.get("csrf")
              },
              config: {
                  retry: false
              }
          });
          if (/^{"code":0/.test(responseText)) {
              log.info('删除动态', `成功删除一条动态(${dyid})`);
              return true;
          } else {
              log.error('删除动态', `删除动态失败(${dyid})\n${responseText}`);
              return false;
          }
      },
      /**
       * 发送评论
       * @param {string} rid
       * cid_str
       * @param {string} msg
       * @param {number} type
       * 1(视频)
       * 11(有图)
       * 17(无图)
       * @returns {Promise<number>}
       * - 成功 0
       * - 未知错误 1
       * - 原动态已删除 2
       * - 评论区已关闭 3
       * - 需要输入验证码 4
       * - 已被对方拉入黑名单 5
       * - 黑名单用户无法互动 6
       * - UP主已关闭评论区 7
       */
      async sendChat(rid, msg, type) {
          const
              responseText = await post({
                  url: API.REPLY_ADD,
                  contents: {
                      oid: rid,
                      type: type,
                      message: msg,
                      csrf: GlobalVar.get("csrf")
                  }
              }),
              res = strToJson(responseText);
          switch (res.code) {
              case 0:
                  log.info('自动评论', '评论成功');
                  return 0;
              case -404:
                  log.error('自动评论', '原动态已删除');
                  return 2;
              case 12002:
                  log.error('自动评论', '评论区已关闭');
                  return 3;
              case 12015:
                  log.error('自动评论', '需要输入验证码');
                  return 4;
              case 12035:
                  log.error('自动评论', `已被对方拉入黑名单`);
                  return 5;
              case 12053:
                  log.error('自动评论', '黑名单用户无法互动');
                  return 6;
              case 12061:
                  log.error('自动评论', 'UP主已关闭评论区');
                  return 7;
              default:
                  log.error('自动评论', `未知错误\n${responseText}`);
                  return 1;
          }
      },
      /**
       * 检查分区  
       * 不存在指定分区时创建  
       * 获取到tagid添加为对象的属性  
       * @param {string} [name]
       * @returns {Promise<number>}
       */
      async checkMyPartition(name) {
          if (!name) name = '此处存放因抽奖临时关注的up'
          const
              responseText = await get({
                  url: API.RELATION_TAGS
              }),
              res = strToJson(responseText);
          let tagid = undefined;
          if (res.code === 0) {
              const data = res.data.filter((it) => it.name === name);
              if (data.length) {
                  log.info('获取分区id', '成功');
                  tagid = data[0].tagid;
              } else {
                  log.warn('获取分区id', `失败 无指定分区名${name}`);
              }
              if (name === '此处存放因抽奖临时关注的up') {
                  if (typeof tagid === 'undefined') {
                      return bili_client.createPartition(name);
                  } else {
                      return tagid;
                  }
              } else {
                  return tagid;
              }
          } else {
              log.error('获取分区id', `访问出错 可在my_config里手动填入\n${responseText}`);
              return tagid;
          }
      },
      /**
       * 创造分区
       * @param {string} partition_name
       * @returns {Promise<number>}
       */
      async createPartition(partition_name) {
          const
              responseText = await post({
                  url: API.RELATION_TAG_CREATE,
                  contents: {
                      tag: partition_name,
                      csrf: GlobalVar.get("csrf")
                  }
              }),
              obj = strToJson(responseText);
          if (obj.code === 0) {
              /* 获取tagid */
              let { tagid } = obj.data;
              log.info('新建分区', '分区新建成功');
              return tagid;
          } else {
              log.error('新建分区', `分区新建失败\n${responseText}`);
              return undefined;
          }
      },
      /**
       * 获取一个分区中50个的id
       * @param {number} tagid
       * @param {number} n 1->
       * @returns {Promise<number[]>}
       */
      async getPartitionUID(tagid, n) {
          const
              responseText = await get({
                  url: API.RELATION_TAG,
                  query: {
                      mid: GlobalVar.get("myUID"),
                      tagid: tagid,
                      pn: n,
                      ps: 50
                  }
              }),
              res = strToJson(responseText);
          let uids = [];
          if (res.code === 0) {
              res.data.forEach(d => {
                  uids.push(d.mid);
              });
              log.info(`获取分组${tagid}`, `成功获取取关分区列表${n}`);
              return uids;
          } else {
              log.error(`获取分组${tagid}`, `获取取关分区列表失败\n${responseText}`);
              return uids;
          }
      }
  };
  
  
  module.exports = bili_client