text: /*
   * Copyright 1999-2018 Alibaba Group Holding Ltd.
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *      http://www.apache.org/licenses/LICENSE-2.0
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  import projectConfig from './config';
  import $ from 'jquery';
  import {Message} from '@alifd/next';
  
  function goLogin() {
    const url = window.location.href;
    localStorage.removeItem('token');
    const base_url = url.split('#')[0];
    console.log('base_url', base_url);
    window.location = `${base_url}#/login`;
  }
  
  const global = window;
  
  /**
   * 获取cookie值
   * @param {*String} keyName cookie名
   */
  const aliwareGetCookieByKeyName = function(keyName) {
    let result = '';
    const cookieList = (document.cookie && document.cookie.split(';')) || [];
    cookieList.forEach(str => {
      const [name = '', value = ''] = str.split('=') || [];
      if (name.trim().indexOf(keyName) !== -1) {
        result = value;
      }
    });
  
    return result.trim();
  };
  
  /**
   * 监听事件对象
   */
  const nacosEvent = (function(_global) {
    const eventListObj = {};
    const ignoreEventListObj = {};
    return {
      /**
       * 只监听一次
       */
      once(eventName, callback) {
        this.listen.call(this, eventName, callback, true);
      },
      /**
       * 监听事件<eventName: String 监听事件名, callback: function 回调函数, once: boolean 是否监听一次>
       */
      listen(eventName, callback, once = false) {
        if (!eventName || !callback) {
          return;
        }
        !eventListObj[eventName] && (eventListObj[eventName] = []);
        eventListObj[eventName].push({
          callback,
          once,
        });
      },
      /**
       * 监听事件, 之前未消费的消息也会进行触发<eventName: String 监听事件名, callback: function 回调函数, once: boolean 是否监听一次>
       */
      listenAllTask(...args) {
        const self = this;
        const argsList = Array.prototype.slice.call(args);
        const eventName = argsList[0];
  
        if (!eventName) {
          return;
        }
        // 监听事件
        self.listen(...argsList);
  
        // 判断是否有未消费的消息
        if (ignoreEventListObj[eventName] && ignoreEventListObj[eventName].length > 0) {
          const eventObj = ignoreEventListObj[eventName].pop();
          self.trigger.apply(eventObj.self, eventObj.argsList);
        }
      },
      /**
       * 触发事件
       */
      trigger(...args) {
        const self = this;
        const argsList = Array.prototype.slice.call(args);
        const eventName = argsList.shift();
        // 如果还没有订阅消息, 将其放到未消费队列里
        if (!eventListObj[eventName]) {
          !ignoreEventListObj[eventName] && (ignoreEventListObj[eventName] = []);
          ignoreEventListObj[eventName].push({
            argsList: Array.prototype.slice.call(args),
            self,
          });
          return;
        }
  
        const newList = [];
        eventListObj[eventName].forEach((_obj, index) => {
          if (Object.prototype.toString.call(_obj.callback) !== '[object Function]') {
            return;
          }
          _obj.callback.apply(self, argsList);
          // 删除只触发一次的事件
          if (!_obj.once) {
            newList.push(_obj);
          }
        });
        eventListObj[eventName] = newList;
      },
      /**
       * 删除监听事件
       */
      remove(eventName, callback) {
        if (!eventName || !eventListObj[eventName]) {
          return;
        }
        if (!callback) {
          eventListObj[eventName] = null;
        } else {
          const newList = [];
          eventListObj[eventName].forEach((_obj, index) => {
            if (_obj.callback !== callback) {
              newList.push(_obj);
            }
          });
          eventListObj[eventName] = newList.length ? newList : null;
        }
      },
    };
  })(global);
  
  /**
   * nacos的工具类
   */
  const nacosUtils = (function(_global) {
    let loadingCount = 0;
    let loadingState = {
      visible: false,
      shape: 'flower',
      tip: 'loading...',
      // color: "#333",
      // style: { height: "100%", width: "100%" }
    };
    return {
      /**
       * 改变loading 的样式
       */
      changeLoadingAttr(obj) {
        if (Object.prototype.toString.call(obj) === '[object Object]') {
          loadingState = Object.assign({}, loadingCount, obj);
        }
      },
      /**
       * 打开loading效果
       */
      openLoading() {
        loadingCount++;
        nacosEvent.trigger(
          'nacosLoadingEvent',
          Object.assign(loadingState, {
            visible: true,
            spinning: true,
          })
        );
      },
      /**
       * 尝试关闭loading, 只有当loadingCount小于0时才会关闭loading效果
       */
      closeLoading() {
        loadingCount--;
        if (loadingCount <= 0) {
          loadingCount = 0;
          nacosEvent.trigger(
            'nacosLoadingEvent',
            Object.assign(loadingState, {
              visible: false,
              spinning: false,
            })
          );
        }
      },
      /**
       * 关闭loading效果
       */
      closeAllLoading() {
        loadingCount = 0;
        nacosEvent.trigger(
          'nacosLoadingEvent',
          Object.assign(loadingState, {
            visible: false,
            spinning: false,
          })
        );
      },
      /**
       * 获取资源地址, 如果资源需要静态化输出 请调用此方法
       */
      getURISource(url) {
        return url;
      },
    };
  })(global);
  
  /**
   * 获取url中的参数
   */
  const getParams = (function(_global) {
    return function(name) {
      const reg = new RegExp(`(^|&)${name}=([^&]*)(&|$)`, 'i');
      let result = [];
      if (_global.location.hash !== '') {
        result = _global.location.hash.split('?'); // 优先判别hash
      } else {
        result = _global.location.href.split('?');
      }
  
      if (result.length === 1) {
        result = _global.parent.location.hash.split('?');
      }
  
      if (result.length > 1) {
        const r = result[1].match(reg);
        if (r != null) {
          return decodeURIComponent(r[2]);
        }
      }
  
      return null;
    };
  })(global);
  
  /**
   * 设置参数
   */
  const setParams = (function(global) {
    let _global = global;
    const _originHref = _global.location.href.split('#')[0];
    return function(name, value) {
      if (!name) {
        return;
      }
  
      let obj = {};
      if (typeof name === 'string') {
        obj = {
          [name]: value,
        };
      }
  
      if (Object.prototype.toString.call(name) === '[object Object]') {
        obj = name;
      }
  
      let hashArr = [];
      if (_global.location.hash) {
        hashArr = _global.location.hash.split('?');
      }
  
      const paramArr = (hashArr[1] && hashArr[1].split('&')) || [];
  
      let paramObj = {};
      paramArr.forEach(val => {
        const tmpArr = val.split('=');
        paramObj[tmpArr[0]] = decodeURIComponent(tmpArr[1] || '');
      });
      paramObj = Object.assign({}, paramObj, obj);
  
      const resArr =
        Object.keys(paramObj).map(key => `${key}=${encodeURIComponent(paramObj[key] || '')}`) || [];
  
      hashArr[1] = resArr.join('&');
      const hashStr = hashArr.join('?');
      if (_global.history.replaceState) {
        const url = _originHref + hashStr;
        _global.history.replaceState(null, '', url);
      } else {
        _global.location.hash = hashStr;
      }
    };
  })(global);
  
  /**
   * 设置参数
   */
  const setParam = function(...args) {
    return setParams.apply(this, args);
  };
  
  /**
   * 删除参数
   */
  const removeParams = (function(global) {
    let _global = global;
    const _originHref = _global.location.href.split('#')[0];
    return function(name) {
      let removeList = [];
  
      const nameType = Object.prototype.toString.call(name);
      if (nameType === '[object String]') {
        removeList.push(name);
      } else if (nameType === '[object Array]') {
        removeList = name;
      } else if (nameType === '[object Object]') {
        removeList = Object.keys(name);
      } else {
        return;
      }
  
      let hashArr = [];
      if (_global.location.hash) {
        hashArr = _global.location.hash.split('?');
      }
  
      let paramArr = (hashArr[1] && hashArr[1].split('&')) || [];
  
      // let paramObj = {};
      paramArr = paramArr.filter(val => {
        const tmpArr = val.split('=');
        return removeList.indexOf(tmpArr[0]) === -1;
      });
  
      hashArr[1] = paramArr.join('&');
      const hashStr = hashArr.join('?');
      if (_global.history.replaceState) {
        const url = _originHref + hashStr;
        _global.history.replaceState(null, '', url);
      } else {
        _global.location.hash = hashStr;
      }
    };
  })(global);
  
  /**
   * 封装的ajax请求
   */
  const request = (function(_global) {
    const middlewareList = [];
    const middlewareBackList = [];
    const serviceMap = {};
    const serviceList = [];
    const methodList = [];
    /**
     * 获取真实url信息
     */
    const NacosRealUrlMapper = (function() {
      serviceList.forEach(obj => {
        serviceMap[obj.registerName] = obj;
      });
      return function(registerName) {
        const serviceObj = serviceMap[registerName];
        if (!serviceObj) {
          return null;
        }
        // 获取正确请求方式
        serviceObj.methodType = methodList[serviceObj.method];
        return serviceObj;
      };
    })();
  
    /**
     * 添加中间件函数
     * @param {*function} callback 回调函数
     */
    function middleWare(callback, isBack = true) {
      if (isBack) {
        middlewareBackList.push(callback);
      } else {
        middlewareList.push(callback);
      }
      return this;
    }
  
    /**
     * 处理中间件
     * @param {*Object} config ajax请求配置信息
     */
    function handleMiddleWare(...allArgs) {
      // 获取除config外传入的参数
      let [config, ...args] = allArgs;
      // 最后一个参数为middlewareList
      const middlewareList = args.pop() || [];
      if (middlewareList && middlewareList.length > 0) {
        config = middlewareList.reduce((config, callback) => {
          if (typeof callback === 'function') {
            return callback.apply(this, [config, ...args]) || config;
          }
          return config;
        }, config);
      }
      return config;
    }
  
    /**
     * 处理自定义url
     * @param {*Object} config ajax请求配置信息
     */
    function handleCustomService(...args) {
      let [config] = args;
      // 只处理com.alibaba.开头的url
      if (config && config.url && config.url.indexOf('com.alibaba.') === 0) {
        const registerName = config.url;
        const serviceObj = NacosRealUrlMapper(registerName);
        if (serviceObj && serviceObj.url && serviceObj.url.replace) {
          // 有mock数据 直接返回 生产环境失效
          if (projectConfig.is_preview && serviceObj.is_mock && config.success) {
            let code = null;
            try {
              code = JSON.parse(serviceObj.defaults);
            } catch (error) {}
            config.success(code);
            return;
          }
          // 替换url中的占位符
          config.url = serviceObj.url.replace(/{([^\}]+)}/g, ($1, $2) => config.$data[$2]);
          try {
            // 添加静态参数
            if (serviceObj.is_param && typeof config.data === 'object') {
              config.data = Object.assign({}, JSON.parse(serviceObj.params), config.data);
            }
          } catch (e) {}
          // 替换请求方式
          if (serviceObj.method && !config.type) {
            config.type = serviceObj.methodType;
          }
          // 将请求参数变为json格式
          if (serviceObj.isJsonData && typeof config.data === 'object') {
            config.data = JSON.stringify(config.data);
            config.processData = false;
            config.dataType = 'json';
            config.contentType = 'application/json';
          }
          try {
            // 设置临时代理 生产环境失效
            if (projectConfig.is_preview && serviceObj.is_proxy) {
              const { beforeSend } = config;
              config.beforeSend = function(xhr) {
                serviceObj.cookie && xhr.setRequestHeader('tmpCookie', serviceObj.cookie);
                serviceObj.header && xhr.setRequestHeader('tmpHeader', serviceObj.header);
                serviceObj.proxy && xhr.setRequestHeader('tmpProxy', serviceObj.proxy);
                beforeSend && beforeSend(xhr);
              };
            }
          } catch (e) {}
          // 设置自动loading效果
          if (serviceObj.autoLoading) {
            // nacosUtils.openLoading();
            const prevComplete = config.complete;
            config.complete = function() {
              nacosUtils.closeLoading();
              typeof prevComplete === 'function' &&
                prevComplete.apply($, Array.prototype.slice.call(args));
            };
          }
          // serviceObj = null;
        }
      }
      return config;
    }
  
    function Request(...allArgs) {
      // 除了config外的传参
      let [config, ...args] = allArgs;
      // 处理前置中间件
      config = handleMiddleWare.apply(this, [config, ...args, middlewareList]);
      // 处理自定义url
      config = handleCustomService.apply(this, [config, ...args]);
      if (!config) return;
      // xsrf
      if (
        config.type &&
        config.type.toLowerCase() === 'post' &&
        config.data &&
        Object.prototype.toString.call(config.data) === '[object Object]' &&
        !config.data.sec_token
      ) {
        const sec_token = aliwareGetCookieByKeyName('XSRF-TOKEN');
        sec_token && (config.data.sec_token = sec_token);
      }
  
      // 处理后置中间件
      config = handleMiddleWare.apply(this, [config, ...args, middlewareBackList]);
      let token = {};
      try {
        token = JSON.parse(localStorage.token);
      } catch (e) {
        console.log('Token Erro', localStorage.token, e);
        goLogin();
      }
      const { accessToken = '' } = token;
      const [url, paramsStr = ''] = config.url.split('?');
      const params = paramsStr.split('&');
      params.push(`accessToken=${accessToken}`);
  
      return $.ajax(
        Object.assign({}, config, {
          type: config.type,
          url: [url, params.join('&')].join('?'),
          data: config.data || '',
          dataType: config.dataType || 'json',
          beforeSend(xhr) {
            config.beforeSend && config.beforeSend(xhr);
          },
          headers: {
            Authorization: localStorage.getItem('token'),
          },
        })
      ).then(
        success => {},
        error => {
          // 处理403 forbidden
          const { status, responseJSON = {} } = error || {};
          if (responseJSON.message) {
            Message.error(responseJSON.message);
          }
          if (
            [401, 403].includes(status) &&
            ['unknown user!', 'token invalid', 'token expired!'].includes(responseJSON.message)
          ) {
            goLogin();
          }
          return error;
        }
      );
    }
  
    // 暴露方法
    Request.handleCustomService = handleCustomService;
    Request.handleMiddleWare = handleMiddleWare;
    Request.NacosRealUrlMapper = NacosRealUrlMapper;
    Request.serviceList = serviceList;
    Request.serviceMap = serviceMap;
    Request.middleWare = middleWare;
  
    return Request;
  })(global);
  
  export {
    nacosEvent,
    nacosUtils,
    aliwareGetCookieByKeyName,
    removeParams,
    getParams,
    setParam,
    setParams,
    request,
  };
  