连续复制
一键复制
一键打包

App.vue

<script>
    export default {
        onLaunch() {
            // 获取店铺配置信息  全局只请求一次
            this.$api.shopConfig(res => {
                this.$store.commit('config', res)
                // #ifdef H5
                //百度统计
                if (res.statistics) {
                    var script = document.createElement("script");
                    script.innerHTML = res.statistics;
                    document.getElementsByTagName("body")[0].appendChild(script);
                }
                // #endif
            })

            //获取地区信息
            this.$api.getAreaList({}, res => {
                if (res.status) {
                    this.$db.set('areaList', res.data)
                }
            });

            // #ifdef APP-PLUS
            this.checkVersion()
            // #endif
        },
        onShow: function() {
            //console.log('App Show')
        },
        onHide: function() {
            //console.log('App Hide')
        },
        methods: {
            // #ifdef APP-PLUS
            // app更新检测
            checkVersion() {
                // 获取应用版本号
                let version = plus.runtime.version

                //检测当前平台,如果是安卓则启动安卓更新
                uni.getSystemInfo({
                    success: res => {
                        this.updateHandler(res.platform, version)
                    }
                })
            },
            // 更新操作
            updateHandler(platform, version) {
                let data = {
                    platform: platform,
                    version: version
                }
                let _this = this;
                this.$api.getAppVersion(data,
                    res => {
                        if (res.status && res.data.lengh > 0) {
                            const info = res.data[0]
                            if (info.version !== '' && info.version > version) {
                                uni.showModal({
                                    //提醒用户更新
                                    title: '更新提示',
                                    content: info.note,
                                    success: res => {
                                        if (res.confirm) {
                                            plus.runtime.openURL(info.download_url)
                                        }
                                    }
                                })
                            }
                        }
                    }
                )
            }
            // #endif
        }
    }
</script>

<style lang="scss">
    /*每个页面公共css */
    @import './static/css/style.css';

    .bgf {
        background: #FFF;
    }

    .flc {
        display: flex;
        justify-content: space-between;
        align-items: center;
    }

    .flc-inline {
        display: inline-flex;
        align-items: center;
    }

    .g5 {
        color: $g5;
    }

    .fz12 {
        font-size: $fz12;
    }
</style>
<style>
    @import url("/components/gaoyia-parse/parse.css");
</style>

cli

<?php
define('dir', __DIR__);
$dirArr = explode('\\', dir);
$md = dir . '\\' . $dirArr[count($dirArr) - 1] . '.md';
if (is_file($md))
    unlink($md);
// 生成md文件
// file_put_contents($md, listdir(dir, '', 0));
$listArr = listdir(dir);
$content = getContent($listArr);
$tree = "###目录###" . PHP_EOL . "```package" . PHP_EOL . listTree($listArr) . PHP_EOL . '```';
file_put_contents($md, $content . PHP_EOL . $tree);
function getContent($arr, $level = 0)
{
    $content = '';
    foreach ($arr as $k => $v) {
        if (is_array($v)) {
            $content .= '###' . getPlaceholder($level, '#') . $k . "###" . getPlaceholder($level, '#') . PHP_EOL;
            $content .= getContent($v, $level + 1);
        } else if(!in_array(getExt($file),['.gif','.jpg','.png'])){
            echo getExt($file);
            $fileArr = explode('/', str_replace('\\', '/', $v));
            $file = $fileArr[count($fileArr) - 1];
            $content .= '###' . getPlaceholder($level, '#') . $file . "###" . getPlaceholder($level, '#') . PHP_EOL;
            $content .= '```' . str_replace('.', '', getExt($file)) . PHP_EOL .mb_convert_encoding( file_get_contents($v), 'UTF-8', 'UTF-8,GBK,GB2312,BIG5' ). PHP_EOL . '```' . PHP_EOL;
        }
    }
    return $content;
}
function listTree($arr, $level = 0)
{
    $content = '';
    $placeholder = getPlaceholder($level);
    foreach ($arr as $k => $v) {
        if (is_array($v)) {
            $content .= $placeholder . '└── ' . $k . PHP_EOL;
            $content .= listTree($v, $level + 1);
        } else {
            $fileArr = explode('/', str_replace('\\', '/', $v));
            $file = $fileArr[count($fileArr) - 1];
            $content .= $placeholder . '├── ' . $file . PHP_EOL;
        }
    }
    return $content;
}
function listdir($dir)
{
    //定义一个数组
    $files = array();
    $notInArr = ['.', '..', '.git', '.idea', '.DS_Store', 'MD', 'MD.php', '.gitignore', '.gitignore'];
    $notExt = ['.exe', '.doc', '.docx', '.pdf', '.sh~', '.rar', '.zip', '.tar','.gif','.jpg','.png'];
    //检测是否存在文件
    if (is_dir($dir)) {
        //打开目录
        if ($handle = opendir($dir)) {
            //返回当前文件的条目
            while (($file = readdir($handle)) !== false) {
                //去除特殊目录
                if (!in_array($file, $notInArr)) {
                    //判断子目录是否还存在子目录
                    if (is_dir($dir . "/" . $file)) {
                        // 递归调用本函数,再次获取目录
                        $files[$file] = listdir($dir . "/" . $file);
                    } else {
                        if (in_array(getExt($file), $notExt))
                            continue;
                        // 获取目录数组
                        $files[] = $dir . "/" . $file;
                    }
                }
            }
            //关闭文件夹
            closedir($handle);
            //返回文件夹数组
            return $files;
        }
    }
}
/**
 * 获取占位符
 * @param $level
 * @param string $placeholder
 * @return string
 */
function getPlaceholder($level, $placeholder = '    ')
{
    for ($i = 0; $i < $level; $i++) {
        $placeholder .= $placeholder;
    }
    return substr($placeholder, 0, strlen($placeholder) - 1);
}
/**
 * 获取文件后戳
 * @param $filename
 * @return bool|string
 */
function getExt($filename)
{
    $pos = strrpos($filename, '.');
    $ext = substr($filename, $pos);
    return $ext;
}

common

html-parser.js

/*
 * HTML5 Parser By Sam Blowes
 *
 * Designed for HTML5 documents
 *
 * Original code by John Resig (ejohn.org)
 * http://ejohn.org/blog/pure-javascript-html-parser/
 * Original code by Erik Arvidsson, Mozilla Public License
 * http://erik.eae.net/simplehtmlparser/simplehtmlparser.js
 *
 * ----------------------------------------------------------------------------
 * License
 * ----------------------------------------------------------------------------
 *
 * This code is triple licensed using Apache Software License 2.0,
 * Mozilla Public License or GNU Public License
 *
 * ////////////////////////////////////////////////////////////////////////////
 *
 * 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
 *
 * ////////////////////////////////////////////////////////////////////////////
 *
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations
 * under the License.
 *
 * The Original Code is Simple HTML Parser.
 *
 * The Initial Developer of the Original Code is Erik Arvidsson.
 * Portions created by Erik Arvidssson are Copyright (C) 2004. All Rights
 * Reserved.
 *
 * ////////////////////////////////////////////////////////////////////////////
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 * ----------------------------------------------------------------------------
 * Usage
 * ----------------------------------------------------------------------------
 *
 * // Use like so:
 * HTMLParser(htmlString, {
 *     start: function(tag, attrs, unary) {},
 *     end: function(tag) {},
 *     chars: function(text) {},
 *     comment: function(text) {}
 * });
 *
 * // or to get an XML string:
 * HTMLtoXML(htmlString);
 *
 * // or to get an XML DOM Document
 * HTMLtoDOM(htmlString);
 *
 * // or to inject into an existing document/DOM node
 * HTMLtoDOM(htmlString, document);
 * HTMLtoDOM(htmlString, document.body);
 *
 */
// Regular Expressions for parsing tags and attributes
var startTag = /^<([-A-Za-z0-9_]+)((?:\s+[a-zA-Z_:][-a-zA-Z0-9_:.]*(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/;
var endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/;
var attr = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g; // Empty Elements - HTML 5

var empty = makeMap('area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr'); // Block Elements - HTML 5
// fixed by xxx 将 ins 标签从块级名单中移除

var block = makeMap('a,address,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video'); // Inline Elements - HTML 5

var inline = makeMap('abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var'); // Elements that you can, intentionally, leave open
// (and which close themselves)

var closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr'); // Attributes that have their values filled in disabled="disabled"

var fillAttrs = makeMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected'); // Special Elements (can contain anything)

var special = makeMap('script,style');
function HTMLParser(html, handler) {
  var index;
  var chars;
  var match;
  var stack = [];
  var last = html;

  stack.last = function () {
    return this[this.length - 1];
  };

  while (html) {
    chars = true; // Make sure we're not in a script or style element

    if (!stack.last() || !special[stack.last()]) {
      // Comment
      if (html.indexOf('<!--') == 0) {
        index = html.indexOf('-->');

        if (index >= 0) {
          if (handler.comment) {
            handler.comment(html.substring(4, index));
          }

          html = html.substring(index + 3);
          chars = false;
        } // end tag

      } else if (html.indexOf('</') == 0) {
        match = html.match(endTag);

        if (match) {
          html = html.substring(match[0].length);
          match[0].replace(endTag, parseEndTag);
          chars = false;
        } // start tag

      } else if (html.indexOf('<') == 0) {
        match = html.match(startTag);

        if (match) {
          html = html.substring(match[0].length);
          match[0].replace(startTag, parseStartTag);
          chars = false;
        }
      }

      if (chars) {
        index = html.indexOf('<');
        var text = index < 0 ? html : html.substring(0, index);
        html = index < 0 ? '' : html.substring(index);

        if (handler.chars) {
          handler.chars(text);
        }
      }
    } else {
      html = html.replace(new RegExp('([\\s\\S]*?)<\/' + stack.last() + '[^>]*>'), function (all, text) {
        text = text.replace(/<!--([\s\S]*?)-->|<!\[CDATA\[([\s\S]*?)]]>/g, '$1$2');

        if (handler.chars) {
          handler.chars(text);
        }

        return '';
      });
      parseEndTag('', stack.last());
    }

    if (html == last) {
      throw 'Parse Error: ' + html;
    }

    last = html;
  } // Clean up any remaining tags


  parseEndTag();

  function parseStartTag(tag, tagName, rest, unary) {
    tagName = tagName.toLowerCase();

    if (block[tagName]) {
      while (stack.last() && inline[stack.last()]) {
        parseEndTag('', stack.last());
      }
    }

    if (closeSelf[tagName] && stack.last() == tagName) {
      parseEndTag('', tagName);
    }

    unary = empty[tagName] || !!unary;

    if (!unary) {
      stack.push(tagName);
    }

    if (handler.start) {
      var attrs = [];
      rest.replace(attr, function (match, name) {
        var value = arguments[2] ? arguments[2] : arguments[3] ? arguments[3] : arguments[4] ? arguments[4] : fillAttrs[name] ? name : '';
        attrs.push({
          name: name,
          value: value,
          escaped: value.replace(/(^|[^\\])"/g, '$1\\\"') // "

        });
      });

      if (handler.start) {
        handler.start(tagName, attrs, unary);
      }
    }
  }

  function parseEndTag(tag, tagName) {
    // If no tag name is provided, clean shop
    if (!tagName) {
      var pos = 0;
    } // Find the closest opened tag of the same type
    else {
        for (var pos = stack.length - 1; pos >= 0; pos--) {
          if (stack[pos] == tagName) {
            break;
          }
        }
      }

    if (pos >= 0) {
      // Close all the open elements, up the stack
      for (var i = stack.length - 1; i >= pos; i--) {
        if (handler.end) {
          handler.end(stack[i]);
        }
      } // Remove the open elements from the stack


      stack.length = pos;
    }
  }
}

function makeMap(str) {
  var obj = {};
  var items = str.split(',');

  for (var i = 0; i < items.length; i++) {
    obj[items[i]] = true;
  }

  return obj;
}

function removeDOCTYPE(html) {
  return html.replace(/<\?xml.*\?>\n/, '').replace(/<!doctype.*>\n/, '').replace(/<!DOCTYPE.*>\n/, '');
}

function parseAttrs(attrs) {
  return attrs.reduce(function (pre, attr) {
    var value = attr.value;
    var name = attr.name;

    if (pre[name]) {
            pre[name] = pre[name] + " " + value;
    } else {
            pre[name] = value;
    }

    return pre;
  }, {});
}

function parseHtml(html) {
  html = removeDOCTYPE(html);
  var stacks = [];
  var results = {
    node: 'root',
    children: []
  };
  HTMLParser(html, {
    start: function start(tag, attrs, unary) {
      var node = {
        name: tag
      };

      if (attrs.length !== 0) {
        node.attrs = parseAttrs(attrs);
      }

      if (unary) {
        var parent = stacks[0] || results;

        if (!parent.children) {
          parent.children = [];
        }

        parent.children.push(node);
      } else {
        stacks.unshift(node);
      }
    },
    end: function end(tag) {
      var node = stacks.shift();
      if (node.name !== tag) console.error('invalid state: mismatch end tag');

      if (stacks.length === 0) {
        results.children.push(node);
      } else {
        var parent = stacks[0];

        if (!parent.children) {
          parent.children = [];
        }

        parent.children.push(node);
      }
    },
    chars: function chars(text) {
      var node = {
        type: 'text',
        text: text
      };

      if (stacks.length === 0) {
        results.children.push(node);
      } else {
        var parent = stacks[0];

        if (!parent.children) {
          parent.children = [];
        }

        parent.children.push(node);
      }
    },
    comment: function comment(text) {
      var node = {
        node: 'comment',
        text: text
      };
      var parent = stacks[0];

      if (!parent.children) {
        parent.children = [];
      }

      parent.children.push(node);
    }
  });
  return results.children;
}

export default parseHtml;

uni-H5Api.js

//#ifdef H5
/** clipboard.js v2.0.4**/
!function(t,e){try{window.ClipboardJS=e();}catch(e){};"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return function(n){var o={};function r(t){if(o[t])return o[t].exports;var e=o[t]={i:t,l:!1,exports:{}};return n[t].call(e.exports,e,e.exports,r),e.l=!0,e.exports}
  return r.m=n,r.c=o,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=0)}([function(t,e,n){"use strict";var r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i=function(){function o(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}
  return function(t,e,n){return e&&o(t.prototype,e),n&&o(t,n),t}}(),a=o(n(1)),c=o(n(3)),u=o(n(4));function o(t){return t&&t.__esModule?t:{default:t}}
  var l=function(t){function o(t,e){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,o);var n=function(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}(this,(o.__proto__||Object.getPrototypeOf(o)).call(this));return n.resolveOptions(e),n.listenClick(t),n}
    return function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}(o,c.default),i(o,[{key:"resolveOptions",value:function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:{};this.action="function"==typeof t.action?t.action:this.defaultAction,this.target="function"==typeof t.target?t.target:this.defaultTarget,this.text="function"==typeof t.text?t.text:this.defaultText,this.container="object"===r(t.container)?t.container:document.body}},{key:"listenClick",value:function(t){var e=this;this.listener=(0,u.default)(t,"click",function(t){return e.onClick(t)})}},{key:"onClick",value:function(t){var e=t.delegateTarget||t.currentTarget;this.clipboardAction&&(this.clipboardAction=null),this.clipboardAction=new a.default({action:this.action(e),target:this.target(e),text:this.text(e),container:this.container,trigger:e,emitter:this})}},{key:"defaultAction",value:function(t){return s("action",t)||'copy'}},{key:"defaultTarget",value:function(t){var e=s("target",t);if(e){return document.querySelector(e)}}},{key:"defaultText",value:function(t){return s("text",t)||this.text}},{key:"destroy",value:function(){this.listener.destroy(),this.clipboardAction&&(this.clipboardAction.destroy(),this.clipboardAction=null)}}],[{key:"isSupported",value:function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:["copy","cut"],e="string"==typeof t?[t]:t,n=!!document.queryCommandSupported;return e.forEach(function(t){n=n&&!!document.queryCommandSupported(t)}),n}}]),o}();function s(t,e){var n="data-clipboard-"+t;let isFun=e&&typeof e.hasAttribute==='function';if(isFun&&e.hasAttribute(n)){return e.getAttribute(n)}}
  t.exports=l},function(t,e,n){"use strict";var o,r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i=function(){function o(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}
  return function(t,e,n){return e&&o(t.prototype,e),n&&o(t,n),t}}(),a=n(2),c=(o=a)&&o.__esModule?o:{default:o};var u=function(){function e(t){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,e),this.resolveOptions(t),this.initSelection()}
  return i(e,[{key:"resolveOptions",value:function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:{};this.action=t.action,this.container=t.container,this.emitter=t.emitter,this.target=t.target,this.text=t.text,this.trigger=t.trigger,this.selectedText=""}},{key:"initSelection",value:function(){this.text?this.selectFake():this.target&&this.selectTarget()}},{key:"selectFake",value:function(){var t=this,e="rtl"==document.documentElement.getAttribute("dir");this.removeFake(),this.fakeHandlerCallback=function(){return t.removeFake()},this.fakeHandler=this.container.addEventListener("click",this.fakeHandlerCallback)||!0,this.fakeElem=document.createElement("textarea"),this.fakeElem.style.fontSize="12pt",this.fakeElem.style.border="0",this.fakeElem.style.padding="0",this.fakeElem.style.margin="0",this.fakeElem.style.position="absolute",this.fakeElem.style[e?"right":"left"]="-9999px";var n=window.pageYOffset||document.documentElement.scrollTop;this.fakeElem.style.top=n+"px",this.fakeElem.setAttribute("readonly",""),this.fakeElem.value=this.text,this.container.appendChild(this.fakeElem),this.selectedText=(0,c.default)(this.fakeElem),this.copyText()}},{key:"removeFake",value:function(){this.fakeHandler&&(this.container.removeEventListener("click",this.fakeHandlerCallback),this.fakeHandler=null,this.fakeHandlerCallback=null),this.fakeElem&&(this.container.removeChild(this.fakeElem),this.fakeElem=null)}},{key:"selectTarget",value:function(){this.selectedText=(0,c.default)(this.target),this.copyText()}},{key:"copyText",value:function(){var e=void 0;try{e=document.execCommand(this.action)}catch(t){e=!1}
      this.handleResult(e)}},{key:"handleResult",value:function(t){this.emitter.emit(t?"success":"error",{action:this.action,text:this.selectedText,trigger:this.trigger,clearSelection:this.clearSelection.bind(this)})}},{key:"clearSelection",value:function(){this.trigger&&this.trigger.focus(),window.getSelection().removeAllRanges()}},{key:"destroy",value:function(){this.removeFake()}},{key:"action",set:function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:"copy";if(this._action=t,"copy"!==this._action&&"cut"!==this._action)throw new Error('Invalid "action" value, use either "copy" or "cut"')},get:function(){return this._action}},{key:"target",set:function(t){if(void 0!==t){if(!t||"object"!==(void 0===t?"undefined":r(t))||1!==t.nodeType)throw new Error('Invalid "target" value, use a valid Element');if("copy"===this.action&&t.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if("cut"===this.action&&(t.hasAttribute("readonly")||t.hasAttribute("disabled")))throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');this._target=t}},get:function(){return this._target}}]),e}();t.exports=u},function(t,e){t.exports=function(t){var e;if("SELECT"===t.nodeName)t.focus(),e=t.value;else if("INPUT"===t.nodeName||"TEXTAREA"===t.nodeName){var n=t.hasAttribute("readonly");n||t.setAttribute("readonly",""),t.select(),t.setSelectionRange(0,t.value.length),n||t.removeAttribute("readonly"),e=t.value}else{t.hasAttribute("contenteditable")&&t.focus();var o=window.getSelection(),r=document.createRange();r.selectNodeContents(t),o.removeAllRanges(),o.addRange(r),e=o.toString()}
  return e}},function(t,e){function n(){}
  n.prototype={on:function(t,e,n){var o=this.e||(this.e={});return(o[t]||(o[t]=[])).push({fn:e,ctx:n}),this},once:function(t,e,n){var o=this;function r(){o.off(t,r),e.apply(n,arguments)}
      return r._=e,this.on(t,r,n)},emit:function(t){for(var e=[].slice.call(arguments,1),n=((this.e||(this.e={}))[t]||[]).slice(),o=0,r=n.length;o<r;o++)n[o].fn.apply(n[o].ctx,e);return this},off:function(t,e){var n=this.e||(this.e={}),o=n[t],r=[];if(o&&e)for(var i=0,a=o.length;i<a;i++)o[i].fn!==e&&o[i].fn._!==e&&r.push(o[i]);return r.length?n[t]=r:delete n[t],this}},t.exports=n},function(t,e,n){var d=n(5),h=n(6);t.exports=function(t,e,n){if(!t&&!e&&!n)throw new Error("Missing required arguments");if(!d.string(e))throw new TypeError("Second argument must be a String");if(!d.fn(n))throw new TypeError("Third argument must be a Function");if(d.node(t))return s=e,f=n,(l=t).addEventListener(s,f),{destroy:function(){l.removeEventListener(s,f)}};if(d.nodeList(t))return a=t,c=e,u=n,Array.prototype.forEach.call(a,function(t){t.addEventListener(c,u)}),{destroy:function(){Array.prototype.forEach.call(a,function(t){t.removeEventListener(c,u)})}};if(d.string(t))return o=t,r=e,i=n,h(document.body,o,r,i);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList");var o,r,i,a,c,u,l,s,f}},function(t,n){n.node=function(t){return void 0!==t&&t instanceof HTMLElement&&1===t.nodeType},n.nodeList=function(t){var e=Object.prototype.toString.call(t);return void 0!==t&&("[object NodeList]"===e||"[object HTMLCollection]"===e)&&"length"in t&&(0===t.length||n.node(t[0]))},n.string=function(t){return"string"==typeof t||t instanceof String},n.fn=function(t){return"[object Function]"===Object.prototype.toString.call(t)}},function(t,e,n){var a=n(7);function i(t,e,n,o,r){var i=function(e,n,t,o){return function(t){t.delegateTarget=a(t.target,n),t.delegateTarget&&o.call(e,t)}}.apply(this,arguments);return t.addEventListener(n,i,r),{destroy:function(){t.removeEventListener(n,i,r)}}}
  t.exports=function(t,e,n,o,r){return"function"==typeof t.addEventListener?i.apply(null,arguments):"function"==typeof n?i.bind(null,document).apply(null,arguments):("string"==typeof t&&(t=document.querySelectorAll(t)),Array.prototype.map.call(t,function(t){return i(t,e,n,o,r)}))}},function(t,e){if("undefined"!=typeof Element&&!Element.prototype.matches){var n=Element.prototype;n.matches=n.matchesSelector||n.mozMatchesSelector||n.msMatchesSelector||n.oMatchesSelector||n.webkitMatchesSelector}
  t.exports=function(t,e){for(;t&&9!==t.nodeType;){if("function"==typeof t.matches&&t.matches(e))return t;t=t.parentNode}}}])});let Types={isFunction:function(obj){var type=Object.prototype.toString.call(obj)
    return type=='[object Function]'},isObject:function(obj){var type=Object.prototype.toString.call(obj)
    return type=='[object Object]'},isString:function(obj){var type=Object.prototype.toString.call(obj)
    return type=='[object String]'}}
uni.setClipboardData=function(options){let emptyFun=function(){}
  let config={data:null,event:null,success:emptyFun,fail:emptyFun,complete:emptyFun}
  if(options&&Types.isObject(options)){config=Object.assign({},config,options)}
  if(options&&Types.isString(options)){config=Object.assign({},config,{data:options})}
  let data=config.data
  let success=config.success||emptyFun
  let fail=config.fail||emptyFun
  let complete=config.complete||emptyFun
  let e=config.event||window.event||{}
  let cb=new ClipboardJS('.null',{text:()=>data})
  cb.on('success',function(res){
    window.__clipboard__=data;
    success&&Types.isFunction(success)&&success({data:res.text})
    complete&&Types.isFunction(complete)&&complete()
    cb.off('error')
    cb.off('success')
    cb.destroy()})
  cb.on('error',function(err){fail&&Types.isFunction(fail)&&fail(err)
    complete&&Types.isFunction(complete)&&complete()
    cb.off('error')
    cb.off('success')
    cb.destroy()})
  cb.onClick(e)};
uni.getClipboardData=function(options){let emptyFun=function(){}
    let config={data:null,event:null,success:emptyFun,fail:emptyFun,complete:emptyFun}
    if(options&&Types.isObject(options)){config=Object.assign({},config,options)}
    let success=config.success||emptyFun
    let fail=config.fail||emptyFun
    let complete=config.complete||emptyFun
    if(window.__clipboard__!==undefined){success&&Types.isFunction(success)&&success({data:window.__clipboard__})}else{fail&&Types.isFunction(fail)&&fail({data:null})}
    complete&&Types.isFunction(complete)&&complete()};
function fileDownLoad(data){var linkElement=document.createElement('a')
  linkElement.setAttribute('href',data.blob)
  linkElement.setAttribute('downLoad',data.name)
  linkElement.click()}
uni.saveImageToPhotosAlbum=uni.saveVideoToPhotosAlbum=function(options){let emptyFun=function(){}
  let config={filePath:null,success:emptyFun,fail:emptyFun,complete:emptyFun}
  if(options&&Types.isObject(options)){config=Object.assign({},config,options)}
  if(options&&Types.isString(options)){config=Object.assign({},config,{filePath:options})}
  let filePath=config.filePath
  let success=config.success||emptyFun
  let fail=config.fail||emptyFun
  let complete=config.complete||emptyFun
  if(!filePath){fail&&Types.isFunction(fail)&&fail({msg:'no File'})
    complete&&Types.isFunction(complete)&&complete()
    return}
  let names=filePath.split('/')
  let name=names[names.length-1]
  uni.downloadFile({url:filePath,success:function(res){let tempFilePath=res.tempFilePath
      fileDownLoad({name:name,blob:tempFilePath})
      success&&Types.isFunction(success)&&success({filePath:filePath})},fail:function(err){fail&&Types.isFunction(fail)&&fail({msg:err})},complete:function(){complete&&Types.isFunction(complete)&&complete()}})}
//#endif

components

area-picker

areaPicker.vue
<template>
    <view>
        <view class="picker-mask" @click="closePicker" catchtouchmove="true" v-show="pickerShow"  ></view>
        <view class="picker-content" :class="{'pickerShow':pickerShow}" >
            <view class="picker-button">
                <text @click="closePicker">取消</text>
                <text @click="confirm">确定</text>
            </view>
            <!-- 三列选择-联动 -->
            <picker-view class="picker-view" indicator-class="picker-view-selected-three" :value="pickerIndex" @change="pickerViewChangeThree">
                <picker-view-column>
                    <view class="picker-item" v-for="(item, index) in pickerList" :key="index">{{item.label}}</view>
                </picker-view-column>
                <picker-view-column >
                    <view class="picker-item" v-for="(item, index) in pickerList[pickerIndex[0]].children" :key="index">{{item.label}}</view>
                </picker-view-column>
                <picker-view-column>
                    <view class="picker-item" v-for="(item, index) in pickerList[pickerIndex[0]].children[pickerIndex[1]].children"
                     :key="index">{{item.label}}</view>
                </picker-view-column>
            </picker-view>
        </view>
    </view>
</template>

<script>
    // mode所有类型
    let pickerModeArray = ["one", "two_linkage", "two_nolinkage", "three"];

    export default {
        name: "area-picker",
        props: {
            areaId:{
                type: Number,
                required: true,
            },
            // 默认picker选中项索引
            defaultIndex: {
                type: Array,
                required: true,
                validator: (value) => {
                    if (value.length > 0 && value.length <= 3) {
                        return true;
                    }
                    return false;
                }
            }
        },
        data() {
            return {
                pickerIndex: [0,0,0], // picker索引值
                pickerShow: false,
                region: ['河南省', '郑州市', '中原区'], //开户行地区
                provinceKey:-1,//省份id
                cityKey:-1,//市id
                areaKey:-1,//区域id
                selectedData:[],
                pickerList:this.$db.get("areaList"),
                province:this.$db.get("areaList"),
            };
        },
        created() {
            this.init();
        },
        watch: {
            // 匹配选中索引
            mode() {
                this.pickerIndex = this.defaultIndex;
            }
        },
        methods: {
            init(){
                this.province = this.$db.get("areaList");
                //查找省市区 id
                this.getFullPath(this.areaId,this.province);
                this.pickerIndex = [this.provinceKey,this.cityKey,this.areaKey];
            },
            //倒查城市信息
            getFullPath(id,data){
                for(var i = 0;i<data.length;i++){
                    if(id == data[i].value){
                        if(!data[i].children){
                            this.areaKey = i;
                            return true;
                        }else if(data[i].hasOwnProperty("children")){
                            if(data[i].children[0] && !data[i].children[0].children){
                                this.cityKey = i;
                                return true;
                            }else{
                                this.provinceKey = i;
                                return true;
                            }
                        }
                    }else{
                        if(data[i].hasOwnProperty("children")){
                            if(data[i].children[0]!==undefined){
                                if(data[i].children[0].hasOwnProperty("children")){
                                    this.provinceKey = i;
                                }else{
                                    this.cityKey = i;
                                }
                            }
                            if(typeof data[i].children !='undefined' ){
                                var res = this.getFullPath(id,data[i].children);
                                if(res){
                                    return true;
                                }
                            }
                        }
                    }
                }
            },
            // 三列联动选项变化
            pickerViewChangeThree(e) {
                let changeValue = e.detail.value;
                
                // 超规处理
                if (this.pickerList[changeValue[0]].children.length - 1 < changeValue[1]) {
                    changeValue[1] = this.pickerList[changeValue[0]].children.length - 1;
                }
                if (this.pickerList[changeValue[0]].children[changeValue[1]].children.length - 1 < changeValue[2]) {
                    changeValue[2] = this.pickerList[changeValue[0]].children[changeValue[1]].children.length - 1;
                }
                this.pickerIndex = changeValue;
            },
            // 显示组件
            showPicker() {
                // 隐藏软件盘
                uni.hideKeyboard();
                this.init();
                this.pickerShow = true;
            },
            // 确定事件——返回选中项的数组索引(也可以自定义其他返回数据,不过返回索引通用性更强)
            confirm() {
                this.pickerShow = false;
                this.selectedData = [
                    {
                        id:this.province[this.pickerIndex[0]].value,
                        name:this.province[this.pickerIndex[0]].label,
                    },
                    {
                        id:this.province[this.pickerIndex[0]].children[this.pickerIndex[1]].value,
                        name:this.province[this.pickerIndex[0]].children[this.pickerIndex[1]].label,
                    },
                    {
                        id:this.province[this.pickerIndex[0]].children[this.pickerIndex[1]].children[this.pickerIndex[2]].value,
                        name:this.province[this.pickerIndex[0]].children[this.pickerIndex[1]].children[this.pickerIndex[2]].label,
                    },
                ];
                this.$emit("onConfirm", this.selectedData);
            },
            // 隐藏组件
            closePicker() {
                this.pickerShow = false;
            }
        }
    }
</script>

<style>
    .picker-mask {
        position: fixed;
        top: 0;
        right: 0;
        left: 0;
        bottom: 0;
        z-index: 50;
        width: 100%;
        height: 100%;
        background-color: rgba(0, 0, 0, 0.3);
    }

    .picker-content {
        flex-direction: column;
        position: fixed;
        bottom: 0;
        left: 0;
        z-index: 100;
        width: 100%;
        height: 600upx;
        background-color: #FFFFFF;
        transform: translateY(100%);
        transition: all 200ms ease;
    }

    .pickerShow {
        transform: translateY(0) !important;
    }

    .picker-content .picker-button {
        justify-content: space-between;
        height: 80upx;
        line-height: 80upx;
    }

    .picker-button text {
        width: 180upx;
        font-size: 28upx;
        font-weight: 500;
        display: block;
        text-align: center;
        overflow: hidden;
    }

    .picker-button text:first-child {
        color: #A1A1A1;
        float: left;
    }

    .picker-button text:last-child {
        color: #FF7159;
        float: right;
    }

    .picker-content .picker-view {
        width: 100%;
        height: 500upx;
    }

    .picker-content .picker-view-selected-one,
    .picker-content .picker-view-selected-two,
    .picker-content .picker-view-selected-three {
        height: 68upx;
        line-height: 68upx;
        border-top: #1AAD19 1upx solid;
        border-bottom: #1AAD19 1upx solid;
    }

    .picker-content .picker-view-selected-one {
        position: relative;
        left: 25%;
        width: 50%;
    }

    .picker-content .picker-view-selected-two {
        position: relative;
        left: 15%;
        width: 70%;
    }

    .picker-content .picker-view-selected-three {
        position: relative;
        left: 5%;
        width: 90%;
    }

    .picker-view .picker-item {
        width: 100%;
        height: 34px;
        line-height: 34px;
        font-size: 15px;
        font-weight: 600;
        display: block;
        text-align: center;
    }
</style>

cmd-progress

cmd-progress.vue
<template>
  <view class="cmd-progress cmd-progress-default" :class="setStatusClass">
    <block v-if="type == 'circle' || type == 'dashboard'">
      <view class="cmd-progress cmd-progress-default" :class="setStatusClass">
        <view class="cmd-progress-inner" :style="setCircleStyle">
          <!-- 绘制圈 start -->
          <!-- #ifdef H5 -->
          <svg viewBox="0 0 100 100" class="cmd-progress-circle">
            <path :d="setCirclePath" stroke="#f3f3f3" :stroke-linecap="strokeShape" :stroke-width="strokeWidth"
              fill-opacity="0" class="cmd-progress-circle-trail" :style="setCircleTrailStyle"></path>
            <path :d="setCirclePath" :stroke-linecap="strokeShape" :stroke-width="strokeWidth" fill-opacity="0" class="cmd-progress-circle-path"
              :style="setCirclePathStyle"></path>
          </svg>
          <!-- #endif -->
          <!-- #ifndef H5 -->
          <text :style="setCircle"></text>
          <!-- #endif -->
          <!-- 绘制圈 end -->
          <!-- 状态文本 start -->
          <block v-if="showInfo && !custom">
            <text class="cmd-progress-text" :title="setFormat">
              <block v-if="status != 'success' && status != 'exception' && setProgress < 100">{{setFormat}}</block>
              <!-- #ifdef H5 -->
              <svg v-if="status == 'exception'" viewBox="64 64 896 896" data-icon="close" width="1.5em" height="1.5em" fill="currentColor"
                aria-hidden="true">
                <path d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 0 0 203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"></path>
              </svg>
              <svg v-if="status == 'success' || setProgress == 100" viewBox="64 64 896 896" data-icon="check" width="1.5em"
                height="1.5em" fill="currentColor" aria-hidden="true" :style="{'color': strokeColor ? strokeColor : ''}">
                <path d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z"></path>
              </svg>
              <!-- #endif -->
              <!-- #ifndef H5 -->
              <text v-if="status == 'exception' || status == 'success' || setProgress == 100" :style="setCircleIcon"></text>
              <!-- #endif -->
            </text>
          </block>
          <block v-else>
            <view class="cmd-progress-custom">
              <slot></slot>
            </view>
          </block>
          <!-- 状态文本 end -->
        </view>
      </view>
    </block>

    <block v-if="type == 'line'">
      <!-- 进度条 start -->
      <view class="cmd-progress-outer">
        <view class="cmd-progress-inner" :style="{'border-radius': strokeShape == 'square' ? 0 : '100px'}">
          <view class="cmd-progress-bg" :style="setLineStyle"></view>
          <view v-if="successPercent" class="cmd-progress-success-bg" :style="setLineSuccessStyle"></view>
        </view>
      </view>
      <!-- 进度条 end -->
      <!-- 进度条是否显示信息 start -->
      <block v-if="showInfo && !custom">
        <text class="cmd-progress-text" :title="setFormat">
          <block v-if="status != 'success' && status != 'exception' && setProgress < 100">{{setFormat}}</block>
          <!-- #ifdef H5 -->
          <svg v-if="status == 'exception'" viewBox="64 64 896 896" data-icon="close-circle" width="1.5em" height="1.5em"
            fill="currentColor" aria-hidden="true">
            <path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66-.3L512 563.4l-99.3 118.4-66.1.3c-4.4 0-8-3.5-8-8 0-1.9.7-3.7 1.9-5.2l130.1-155L340.5 359a8.32 8.32 0 0 1-1.9-5.2c0-4.4 3.6-8 8-8l66.1.3L512 464.6l99.3-118.4 66-.3c4.4 0 8 3.5 8 8 0 1.9-.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z"></path>
          </svg>
          <svg v-if="status == 'success' || setProgress == 100" viewBox="64 64 896 896" data-icon="check-circle" width="1.5em"
            height="1.5em" fill="currentColor" aria-hidden="true" :style="{'color': strokeColor ? strokeColor : ''}">
            <path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm193.5 301.7l-210.6 292a31.8 31.8 0 0 1-51.7 0L318.5 484.9c-3.8-5.3 0-12.7 6.5-12.7h46.9c10.2 0 19.9 4.9 25.9 13.3l71.2 98.8 157.2-218c6-8.3 15.6-13.3 25.9-13.3H699c6.5 0 10.3 7.4 6.5 12.7z"></path>
          </svg>
          <!-- #endif -->
          <!-- #ifndef H5 -->
          <text v-if="status == 'exception' || status == 'success' || setProgress == 100" :style="setLineStatusIcon"></text>
          <!-- #endif -->
        </text>
      </block>
      <block v-else>
        <view class="cmd-progress-custom">
          <slot></slot>
        </view>
      </block>
      <!-- 进度条是否显示信息 end -->
    </block>
  </view>
</template>

<script>
  /**  
   * 进度条组件  
   * @description 显示一个操作完成的百分比时,为用户显示该操作的当前进度和状态。  
   * @tutorial https://ext.dcloud.net.cn/plugin?id=259  
   * @property {String} type 进度类型 - 线型:line、圆圈形:circle、仪表盘:dashboard,默认线型:line  
   * @property {Number} percent 进度百分比值 - 显示范围0-100 ,可能数比较大就需要自己转成百分比的值  
   * @property {Number} success-percent 进度已完成的百分几 - 仅支持进度线型:line  
   * @property {String} status 进度状态 - 涌动:active(仅支持线型:line)、正常:normal、完成:success、失败:exception,默认正常:normal  
   * @property {Boolean} show-info 进度状态信息 - 是否显示进度数值或状态图标,默认true  
   * @property {Number} stroke-width 进度线条的宽度 - 建议在条线的宽度范围:1-50,与进度条显示宽度有关,默认8  
   * @property {String} stroke-color 进度线条的颜色 - 渐变色仅支持线型:line  
   * @property {String} stroke-shape 进度线条两端的形状 - 圆:round、方块直角:square,默认圆:round  
   * @property {Number} width 进度画布宽度 - 仅支持圆圈形:circle、仪表盘:dashboard,默认80  
   * @property {String} gap-degree 进度圆形缺口角度 - 可取值 0 ~ 360,仅支持圆圈形:circle、仪表盘:dashboard  
   * @property {String} gap-position 进度圆形缺口位置 - 可取值'top', 'bottom', 'left', 'right',仅支持圆圈形:circle、仪表盘:dashboard  
   * @property {Boolean} custom 自定义文本格式插槽,条line:圈circle 仪表板dashboard  
   * @example <cmd-progress :percent="30"></cmd-progress>  
   */
  export default {
    name: 'cmd-progress',

    props: {
      /**
       * 类型默认:line,可选 line circle dashboard
       */
      type: {
        validator: val => {
          return ['line', 'circle', 'dashboard'].includes(val);
        },
        default: 'line'
      },
      /**
       * 百分比
       */
      percent: {
        type: Number,
        default: 0
      },
      /**
       * 已完成的分段百分,仅支持类型line
       */
      successPercent: {
        type: Number,
        default: 0
      },
      /**
       * 是否显示进度数值或状态图标
       */
      showInfo: {
        type: Boolean,
        default: true
      },
      /**
       * 自定义文本格式插槽,条line:圈circle 仪表板dashboard
       */
      custom: {
        type: Boolean,
        default: false
      },
      /**
       * 进度状态,可选:normal success exception (active仅支持类型line
       */
      status: {
        validator: val => {
          return ['normal', 'success', 'exception', 'active'].includes(val);
        },
        default: 'normal'
      },
      /**
       * 条线的宽度1-50,与width有关
       */
      strokeWidth: {
        type: Number,
        default: 6
      },
      /**
       * 条线的颜色,渐变色仅支持类型line
       */
      strokeColor: {
        type: String,
        default: ''
      },
      /**
       * 条线两端的形状 可选:'round', 'square'
       */
      strokeShape: {
        validator: val => {
          return ['round', 'square'].includes(val);
        },
        default: 'round'
      },
      /**
       * 圆形进度条画布宽度,支持类型circle dashboard
       */
      width: {
        type: Number,
        default: 80
      },
      /**
       * 圆形进度条缺口角度,可取值 0 ~ 360,支持类型circle dashboard
       */
      gapDegree: {
        type: Number,
        default: 0
      },
      /**
       * 圆形进度条缺口位置,可取值'top', 'bottom', 'left', 'right' ,支持类型circle dashboard
       */
      gapPosition: {
        validator: val => {
          return ['top', 'bottom', 'left', 'right'].includes(val);
        },
        default: 'top'
      }
    },

    computed: {
      /**
       * 百分比格式
       */
      setFormat() {
        return `${this.setProgress}%`;
      },
      /**
       * 设置显示进度值,禁止小于0和超过100
       */
      setProgress() {
        let percent = this.percent;
        if (!this.percent || this.percent < 0) {
          percent = 0;
        } else if (this.percent >= 100) {
          percent = 100;
        }
        return percent;
      },
      /**
       * 进度圈svg大小
       */
      setCircleStyle() {
        return `width: ${this.width}px;
                height: ${this.width}px;
                fontSize: ${this.width * 0.15 + 6}px;`
      },
      /**
       * 圈底色
       */
      setCircleTrailStyle() {
        const radius = 50 - this.strokeWidth / 2;
        const len = Math.PI * 2 * radius;
        const gapDeg = this.gapDegree || (this.type === 'dashboard' && 75);
        return `stroke-dasharray: ${len - (gapDeg||0)}px, ${len}px;
                stroke-dashoffset: -${(gapDeg||0) / 2}px;
                transition: stroke-dashoffset 0.3s ease 0s, stroke-dasharray 0.3s ease 0s, stroke 0.3s;`
      },
      /**
       * 圈进度
       */
      setCirclePathStyle() {
        const radius = 50 - this.strokeWidth / 2;
        const len = Math.PI * 2 * radius;
        const gapDeg = this.gapDegree || (this.type === 'dashboard' && 75);
        return `stroke: ${this.strokeColor};
                stroke-dasharray: ${(this.setProgress / 100) * (len - (gapDeg||0))}px, ${len}px;
                stroke-dashoffset: -${(gapDeg||0) / 2}px;
                transition: stroke-dashoffset 0.3s ease 0s, stroke-dasharray 0.3s ease 0s, stroke 0.3s, stroke-width 0.06s ease 0.3s;`
      },
      /**
       * 绘制圈
       */
      setCirclePath() {
        const radius = 50 - this.strokeWidth / 2;
        let beginPositionX = 0;
        let beginPositionY = -radius;
        let endPositionX = 0;
        let endPositionY = -2 * radius;
        const gapPos = (this.type === 'dashboard' && 'bottom') || this.gapPosition || 'top';
        switch (gapPos) {
          case 'left':
            beginPositionX = -radius;
            beginPositionY = 0;
            endPositionX = 2 * radius;
            endPositionY = 0;
            break;
          case 'right':
            beginPositionX = radius;
            beginPositionY = 0;
            endPositionX = -2 * radius;
            endPositionY = 0;
            break;
          case 'bottom':
            beginPositionY = radius;
            endPositionY = 2 * radius;
            break;
          default:
            break;
        }
        return `M 50,50 m ${beginPositionX},${beginPositionY} a ${radius},${radius} 0 1 1 ${endPositionX},${-endPositionY} a ${radius},${radius} 0 1 1 ${-endPositionX},${endPositionY}`;
      },
      // #ifndef H5
      /**
       * 非H5端,绘制进度圈svg转base URL
       */
      setCircle() {
        const radius = 50 - this.strokeWidth / 2;
        const len = Math.PI * 2 * radius;
        const gapDeg = this.gapDegree || (this.type === 'dashboard' && 75);
        let currentColor = '#108ee9'
        // 异常进度
        if (this.status == 'exception') {
          currentColor = '#f5222d'
        }
        // 完成进度
        if (this.status == 'success' || this.setProgress >= 100 || this.strokeColor) {
          currentColor = this.strokeColor || '#fff'
        }
        let svgToBase =
          `data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' class='cmd-progress-circle'%3E%3Cpath d='${this.setCirclePath}' stroke='%23f3f3f3' stroke-linecap='${this.strokeShape}' stroke-width='${this.strokeWidth}' fill-opacity='0' class='cmd-progress-circle-trail' style='stroke-dasharray: ${len - (gapDeg||0)}px, ${len}px;stroke-dashoffset: -${(gapDeg||0) / 2}px;transition: stroke-dashoffset 0.3s ease 0s, stroke-dasharray 0.3s ease 0s, stroke 0.3s;'%3E%3C/path%3E%3Cpath  d='${this.setCirclePath}' stroke-linecap='${this.strokeShape}' stroke-width='${this.strokeWidth}' fill-opacity='0' class='cmd-progress-circle-path' style='stroke: ${currentColor};stroke-dasharray: ${(this.setProgress / 100) * (len - (gapDeg||0))}px, ${len}px;stroke-dashoffset: -${(gapDeg||0) / 2}px;transition: stroke-dashoffset 0.3s ease 0s, stroke-dasharray 0.3s ease 0s, stroke 0.3s, stroke-width 0.06s ease 0.3s;'%3E%3C/path%3E%3C/svg%3E`
        return `background-image: url("${svgToBase}");
                background-size: cover;
                display: inline-block;
                ${this.setCircleStyle}`;
      },
      /**
       * 设置进度圈状态图标
       */
      setCircleIcon() {
        let currentColor = '#108ee9'
        let svgToBase = ''
        // 异常进度
        if (this.status == 'exception') {
          currentColor = '#f5222d'
          svgToBase =
            `data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='64 64 896 896' data-icon='close' width='1.5em' height='1.5em' fill='${currentColor}' aria-hidden='true'%3E %3Cpath d='M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 0 0 203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z'%3E%3C/path%3E %3C/svg%3E`;
        }
        // 完成进度
        if (this.status == 'success' || this.setProgress >= 100) {
          currentColor = this.strokeColor || '#fff'
          svgToBase =
            `data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='64 64 896 896' data-icon='check' width='1.5em' height='1.5em' fill='${currentColor}' aria-hidden='true'%3E %3Cpath d='M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z'%3E%3C/path%3E %3C/svg%3E`;
        }
        return `background-image: url("${svgToBase}");
                background-size: cover;
                display: inline-block;
                width: 1.5em;
                height: 1.5em;`;
      },
      // #endif
      /**
       * 设置进度条样式
       */
      setLineStyle() {
        return `width: ${this.setProgress}%;
                height: ${this.strokeWidth}px;
                background: ${this.strokeColor};
                border-radius: ${this.strokeShape === 'square' ? 0 : '100px'};`;
      },
      /**
       * 设置已完成分段进度
       */
      setLineSuccessStyle() {
        let successPercent = this.successPercent;
        if (!this.successPercent || this.successPercent < 0 || this.setProgress < this.successPercent) {
          successPercent = 0;
        } else if (this.successPercent >= 100) {
          successPercent = 100;
        }
        return `width: ${successPercent}%;
                height: ${this.strokeWidth}px;
                border-radius: ${this.strokeShape === 'square' ? 0 : '100px'};`;
      },
      // #ifndef H5
      /**
       * 设置进度条状态图标
       */
      setLineStatusIcon() {
        let currentColor = '#108ee9'
        let svgToBase = ''
        // 异常进度
        if (this.status == 'exception') {
          currentColor = '#f5222d'
          svgToBase =
            `data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='64 64 896 896' data-icon='close-circle' width='1.5em' height='1.5em' fill='${currentColor}' aria-hidden='true'%3E %3Cpath d='M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm165.4 618.2l-66-.3L512 563.4l-99.3 118.4-66.1.3c-4.4 0-8-3.5-8-8 0-1.9.7-3.7 1.9-5.2l130.1-155L340.5 359a8.32 8.32 0 0 1-1.9-5.2c0-4.4 3.6-8 8-8l66.1.3L512 464.6l99.3-118.4 66-.3c4.4 0 8 3.5 8 8 0 1.9-.7 3.7-1.9 5.2L553.5 514l130 155c1.2 1.5 1.9 3.3 1.9 5.2 0 4.4-3.6 8-8 8z'%3E%3C/path%3E %3C/svg%3E`;
        }
        // 完成进度
        if (this.status == 'success' || this.setProgress >= 100) {
          currentColor = this.strokeColor || '#fff'
          svgToBase =
            `data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='64 64 896 896' data-icon='check-circle' width='1.5em' height='1.5em' fill='${currentColor}' aria-hidden='true'%3E %3Cpath d='M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm193.5 301.7l-210.6 292a31.8 31.8 0 0 1-51.7 0L318.5 484.9c-3.8-5.3 0-12.7 6.5-12.7h46.9c10.2 0 19.9 4.9 25.9 13.3l71.2 98.8 157.2-218c6-8.3 15.6-13.3 25.9-13.3H699c6.5 0 10.3 7.4 6.5 12.7z'%3E%3C/path%3E %3C/svg%3E`;
        }
        return `background-image: url("${svgToBase}");
                background-size: cover;
                display: inline-block;
                width: 1.5em;
                height: 1.5em;`;
      },
      // #endif
      /**
       * 状态样式
       */
      setStatusClass() {
        let statusClass = [];
        // 异常进度
        if (this.status == 'exception') {
          statusClass.push('cmd-progress-status-exception')
        }
        // 完成进度
        if (this.status == 'success' || this.setProgress >= 100) {
          statusClass.push('cmd-progress-status-success')
        }
        // 活动进度条
        if (this.status == 'active') {
          statusClass.push('cmd-progress-status-active')
        }
        // 是否显示信息
        if (this.showInfo) {
          statusClass.push('cmd-progress-show-info')
        }
        // 进度条类型
        if (this.type === 'line') {
          statusClass.push('cmd-progress-line')
        }
        // 进度圈、仪表盘类型
        if (this.type === 'circle' || this.type === 'dashboard') {
          statusClass.push('cmd-progress-circle')
        }
        statusClass.push('cmd-progress-status-normal')
        return statusClass;
      }
    }
  }
</script>

<style>
  .cmd-progress {
    font-family: "Chinese Quote", -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
    font-size: 28upx;
    font-variant: tabular-nums;
    line-height: 1.5;
    color: rgba(0, 0, 0, 0.65);
    box-sizing: border-box;
    margin: 0;
    padding: 0;
    list-style: none;
    display: inline-block;
  }

  .cmd-progress-line {
    width: 100%;
    font-size: 28upx;
    position: relative;
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: center;
  }

  .cmd-progress-outer {
    display: inline-block;
    width: 100%;
    margin-right: 0;
    padding-right: 0;
  }

  .cmd-progress-show-info .cmd-progress-outer {
    flex: 1;
  }

  .cmd-progress-inner {
    display: inline-block;
    width: 100%;
    background-color: #f5f5f5;
    border-radius: 200upx;
    vertical-align: middle;
    position: relative;
  }

  .cmd-progress-circle-trail {
    stroke: #f5f5f5;
  }

  .cmd-progress-circle-path {
    stroke: #1890ff;
    animation: appear 0.3s;
  }

  .cmd-progress-success-bg,
  .cmd-progress-bg {
    background-color: #1890ff;
    transition: all 0.4s cubic-bezier(0.08, 0.82, 0.17, 1) 0s;
    position: relative;
  }

  .cmd-progress-success-bg {
    background-color: #fff;
    position: absolute;
    top: 0;
    left: 0;
  }

  .cmd-progress-custom {
    max-width: 50%;
    margin-left: 16upx;
    vertical-align: middle;
    display: inline-block;
    white-space: normal;
    word-wrap: break-word;
    word-break: break-all;
    line-height: 1;
  }

  .cmd-progress-text {
    min-width: 60upx;
    text-align: left;
    margin-left: 16upx;
    vertical-align: middle;
    display: inline-block;
    white-space: normal;
    color: rgba(255, 255, 255, 0.8);
    line-height: 1;
  }

  .cmd-progress-status-active .cmd-progress-bg:before {
    content: "";
    opacity: 0;
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: #fff;
    border-radius: 20upx;
    -webkit-animation: cmd-progress-active 2.4s cubic-bezier(0.23, 1, 0.32, 1) infinite;
    animation: cmd-progress-active 2.4s cubic-bezier(0.23, 1, 0.32, 1) infinite;
  }

  .cmd-progress-status-exception .cmd-progress-bg {
    background-color: #f5222d;
  }

  .cmd-progress-status-exception .cmd-progress-text {
    color: #f5222d;
  }

  .cmd-progress-status-exception .cmd-progress-circle-path {
    stroke: #f5222d;
  }

  .cmd-progress-status-success .cmd-progress-bg {
    background-color: #fff;
  }

  .cmd-progress-status-success .cmd-progress-text {
    color: #fff;
  }

  .cmd-progress-status-success .cmd-progress-circle-path {
    stroke: #fff;
  }

  .cmd-progress-circle .cmd-progress-inner {
    position: relative;
    line-height: 1;
    background-color: transparent;
  }

  .cmd-progress-circle .cmd-progress-custom {
    display: block;
    position: absolute;
    line-height: 1;
    top: 50%;
    -webkit-transform: translateY(-50%);
    transform: translateY(-50%);
    left: 25%;
    right: 25%;
    margin: 0;
    overflow: hidden;
    white-space: normal;
    word-wrap: break-word;
    word-break: break-all;
  }

  .cmd-progress-circle .cmd-progress-text {
    display: block;
    position: absolute;
    width: 100%;
    text-align: center;
    line-height: 1;
    top: 50%;
    -webkit-transform: translateY(-50%);
    transform: translateY(-50%);
    left: 0;
    margin: 0;
    color: rgba(0, 0, 0, 0.65);
    white-space: normal;
  }

  .cmd-progress-circle .cmd-progress-status-exception .cmd-progress-text {
    color: #f5222d;
  }

  .cmd-progress-circle .cmd-progress-status-success .cmd-progress-text {
    color: #fff;
  }

  @keyframes cmd-progress-active {
    0% {
      opacity: 0.1;
      width: 0;
    }

    20% {
      opacity: 0.5;
      width: 0;
    }

    100% {
      opacity: 0;
      width: 100%;
    }
  }
</style>

gaoyia-parse

components
wxParseAudio.vue
<template>
    <!-- '<audio/>' 组件不再维护,建议使用能力更强的 'uni.createInnerAudioContext' 接口 有时间再改-->
  <!--增加audio标签支持-->
  <audio
    :id="node.attr.id"
    :class="node.classStr"
    :style="node.styleStr"
    :src="node.attr.src"
    :loop="node.attr.loop"
    :poster="node.attr.poster"
    :name="node.attr.name"
    :author="node.attr.author"
    controls></audio>
</template>

<script>
export default {
  name: 'wxParseAudio',
  props: {
    node: {
      type: Object,
      default() {
        return {};
      },
    },
  },
};
</script>
wxParseImg.vue
<template>
    <image
        :mode="node.attr.mode"
        :lazy-load="node.attr.lazyLoad"
        :class="node.classStr"
        :style="newStyleStr || node.styleStr"
        :data-src="node.attr.src"
        :src="node.attr.src"
        @tap="wxParseImgTap"
        @load="wxParseImgLoad"
    />
</template>

<script>
export default {
    name: 'wxParseImg',
    data() {
        return {
            newStyleStr: '',
            preview: true
        };
    },
    inject: ['parseWidth'],
    mounted() {},
    props: {
        node: {
            type: Object,
            default() {
                return {};
            }
        }
    },
    
    methods: {
        wxParseImgTap(e) {
            if (!this.preview) return;
            const { src } = e.currentTarget.dataset;
            if (!src) return;
            let parent = this.$parent;
            while (!parent.preview || typeof parent.preview !== 'function') {
                // TODO 遍历获取父节点执行方法
                parent = parent.$parent;
            }
            parent.preview(src, e);
        },
        // 图片视觉宽高计算函数区
        wxParseImgLoad(e) {
            const { src } = e.currentTarget.dataset;
            if (!src) return;
            let { width, height } = e.mp.detail;

            const recal = this.wxAutoImageCal(width, height);

            const { imageheight, imageWidth } = recal;
            const { padding, mode } = this.node.attr;//删除padding
            // const { mode } = this.node.attr;

            const { styleStr } = this.node;
            const imageHeightStyle = mode === 'widthFix' ? '' : `height: ${imageheight}px;`;

            this.newStyleStr = `${styleStr}; ${imageHeightStyle}; width: ${imageWidth}px; padding: 0 ${+padding}px;`;//删除padding
            // this.newStyleStr = `${styleStr}; ${imageHeightStyle}; width: ${imageWidth}px;`;
        },
        // 计算视觉优先的图片宽高
        wxAutoImageCal(originalWidth, originalHeight) {
            // 获取图片的原始长宽
            const windowWidth = this.parseWidth.value;
            const results = {};

            if (originalWidth < 60 || originalHeight < 60) {
                const { src } = this.node.attr;
                let parent = this.$parent;
                while (!parent.preview || typeof parent.preview !== 'function') {
                    parent = parent.$parent;
                }
                parent.removeImageUrl(src);
                this.preview = false;
            }

            // 判断按照那种方式进行缩放
            if (originalWidth > windowWidth) {
                // 在图片width大于手机屏幕width时候
                results.imageWidth = windowWidth;
                results.imageheight = windowWidth * (originalHeight / originalWidth);
            } else {
                // 否则展示原来的数据
                results.imageWidth = originalWidth;
                results.imageheight = originalHeight;
            }
            return results;
        }
    }
};
</script>
wxParseTable.vue
<template>
    <rich-text :nodes="nodes"></rich-text>
</template>

<script>
export default {
    name: 'wxParseTable',
    props: {
        node: {
            type: Object,
            default() {
                return {};
            },
        },
    },
    data() {
        return {
            nodes:[]
        };
    },
    mounted() {
        this.nodes=this.loadNode([this.node]);
    },
    methods: {
        loadNode(node) {
            let obj = [];
            for (let children of node) {
                // console.log(children)
                if (children.node=='element') {
                    let t = {
                        name:children.tag,
                        attrs: {
                            class: children.classStr,
                            // style: children.styleStr,
                        },
                        children: children.nodes?this.loadNode(children.nodes):[]
                    }
                    
                    obj.push(t)
                } else if(children.node=='text'){
                    obj.push({
                        type: 'text',
                        text: children.text
                    })
                }
            }
            return obj
        }
    }
};
</script>
wxParseTemplate0.vue
<template>
    <!--判断是否是标签节点-->
    <block v-if="node.node == 'element'">
        <!--button类型-->
        <button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
            <wx-parse-template :node="node" />
        </button>
        
        <!--a类型-->
        <view v-else-if="node.tag == 'a'" @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
                <wx-parse-template :node="node" />
            </block>
        </view>
        
        <!--li类型-->
        <view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
                <wx-parse-template :node="node" />
            </block>
        </view>
        
        <!--table类型-->
        <wx-parse-table v-else-if="node.tag == 'table'" :node="node" />
        
        <!--br类型-->
        <!-- #ifndef H5 -->
            <text v-else-if="node.tag == 'br'">\n</text>
        <!-- #endif -->
        <!-- #ifdef H5 -->
            <br v-else-if="node.tag == 'br'">
        <!-- #endif -->
        
        <!--video类型-->
        <wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
    
        <!--audio类型-->
        <wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
    
        <!--img类型-->
        <wx-parse-img :node="node" v-else-if="node.tag == 'img'"/>
    
        <!--其他标签-->
        <view v-else :class="node.classStr" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
                <wx-parse-template :node="node" />
            </block>
        </view>
    </block>
    
    <!--判断是否是文本节点-->
    <block v-else-if="node.node == 'text'">{{node.text}}</block>
</template>

<script>
    import wxParseTemplate from './wxParseTemplate1';
    import wxParseImg from './wxParseImg';
    import wxParseVideo from './wxParseVideo';
    import wxParseAudio from './wxParseAudio';
    import wxParseTable from './wxParseTable';

    export default {
        name: 'wxParseTemplate0',
        props: {
            node: {},
        },
        components: {
            wxParseTemplate,
            wxParseImg,
            wxParseVideo,
            wxParseAudio,
            wxParseTable
        },
        methods: {
            wxParseATap(e) {
                const {
                    href
                } = e.currentTarget.dataset;// TODO currentTarget才有dataset
                if (!href) return;
                let parent = this.$parent;
                while(!parent.preview || typeof parent.preview !== 'function') {// TODO 遍历获取父节点执行方法
                    parent = parent.$parent;
                }
                parent.navigate(href, e);
            },
        }
    };
</script>
wxParseTemplate1.vue
<template>
    <!--判断是否是标签节点-->
    <block v-if="node.node == 'element'">
        <!--button类型-->
        <button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
            <wx-parse-template :node="node" />
        </button>
        
        <!--a类型-->
        <view v-else-if="node.tag == 'a'" @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
                <wx-parse-template :node="node" />
            </block>
        </view>
        
        <!--li类型-->
        <view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
                <wx-parse-template :node="node" />
            </block>
        </view>
        
        <!--table类型-->
        <wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
        
        <!--br类型-->
        <!-- #ifndef H5 -->
            <text v-else-if="node.tag == 'br'">\n</text>
        <!-- #endif -->
        <!-- #ifdef H5 -->
            <br v-else-if="node.tag == 'br'">
        <!-- #endif -->
        
        <!--video类型-->
        <wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
    
        <!--audio类型-->
        <wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
    
        <!--img类型-->
        <wx-parse-img :node="node" v-else-if="node.tag == 'img'"/>
    
        <!--其他标签-->
        <view v-else :class="node.classStr" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
                <wx-parse-template :node="node" />
            </block>
        </view>
    </block>
    
    <!--判断是否是文本节点-->
    <block v-else-if="node.node == 'text'">{{node.text}}</block>
</template>

<script>
    import wxParseTemplate from './wxParseTemplate2';
    import wxParseImg from './wxParseImg';
    import wxParseVideo from './wxParseVideo';
    import wxParseAudio from './wxParseAudio';
    import wxParseTable from './wxParseTable';
    
    export default {
        name: 'wxParseTemplate1',
        props: {
            node: {},
        },
        components: {
            wxParseTemplate,
            wxParseImg,
            wxParseVideo,
            wxParseAudio,
            wxParseTable
        },
        methods: {
            wxParseATap(e) {
                const {
                    href
                } = e.currentTarget.dataset;
                if (!href) return;
                let parent = this.$parent;
                while(!parent.preview || typeof parent.preview !== 'function') {
                    parent = parent.$parent;
                }
                parent.navigate(href, e);
            },
        },
    };
</script>
wxParseTemplate10.vue
<template>
        <!--判断是否是标签节点-->
    <block v-if="node.node == 'element'">
        <!--button类型-->
        <button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
            <wx-parse-template :node="node" />
        </button>
        
        <!--a类型-->
        <view v-else-if="node.tag == 'a'" @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
                <wx-parse-template :node="node" />
            </block>
        </view>
        
        <!--li类型-->
        <view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
                <wx-parse-template :node="node" />
            </block>
        </view>
        
        <!--table类型-->
        <wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
        
        <!--br类型-->
        <!-- #ifndef H5 -->
            <text v-else-if="node.tag == 'br'">\n</text>
        <!-- #endif -->
        <!-- #ifdef H5 -->
            <br v-else-if="node.tag == 'br'">
        <!-- #endif -->
        
        <!--video类型-->
        <wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
    
        <!--audio类型-->
        <wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
    
        <!--img类型-->
        <wx-parse-img :node="node" v-else-if="node.tag == 'img'"/>
    
        <!--其他标签-->
        <view v-else :class="node.classStr" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
                <wx-parse-template :node="node" />
            </block>
        </view>
    </block>
    
    <!--判断是否是文本节点-->
    <block v-else-if="node.node == 'text'">{{node.text}}</block>
</template>

<script>
    import wxParseTemplate from './wxParseTemplate11';
    import wxParseImg from './wxParseImg';
    import wxParseVideo from './wxParseVideo';
    import wxParseAudio from './wxParseAudio';
    import wxParseTable from './wxParseTable';
    
    export default {
        name: 'wxParseTemplate10',
        props: {
            node: {},
        },
        components: {
            wxParseTemplate,
            wxParseImg,
            wxParseVideo,
            wxParseAudio,
            wxParseTable
        },
        methods: {
            wxParseATap(e) {
                const {
                    href
                } = e.currentTarget.dataset;
                if (!href) return;
                let parent = this.$parent;
                while(!parent.preview || typeof parent.preview !== 'function') {
                    parent = parent.$parent;
                }
                parent.navigate(href, e);
            },
        },
    };
</script>
wxParseTemplate11.vue
<template>
        <!--判断是否是标签节点-->
    <block v-if="node.node == 'element'">
        <!--button类型-->
        <button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
        </button>
        
        <!--a类型-->
        <view v-else-if="node.tag == 'a'" @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
            </block>
        </view>
        
        <!--li类型-->
        <view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
            </block>
        </view>
        
        <!--table类型-->
        <wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />

        <!--br类型-->
        <!-- #ifndef H5 -->
            <text v-else-if="node.tag == 'br'">\n</text>
        <!-- #endif -->
        <!-- #ifdef H5 -->
            <br v-else-if="node.tag == 'br'">
        <!-- #endif -->
        
        <!--video类型-->
        <wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
    
        <!--audio类型-->
        <wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
    
        <!--img类型-->
        <wx-parse-img :node="node" v-else-if="node.tag == 'img'"/>
    
        <!--其他标签-->
        <view v-else :class="node.classStr" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
            </block>
        </view>
    </block>
    
    <!--判断是否是文本节点-->
    <block v-else-if="node.node == 'text'">{{node.text}}</block>
</template>

<script>
    import wxParseImg from './wxParseImg';
    import wxParseVideo from './wxParseVideo';
    import wxParseAudio from './wxParseAudio';
    import wxParseTable from './wxParseTable';
    
    export default {
        name: 'wxParseTemplate11',
        props: {
            node: {},
        },
        components: {
            wxParseImg,
            wxParseVideo,
            wxParseAudio,
            wxParseTable
        },
        methods: {
            wxParseATap(e) {
                const {
                    href
                } = e.currentTarget.dataset;
                if (!href) return;
                let parent = this.$parent;
                while(!parent.preview || typeof parent.preview !== 'function') {
                    parent = parent.$parent;
                }
                parent.navigate(href, e);
            },
        },
    };
</script>
wxParseTemplate2.vue
<template>
        <!--判断是否是标签节点-->
    <block v-if="node.node == 'element'">
        <!--button类型-->
        <button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
            <wx-parse-template :node="node" />
        </button>
        
        <!--a类型-->
        <view v-else-if="node.tag == 'a'" @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
                <wx-parse-template :node="node" />
            </block>
        </view>
        
        <!--li类型-->
        <view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
                <wx-parse-template :node="node" />
            </block>
        </view>
        
        <!--table类型-->
        <wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
        
        <!--br类型-->
        <!-- #ifndef H5 -->
            <text v-else-if="node.tag == 'br'">\n</text>
        <!-- #endif -->
        <!-- #ifdef H5 -->
            <br v-else-if="node.tag == 'br'">
        <!-- #endif -->
        
        <!--video类型-->
        <wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
    
        <!--audio类型-->
        <wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
    
        <!--img类型-->
        <wx-parse-img :node="node" v-else-if="node.tag == 'img'"/>
    
        <!--其他标签-->
        <view v-else :class="node.classStr" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
                <wx-parse-template :node="node" />
            </block>
        </view>
    </block>
    
    <!--判断是否是文本节点-->
    <block v-else-if="node.node == 'text'">{{node.text}}</block>
</template>

<script>
    import wxParseTemplate from './wxParseTemplate3';
    import wxParseImg from './wxParseImg';
    import wxParseVideo from './wxParseVideo';
    import wxParseAudio from './wxParseAudio';
    import wxParseTable from './wxParseTable';
    
    export default {
        name: 'wxParseTemplate2',
        props: {
            node: {},
        },
        components: {
            wxParseTemplate,
            wxParseImg,
            wxParseVideo,
            wxParseAudio,
            wxParseTable
        },
        methods: {
            wxParseATap(e) {
                const {
                    href
                } = e.currentTarget.dataset;
                if (!href) return;
                let parent = this.$parent;
                while(!parent.preview || typeof parent.preview !== 'function') {
                    parent = parent.$parent;
                }
                parent.navigate(href, e);
            },
        },
    };
</script>
wxParseTemplate3.vue
<template>
        <!--判断是否是标签节点-->
    <block v-if="node.node == 'element'">
        <!--button类型-->
        <button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
            <wx-parse-template :node="node" />
        </button>
        
        <!--a类型-->
        <view v-else-if="node.tag == 'a'" @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
                <wx-parse-template :node="node" />
            </block>
        </view>
        
        <!--li类型-->
        <view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
                <wx-parse-template :node="node" />
            </block>
        </view>
        
        <!--table类型-->
        <wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
        
        <!--br类型-->
        <!-- #ifndef H5 -->
            <text v-else-if="node.tag == 'br'">\n</text>
        <!-- #endif -->
        <!-- #ifdef H5 -->
            <br v-else-if="node.tag == 'br'">
        <!-- #endif -->
        
        <!--video类型-->
        <wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
    
        <!--audio类型-->
        <wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
    
        <!--img类型-->
        <wx-parse-img :node="node" v-else-if="node.tag == 'img'"/>
    
        <!--其他标签-->
        <view v-else :class="node.classStr" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
                <wx-parse-template :node="node" />
            </block>
        </view>
    </block>
    
    <!--判断是否是文本节点-->
    <block v-else-if="node.node == 'text'">{{node.text}}</block>
</template>

<script>
    import wxParseTemplate from './wxParseTemplate4';
    import wxParseImg from './wxParseImg';
    import wxParseVideo from './wxParseVideo';
    import wxParseAudio from './wxParseAudio';
    import wxParseTable from './wxParseTable';
    
    export default {
        name: 'wxParseTemplate3',
        props: {
            node: {},
        },
        components: {
            wxParseTemplate,
            wxParseImg,
            wxParseVideo,
            wxParseAudio,
            wxParseTable
        },
        methods: {
            wxParseATap(e) {
                const {
                    href
                } = e.currentTarget.dataset;
                if (!href) return;
                let parent = this.$parent;
                while(!parent.preview || typeof parent.preview !== 'function') {
                    parent = parent.$parent;
                }
                parent.navigate(href, e);
            },
        },
    };
</script>
wxParseTemplate4.vue
<template>
        <!--判断是否是标签节点-->
    <block v-if="node.node == 'element'">
        <!--button类型-->
        <button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
            <wx-parse-template :node="node" />
        </button>
        
        <!--a类型-->
        <view v-else-if="node.tag == 'a'" @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
                <wx-parse-template :node="node" />
            </block>
        </view>
        
        <!--li类型-->
        <view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
                <wx-parse-template :node="node" />
            </block>
        </view>
        
        <!--table类型-->
        <wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
        
        <!--br类型-->
        <!-- #ifndef H5 -->
            <text v-else-if="node.tag == 'br'">\n</text>
        <!-- #endif -->
        <!-- #ifdef H5 -->
            <br v-else-if="node.tag == 'br'">
        <!-- #endif -->
        
        <!--video类型-->
        <wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
    
        <!--audio类型-->
        <wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
    
        <!--img类型-->
        <wx-parse-img :node="node" v-else-if="node.tag == 'img'"/>
    
        <!--其他标签-->
        <view v-else :class="node.classStr" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
                <wx-parse-template :node="node" />
            </block>
        </view>
    </block>
    
    <!--判断是否是文本节点-->
    <block v-else-if="node.node == 'text'">{{node.text}}</block>
</template>

<script>
    import wxParseTemplate from './wxParseTemplate5';
    import wxParseImg from './wxParseImg';
    import wxParseVideo from './wxParseVideo';
    import wxParseAudio from './wxParseAudio';
    import wxParseTable from './wxParseTable';
    
    export default {
        name: 'wxParseTemplate4',
        props: {
            node: {},
        },
        components: {
            wxParseTemplate,
            wxParseImg,
            wxParseVideo,
            wxParseAudio,
            wxParseTable
        },
        methods: {
            wxParseATap(e) {
                const {
                    href
                } = e.currentTarget.dataset;
                if (!href) return;
                let parent = this.$parent;
                while(!parent.preview || typeof parent.preview !== 'function') {
                    parent = parent.$parent;
                }
                parent.navigate(href, e);
            },
        },
    };
</script>
wxParseTemplate5.vue
<template>
        <!--判断是否是标签节点-->
    <block v-if="node.node == 'element'">
        <!--button类型-->
        <button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
            <wx-parse-template :node="node" />
        </button>
        
        <!--a类型-->
        <view v-else-if="node.tag == 'a'" @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
                <wx-parse-template :node="node" />
            </block>
        </view>
        
        <!--li类型-->
        <view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
                <wx-parse-template :node="node" />
            </block>
        </view>
        
        <!--table类型-->
        <wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
        
        <!--br类型-->
        <!-- #ifndef H5 -->
            <text v-else-if="node.tag == 'br'">\n</text>
        <!-- #endif -->
        <!-- #ifdef H5 -->
            <br v-else-if="node.tag == 'br'">
        <!-- #endif -->
        
        <!--video类型-->
        <wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
    
        <!--audio类型-->
        <wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
    
        <!--img类型-->
        <wx-parse-img :node="node" v-else-if="node.tag == 'img'"/>
    
        <!--其他标签-->
        <view v-else :class="node.classStr" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
                <wx-parse-template :node="node" />
            </block>
        </view>
    </block>
    
    <!--判断是否是文本节点-->
    <block v-else-if="node.node == 'text'">{{node.text}}</block>
</template>

<script>
    import wxParseTemplate from './wxParseTemplate6';
    import wxParseImg from './wxParseImg';
    import wxParseVideo from './wxParseVideo';
    import wxParseAudio from './wxParseAudio';
    import wxParseTable from './wxParseTable';
    
    export default {
        name: 'wxParseTemplate5',
        props: {
            node: {},
        },
        components: {
            wxParseTemplate,
            wxParseImg,
            wxParseVideo,
            wxParseAudio,
            wxParseTable
        },
        methods: {
            wxParseATap(e) {
                const {
                    href
                } = e.currentTarget.dataset;
                if (!href) return;
                let parent = this.$parent;
                while(!parent.preview || typeof parent.preview !== 'function') {
                    parent = parent.$parent;
                }
                parent.navigate(href, e);
            },
        },
    };
</script>
wxParseTemplate6.vue
<template>
        <!--判断是否是标签节点-->
    <block v-if="node.node == 'element'">
        <!--button类型-->
        <button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
            <wx-parse-template :node="node" />
        </button>
        
        <!--a类型-->
        <view v-else-if="node.tag == 'a'" @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
                <wx-parse-template :node="node" />
            </block>
        </view>
        
        <!--li类型-->
        <view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
                <wx-parse-template :node="node" />
            </block>
        </view>
        
        <!--table类型-->
        <wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
        
        <!--br类型-->
        <!-- #ifndef H5 -->
            <text v-else-if="node.tag == 'br'">\n</text>
        <!-- #endif -->
        <!-- #ifdef H5 -->
            <br v-else-if="node.tag == 'br'">
        <!-- #endif -->
        
        <!--video类型-->
        <wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
    
        <!--audio类型-->
        <wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
    
        <!--img类型-->
        <wx-parse-img :node="node" v-else-if="node.tag == 'img'"/>
    
        <!--其他标签-->
        <view v-else :class="node.classStr" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
                <wx-parse-template :node="node" />
            </block>
        </view>
    </block>
    
    <!--判断是否是文本节点-->
    <block v-else-if="node.node == 'text'">{{node.text}}</block>
</template>

<script>
    import wxParseTemplate from './wxParseTemplate7';
    import wxParseImg from './wxParseImg';
    import wxParseVideo from './wxParseVideo';
    import wxParseAudio from './wxParseAudio';
    import wxParseTable from './wxParseTable';
    
    export default {
        name: 'wxParseTemplate6',
        props: {
            node: {},
        },
        components: {
            wxParseTemplate,
            wxParseImg,
            wxParseVideo,
            wxParseAudio,
            wxParseTable
        },
        methods: {
            wxParseATap(e) {
                const {
                    href
                } = e.currentTarget.dataset;
                if (!href) return;
                let parent = this.$parent;
                while(!parent.preview || typeof parent.preview !== 'function') {
                    parent = parent.$parent;
                }
                parent.navigate(href, e);
            },
        },
    };
</script>
wxParseTemplate7.vue
<template>
        <!--判断是否是标签节点-->
    <block v-if="node.node == 'element'">
        <!--button类型-->
        <button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
            <wx-parse-template :node="node" />
        </button>
        
        <!--a类型-->
        <view v-else-if="node.tag == 'a'" @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
                <wx-parse-template :node="node" />
            </block>
        </view>
        
        <!--li类型-->
        <view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
                <wx-parse-template :node="node" />
            </block>
        </view>
        
        <!--table类型-->
        <wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
        
        <!--br类型-->
        <!-- #ifndef H5 -->
            <text v-else-if="node.tag == 'br'">\n</text>
        <!-- #endif -->
        <!-- #ifdef H5 -->
            <br v-else-if="node.tag == 'br'">
        <!-- #endif -->
        
        <!--video类型-->
        <wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
    
        <!--audio类型-->
        <wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
    
        <!--img类型-->
        <wx-parse-img :node="node" v-else-if="node.tag == 'img'"/>
    
        <!--其他标签-->
        <view v-else :class="node.classStr" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
                <wx-parse-template :node="node" />
            </block>
        </view>
    </block>
    
    <!--判断是否是文本节点-->
    <block v-else-if="node.node == 'text'">{{node.text}}</block>
</template>

<script>
    import wxParseTemplate from './wxParseTemplate8';
    import wxParseImg from './wxParseImg';
    import wxParseVideo from './wxParseVideo';
    import wxParseAudio from './wxParseAudio';
    import wxParseTable from './wxParseTable';
    
    export default {
        name: 'wxParseTemplate7',
        props: {
            node: {},
        },
        components: {
            wxParseTemplate,
            wxParseImg,
            wxParseVideo,
            wxParseAudio,
            wxParseTable
        },
        methods: {
            wxParseATap(e) {
                const {
                    href
                } = e.currentTarget.dataset;
                if (!href) return;
                let parent = this.$parent;
                while(!parent.preview || typeof parent.preview !== 'function') {
                    parent = parent.$parent;
                }
                parent.navigate(href, e);
            },
        },
    };
</script>
wxParseTemplate8.vue
<template>
        <!--判断是否是标签节点-->
    <block v-if="node.node == 'element'">
        <!--button类型-->
        <button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
            <wx-parse-template :node="node" />
        </button>
        
        <!--a类型-->
        <view v-else-if="node.tag == 'a'" @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
                <wx-parse-template :node="node" />
            </block>
        </view>
        
        <!--li类型-->
        <view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
                <wx-parse-template :node="node" />
            </block>
        </view>
        
        <!--table类型-->
        <wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />

        <!--br类型-->
        <!-- #ifndef H5 -->
            <text v-else-if="node.tag == 'br'">\n</text>
        <!-- #endif -->
        <!-- #ifdef H5 -->
            <br v-else-if="node.tag == 'br'">
        <!-- #endif -->
        
        <!--video类型-->
        <wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
    
        <!--audio类型-->
        <wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
    
        <!--img类型-->
        <wx-parse-img :node="node" v-else-if="node.tag == 'img'"/>
    
        <!--其他标签-->
        <view v-else :class="node.classStr" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
                <wx-parse-template :node="node" />
            </block>
        </view>
    </block>
    
    <!--判断是否是文本节点-->
    <block v-else-if="node.node == 'text'">{{node.text}}</block>
</template>

<script>
    import wxParseTemplate from './wxParseTemplate9';
    import wxParseImg from './wxParseImg';
    import wxParseVideo from './wxParseVideo';
    import wxParseAudio from './wxParseAudio';
    import wxParseTable from './wxParseTable';
    
    export default {
        name: 'wxParseTemplate8',
        props: {
            node: {},
        },
        components: {
            wxParseTemplate,
            wxParseImg,
            wxParseVideo,
            wxParseAudio,
            wxParseTable
        },
        methods: {
            wxParseATap(e) {
                const {
                    href
                } = e.currentTarget.dataset;
                if (!href) return;
                let parent = this.$parent;
                while(!parent.preview || typeof parent.preview !== 'function') {
                    parent = parent.$parent;
                }
                parent.navigate(href, e);
            },
        },
    };
</script>
wxParseTemplate9.vue
<template>
        <!--判断是否是标签节点-->
    <block v-if="node.node == 'element'">
        <!--button类型-->
        <button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
            <wx-parse-template :node="node" />
        </button>
        
        <!--a类型-->
        <view v-else-if="node.tag == 'a'" @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
                <wx-parse-template :node="node" />
            </block>
        </view>
        
        <!--li类型-->
        <view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
                <wx-parse-template :node="node" />
            </block>
        </view>
        
        <!--table类型-->
        <wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
        
        <!--br类型-->
        <!-- #ifndef H5 -->
            <text v-else-if="node.tag == 'br'">\n</text>
        <!-- #endif -->
        <!-- #ifdef H5 -->
            <br v-else-if="node.tag == 'br'">
        <!-- #endif -->
        
        <!--video类型-->
        <wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
    
        <!--audio类型-->
        <wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
    
        <!--img类型-->
        <wx-parse-img :node="node" v-else-if="node.tag == 'img'"/>
    
        <!--其他标签-->
        <view v-else :class="node.classStr" :style="node.styleStr">
            <block v-for="(node, index) of node.nodes" :key="index">
                <wx-parse-template :node="node" />
            </block>
        </view>
    </block>
    
    <!--判断是否是文本节点-->
    <block v-else-if="node.node == 'text'">{{node.text}}</block>
</template>

<script>
    import wxParseTemplate from './wxParseTemplate10';
    import wxParseImg from './wxParseImg';
    import wxParseVideo from './wxParseVideo';
    import wxParseAudio from './wxParseAudio';
    import wxParseTable from './wxParseTable';
    
    export default {
        name: 'wxParseTemplate9',
        props: {
            node: {},
        },
        components: {
            wxParseTemplate,
            wxParseImg,
            wxParseVideo,
            wxParseAudio,
            wxParseTable
        },
        methods: {
            wxParseATap(e) {
                const {
                    href
                } = e.currentTarget.dataset;
                if (!href) return;
                let parent = this.$parent;
                while(!parent.preview || typeof parent.preview !== 'function') {
                    parent = parent.$parent;
                }
                parent.navigate(href, e);
            },
        },
    };
</script>
wxParseVideo.vue
<template>
  <!--增加video标签支持,并循环添加-->
  <view :class="node.classStr" :style="node.styleStr">
    <video :class="node.classStr" :style="node.styleStr" class="video-video" :src="node.attr.src" :poster="node.attr.poster"></video>
  </view>
</template>

<script>
export default {
  name: 'wxParseVideo',
  props: {
    node: {},
  },
};
</script>
libs
html2json.js
/**
 * html2Json 改造来自: https://github.com/Jxck/html2json
 *
 *
 * author: Di (微信小程序开发工程师)
 * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com)
 *               垂直微信小程序开发交流社区
 *
 * github地址: https://github.com/icindy/wxParse
 *
 * for: 微信小程序富文本解析
 * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184
 */

import wxDiscode from './wxDiscode';
import HTMLParser from './htmlparser';

function makeMap(str) {
  const obj = {};
  const items = str.split(',');
  for (let i = 0; i < items.length; i += 1) obj[items[i]] = true;
  return obj;
}

// Block Elements - HTML 5
const block = makeMap('br,code,address,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,ins,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video');

// Inline Elements - HTML 5
const inline = makeMap('a,abbr,acronym,applet,b,basefont,bdo,big,button,cite,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var');

// Elements that you can, intentionally, leave open
// (and which close themselves)
const closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr');

function removeDOCTYPE(html) {
  const isDocument = /<body.*>([^]*)<\/body>/.test(html);
  return isDocument ? RegExp.$1 : html;
}

function trimHtml(html) {
  return html
    .replace(/<!--.*?-->/gi, '')
    .replace(/\/\*.*?\*\//gi, '')
    .replace(/[ ]+</gi, '<')
    .replace(/<script[^]*<\/script>/gi, '')
    .replace(/<style[^]*<\/style>/gi, '');
}

function getScreenInfo() {
  const screen = {};
  wx.getSystemInfo({
    success: (res) => {
      screen.width = res.windowWidth;
      screen.height = res.windowHeight;
    },
  });
  return screen;
}

function html2json(html, customHandler, imageProp, host) {
  // 处理字符串
  html = removeDOCTYPE(html);
  html = trimHtml(html);
  html = wxDiscode.strDiscode(html);
  // 生成node节点
  const bufArray = [];
  const results = {
    nodes: [],
    imageUrls: [],
  };

    const screen = getScreenInfo();
  function Node(tag) {
    this.node = 'element';
    this.tag = tag;
        
        this.$screen = screen;
  }

  HTMLParser(html, {
    start(tag, attrs, unary) {
      // node for this element
      const node = new Node(tag);

      if (bufArray.length !== 0) {
        const parent = bufArray[0];
        if (parent.nodes === undefined) {
          parent.nodes = [];
        }
      }

      if (block[tag]) {
        node.tagType = 'block';
      } else if (inline[tag]) {
        node.tagType = 'inline';
      } else if (closeSelf[tag]) {
        node.tagType = 'closeSelf';
      }

      node.attr = attrs.reduce((pre, attr) => {
        const { name } = attr;
        let { value } = attr;
        if (name === 'class') {
          node.classStr = value;
        }
        // has multi attibutes
        // make it array of attribute
        if (name === 'style') {
          node.styleStr = value;
        }
        if (value.match(/ /)) {
          value = value.split(' ');
        }

        // if attr already exists
        // merge it
        if (pre[name]) {
          if (Array.isArray(pre[name])) {
            // already array, push to last
            pre[name].push(value);
          } else {
            // single value, make it array
            pre[name] = [pre[name], value];
          }
        } else {
          // not exist, put it
          pre[name] = value;
        }

        return pre;
      }, {});

      // 优化样式相关属性
      if (node.classStr) {
        node.classStr += ` ${node.tag}`;
      } else {
        node.classStr = node.tag;
      }
      if (node.tagType === 'inline') {
        node.classStr += ' inline';
      }

      // 对img添加额外数据
      if (node.tag === 'img') {
        let imgUrl = node.attr.src;
        imgUrl = wxDiscode.urlToHttpUrl(imgUrl, imageProp.domain);
        Object.assign(node.attr, imageProp, {
          src: imgUrl || '',
        });
        if (imgUrl) {
          results.imageUrls.push(imgUrl);
        }
      }

      // 处理a标签属性
      if (node.tag === 'a') {
        node.attr.href = node.attr.href || '';
      }

      // 处理font标签样式属性
      if (node.tag === 'font') {
        const fontSize = [
          'x-small',
          'small',
          'medium',
          'large',
          'x-large',
          'xx-large',
          '-webkit-xxx-large',
        ];
        const styleAttrs = {
          color: 'color',
          face: 'font-family',
          size: 'font-size',
        };
        if (!node.styleStr) node.styleStr = '';
        Object.keys(styleAttrs).forEach((key) => {
          if (node.attr[key]) {
            const value = key === 'size' ? fontSize[node.attr[key] - 1] : node.attr[key];
            node.styleStr += `${styleAttrs[key]}: ${value};`;
          }
        });
      }

      // 临时记录source资源
      if (node.tag === 'source') {
        results.source = node.attr.src;
      }

      if (customHandler.start) {
        customHandler.start(node, results);
      }

      if (unary) {
        // if this tag doesn't have end tag
        // like <img src="hoge.png"/>
        // add to parents
        const parent = bufArray[0] || results;
        if (parent.nodes === undefined) {
          parent.nodes = [];
        }
        parent.nodes.push(node);
      } else {
        bufArray.unshift(node);
      }
    },
    end(tag) {
      // merge into parent tag
      const node = bufArray.shift();
      if (node.tag !== tag) {
        console.error('invalid state: mismatch end tag');
      }

      // 当有缓存source资源时于于video补上src资源
      if (node.tag === 'video' && results.source) {
        node.attr.src = results.source;
        delete results.source;
      }

      if (customHandler.end) {
        customHandler.end(node, results);
      }

      if (bufArray.length === 0) {
        results.nodes.push(node);
      } else {
        const parent = bufArray[0];
        if (!parent.nodes) {
          parent.nodes = [];
        }
        parent.nodes.push(node);
      }
    },
    chars(text) {
      if (!text.trim()) return;

      const node = {
        node: 'text',
        text,
      };

      if (customHandler.chars) {
        customHandler.chars(node, results);
      }

      if (bufArray.length === 0) {
        results.nodes.push(node);
      } else {
        const parent = bufArray[0];
        if (parent.nodes === undefined) {
          parent.nodes = [];
        }
        parent.nodes.push(node);
      }
    },
  });

  return results;
}

export default html2json;
htmlparser.js
/**
 *
 * htmlParser改造自: https://github.com/blowsie/Pure-JavaScript-HTML5-Parser
 *
 * author: Di (微信小程序开发工程师)
 * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com)
 *               垂直微信小程序开发交流社区
 *
 * github地址: https://github.com/icindy/wxParse
 *
 * for: 微信小程序富文本解析
 * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184
 */
// Regular Expressions for parsing tags and attributes

const startTag = /^<([-A-Za-z0-9_]+)((?:\s+[a-zA-Z0-9_:][-a-zA-Z0-9_:.]*(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/;
const endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/;
const attr = /([a-zA-Z0-9_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g;

function makeMap(str) {
  const obj = {};
  const items = str.split(',');
  for (let i = 0; i < items.length; i += 1) obj[items[i]] = true;
  return obj;
}

// Empty Elements - HTML 5
const empty = makeMap('area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr');

// Block Elements - HTML 5
const block = makeMap('address,code,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,ins,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video');

// Inline Elements - HTML 5
const inline = makeMap('a,abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var');

// Elements that you can, intentionally, leave open
// (and which close themselves)
const closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr');

// Attributes that have their values filled in disabled="disabled"
const fillAttrs = makeMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected');

function HTMLParser(html, handler) {
  let index;
  let chars;
  let match;
  let last = html;
  const stack = [];

  stack.last = () => stack[stack.length - 1];

  function parseEndTag(tag, tagName) {
    // If no tag name is provided, clean shop
    let pos;
    if (!tagName) {
      pos = 0;
    } else {
      // Find the closest opened tag of the same type
      tagName = tagName.toLowerCase();
      for (pos = stack.length - 1; pos >= 0; pos -= 1) {
        if (stack[pos] === tagName) break;
      }
    }
    if (pos >= 0) {
      // Close all the open elements, up the stack
      for (let i = stack.length - 1; i >= pos; i -= 1) {
        if (handler.end) handler.end(stack[i]);
      }

      // Remove the open elements from the stack
      stack.length = pos;
    }
  }

  function parseStartTag(tag, tagName, rest, unary) {
    tagName = tagName.toLowerCase();

    if (block[tagName]) {
      while (stack.last() && inline[stack.last()]) {
        parseEndTag('', stack.last());
      }
    }

    if (closeSelf[tagName] && stack.last() === tagName) {
      parseEndTag('', tagName);
    }

    unary = empty[tagName] || !!unary;

    if (!unary) stack.push(tagName);

    if (handler.start) {
      const attrs = [];

      rest.replace(attr, function genAttr(matches, name) {
        const value = arguments[2] || arguments[3] || arguments[4] || (fillAttrs[name] ? name : '');

        attrs.push({
          name,
          value,
          escaped: value.replace(/(^|[^\\])"/g, '$1\\"'), // "
        });
      });

      if (handler.start) {
        handler.start(tagName, attrs, unary);
      }
    }
  }

  while (html) {
    chars = true;

    if (html.indexOf('</') === 0) {
      match = html.match(endTag);

      if (match) {
        html = html.substring(match[0].length);
        match[0].replace(endTag, parseEndTag);
        chars = false;
      }

      // start tag
    } else if (html.indexOf('<') === 0) {
      match = html.match(startTag);

      if (match) {
        html = html.substring(match[0].length);
        match[0].replace(startTag, parseStartTag);
        chars = false;
      }
    }

    if (chars) {
      index = html.indexOf('<');
      let text = '';
      while (index === 0) {
        text += '<';
        html = html.substring(1);
        index = html.indexOf('<');
      }
      text += index < 0 ? html : html.substring(0, index);
      html = index < 0 ? '' : html.substring(index);

      if (handler.chars) handler.chars(text);
    }

    if (html === last) throw new Error(`Parse Error: ${html}`);
    last = html;
  }

  // Clean up any remaining tags
  parseEndTag();
}

export default HTMLParser;
wxDiscode.js
// HTML 支持的数学符号
function strNumDiscode(str) {
  str = str.replace(/&forall;/g, '∀');
  str = str.replace(/&part;/g, '∂');
  str = str.replace(/&exist;/g, '∃');
  str = str.replace(/&empty;/g, '∅');
  str = str.replace(/&nabla;/g, '∇');
  str = str.replace(/&isin;/g, '∈');
  str = str.replace(/&notin;/g, '∉');
  str = str.replace(/&ni;/g, '∋');
  str = str.replace(/&prod;/g, '∏');
  str = str.replace(/&sum;/g, '∑');
  str = str.replace(/&minus;/g, '−');
  str = str.replace(/&lowast;/g, '∗');
  str = str.replace(/&radic;/g, '√');
  str = str.replace(/&prop;/g, '∝');
  str = str.replace(/&infin;/g, '∞');
  str = str.replace(/&ang;/g, '∠');
  str = str.replace(/&and;/g, '∧');
  str = str.replace(/&or;/g, '∨');
  str = str.replace(/&cap;/g, '∩');
  str = str.replace(/&cup;/g, '∪');
  str = str.replace(/&int;/g, '∫');
  str = str.replace(/&there4;/g, '∴');
  str = str.replace(/&sim;/g, '∼');
  str = str.replace(/&cong;/g, '≅');
  str = str.replace(/&asymp;/g, '≈');
  str = str.replace(/&ne;/g, '≠');
  str = str.replace(/&le;/g, '≤');
  str = str.replace(/&ge;/g, '≥');
  str = str.replace(/&sub;/g, '⊂');
  str = str.replace(/&sup;/g, '⊃');
  str = str.replace(/&nsub;/g, '⊄');
  str = str.replace(/&sube;/g, '⊆');
  str = str.replace(/&supe;/g, '⊇');
  str = str.replace(/&oplus;/g, '⊕');
  str = str.replace(/&otimes;/g, '⊗');
  str = str.replace(/&perp;/g, '⊥');
  str = str.replace(/&sdot;/g, '⋅');
  return str;
}

// HTML 支持的希腊字母
function strGreeceDiscode(str) {
  str = str.replace(/&Alpha;/g, 'Α');
  str = str.replace(/&Beta;/g, 'Β');
  str = str.replace(/&Gamma;/g, 'Γ');
  str = str.replace(/&Delta;/g, 'Δ');
  str = str.replace(/&Epsilon;/g, 'Ε');
  str = str.replace(/&Zeta;/g, 'Ζ');
  str = str.replace(/&Eta;/g, 'Η');
  str = str.replace(/&Theta;/g, 'Θ');
  str = str.replace(/&Iota;/g, 'Ι');
  str = str.replace(/&Kappa;/g, 'Κ');
  str = str.replace(/&Lambda;/g, 'Λ');
  str = str.replace(/&Mu;/g, 'Μ');
  str = str.replace(/&Nu;/g, 'Ν');
  str = str.replace(/&Xi;/g, 'Ν');
  str = str.replace(/&Omicron;/g, 'Ο');
  str = str.replace(/&Pi;/g, 'Π');
  str = str.replace(/&Rho;/g, 'Ρ');
  str = str.replace(/&Sigma;/g, 'Σ');
  str = str.replace(/&Tau;/g, 'Τ');
  str = str.replace(/&Upsilon;/g, 'Υ');
  str = str.replace(/&Phi;/g, 'Φ');
  str = str.replace(/&Chi;/g, 'Χ');
  str = str.replace(/&Psi;/g, 'Ψ');
  str = str.replace(/&Omega;/g, 'Ω');

  str = str.replace(/&alpha;/g, 'α');
  str = str.replace(/&beta;/g, 'β');
  str = str.replace(/&gamma;/g, 'γ');
  str = str.replace(/&delta;/g, 'δ');
  str = str.replace(/&epsilon;/g, 'ε');
  str = str.replace(/&zeta;/g, 'ζ');
  str = str.replace(/&eta;/g, 'η');
  str = str.replace(/&theta;/g, 'θ');
  str = str.replace(/&iota;/g, 'ι');
  str = str.replace(/&kappa;/g, 'κ');
  str = str.replace(/&lambda;/g, 'λ');
  str = str.replace(/&mu;/g, 'μ');
  str = str.replace(/&nu;/g, 'ν');
  str = str.replace(/&xi;/g, 'ξ');
  str = str.replace(/&omicron;/g, 'ο');
  str = str.replace(/&pi;/g, 'π');
  str = str.replace(/&rho;/g, 'ρ');
  str = str.replace(/&sigmaf;/g, 'ς');
  str = str.replace(/&sigma;/g, 'σ');
  str = str.replace(/&tau;/g, 'τ');
  str = str.replace(/&upsilon;/g, 'υ');
  str = str.replace(/&phi;/g, 'φ');
  str = str.replace(/&chi;/g, 'χ');
  str = str.replace(/&psi;/g, 'ψ');
  str = str.replace(/&omega;/g, 'ω');
  str = str.replace(/&thetasym;/g, 'ϑ');
  str = str.replace(/&upsih;/g, 'ϒ');
  str = str.replace(/&piv;/g, 'ϖ');
  str = str.replace(/&middot;/g, '·');
  return str;
}

function strcharacterDiscode(str) {
  // 加入常用解析
  str = str.replace(/&nbsp;/g, ' ');
  str = str.replace(/&ensp;/g, ' ');
  str = str.replace(/&emsp;/g, ' ');
  str = str.replace(/&quot;/g, "'");
  str = str.replace(/&amp;/g, '&');
  str = str.replace(/&lt;/g, '<');
  str = str.replace(/&gt;/g, '>');
  str = str.replace(/&#8226;/g, '•');

  return str;
}

// HTML 支持的其他实体
function strOtherDiscode(str) {
  str = str.replace(/&OElig;/g, 'Œ');
  str = str.replace(/&oelig;/g, 'œ');
  str = str.replace(/&Scaron;/g, 'Š');
  str = str.replace(/&scaron;/g, 'š');
  str = str.replace(/&Yuml;/g, 'Ÿ');
  str = str.replace(/&fnof;/g, 'ƒ');
  str = str.replace(/&circ;/g, 'ˆ');
  str = str.replace(/&tilde;/g, '˜');
  str = str.replace(/&ensp;/g, '');
  str = str.replace(/&emsp;/g, '');
  str = str.replace(/&thinsp;/g, '');
  str = str.replace(/&zwnj;/g, '');
  str = str.replace(/&zwj;/g, '');
  str = str.replace(/&lrm;/g, '');
  str = str.replace(/&rlm;/g, '');
  str = str.replace(/&ndash;/g, '–');
  str = str.replace(/&mdash;/g, '—');
  str = str.replace(/&lsquo;/g, '‘');
  str = str.replace(/&rsquo;/g, '’');
  str = str.replace(/&sbquo;/g, '‚');
  str = str.replace(/&ldquo;/g, '“');
  str = str.replace(/&rdquo;/g, '”');
  str = str.replace(/&bdquo;/g, '„');
  str = str.replace(/&dagger;/g, '†');
  str = str.replace(/&Dagger;/g, '‡');
  str = str.replace(/&bull;/g, '•');
  str = str.replace(/&hellip;/g, '…');
  str = str.replace(/&permil;/g, '‰');
  str = str.replace(/&prime;/g, '′');
  str = str.replace(/&Prime;/g, '″');
  str = str.replace(/&lsaquo;/g, '‹');
  str = str.replace(/&rsaquo;/g, '›');
  str = str.replace(/&oline;/g, '‾');
  str = str.replace(/&euro;/g, '€');
  str = str.replace(/&trade;/g, '™');

  str = str.replace(/&larr;/g, '←');
  str = str.replace(/&uarr;/g, '↑');
  str = str.replace(/&rarr;/g, '→');
  str = str.replace(/&darr;/g, '↓');
  str = str.replace(/&harr;/g, '↔');
  str = str.replace(/&crarr;/g, '↵');
  str = str.replace(/&lceil;/g, '⌈');
  str = str.replace(/&rceil;/g, '⌉');

  str = str.replace(/&lfloor;/g, '⌊');
  str = str.replace(/&rfloor;/g, '⌋');
  str = str.replace(/&loz;/g, '◊');
  str = str.replace(/&spades;/g, '♠');
  str = str.replace(/&clubs;/g, '♣');
  str = str.replace(/&hearts;/g, '♥');

  str = str.replace(/&diams;/g, '♦');
  str = str.replace(/&#39;/g, "'");
  return str;
}

function strDiscode(str) {
  str = strNumDiscode(str);
  str = strGreeceDiscode(str);
  str = strcharacterDiscode(str);
  str = strOtherDiscode(str);
  return str;
}

function urlToHttpUrl(url, domain) {
  if (/^\/\//.test(url)) {
    return `https:${url}`;
  } else if (/^\//.test(url)) {
    return `https://${domain}${url}`;
  }
  return url;
}

export default {
  strDiscode,
  urlToHttpUrl,
};
parse.css
/**
 * author: Di (微信小程序开发工程师)
 * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com)
 *         垂直微信小程序开发交流社区
 *
 * github地址: https://github.com/icindy/wxParse
 *
 * for: 微信小程序富文本解析
 * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184
 */
/**
 * 请在全局下引入该文件,@import '/static/wxParse.css';
 */
.wxParse {
    user-select:none;
    width: 100%;
    font-family: Helvetica, "PingFangSC", 'Microsoft Yahei', '微软雅黑', Arial, sans-serif;
    color: #333;
    line-height: 1.5;
    font-size: 1em;
    text-align:justify;/* //左右两端对齐 */
    word-wrap: break-word;/*超出自动换行*/
}
.wxParse view ,.wxParse uni-view{
    word-break: break-word;
}
.wxParse .p {
    padding-bottom: 1em;
    clear: both;
    /* letter-spacing: 0;//字间距 */
}
.wxParse .inline {
  display: inline;
  margin: 0;
  padding: 0;
}

.wxParse .div {
  margin: 0;
  padding: 0;
  display: block;
}

.wxParse .h1{
  font-size: 2em;
  line-height: 1.2em;
  margin: 0.67em 0;
}
.wxParse .h2{
  font-size: 1.5em;
  margin: 0.83em 0;
}
.wxParse .h3{
  font-size: 1.17em;
  margin: 1em 0;
}
.wxParse .h4{
  margin: 1.33em 0;
}
.wxParse .h5{
  font-size: 0.83em;
  margin: 1.67em 0;
}
.wxParse .h6{
  font-size: 0.83em;
  margin: 1.67em 0;
}

.wxParse .h1,
.wxParse .h2,
.wxParse .h3,
.wxParse .h4,
.wxParse .h5,
.wxParse .h6,
.wxParse .b,
.wxParse .strong{
  font-weight: bolder;
}

.wxParse .i,
.wxParse .cite,
.wxParse .em,
.wxParse .var,
.wxParse .address {
  font-style: italic;
}

.wxParse .pre,
.wxParse .tt,
.wxParse .code,
.wxParse .kbd,
.wxParse .samp {
  font-family: monospace;
}
.wxParse .pre {
  overflow: auto;
  background: #f5f5f5;
  padding: 16upx;
  white-space: pre;
  margin: 1em 0upx;
}
.wxParse .code {
  display: inline;
  background: #f5f5f5;
}

.wxParse .big {
  font-size: 1.17em;
}

.wxParse .small,
.wxParse .sub,
.wxParse .sup {
  font-size: 0.83em;
}

.wxParse .sub {
  vertical-align: sub;
}
.wxParse .sup {
  vertical-align: super;
}

.wxParse .s,
.wxParse .strike,
.wxParse .del {
  text-decoration: line-through;
}

.wxParse .strong,
.wxParse .s {
  display: inline;
}

.wxParse .a {
  color: deepskyblue;
}

.wxParse .video {
  text-align: center;
  margin: 22upx 0;
}

.wxParse .video-video {
  width: 100%;
}
.wxParse .uni-image{
    max-width: 100%;
}
.wxParse .img {
  display: block;
  max-width: 100%;
  margin-bottom: -1em;/* //与p标签底部padding同时修改 */
  overflow: hidden;
}

.wxParse .blockquote {
  margin: 10upx 0;
  padding: 22upx 0 22upx 22upx;
  font-family: Courier, Calibri, "宋体";
  background: #f5f5f5;
  border-left: 6upx solid #dbdbdb;
}
.wxParse .blockquote .p {
  margin: 0;
}
.wxParse .ul, .wxParse .ol {
  display: block;
  margin: 1em 0;
  padding-left: 2em;
}
.wxParse .ol {
  list-style-type: disc;
}
.wxParse .ol {
  list-style-type: decimal;
}
.wxParse .ol>weixin-parse-template,.wxParse .ul>weixin-parse-template {
  display: list-item;
  align-items: baseline;
  text-align: match-parent;
}

.wxParse .ol>.li,.wxParse .ul>.li {
  display: list-item;
  align-items: baseline;
  text-align: match-parent;
}
.wxParse .ul .ul, .wxParse .ol .ul {
  list-style-type: circle;
}
.wxParse .ol .ol .ul, .wxParse .ol .ul .ul, .wxParse .ul .ol .ul, .wxParse .ul .ul .ul {
    list-style-type: square;
}

.wxParse .u {
  text-decoration: underline;
}
.wxParse .hide {
  display: none;
}
.wxParse .del {
  display: inline;
}
.wxParse .figure {
  overflow: hidden;
}
.wxParse .table {
    border-collapse:collapse;
    box-sizing: border-box;
    /* 内边框 */
    border: 1px solid #dadada;
    width: 100%;
}
.wxParse .tbody{
    border-collapse:collapse;
    box-sizing: border-box;
    /* 内边框 */
    border: 1px solid #dadada;
}
.wxParse .thead, .wxParse .tfoot, .wxParse .th{
    border-collapse:collapse;
    box-sizing: border-box;
    background: #ececec;
    font-weight: 40;
}
.wxParse .tr {
    border-collapse:collapse;
    box-sizing: border-box;
    /* border: 2px solid #F0AD4E; */
    overflow:auto;
}
.wxParse .th,
.wxParse .td{
    border-collapse:collapse;
    box-sizing: border-box;
    border: 2upx solid #dadada;
    overflow:auto;
}
.wxParse .audio, .wxParse .uni-audio-default{
    display: block;
}
.textarea ._div{
    background-color:#fff !important;
}
parse.vue
<!--**
 * forked from:https://github.com/F-loat/mpvue-wxParse
 *
 * github地址: https://github.com/dcloudio/uParse
 *
 * for: uni-app框架下 富文本解析
 * 
 * 优化 by gaoyia@qq.com  https://github.com/gaoyia/parse
 */-->

<template>
    <!--基础元素-->
    <div class="wxParse" :class="className" :style="'user-select:' + userSelect">
        <block v-for="(node, index) of nodes" :key="index" v-if="!loading">
            <wxParseTemplate :node="node" />
        </block>
    </div>
</template>

<script>
    import HtmlToJson from './libs/html2json';
    import wxParseTemplate from './components/wxParseTemplate0';

    export default {
        name: 'wxParse',
        props: {
            // user-select:none;
            userSelect: {
                type: String,
                default: 'text' //none |text| all | element
            },
            imgOptions: {
                type: [Object, Boolean],
                default: function() {
                    return {
                        loop: false,
                        indicator: 'number',
                        longPressActions: false
                        // longPressActions: {
                        //      itemList: ['发送给朋友', '保存图片', '收藏'],
                        //         success: function (res) {
                        //             console.log('选中了第' + (res.tapIndex + 1) + '个按钮');
                        //         },
                        //         fail: function (res) {
                        //             console.log(res.errMsg);
                        //         }    
                        //     }
                        // }
                    }
                }
            },
            loading: {
                type: Boolean,
                default: false
            },
            className: {
                type: String,
                default: ''
            },
            content: {
                type: String,
                default: ''
            },
            noData: {
                type: String,
                default: '<div style="color: red;">数据不能为空</div>'
            },
            startHandler: {
                type: Function,
                default () {
                    return node => {
                        node.attr.class = null;
                        node.attr.style = null;
                    };
                }
            },
            endHandler: {
                type: Function,
                default: null
            },
            charsHandler: {
                type: Function,
                default: null
            },
            imageProp: {
                type: Object,
                default () {
                    return {
                        mode: 'aspectFit',
                        padding: 0,
                        lazyLoad: false,
                        domain: ''
                    };
                }
            }
        },
        components: {
            wxParseTemplate
        },
        data() {
            return {
                nodes: {},
                imageUrls: [],
                wxParseWidth: {
                    value: 0
                }
            };
        },
        computed: {},
        mounted() {
            let that = this
            this.getWidth().then(function(data) {
                that.wxParseWidth.value = data;
            })
            this.setHtml()
        },
        methods: {
            setHtml() {
                let {
                    content,
                    noData,
                    imageProp,
                    startHandler,
                    endHandler,
                    charsHandler
                } = this;
                let parseData = content || noData;
                let customHandler = {
                    start: startHandler,
                    end: endHandler,
                    chars: charsHandler
                };
                let results = HtmlToJson(parseData, customHandler, imageProp, this);
                this.imageUrls = results.imageUrls;
                this.nodes = results.nodes;
            },
            getWidth() {
                return new Promise((res, rej) => {
                    // #ifndef MP-ALIPAY || MP-BAIDU
                    var view = uni.createSelectorQuery().select(".content");
                    view.boundingClientRect(data => {
                        if(data.width){
                            res(data.width);
                        }else{
                            res('100%');
                        }
                    }).exec();
                    /* uni.createSelectorQuery()
                        .in(this)
                        .select('.wxParse')
                        .fields({size: true,scrollOffset: true},data => {
                                console.log(data);
                                //res(data.width);
                            }
                        ).exec(); */
                    // #endif
                    // #ifdef MP-BAIDU
                    swan.createSelectorQuery().select('.wxParse').boundingClientRect(function(rect) {
                        rect[0].width
                    }).exec()
                    // #endif
                    // #ifdef MP-ALIPAY
                    my.createSelectorQuery()
                        .select('.wxParse')
                        .boundingClientRect().exec((ret) => {
                            res(ret[0].width);
                        });
                    // #endif
                });
            },
            navigate(href, $event) {
                this.$emit('navigate', href, $event);
            },
            preview(src, $event) {
                if (!this.imageUrls.length || typeof this.imgOptions === 'boolean') {

                } else {
                    uni.previewImage({
                        current: src,
                        urls: this.imageUrls,
                        loop: this.imgOptions.loop,
                        indicator: this.imgOptions.indicator,
                        longPressActions: this.imgOptions.longPressActions
                    });
                }
                this.$emit('preview', src, $event);
            },
            removeImageUrl(src) {
                const {
                    imageUrls
                } = this;
                imageUrls.splice(imageUrls.indexOf(src), 1);
            }
        },
        // 父组件中提供
        provide() {
            return {
                parseWidth: this.wxParseWidth
                // 提示:provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的。
            };
        },
        watch: {
            content() {
                this.setHtml()
            }
        }
    };
</script>

jihai-copyright

jihaiCopyright.vue
<template>
    <view class="cpr">
        <view class="color-9">
            吉海科技 © jihainet.com
        </view>
        <view class="color-9">
            版权所有
        </view>
    </view>
</template>

<script>
</script>

<style>
.cpr{
    text-align: center;
    font-size: 24upx;
    margin: 20upx 0;
}
</style>

jihai-lable.vue

<template>
    <view>
        <radio-group class="uni-list" @change="radioChange">
            <label class="uni-list-cell uni-list-cell-pd" v-for="(item, index) in type_list" :key="index">
                <view class="invoice-type-icon">
                    <radio class="a-radio" :id="item.name" :value="item.value" :checked="item.checked" :disabled="item.disabled"></radio>
                </view>
                <view class="invoice-type-c">
                    <label class="label-2-text" :for="item.name">
                        <text>{{item.name}}</text>
                    </label>
                </view>
            </label>
        </radio-group>
    </view>
</template>

<script>
    export default {
        data() {
            return {
                type_list: [
                    { value: '1', name: '仅退款', checked: true, disabled: false },
                    { value: '2', name: '退货退款', checked: false, disabled:false },
                ],
            };
        },
        methods:{
            radioChange: function(evt) {
                this.type_list.forEach(item => {
                    if (item.value === evt.target.value) {
                        item.checked = true;
                        this.aftersale_type = evt.target.value;
                    }else{
                        item.checked = false;
                    }
                });
                if(this.type_list[0].checked){
                    this.refund_input_noedit = true;
                }else{
                    this.refund_input_noedit = false;
                }
            },
        }
    }
</script>

<style>

</style>

jshop

image
jshop-article.vue
<template>
    <view class='index-article cell-group bottom-cell-group' v-if="data.params.list && data.params.list.length > 0">
        <view class='cell-item'
        v-for="item in data.params.list"
        :key="item.id"
        @click="articleDetail(item.id)"
        >
            
            <view class="cell-item-bd">
                <view class="article-title ">
                    {{ item.title }}
                </view>
                <view class="article-time">
                    {{ item.ctime }}
                </view>
            </view>
            <view class="cell-title-img">
                <image :src="item.cover" mode="aspectFill"></image>
            </view>
        </view>
    </view>
</template>

<script>
export default {
    name: "jshoparticle",
    props: {
        data:{
            // type: Array,
            required: true,
        }
    },
    methods: {
        // 查看文章详情
        articleDetail (articleId) {
            this.$common.navigateTo('/pages/article/index?id=' + articleId+'&id_type=1')
        }
    }
}
</script>

<style>
.index-article .cell-title-img{
    width: 160upx;
    height: 160upx;
    float: right;
}
.index-article .cell-title-img image{
    width: 100%;
    height: 100%;
}
.index-article .cell-item-bd{
    padding-right: 0;
    vertical-align: top;
    position: relative;
}
.index-article .article-title{
    font-size: 28upx;
    color: #333;
    width: 100%;
    min-height: 80upx;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
}
.index-article .article-time{
    font-size: 24upx;
    color: #999;
    display: inline-block;
    min-width: 220upx;
    min-height: 32upx;
    position: absolute;
    bottom: 0;
}

</style>
jshop-articleClassify.vue
<template>
    <view class='index-article cell-group bottom-cell-group' v-if="data.params.list && data.params.list.length > 0">
        <view class='cell-item'
        v-for="item in data.params.list"
        :key="item.id"
        @click="articleDetail(item.id)"
        >
            <view class="cell-item-bd">
                <view class="article-title ">
                    {{ item.title }}
                </view>
                <view class="article-time">
                    {{ item.ctime }}
                </view>
            </view>
        
            <view class="cell-title-img">
                <image :src="item.cover" mode="aspectFill"></image>
            </view>
        </view>
    </view>
</template>

<script>
export default {
    name: "jshoparticleclassify",
    props: {
        data:{
            // type: Array,
            required: true,
        }
    },
    methods: {
        // 查看文章详情
        articleDetail (articleId) {
            this.$common.navigateTo('/pages/article/index?id=' + articleId+'&id_type=1')
        }
    }
}
</script>

<style>
.index-article .cell-title-img{
    width: 160upx;
    height: 160upx;
    float: right;
}
.index-article .cell-title-img image{
    width: 100%;
    height: 100%;
}
.index-article .cell-item-bd{
    padding-right: 0;
    vertical-align: top;
    position: relative;
}
.index-article .article-title{
    font-size: 28upx;
    color: #333;
    width: 100%;
    min-height: 80upx;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
}
.index-article .article-time{
    font-size: 24upx;
    color: #999;
    display: inline-block;
    min-width: 220upx;
    min-height: 32upx;
    position: absolute;
    bottom: 0;
}

</style>
jshop-blank.vue
<template>
    <view class="blank" :style="{background:data.params.backgroundColor,height:data.params.height*2+'rpx'}"></view>
</template>

<script>
export default {
    name: "jshopblank",
    props: {
        data:{
            // type: Array,
            required: true,
        }
    },
    methods: {
        
    }
}
</script>

<style>
</style>
jshop-content.vue
<template>
    <view class="content">
        <u-parse :content="content" @preview="preview" @navigate="navigate" />
    </view>
</template>
<script>
    //视频和文本解析组件
    import uParse from '@/components/gaoyia-parse/parse.vue'
    export default {
        name: 'jshop-content',
        components: {
            uParse
        },
        props: {
            content: {}
        },
        created() {},
        methods: {
            preview(src, e) {
                // do something
            },
            navigate(href, e) {
                // do something
            }
        }
    }
</script>
jshop-coupon.vue
<template>
    <view class="coupon bottom-cell-group" v-if="data.params.list.length > 0">
        <view class="coupon-item" v-for="item in data.params.list" :key="item.id" @click="receiveCoupon(item.id)">
            <view class="coupon-i-l">
                <view class="coupon-i-l-t">
                    <image class="icon" src="/static/image/element-ic.png" mode=""></image>
                    <text>{{ item.name }}</text>
                </view>
                <view class="coupon-i-l-b">
                    {{ item.expression1 + item.expression2 }}
                </view>
            </view>
            <view class="coupon-i-r">
                <image class="coupon-logo" src="/static/image/coupon-element.png" mode=""></image>
            </view>
        </view>
    </view>
</template>

<script>
export default {
    name: "jshopcoupon",
    props: {
        data:{
            // type: Array,
            required: true,
        }
    },
    methods: {
        // 用户领取优惠券
        receiveCoupon(couponId) {
            let data = {
                promotion_id: couponId
            }
            this.$api.getCoupon(data, res => {
                if (res.status) {
                    this.$common.successToShow(res.msg)
                } else {
                    this.$common.errorToShow(res.msg)
                }
            })
        },
    }
}    
</script>

<style>
.coupon {
    padding: 0 26upx;
    background-color: #f8f8f8;
}

.coupon-item {
    padding: 20upx;
    margin-bottom: 20upx;
    background-color: #fff;
}

.coupon-i-l {
    width: 400upx;
    display: inline-block;
}

.coupon-i-l-t {
    font-size: 32upx;
    position: relative;
    margin-bottom: 10upx;
}

.coupon-i-l-t .icon {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
}

.coupon-i-l-t text {
    margin-left: 60upx;
}

.coupon-i-l-b {
    font-size: 24upx;
    color: #999;
}

.coupon-i-r {
    width: 258upx;
    display: inline-block;
    text-align: center;
}

.coupon-logo {
    width: 130upx;
    height: 100upx;
}

</style>
jshop-goods.vue
<template>
    <view class="index-goods">
        <!-- 列表平铺两列三列 -->
        <view class='img-grids bottom-cell-group' 
        v-if="data.params.column == '2' && data.params.display == 'list' || data.params.column == '3' && data.params.display == 'list'"
        v-bind:class="'column'+data.params.column">
            <view class='cell-item right-img' v-if="data.params.title != ''">
                <view class='cell-item-hd'>
                    <view class='cell-hd-title'>{{data.params.title}}</view>
                </view>
                <view class='cell-item-bd'>
                </view>
                <view class='cell-item-ft' v-if="data.params.lookMore == 'true'">
                    <image class='cell-ft-next icon' src='/static/image/right.png'></image>
                    <text class='cell-ft-text' @click="goodsList({cat_id: data.params.classifyId,brand_id:data.params.brandId})">查看更多</text>
                </view>
            </view>
            <!-- <view class='img-grids'> -->
                <view class="" v-if="data.params.list.length">
                    <view class="img-grids-item" v-for="item in data.params.list" :key="item.id" @click="goodsDetail(item.id)">
                        <image
                            class="img-grids-item-t have-none"
                            :src="item.image_url"
                            mode='aspectFill'
                        ></image>
                        <view class="img-grids-item-b">
                            <view class="goods-name grids-goods-name">
                                {{item.name}}
                            </view>
                            <view class="goods-item-c">
                                <view class="goods-price red-price">¥{{item.price}}</view>
                            </view>
                        </view>
                    </view>
                </view>
        
                <view v-else-if="!data.params.list.length && !data.params.listAjax">
                    <view class='img-grids-item'>
                        <image class='img-grids-item-t have-none' src='' mode=''></image>
                        <view class='img-grids-item-b'>
                            <view class='goods-name grids-goods-name have-none'></view>
                            <view class='goods-item-c'>
                                <view class='goods-price red-price have-none'></view>
                            </view>
                        </view>
                    </view>
                    <view class='img-grids-item'>
                        <image class='img-grids-item-t have-none' src='' mode=''></image>
                        <view class='img-grids-item-b'>
                            <view class='goods-name grids-goods-name have-none'></view>
                            <view class='goods-item-c'>
                                <view class='goods-price red-price have-none'></view>
                            </view>
                        </view>
                    </view>
                    <view class='img-grids-item'>
                        <image class='img-grids-item-t have-none' src='' mode=''></image>
                        <view class='img-grids-item-b'>
                            <view class='goods-name grids-goods-name have-none'></view>
                            <view class='goods-item-c'>
                                <view class='goods-price red-price have-none'></view>
                            </view>
                        </view>
                    </view>
                </view>
                <!-- <view v-else="">
                    <scroll-view class='swiper-list' scroll-x="true"></scroll-view>
                </view> -->
            <!-- </view> -->
        </view>
        
        <!-- 列表平铺单列 -->
        <view class="img-list bottom-cell-group" 
        v-if="data.params.column == '1' && data.params.display == 'list'" >
            <view class='cell-item right-img' v-if="data.params.title != ''">
                <view class='cell-item-hd'>
                    <view class='cell-hd-title'>{{data.params.title}}</view>
                </view>
                <view class='cell-item-bd'>
                </view>
                <view class='cell-item-ft' v-if="data.params.lookMore == 'true'">
                    <image class='cell-ft-next icon' src='/static/image/right.png'></image>
                    <text class='cell-ft-text' @click="goodsList({cat_id: data.params.classifyId,brand_id:data.params.brandId})">查看更多</text>
                </view>
            </view>
            <view v-if="data.params.list.length>0">
                <view class="img-list-item" v-for="(item, index) in data.params.list" :key="index" @click="goodsDetail(item.id)">
                    <image class="img-list-item-l have-none" :src="item.image_url" mode='aspectFill'></image>
                    <view class="img-list-item-r">
                        <view class="goods-name list-goods-name">
                            {{item.name}}
                        </view>
                        <view class="goods-item-c">
                            <view class="goods-price red-price">¥{{item.price}}</view>
                            <view class="goods-buy">
                                <view class="goods-salesvolume" v-if="item.comments_count > 0">{{item.comments_count}}条评论</view>
                                <view class="goods-salesvolume" v-else-if="item.comments_count <= 0">暂无评论</view>
                                <image class="goods-cart" src="/static/image/ic-car.png"></image>
                            </view>
                        </view>
                    </view>
                </view>
            </view>
            <view class="order-none" v-else>
                <image class="order-none-img" src="/static/image/order.png" mode=""></image>
            </view>
        </view>
        
        <!-- 横向滚动 -->
        <view class='img-grids bottom-cell-group' 
        v-if="data.params.column == '2' && data.params.display == 'slide' || data.params.column == '3' && data.params.display == 'slide'"
        v-bind:class="'slide'+data.params.column">
            <view class='cell-item right-img' v-if="data.params.title != ''">
                <view class='cell-item-hd'>
                    <view class='cell-hd-title'>{{data.params.title}}</view>
                </view>
                <view class='cell-item-bd'>
                </view>
                <view class='cell-item-ft' v-if="data.params.lookMore == 'true'">
                    <image class='cell-ft-next icon' src='/static/image/right.png'></image>
                    <text class='cell-ft-text' @click="goodsList({cat_id: data.params.classifyId,brand_id:data.params.brandId})">查看更多</text>
                </view>
            </view>
            <view class='swiper-grids'>
                <scroll-view class='swiper-list' scroll-x="true" v-if="data.params.list.length">
                    <view class='img-grids-item' v-for="item in data.params.list" :key="item.id" @click="goodsDetail(item.id)">
                        <image class='img-grids-item-t have-none' :src='item.image_url' mode='aspectFill'></image>
                        <view class='img-grids-item-b'>
                            <view class='goods-name grids-goods-name'>{{ item.name }}</view>
                            <view class='goods-item-c'>
                                <view class='goods-price red-price'>¥{{ item.price }}</view>
                            </view>
                        </view>
                    </view>
                </scroll-view>
                <view v-else-if="!goodsListOfHotAjax && !goodsListOfHot.length">
                    <scroll-view class='swiper-list' scroll-x="true">
                        <view class='img-grids-item'>
                            <image class='img-grids-item-t have-none' src='' mode='aspectFill'></image>
                            <view class='img-grids-item-b'>
                                <view class='goods-name grids-goods-name have-none'></view>
                                <view class='goods-item-c'>
                                    <view class='goods-price red-price have-none'></view>
                                </view>
                            </view>
                        </view>
                        <view class='img-grids-item'>
                            <image class='img-grids-item-t have-none' src='' mode='aspectFill'></image>
                            <view class='img-grids-item-b'>
                                <view class='goods-name grids-goods-name have-none'></view>
                                <view class='goods-item-c'>
                                    <view class='goods-price red-price have-none'></view>
                                </view>
                            </view>
                        </view>
                        <view class='img-grids-item'>
                            <image class='img-grids-item-t have-none' src='' mode=''></image>
                            <view class='img-grids-item-b'>
                                <view class='goods-name grids-goods-name have-none'></view>
                                <view class='goods-item-c'>
                                    <view class='goods-price red-price have-none'></view>
                                </view>
                            </view>
                        </view>
                    </scroll-view>
                </view>
                <view v-else="">
                    <scroll-view class='swiper-list' scroll-x="true"></scroll-view>
                </view>
            </view>
        </view>
    </view>
</template>

<script>
import {goods} from '@/config/mixins.js'
export default {
    mixins: [goods],
    name: "jshopgoods",
    props: {
        data:{
            // type: Array,
            required: true,
        }
    },
    methods: {
        //跳转到商品详情页面
        goodsDetail: function(id) {
            let url = '/pages/goods/index/index?id=' + id;
            this.$common.navigateTo(url);
        },
    },
}
</script>

<style>
.cell-item {
    border: none;
    /* padding-bottom: 0; */
}
.cell-ft-text {
    font-size: 22upx;
    color: #999;
}
.img-grids,.img-list{
    /* margin-top: 20upx; */
    background-color: #fff;
}
.img-grids-item{
    display: inline-table;
    margin-top: 0;
    margin-bottom: 14upx;
}
.column3 .img-grids-item{
    width: 230upx;
    margin: 15upx;
    margin-right: 0;
    margin-top: 0;
    margin-bottom: 6upx;
}
.column3 .img-grids-item:nth-child(3n){
    margin-right: 15upx;
}
.column3 .img-grids-item-t{
    width: 230upx;
    height: 230upx;
}
.column3 .grids-goods-name{
    font-size: 24upx;
    height: 68upx;
}
.column3 .img-grids-item-b{
    padding: 0 8upx 8upx;
}
.column3 .goods-price{
    font-size: 26upx;
}
.slide3 .img-grids-item{
    width: 200upx;
}
.slide3 .img-grids-item-t{
    width: 200upx;
    height: 200upx;
}
.slide3 .grids-goods-name{
    font-size: 24upx;
}
.index-goods .img-grids-item{
    display: inline-block;
    margin-top: 0;
}
.index-goods .img-list-item{
    padding: 0upx 26upx;
    margin-bottom: 14upx;
}
.index-goods .img-list{
    padding-bottom: 10upx;
}
</style>
jshop-groupPurchase.vue
<template>
    <!-- 团购秒杀 -->
    <view class="img-list bottom-cell-group group-buying" v-if="data.params.list && data.params.list.length > 0">
        <view class='cell-item right-img'>
            <view class='cell-item-hd group-title'>
                {{data.params.title}}
                <!-- <view class='cell-hd-title'></view> -->
            </view>
        </view>
        <view class='swiper-grids'>
            <scroll-view class='swiper-list' scroll-x="true">
                <view class="img-list-item" v-if="item.goods !== 'undefined' && item.goods" v-for="(item, key) in data.params.list"
                 :key="key">
                    <image class="img-list-item-l medium-img have-none" :src="item.goods.image_url" mode='aspectFill' @click="groupDetail(item.goods.id, item.goods.group_id)"></image>
                    <view class="img-list-item-r medium-right">
                        <view class="goods-name list-goods-name" @click="groupDetail(item.goods.id, item.goods.group_id)">{{item.goods.name}}</view>
                        <view class="goods-item-c">
                            <view class="goods-price red-price">¥{{item.goods.product.price}}</view>
                            <view class="goods-buy">
                                <view class="goods-salesvolume red-price" v-if="(item.goods.lasttime != '已经结束' || item.goods.lasttime != '即将开始') && item.goods.lasttime">剩余:<uni-countdown
                                     :show-day="false" :hour="item.goods.lasttime.hour" :minute="item.goods.lasttime.minute" :second="item.goods.lasttime.second"></uni-countdown>
                                </view>
                                <view class="goods-salesvolume red-price" v-if="item.goods.lasttime == '已经结束'">已结束</view>
                                <view class="goods-salesvolume red-price" v-if="item.goods.lasttime == '即将开始'">即将开始</view>
                                <image class="goods-cart" src="/static/image/ic-car.png" @click="groupDetail(item.goods.id, item.goods.group_id)"></image>
                            </view>
                        </view>
                    </view>
                </view>
            </scroll-view>
        </view>
    </view>
</template>

<script>
    import uniCountdown from "@/components/uni-countdown/uni-countdown.vue"
    import {
        goods
    } from '@/config/mixins.js'
    export default {
        mixins: [goods],
        components: {
            uniCountdown
        },
        name: "jshopgrouppurchase",
        props: {
            data: {
                // type: Array,
                required: false,
            }
        },
        methods: {
            showSliderInfo(type, val) {
                if (type == 1) {
                    if (val.indexOf('http') != -1) {
                        // #ifdef H5 
                        window.location.href = val
                        // #endif
                    } else {
                        // #ifdef H5 || APP-PLUS || APP-PLUS-NVUE || MP
                        if (val == '/pages/classify/classify' || val == '/pages/cart/index/index' || val == '/pages/member/index/index') {
                            uni.switchTab({
                                url: val
                            });
                            return;
                        } else {
                            this.$common.navigateTo(val);
                            return;
                        }
                        // #endif
                    }
                } else if (type == 2) {
                    // 商品详情
                    this.goodsDetail(val)
                } else if (type == 3) {
                    // 文章详情
                    this.$common.navigateTo('/pages/article/index?id=' + val +'&id_type=1')
                } else if (type == 4) {
                    // 文章列表
                    this.$common.navigateTo('/pages/article/list?cid=' + val)
                } else if (type == 5) {
                    //智能表单 
                    this.$common.navigateTo('/pages/form/detail/form?id=' + val)
                }
            },
            //跳转到商品详情页面
            // goodsDetail: function(id) {
            //     let url = '/pages/goods/index/index?id=' + id;
            //     this.$common.navigateTo(url);
            // },
        },
    }
</script>

<style>
    .img-list,
    .img-grids {
        background-color: #fff;
    }

    .cell-item {
        border: none;
    }

    .group-buying .img-list-item {
        min-height: 236upx;
        padding: 20upx;
        margin-left: 26upx;
        margin-bottom: 26upx;
        display: inline-table;
        background-color: #f9f9f9;
    }

    .swiper-grids .img-list-item:last-child {
        margin-right: 26upx;
    }

    /* .group-buying .goods-name{
    min-height: 74upx;
} */
    .group-buying .group-title {
        width: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
</style>
jshop-imgSingle.vue
<template>
    <!-- 单图 -->
    <view class="ad jshop-imgsingle" v-if="data.params.list && data.params.list.length > 0">
        <view class="" v-for="item in data.params.list" :key="item.id">
            <image class="ad-img" :src="item.image" mode="widthFix" @click="showSliderInfo(item.linkType, item.linkValue)"></image>
            <view class="imgup-btn" v-if="item.buttonText != ''" @click="showSliderInfo(item.linkType, item.linkValue)">
                <button class="btn btn-fillet" :style="{background:item.buttonColor,color:item.textColor}">{{item.buttonText}}</button>
            </view>
        </view>
    </view>
</template>

<script>
    export default {
        name: "jshopimgsingle",
        props: {
            data: {
                // type: Object,
                required: true,
            }
        },
        methods: {
            showSliderInfo(type, val) {
                if (!val) {
                    return;
                }
                if (type == 1) {
                    if (val.indexOf('http') != -1) {
                        // #ifdef H5 
                        window.location.href = val
                        // #endif
                    } else {
                        // #ifdef H5 || APP-PLUS || APP-PLUS-NVUE || MP
                        if (val == '/pages/index/index' || val == '/pages/classify/classify' || val == '/pages/cart/index/index' || val == '/pages/member/index/index') {
                            uni.switchTab({
                                url: val
                            });
                            return;
                        } else {
                            this.$common.navigateTo(val);
                            return;
                        }
                        // #endif
                    }
                } else if (type == 2) {
                    // 商品详情
                    this.goodsDetail(val)
                } else if (type == 3) {
                    // 文章详情
                    this.$common.navigateTo('/pages/article/index?id=' + val + '&id_type=1')
                } else if (type == 4) {
                    // 文章列表
                    this.$common.navigateTo('/pages/article/list?cid=' + val)
                } else if (type == 5) {
                    //智能表单 
                    this.$common.navigateTo('/pages/form/detail/form?id=' + val)
                }
            },
            //跳转到商品详情页面
            goodsDetail: function(id) {
                // let ins = encodeURIComponent('id='+id);
                let url = '/pages/goods/index/index?id=' + id;
                this.$common.navigateTo(url);
            },
        },
    }
</script>

<style>
    /* .ad {
    width: 100%;
    overflow: hidden;
}
.ad-img{
    width: 100%;
    float: left;
    margin-bottom: 20upx;
}
.ad-img:last-child{
    margin-bottom: 0;
} */
    .jshop-imgsingle.ad {
        width: 100%;
        overflow: hidden;
        position: relative;
    }

    .jshop-imgsingle .ad-img {
        width: 100%;
        float: left;
        position: relative;
        z-index: 667;
        /* margin-bottom: 20upx; */
    }

    .jshop-imgsingle .ad-img:last-child {
        margin-bottom: 0;
    }

    .jshop-imgsingle .imgup-btn {
        position: absolute;
        z-index: 668;
        bottom: 80upx;
        left: 40upx;
    }

    .jshop-imgsingle .imgup-btn .btn {
        line-height: 2;
        font-size: 28upx;
        padding: 0 50upx;
    }
</style>
jshop-imgSlide.vue
<template>
    <view class='swiper bottom-cell-group' v-if="data.params.list && data.params.list.length > 0">
        <swiper class="swiper-c" :indicator-dots="swiper.indicatorDots" :autoplay="swiper.autoplay" :interval="data.params.duration"
         :duration="swiper.duration">
            <swiper-item class="have-none" v-for="(item, index) in data.params.list" :key="index">
                <image class='' :src="item.image" @click="showSliderInfo(item.linkType, item.linkValue)" mode="aspectFill"></image>
            </swiper-item>
        </swiper>
    </view>
</template>

<script>
    export default {
        name: "jshopimgSlide",
        props: {
            data: {
                // type: Object,
                required: true,
            }
        },
        data() {
            return {
                swiper: {
                    indicatorDots: true,
                    autoplay: true,
                    // interval: 2000,
                    duration: 500,
                },
            };
        },
        created() {},
        watch: {},
        methods: {
            // 广告点击查看详情
            showSliderInfo(type, val) {
                if (!val) {
                    return;
                }
                if (type == 1) {
                    if (val.indexOf('http') != -1) {
                        // #ifdef H5 
                        window.location.href = val
                        // #endif
                    } else {
                        // #ifdef H5 || APP-PLUS || APP-PLUS-NVUE || MP
                        if (val == '/pages/index/index' || val == '/pages/classify/classify' || val == '/pages/cart/index/index' || val == '/pages/member/index/index') {
                            uni.switchTab({
                                url: val
                            });
                            return;
                        } else {
                            this.$common.navigateTo(val);
                            return;
                        }
                        // #endif
                    }
                } else if (type == 2) {
                    // 商品详情
                    this.goodsDetail(val)
                } else if (type == 3) {
                    // 文章详情
                    this.$common.navigateTo('/pages/article/index?id=' + val + '&id_type=1')
                } else if (type == 4) {
                    // 文章列表
                    this.$common.navigateTo('/pages/article/list?cid=' + val)
                } else if (type == 5) {
                    //智能表单 
                    this.$common.navigateTo('/pages/form/detail/form?id=' + val)
                }
            },
            //跳转到商品详情页面
            goodsDetail: function(id) {
                let url = '/pages/goods/index/index?id=' + id;
                this.$common.navigateTo(url);
            },
        }
    }
</script>

<style>
    .swiper {
        height: 340upx;
    }
</style>
jshop-imgWindow.vue
<template>
    <view class="imgwindow bottom-cell-group">
        <view class="imgwindow-list" v-if="data.params.style == '2' ||data.params.style == '3' ||data.params.style == '4'"
         v-bind:class="'row'+data.params.style" :style="{margin:-data.params.margin+'px'}">
            <view class="imgwindow-item" ref="imgwitem" :style="{height:height+'px',padding:data.params.margin+'px'}" v-for="(item, index) in data.params.list"
             :key="index">
                <image :src="item.image" mode="aspectFill" @click="showSliderInfo(item.linkType, item.linkValue)"></image>
            </view>
        </view>
        <view class="imgwindow-list" v-if="data.params.style == '0'" v-bind:class="'row'+data.params.style" :style="{margin:-data.params.margin+'px'}">
            <view class="imgwindow-item" ref="imgwitem" :style="{height:height+'px',padding:data.params.margin+'px'}" v-for="(item, index) in data.params.list"
             :key="index" v-if="index == 0">
                <image :src="item.image" mode="aspectFill" @click="showSliderInfo(item.linkType, item.linkValue)"></image>
            </view>
            <view class="imgwindow-item" ref="imgwitem" :style="{height:height1+'px',padding:data.params.margin+'px'}" v-for="(item, index) in data.params.list"
             :key="index" v-if="index !== 0">
                <image :src="item.image" mode="aspectFill" @click="showSliderInfo(item.linkType, item.linkValue)"></image>
            </view>
        </view>
    </view>
</template>

<script>
    export default {
        name: "jshopimgwindow",
        props: {
            data: {
                // type: Object,
                required: true,
            }
        },
        data() {
            return {
                height: '',
                height1: '',
                padding: '3'
            }
        },
        mounted() {
            // #ifdef H5 || APP-PLUS || APP-PLUS-NVUE
            var view = uni.createSelectorQuery().in(this).select(".imgwindow-item");
            view.boundingClientRect(data => {
                this.height = data.width;
                // 橱窗小图高度
                this.height1 = data.width / 2;
            }).exec();
            // #endif

            // #ifdef MP-ALIPAY
            var view = uni.createSelectorQuery().select(".content").boundingClientRect().exec(data => {
                this.height1 = data[0].width / 4;
                if (this.data.params.style == '3') {
                    this.height = data[0].width / 3;
                } else if (this.data.params.style == '2') {
                    this.height = data[0].width / 2;
                } else if (this.data.params.style == '4') {
                    this.height = data[0].width / 4;
                } else if (this.data.params.style == '0') {
                    this.height = data[0].width / 2;
                }
            });
            // #endif

            // #ifdef MP-WEIXIN

            var view = uni.createSelectorQuery().select(".content");

            view.boundingClientRect(data => {

                this.height1 = data.width / 4;
                if (this.data.params.style == '3') {
                    this.height = data.width / 3;
                } else if (this.data.params.style == '2') {
                    this.height = data.width / 2;
                } else if (this.data.params.style == '4') {
                    this.height = data.width / 4;
                } else if (this.data.params.style == '0') {
                    this.height = data.width / 2;
                }
            }).exec();
            // #endif
        },
        methods: {
            showSliderInfo(type, val) {
                if (!val) {
                    return;
                }
                if (type == 1) {
                    if (val.indexOf('http') != -1) {
                        // #ifdef H5 
                        window.location.href = val
                        // #endif
                    } else {
                        // #ifdef H5 || APP-PLUS || APP-PLUS-NVUE || MP
                        if (val == '/pages/index/index' || val == '/pages/classify/classify' || val == '/pages/cart/index/index' || val ==
                            '/pages/member/index/index') {
                            uni.switchTab({
                                url: val
                            });
                            return;
                        } else {
                            this.$common.navigateTo(val);
                            return;
                        }
                        // #endif
                    }
                } else if (type == 2) {
                    // 商品详情
                    this.goodsDetail(val)
                } else if (type == 3) {
                    // 文章详情
                    this.$common.navigateTo('/pages/article/index?id=' + val + '&id_type=1')
                } else if (type == 4) {
                    // 文章列表
                    this.$common.navigateTo('/pages/article/list?cid=' + val)
                } else if (type == 5) {
                    //智能表单 
                    this.$common.navigateTo('/pages/form/detail/form?id=' + val)
                }
            },
            //跳转到商品详情页面
            goodsDetail: function(id) {
                let url = '/pages/goods/index/index?id=' + id;
                this.$common.navigateTo(url);
            },
        }
    }
</script>

<style>
    .imgwindow {
        width: 100%;
    }

    .imgwindow-list {
        overflow: hidden;
        /* margin: -16upx; */
    }

    /* 堆积两列 */
    .imgwindow-list .imgwindow-item {
        height: auto;
        float: left;
        /* padding: 8upx; */
    }

    .imgwindow-list .imgwindow-item image {
        width: 100%;
        height: 100%;
    }

    .imgwindow-list.row0 .imgwindow-item:first-child {
        width: 50%;
    }

    .imgwindow-list.row0 .imgwindow-item:nth-child(2) {
        width: 50%;
    }

    .imgwindow-list.row0 .imgwindow-item:nth-child(3),
    .imgwindow-list.row0 .imgwindow-item:nth-child(4) {
        width: 25%;

    }

    .imgwindow-list.row2 .imgwindow-item {
        width: 50%;
    }

    .imgwindow-list.row3 .imgwindow-item {
        width: 33.3%;
    }

    .imgwindow-list.row4 .imgwindow-item {
        width: 25%;
    }
</style>
jshop-navBar.vue
<template>
    <view class="imgnavbar bottom-cell-group">
        <view class="imgnavbar-list" v-if="data.params.limit == '3' ||data.params.limit == '4' ||data.params.limit == '5'"
         v-bind:class="'row'+data.params.limit">
            <view class="imgnavbar-item" ref="imgwitem" v-for="(item, index) in data.params.list" :key="index">
                <image class="imgnavbar-item-img" :src="item.image" mode="aspectFill" @click="showSliderInfo(item.linkType, item.linkValue)"></image>
                <view class="imgnavbar-item-text">{{item.text}}</view>
            </view>
        </view>
    </view>
</template>

<script>
    export default {
        name: "jshopnavbar",
        props: {
            data: {
                // type: Object,
                required: true,
            }
        },
        data() {
            return {
                height: '',
                height1: ''
            }
        },
        onLoad() {

        },
        mounted() {

        },
        methods: {
            showSliderInfo(type, val) {
                if (!val) {
                    return;
                }
                if (type == 1) {
                    if (val.indexOf('http') != -1) {
                        // #ifdef H5 
                        window.location.href = val
                        // #endif
                    } else {
                        // #ifdef H5 || APP-PLUS || APP-PLUS-NVUE || MP
                        if (val == '/pages/index/index' || val == '/pages/classify/classify' || val == '/pages/cart/index/index' || val == '/pages/member/index/index') {
                            uni.switchTab({
                                url: val
                            });
                            return;
                        } else {
                            this.$common.navigateTo(val);
                            return;
                        }
                        // #endif
                    }
                } else if (type == 2) {
                    // 商品详情
                    this.goodsDetail(val)
                } else if (type == 3) {
                    // 文章详情
                    this.$common.navigateTo('/pages/article/index?id=' + val + '&id_type=1')
                } else if (type == 4) {
                    // 文章列表
                    this.$common.navigateTo('/pages/article/list?cid=' + val)
                } else if (type == 5) {
                    //智能表单 
                    this.$common.navigateTo('/pages/form/detail/form?id=' + val)
                }
            },
            //跳转到商品详情页面
            goodsDetail: function(id) {
                let url = '/pages/goods/index/index?id=' + id;
                this.$common.navigateTo(url);
            },
        }
    }
</script>

<style>
    .imgnavbar {
        width: 100%;
        background-color: #fff;
    }

    .imgnavbar-list {
        overflow: hidden;
        padding: 24upx 0 0;
    }

    /* 堆积两列 */
    .imgnavbar-list .imgnavbar-item {
        height: auto;
        float: left;
        padding: 0upx 10upx;
        margin-bottom: 20upx;
        text-align: center;
    }

    .imgnavbar-list .imgnavbar-item image {
        width: 90upx;
        height: 90upx;
        margin-bottom: 6upx;
    }

    .imgnavbar-item-text {
        font-size: 26upx;
        color: #666;
        width: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .imgnavbar-list.row3 .imgnavbar-item {
        width: 33.3%;
    }

    .imgnavbar-list.row4 .imgnavbar-item {
        width: 25%;
    }

    .imgnavbar-list.row5 .imgnavbar-item {
        width: 20%;
    }

    .imgnavbar-list.row5 .imgnavbar-item .imgnavbar-item-text {
        font-size: 24upx;
    }
</style>
jshop-notice.vue
<template>
    <view class="notice bottom-cell-group" v-if="data.params.list && data.params.list.length > 0">
        <view class="notice-icon">
            <image class="icon news-icon" src="/static/image/news.png" mode=""></image>
        </view>
        <swiper class="notice-c" :indicator-dots="false" :autoplay="true" :interval="3000" :duration="1000" :vertical="true" :circular="true">
            <swiper-item v-for="item in data.params.list" :key="item.id">
                <view class="swiper-item" @click="goNotice(item.id)">{{ item.title }}</view>
            </swiper-item>
        </swiper>
    </view>
</template>

<script>
    export default {
        name: "jshopnotice",
        props: {
            data:{
                // type: Object,
                required: true,
            }
        },
        methods: {
            // 点击公告
            goNotice(id) {
                // 文章详情
                this.$common.navigateTo('/pages/article/index?id=' + id+'&id_type=2')
            },
        },
    }
</script>

<style>
.notice {
    padding: 6upx 26upx 6upx 60upx;
    position: relative;
    overflow: hidden;
    background-color: #fff;
    color: #333;
}
.notice-icon {
    display: inline-block;
    height: 40upx;
    position: absolute;
    top: 59%;
    left: 26upx;
    transform: translateY(-50%);
    overflow: hidden;
}
.news-icon {
    width: 30upx;
    height: 30upx;
    float: left;
}
.notice-c {
    margin-left: 10upx;
    height: 50upx;
    line-height: 50upx;
    width: 630upx;
    display: inline-block;
    font-size: 28upx;
    float: left;
}
</style>
jshop-pintuan.vue
<template>
    <!-- 拼团 -->
    <view class="img-list bottom-cell-group group-buying" v-if="data.params.list && data.params.list.length > 0">
        <view class='cell-item right-img'>
            <view class='cell-item-hd group-title'>
                {{data.params.title}}
            </view>
        </view>
        <view class='swiper-grids' >
            <scroll-view class='swiper-list' scroll-x="true">
                <view class="img-list-item" v-if="item.goods_id !== 'undefined' && item.goods_id" v-for="(item, key) in data.params.list" :key="key">
                    <image class="img-list-item-l medium-img have-none" :src="item.goods_image" mode='aspectFill' @click="pintuanDetail(item.goods_id)"></image>
                    <view class="img-list-item-r medium-right">
                        <view class="goods-name list-goods-name" @click="pintuanDetail(item.goods_id)">{{item.goods_name}}</view>
                        <view class="goods-item-c">
                            <view class="goods-price red-price">¥{{item.pintuan_price}}</view>
                            <view class="goods-buy">
                                <view class="goods-salesvolume red-price" v-if="(item.pintuan_start_status == 1) && item.lasttime">剩余:<uni-countdown :show-day="false" :hour="item.lasttime.hour" :minute="item.lasttime.minute" :second="item.lasttime.second"></uni-countdown></view>
                                <view class="goods-salesvolume red-price" v-if="item.pintuan_start_status == 3">已结束</view>
                                <view class="goods-salesvolume red-price" v-if="item.pintuan_start_status == 2">即将开团</view>
                                
                                <image class="goods-cart" src="/static/image/ic-car.png" @click="pintuanDetail(item.goods.id)"></image>
                            </view>
                        </view>
                    </view>
                </view>
            </scroll-view>
        </view>
    </view>
</template>

<script>
import uniCountdown from "@/components/uni-countdown/uni-countdown.vue"
import {goods} from '@/config/mixins.js'
export default {
    mixins: [goods],
    components:{uniCountdown},
    name: "jshoppintuan",
    props: {
        data:{
            // type: Array,
            required: false,
        }
    },
    methods: {
    },
}
</script>

<style>
.img-list, .img-grids {
    background-color: #fff;
}
.cell-item{
    border: none;
}
.group-buying .img-list-item{
    min-height: 236upx;
    padding: 20upx;
    margin-left: 26upx;
    margin-bottom: 26upx;
    display: inline-table;
    background-color: #f9f9f9;
}
.swiper-grids .img-list-item:last-child{
    margin-right: 26upx;
}

/* .group-buying .goods-name{
    min-height: 74upx;
} */
.group-buying .group-title{
    width: 100%;
    overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
</style>
jshop-record.vue
<template>
    <view class="adbrathing" 
    v-show="adbshow" 
    v-bind:class="['adbrathing'+data.params.style.align,!hideanimation?'pc':hideanimation?'hc':'']" 
    :style="{top:data.params.style.top+'%'}" >
        <view class="adbrathing-c">
            <view class="adbrathing-l">
                <image class="user-head-img" :src="log.avatar" mode="aspectFill"></image>
                <view class="user-name">
                    {{log.nickname}}
                </view>
            </view>
            <view class="adbrathing-r">
                 {{log.ctime}}{{log.desc}}
            </view>
        </view>
    </view>
</template>

<script>
import { apiBaseUrl } from '@/config/config.js';
export default {
    name: "jshoprecord",
    props: {
        data:{
            // type: Object,
            required: true,
        },
        //记录显示的位置类型
        ltype:{
            type: String,
            required: false,
            default:'home',
        },
        //记录显示的位置的值
        lvalue:{
            type: String,
            required: false,
            default:'0',
        }
    },
    data() {
        return { 
            adbshow:false,
            hideanimation: true,
            log:{
                avatar:'/static/demo-img/user-head.jpg',
                nickname:'',
                desc:'',
                ctime:'',
            },
            times:{},//定时器
        };
    },
    methods:{
        //隐藏
        hideLog(){
            var _this = this;    
            _this.times = setInterval(function(){
                _this.adbshow = !_this.adbshow;
                _this.hideanimation = !_this.hideanimation;
                clearInterval(_this.times);
                _this.times = setInterval(function(){
                    _this.getRecod();
                },5000);
            },3000)
        },
        //获取日志
        getRecod(){
            var _this = this;
            if(_this.times !={}){
                clearInterval(_this.times);
            }
            var data = {
                type:_this.ltype,
                value:_this.lvalue,
                method:'pages.getrecod',
            };
            uni.request({
                url: apiBaseUrl+'api.html',
                data: data,
                header: {
                    'Accept': 'application/json',
                    'Content-Type': 'application/json',
                },
                method: 'POST',
                success: (response) => {
                    var res = response.data;
                    if(res.status == true){
                        if(res.data){
                            _this.log = res.data;
                            _this.adbshow = true;
                            _this.hideanimation = false;
                            _this.hideLog();
                        }
                    }
                }
            });
        }
    },
    mounted() {
        this.getRecod();
    }
}
</script>

<style lang="scss">
.adbrathing{
    position: fixed;
    // top: 100px;
    // right: 30upx;
    // max-width: 400upx;
    height: 70upx;
    background-color: rgba(0,0,0,.5);
    border-radius: 10upx;
    padding: 10upx;
    z-index: 666;
    .adbrathing-c{
        width: 100%;
        height: 100%;
        overflow: hidden;
        color: #fff;
        font-size: 24upx;
        
        .adbrathing-l{
            display: inline-block;
            height: 100%;
            float: left;
            overflow: hidden;
            .user-head-img{
                width: 50upx;
                height: 50upx;
                border-radius: 50%;
                float: left;
                
            }
            .user-name{
                float: left;
                display: inline-block;
                height: 100%;
                line-height: 50upx;
                margin: 0 4upx 0 10upx;
                max-width: 120upx;
                overflow: hidden;
                text-overflow: ellipsis;
                white-space: nowrap;
            }
        }
        
        .adbrathing-r{
            float: left;
            height: 100%;
            display: inline-block;
            line-height: 50upx;
        }
    }
    
}
.adbrathingleft{
    left: 30upx
}
.adbrathingright{
    right: 30upx
}
.pc{
    animation: showcenter .55s;
}
.hc{
    animation: hidecenter .55s;
}
@keyframes showcenter{
    0% {
        opacity: 0;
    }
    100% {
        opacity: 1;
    }
}
@keyframes hidecenter{
    0% {
        opacity: 1;
    }
    100% {
        opacity: 0;
    }
}
</style>
jshop-search.vue
<template>
    <view class="" >
        <!-- 搜索框 -->
        <view class="search" ref="searchBar" id="search">
            <view class='search-c' @click='goSearch()'>
                <view class='search-input search-input-p' v-bind:class="data.params.style">
                    <view class="search-input-p-c">
                        {{data.params.keywords}}
                    </view>
                </view>
                <image class='icon search-icon' src='/static/image/zoom.png'></image>
            </view>
        </view>
        <!-- 搜索框 -->
        <view class="search search-fixed" v-show="searchFixed">
            <view class='search-c' @click='goSearch()'>
                <view class='search-input search-input-p' v-bind:class="data.params.style">
                    <view class="search-input-p-c">
                        {{data.params.keywords}}
                    </view>
                </view>
                <image class='icon search-icon' src='/static/image/zoom.png'></image>
            </view>
        </view>    
    </view>
</template>

<script>
    export default {
        name: "jshopsearch",
        props: {
            data:{
                // type: Object,
                required: true,
            }
        },
        data() {
            return {
                keyword:'',
                searchTop: 0,
                scrollTop: 0,
                searchFixed: false
            };
        },
        onLoad() {
            
        },
    
        created() {
            //#ifdef H5
            this.$nextTick(() => {
                this.searchTop = this.$refs.searchBar.$el.offsetTop;
            })
            // #endif
            this.searchStyle()
            
            
            
        },

        mounted() {
            // #ifdef H5
            window.addEventListener('scroll', this.handleScroll)
            // #endif
            
                
        },
        methods: {
            searchStyle (){
                this.$store.commit('searchStyle',this.data.params.style)
                // console.log(this.data.params.style)
            },
            goSearch() {
                uni.navigateTo({
                    url: '/pages/index/search'
                });
            },
            handleScroll() {
                this.scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
                this.scrollTop >= this.searchTop? this.searchFixed = true : this.searchFixed = false;
            },
        },
        onPageScroll(){
            var _this = this;
            // #ifdef MP-WEIXIN || APP-PLUS
            const query = uni.createSelectorQuery().in(this)
              query.select('.search').boundingClientRect(function(res){
                if(res.top<0){
                    _this.searchFixed = true ;
                }else{
                    _this.searchFixed = false;
                }
              }).exec()
            // #endif
        }
    }
</script>

<style>
.search-input-p {
    color: #888;
}
.square{
    border-radius: 0;
}
.radius{
    border-radius: 12upx;
}
.search-fixed{
    position: fixed;
    top: 0;
    /* background: linear-gradient(rgba(0, 0, 0, .5), rgba(0, 0, 0, 0)); */
    transition: all .5s;
}
/* .isOpacity {
        background: linear-gradient(rgba(0, 0, 0, .5), rgba(0, 0, 0, 0));
        transition: all .5s;
    }

.isOpacity .search-input {
    background-color: rgba(255, 255, 255, .5);
    transition: all .5s;
} */
</style>
jshop-textarea.vue
<template>
    <view class="textarea bottom-cell-group" >
        <jshopContent :content="data.params" v-if="data.params"></jshopContent>
    </view>
</template>

<script>
import htmlParser from '@/common/html-parser'
import jshopContent from '@/components/jshop/jshop-content.vue'//视频和文本解析组件

export default {
    components: {
        jshopContent
    },
    name: "jshoptextarea",
    props: {
        data:{
            // type: Object,
            required: true,
        }
    },
    created() {
        //this.data.params = htmlParser(this.data.params)
    },
    onLoad() {
        
    },
    methods: {
        
    }
}
</script>

<style>
.textarea{
    width: 100%;
    background-color: #fff;
    padding: 10upx 26upx;
    /* height: 40upx; */
}
.textarea p img{
    width: 100% !important;
}
.textarea div{
    background-color: #000;
}
.textarea p {
    background-color: #000;
}
</style>
jshop-video.vue
<template>
    <view class="video bottom-cell-group" >
        <video :src="data.params.list[0].url" :poster="data.params.list[0].image" controls :autoplay='data.params.autoplay'></video>
    </view>
</template>

<script>
export default {
    name: "jshopvideo",
    props: {
        data:{
            type: Object,
            required: true,
        }
    },
    onLoad(){
        
    },
    methods: {
        
    }
}
</script>

<style>
.video video{
    width: 100%;
    min-height: 200upx;
}
</style>
jshop.vue
<template>
  <view>
    <block v-for="(item,index) in data" :key="index">
      <jshopsearch :data="item" v-if="item.widget_code=='search' "></jshopsearch>
      <jshopnotice :data="item" v-if="item.widget_code=='notice' "></jshopnotice>
      <jshopimgSlide :data="item" v-if="item.widget_code=='imgSlide' "></jshopimgSlide>
      <jshopcoupon :data="item" v-if="item.widget_code=='coupon' "></jshopcoupon>
      <jshopblank :data="item" v-if="item.widget_code=='blank' "></jshopblank>
      <jshoptextarea :data="item" v-if="item.widget_code=='textarea' "></jshoptextarea>
      <jshopvideo :data="item" v-if="item.widget_code=='video' "></jshopvideo>
      <jshopimgWindow :data="item" v-if="item.widget_code=='imgWindow' "></jshopimgWindow>
      <jshopimgSingle :data="item" v-if="item.widget_code=='imgSingle' "></jshopimgSingle>
      <jshopgoods :data="item" v-if="item.widget_code=='goods' "></jshopgoods>
      <jshoparticle :data="item" v-if="item.widget_code=='article' "></jshoparticle>
      <jshoparticleClassify :data="item" v-if="item.widget_code=='articleClassify' "></jshoparticleClassify>
      <jshopnavBar :data="item" v-if="item.widget_code=='navBar' "></jshopnavBar>
      <jshopgroupPurchase :data="item" v-if="item.widget_code=='groupPurchase' "></jshopgroupPurchase>
      <jshoprecord :data="item" v-if="item.widget_code=='record' "></jshoprecord>
      <jshoppintuan :data="item" v-if="item.widget_code=='pintuan' "></jshoppintuan>
    </block>
  </view>
</template>

<script>
/**
 * 吉海科技jshop小程序插件集合。
 * author:novice
 * date:2019:05:20
 */
import uniCountdown from '@/components/uni-countdown/uni-countdown.vue'
import jshopimgSlide from '@/components/jshop/jshop-imgSlide.vue'
import jshopsearch from '@/components/jshop/jshop-search.vue'
import jshopnotice from '@/components/jshop/jshop-notice.vue'
import jshopcoupon from '@/components/jshop/jshop-coupon.vue'
import jshopblank from '@/components/jshop/jshop-blank.vue'
import jshoptextarea from '@/components/jshop/jshop-textarea.vue'
import jshopvideo from '@/components/jshop/jshop-video.vue'
import jshopimgWindow from '@/components/jshop/jshop-imgWindow.vue'
import jshopimgSingle from '@/components/jshop/jshop-imgSingle.vue'
import jshopgoods from '@/components/jshop/jshop-goods.vue'
import jshoparticle from '@/components/jshop/jshop-article.vue'
import jshoparticleClassify from '@/components/jshop/jshop-articleClassify.vue'
import jshopnavBar from '@/components/jshop/jshop-navBar.vue'
import jshopgroupPurchase from '@/components/jshop/jshop-groupPurchase.vue'
import jshoprecord from '@/components/jshop/jshop-record.vue'
import jshoppintuan from '@/components/jshop/jshop-pintuan.vue'
export default {
  name: 'jshop',
  components: {
    jshopimgSlide,
    jshopsearch,
    jshopnotice,
    jshopcoupon,
    jshopblank,
    jshoptextarea,
    jshopvideo,
    jshopimgWindow,
    jshopimgSingle,
    jshopgoods,
    jshoparticle,
    jshoparticleClassify,
    jshopnavBar,
    jshopgroupPurchase,
    jshoprecord,
    jshoppintuan
  },
  props: {
    data: {
      default: function() {
        return []
      }
    }
  }
}
</script>

lvv-popup

lvv-popup.vue
<template>
    <view class="lvv-popup" v-show="popshow" @touchmove.prevent>
        <view class="lvv-popupmark" :class="position=='top'&&!hideanimation?'pt':position=='left'&&!hideanimation?'pl':position=='right'&&!hideanimation?'pr':position=='bottom'&&!hideanimation?'pc':position=='top'&&hideanimation?'ht':position=='left'&&hideanimation?'hl':position=='right'&&hideanimation?'hr':position=='bottom'&&hideanimation?'hc':''" @click="close"></view>
        <view class="lvv-popupcontent" @click="close" :class="position=='top'&&!hideanimation?'pt':position=='left'&&!hideanimation?'pl':position=='right'&&!hideanimation?'pr':position=='bottom'&&!hideanimation?'pb':position=='top'&&hideanimation?'ht':position=='left'&&hideanimation?'hl':position=='right'&&hideanimation?'hr':position=='bottom'&&hideanimation?'hb':''">
            <view class="realcontent" @click.stop="">
                <slot></slot>
            </view>
        </view>
    </view>
</template>
<script>
    export default {
        props:{
            position:{
                type:String,
                default:null 
            }
        },
        data() { 
            return { 
                popshow:false,
                hideanimation:false,
            };
        },
        methods:{
            // Toshow popup page
            show:function(){
                this.popshow = true;
            },
            // Tohide popup page
            close:function(){
                let that = this;
                this.$emit("close");
                that.hideanimation = true;
                if(that.position==null){
                    that.popshow = false;
                }else{
                    setTimeout(function(){
                        that.popshow = false;
                        that.hideanimation = false;
                    },500)
                }
            }
        },
    }
</script>

<style lang="scss">
.lvv-popup{
    top:0;
    left: 0;
    width: 100%;
    height: 100%;
    position: fixed;
        z-index: 98;
    .lvv-popupmark{
      top: 0; 
      left: 0;
      width: 100%;
      height: 100%;
            z-index: 99;
      position: absolute;
      background: rgba(0,0,0,0.5);      
    }
        .lvv-popupmark.pt,.lvv-popupmark.ht{
            background: none
        }
        .lvv-popupcontent{
            width: 100%;
            height: 100%;
            top:0;
            left:0;
            position: absolute;
            z-index: 100;
            // overflow-y:;
        }
        .pt{
            animation: showtop 0.5s;
        }
        .pl{
            animation: showleft 0.5s;
        }
        .pr{
            animation: showright 0.5s;
        }
        .pb{
            animation: showbottom .5s;
        }
        .ht{
            animation: hidetop 0.5s;
        }
        .hl{
            animation: hideleft 0.55s;
        }
        .hr{
            animation: hideright 0.55s;
        }
        .hb{
            animation: hidebottom 1s;
        }
        .pc{
            animation: showcontent .55s;
        }
        .hc{
            animation: hidecontent .55s;
        }
        
  }
    @keyframes showtop{
      0% {
            // top: -0px;
        transform: translateY(-100%);
            // height: 0;
          opacity: 1;
      }
      100% {
            top: 0px;
            // height: 100%;
        transform: translateY(0%);
            opacity: 1;
      }
    }
    @keyframes showleft{
      0% {
        transform: translateX(-100%);
          opacity: 1;
      }
      50% {
          opacity: 0;
      }
      100% {
        transform: translateX(0);
      }
    }
    @keyframes showright{
      0% {
        transform: translateX(100%);
          opacity: 1;
      }
      50% {
          opacity: 0;
      }
      100% {
        transform: translateX(0);
      }
    }
    @keyframes showbottom{
      0% {
        transform: translateY(100%);
            opacity: 1;
      }
      50% {
            opacity: 0.5;
      }
      100% {
        transform: translateY(0);
      }
    }
    @keyframes hidetop{
      0% {
        transform: translateY(0%);
            // height: 100%;
            opacity: 1;
      }
      100% {
        transform: translateY(-100%);
            // height: 0;
          opacity: 1;
      }
    }
    @keyframes hideleft{
      0% {
        transform: translateX(0);
      }
      50% {
          opacity: 0;
      }
      100% {
        transform: translateX(-100%);
            opacity: 1;
      }
    }
    @keyframes hideright{
      0% {
        transform: translateX(0);
      }
      50% {
          opacity: 0;
      }
      100% {
        transform: translateX(100%);
            opacity: 1;
      }
    }
    @keyframes hidebottom{
      0% {
        transform: translateY(0);
      }
      50% {
            opacity: 0;
      }
      100% {
        transform: translateY(100%);
            opacity: 1;
      }
    }
    
    @keyframes showcontent{
      0% {
            opacity: 0;
      }
      100% {
            opacity: 1;
      }
    }
    @keyframes hidecontent{
          0% {
                opacity: 1;
          }
          100% {
                opacity: 0;
          }
        }
</style>

mpvue-citypicker

city-data
area.js
/* eslint-disable */
var areaData = [
    [
        [{
            "label": "东城区",
            "value": "110101"
        }, {
            "label": "西城区",
            "value": "110102"
        }, {
            "label": "朝阳区",
            "value": "110105"
        }, {
            "label": "丰台区",
            "value": "110106"
        }, {
            "label": "石景山区",
            "value": "110107"
        }, {
            "label": "海淀区",
            "value": "110108"
        }, {
            "label": "门头沟区",
            "value": "110109"
        }, {
            "label": "房山区",
            "value": "110111"
        }, {
            "label": "通州区",
            "value": "110112"
        }, {
            "label": "顺义区",
            "value": "110113"
        }, {
            "label": "昌平区",
            "value": "110114"
        }, {
            "label": "大兴区",
            "value": "110115"
        }, {
            "label": "怀柔区",
            "value": "110116"
        }, {
            "label": "平谷区",
            "value": "110117"
        }, {
            "label": "密云区",
            "value": "110118"
        }, {
            "label": "延庆区",
            "value": "110119"
        }]
    ],
    [
        [{
            "label": "和平区",
            "value": "120101"
        }, {
            "label": "河东区",
            "value": "120102"
        }, {
            "label": "河西区",
            "value": "120103"
        }, {
            "label": "南开区",
            "value": "120104"
        }, {
            "label": "河北区",
            "value": "120105"
        }, {
            "label": "红桥区",
            "value": "120106"
        }, {
            "label": "东丽区",
            "value": "120110"
        }, {
            "label": "西青区",
            "value": "120111"
        }, {
            "label": "津南区",
            "value": "120112"
        }, {
            "label": "北辰区",
            "value": "120113"
        }, {
            "label": "武清区",
            "value": "120114"
        }, {
            "label": "宝坻区",
            "value": "120115"
        }, {
            "label": "滨海新区",
            "value": "120116"
        }, {
            "label": "宁河区",
            "value": "120117"
        }, {
            "label": "静海区",
            "value": "120118"
        }, {
            "label": "蓟州区",
            "value": "120119"
        }]
    ],
    [
        [{
            "label": "市辖区",
            "value": "130101"
        }, {
            "label": "长安区",
            "value": "130102"
        }, {
            "label": "桥西区",
            "value": "130104"
        }, {
            "label": "新华区",
            "value": "130105"
        }, {
            "label": "井陉矿区",
            "value": "130107"
        }, {
            "label": "裕华区",
            "value": "130108"
        }, {
            "label": "藁城区",
            "value": "130109"
        }, {
            "label": "鹿泉区",
            "value": "130110"
        }, {
            "label": "栾城区",
            "value": "130111"
        }, {
            "label": "井陉县",
            "value": "130121"
        }, {
            "label": "正定县",
            "value": "130123"
        }, {
            "label": "行唐县",
            "value": "130125"
        }, {
            "label": "灵寿县",
            "value": "130126"
        }, {
            "label": "高邑县",
            "value": "130127"
        }, {
            "label": "深泽县",
            "value": "130128"
        }, {
            "label": "赞皇县",
            "value": "130129"
        }, {
            "label": "无极县",
            "value": "130130"
        }, {
            "label": "平山县",
            "value": "130131"
        }, {
            "label": "元氏县",
            "value": "130132"
        }, {
            "label": "赵县",
            "value": "130133"
        }, {
            "label": "晋州市",
            "value": "130183"
        }, {
            "label": "新乐市",
            "value": "130184"
        }],
        [{
            "label": "市辖区",
            "value": "130201"
        }, {
            "label": "路南区",
            "value": "130202"
        }, {
            "label": "路北区",
            "value": "130203"
        }, {
            "label": "古冶区",
            "value": "130204"
        }, {
            "label": "开平区",
            "value": "130205"
        }, {
            "label": "丰南区",
            "value": "130207"
        }, {
            "label": "丰润区",
            "value": "130208"
        }, {
            "label": "曹妃甸区",
            "value": "130209"
        }, {
            "label": "滦县",
            "value": "130223"
        }, {
            "label": "滦南县",
            "value": "130224"
        }, {
            "label": "乐亭县",
            "value": "130225"
        }, {
            "label": "迁西县",
            "value": "130227"
        }, {
            "label": "玉田县",
            "value": "130229"
        }, {
            "label": "遵化市",
            "value": "130281"
        }, {
            "label": "迁安市",
            "value": "130283"
        }],
        [{
            "label": "市辖区",
            "value": "130301"
        }, {
            "label": "海港区",
            "value": "130302"
        }, {
            "label": "山海关区",
            "value": "130303"
        }, {
            "label": "北戴河区",
            "value": "130304"
        }, {
            "label": "抚宁区",
            "value": "130306"
        }, {
            "label": "青龙满族自治县",
            "value": "130321"
        }, {
            "label": "昌黎县",
            "value": "130322"
        }, {
            "label": "卢龙县",
            "value": "130324"
        }],
        [{
            "label": "市辖区",
            "value": "130401"
        }, {
            "label": "邯山区",
            "value": "130402"
        }, {
            "label": "丛台区",
            "value": "130403"
        }, {
            "label": "复兴区",
            "value": "130404"
        }, {
            "label": "峰峰矿区",
            "value": "130406"
        }, {
            "label": "邯郸县",
            "value": "130421"
        }, {
            "label": "临漳县",
            "value": "130423"
        }, {
            "label": "成安县",
            "value": "130424"
        }, {
            "label": "大名县",
            "value": "130425"
        }, {
            "label": "涉县",
            "value": "130426"
        }, {
            "label": "磁县",
            "value": "130427"
        }, {
            "label": "肥乡县",
            "value": "130428"
        }, {
            "label": "永年县",
            "value": "130429"
        }, {
            "label": "邱县",
            "value": "130430"
        }, {
            "label": "鸡泽县",
            "value": "130431"
        }, {
            "label": "广平县",
            "value": "130432"
        }, {
            "label": "馆陶县",
            "value": "130433"
        }, {
            "label": "魏县",
            "value": "130434"
        }, {
            "label": "曲周县",
            "value": "130435"
        }, {
            "label": "武安市",
            "value": "130481"
        }],
        [{
            "label": "市辖区",
            "value": "130501"
        }, {
            "label": "桥东区",
            "value": "130502"
        }, {
            "label": "桥西区",
            "value": "130503"
        }, {
            "label": "邢台县",
            "value": "130521"
        }, {
            "label": "临城县",
            "value": "130522"
        }, {
            "label": "内丘县",
            "value": "130523"
        }, {
            "label": "柏乡县",
            "value": "130524"
        }, {
            "label": "隆尧县",
            "value": "130525"
        }, {
            "label": "任县",
            "value": "130526"
        }, {
            "label": "南和县",
            "value": "130527"
        }, {
            "label": "宁晋县",
            "value": "130528"
        }, {
            "label": "巨鹿县",
            "value": "130529"
        }, {
            "label": "新河县",
            "value": "130530"
        }, {
            "label": "广宗县",
            "value": "130531"
        }, {
            "label": "平乡县",
            "value": "130532"
        }, {
            "label": "威县",
            "value": "130533"
        }, {
            "label": "清河县",
            "value": "130534"
        }, {
            "label": "临西县",
            "value": "130535"
        }, {
            "label": "南宫市",
            "value": "130581"
        }, {
            "label": "沙河市",
            "value": "130582"
        }],
        [{
            "label": "市辖区",
            "value": "130601"
        }, {
            "label": "竞秀区",
            "value": "130602"
        }, {
            "label": "莲池区",
            "value": "130606"
        }, {
            "label": "满城区",
            "value": "130607"
        }, {
            "label": "清苑区",
            "value": "130608"
        }, {
            "label": "徐水区",
            "value": "130609"
        }, {
            "label": "涞水县",
            "value": "130623"
        }, {
            "label": "阜平县",
            "value": "130624"
        }, {
            "label": "定兴县",
            "value": "130626"
        }, {
            "label": "唐县",
            "value": "130627"
        }, {
            "label": "高阳县",
            "value": "130628"
        }, {
            "label": "容城县",
            "value": "130629"
        }, {
            "label": "涞源县",
            "value": "130630"
        }, {
            "label": "望都县",
            "value": "130631"
        }, {
            "label": "安新县",
            "value": "130632"
        }, {
            "label": "易县",
            "value": "130633"
        }, {
            "label": "曲阳县",
            "value": "130634"
        }, {
            "label": "蠡县",
            "value": "130635"
        }, {
            "label": "顺平县",
            "value": "130636"
        }, {
            "label": "博野县",
            "value": "130637"
        }, {
            "label": "雄县",
            "value": "130638"
        }, {
            "label": "涿州市",
            "value": "130681"
        }, {
            "label": "安国市",
            "value": "130683"
        }, {
            "label": "高碑店市",
            "value": "130684"
        }],
        [{
            "label": "市辖区",
            "value": "130701"
        }, {
            "label": "桥东区",
            "value": "130702"
        }, {
            "label": "桥西区",
            "value": "130703"
        }, {
            "label": "宣化区",
            "value": "130705"
        }, {
            "label": "下花园区",
            "value": "130706"
        }, {
            "label": "万全区",
            "value": "130708"
        }, {
            "label": "崇礼区",
            "value": "130709"
        }, {
            "label": "张北县",
            "value": "130722"
        }, {
            "label": "康保县",
            "value": "130723"
        }, {
            "label": "沽源县",
            "value": "130724"
        }, {
            "label": "尚义县",
            "value": "130725"
        }, {
            "label": "蔚县",
            "value": "130726"
        }, {
            "label": "阳原县",
            "value": "130727"
        }, {
            "label": "怀安县",
            "value": "130728"
        }, {
            "label": "怀来县",
            "value": "130730"
        }, {
            "label": "涿鹿县",
            "value": "130731"
        }, {
            "label": "赤城县",
            "value": "130732"
        }],
        [{
            "label": "市辖区",
            "value": "130801"
        }, {
            "label": "双桥区",
            "value": "130802"
        }, {
            "label": "双滦区",
            "value": "130803"
        }, {
            "label": "鹰手营子矿区",
            "value": "130804"
        }, {
            "label": "承德县",
            "value": "130821"
        }, {
            "label": "兴隆县",
            "value": "130822"
        }, {
            "label": "平泉县",
            "value": "130823"
        }, {
            "label": "滦平县",
            "value": "130824"
        }, {
            "label": "隆化县",
            "value": "130825"
        }, {
            "label": "丰宁满族自治县",
            "value": "130826"
        }, {
            "label": "宽城满族自治县",
            "value": "130827"
        }, {
            "label": "围场满族蒙古族自治县",
            "value": "130828"
        }],
        [{
            "label": "市辖区",
            "value": "130901"
        }, {
            "label": "新华区",
            "value": "130902"
        }, {
            "label": "运河区",
            "value": "130903"
        }, {
            "label": "沧县",
            "value": "130921"
        }, {
            "label": "青县",
            "value": "130922"
        }, {
            "label": "东光县",
            "value": "130923"
        }, {
            "label": "海兴县",
            "value": "130924"
        }, {
            "label": "盐山县",
            "value": "130925"
        }, {
            "label": "肃宁县",
            "value": "130926"
        }, {
            "label": "南皮县",
            "value": "130927"
        }, {
            "label": "吴桥县",
            "value": "130928"
        }, {
            "label": "献县",
            "value": "130929"
        }, {
            "label": "孟村回族自治县",
            "value": "130930"
        }, {
            "label": "泊头市",
            "value": "130981"
        }, {
            "label": "任丘市",
            "value": "130982"
        }, {
            "label": "黄骅市",
            "value": "130983"
        }, {
            "label": "河间市",
            "value": "130984"
        }],
        [{
            "label": "市辖区",
            "value": "131001"
        }, {
            "label": "安次区",
            "value": "131002"
        }, {
            "label": "广阳区",
            "value": "131003"
        }, {
            "label": "固安县",
            "value": "131022"
        }, {
            "label": "永清县",
            "value": "131023"
        }, {
            "label": "香河县",
            "value": "131024"
        }, {
            "label": "大城县",
            "value": "131025"
        }, {
            "label": "文安县",
            "value": "131026"
        }, {
            "label": "大厂回族自治县",
            "value": "131028"
        }, {
            "label": "霸州市",
            "value": "131081"
        }, {
            "label": "三河市",
            "value": "131082"
        }],
        [{
            "label": "市辖区",
            "value": "131101"
        }, {
            "label": "桃城区",
            "value": "131102"
        }, {
            "label": "冀州区",
            "value": "131103"
        }, {
            "label": "枣强县",
            "value": "131121"
        }, {
            "label": "武邑县",
            "value": "131122"
        }, {
            "label": "武强县",
            "value": "131123"
        }, {
            "label": "饶阳县",
            "value": "131124"
        }, {
            "label": "安平县",
            "value": "131125"
        }, {
            "label": "故城县",
            "value": "131126"
        }, {
            "label": "景县",
            "value": "131127"
        }, {
            "label": "阜城县",
            "value": "131128"
        }, {
            "label": "深州市",
            "value": "131182"
        }],
        [{
            "label": "市辖区",
            "value": "139001"
        }, {
            "label": "辛集市",
            "value": "139002"
        }]
    ],
    [
        [{
            "label": "市辖区",
            "value": "140101"
        }, {
            "label": "小店区",
            "value": "140105"
        }, {
            "label": "迎泽区",
            "value": "140106"
        }, {
            "label": "杏花岭区",
            "value": "140107"
        }, {
            "label": "尖草坪区",
            "value": "140108"
        }, {
            "label": "万柏林区",
            "value": "140109"
        }, {
            "label": "晋源区",
            "value": "140110"
        }, {
            "label": "清徐县",
            "value": "140121"
        }, {
            "label": "阳曲县",
            "value": "140122"
        }, {
            "label": "娄烦县",
            "value": "140123"
        }, {
            "label": "古交市",
            "value": "140181"
        }],
        [{
            "label": "市辖区",
            "value": "140201"
        }, {
            "label": "城区",
            "value": "140202"
        }, {
            "label": "矿区",
            "value": "140203"
        }, {
            "label": "南郊区",
            "value": "140211"
        }, {
            "label": "新荣区",
            "value": "140212"
        }, {
            "label": "阳高县",
            "value": "140221"
        }, {
            "label": "天镇县",
            "value": "140222"
        }, {
            "label": "广灵县",
            "value": "140223"
        }, {
            "label": "灵丘县",
            "value": "140224"
        }, {
            "label": "浑源县",
            "value": "140225"
        }, {
            "label": "左云县",
            "value": "140226"
        }, {
            "label": "大同县",
            "value": "140227"
        }],
        [{
            "label": "市辖区",
            "value": "140301"
        }, {
            "label": "城区",
            "value": "140302"
        }, {
            "label": "矿区",
            "value": "140303"
        }, {
            "label": "郊区",
            "value": "140311"
        }, {
            "label": "平定县",
            "value": "140321"
        }, {
            "label": "盂县",
            "value": "140322"
        }],
        [{
            "label": "市辖区",
            "value": "140401"
        }, {
            "label": "城区",
            "value": "140402"
        }, {
            "label": "郊区",
            "value": "140411"
        }, {
            "label": "长治县",
            "value": "140421"
        }, {
            "label": "襄垣县",
            "value": "140423"
        }, {
            "label": "屯留县",
            "value": "140424"
        }, {
            "label": "平顺县",
            "value": "140425"
        }, {
            "label": "黎城县",
            "value": "140426"
        }, {
            "label": "壶关县",
            "value": "140427"
        }, {
            "label": "长子县",
            "value": "140428"
        }, {
            "label": "武乡县",
            "value": "140429"
        }, {
            "label": "沁县",
            "value": "140430"
        }, {
            "label": "沁源县",
            "value": "140431"
        }, {
            "label": "潞城市",
            "value": "140481"
        }],
        [{
            "label": "市辖区",
            "value": "140501"
        }, {
            "label": "城区",
            "value": "140502"
        }, {
            "label": "沁水县",
            "value": "140521"
        }, {
            "label": "阳城县",
            "value": "140522"
        }, {
            "label": "陵川县",
            "value": "140524"
        }, {
            "label": "泽州县",
            "value": "140525"
        }, {
            "label": "高平市",
            "value": "140581"
        }],
        [{
            "label": "市辖区",
            "value": "140601"
        }, {
            "label": "朔城区",
            "value": "140602"
        }, {
            "label": "平鲁区",
            "value": "140603"
        }, {
            "label": "山阴县",
            "value": "140621"
        }, {
            "label": "应县",
            "value": "140622"
        }, {
            "label": "右玉县",
            "value": "140623"
        }, {
            "label": "怀仁县",
            "value": "140624"
        }],
        [{
            "label": "市辖区",
            "value": "140701"
        }, {
            "label": "榆次区",
            "value": "140702"
        }, {
            "label": "榆社县",
            "value": "140721"
        }, {
            "label": "左权县",
            "value": "140722"
        }, {
            "label": "和顺县",
            "value": "140723"
        }, {
            "label": "昔阳县",
            "value": "140724"
        }, {
            "label": "寿阳县",
            "value": "140725"
        }, {
            "label": "太谷县",
            "value": "140726"
        }, {
            "label": "祁县",
            "value": "140727"
        }, {
            "label": "平遥县",
            "value": "140728"
        }, {
            "label": "灵石县",
            "value": "140729"
        }, {
            "label": "介休市",
            "value": "140781"
        }],
        [{
            "label": "市辖区",
            "value": "140801"
        }, {
            "label": "盐湖区",
            "value": "140802"
        }, {
            "label": "临猗县",
            "value": "140821"
        }, {
            "label": "万荣县",
            "value": "140822"
        }, {
            "label": "闻喜县",
            "value": "140823"
        }, {
            "label": "稷山县",
            "value": "140824"
        }, {
            "label": "新绛县",
            "value": "140825"
        }, {
            "label": "绛县",
            "value": "140826"
        }, {
            "label": "垣曲县",
            "value": "140827"
        }, {
            "label": "夏县",
            "value": "140828"
        }, {
            "label": "平陆县",
            "value": "140829"
        }, {
            "label": "芮城县",
            "value": "140830"
        }, {
            "label": "永济市",
            "value": "140881"
        }, {
            "label": "河津市",
            "value": "140882"
        }],
        [{
            "label": "市辖区",
            "value": "140901"
        }, {
            "label": "忻府区",
            "value": "140902"
        }, {
            "label": "定襄县",
            "value": "140921"
        }, {
            "label": "五台县",
            "value": "140922"
        }, {
            "label": "代县",
            "value": "140923"
        }, {
            "label": "繁峙县",
            "value": "140924"
        }, {
            "label": "宁武县",
            "value": "140925"
        }, {
            "label": "静乐县",
            "value": "140926"
        }, {
            "label": "神池县",
            "value": "140927"
        }, {
            "label": "五寨县",
            "value": "140928"
        }, {
            "label": "岢岚县",
            "value": "140929"
        }, {
            "label": "河曲县",
            "value": "140930"
        }, {
            "label": "保德县",
            "value": "140931"
        }, {
            "label": "偏关县",
            "value": "140932"
        }, {
            "label": "原平市",
            "value": "140981"
        }],
        [{
            "label": "市辖区",
            "value": "141001"
        }, {
            "label": "尧都区",
            "value": "141002"
        }, {
            "label": "曲沃县",
            "value": "141021"
        }, {
            "label": "翼城县",
            "value": "141022"
        }, {
            "label": "襄汾县",
            "value": "141023"
        }, {
            "label": "洪洞县",
            "value": "141024"
        }, {
            "label": "古县",
            "value": "141025"
        }, {
            "label": "安泽县",
            "value": "141026"
        }, {
            "label": "浮山县",
            "value": "141027"
        }, {
            "label": "吉县",
            "value": "141028"
        }, {
            "label": "乡宁县",
            "value": "141029"
        }, {
            "label": "大宁县",
            "value": "141030"
        }, {
            "label": "隰县",
            "value": "141031"
        }, {
            "label": "永和县",
            "value": "141032"
        }, {
            "label": "蒲县",
            "value": "141033"
        }, {
            "label": "汾西县",
            "value": "141034"
        }, {
            "label": "侯马市",
            "value": "141081"
        }, {
            "label": "霍州市",
            "value": "141082"
        }],
        [{
            "label": "市辖区",
            "value": "141101"
        }, {
            "label": "离石区",
            "value": "141102"
        }, {
            "label": "文水县",
            "value": "141121"
        }, {
            "label": "交城县",
            "value": "141122"
        }, {
            "label": "兴县",
            "value": "141123"
        }, {
            "label": "临县",
            "value": "141124"
        }, {
            "label": "柳林县",
            "value": "141125"
        }, {
            "label": "石楼县",
            "value": "141126"
        }, {
            "label": "岚县",
            "value": "141127"
        }, {
            "label": "方山县",
            "value": "141128"
        }, {
            "label": "中阳县",
            "value": "141129"
        }, {
            "label": "交口县",
            "value": "141130"
        }, {
            "label": "孝义市",
            "value": "141181"
        }, {
            "label": "汾阳市",
            "value": "141182"
        }]
    ],
    [
        [{
            "label": "市辖区",
            "value": "150101"
        }, {
            "label": "新城区",
            "value": "150102"
        }, {
            "label": "回民区",
            "value": "150103"
        }, {
            "label": "玉泉区",
            "value": "150104"
        }, {
            "label": "赛罕区",
            "value": "150105"
        }, {
            "label": "土默特左旗",
            "value": "150121"
        }, {
            "label": "托克托县",
            "value": "150122"
        }, {
            "label": "和林格尔县",
            "value": "150123"
        }, {
            "label": "清水河县",
            "value": "150124"
        }, {
            "label": "武川县",
            "value": "150125"
        }],
        [{
            "label": "市辖区",
            "value": "150201"
        }, {
            "label": "东河区",
            "value": "150202"
        }, {
            "label": "昆都仑区",
            "value": "150203"
        }, {
            "label": "青山区",
            "value": "150204"
        }, {
            "label": "石拐区",
            "value": "150205"
        }, {
            "label": "白云鄂博矿区",
            "value": "150206"
        }, {
            "label": "九原区",
            "value": "150207"
        }, {
            "label": "土默特右旗",
            "value": "150221"
        }, {
            "label": "固阳县",
            "value": "150222"
        }, {
            "label": "达尔罕茂明安联合旗",
            "value": "150223"
        }],
        [{
            "label": "市辖区",
            "value": "150301"
        }, {
            "label": "海勃湾区",
            "value": "150302"
        }, {
            "label": "海南区",
            "value": "150303"
        }, {
            "label": "乌达区",
            "value": "150304"
        }],
        [{
            "label": "市辖区",
            "value": "150401"
        }, {
            "label": "红山区",
            "value": "150402"
        }, {
            "label": "元宝山区",
            "value": "150403"
        }, {
            "label": "松山区",
            "value": "150404"
        }, {
            "label": "阿鲁科尔沁旗",
            "value": "150421"
        }, {
            "label": "巴林左旗",
            "value": "150422"
        }, {
            "label": "巴林右旗",
            "value": "150423"
        }, {
            "label": "林西县",
            "value": "150424"
        }, {
            "label": "克什克腾旗",
            "value": "150425"
        }, {
            "label": "翁牛特旗",
            "value": "150426"
        }, {
            "label": "喀喇沁旗",
            "value": "150428"
        }, {
            "label": "宁城县",
            "value": "150429"
        }, {
            "label": "敖汉旗",
            "value": "150430"
        }],
        [{
            "label": "市辖区",
            "value": "150501"
        }, {
            "label": "科尔沁区",
            "value": "150502"
        }, {
            "label": "科尔沁左翼中旗",
            "value": "150521"
        }, {
            "label": "科尔沁左翼后旗",
            "value": "150522"
        }, {
            "label": "开鲁县",
            "value": "150523"
        }, {
            "label": "库伦旗",
            "value": "150524"
        }, {
            "label": "奈曼旗",
            "value": "150525"
        }, {
            "label": "扎鲁特旗",
            "value": "150526"
        }, {
            "label": "霍林郭勒市",
            "value": "150581"
        }],
        [{
            "label": "市辖区",
            "value": "150601"
        }, {
            "label": "东胜区",
            "value": "150602"
        }, {
            "label": "康巴什区",
            "value": "150603"
        }, {
            "label": "达拉特旗",
            "value": "150621"
        }, {
            "label": "准格尔旗",
            "value": "150622"
        }, {
            "label": "鄂托克前旗",
            "value": "150623"
        }, {
            "label": "鄂托克旗",
            "value": "150624"
        }, {
            "label": "杭锦旗",
            "value": "150625"
        }, {
            "label": "乌审旗",
            "value": "150626"
        }, {
            "label": "伊金霍洛旗",
            "value": "150627"
        }],
        [{
            "label": "市辖区",
            "value": "150701"
        }, {
            "label": "海拉尔区",
            "value": "150702"
        }, {
            "label": "扎赉诺尔区",
            "value": "150703"
        }, {
            "label": "阿荣旗",
            "value": "150721"
        }, {
            "label": "莫力达瓦达斡尔族自治旗",
            "value": "150722"
        }, {
            "label": "鄂伦春自治旗",
            "value": "150723"
        }, {
            "label": "鄂温克族自治旗",
            "value": "150724"
        }, {
            "label": "陈巴尔虎旗",
            "value": "150725"
        }, {
            "label": "新巴尔虎左旗",
            "value": "150726"
        }, {
            "label": "新巴尔虎右旗",
            "value": "150727"
        }, {
            "label": "满洲里市",
            "value": "150781"
        }, {
            "label": "牙克石市",
            "value": "150782"
        }, {
            "label": "扎兰屯市",
            "value": "150783"
        }, {
            "label": "额尔古纳市",
            "value": "150784"
        }, {
            "label": "根河市",
            "value": "150785"
        }],
        [{
            "label": "市辖区",
            "value": "150801"
        }, {
            "label": "临河区",
            "value": "150802"
        }, {
            "label": "五原县",
            "value": "150821"
        }, {
            "label": "磴口县",
            "value": "150822"
        }, {
            "label": "乌拉特前旗",
            "value": "150823"
        }, {
            "label": "乌拉特中旗",
            "value": "150824"
        }, {
            "label": "乌拉特后旗",
            "value": "150825"
        }, {
            "label": "杭锦后旗",
            "value": "150826"
        }],
        [{
            "label": "市辖区",
            "value": "150901"
        }, {
            "label": "集宁区",
            "value": "150902"
        }, {
            "label": "卓资县",
            "value": "150921"
        }, {
            "label": "化德县",
            "value": "150922"
        }, {
            "label": "商都县",
            "value": "150923"
        }, {
            "label": "兴和县",
            "value": "150924"
        }, {
            "label": "凉城县",
            "value": "150925"
        }, {
            "label": "察哈尔右翼前旗",
            "value": "150926"
        }, {
            "label": "察哈尔右翼中旗",
            "value": "150927"
        }, {
            "label": "察哈尔右翼后旗",
            "value": "150928"
        }, {
            "label": "四子王旗",
            "value": "150929"
        }, {
            "label": "丰镇市",
            "value": "150981"
        }],
        [{
            "label": "市辖区",
            "value": "152201"
        }, {
            "label": "阿尔山市",
            "value": "152202"
        }, {
            "label": "科尔沁右翼前旗",
            "value": "152221"
        }, {
            "label": "科尔沁右翼中旗",
            "value": "152222"
        }, {
            "label": "扎赉特旗",
            "value": "152223"
        }, {
            "label": "突泉县",
            "value": "152224"
        }],
        [{
            "label": "市辖区",
            "value": "152501"
        }, {
            "label": "锡林浩特市",
            "value": "152502"
        }, {
            "label": "阿巴嘎旗",
            "value": "152522"
        }, {
            "label": "苏尼特左旗",
            "value": "152523"
        }, {
            "label": "苏尼特右旗",
            "value": "152524"
        }, {
            "label": "东乌珠穆沁旗",
            "value": "152525"
        }, {
            "label": "西乌珠穆沁旗",
            "value": "152526"
        }, {
            "label": "太仆寺旗",
            "value": "152527"
        }, {
            "label": "镶黄旗",
            "value": "152528"
        }, {
            "label": "正镶白旗",
            "value": "152529"
        }, {
            "label": "正蓝旗",
            "value": "152530"
        }, {
            "label": "多伦县",
            "value": "152531"
        }],
        [{
            "label": "阿拉善左旗",
            "value": "152921"
        }, {
            "label": "阿拉善右旗",
            "value": "152922"
        }, {
            "label": "额济纳旗",
            "value": "152923"
        }]
    ],
    [
        [{
            "label": "市辖区",
            "value": "210101"
        }, {
            "label": "和平区",
            "value": "210102"
        }, {
            "label": "沈河区",
            "value": "210103"
        }, {
            "label": "大东区",
            "value": "210104"
        }, {
            "label": "皇姑区",
            "value": "210105"
        }, {
            "label": "铁西区",
            "value": "210106"
        }, {
            "label": "苏家屯区",
            "value": "210111"
        }, {
            "label": "浑南区",
            "value": "210112"
        }, {
            "label": "沈北新区",
            "value": "210113"
        }, {
            "label": "于洪区",
            "value": "210114"
        }, {
            "label": "辽中区",
            "value": "210115"
        }, {
            "label": "康平县",
            "value": "210123"
        }, {
            "label": "法库县",
            "value": "210124"
        }, {
            "label": "新民市",
            "value": "210181"
        }],
        [{
            "label": "市辖区",
            "value": "210201"
        }, {
            "label": "中山区",
            "value": "210202"
        }, {
            "label": "西岗区",
            "value": "210203"
        }, {
            "label": "沙河口区",
            "value": "210204"
        }, {
            "label": "甘井子区",
            "value": "210211"
        }, {
            "label": "旅顺口区",
            "value": "210212"
        }, {
            "label": "金州区",
            "value": "210213"
        }, {
            "label": "普兰店区",
            "value": "210214"
        }, {
            "label": "长海县",
            "value": "210224"
        }, {
            "label": "瓦房店市",
            "value": "210281"
        }, {
            "label": "庄河市",
            "value": "210283"
        }],
        [{
            "label": "市辖区",
            "value": "210301"
        }, {
            "label": "铁东区",
            "value": "210302"
        }, {
            "label": "铁西区",
            "value": "210303"
        }, {
            "label": "立山区",
            "value": "210304"
        }, {
            "label": "千山区",
            "value": "210311"
        }, {
            "label": "台安县",
            "value": "210321"
        }, {
            "label": "岫岩满族自治县",
            "value": "210323"
        }, {
            "label": "海城市",
            "value": "210381"
        }],
        [{
            "label": "市辖区",
            "value": "210401"
        }, {
            "label": "新抚区",
            "value": "210402"
        }, {
            "label": "东洲区",
            "value": "210403"
        }, {
            "label": "望花区",
            "value": "210404"
        }, {
            "label": "顺城区",
            "value": "210411"
        }, {
            "label": "抚顺县",
            "value": "210421"
        }, {
            "label": "新宾满族自治县",
            "value": "210422"
        }, {
            "label": "清原满族自治县",
            "value": "210423"
        }],
        [{
            "label": "市辖区",
            "value": "210501"
        }, {
            "label": "平山区",
            "value": "210502"
        }, {
            "label": "溪湖区",
            "value": "210503"
        }, {
            "label": "明山区",
            "value": "210504"
        }, {
            "label": "南芬区",
            "value": "210505"
        }, {
            "label": "本溪满族自治县",
            "value": "210521"
        }, {
            "label": "桓仁满族自治县",
            "value": "210522"
        }],
        [{
            "label": "市辖区",
            "value": "210601"
        }, {
            "label": "元宝区",
            "value": "210602"
        }, {
            "label": "振兴区",
            "value": "210603"
        }, {
            "label": "振安区",
            "value": "210604"
        }, {
            "label": "宽甸满族自治县",
            "value": "210624"
        }, {
            "label": "东港市",
            "value": "210681"
        }, {
            "label": "凤城市",
            "value": "210682"
        }],
        [{
            "label": "市辖区",
            "value": "210701"
        }, {
            "label": "古塔区",
            "value": "210702"
        }, {
            "label": "凌河区",
            "value": "210703"
        }, {
            "label": "太和区",
            "value": "210711"
        }, {
            "label": "黑山县",
            "value": "210726"
        }, {
            "label": "义县",
            "value": "210727"
        }, {
            "label": "凌海市",
            "value": "210781"
        }, {
            "label": "北镇市",
            "value": "210782"
        }],
        [{
            "label": "市辖区",
            "value": "210801"
        }, {
            "label": "站前区",
            "value": "210802"
        }, {
            "label": "西市区",
            "value": "210803"
        }, {
            "label": "鲅鱼圈区",
            "value": "210804"
        }, {
            "label": "老边区",
            "value": "210811"
        }, {
            "label": "盖州市",
            "value": "210881"
        }, {
            "label": "大石桥市",
            "value": "210882"
        }],
        [{
            "label": "市辖区",
            "value": "210901"
        }, {
            "label": "海州区",
            "value": "210902"
        }, {
            "label": "新邱区",
            "value": "210903"
        }, {
            "label": "太平区",
            "value": "210904"
        }, {
            "label": "清河门区",
            "value": "210905"
        }, {
            "label": "细河区",
            "value": "210911"
        }, {
            "label": "阜新蒙古族自治县",
            "value": "210921"
        }, {
            "label": "彰武县",
            "value": "210922"
        }],
        [{
            "label": "市辖区",
            "value": "211001"
        }, {
            "label": "白塔区",
            "value": "211002"
        }, {
            "label": "文圣区",
            "value": "211003"
        }, {
            "label": "宏伟区",
            "value": "211004"
        }, {
            "label": "弓长岭区",
            "value": "211005"
        }, {
            "label": "太子河区",
            "value": "211011"
        }, {
            "label": "辽阳县",
            "value": "211021"
        }, {
            "label": "灯塔市",
            "value": "211081"
        }],
        [{
            "label": "市辖区",
            "value": "211101"
        }, {
            "label": "双台子区",
            "value": "211102"
        }, {
            "label": "兴隆台区",
            "value": "211103"
        }, {
            "label": "大洼区",
            "value": "211104"
        }, {
            "label": "盘山县",
            "value": "211122"
        }],
        [{
            "label": "市辖区",
            "value": "211201"
        }, {
            "label": "银州区",
            "value": "211202"
        }, {
            "label": "清河区",
            "value": "211204"
        }, {
            "label": "铁岭县",
            "value": "211221"
        }, {
            "label": "西丰县",
            "value": "211223"
        }, {
            "label": "昌图县",
            "value": "211224"
        }, {
            "label": "调兵山市",
            "value": "211281"
        }, {
            "label": "开原市",
            "value": "211282"
        }],
        [{
            "label": "市辖区",
            "value": "211301"
        }, {
            "label": "双塔区",
            "value": "211302"
        }, {
            "label": "龙城区",
            "value": "211303"
        }, {
            "label": "朝阳县",
            "value": "211321"
        }, {
            "label": "建平县",
            "value": "211322"
        }, {
            "label": "喀喇沁左翼蒙古族自治县",
            "value": "211324"
        }, {
            "label": "北票市",
            "value": "211381"
        }, {
            "label": "凌源市",
            "value": "211382"
        }],
        [{
            "label": "市辖区",
            "value": "211401"
        }, {
            "label": "连山区",
            "value": "211402"
        }, {
            "label": "龙港区",
            "value": "211403"
        }, {
            "label": "南票区",
            "value": "211404"
        }, {
            "label": "绥中县",
            "value": "211421"
        }, {
            "label": "建昌县",
            "value": "211422"
        }, {
            "label": "兴城市",
            "value": "211481"
        }]
    ],
    [
        [{
            "label": "市辖区",
            "value": "220101"
        }, {
            "label": "南关区",
            "value": "220102"
        }, {
            "label": "宽城区",
            "value": "220103"
        }, {
            "label": "朝阳区",
            "value": "220104"
        }, {
            "label": "二道区",
            "value": "220105"
        }, {
            "label": "绿园区",
            "value": "220106"
        }, {
            "label": "双阳区",
            "value": "220112"
        }, {
            "label": "九台区",
            "value": "220113"
        }, {
            "label": "农安县",
            "value": "220122"
        }, {
            "label": "榆树市",
            "value": "220182"
        }, {
            "label": "德惠市",
            "value": "220183"
        }],
        [{
            "label": "市辖区",
            "value": "220201"
        }, {
            "label": "昌邑区",
            "value": "220202"
        }, {
            "label": "龙潭区",
            "value": "220203"
        }, {
            "label": "船营区",
            "value": "220204"
        }, {
            "label": "丰满区",
            "value": "220211"
        }, {
            "label": "永吉县",
            "value": "220221"
        }, {
            "label": "蛟河市",
            "value": "220281"
        }, {
            "label": "桦甸市",
            "value": "220282"
        }, {
            "label": "舒兰市",
            "value": "220283"
        }, {
            "label": "磐石市",
            "value": "220284"
        }],
        [{
            "label": "市辖区",
            "value": "220301"
        }, {
            "label": "铁西区",
            "value": "220302"
        }, {
            "label": "铁东区",
            "value": "220303"
        }, {
            "label": "梨树县",
            "value": "220322"
        }, {
            "label": "伊通满族自治县",
            "value": "220323"
        }, {
            "label": "公主岭市",
            "value": "220381"
        }, {
            "label": "双辽市",
            "value": "220382"
        }],
        [{
            "label": "市辖区",
            "value": "220401"
        }, {
            "label": "龙山区",
            "value": "220402"
        }, {
            "label": "西安区",
            "value": "220403"
        }, {
            "label": "东丰县",
            "value": "220421"
        }, {
            "label": "东辽县",
            "value": "220422"
        }],
        [{
            "label": "市辖区",
            "value": "220501"
        }, {
            "label": "东昌区",
            "value": "220502"
        }, {
            "label": "二道江区",
            "value": "220503"
        }, {
            "label": "通化县",
            "value": "220521"
        }, {
            "label": "辉南县",
            "value": "220523"
        }, {
            "label": "柳河县",
            "value": "220524"
        }, {
            "label": "梅河口市",
            "value": "220581"
        }, {
            "label": "集安市",
            "value": "220582"
        }],
        [{
            "label": "市辖区",
            "value": "220601"
        }, {
            "label": "浑江区",
            "value": "220602"
        }, {
            "label": "江源区",
            "value": "220605"
        }, {
            "label": "抚松县",
            "value": "220621"
        }, {
            "label": "靖宇县",
            "value": "220622"
        }, {
            "label": "长白朝鲜族自治县",
            "value": "220623"
        }, {
            "label": "临江市",
            "value": "220681"
        }],
        [{
            "label": "市辖区",
            "value": "220701"
        }, {
            "label": "宁江区",
            "value": "220702"
        }, {
            "label": "前郭尔罗斯蒙古族自治县",
            "value": "220721"
        }, {
            "label": "长岭县",
            "value": "220722"
        }, {
            "label": "乾安县",
            "value": "220723"
        }, {
            "label": "扶余市",
            "value": "220781"
        }],
        [{
            "label": "市辖区",
            "value": "220801"
        }, {
            "label": "洮北区",
            "value": "220802"
        }, {
            "label": "镇赉县",
            "value": "220821"
        }, {
            "label": "通榆县",
            "value": "220822"
        }, {
            "label": "洮南市",
            "value": "220881"
        }, {
            "label": "大安市",
            "value": "220882"
        }],
        [{
            "label": "市辖区",
            "value": "222401"
        }, {
            "label": "图们市",
            "value": "222402"
        }, {
            "label": "敦化市",
            "value": "222403"
        }, {
            "label": "珲春市",
            "value": "222404"
        }, {
            "label": "龙井市",
            "value": "222405"
        }, {
            "label": "和龙市",
            "value": "222406"
        }, {
            "label": "汪清县",
            "value": "222424"
        }, {
            "label": "安图县",
            "value": "222426"
        }]
    ],
    [
        [{
            "label": "市辖区",
            "value": "230101"
        }, {
            "label": "道里区",
            "value": "230102"
        }, {
            "label": "南岗区",
            "value": "230103"
        }, {
            "label": "道外区",
            "value": "230104"
        }, {
            "label": "平房区",
            "value": "230108"
        }, {
            "label": "松北区",
            "value": "230109"
        }, {
            "label": "香坊区",
            "value": "230110"
        }, {
            "label": "呼兰区",
            "value": "230111"
        }, {
            "label": "阿城区",
            "value": "230112"
        }, {
            "label": "双城区",
            "value": "230113"
        }, {
            "label": "依兰县",
            "value": "230123"
        }, {
            "label": "方正县",
            "value": "230124"
        }, {
            "label": "宾县",
            "value": "230125"
        }, {
            "label": "巴彦县",
            "value": "230126"
        }, {
            "label": "木兰县",
            "value": "230127"
        }, {
            "label": "通河县",
            "value": "230128"
        }, {
            "label": "延寿县",
            "value": "230129"
        }, {
            "label": "尚志市",
            "value": "230183"
        }, {
            "label": "五常市",
            "value": "230184"
        }],
        [{
            "label": "市辖区",
            "value": "230201"
        }, {
            "label": "龙沙区",
            "value": "230202"
        }, {
            "label": "建华区",
            "value": "230203"
        }, {
            "label": "铁锋区",
            "value": "230204"
        }, {
            "label": "昂昂溪区",
            "value": "230205"
        }, {
            "label": "富拉尔基区",
            "value": "230206"
        }, {
            "label": "碾子山区",
            "value": "230207"
        }, {
            "label": "梅里斯达斡尔族区",
            "value": "230208"
        }, {
            "label": "龙江县",
            "value": "230221"
        }, {
            "label": "依安县",
            "value": "230223"
        }, {
            "label": "泰来县",
            "value": "230224"
        }, {
            "label": "甘南县",
            "value": "230225"
        }, {
            "label": "富裕县",
            "value": "230227"
        }, {
            "label": "克山县",
            "value": "230229"
        }, {
            "label": "克东县",
            "value": "230230"
        }, {
            "label": "拜泉县",
            "value": "230231"
        }, {
            "label": "讷河市",
            "value": "230281"
        }],
        [{
            "label": "市辖区",
            "value": "230301"
        }, {
            "label": "鸡冠区",
            "value": "230302"
        }, {
            "label": "恒山区",
            "value": "230303"
        }, {
            "label": "滴道区",
            "value": "230304"
        }, {
            "label": "梨树区",
            "value": "230305"
        }, {
            "label": "城子河区",
            "value": "230306"
        }, {
            "label": "麻山区",
            "value": "230307"
        }, {
            "label": "鸡东县",
            "value": "230321"
        }, {
            "label": "虎林市",
            "value": "230381"
        }, {
            "label": "密山市",
            "value": "230382"
        }],
        [{
            "label": "市辖区",
            "value": "230401"
        }, {
            "label": "向阳区",
            "value": "230402"
        }, {
            "label": "工农区",
            "value": "230403"
        }, {
            "label": "南山区",
            "value": "230404"
        }, {
            "label": "兴安区",
            "value": "230405"
        }, {
            "label": "东山区",
            "value": "230406"
        }, {
            "label": "兴山区",
            "value": "230407"
        }, {
            "label": "萝北县",
            "value": "230421"
        }, {
            "label": "绥滨县",
            "value": "230422"
        }],
        [{
            "label": "市辖区",
            "value": "230501"
        }, {
            "label": "尖山区",
            "value": "230502"
        }, {
            "label": "岭东区",
            "value": "230503"
        }, {
            "label": "四方台区",
            "value": "230505"
        }, {
            "label": "宝山区",
            "value": "230506"
        }, {
            "label": "集贤县",
            "value": "230521"
        }, {
            "label": "友谊县",
            "value": "230522"
        }, {
            "label": "宝清县",
            "value": "230523"
        }, {
            "label": "饶河县",
            "value": "230524"
        }],
        [{
            "label": "市辖区",
            "value": "230601"
        }, {
            "label": "萨尔图区",
            "value": "230602"
        }, {
            "label": "龙凤区",
            "value": "230603"
        }, {
            "label": "让胡路区",
            "value": "230604"
        }, {
            "label": "红岗区",
            "value": "230605"
        }, {
            "label": "大同区",
            "value": "230606"
        }, {
            "label": "肇州县",
            "value": "230621"
        }, {
            "label": "肇源县",
            "value": "230622"
        }, {
            "label": "林甸县",
            "value": "230623"
        }, {
            "label": "杜尔伯特蒙古族自治县",
            "value": "230624"
        }],
        [{
            "label": "市辖区",
            "value": "230701"
        }, {
            "label": "伊春区",
            "value": "230702"
        }, {
            "label": "南岔区",
            "value": "230703"
        }, {
            "label": "友好区",
            "value": "230704"
        }, {
            "label": "西林区",
            "value": "230705"
        }, {
            "label": "翠峦区",
            "value": "230706"
        }, {
            "label": "新青区",
            "value": "230707"
        }, {
            "label": "美溪区",
            "value": "230708"
        }, {
            "label": "金山屯区",
            "value": "230709"
        }, {
            "label": "五营区",
            "value": "230710"
        }, {
            "label": "乌马河区",
            "value": "230711"
        }, {
            "label": "汤旺河区",
            "value": "230712"
        }, {
            "label": "带岭区",
            "value": "230713"
        }, {
            "label": "乌伊岭区",
            "value": "230714"
        }, {
            "label": "红星区",
            "value": "230715"
        }, {
            "label": "上甘岭区",
            "value": "230716"
        }, {
            "label": "嘉荫县",
            "value": "230722"
        }, {
            "label": "铁力市",
            "value": "230781"
        }],
        [{
            "label": "市辖区",
            "value": "230801"
        }, {
            "label": "向阳区",
            "value": "230803"
        }, {
            "label": "前进区",
            "value": "230804"
        }, {
            "label": "东风区",
            "value": "230805"
        }, {
            "label": "郊区",
            "value": "230811"
        }, {
            "label": "桦南县",
            "value": "230822"
        }, {
            "label": "桦川县",
            "value": "230826"
        }, {
            "label": "汤原县",
            "value": "230828"
        }, {
            "label": "同江市",
            "value": "230881"
        }, {
            "label": "富锦市",
            "value": "230882"
        }, {
            "label": "抚远市",
            "value": "230883"
        }],
        [{
            "label": "市辖区",
            "value": "230901"
        }, {
            "label": "新兴区",
            "value": "230902"
        }, {
            "label": "桃山区",
            "value": "230903"
        }, {
            "label": "茄子河区",
            "value": "230904"
        }, {
            "label": "勃利县",
            "value": "230921"
        }],
        [{
            "label": "市辖区",
            "value": "231001"
        }, {
            "label": "东安区",
            "value": "231002"
        }, {
            "label": "阳明区",
            "value": "231003"
        }, {
            "label": "爱民区",
            "value": "231004"
        }, {
            "label": "西安区",
            "value": "231005"
        }, {
            "label": "林口县",
            "value": "231025"
        }, {
            "label": "绥芬河市",
            "value": "231081"
        }, {
            "label": "海林市",
            "value": "231083"
        }, {
            "label": "宁安市",
            "value": "231084"
        }, {
            "label": "穆棱市",
            "value": "231085"
        }, {
            "label": "东宁市",
            "value": "231086"
        }],
        [{
            "label": "市辖区",
            "value": "231101"
        }, {
            "label": "爱辉区",
            "value": "231102"
        }, {
            "label": "嫩江县",
            "value": "231121"
        }, {
            "label": "逊克县",
            "value": "231123"
        }, {
            "label": "孙吴县",
            "value": "231124"
        }, {
            "label": "北安市",
            "value": "231181"
        }, {
            "label": "五大连池市",
            "value": "231182"
        }],
        [{
            "label": "市辖区",
            "value": "231201"
        }, {
            "label": "北林区",
            "value": "231202"
        }, {
            "label": "望奎县",
            "value": "231221"
        }, {
            "label": "兰西县",
            "value": "231222"
        }, {
            "label": "青冈县",
            "value": "231223"
        }, {
            "label": "庆安县",
            "value": "231224"
        }, {
            "label": "明水县",
            "value": "231225"
        }, {
            "label": "绥棱县",
            "value": "231226"
        }, {
            "label": "安达市",
            "value": "231281"
        }, {
            "label": "肇东市",
            "value": "231282"
        }, {
            "label": "海伦市",
            "value": "231283"
        }],
        [{
            "label": "呼玛县",
            "value": "232721"
        }, {
            "label": "塔河县",
            "value": "232722"
        }, {
            "label": "漠河县",
            "value": "232723"
        }]
    ],
    [
        [{
            "label": "黄浦区",
            "value": "310101"
        }, {
            "label": "徐汇区",
            "value": "310104"
        }, {
            "label": "长宁区",
            "value": "310105"
        }, {
            "label": "静安区",
            "value": "310106"
        }, {
            "label": "普陀区",
            "value": "310107"
        }, {
            "label": "虹口区",
            "value": "310109"
        }, {
            "label": "杨浦区",
            "value": "310110"
        }, {
            "label": "闵行区",
            "value": "310112"
        }, {
            "label": "宝山区",
            "value": "310113"
        }, {
            "label": "嘉定区",
            "value": "310114"
        }, {
            "label": "浦东新区",
            "value": "310115"
        }, {
            "label": "金山区",
            "value": "310116"
        }, {
            "label": "松江区",
            "value": "310117"
        }, {
            "label": "青浦区",
            "value": "310118"
        }, {
            "label": "奉贤区",
            "value": "310120"
        }, {
            "label": "崇明区",
            "value": "310151"
        }]
    ],
    [
        [{
            "label": "市辖区",
            "value": "320101"
        }, {
            "label": "玄武区",
            "value": "320102"
        }, {
            "label": "秦淮区",
            "value": "320104"
        }, {
            "label": "建邺区",
            "value": "320105"
        }, {
            "label": "鼓楼区",
            "value": "320106"
        }, {
            "label": "浦口区",
            "value": "320111"
        }, {
            "label": "栖霞区",
            "value": "320113"
        }, {
            "label": "雨花台区",
            "value": "320114"
        }, {
            "label": "江宁区",
            "value": "320115"
        }, {
            "label": "六合区",
            "value": "320116"
        }, {
            "label": "溧水区",
            "value": "320117"
        }, {
            "label": "高淳区",
            "value": "320118"
        }],
        [{
            "label": "市辖区",
            "value": "320201"
        }, {
            "label": "锡山区",
            "value": "320205"
        }, {
            "label": "惠山区",
            "value": "320206"
        }, {
            "label": "滨湖区",
            "value": "320211"
        }, {
            "label": "梁溪区",
            "value": "320213"
        }, {
            "label": "新吴区",
            "value": "320214"
        }, {
            "label": "江阴市",
            "value": "320281"
        }, {
            "label": "宜兴市",
            "value": "320282"
        }],
        [{
            "label": "市辖区",
            "value": "320301"
        }, {
            "label": "鼓楼区",
            "value": "320302"
        }, {
            "label": "云龙区",
            "value": "320303"
        }, {
            "label": "贾汪区",
            "value": "320305"
        }, {
            "label": "泉山区",
            "value": "320311"
        }, {
            "label": "铜山区",
            "value": "320312"
        }, {
            "label": "丰县",
            "value": "320321"
        }, {
            "label": "沛县",
            "value": "320322"
        }, {
            "label": "睢宁县",
            "value": "320324"
        }, {
            "label": "新沂市",
            "value": "320381"
        }, {
            "label": "邳州市",
            "value": "320382"
        }],
        [{
            "label": "市辖区",
            "value": "320401"
        }, {
            "label": "天宁区",
            "value": "320402"
        }, {
            "label": "钟楼区",
            "value": "320404"
        }, {
            "label": "新北区",
            "value": "320411"
        }, {
            "label": "武进区",
            "value": "320412"
        }, {
            "label": "金坛区",
            "value": "320413"
        }, {
            "label": "溧阳市",
            "value": "320481"
        }],
        [{
            "label": "市辖区",
            "value": "320501"
        }, {
            "label": "虎丘区",
            "value": "320505"
        }, {
            "label": "吴中区",
            "value": "320506"
        }, {
            "label": "相城区",
            "value": "320507"
        }, {
            "label": "姑苏区",
            "value": "320508"
        }, {
            "label": "吴江区",
            "value": "320509"
        }, {
            "label": "常熟市",
            "value": "320581"
        }, {
            "label": "张家港市",
            "value": "320582"
        }, {
            "label": "昆山市",
            "value": "320583"
        }, {
            "label": "太仓市",
            "value": "320585"
        }],
        [{
            "label": "市辖区",
            "value": "320601"
        }, {
            "label": "崇川区",
            "value": "320602"
        }, {
            "label": "港闸区",
            "value": "320611"
        }, {
            "label": "通州区",
            "value": "320612"
        }, {
            "label": "海安县",
            "value": "320621"
        }, {
            "label": "如东县",
            "value": "320623"
        }, {
            "label": "启东市",
            "value": "320681"
        }, {
            "label": "如皋市",
            "value": "320682"
        }, {
            "label": "海门市",
            "value": "320684"
        }],
        [{
            "label": "市辖区",
            "value": "320701"
        }, {
            "label": "连云区",
            "value": "320703"
        }, {
            "label": "海州区",
            "value": "320706"
        }, {
            "label": "赣榆区",
            "value": "320707"
        }, {
            "label": "东海县",
            "value": "320722"
        }, {
            "label": "灌云县",
            "value": "320723"
        }, {
            "label": "灌南县",
            "value": "320724"
        }],
        [{
            "label": "市辖区",
            "value": "320801"
        }, {
            "label": "淮安区",
            "value": "320803"
        }, {
            "label": "淮阴区",
            "value": "320804"
        }, {
            "label": "清江浦区",
            "value": "320812"
        }, {
            "label": "洪泽区",
            "value": "320813"
        }, {
            "label": "涟水县",
            "value": "320826"
        }, {
            "label": "盱眙县",
            "value": "320830"
        }, {
            "label": "金湖县",
            "value": "320831"
        }],
        [{
            "label": "市辖区",
            "value": "320901"
        }, {
            "label": "亭湖区",
            "value": "320902"
        }, {
            "label": "盐都区",
            "value": "320903"
        }, {
            "label": "大丰区",
            "value": "320904"
        }, {
            "label": "响水县",
            "value": "320921"
        }, {
            "label": "滨海县",
            "value": "320922"
        }, {
            "label": "阜宁县",
            "value": "320923"
        }, {
            "label": "射阳县",
            "value": "320924"
        }, {
            "label": "建湖县",
            "value": "320925"
        }, {
            "label": "东台市",
            "value": "320981"
        }],
        [{
            "label": "市辖区",
            "value": "321001"
        }, {
            "label": "广陵区",
            "value": "321002"
        }, {
            "label": "邗江区",
            "value": "321003"
        }, {
            "label": "江都区",
            "value": "321012"
        }, {
            "label": "宝应县",
            "value": "321023"
        }, {
            "label": "仪征市",
            "value": "321081"
        }, {
            "label": "高邮市",
            "value": "321084"
        }],
        [{
            "label": "市辖区",
            "value": "321101"
        }, {
            "label": "京口区",
            "value": "321102"
        }, {
            "label": "润州区",
            "value": "321111"
        }, {
            "label": "丹徒区",
            "value": "321112"
        }, {
            "label": "丹阳市",
            "value": "321181"
        }, {
            "label": "扬中市",
            "value": "321182"
        }, {
            "label": "句容市",
            "value": "321183"
        }],
        [{
            "label": "市辖区",
            "value": "321201"
        }, {
            "label": "海陵区",
            "value": "321202"
        }, {
            "label": "高港区",
            "value": "321203"
        }, {
            "label": "姜堰区",
            "value": "321204"
        }, {
            "label": "兴化市",
            "value": "321281"
        }, {
            "label": "靖江市",
            "value": "321282"
        }, {
            "label": "泰兴市",
            "value": "321283"
        }],
        [{
            "label": "市辖区",
            "value": "321301"
        }, {
            "label": "宿城区",
            "value": "321302"
        }, {
            "label": "宿豫区",
            "value": "321311"
        }, {
            "label": "沭阳县",
            "value": "321322"
        }, {
            "label": "泗阳县",
            "value": "321323"
        }, {
            "label": "泗洪县",
            "value": "321324"
        }]
    ],
    [
        [{
            "label": "市辖区",
            "value": "330101"
        }, {
            "label": "上城区",
            "value": "330102"
        }, {
            "label": "下城区",
            "value": "330103"
        }, {
            "label": "江干区",
            "value": "330104"
        }, {
            "label": "拱墅区",
            "value": "330105"
        }, {
            "label": "西湖区",
            "value": "330106"
        }, {
            "label": "滨江区",
            "value": "330108"
        }, {
            "label": "萧山区",
            "value": "330109"
        }, {
            "label": "余杭区",
            "value": "330110"
        }, {
            "label": "富阳区",
            "value": "330111"
        }, {
            "label": "桐庐县",
            "value": "330122"
        }, {
            "label": "淳安县",
            "value": "330127"
        }, {
            "label": "建德市",
            "value": "330182"
        }, {
            "label": "临安市",
            "value": "330185"
        }, {
            "label": "富阳市",
            "value": "920001"
        }],
        [{
            "label": "市辖区",
            "value": "330201"
        }, {
            "label": "海曙区",
            "value": "330203"
        }, {
            "label": "江东区",
            "value": "330204"
        }, {
            "label": "江北区",
            "value": "330205"
        }, {
            "label": "北仑区",
            "value": "330206"
        }, {
            "label": "镇海区",
            "value": "330211"
        }, {
            "label": "鄞州区",
            "value": "330212"
        }, {
            "label": "象山县",
            "value": "330225"
        }, {
            "label": "宁海县",
            "value": "330226"
        }, {
            "label": "余姚市",
            "value": "330281"
        }, {
            "label": "慈溪市",
            "value": "330282"
        }, {
            "label": "奉化市",
            "value": "330283"
        }],
        [{
            "label": "市辖区",
            "value": "330301"
        }, {
            "label": "鹿城区",
            "value": "330302"
        }, {
            "label": "龙湾区",
            "value": "330303"
        }, {
            "label": "瓯海区",
            "value": "330304"
        }, {
            "label": "洞头区",
            "value": "330305"
        }, {
            "label": "永嘉县",
            "value": "330324"
        }, {
            "label": "平阳县",
            "value": "330326"
        }, {
            "label": "苍南县",
            "value": "330327"
        }, {
            "label": "文成县",
            "value": "330328"
        }, {
            "label": "泰顺县",
            "value": "330329"
        }, {
            "label": "瑞安市",
            "value": "330381"
        }, {
            "label": "乐清市",
            "value": "330382"
        }],
        [{
            "label": "市辖区",
            "value": "330401"
        }, {
            "label": "南湖区",
            "value": "330402"
        }, {
            "label": "秀洲区",
            "value": "330411"
        }, {
            "label": "嘉善县",
            "value": "330421"
        }, {
            "label": "海盐县",
            "value": "330424"
        }, {
            "label": "海宁市",
            "value": "330481"
        }, {
            "label": "平湖市",
            "value": "330482"
        }, {
            "label": "桐乡市",
            "value": "330483"
        }],
        [{
            "label": "市辖区",
            "value": "330501"
        }, {
            "label": "吴兴区",
            "value": "330502"
        }, {
            "label": "南浔区",
            "value": "330503"
        }, {
            "label": "德清县",
            "value": "330521"
        }, {
            "label": "长兴县",
            "value": "330522"
        }, {
            "label": "安吉县",
            "value": "330523"
        }],
        [{
            "label": "市辖区",
            "value": "330601"
        }, {
            "label": "越城区",
            "value": "330602"
        }, {
            "label": "柯桥区",
            "value": "330603"
        }, {
            "label": "上虞区",
            "value": "330604"
        }, {
            "label": "新昌县",
            "value": "330624"
        }, {
            "label": "诸暨市",
            "value": "330681"
        }, {
            "label": "嵊州市",
            "value": "330683"
        }],
        [{
            "label": "市辖区",
            "value": "330701"
        }, {
            "label": "婺城区",
            "value": "330702"
        }, {
            "label": "金东区",
            "value": "330703"
        }, {
            "label": "武义县",
            "value": "330723"
        }, {
            "label": "浦江县",
            "value": "330726"
        }, {
            "label": "磐安县",
            "value": "330727"
        }, {
            "label": "兰溪市",
            "value": "330781"
        }, {
            "label": "义乌市",
            "value": "330782"
        }, {
            "label": "东阳市",
            "value": "330783"
        }, {
            "label": "永康市",
            "value": "330784"
        }],
        [{
            "label": "市辖区",
            "value": "330801"
        }, {
            "label": "柯城区",
            "value": "330802"
        }, {
            "label": "衢江区",
            "value": "330803"
        }, {
            "label": "常山县",
            "value": "330822"
        }, {
            "label": "开化县",
            "value": "330824"
        }, {
            "label": "龙游县",
            "value": "330825"
        }, {
            "label": "江山市",
            "value": "330881"
        }],
        [{
            "label": "市辖区",
            "value": "330901"
        }, {
            "label": "定海区",
            "value": "330902"
        }, {
            "label": "普陀区",
            "value": "330903"
        }, {
            "label": "岱山县",
            "value": "330921"
        }, {
            "label": "嵊泗县",
            "value": "330922"
        }],
        [{
            "label": "市辖区",
            "value": "331001"
        }, {
            "label": "椒江区",
            "value": "331002"
        }, {
            "label": "黄岩区",
            "value": "331003"
        }, {
            "label": "路桥区",
            "value": "331004"
        }, {
            "label": "玉环县",
            "value": "331021"
        }, {
            "label": "三门县",
            "value": "331022"
        }, {
            "label": "天台县",
            "value": "331023"
        }, {
            "label": "仙居县",
            "value": "331024"
        }, {
            "label": "温岭市",
            "value": "331081"
        }, {
            "label": "临海市",
            "value": "331082"
        }],
        [{
            "label": "市辖区",
            "value": "331101"
        }, {
            "label": "莲都区",
            "value": "331102"
        }, {
            "label": "青田县",
            "value": "331121"
        }, {
            "label": "缙云县",
            "value": "331122"
        }, {
            "label": "遂昌县",
            "value": "331123"
        }, {
            "label": "松阳县",
            "value": "331124"
        }, {
            "label": "云和县",
            "value": "331125"
        }, {
            "label": "庆元县",
            "value": "331126"
        }, {
            "label": "景宁畲族自治县",
            "value": "331127"
        }, {
            "label": "龙泉市",
            "value": "331181"
        }]
    ],
    [
        [{
            "label": "市辖区",
            "value": "340101"
        }, {
            "label": "瑶海区",
            "value": "340102"
        }, {
            "label": "庐阳区",
            "value": "340103"
        }, {
            "label": "蜀山区",
            "value": "340104"
        }, {
            "label": "包河区",
            "value": "340111"
        }, {
            "label": "长丰县",
            "value": "340121"
        }, {
            "label": "肥东县",
            "value": "340122"
        }, {
            "label": "肥西县",
            "value": "340123"
        }, {
            "label": "庐江县",
            "value": "340124"
        }, {
            "label": "巢湖市",
            "value": "340181"
        }],
        [{
            "label": "市辖区",
            "value": "340201"
        }, {
            "label": "镜湖区",
            "value": "340202"
        }, {
            "label": "弋江区",
            "value": "340203"
        }, {
            "label": "鸠江区",
            "value": "340207"
        }, {
            "label": "三山区",
            "value": "340208"
        }, {
            "label": "芜湖县",
            "value": "340221"
        }, {
            "label": "繁昌县",
            "value": "340222"
        }, {
            "label": "南陵县",
            "value": "340223"
        }, {
            "label": "无为县",
            "value": "340225"
        }],
        [{
            "label": "市辖区",
            "value": "340301"
        }, {
            "label": "龙子湖区",
            "value": "340302"
        }, {
            "label": "蚌山区",
            "value": "340303"
        }, {
            "label": "禹会区",
            "value": "340304"
        }, {
            "label": "淮上区",
            "value": "340311"
        }, {
            "label": "怀远县",
            "value": "340321"
        }, {
            "label": "五河县",
            "value": "340322"
        }, {
            "label": "固镇县",
            "value": "340323"
        }],
        [{
            "label": "市辖区",
            "value": "340401"
        }, {
            "label": "大通区",
            "value": "340402"
        }, {
            "label": "田家庵区",
            "value": "340403"
        }, {
            "label": "谢家集区",
            "value": "340404"
        }, {
            "label": "八公山区",
            "value": "340405"
        }, {
            "label": "潘集区",
            "value": "340406"
        }, {
            "label": "凤台县",
            "value": "340421"
        }, {
            "label": "寿县",
            "value": "340422"
        }],
        [{
            "label": "市辖区",
            "value": "340501"
        }, {
            "label": "花山区",
            "value": "340503"
        }, {
            "label": "雨山区",
            "value": "340504"
        }, {
            "label": "博望区",
            "value": "340506"
        }, {
            "label": "当涂县",
            "value": "340521"
        }, {
            "label": "含山县",
            "value": "340522"
        }, {
            "label": "和县",
            "value": "340523"
        }],
        [{
            "label": "市辖区",
            "value": "340601"
        }, {
            "label": "杜集区",
            "value": "340602"
        }, {
            "label": "相山区",
            "value": "340603"
        }, {
            "label": "烈山区",
            "value": "340604"
        }, {
            "label": "濉溪县",
            "value": "340621"
        }],
        [{
            "label": "市辖区",
            "value": "340701"
        }, {
            "label": "铜官区",
            "value": "340705"
        }, {
            "label": "义安区",
            "value": "340706"
        }, {
            "label": "郊区",
            "value": "340711"
        }, {
            "label": "枞阳县",
            "value": "340722"
        }],
        [{
            "label": "市辖区",
            "value": "340801"
        }, {
            "label": "迎江区",
            "value": "340802"
        }, {
            "label": "大观区",
            "value": "340803"
        }, {
            "label": "宜秀区",
            "value": "340811"
        }, {
            "label": "怀宁县",
            "value": "340822"
        }, {
            "label": "潜山县",
            "value": "340824"
        }, {
            "label": "太湖县",
            "value": "340825"
        }, {
            "label": "宿松县",
            "value": "340826"
        }, {
            "label": "望江县",
            "value": "340827"
        }, {
            "label": "岳西县",
            "value": "340828"
        }, {
            "label": "桐城市",
            "value": "340881"
        }],
        [{
            "label": "市辖区",
            "value": "341001"
        }, {
            "label": "屯溪区",
            "value": "341002"
        }, {
            "label": "黄山区",
            "value": "341003"
        }, {
            "label": "徽州区",
            "value": "341004"
        }, {
            "label": "歙县",
            "value": "341021"
        }, {
            "label": "休宁县",
            "value": "341022"
        }, {
            "label": "黟县",
            "value": "341023"
        }, {
            "label": "祁门县",
            "value": "341024"
        }],
        [{
            "label": "市辖区",
            "value": "341101"
        }, {
            "label": "琅琊区",
            "value": "341102"
        }, {
            "label": "南谯区",
            "value": "341103"
        }, {
            "label": "来安县",
            "value": "341122"
        }, {
            "label": "全椒县",
            "value": "341124"
        }, {
            "label": "定远县",
            "value": "341125"
        }, {
            "label": "凤阳县",
            "value": "341126"
        }, {
            "label": "天长市",
            "value": "341181"
        }, {
            "label": "明光市",
            "value": "341182"
        }],
        [{
            "label": "市辖区",
            "value": "341201"
        }, {
            "label": "颍州区",
            "value": "341202"
        }, {
            "label": "颍东区",
            "value": "341203"
        }, {
            "label": "颍泉区",
            "value": "341204"
        }, {
            "label": "临泉县",
            "value": "341221"
        }, {
            "label": "太和县",
            "value": "341222"
        }, {
            "label": "阜南县",
            "value": "341225"
        }, {
            "label": "颍上县",
            "value": "341226"
        }, {
            "label": "界首市",
            "value": "341282"
        }],
        [{
            "label": "市辖区",
            "value": "341301"
        }, {
            "label": "埇桥区",
            "value": "341302"
        }, {
            "label": "砀山县",
            "value": "341321"
        }, {
            "label": "萧县",
            "value": "341322"
        }, {
            "label": "灵璧县",
            "value": "341323"
        }, {
            "label": "泗县",
            "value": "341324"
        }],
        [{
            "label": "市辖区",
            "value": "341501"
        }, {
            "label": "金安区",
            "value": "341502"
        }, {
            "label": "裕安区",
            "value": "341503"
        }, {
            "label": "叶集区",
            "value": "341504"
        }, {
            "label": "霍邱县",
            "value": "341522"
        }, {
            "label": "舒城县",
            "value": "341523"
        }, {
            "label": "金寨县",
            "value": "341524"
        }, {
            "label": "霍山县",
            "value": "341525"
        }],
        [{
            "label": "市辖区",
            "value": "341601"
        }, {
            "label": "谯城区",
            "value": "341602"
        }, {
            "label": "涡阳县",
            "value": "341621"
        }, {
            "label": "蒙城县",
            "value": "341622"
        }, {
            "label": "利辛县",
            "value": "341623"
        }],
        [{
            "label": "市辖区",
            "value": "341701"
        }, {
            "label": "贵池区",
            "value": "341702"
        }, {
            "label": "东至县",
            "value": "341721"
        }, {
            "label": "石台县",
            "value": "341722"
        }, {
            "label": "青阳县",
            "value": "341723"
        }],
        [{
            "label": "市辖区",
            "value": "341801"
        }, {
            "label": "宣州区",
            "value": "341802"
        }, {
            "label": "郎溪县",
            "value": "341821"
        }, {
            "label": "广德县",
            "value": "341822"
        }, {
            "label": "泾县",
            "value": "341823"
        }, {
            "label": "绩溪县",
            "value": "341824"
        }, {
            "label": "旌德县",
            "value": "341825"
        }, {
            "label": "宁国市",
            "value": "341881"
        }]
    ],
    [
        [{
            "label": "市辖区",
            "value": "350101"
        }, {
            "label": "鼓楼区",
            "value": "350102"
        }, {
            "label": "台江区",
            "value": "350103"
        }, {
            "label": "仓山区",
            "value": "350104"
        }, {
            "label": "马尾区",
            "value": "350105"
        }, {
            "label": "晋安区",
            "value": "350111"
        }, {
            "label": "闽侯县",
            "value": "350121"
        }, {
            "label": "连江县",
            "value": "350122"
        }, {
            "label": "罗源县",
            "value": "350123"
        }, {
            "label": "闽清县",
            "value": "350124"
        }, {
            "label": "永泰县",
            "value": "350125"
        }, {
            "label": "平潭县",
            "value": "350128"
        }, {
            "label": "福清市",
            "value": "350181"
        }, {
            "label": "长乐市",
            "value": "350182"
        }],
        [{
            "label": "市辖区",
            "value": "350201"
        }, {
            "label": "思明区",
            "value": "350203"
        }, {
            "label": "海沧区",
            "value": "350205"
        }, {
            "label": "湖里区",
            "value": "350206"
        }, {
            "label": "集美区",
            "value": "350211"
        }, {
            "label": "同安区",
            "value": "350212"
        }, {
            "label": "翔安区",
            "value": "350213"
        }],
        [{
            "label": "市辖区",
            "value": "350301"
        }, {
            "label": "城厢区",
            "value": "350302"
        }, {
            "label": "涵江区",
            "value": "350303"
        }, {
            "label": "荔城区",
            "value": "350304"
        }, {
            "label": "秀屿区",
            "value": "350305"
        }, {
            "label": "仙游县",
            "value": "350322"
        }],
        [{
            "label": "市辖区",
            "value": "350401"
        }, {
            "label": "梅列区",
            "value": "350402"
        }, {
            "label": "三元区",
            "value": "350403"
        }, {
            "label": "明溪县",
            "value": "350421"
        }, {
            "label": "清流县",
            "value": "350423"
        }, {
            "label": "宁化县",
            "value": "350424"
        }, {
            "label": "大田县",
            "value": "350425"
        }, {
            "label": "尤溪县",
            "value": "350426"
        }, {
            "label": "沙县",
            "value": "350427"
        }, {
            "label": "将乐县",
            "value": "350428"
        }, {
            "label": "泰宁县",
            "value": "350429"
        }, {
            "label": "建宁县",
            "value": "350430"
        }, {
            "label": "永安市",
            "value": "350481"
        }],
        [{
            "label": "市辖区",
            "value": "350501"
        }, {
            "label": "鲤城区",
            "value": "350502"
        }, {
            "label": "丰泽区",
            "value": "350503"
        }, {
            "label": "洛江区",
            "value": "350504"
        }, {
            "label": "泉港区",
            "value": "350505"
        }, {
            "label": "惠安县",
            "value": "350521"
        }, {
            "label": "安溪县",
            "value": "350524"
        }, {
            "label": "永春县",
            "value": "350525"
        }, {
            "label": "德化县",
            "value": "350526"
        }, {
            "label": "金门县",
            "value": "350527"
        }, {
            "label": "石狮市",
            "value": "350581"
        }, {
            "label": "晋江市",
            "value": "350582"
        }, {
            "label": "南安市",
            "value": "350583"
        }],
        [{
            "label": "市辖区",
            "value": "350601"
        }, {
            "label": "芗城区",
            "value": "350602"
        }, {
            "label": "龙文区",
            "value": "350603"
        }, {
            "label": "云霄县",
            "value": "350622"
        }, {
            "label": "漳浦县",
            "value": "350623"
        }, {
            "label": "诏安县",
            "value": "350624"
        }, {
            "label": "长泰县",
            "value": "350625"
        }, {
            "label": "东山县",
            "value": "350626"
        }, {
            "label": "南靖县",
            "value": "350627"
        }, {
            "label": "平和县",
            "value": "350628"
        }, {
            "label": "华安县",
            "value": "350629"
        }, {
            "label": "龙海市",
            "value": "350681"
        }],
        [{
            "label": "市辖区",
            "value": "350701"
        }, {
            "label": "延平区",
            "value": "350702"
        }, {
            "label": "建阳区",
            "value": "350703"
        }, {
            "label": "顺昌县",
            "value": "350721"
        }, {
            "label": "浦城县",
            "value": "350722"
        }, {
            "label": "光泽县",
            "value": "350723"
        }, {
            "label": "松溪县",
            "value": "350724"
        }, {
            "label": "政和县",
            "value": "350725"
        }, {
            "label": "邵武市",
            "value": "350781"
        }, {
            "label": "武夷山市",
            "value": "350782"
        }, {
            "label": "建瓯市",
            "value": "350783"
        }],
        [{
            "label": "市辖区",
            "value": "350801"
        }, {
            "label": "新罗区",
            "value": "350802"
        }, {
            "label": "永定区",
            "value": "350803"
        }, {
            "label": "长汀县",
            "value": "350821"
        }, {
            "label": "上杭县",
            "value": "350823"
        }, {
            "label": "武平县",
            "value": "350824"
        }, {
            "label": "连城县",
            "value": "350825"
        }, {
            "label": "漳平市",
            "value": "350881"
        }],
        [{
            "label": "市辖区",
            "value": "350901"
        }, {
            "label": "蕉城区",
            "value": "350902"
        }, {
            "label": "霞浦县",
            "value": "350921"
        }, {
            "label": "古田县",
            "value": "350922"
        }, {
            "label": "屏南县",
            "value": "350923"
        }, {
            "label": "寿宁县",
            "value": "350924"
        }, {
            "label": "周宁县",
            "value": "350925"
        }, {
            "label": "柘荣县",
            "value": "350926"
        }, {
            "label": "福安市",
            "value": "350981"
        }, {
            "label": "福鼎市",
            "value": "350982"
        }]
    ],
    [
        [{
            "label": "市辖区",
            "value": "360101"
        }, {
            "label": "东湖区",
            "value": "360102"
        }, {
            "label": "西湖区",
            "value": "360103"
        }, {
            "label": "青云谱区",
            "value": "360104"
        }, {
            "label": "湾里区",
            "value": "360105"
        }, {
            "label": "青山湖区",
            "value": "360111"
        }, {
            "label": "新建区",
            "value": "360112"
        }, {
            "label": "南昌县",
            "value": "360121"
        }, {
            "label": "安义县",
            "value": "360123"
        }, {
            "label": "进贤县",
            "value": "360124"
        }],
        [{
            "label": "市辖区",
            "value": "360201"
        }, {
            "label": "昌江区",
            "value": "360202"
        }, {
            "label": "珠山区",
            "value": "360203"
        }, {
            "label": "浮梁县",
            "value": "360222"
        }, {
            "label": "乐平市",
            "value": "360281"
        }],
        [{
            "label": "市辖区",
            "value": "360301"
        }, {
            "label": "安源区",
            "value": "360302"
        }, {
            "label": "湘东区",
            "value": "360313"
        }, {
            "label": "莲花县",
            "value": "360321"
        }, {
            "label": "上栗县",
            "value": "360322"
        }, {
            "label": "芦溪县",
            "value": "360323"
        }],
        [{
            "label": "市辖区",
            "value": "360401"
        }, {
            "label": "濂溪区",
            "value": "360402"
        }, {
            "label": "浔阳区",
            "value": "360403"
        }, {
            "label": "九江县",
            "value": "360421"
        }, {
            "label": "武宁县",
            "value": "360423"
        }, {
            "label": "修水县",
            "value": "360424"
        }, {
            "label": "永修县",
            "value": "360425"
        }, {
            "label": "德安县",
            "value": "360426"
        }, {
            "label": "都昌县",
            "value": "360428"
        }, {
            "label": "湖口县",
            "value": "360429"
        }, {
            "label": "彭泽县",
            "value": "360430"
        }, {
            "label": "瑞昌市",
            "value": "360481"
        }, {
            "label": "共青城市",
            "value": "360482"
        }, {
            "label": "庐山市",
            "value": "360483"
        }],
        [{
            "label": "市辖区",
            "value": "360501"
        }, {
            "label": "渝水区",
            "value": "360502"
        }, {
            "label": "分宜县",
            "value": "360521"
        }],
        [{
            "label": "市辖区",
            "value": "360601"
        }, {
            "label": "月湖区",
            "value": "360602"
        }, {
            "label": "余江县",
            "value": "360622"
        }, {
            "label": "贵溪市",
            "value": "360681"
        }],
        [{
            "label": "市辖区",
            "value": "360701"
        }, {
            "label": "章贡区",
            "value": "360702"
        }, {
            "label": "南康区",
            "value": "360703"
        }, {
            "label": "赣县",
            "value": "360721"
        }, {
            "label": "信丰县",
            "value": "360722"
        }, {
            "label": "大余县",
            "value": "360723"
        }, {
            "label": "上犹县",
            "value": "360724"
        }, {
            "label": "崇义县",
            "value": "360725"
        }, {
            "label": "安远县",
            "value": "360726"
        }, {
            "label": "龙南县",
            "value": "360727"
        }, {
            "label": "定南县",
            "value": "360728"
        }, {
            "label": "全南县",
            "value": "360729"
        }, {
            "label": "宁都县",
            "value": "360730"
        }, {
            "label": "于都县",
            "value": "360731"
        }, {
            "label": "兴国县",
            "value": "360732"
        }, {
            "label": "会昌县",
            "value": "360733"
        }, {
            "label": "寻乌县",
            "value": "360734"
        }, {
            "label": "石城县",
            "value": "360735"
        }, {
            "label": "瑞金市",
            "value": "360781"
        }],
        [{
            "label": "市辖区",
            "value": "360801"
        }, {
            "label": "吉州区",
            "value": "360802"
        }, {
            "label": "青原区",
            "value": "360803"
        }, {
            "label": "吉安县",
            "value": "360821"
        }, {
            "label": "吉水县",
            "value": "360822"
        }, {
            "label": "峡江县",
            "value": "360823"
        }, {
            "label": "新干县",
            "value": "360824"
        }, {
            "label": "永丰县",
            "value": "360825"
        }, {
            "label": "泰和县",
            "value": "360826"
        }, {
            "label": "遂川县",
            "value": "360827"
        }, {
            "label": "万安县",
            "value": "360828"
        }, {
            "label": "安福县",
            "value": "360829"
        }, {
            "label": "永新县",
            "value": "360830"
        }, {
            "label": "井冈山市",
            "value": "360881"
        }],
        [{
            "label": "市辖区",
            "value": "360901"
        }, {
            "label": "袁州区",
            "value": "360902"
        }, {
            "label": "奉新县",
            "value": "360921"
        }, {
            "label": "万载县",
            "value": "360922"
        }, {
            "label": "上高县",
            "value": "360923"
        }, {
            "label": "宜丰县",
            "value": "360924"
        }, {
            "label": "靖安县",
            "value": "360925"
        }, {
            "label": "铜鼓县",
            "value": "360926"
        }, {
            "label": "丰城市",
            "value": "360981"
        }, {
            "label": "樟树市",
            "value": "360982"
        }, {
            "label": "高安市",
            "value": "360983"
        }],
        [{
            "label": "市辖区",
            "value": "361001"
        }, {
            "label": "临川区",
            "value": "361002"
        }, {
            "label": "南城县",
            "value": "361021"
        }, {
            "label": "黎川县",
            "value": "361022"
        }, {
            "label": "南丰县",
            "value": "361023"
        }, {
            "label": "崇仁县",
            "value": "361024"
        }, {
            "label": "乐安县",
            "value": "361025"
        }, {
            "label": "宜黄县",
            "value": "361026"
        }, {
            "label": "金溪县",
            "value": "361027"
        }, {
            "label": "资溪县",
            "value": "361028"
        }, {
            "label": "东乡县",
            "value": "361029"
        }, {
            "label": "广昌县",
            "value": "361030"
        }],
        [{
            "label": "市辖区",
            "value": "361101"
        }, {
            "label": "信州区",
            "value": "361102"
        }, {
            "label": "广丰区",
            "value": "361103"
        }, {
            "label": "上饶县",
            "value": "361121"
        }, {
            "label": "玉山县",
            "value": "361123"
        }, {
            "label": "铅山县",
            "value": "361124"
        }, {
            "label": "横峰县",
            "value": "361125"
        }, {
            "label": "弋阳县",
            "value": "361126"
        }, {
            "label": "余干县",
            "value": "361127"
        }, {
            "label": "鄱阳县",
            "value": "361128"
        }, {
            "label": "万年县",
            "value": "361129"
        }, {
            "label": "婺源县",
            "value": "361130"
        }, {
            "label": "德兴市",
            "value": "361181"
        }]
    ],
    [
        [{
            "label": "市辖区",
            "value": "370101"
        }, {
            "label": "历下区",
            "value": "370102"
        }, {
            "label": "市中区",
            "value": "370103"
        }, {
            "label": "槐荫区",
            "value": "370104"
        }, {
            "label": "天桥区",
            "value": "370105"
        }, {
            "label": "历城区",
            "value": "370112"
        }, {
            "label": "长清区",
            "value": "370113"
        }, {
            "label": "平阴县",
            "value": "370124"
        }, {
            "label": "济阳县",
            "value": "370125"
        }, {
            "label": "商河县",
            "value": "370126"
        }, {
            "label": "章丘市",
            "value": "370181"
        }],
        [{
            "label": "市辖区",
            "value": "370201"
        }, {
            "label": "市南区",
            "value": "370202"
        }, {
            "label": "市北区",
            "value": "370203"
        }, {
            "label": "黄岛区",
            "value": "370211"
        }, {
            "label": "崂山区",
            "value": "370212"
        }, {
            "label": "李沧区",
            "value": "370213"
        }, {
            "label": "城阳区",
            "value": "370214"
        }, {
            "label": "胶州市",
            "value": "370281"
        }, {
            "label": "即墨市",
            "value": "370282"
        }, {
            "label": "平度市",
            "value": "370283"
        }, {
            "label": "莱西市",
            "value": "370285"
        }],
        [{
            "label": "市辖区",
            "value": "370301"
        }, {
            "label": "淄川区",
            "value": "370302"
        }, {
            "label": "张店区",
            "value": "370303"
        }, {
            "label": "博山区",
            "value": "370304"
        }, {
            "label": "临淄区",
            "value": "370305"
        }, {
            "label": "周村区",
            "value": "370306"
        }, {
            "label": "桓台县",
            "value": "370321"
        }, {
            "label": "高青县",
            "value": "370322"
        }, {
            "label": "沂源县",
            "value": "370323"
        }],
        [{
            "label": "市辖区",
            "value": "370401"
        }, {
            "label": "市中区",
            "value": "370402"
        }, {
            "label": "薛城区",
            "value": "370403"
        }, {
            "label": "峄城区",
            "value": "370404"
        }, {
            "label": "台儿庄区",
            "value": "370405"
        }, {
            "label": "山亭区",
            "value": "370406"
        }, {
            "label": "滕州市",
            "value": "370481"
        }],
        [{
            "label": "市辖区",
            "value": "370501"
        }, {
            "label": "东营区",
            "value": "370502"
        }, {
            "label": "河口区",
            "value": "370503"
        }, {
            "label": "垦利区",
            "value": "370505"
        }, {
            "label": "利津县",
            "value": "370522"
        }, {
            "label": "广饶县",
            "value": "370523"
        }],
        [{
            "label": "市辖区",
            "value": "370601"
        }, {
            "label": "芝罘区",
            "value": "370602"
        }, {
            "label": "福山区",
            "value": "370611"
        }, {
            "label": "牟平区",
            "value": "370612"
        }, {
            "label": "莱山区",
            "value": "370613"
        }, {
            "label": "长岛县",
            "value": "370634"
        }, {
            "label": "龙口市",
            "value": "370681"
        }, {
            "label": "莱阳市",
            "value": "370682"
        }, {
            "label": "莱州市",
            "value": "370683"
        }, {
            "label": "蓬莱市",
            "value": "370684"
        }, {
            "label": "招远市",
            "value": "370685"
        }, {
            "label": "栖霞市",
            "value": "370686"
        }, {
            "label": "海阳市",
            "value": "370687"
        }],
        [{
            "label": "市辖区",
            "value": "370701"
        }, {
            "label": "潍城区",
            "value": "370702"
        }, {
            "label": "寒亭区",
            "value": "370703"
        }, {
            "label": "坊子区",
            "value": "370704"
        }, {
            "label": "奎文区",
            "value": "370705"
        }, {
            "label": "临朐县",
            "value": "370724"
        }, {
            "label": "昌乐县",
            "value": "370725"
        }, {
            "label": "青州市",
            "value": "370781"
        }, {
            "label": "诸城市",
            "value": "370782"
        }, {
            "label": "寿光市",
            "value": "370783"
        }, {
            "label": "安丘市",
            "value": "370784"
        }, {
            "label": "高密市",
            "value": "370785"
        }, {
            "label": "昌邑市",
            "value": "370786"
        }],
        [{
            "label": "市辖区",
            "value": "370801"
        }, {
            "label": "任城区",
            "value": "370811"
        }, {
            "label": "兖州区",
            "value": "370812"
        }, {
            "label": "微山县",
            "value": "370826"
        }, {
            "label": "鱼台县",
            "value": "370827"
        }, {
            "label": "金乡县",
            "value": "370828"
        }, {
            "label": "嘉祥县",
            "value": "370829"
        }, {
            "label": "汶上县",
            "value": "370830"
        }, {
            "label": "泗水县",
            "value": "370831"
        }, {
            "label": "梁山县",
            "value": "370832"
        }, {
            "label": "曲阜市",
            "value": "370881"
        }, {
            "label": "邹城市",
            "value": "370883"
        }],
        [{
            "label": "市辖区",
            "value": "370901"
        }, {
            "label": "泰山区",
            "value": "370902"
        }, {
            "label": "岱岳区",
            "value": "370911"
        }, {
            "label": "宁阳县",
            "value": "370921"
        }, {
            "label": "东平县",
            "value": "370923"
        }, {
            "label": "新泰市",
            "value": "370982"
        }, {
            "label": "肥城市",
            "value": "370983"
        }],
        [{
            "label": "市辖区",
            "value": "371001"
        }, {
            "label": "环翠区",
            "value": "371002"
        }, {
            "label": "文登区",
            "value": "371003"
        }, {
            "label": "荣成市",
            "value": "371082"
        }, {
            "label": "乳山市",
            "value": "371083"
        }],
        [{
            "label": "市辖区",
            "value": "371101"
        }, {
            "label": "东港区",
            "value": "371102"
        }, {
            "label": "岚山区",
            "value": "371103"
        }, {
            "label": "五莲县",
            "value": "371121"
        }, {
            "label": "莒县",
            "value": "371122"
        }],
        [{
            "label": "市辖区",
            "value": "371201"
        }, {
            "label": "莱城区",
            "value": "371202"
        }, {
            "label": "钢城区",
            "value": "371203"
        }],
        [{
            "label": "市辖区",
            "value": "371301"
        }, {
            "label": "兰山区",
            "value": "371302"
        }, {
            "label": "罗庄区",
            "value": "371311"
        }, {
            "label": "河东区",
            "value": "371312"
        }, {
            "label": "沂南县",
            "value": "371321"
        }, {
            "label": "郯城县",
            "value": "371322"
        }, {
            "label": "沂水县",
            "value": "371323"
        }, {
            "label": "兰陵县",
            "value": "371324"
        }, {
            "label": "费县",
            "value": "371325"
        }, {
            "label": "平邑县",
            "value": "371326"
        }, {
            "label": "莒南县",
            "value": "371327"
        }, {
            "label": "蒙阴县",
            "value": "371328"
        }, {
            "label": "临沭县",
            "value": "371329"
        }],
        [{
            "label": "市辖区",
            "value": "371401"
        }, {
            "label": "德城区",
            "value": "371402"
        }, {
            "label": "陵城区",
            "value": "371403"
        }, {
            "label": "宁津县",
            "value": "371422"
        }, {
            "label": "庆云县",
            "value": "371423"
        }, {
            "label": "临邑县",
            "value": "371424"
        }, {
            "label": "齐河县",
            "value": "371425"
        }, {
            "label": "平原县",
            "value": "371426"
        }, {
            "label": "夏津县",
            "value": "371427"
        }, {
            "label": "武城县",
            "value": "371428"
        }, {
            "label": "乐陵市",
            "value": "371481"
        }, {
            "label": "禹城市",
            "value": "371482"
        }],
        [{
            "label": "市辖区",
            "value": "371501"
        }, {
            "label": "东昌府区",
            "value": "371502"
        }, {
            "label": "阳谷县",
            "value": "371521"
        }, {
            "label": "莘县",
            "value": "371522"
        }, {
            "label": "茌平县",
            "value": "371523"
        }, {
            "label": "东阿县",
            "value": "371524"
        }, {
            "label": "冠县",
            "value": "371525"
        }, {
            "label": "高唐县",
            "value": "371526"
        }, {
            "label": "临清市",
            "value": "371581"
        }],
        [{
            "label": "市辖区",
            "value": "371601"
        }, {
            "label": "滨城区",
            "value": "371602"
        }, {
            "label": "沾化区",
            "value": "371603"
        }, {
            "label": "惠民县",
            "value": "371621"
        }, {
            "label": "阳信县",
            "value": "371622"
        }, {
            "label": "无棣县",
            "value": "371623"
        }, {
            "label": "博兴县",
            "value": "371625"
        }, {
            "label": "邹平县",
            "value": "371626"
        }],
        [{
            "label": "市辖区",
            "value": "371701"
        }, {
            "label": "牡丹区",
            "value": "371702"
        }, {
            "label": "定陶区",
            "value": "371703"
        }, {
            "label": "曹县",
            "value": "371721"
        }, {
            "label": "单县",
            "value": "371722"
        }, {
            "label": "成武县",
            "value": "371723"
        }, {
            "label": "巨野县",
            "value": "371724"
        }, {
            "label": "郓城县",
            "value": "371725"
        }, {
            "label": "鄄城县",
            "value": "371726"
        }, {
            "label": "东明县",
            "value": "371728"
        }]
    ],
    [
        [{
            "label": "市辖区",
            "value": "410101"
        }, {
            "label": "中原区",
            "value": "410102"
        }, {
            "label": "二七区",
            "value": "410103"
        }, {
            "label": "管城回族区",
            "value": "410104"
        }, {
            "label": "金水区",
            "value": "410105"
        }, {
            "label": "上街区",
            "value": "410106"
        }, {
            "label": "惠济区",
            "value": "410108"
        }, {
            "label": "中牟县",
            "value": "410122"
        }, {
            "label": "巩义市",
            "value": "410181"
        }, {
            "label": "荥阳市",
            "value": "410182"
        }, {
            "label": "新密市",
            "value": "410183"
        }, {
            "label": "新郑市",
            "value": "410184"
        }, {
            "label": "登封市",
            "value": "410185"
        }, {
            "label": "郑东新区",
            "value": "920002"
        }],
        [{
            "label": "市辖区",
            "value": "410201"
        }, {
            "label": "龙亭区",
            "value": "410202"
        }, {
            "label": "顺河回族区",
            "value": "410203"
        }, {
            "label": "鼓楼区",
            "value": "410204"
        }, {
            "label": "禹王台区",
            "value": "410205"
        }, {
            "label": "金明区",
            "value": "410211"
        }, {
            "label": "祥符区",
            "value": "410212"
        }, {
            "label": "杞县",
            "value": "410221"
        }, {
            "label": "通许县",
            "value": "410222"
        }, {
            "label": "尉氏县",
            "value": "410223"
        }, {
            "label": "兰考县",
            "value": "410225"
        }],
        [{
            "label": "市辖区",
            "value": "410301"
        }, {
            "label": "老城区",
            "value": "410302"
        }, {
            "label": "西工区",
            "value": "410303"
        }, {
            "label": "瀍河回族区",
            "value": "410304"
        }, {
            "label": "涧西区",
            "value": "410305"
        }, {
            "label": "吉利区",
            "value": "410306"
        }, {
            "label": "洛龙区",
            "value": "410311"
        }, {
            "label": "孟津县",
            "value": "410322"
        }, {
            "label": "新安县",
            "value": "410323"
        }, {
            "label": "栾川县",
            "value": "410324"
        }, {
            "label": "嵩县",
            "value": "410325"
        }, {
            "label": "汝阳县",
            "value": "410326"
        }, {
            "label": "宜阳县",
            "value": "410327"
        }, {
            "label": "洛宁县",
            "value": "410328"
        }, {
            "label": "伊川县",
            "value": "410329"
        }, {
            "label": "偃师市",
            "value": "410381"
        }],
        [{
            "label": "市辖区",
            "value": "410401"
        }, {
            "label": "新华区",
            "value": "410402"
        }, {
            "label": "卫东区",
            "value": "410403"
        }, {
            "label": "石龙区",
            "value": "410404"
        }, {
            "label": "湛河区",
            "value": "410411"
        }, {
            "label": "宝丰县",
            "value": "410421"
        }, {
            "label": "叶县",
            "value": "410422"
        }, {
            "label": "鲁山县",
            "value": "410423"
        }, {
            "label": "郏县",
            "value": "410425"
        }, {
            "label": "舞钢市",
            "value": "410481"
        }, {
            "label": "汝州市",
            "value": "410482"
        }],
        [{
            "label": "市辖区",
            "value": "410501"
        }, {
            "label": "文峰区",
            "value": "410502"
        }, {
            "label": "北关区",
            "value": "410503"
        }, {
            "label": "殷都区",
            "value": "410505"
        }, {
            "label": "龙安区",
            "value": "410506"
        }, {
            "label": "安阳县",
            "value": "410522"
        }, {
            "label": "汤阴县",
            "value": "410523"
        }, {
            "label": "滑县",
            "value": "410526"
        }, {
            "label": "内黄县",
            "value": "410527"
        }, {
            "label": "林州市",
            "value": "410581"
        }],
        [{
            "label": "市辖区",
            "value": "410601"
        }, {
            "label": "鹤山区",
            "value": "410602"
        }, {
            "label": "山城区",
            "value": "410603"
        }, {
            "label": "淇滨区",
            "value": "410611"
        }, {
            "label": "浚县",
            "value": "410621"
        }, {
            "label": "淇县",
            "value": "410622"
        }],
        [{
            "label": "市辖区",
            "value": "410701"
        }, {
            "label": "红旗区",
            "value": "410702"
        }, {
            "label": "卫滨区",
            "value": "410703"
        }, {
            "label": "凤泉区",
            "value": "410704"
        }, {
            "label": "牧野区",
            "value": "410711"
        }, {
            "label": "新乡县",
            "value": "410721"
        }, {
            "label": "获嘉县",
            "value": "410724"
        }, {
            "label": "原阳县",
            "value": "410725"
        }, {
            "label": "延津县",
            "value": "410726"
        }, {
            "label": "封丘县",
            "value": "410727"
        }, {
            "label": "长垣县",
            "value": "410728"
        }, {
            "label": "卫辉市",
            "value": "410781"
        }, {
            "label": "辉县市",
            "value": "410782"
        }],
        [{
            "label": "市辖区",
            "value": "410801"
        }, {
            "label": "解放区",
            "value": "410802"
        }, {
            "label": "中站区",
            "value": "410803"
        }, {
            "label": "马村区",
            "value": "410804"
        }, {
            "label": "山阳区",
            "value": "410811"
        }, {
            "label": "修武县",
            "value": "410821"
        }, {
            "label": "博爱县",
            "value": "410822"
        }, {
            "label": "武陟县",
            "value": "410823"
        }, {
            "label": "温县",
            "value": "410825"
        }, {
            "label": "沁阳市",
            "value": "410882"
        }, {
            "label": "孟州市",
            "value": "410883"
        }],
        [{
            "label": "市辖区",
            "value": "410901"
        }, {
            "label": "华龙区",
            "value": "410902"
        }, {
            "label": "清丰县",
            "value": "410922"
        }, {
            "label": "南乐县",
            "value": "410923"
        }, {
            "label": "范县",
            "value": "410926"
        }, {
            "label": "台前县",
            "value": "410927"
        }, {
            "label": "濮阳县",
            "value": "410928"
        }],
        [{
            "label": "市辖区",
            "value": "411001"
        }, {
            "label": "魏都区",
            "value": "411002"
        }, {
            "label": "许昌县",
            "value": "411023"
        }, {
            "label": "鄢陵县",
            "value": "411024"
        }, {
            "label": "襄城县",
            "value": "411025"
        }, {
            "label": "禹州市",
            "value": "411081"
        }, {
            "label": "长葛市",
            "value": "411082"
        }],
        [{
            "label": "市辖区",
            "value": "411101"
        }, {
            "label": "源汇区",
            "value": "411102"
        }, {
            "label": "郾城区",
            "value": "411103"
        }, {
            "label": "召陵区",
            "value": "411104"
        }, {
            "label": "舞阳县",
            "value": "411121"
        }, {
            "label": "临颍县",
            "value": "411122"
        }],
        [{
            "label": "市辖区",
            "value": "411201"
        }, {
            "label": "湖滨区",
            "value": "411202"
        }, {
            "label": "陕州区",
            "value": "411203"
        }, {
            "label": "渑池县",
            "value": "411221"
        }, {
            "label": "卢氏县",
            "value": "411224"
        }, {
            "label": "义马市",
            "value": "411281"
        }, {
            "label": "灵宝市",
            "value": "411282"
        }],
        [{
            "label": "市辖区",
            "value": "411301"
        }, {
            "label": "宛城区",
            "value": "411302"
        }, {
            "label": "卧龙区",
            "value": "411303"
        }, {
            "label": "南召县",
            "value": "411321"
        }, {
            "label": "方城县",
            "value": "411322"
        }, {
            "label": "西峡县",
            "value": "411323"
        }, {
            "label": "镇平县",
            "value": "411324"
        }, {
            "label": "内乡县",
            "value": "411325"
        }, {
            "label": "淅川县",
            "value": "411326"
        }, {
            "label": "社旗县",
            "value": "411327"
        }, {
            "label": "唐河县",
            "value": "411328"
        }, {
            "label": "新野县",
            "value": "411329"
        }, {
            "label": "桐柏县",
            "value": "411330"
        }, {
            "label": "邓州市",
            "value": "411381"
        }],
        [{
            "label": "市辖区",
            "value": "411401"
        }, {
            "label": "梁园区",
            "value": "411402"
        }, {
            "label": "睢阳区",
            "value": "411403"
        }, {
            "label": "民权县",
            "value": "411421"
        }, {
            "label": "睢县",
            "value": "411422"
        }, {
            "label": "宁陵县",
            "value": "411423"
        }, {
            "label": "柘城县",
            "value": "411424"
        }, {
            "label": "虞城县",
            "value": "411425"
        }, {
            "label": "夏邑县",
            "value": "411426"
        }, {
            "label": "永城市",
            "value": "411481"
        }],
        [{
            "label": "市辖区",
            "value": "411501"
        }, {
            "label": "浉河区",
            "value": "411502"
        }, {
            "label": "平桥区",
            "value": "411503"
        }, {
            "label": "罗山县",
            "value": "411521"
        }, {
            "label": "光山县",
            "value": "411522"
        }, {
            "label": "新县",
            "value": "411523"
        }, {
            "label": "商城县",
            "value": "411524"
        }, {
            "label": "固始县",
            "value": "411525"
        }, {
            "label": "潢川县",
            "value": "411526"
        }, {
            "label": "淮滨县",
            "value": "411527"
        }, {
            "label": "息县",
            "value": "411528"
        }],
        [{
            "label": "市辖区",
            "value": "411601"
        }, {
            "label": "川汇区",
            "value": "411602"
        }, {
            "label": "扶沟县",
            "value": "411621"
        }, {
            "label": "西华县",
            "value": "411622"
        }, {
            "label": "商水县",
            "value": "411623"
        }, {
            "label": "沈丘县",
            "value": "411624"
        }, {
            "label": "郸城县",
            "value": "411625"
        }, {
            "label": "淮阳县",
            "value": "411626"
        }, {
            "label": "太康县",
            "value": "411627"
        }, {
            "label": "鹿邑县",
            "value": "411628"
        }, {
            "label": "项城市",
            "value": "411681"
        }],
        [{
            "label": "市辖区",
            "value": "411701"
        }, {
            "label": "驿城区",
            "value": "411702"
        }, {
            "label": "西平县",
            "value": "411721"
        }, {
            "label": "上蔡县",
            "value": "411722"
        }, {
            "label": "平舆县",
            "value": "411723"
        }, {
            "label": "正阳县",
            "value": "411724"
        }, {
            "label": "确山县",
            "value": "411725"
        }, {
            "label": "泌阳县",
            "value": "411726"
        }, {
            "label": "汝南县",
            "value": "411727"
        }, {
            "label": "遂平县",
            "value": "411728"
        }, {
            "label": "新蔡县",
            "value": "411729"
        }],
        [{
            "label": "市辖区",
            "value": "419001"
        }]
    ],
    [
        [{
            "label": "市辖区",
            "value": "420101"
        }, {
            "label": "江岸区",
            "value": "420102"
        }, {
            "label": "江汉区",
            "value": "420103"
        }, {
            "label": "硚口区",
            "value": "420104"
        }, {
            "label": "汉阳区",
            "value": "420105"
        }, {
            "label": "武昌区",
            "value": "420106"
        }, {
            "label": "青山区",
            "value": "420107"
        }, {
            "label": "洪山区",
            "value": "420111"
        }, {
            "label": "东西湖区",
            "value": "420112"
        }, {
            "label": "汉南区",
            "value": "420113"
        }, {
            "label": "蔡甸区",
            "value": "420114"
        }, {
            "label": "江夏区",
            "value": "420115"
        }, {
            "label": "黄陂区",
            "value": "420116"
        }, {
            "label": "新洲区",
            "value": "420117"
        }],
        [{
            "label": "市辖区",
            "value": "420201"
        }, {
            "label": "黄石港区",
            "value": "420202"
        }, {
            "label": "西塞山区",
            "value": "420203"
        }, {
            "label": "下陆区",
            "value": "420204"
        }, {
            "label": "铁山区",
            "value": "420205"
        }, {
            "label": "阳新县",
            "value": "420222"
        }, {
            "label": "大冶市",
            "value": "420281"
        }],
        [{
            "label": "市辖区",
            "value": "420301"
        }, {
            "label": "茅箭区",
            "value": "420302"
        }, {
            "label": "张湾区",
            "value": "420303"
        }, {
            "label": "郧阳区",
            "value": "420304"
        }, {
            "label": "郧西县",
            "value": "420322"
        }, {
            "label": "竹山县",
            "value": "420323"
        }, {
            "label": "竹溪县",
            "value": "420324"
        }, {
            "label": "房县",
            "value": "420325"
        }, {
            "label": "丹江口市",
            "value": "420381"
        }],
        [{
            "label": "市辖区",
            "value": "420501"
        }, {
            "label": "西陵区",
            "value": "420502"
        }, {
            "label": "伍家岗区",
            "value": "420503"
        }, {
            "label": "点军区",
            "value": "420504"
        }, {
            "label": "猇亭区",
            "value": "420505"
        }, {
            "label": "夷陵区",
            "value": "420506"
        }, {
            "label": "远安县",
            "value": "420525"
        }, {
            "label": "兴山县",
            "value": "420526"
        }, {
            "label": "秭归县",
            "value": "420527"
        }, {
            "label": "长阳土家族自治县",
            "value": "420528"
        }, {
            "label": "五峰土家族自治县",
            "value": "420529"
        }, {
            "label": "宜都市",
            "value": "420581"
        }, {
            "label": "当阳市",
            "value": "420582"
        }, {
            "label": "枝江市",
            "value": "420583"
        }],
        [{
            "label": "市辖区",
            "value": "420601"
        }, {
            "label": "襄城区",
            "value": "420602"
        }, {
            "label": "樊城区",
            "value": "420606"
        }, {
            "label": "襄州区",
            "value": "420607"
        }, {
            "label": "南漳县",
            "value": "420624"
        }, {
            "label": "谷城县",
            "value": "420625"
        }, {
            "label": "保康县",
            "value": "420626"
        }, {
            "label": "老河口市",
            "value": "420682"
        }, {
            "label": "枣阳市",
            "value": "420683"
        }, {
            "label": "宜城市",
            "value": "420684"
        }],
        [{
            "label": "市辖区",
            "value": "420701"
        }, {
            "label": "梁子湖区",
            "value": "420702"
        }, {
            "label": "华容区",
            "value": "420703"
        }, {
            "label": "鄂城区",
            "value": "420704"
        }],
        [{
            "label": "市辖区",
            "value": "420801"
        }, {
            "label": "东宝区",
            "value": "420802"
        }, {
            "label": "掇刀区",
            "value": "420804"
        }, {
            "label": "京山县",
            "value": "420821"
        }, {
            "label": "沙洋县",
            "value": "420822"
        }, {
            "label": "钟祥市",
            "value": "420881"
        }],
        [{
            "label": "市辖区",
            "value": "420901"
        }, {
            "label": "孝南区",
            "value": "420902"
        }, {
            "label": "孝昌县",
            "value": "420921"
        }, {
            "label": "大悟县",
            "value": "420922"
        }, {
            "label": "云梦县",
            "value": "420923"
        }, {
            "label": "应城市",
            "value": "420981"
        }, {
            "label": "安陆市",
            "value": "420982"
        }, {
            "label": "汉川市",
            "value": "420984"
        }],
        [{
            "label": "市辖区",
            "value": "421001"
        }, {
            "label": "沙市区",
            "value": "421002"
        }, {
            "label": "荆州区",
            "value": "421003"
        }, {
            "label": "公安县",
            "value": "421022"
        }, {
            "label": "监利县",
            "value": "421023"
        }, {
            "label": "江陵县",
            "value": "421024"
        }, {
            "label": "石首市",
            "value": "421081"
        }, {
            "label": "洪湖市",
            "value": "421083"
        }, {
            "label": "松滋市",
            "value": "421087"
        }],
        [{
            "label": "市辖区",
            "value": "421101"
        }, {
            "label": "黄州区",
            "value": "421102"
        }, {
            "label": "团风县",
            "value": "421121"
        }, {
            "label": "红安县",
            "value": "421122"
        }, {
            "label": "罗田县",
            "value": "421123"
        }, {
            "label": "英山县",
            "value": "421124"
        }, {
            "label": "浠水县",
            "value": "421125"
        }, {
            "label": "蕲春县",
            "value": "421126"
        }, {
            "label": "黄梅县",
            "value": "421127"
        }, {
            "label": "麻城市",
            "value": "421181"
        }, {
            "label": "武穴市",
            "value": "421182"
        }],
        [{
            "label": "市辖区",
            "value": "421201"
        }, {
            "label": "咸安区",
            "value": "421202"
        }, {
            "label": "嘉鱼县",
            "value": "421221"
        }, {
            "label": "通城县",
            "value": "421222"
        }, {
            "label": "崇阳县",
            "value": "421223"
        }, {
            "label": "通山县",
            "value": "421224"
        }, {
            "label": "赤壁市",
            "value": "421281"
        }],
        [{
            "label": "市辖区",
            "value": "421301"
        }, {
            "label": "曾都区",
            "value": "421303"
        }, {
            "label": "随县",
            "value": "421321"
        }, {
            "label": "广水市",
            "value": "421381"
        }],
        [{
            "label": "市辖区",
            "value": "422801"
        }, {
            "label": "利川市",
            "value": "422802"
        }, {
            "label": "建始县",
            "value": "422822"
        }, {
            "label": "巴东县",
            "value": "422823"
        }, {
            "label": "宣恩县",
            "value": "422825"
        }, {
            "label": "咸丰县",
            "value": "422826"
        }, {
            "label": "来凤县",
            "value": "422827"
        }, {
            "label": "鹤峰县",
            "value": "422828"
        }],
        [{
            "label": "仙桃市",
            "value": "429004"
        }, {
            "label": "潜江市",
            "value": "429005"
        }, {
            "label": "天门市",
            "value": "429006"
        }, {
            "label": "神农架林区",
            "value": "429021"
        }]
    ],
    [
        [{
            "label": "市辖区",
            "value": "430101"
        }, {
            "label": "芙蓉区",
            "value": "430102"
        }, {
            "label": "天心区",
            "value": "430103"
        }, {
            "label": "岳麓区",
            "value": "430104"
        }, {
            "label": "开福区",
            "value": "430105"
        }, {
            "label": "雨花区",
            "value": "430111"
        }, {
            "label": "望城区",
            "value": "430112"
        }, {
            "label": "长沙县",
            "value": "430121"
        }, {
            "label": "宁乡县",
            "value": "430124"
        }, {
            "label": "浏阳市",
            "value": "430181"
        }],
        [{
            "label": "市辖区",
            "value": "430201"
        }, {
            "label": "荷塘区",
            "value": "430202"
        }, {
            "label": "芦淞区",
            "value": "430203"
        }, {
            "label": "石峰区",
            "value": "430204"
        }, {
            "label": "天元区",
            "value": "430211"
        }, {
            "label": "株洲县",
            "value": "430221"
        }, {
            "label": "攸县",
            "value": "430223"
        }, {
            "label": "茶陵县",
            "value": "430224"
        }, {
            "label": "炎陵县",
            "value": "430225"
        }, {
            "label": "醴陵市",
            "value": "430281"
        }],
        [{
            "label": "市辖区",
            "value": "430301"
        }, {
            "label": "雨湖区",
            "value": "430302"
        }, {
            "label": "岳塘区",
            "value": "430304"
        }, {
            "label": "湘潭县",
            "value": "430321"
        }, {
            "label": "湘乡市",
            "value": "430381"
        }, {
            "label": "韶山市",
            "value": "430382"
        }],
        [{
            "label": "市辖区",
            "value": "430401"
        }, {
            "label": "珠晖区",
            "value": "430405"
        }, {
            "label": "雁峰区",
            "value": "430406"
        }, {
            "label": "石鼓区",
            "value": "430407"
        }, {
            "label": "蒸湘区",
            "value": "430408"
        }, {
            "label": "南岳区",
            "value": "430412"
        }, {
            "label": "衡阳县",
            "value": "430421"
        }, {
            "label": "衡南县",
            "value": "430422"
        }, {
            "label": "衡山县",
            "value": "430423"
        }, {
            "label": "衡东县",
            "value": "430424"
        }, {
            "label": "祁东县",
            "value": "430426"
        }, {
            "label": "耒阳市",
            "value": "430481"
        }, {
            "label": "常宁市",
            "value": "430482"
        }],
        [{
            "label": "市辖区",
            "value": "430501"
        }, {
            "label": "双清区",
            "value": "430502"
        }, {
            "label": "大祥区",
            "value": "430503"
        }, {
            "label": "北塔区",
            "value": "430511"
        }, {
            "label": "邵东县",
            "value": "430521"
        }, {
            "label": "新邵县",
            "value": "430522"
        }, {
            "label": "邵阳县",
            "value": "430523"
        }, {
            "label": "隆回县",
            "value": "430524"
        }, {
            "label": "洞口县",
            "value": "430525"
        }, {
            "label": "绥宁县",
            "value": "430527"
        }, {
            "label": "新宁县",
            "value": "430528"
        }, {
            "label": "城步苗族自治县",
            "value": "430529"
        }, {
            "label": "武冈市",
            "value": "430581"
        }],
        [{
            "label": "市辖区",
            "value": "430601"
        }, {
            "label": "岳阳楼区",
            "value": "430602"
        }, {
            "label": "云溪区",
            "value": "430603"
        }, {
            "label": "君山区",
            "value": "430611"
        }, {
            "label": "岳阳县",
            "value": "430621"
        }, {
            "label": "华容县",
            "value": "430623"
        }, {
            "label": "湘阴县",
            "value": "430624"
        }, {
            "label": "平江县",
            "value": "430626"
        }, {
            "label": "汨罗市",
            "value": "430681"
        }, {
            "label": "临湘市",
            "value": "430682"
        }],
        [{
            "label": "市辖区",
            "value": "430701"
        }, {
            "label": "武陵区",
            "value": "430702"
        }, {
            "label": "鼎城区",
            "value": "430703"
        }, {
            "label": "安乡县",
            "value": "430721"
        }, {
            "label": "汉寿县",
            "value": "430722"
        }, {
            "label": "澧县",
            "value": "430723"
        }, {
            "label": "临澧县",
            "value": "430724"
        }, {
            "label": "桃源县",
            "value": "430725"
        }, {
            "label": "石门县",
            "value": "430726"
        }, {
            "label": "津市市",
            "value": "430781"
        }],
        [{
            "label": "市辖区",
            "value": "430801"
        }, {
            "label": "永定区",
            "value": "430802"
        }, {
            "label": "武陵源区",
            "value": "430811"
        }, {
            "label": "慈利县",
            "value": "430821"
        }, {
            "label": "桑植县",
            "value": "430822"
        }],
        [{
            "label": "市辖区",
            "value": "430901"
        }, {
            "label": "资阳区",
            "value": "430902"
        }, {
            "label": "赫山区",
            "value": "430903"
        }, {
            "label": "南县",
            "value": "430921"
        }, {
            "label": "桃江县",
            "value": "430922"
        }, {
            "label": "安化县",
            "value": "430923"
        }, {
            "label": "沅江市",
            "value": "430981"
        }],
        [{
            "label": "市辖区",
            "value": "431001"
        }, {
            "label": "北湖区",
            "value": "431002"
        }, {
            "label": "苏仙区",
            "value": "431003"
        }, {
            "label": "桂阳县",
            "value": "431021"
        }, {
            "label": "宜章县",
            "value": "431022"
        }, {
            "label": "永兴县",
            "value": "431023"
        }, {
            "label": "嘉禾县",
            "value": "431024"
        }, {
            "label": "临武县",
            "value": "431025"
        }, {
            "label": "汝城县",
            "value": "431026"
        }, {
            "label": "桂东县",
            "value": "431027"
        }, {
            "label": "安仁县",
            "value": "431028"
        }, {
            "label": "资兴市",
            "value": "431081"
        }],
        [{
            "label": "市辖区",
            "value": "431101"
        }, {
            "label": "零陵区",
            "value": "431102"
        }, {
            "label": "冷水滩区",
            "value": "431103"
        }, {
            "label": "祁阳县",
            "value": "431121"
        }, {
            "label": "东安县",
            "value": "431122"
        }, {
            "label": "双牌县",
            "value": "431123"
        }, {
            "label": "道县",
            "value": "431124"
        }, {
            "label": "江永县",
            "value": "431125"
        }, {
            "label": "宁远县",
            "value": "431126"
        }, {
            "label": "蓝山县",
            "value": "431127"
        }, {
            "label": "新田县",
            "value": "431128"
        }, {
            "label": "江华瑶族自治县",
            "value": "431129"
        }],
        [{
            "label": "市辖区",
            "value": "431201"
        }, {
            "label": "鹤城区",
            "value": "431202"
        }, {
            "label": "中方县",
            "value": "431221"
        }, {
            "label": "沅陵县",
            "value": "431222"
        }, {
            "label": "辰溪县",
            "value": "431223"
        }, {
            "label": "溆浦县",
            "value": "431224"
        }, {
            "label": "会同县",
            "value": "431225"
        }, {
            "label": "麻阳苗族自治县",
            "value": "431226"
        }, {
            "label": "新晃侗族自治县",
            "value": "431227"
        }, {
            "label": "芷江侗族自治县",
            "value": "431228"
        }, {
            "label": "靖州苗族侗族自治县",
            "value": "431229"
        }, {
            "label": "通道侗族自治县",
            "value": "431230"
        }, {
            "label": "洪江市",
            "value": "431281"
        }],
        [{
            "label": "市辖区",
            "value": "431301"
        }, {
            "label": "娄星区",
            "value": "431302"
        }, {
            "label": "双峰县",
            "value": "431321"
        }, {
            "label": "新化县",
            "value": "431322"
        }, {
            "label": "冷水江市",
            "value": "431381"
        }, {
            "label": "涟源市",
            "value": "431382"
        }],
        [{
            "label": "市辖区",
            "value": "433101"
        }, {
            "label": "泸溪县",
            "value": "433122"
        }, {
            "label": "凤凰县",
            "value": "433123"
        }, {
            "label": "花垣县",
            "value": "433124"
        }, {
            "label": "保靖县",
            "value": "433125"
        }, {
            "label": "古丈县",
            "value": "433126"
        }, {
            "label": "永顺县",
            "value": "433127"
        }, {
            "label": "龙山县",
            "value": "433130"
        }]
    ], {
        "0": [{
            "label": "市辖区",
            "value": "440101"
        }, {
            "label": "荔湾区",
            "value": "440103"
        }, {
            "label": "越秀区",
            "value": "440104"
        }, {
            "label": "海珠区",
            "value": "440105"
        }, {
            "label": "天河区",
            "value": "440106"
        }, {
            "label": "白云区",
            "value": "440111"
        }, {
            "label": "黄埔区",
            "value": "440112"
        }, {
            "label": "番禺区",
            "value": "440113"
        }, {
            "label": "花都区",
            "value": "440114"
        }, {
            "label": "南沙区",
            "value": "440115"
        }, {
            "label": "从化区",
            "value": "440117"
        }, {
            "label": "增城区",
            "value": "440118"
        }, {
            "label": "萝岗区",
            "value": "920003"
        }],
        "1": [{
            "label": "市辖区",
            "value": "440201"
        }, {
            "label": "武江区",
            "value": "440203"
        }, {
            "label": "浈江区",
            "value": "440204"
        }, {
            "label": "曲江区",
            "value": "440205"
        }, {
            "label": "始兴县",
            "value": "440222"
        }, {
            "label": "仁化县",
            "value": "440224"
        }, {
            "label": "翁源县",
            "value": "440229"
        }, {
            "label": "乳源瑶族自治县",
            "value": "440232"
        }, {
            "label": "新丰县",
            "value": "440233"
        }, {
            "label": "乐昌市",
            "value": "440281"
        }, {
            "label": "南雄市",
            "value": "440282"
        }],
        "2": [{
            "label": "市辖区",
            "value": "440301"
        }, {
            "label": "罗湖区",
            "value": "440303"
        }, {
            "label": "福田区",
            "value": "440304"
        }, {
            "label": "南山区",
            "value": "440305"
        }, {
            "label": "宝安区",
            "value": "440306"
        }, {
            "label": "龙岗区",
            "value": "440307"
        }, {
            "label": "盐田区",
            "value": "440308"
        }],
        "3": [{
            "label": "市辖区",
            "value": "440401"
        }, {
            "label": "香洲区",
            "value": "440402"
        }, {
            "label": "斗门区",
            "value": "440403"
        }, {
            "label": "金湾区",
            "value": "440404"
        }],
        "4": [{
            "label": "市辖区",
            "value": "440501"
        }, {
            "label": "龙湖区",
            "value": "440507"
        }, {
            "label": "金平区",
            "value": "440511"
        }, {
            "label": "濠江区",
            "value": "440512"
        }, {
            "label": "潮阳区",
            "value": "440513"
        }, {
            "label": "潮南区",
            "value": "440514"
        }, {
            "label": "澄海区",
            "value": "440515"
        }, {
            "label": "南澳县",
            "value": "440523"
        }],
        "5": [{
            "label": "市辖区",
            "value": "440601"
        }, {
            "label": "禅城区",
            "value": "440604"
        }, {
            "label": "南海区",
            "value": "440605"
        }, {
            "label": "顺德区",
            "value": "440606"
        }, {
            "label": "三水区",
            "value": "440607"
        }, {
            "label": "高明区",
            "value": "440608"
        }],
        "6": [{
            "label": "市辖区",
            "value": "440701"
        }, {
            "label": "蓬江区",
            "value": "440703"
        }, {
            "label": "江海区",
            "value": "440704"
        }, {
            "label": "新会区",
            "value": "440705"
        }, {
            "label": "台山市",
            "value": "440781"
        }, {
            "label": "开平市",
            "value": "440783"
        }, {
            "label": "鹤山市",
            "value": "440784"
        }, {
            "label": "恩平市",
            "value": "440785"
        }],
        "7": [{
            "label": "市辖区",
            "value": "440801"
        }, {
            "label": "赤坎区",
            "value": "440802"
        }, {
            "label": "霞山区",
            "value": "440803"
        }, {
            "label": "坡头区",
            "value": "440804"
        }, {
            "label": "麻章区",
            "value": "440811"
        }, {
            "label": "遂溪县",
            "value": "440823"
        }, {
            "label": "徐闻县",
            "value": "440825"
        }, {
            "label": "廉江市",
            "value": "440881"
        }, {
            "label": "雷州市",
            "value": "440882"
        }, {
            "label": "吴川市",
            "value": "440883"
        }],
        "8": [{
            "label": "市辖区",
            "value": "440901"
        }, {
            "label": "茂南区",
            "value": "440902"
        }, {
            "label": "电白区",
            "value": "440904"
        }, {
            "label": "高州市",
            "value": "440981"
        }, {
            "label": "化州市",
            "value": "440982"
        }, {
            "label": "信宜市",
            "value": "440983"
        }],
        "9": [{
            "label": "市辖区",
            "value": "441201"
        }, {
            "label": "端州区",
            "value": "441202"
        }, {
            "label": "鼎湖区",
            "value": "441203"
        }, {
            "label": "高要区",
            "value": "441204"
        }, {
            "label": "广宁县",
            "value": "441223"
        }, {
            "label": "怀集县",
            "value": "441224"
        }, {
            "label": "封开县",
            "value": "441225"
        }, {
            "label": "德庆县",
            "value": "441226"
        }, {
            "label": "四会市",
            "value": "441284"
        }],
        "10": [{
            "label": "市辖区",
            "value": "441301"
        }, {
            "label": "惠城区",
            "value": "441302"
        }, {
            "label": "惠阳区",
            "value": "441303"
        }, {
            "label": "博罗县",
            "value": "441322"
        }, {
            "label": "惠东县",
            "value": "441323"
        }, {
            "label": "龙门县",
            "value": "441324"
        }],
        "11": [{
            "label": "市辖区",
            "value": "441401"
        }, {
            "label": "梅江区",
            "value": "441402"
        }, {
            "label": "梅县区",
            "value": "441403"
        }, {
            "label": "大埔县",
            "value": "441422"
        }, {
            "label": "丰顺县",
            "value": "441423"
        }, {
            "label": "五华县",
            "value": "441424"
        }, {
            "label": "平远县",
            "value": "441426"
        }, {
            "label": "蕉岭县",
            "value": "441427"
        }, {
            "label": "兴宁市",
            "value": "441481"
        }],
        "12": [{
            "label": "市辖区",
            "value": "441501"
        }, {
            "label": "城区",
            "value": "441502"
        }, {
            "label": "海丰县",
            "value": "441521"
        }, {
            "label": "陆河县",
            "value": "441523"
        }, {
            "label": "陆丰市",
            "value": "441581"
        }],
        "13": [{
            "label": "市辖区",
            "value": "441601"
        }, {
            "label": "源城区",
            "value": "441602"
        }, {
            "label": "紫金县",
            "value": "441621"
        }, {
            "label": "龙川县",
            "value": "441622"
        }, {
            "label": "连平县",
            "value": "441623"
        }, {
            "label": "和平县",
            "value": "441624"
        }, {
            "label": "东源县",
            "value": "441625"
        }],
        "14": [{
            "label": "市辖区",
            "value": "441701"
        }, {
            "label": "江城区",
            "value": "441702"
        }, {
            "label": "阳东区",
            "value": "441704"
        }, {
            "label": "阳西县",
            "value": "441721"
        }, {
            "label": "阳春市",
            "value": "441781"
        }],
        "15": [{
            "label": "市辖区",
            "value": "441801"
        }, {
            "label": "清城区",
            "value": "441802"
        }, {
            "label": "清新区",
            "value": "441803"
        }, {
            "label": "佛冈县",
            "value": "441821"
        }, {
            "label": "阳山县",
            "value": "441823"
        }, {
            "label": "连山壮族瑶族自治县",
            "value": "441825"
        }, {
            "label": "连南瑶族自治县",
            "value": "441826"
        }, {
            "label": "英德市",
            "value": "441881"
        }, {
            "label": "连州市",
            "value": "441882"
        }],
        "18": [{
            "label": "市辖区",
            "value": "445101"
        }, {
            "label": "湘桥区",
            "value": "445102"
        }, {
            "label": "潮安区",
            "value": "445103"
        }, {
            "label": "饶平县",
            "value": "445122"
        }],
        "19": [{
            "label": "市辖区",
            "value": "445201"
        }, {
            "label": "榕城区",
            "value": "445202"
        }, {
            "label": "揭东区",
            "value": "445203"
        }, {
            "label": "揭西县",
            "value": "445222"
        }, {
            "label": "惠来县",
            "value": "445224"
        }, {
            "label": "普宁市",
            "value": "445281"
        }],
        "20": [{
            "label": "市辖区",
            "value": "445301"
        }, {
            "label": "云城区",
            "value": "445302"
        }, {
            "label": "云安区",
            "value": "445303"
        }, {
            "label": "新兴县",
            "value": "445321"
        }, {
            "label": "郁南县",
            "value": "445322"
        }, {
            "label": "罗定市",
            "value": "445381"
        }]
    },
    [
        [{
            "label": "市辖区",
            "value": "450101"
        }, {
            "label": "兴宁区",
            "value": "450102"
        }, {
            "label": "青秀区",
            "value": "450103"
        }, {
            "label": "江南区",
            "value": "450105"
        }, {
            "label": "西乡塘区",
            "value": "450107"
        }, {
            "label": "良庆区",
            "value": "450108"
        }, {
            "label": "邕宁区",
            "value": "450109"
        }, {
            "label": "武鸣区",
            "value": "450110"
        }, {
            "label": "隆安县",
            "value": "450123"
        }, {
            "label": "马山县",
            "value": "450124"
        }, {
            "label": "上林县",
            "value": "450125"
        }, {
            "label": "宾阳县",
            "value": "450126"
        }, {
            "label": "横县",
            "value": "450127"
        }],
        [{
            "label": "市辖区",
            "value": "450201"
        }, {
            "label": "城中区",
            "value": "450202"
        }, {
            "label": "鱼峰区",
            "value": "450203"
        }, {
            "label": "柳南区",
            "value": "450204"
        }, {
            "label": "柳北区",
            "value": "450205"
        }, {
            "label": "柳江区",
            "value": "450206"
        }, {
            "label": "柳城县",
            "value": "450222"
        }, {
            "label": "鹿寨县",
            "value": "450223"
        }, {
            "label": "融安县",
            "value": "450224"
        }, {
            "label": "融水苗族自治县",
            "value": "450225"
        }, {
            "label": "三江侗族自治县",
            "value": "450226"
        }],
        [{
            "label": "市辖区",
            "value": "450301"
        }, {
            "label": "秀峰区",
            "value": "450302"
        }, {
            "label": "叠彩区",
            "value": "450303"
        }, {
            "label": "象山区",
            "value": "450304"
        }, {
            "label": "七星区",
            "value": "450305"
        }, {
            "label": "雁山区",
            "value": "450311"
        }, {
            "label": "临桂区",
            "value": "450312"
        }, {
            "label": "阳朔县",
            "value": "450321"
        }, {
            "label": "灵川县",
            "value": "450323"
        }, {
            "label": "全州县",
            "value": "450324"
        }, {
            "label": "兴安县",
            "value": "450325"
        }, {
            "label": "永福县",
            "value": "450326"
        }, {
            "label": "灌阳县",
            "value": "450327"
        }, {
            "label": "龙胜各族自治县",
            "value": "450328"
        }, {
            "label": "资源县",
            "value": "450329"
        }, {
            "label": "平乐县",
            "value": "450330"
        }, {
            "label": "荔浦县",
            "value": "450331"
        }, {
            "label": "恭城瑶族自治县",
            "value": "450332"
        }],
        [{
            "label": "市辖区",
            "value": "450401"
        }, {
            "label": "万秀区",
            "value": "450403"
        }, {
            "label": "长洲区",
            "value": "450405"
        }, {
            "label": "龙圩区",
            "value": "450406"
        }, {
            "label": "苍梧县",
            "value": "450421"
        }, {
            "label": "藤县",
            "value": "450422"
        }, {
            "label": "蒙山县",
            "value": "450423"
        }, {
            "label": "岑溪市",
            "value": "450481"
        }],
        [{
            "label": "市辖区",
            "value": "450501"
        }, {
            "label": "海城区",
            "value": "450502"
        }, {
            "label": "银海区",
            "value": "450503"
        }, {
            "label": "铁山港区",
            "value": "450512"
        }, {
            "label": "合浦县",
            "value": "450521"
        }],
        [{
            "label": "市辖区",
            "value": "450601"
        }, {
            "label": "港口区",
            "value": "450602"
        }, {
            "label": "防城区",
            "value": "450603"
        }, {
            "label": "上思县",
            "value": "450621"
        }, {
            "label": "东兴市",
            "value": "450681"
        }],
        [{
            "label": "市辖区",
            "value": "450701"
        }, {
            "label": "钦南区",
            "value": "450702"
        }, {
            "label": "钦北区",
            "value": "450703"
        }, {
            "label": "灵山县",
            "value": "450721"
        }, {
            "label": "浦北县",
            "value": "450722"
        }],
        [{
            "label": "市辖区",
            "value": "450801"
        }, {
            "label": "港北区",
            "value": "450802"
        }, {
            "label": "港南区",
            "value": "450803"
        }, {
            "label": "覃塘区",
            "value": "450804"
        }, {
            "label": "平南县",
            "value": "450821"
        }, {
            "label": "桂平市",
            "value": "450881"
        }],
        [{
            "label": "市辖区",
            "value": "450901"
        }, {
            "label": "玉州区",
            "value": "450902"
        }, {
            "label": "福绵区",
            "value": "450903"
        }, {
            "label": "容县",
            "value": "450921"
        }, {
            "label": "陆川县",
            "value": "450922"
        }, {
            "label": "博白县",
            "value": "450923"
        }, {
            "label": "兴业县",
            "value": "450924"
        }, {
            "label": "北流市",
            "value": "450981"
        }],
        [{
            "label": "市辖区",
            "value": "451001"
        }, {
            "label": "右江区",
            "value": "451002"
        }, {
            "label": "田阳县",
            "value": "451021"
        }, {
            "label": "田东县",
            "value": "451022"
        }, {
            "label": "平果县",
            "value": "451023"
        }, {
            "label": "德保县",
            "value": "451024"
        }, {
            "label": "那坡县",
            "value": "451026"
        }, {
            "label": "凌云县",
            "value": "451027"
        }, {
            "label": "乐业县",
            "value": "451028"
        }, {
            "label": "田林县",
            "value": "451029"
        }, {
            "label": "西林县",
            "value": "451030"
        }, {
            "label": "隆林各族自治县",
            "value": "451031"
        }, {
            "label": "靖西市",
            "value": "451081"
        }],
        [{
            "label": "市辖区",
            "value": "451101"
        }, {
            "label": "八步区",
            "value": "451102"
        }, {
            "label": "平桂区",
            "value": "451103"
        }, {
            "label": "昭平县",
            "value": "451121"
        }, {
            "label": "钟山县",
            "value": "451122"
        }, {
            "label": "富川瑶族自治县",
            "value": "451123"
        }],
        [{
            "label": "市辖区",
            "value": "451201"
        }, {
            "label": "金城江区",
            "value": "451202"
        }, {
            "label": "南丹县",
            "value": "451221"
        }, {
            "label": "天峨县",
            "value": "451222"
        }, {
            "label": "凤山县",
            "value": "451223"
        }, {
            "label": "东兰县",
            "value": "451224"
        }, {
            "label": "罗城仫佬族自治县",
            "value": "451225"
        }, {
            "label": "环江毛南族自治县",
            "value": "451226"
        }, {
            "label": "巴马瑶族自治县",
            "value": "451227"
        }, {
            "label": "都安瑶族自治县",
            "value": "451228"
        }, {
            "label": "大化瑶族自治县",
            "value": "451229"
        }, {
            "label": "宜州市",
            "value": "451281"
        }],
        [{
            "label": "市辖区",
            "value": "451301"
        }, {
            "label": "兴宾区",
            "value": "451302"
        }, {
            "label": "忻城县",
            "value": "451321"
        }, {
            "label": "象州县",
            "value": "451322"
        }, {
            "label": "武宣县",
            "value": "451323"
        }, {
            "label": "金秀瑶族自治县",
            "value": "451324"
        }, {
            "label": "合山市",
            "value": "451381"
        }],
        [{
            "label": "市辖区",
            "value": "451401"
        }, {
            "label": "江州区",
            "value": "451402"
        }, {
            "label": "扶绥县",
            "value": "451421"
        }, {
            "label": "宁明县",
            "value": "451422"
        }, {
            "label": "龙州县",
            "value": "451423"
        }, {
            "label": "大新县",
            "value": "451424"
        }, {
            "label": "天等县",
            "value": "451425"
        }, {
            "label": "凭祥市",
            "value": "451481"
        }]
    ], {
        "0": [{
            "label": "市辖区",
            "value": "460101"
        }, {
            "label": "秀英区",
            "value": "460105"
        }, {
            "label": "龙华区",
            "value": "460106"
        }, {
            "label": "琼山区",
            "value": "460107"
        }, {
            "label": "美兰区",
            "value": "460108"
        }],
        "1": [{
            "label": "市辖区",
            "value": "460201"
        }, {
            "label": "海棠区",
            "value": "460202"
        }, {
            "label": "吉阳区",
            "value": "460203"
        }, {
            "label": "天涯区",
            "value": "460204"
        }, {
            "label": "崖州区",
            "value": "460205"
        }],
        "4": [{
            "label": "市辖区",
            "value": "469001"
        }, {
            "label": "琼海市",
            "value": "469002"
        }, {
            "label": "文昌市",
            "value": "469005"
        }, {
            "label": "万宁市",
            "value": "469006"
        }, {
            "label": "东方市",
            "value": "469007"
        }, {
            "label": "定安县",
            "value": "469021"
        }, {
            "label": "屯昌县",
            "value": "469022"
        }, {
            "label": "澄迈县",
            "value": "469023"
        }, {
            "label": "临高县",
            "value": "469024"
        }, {
            "label": "白沙黎族自治县",
            "value": "469025"
        }, {
            "label": "昌江黎族自治县",
            "value": "469026"
        }, {
            "label": "乐东黎族自治县",
            "value": "469027"
        }, {
            "label": "陵水黎族自治县",
            "value": "469028"
        }, {
            "label": "保亭黎族苗族自治县",
            "value": "469029"
        }, {
            "label": "琼中黎族苗族自治县",
            "value": "469030"
        }]
    },
    [
        [{
            "label": "万州区",
            "value": "500101"
        }, {
            "label": "涪陵区",
            "value": "500102"
        }, {
            "label": "渝中区",
            "value": "500103"
        }, {
            "label": "大渡口区",
            "value": "500104"
        }, {
            "label": "江北区",
            "value": "500105"
        }, {
            "label": "沙坪坝区",
            "value": "500106"
        }, {
            "label": "九龙坡区",
            "value": "500107"
        }, {
            "label": "南岸区",
            "value": "500108"
        }, {
            "label": "北碚区",
            "value": "500109"
        }, {
            "label": "綦江区",
            "value": "500110"
        }, {
            "label": "大足区",
            "value": "500111"
        }, {
            "label": "渝北区",
            "value": "500112"
        }, {
            "label": "巴南区",
            "value": "500113"
        }, {
            "label": "黔江区",
            "value": "500114"
        }, {
            "label": "长寿区",
            "value": "500115"
        }, {
            "label": "江津区",
            "value": "500116"
        }, {
            "label": "合川区",
            "value": "500117"
        }, {
            "label": "永川区",
            "value": "500118"
        }, {
            "label": "南川区",
            "value": "500119"
        }, {
            "label": "璧山区",
            "value": "500120"
        }, {
            "label": "铜梁区",
            "value": "500151"
        }, {
            "label": "潼南区",
            "value": "500152"
        }, {
            "label": "荣昌区",
            "value": "500153"
        }, {
            "label": "开州区",
            "value": "500154"
        }],
        [{
            "label": "梁平县",
            "value": "500228"
        }, {
            "label": "城口县",
            "value": "500229"
        }, {
            "label": "丰都县",
            "value": "500230"
        }, {
            "label": "垫江县",
            "value": "500231"
        }, {
            "label": "武隆县",
            "value": "500232"
        }, {
            "label": "忠县",
            "value": "500233"
        }, {
            "label": "云阳县",
            "value": "500235"
        }, {
            "label": "奉节县",
            "value": "500236"
        }, {
            "label": "巫山县",
            "value": "500237"
        }, {
            "label": "巫溪县",
            "value": "500238"
        }, {
            "label": "石柱土家族自治县",
            "value": "500240"
        }, {
            "label": "秀山土家族苗族自治县",
            "value": "500241"
        }, {
            "label": "酉阳土家族苗族自治县",
            "value": "500242"
        }, {
            "label": "彭水苗族土家族自治县",
            "value": "500243"
        }, {
            "label": "静海县",
            "value": "920000"
        }]
    ],
    [
        [{
            "label": "市辖区",
            "value": "510101"
        }, {
            "label": "锦江区",
            "value": "510104"
        }, {
            "label": "青羊区",
            "value": "510105"
        }, {
            "label": "金牛区",
            "value": "510106"
        }, {
            "label": "武侯区",
            "value": "510107"
        }, {
            "label": "成华区",
            "value": "510108"
        }, {
            "label": "龙泉驿区",
            "value": "510112"
        }, {
            "label": "青白江区",
            "value": "510113"
        }, {
            "label": "新都区",
            "value": "510114"
        }, {
            "label": "温江区",
            "value": "510115"
        }, {
            "label": "双流区",
            "value": "510116"
        }, {
            "label": "金堂县",
            "value": "510121"
        }, {
            "label": "郫县",
            "value": "510124"
        }, {
            "label": "大邑县",
            "value": "510129"
        }, {
            "label": "蒲江县",
            "value": "510131"
        }, {
            "label": "新津县",
            "value": "510132"
        }, {
            "label": "都江堰市",
            "value": "510181"
        }, {
            "label": "彭州市",
            "value": "510182"
        }, {
            "label": "邛崃市",
            "value": "510183"
        }, {
            "label": "崇州市",
            "value": "510184"
        }, {
            "label": "简阳市",
            "value": "510185"
        }],
        [{
            "label": "市辖区",
            "value": "510301"
        }, {
            "label": "自流井区",
            "value": "510302"
        }, {
            "label": "贡井区",
            "value": "510303"
        }, {
            "label": "大安区",
            "value": "510304"
        }, {
            "label": "沿滩区",
            "value": "510311"
        }, {
            "label": "荣县",
            "value": "510321"
        }, {
            "label": "富顺县",
            "value": "510322"
        }],
        [{
            "label": "市辖区",
            "value": "510401"
        }, {
            "label": "东区",
            "value": "510402"
        }, {
            "label": "西区",
            "value": "510403"
        }, {
            "label": "仁和区",
            "value": "510411"
        }, {
            "label": "米易县",
            "value": "510421"
        }, {
            "label": "盐边县",
            "value": "510422"
        }],
        [{
            "label": "市辖区",
            "value": "510501"
        }, {
            "label": "江阳区",
            "value": "510502"
        }, {
            "label": "纳溪区",
            "value": "510503"
        }, {
            "label": "龙马潭区",
            "value": "510504"
        }, {
            "label": "泸县",
            "value": "510521"
        }, {
            "label": "合江县",
            "value": "510522"
        }, {
            "label": "叙永县",
            "value": "510524"
        }, {
            "label": "古蔺县",
            "value": "510525"
        }],
        [{
            "label": "市辖区",
            "value": "510601"
        }, {
            "label": "旌阳区",
            "value": "510603"
        }, {
            "label": "中江县",
            "value": "510623"
        }, {
            "label": "罗江县",
            "value": "510626"
        }, {
            "label": "广汉市",
            "value": "510681"
        }, {
            "label": "什邡市",
            "value": "510682"
        }, {
            "label": "绵竹市",
            "value": "510683"
        }],
        [{
            "label": "市辖区",
            "value": "510701"
        }, {
            "label": "涪城区",
            "value": "510703"
        }, {
            "label": "游仙区",
            "value": "510704"
        }, {
            "label": "安州区",
            "value": "510705"
        }, {
            "label": "三台县",
            "value": "510722"
        }, {
            "label": "盐亭县",
            "value": "510723"
        }, {
            "label": "梓潼县",
            "value": "510725"
        }, {
            "label": "北川羌族自治县",
            "value": "510726"
        }, {
            "label": "平武县",
            "value": "510727"
        }, {
            "label": "江油市",
            "value": "510781"
        }],
        [{
            "label": "市辖区",
            "value": "510801"
        }, {
            "label": "利州区",
            "value": "510802"
        }, {
            "label": "昭化区",
            "value": "510811"
        }, {
            "label": "朝天区",
            "value": "510812"
        }, {
            "label": "旺苍县",
            "value": "510821"
        }, {
            "label": "青川县",
            "value": "510822"
        }, {
            "label": "剑阁县",
            "value": "510823"
        }, {
            "label": "苍溪县",
            "value": "510824"
        }],
        [{
            "label": "市辖区",
            "value": "510901"
        }, {
            "label": "船山区",
            "value": "510903"
        }, {
            "label": "安居区",
            "value": "510904"
        }, {
            "label": "蓬溪县",
            "value": "510921"
        }, {
            "label": "射洪县",
            "value": "510922"
        }, {
            "label": "大英县",
            "value": "510923"
        }],
        [{
            "label": "市辖区",
            "value": "511001"
        }, {
            "label": "市中区",
            "value": "511002"
        }, {
            "label": "东兴区",
            "value": "511011"
        }, {
            "label": "威远县",
            "value": "511024"
        }, {
            "label": "资中县",
            "value": "511025"
        }, {
            "label": "隆昌县",
            "value": "511028"
        }],
        [{
            "label": "市辖区",
            "value": "511101"
        }, {
            "label": "市中区",
            "value": "511102"
        }, {
            "label": "沙湾区",
            "value": "511111"
        }, {
            "label": "五通桥区",
            "value": "511112"
        }, {
            "label": "金口河区",
            "value": "511113"
        }, {
            "label": "犍为县",
            "value": "511123"
        }, {
            "label": "井研县",
            "value": "511124"
        }, {
            "label": "夹江县",
            "value": "511126"
        }, {
            "label": "沐川县",
            "value": "511129"
        }, {
            "label": "峨边彝族自治县",
            "value": "511132"
        }, {
            "label": "马边彝族自治县",
            "value": "511133"
        }, {
            "label": "峨眉山市",
            "value": "511181"
        }],
        [{
            "label": "市辖区",
            "value": "511301"
        }, {
            "label": "顺庆区",
            "value": "511302"
        }, {
            "label": "高坪区",
            "value": "511303"
        }, {
            "label": "嘉陵区",
            "value": "511304"
        }, {
            "label": "南部县",
            "value": "511321"
        }, {
            "label": "营山县",
            "value": "511322"
        }, {
            "label": "蓬安县",
            "value": "511323"
        }, {
            "label": "仪陇县",
            "value": "511324"
        }, {
            "label": "西充县",
            "value": "511325"
        }, {
            "label": "阆中市",
            "value": "511381"
        }],
        [{
            "label": "市辖区",
            "value": "511401"
        }, {
            "label": "东坡区",
            "value": "511402"
        }, {
            "label": "彭山区",
            "value": "511403"
        }, {
            "label": "仁寿县",
            "value": "511421"
        }, {
            "label": "洪雅县",
            "value": "511423"
        }, {
            "label": "丹棱县",
            "value": "511424"
        }, {
            "label": "青神县",
            "value": "511425"
        }],
        [{
            "label": "市辖区",
            "value": "511501"
        }, {
            "label": "翠屏区",
            "value": "511502"
        }, {
            "label": "南溪区",
            "value": "511503"
        }, {
            "label": "宜宾县",
            "value": "511521"
        }, {
            "label": "江安县",
            "value": "511523"
        }, {
            "label": "长宁县",
            "value": "511524"
        }, {
            "label": "高县",
            "value": "511525"
        }, {
            "label": "珙县",
            "value": "511526"
        }, {
            "label": "筠连县",
            "value": "511527"
        }, {
            "label": "兴文县",
            "value": "511528"
        }, {
            "label": "屏山县",
            "value": "511529"
        }],
        [{
            "label": "市辖区",
            "value": "511601"
        }, {
            "label": "广安区",
            "value": "511602"
        }, {
            "label": "前锋区",
            "value": "511603"
        }, {
            "label": "岳池县",
            "value": "511621"
        }, {
            "label": "武胜县",
            "value": "511622"
        }, {
            "label": "邻水县",
            "value": "511623"
        }, {
            "label": "华蓥市",
            "value": "511681"
        }],
        [{
            "label": "市辖区",
            "value": "511701"
        }, {
            "label": "通川区",
            "value": "511702"
        }, {
            "label": "达川区",
            "value": "511703"
        }, {
            "label": "宣汉县",
            "value": "511722"
        }, {
            "label": "开江县",
            "value": "511723"
        }, {
            "label": "大竹县",
            "value": "511724"
        }, {
            "label": "渠县",
            "value": "511725"
        }, {
            "label": "万源市",
            "value": "511781"
        }],
        [{
            "label": "市辖区",
            "value": "511801"
        }, {
            "label": "雨城区",
            "value": "511802"
        }, {
            "label": "名山区",
            "value": "511803"
        }, {
            "label": "荥经县",
            "value": "511822"
        }, {
            "label": "汉源县",
            "value": "511823"
        }, {
            "label": "石棉县",
            "value": "511824"
        }, {
            "label": "天全县",
            "value": "511825"
        }, {
            "label": "芦山县",
            "value": "511826"
        }, {
            "label": "宝兴县",
            "value": "511827"
        }],
        [{
            "label": "市辖区",
            "value": "511901"
        }, {
            "label": "巴州区",
            "value": "511902"
        }, {
            "label": "恩阳区",
            "value": "511903"
        }, {
            "label": "通江县",
            "value": "511921"
        }, {
            "label": "南江县",
            "value": "511922"
        }, {
            "label": "平昌县",
            "value": "511923"
        }],
        [{
            "label": "市辖区",
            "value": "512001"
        }, {
            "label": "雁江区",
            "value": "512002"
        }, {
            "label": "安岳县",
            "value": "512021"
        }, {
            "label": "乐至县",
            "value": "512022"
        }],
        [{
            "label": "市辖区",
            "value": "513201"
        }, {
            "label": "汶川县",
            "value": "513221"
        }, {
            "label": "理县",
            "value": "513222"
        }, {
            "label": "茂县",
            "value": "513223"
        }, {
            "label": "松潘县",
            "value": "513224"
        }, {
            "label": "九寨沟县",
            "value": "513225"
        }, {
            "label": "金川县",
            "value": "513226"
        }, {
            "label": "小金县",
            "value": "513227"
        }, {
            "label": "黑水县",
            "value": "513228"
        }, {
            "label": "壤塘县",
            "value": "513230"
        }, {
            "label": "阿坝县",
            "value": "513231"
        }, {
            "label": "若尔盖县",
            "value": "513232"
        }, {
            "label": "红原县",
            "value": "513233"
        }],
        [{
            "label": "市辖区",
            "value": "513301"
        }, {
            "label": "泸定县",
            "value": "513322"
        }, {
            "label": "丹巴县",
            "value": "513323"
        }, {
            "label": "九龙县",
            "value": "513324"
        }, {
            "label": "雅江县",
            "value": "513325"
        }, {
            "label": "道孚县",
            "value": "513326"
        }, {
            "label": "炉霍县",
            "value": "513327"
        }, {
            "label": "甘孜县",
            "value": "513328"
        }, {
            "label": "新龙县",
            "value": "513329"
        }, {
            "label": "德格县",
            "value": "513330"
        }, {
            "label": "白玉县",
            "value": "513331"
        }, {
            "label": "石渠县",
            "value": "513332"
        }, {
            "label": "色达县",
            "value": "513333"
        }, {
            "label": "理塘县",
            "value": "513334"
        }, {
            "label": "巴塘县",
            "value": "513335"
        }, {
            "label": "乡城县",
            "value": "513336"
        }, {
            "label": "稻城县",
            "value": "513337"
        }, {
            "label": "得荣县",
            "value": "513338"
        }],
        [{
            "label": "市辖区",
            "value": "513401"
        }, {
            "label": "木里藏族自治县",
            "value": "513422"
        }, {
            "label": "盐源县",
            "value": "513423"
        }, {
            "label": "德昌县",
            "value": "513424"
        }, {
            "label": "会理县",
            "value": "513425"
        }, {
            "label": "会东县",
            "value": "513426"
        }, {
            "label": "宁南县",
            "value": "513427"
        }, {
            "label": "普格县",
            "value": "513428"
        }, {
            "label": "布拖县",
            "value": "513429"
        }, {
            "label": "金阳县",
            "value": "513430"
        }, {
            "label": "昭觉县",
            "value": "513431"
        }, {
            "label": "喜德县",
            "value": "513432"
        }, {
            "label": "冕宁县",
            "value": "513433"
        }, {
            "label": "越西县",
            "value": "513434"
        }, {
            "label": "甘洛县",
            "value": "513435"
        }, {
            "label": "美姑县",
            "value": "513436"
        }, {
            "label": "雷波县",
            "value": "513437"
        }]
    ],
    [
        [{
            "label": "市辖区",
            "value": "520101"
        }, {
            "label": "南明区",
            "value": "520102"
        }, {
            "label": "云岩区",
            "value": "520103"
        }, {
            "label": "花溪区",
            "value": "520111"
        }, {
            "label": "乌当区",
            "value": "520112"
        }, {
            "label": "白云区",
            "value": "520113"
        }, {
            "label": "观山湖区",
            "value": "520115"
        }, {
            "label": "开阳县",
            "value": "520121"
        }, {
            "label": "息烽县",
            "value": "520122"
        }, {
            "label": "修文县",
            "value": "520123"
        }, {
            "label": "清镇市",
            "value": "520181"
        }],
        [{
            "label": "钟山区",
            "value": "520201"
        }, {
            "label": "六枝特区",
            "value": "520203"
        }, {
            "label": "水城县",
            "value": "520221"
        }, {
            "label": "盘县",
            "value": "520222"
        }],
        [{
            "label": "市辖区",
            "value": "520301"
        }, {
            "label": "红花岗区",
            "value": "520302"
        }, {
            "label": "汇川区",
            "value": "520303"
        }, {
            "label": "播州区",
            "value": "520304"
        }, {
            "label": "桐梓县",
            "value": "520322"
        }, {
            "label": "绥阳县",
            "value": "520323"
        }, {
            "label": "正安县",
            "value": "520324"
        }, {
            "label": "道真仡佬族苗族自治县",
            "value": "520325"
        }, {
            "label": "务川仡佬族苗族自治县",
            "value": "520326"
        }, {
            "label": "凤冈县",
            "value": "520327"
        }, {
            "label": "湄潭县",
            "value": "520328"
        }, {
            "label": "余庆县",
            "value": "520329"
        }, {
            "label": "习水县",
            "value": "520330"
        }, {
            "label": "赤水市",
            "value": "520381"
        }, {
            "label": "仁怀市",
            "value": "520382"
        }],
        [{
            "label": "市辖区",
            "value": "520401"
        }, {
            "label": "西秀区",
            "value": "520402"
        }, {
            "label": "平坝区",
            "value": "520403"
        }, {
            "label": "普定县",
            "value": "520422"
        }, {
            "label": "镇宁布依族苗族自治县",
            "value": "520423"
        }, {
            "label": "关岭布依族苗族自治县",
            "value": "520424"
        }, {
            "label": "紫云苗族布依族自治县",
            "value": "520425"
        }],
        [{
            "label": "市辖区",
            "value": "520501"
        }, {
            "label": "七星关区",
            "value": "520502"
        }, {
            "label": "大方县",
            "value": "520521"
        }, {
            "label": "黔西县",
            "value": "520522"
        }, {
            "label": "金沙县",
            "value": "520523"
        }, {
            "label": "织金县",
            "value": "520524"
        }, {
            "label": "纳雍县",
            "value": "520525"
        }, {
            "label": "威宁彝族回族苗族自治县",
            "value": "520526"
        }, {
            "label": "赫章县",
            "value": "520527"
        }],
        [{
            "label": "市辖区",
            "value": "520601"
        }, {
            "label": "碧江区",
            "value": "520602"
        }, {
            "label": "万山区",
            "value": "520603"
        }, {
            "label": "江口县",
            "value": "520621"
        }, {
            "label": "玉屏侗族自治县",
            "value": "520622"
        }, {
            "label": "石阡县",
            "value": "520623"
        }, {
            "label": "思南县",
            "value": "520624"
        }, {
            "label": "印江土家族苗族自治县",
            "value": "520625"
        }, {
            "label": "德江县",
            "value": "520626"
        }, {
            "label": "沿河土家族自治县",
            "value": "520627"
        }, {
            "label": "松桃苗族自治县",
            "value": "520628"
        }],
        [{
            "label": "市辖区",
            "value": "522301"
        }, {
            "label": "兴仁县",
            "value": "522322"
        }, {
            "label": "普安县",
            "value": "522323"
        }, {
            "label": "晴隆县",
            "value": "522324"
        }, {
            "label": "贞丰县",
            "value": "522325"
        }, {
            "label": "望谟县",
            "value": "522326"
        }, {
            "label": "册亨县",
            "value": "522327"
        }, {
            "label": "安龙县",
            "value": "522328"
        }],
        [{
            "label": "市辖区",
            "value": "522601"
        }, {
            "label": "黄平县",
            "value": "522622"
        }, {
            "label": "施秉县",
            "value": "522623"
        }, {
            "label": "三穗县",
            "value": "522624"
        }, {
            "label": "镇远县",
            "value": "522625"
        }, {
            "label": "岑巩县",
            "value": "522626"
        }, {
            "label": "天柱县",
            "value": "522627"
        }, {
            "label": "锦屏县",
            "value": "522628"
        }, {
            "label": "剑河县",
            "value": "522629"
        }, {
            "label": "台江县",
            "value": "522630"
        }, {
            "label": "黎平县",
            "value": "522631"
        }, {
            "label": "榕江县",
            "value": "522632"
        }, {
            "label": "从江县",
            "value": "522633"
        }, {
            "label": "雷山县",
            "value": "522634"
        }, {
            "label": "麻江县",
            "value": "522635"
        }, {
            "label": "丹寨县",
            "value": "522636"
        }],
        [{
            "label": "市辖区",
            "value": "522701"
        }, {
            "label": "福泉市",
            "value": "522702"
        }, {
            "label": "荔波县",
            "value": "522722"
        }, {
            "label": "贵定县",
            "value": "522723"
        }, {
            "label": "瓮安县",
            "value": "522725"
        }, {
            "label": "独山县",
            "value": "522726"
        }, {
            "label": "平塘县",
            "value": "522727"
        }, {
            "label": "罗甸县",
            "value": "522728"
        }, {
            "label": "长顺县",
            "value": "522729"
        }, {
            "label": "龙里县",
            "value": "522730"
        }, {
            "label": "惠水县",
            "value": "522731"
        }, {
            "label": "三都水族自治县",
            "value": "522732"
        }]
    ],
    [
        [{
            "label": "市辖区",
            "value": "530101"
        }, {
            "label": "五华区",
            "value": "530102"
        }, {
            "label": "盘龙区",
            "value": "530103"
        }, {
            "label": "官渡区",
            "value": "530111"
        }, {
            "label": "西山区",
            "value": "530112"
        }, {
            "label": "东川区",
            "value": "530113"
        }, {
            "label": "呈贡区",
            "value": "530114"
        }, {
            "label": "晋宁县",
            "value": "530122"
        }, {
            "label": "富民县",
            "value": "530124"
        }, {
            "label": "宜良县",
            "value": "530125"
        }, {
            "label": "石林彝族自治县",
            "value": "530126"
        }, {
            "label": "嵩明县",
            "value": "530127"
        }, {
            "label": "禄劝彝族苗族自治县",
            "value": "530128"
        }, {
            "label": "寻甸回族彝族自治县",
            "value": "530129"
        }, {
            "label": "安宁市",
            "value": "530181"
        }],
        [{
            "label": "市辖区",
            "value": "530301"
        }, {
            "label": "麒麟区",
            "value": "530302"
        }, {
            "label": "沾益区",
            "value": "530303"
        }, {
            "label": "马龙县",
            "value": "530321"
        }, {
            "label": "陆良县",
            "value": "530322"
        }, {
            "label": "师宗县",
            "value": "530323"
        }, {
            "label": "罗平县",
            "value": "530324"
        }, {
            "label": "富源县",
            "value": "530325"
        }, {
            "label": "会泽县",
            "value": "530326"
        }, {
            "label": "宣威市",
            "value": "530381"
        }],
        [{
            "label": "市辖区",
            "value": "530401"
        }, {
            "label": "红塔区",
            "value": "530402"
        }, {
            "label": "江川区",
            "value": "530403"
        }, {
            "label": "澄江县",
            "value": "530422"
        }, {
            "label": "通海县",
            "value": "530423"
        }, {
            "label": "华宁县",
            "value": "530424"
        }, {
            "label": "易门县",
            "value": "530425"
        }, {
            "label": "峨山彝族自治县",
            "value": "530426"
        }, {
            "label": "新平彝族傣族自治县",
            "value": "530427"
        }, {
            "label": "元江哈尼族彝族傣族自治县",
            "value": "530428"
        }],
        [{
            "label": "市辖区",
            "value": "530501"
        }, {
            "label": "隆阳区",
            "value": "530502"
        }, {
            "label": "施甸县",
            "value": "530521"
        }, {
            "label": "龙陵县",
            "value": "530523"
        }, {
            "label": "昌宁县",
            "value": "530524"
        }, {
            "label": "腾冲市",
            "value": "530581"
        }],
        [{
            "label": "市辖区",
            "value": "530601"
        }, {
            "label": "昭阳区",
            "value": "530602"
        }, {
            "label": "鲁甸县",
            "value": "530621"
        }, {
            "label": "巧家县",
            "value": "530622"
        }, {
            "label": "盐津县",
            "value": "530623"
        }, {
            "label": "大关县",
            "value": "530624"
        }, {
            "label": "永善县",
            "value": "530625"
        }, {
            "label": "绥江县",
            "value": "530626"
        }, {
            "label": "镇雄县",
            "value": "530627"
        }, {
            "label": "彝良县",
            "value": "530628"
        }, {
            "label": "威信县",
            "value": "530629"
        }, {
            "label": "水富县",
            "value": "530630"
        }],
        [{
            "label": "市辖区",
            "value": "530701"
        }, {
            "label": "古城区",
            "value": "530702"
        }, {
            "label": "玉龙纳西族自治县",
            "value": "530721"
        }, {
            "label": "永胜县",
            "value": "530722"
        }, {
            "label": "华坪县",
            "value": "530723"
        }, {
            "label": "宁蒗彝族自治县",
            "value": "530724"
        }],
        [{
            "label": "市辖区",
            "value": "530801"
        }, {
            "label": "思茅区",
            "value": "530802"
        }, {
            "label": "宁洱哈尼族彝族自治县",
            "value": "530821"
        }, {
            "label": "墨江哈尼族自治县",
            "value": "530822"
        }, {
            "label": "景东彝族自治县",
            "value": "530823"
        }, {
            "label": "景谷傣族彝族自治县",
            "value": "530824"
        }, {
            "label": "镇沅彝族哈尼族拉祜族自治县",
            "value": "530825"
        }, {
            "label": "江城哈尼族彝族自治县",
            "value": "530826"
        }, {
            "label": "孟连傣族拉祜族佤族自治县",
            "value": "530827"
        }, {
            "label": "澜沧拉祜族自治县",
            "value": "530828"
        }, {
            "label": "西盟佤族自治县",
            "value": "530829"
        }],
        [{
            "label": "市辖区",
            "value": "530901"
        }, {
            "label": "临翔区",
            "value": "530902"
        }, {
            "label": "凤庆县",
            "value": "530921"
        }, {
            "label": "云县",
            "value": "530922"
        }, {
            "label": "永德县",
            "value": "530923"
        }, {
            "label": "镇康县",
            "value": "530924"
        }, {
            "label": "双江拉祜族佤族布朗族傣族自治县",
            "value": "530925"
        }, {
            "label": "耿马傣族佤族自治县",
            "value": "530926"
        }, {
            "label": "沧源佤族自治县",
            "value": "530927"
        }],
        [{
            "label": "市辖区",
            "value": "532301"
        }, {
            "label": "双柏县",
            "value": "532322"
        }, {
            "label": "牟定县",
            "value": "532323"
        }, {
            "label": "南华县",
            "value": "532324"
        }, {
            "label": "姚安县",
            "value": "532325"
        }, {
            "label": "大姚县",
            "value": "532326"
        }, {
            "label": "永仁县",
            "value": "532327"
        }, {
            "label": "元谋县",
            "value": "532328"
        }, {
            "label": "武定县",
            "value": "532329"
        }, {
            "label": "禄丰县",
            "value": "532331"
        }],
        [{
            "label": "市辖区",
            "value": "532501"
        }, {
            "label": "开远市",
            "value": "532502"
        }, {
            "label": "蒙自市",
            "value": "532503"
        }, {
            "label": "弥勒市",
            "value": "532504"
        }, {
            "label": "屏边苗族自治县",
            "value": "532523"
        }, {
            "label": "建水县",
            "value": "532524"
        }, {
            "label": "石屏县",
            "value": "532525"
        }, {
            "label": "泸西县",
            "value": "532527"
        }, {
            "label": "元阳县",
            "value": "532528"
        }, {
            "label": "红河县",
            "value": "532529"
        }, {
            "label": "金平苗族瑶族傣族自治县",
            "value": "532530"
        }, {
            "label": "绿春县",
            "value": "532531"
        }, {
            "label": "河口瑶族自治县",
            "value": "532532"
        }],
        [{
            "label": "市辖区",
            "value": "532601"
        }, {
            "label": "砚山县",
            "value": "532622"
        }, {
            "label": "西畴县",
            "value": "532623"
        }, {
            "label": "麻栗坡县",
            "value": "532624"
        }, {
            "label": "马关县",
            "value": "532625"
        }, {
            "label": "丘北县",
            "value": "532626"
        }, {
            "label": "广南县",
            "value": "532627"
        }, {
            "label": "富宁县",
            "value": "532628"
        }],
        [{
            "label": "市辖区",
            "value": "532801"
        }, {
            "label": "勐海县",
            "value": "532822"
        }, {
            "label": "勐腊县",
            "value": "532823"
        }],
        [{
            "label": "市辖区",
            "value": "532901"
        }, {
            "label": "漾濞彝族自治县",
            "value": "532922"
        }, {
            "label": "祥云县",
            "value": "532923"
        }, {
            "label": "宾川县",
            "value": "532924"
        }, {
            "label": "弥渡县",
            "value": "532925"
        }, {
            "label": "南涧彝族自治县",
            "value": "532926"
        }, {
            "label": "巍山彝族回族自治县",
            "value": "532927"
        }, {
            "label": "永平县",
            "value": "532928"
        }, {
            "label": "云龙县",
            "value": "532929"
        }, {
            "label": "洱源县",
            "value": "532930"
        }, {
            "label": "剑川县",
            "value": "532931"
        }, {
            "label": "鹤庆县",
            "value": "532932"
        }],
        [{
            "label": "瑞丽市",
            "value": "533102"
        }, {
            "label": "芒市",
            "value": "533103"
        }, {
            "label": "梁河县",
            "value": "533122"
        }, {
            "label": "盈江县",
            "value": "533123"
        }, {
            "label": "陇川县",
            "value": "533124"
        }],
        [{
            "label": "市辖区",
            "value": "533301"
        }, {
            "label": "福贡县",
            "value": "533323"
        }, {
            "label": "贡山独龙族怒族自治县",
            "value": "533324"
        }, {
            "label": "兰坪白族普米族自治县",
            "value": "533325"
        }],
        [{
            "label": "市辖区",
            "value": "533401"
        }, {
            "label": "德钦县",
            "value": "533422"
        }, {
            "label": "维西傈僳族自治县",
            "value": "533423"
        }]
    ],
    [
        [{
            "label": "市辖区",
            "value": "540101"
        }, {
            "label": "城关区",
            "value": "540102"
        }, {
            "label": "堆龙德庆区",
            "value": "540103"
        }, {
            "label": "林周县",
            "value": "540121"
        }, {
            "label": "当雄县",
            "value": "540122"
        }, {
            "label": "尼木县",
            "value": "540123"
        }, {
            "label": "曲水县",
            "value": "540124"
        }, {
            "label": "达孜县",
            "value": "540126"
        }, {
            "label": "墨竹工卡县",
            "value": "540127"
        }],
        [{
            "label": "桑珠孜区",
            "value": "540202"
        }, {
            "label": "南木林县",
            "value": "540221"
        }, {
            "label": "江孜县",
            "value": "540222"
        }, {
            "label": "定日县",
            "value": "540223"
        }, {
            "label": "萨迦县",
            "value": "540224"
        }, {
            "label": "拉孜县",
            "value": "540225"
        }, {
            "label": "昂仁县",
            "value": "540226"
        }, {
            "label": "谢通门县",
            "value": "540227"
        }, {
            "label": "白朗县",
            "value": "540228"
        }, {
            "label": "仁布县",
            "value": "540229"
        }, {
            "label": "康马县",
            "value": "540230"
        }, {
            "label": "定结县",
            "value": "540231"
        }, {
            "label": "仲巴县",
            "value": "540232"
        }, {
            "label": "亚东县",
            "value": "540233"
        }, {
            "label": "吉隆县",
            "value": "540234"
        }, {
            "label": "聂拉木县",
            "value": "540235"
        }, {
            "label": "萨嘎县",
            "value": "540236"
        }, {
            "label": "岗巴县",
            "value": "540237"
        }],
        [{
            "label": "卡若区",
            "value": "540302"
        }, {
            "label": "江达县",
            "value": "540321"
        }, {
            "label": "贡觉县",
            "value": "540322"
        }, {
            "label": "类乌齐县",
            "value": "540323"
        }, {
            "label": "丁青县",
            "value": "540324"
        }, {
            "label": "察雅县",
            "value": "540325"
        }, {
            "label": "八宿县",
            "value": "540326"
        }, {
            "label": "左贡县",
            "value": "540327"
        }, {
            "label": "芒康县",
            "value": "540328"
        }, {
            "label": "洛隆县",
            "value": "540329"
        }, {
            "label": "边坝县",
            "value": "540330"
        }],
        [{
            "label": "巴宜区",
            "value": "540402"
        }, {
            "label": "工布江达县",
            "value": "540421"
        }, {
            "label": "米林县",
            "value": "540422"
        }, {
            "label": "墨脱县",
            "value": "540423"
        }, {
            "label": "波密县",
            "value": "540424"
        }, {
            "label": "察隅县",
            "value": "540425"
        }, {
            "label": "朗县",
            "value": "540426"
        }],
        [{
            "label": "市辖区",
            "value": "540501"
        }, {
            "label": "乃东区",
            "value": "540502"
        }, {
            "label": "扎囊县",
            "value": "540521"
        }, {
            "label": "贡嘎县",
            "value": "540522"
        }, {
            "label": "桑日县",
            "value": "540523"
        }, {
            "label": "琼结县",
            "value": "540524"
        }, {
            "label": "曲松县",
            "value": "540525"
        }, {
            "label": "措美县",
            "value": "540526"
        }, {
            "label": "洛扎县",
            "value": "540527"
        }, {
            "label": "加查县",
            "value": "540528"
        }, {
            "label": "隆子县",
            "value": "540529"
        }, {
            "label": "错那县",
            "value": "540530"
        }, {
            "label": "浪卡子县",
            "value": "540531"
        }],
        [{
            "label": "那曲县",
            "value": "542421"
        }, {
            "label": "嘉黎县",
            "value": "542422"
        }, {
            "label": "比如县",
            "value": "542423"
        }, {
            "label": "聂荣县",
            "value": "542424"
        }, {
            "label": "安多县",
            "value": "542425"
        }, {
            "label": "申扎县",
            "value": "542426"
        }, {
            "label": "索县",
            "value": "542427"
        }, {
            "label": "班戈县",
            "value": "542428"
        }, {
            "label": "巴青县",
            "value": "542429"
        }, {
            "label": "尼玛县",
            "value": "542430"
        }, {
            "label": "双湖县",
            "value": "542431"
        }],
        [{
            "label": "普兰县",
            "value": "542521"
        }, {
            "label": "札达县",
            "value": "542522"
        }, {
            "label": "噶尔县",
            "value": "542523"
        }, {
            "label": "日土县",
            "value": "542524"
        }, {
            "label": "革吉县",
            "value": "542525"
        }, {
            "label": "改则县",
            "value": "542526"
        }, {
            "label": "措勤县",
            "value": "542527"
        }]
    ],
    [
        [{
            "label": "市辖区",
            "value": "610101"
        }, {
            "label": "新城区",
            "value": "610102"
        }, {
            "label": "碑林区",
            "value": "610103"
        }, {
            "label": "莲湖区",
            "value": "610104"
        }, {
            "label": "灞桥区",
            "value": "610111"
        }, {
            "label": "未央区",
            "value": "610112"
        }, {
            "label": "雁塔区",
            "value": "610113"
        }, {
            "label": "阎良区",
            "value": "610114"
        }, {
            "label": "临潼区",
            "value": "610115"
        }, {
            "label": "长安区",
            "value": "610116"
        }, {
            "label": "高陵区",
            "value": "610117"
        }, {
            "label": "蓝田县",
            "value": "610122"
        }, {
            "label": "周至县",
            "value": "610124"
        }, {
            "label": "户县",
            "value": "610125"
        }],
        [{
            "label": "市辖区",
            "value": "610201"
        }, {
            "label": "王益区",
            "value": "610202"
        }, {
            "label": "印台区",
            "value": "610203"
        }, {
            "label": "耀州区",
            "value": "610204"
        }, {
            "label": "宜君县",
            "value": "610222"
        }],
        [{
            "label": "市辖区",
            "value": "610301"
        }, {
            "label": "渭滨区",
            "value": "610302"
        }, {
            "label": "金台区",
            "value": "610303"
        }, {
            "label": "陈仓区",
            "value": "610304"
        }, {
            "label": "凤翔县",
            "value": "610322"
        }, {
            "label": "岐山县",
            "value": "610323"
        }, {
            "label": "扶风县",
            "value": "610324"
        }, {
            "label": "眉县",
            "value": "610326"
        }, {
            "label": "陇县",
            "value": "610327"
        }, {
            "label": "千阳县",
            "value": "610328"
        }, {
            "label": "麟游县",
            "value": "610329"
        }, {
            "label": "凤县",
            "value": "610330"
        }, {
            "label": "太白县",
            "value": "610331"
        }],
        [{
            "label": "市辖区",
            "value": "610401"
        }, {
            "label": "秦都区",
            "value": "610402"
        }, {
            "label": "杨陵区",
            "value": "610403"
        }, {
            "label": "渭城区",
            "value": "610404"
        }, {
            "label": "三原县",
            "value": "610422"
        }, {
            "label": "泾阳县",
            "value": "610423"
        }, {
            "label": "乾县",
            "value": "610424"
        }, {
            "label": "礼泉县",
            "value": "610425"
        }, {
            "label": "永寿县",
            "value": "610426"
        }, {
            "label": "彬县",
            "value": "610427"
        }, {
            "label": "长武县",
            "value": "610428"
        }, {
            "label": "旬邑县",
            "value": "610429"
        }, {
            "label": "淳化县",
            "value": "610430"
        }, {
            "label": "武功县",
            "value": "610431"
        }, {
            "label": "兴平市",
            "value": "610481"
        }],
        [{
            "label": "市辖区",
            "value": "610501"
        }, {
            "label": "临渭区",
            "value": "610502"
        }, {
            "label": "华州区",
            "value": "610503"
        }, {
            "label": "潼关县",
            "value": "610522"
        }, {
            "label": "大荔县",
            "value": "610523"
        }, {
            "label": "合阳县",
            "value": "610524"
        }, {
            "label": "澄城县",
            "value": "610525"
        }, {
            "label": "蒲城县",
            "value": "610526"
        }, {
            "label": "白水县",
            "value": "610527"
        }, {
            "label": "富平县",
            "value": "610528"
        }, {
            "label": "韩城市",
            "value": "610581"
        }, {
            "label": "华阴市",
            "value": "610582"
        }],
        [{
            "label": "市辖区",
            "value": "610601"
        }, {
            "label": "宝塔区",
            "value": "610602"
        }, {
            "label": "安塞区",
            "value": "610603"
        }, {
            "label": "延长县",
            "value": "610621"
        }, {
            "label": "延川县",
            "value": "610622"
        }, {
            "label": "子长县",
            "value": "610623"
        }, {
            "label": "志丹县",
            "value": "610625"
        }, {
            "label": "吴起县",
            "value": "610626"
        }, {
            "label": "甘泉县",
            "value": "610627"
        }, {
            "label": "富县",
            "value": "610628"
        }, {
            "label": "洛川县",
            "value": "610629"
        }, {
            "label": "宜川县",
            "value": "610630"
        }, {
            "label": "黄龙县",
            "value": "610631"
        }, {
            "label": "黄陵县",
            "value": "610632"
        }],
        [{
            "label": "市辖区",
            "value": "610701"
        }, {
            "label": "汉台区",
            "value": "610702"
        }, {
            "label": "南郑县",
            "value": "610721"
        }, {
            "label": "城固县",
            "value": "610722"
        }, {
            "label": "洋县",
            "value": "610723"
        }, {
            "label": "西乡县",
            "value": "610724"
        }, {
            "label": "勉县",
            "value": "610725"
        }, {
            "label": "宁强县",
            "value": "610726"
        }, {
            "label": "略阳县",
            "value": "610727"
        }, {
            "label": "镇巴县",
            "value": "610728"
        }, {
            "label": "留坝县",
            "value": "610729"
        }, {
            "label": "佛坪县",
            "value": "610730"
        }],
        [{
            "label": "市辖区",
            "value": "610801"
        }, {
            "label": "榆阳区",
            "value": "610802"
        }, {
            "label": "横山区",
            "value": "610803"
        }, {
            "label": "神木县",
            "value": "610821"
        }, {
            "label": "府谷县",
            "value": "610822"
        }, {
            "label": "靖边县",
            "value": "610824"
        }, {
            "label": "定边县",
            "value": "610825"
        }, {
            "label": "绥德县",
            "value": "610826"
        }, {
            "label": "米脂县",
            "value": "610827"
        }, {
            "label": "佳县",
            "value": "610828"
        }, {
            "label": "吴堡县",
            "value": "610829"
        }, {
            "label": "清涧县",
            "value": "610830"
        }, {
            "label": "子洲县",
            "value": "610831"
        }],
        [{
            "label": "市辖区",
            "value": "610901"
        }, {
            "label": "汉滨区",
            "value": "610902"
        }, {
            "label": "汉阴县",
            "value": "610921"
        }, {
            "label": "石泉县",
            "value": "610922"
        }, {
            "label": "宁陕县",
            "value": "610923"
        }, {
            "label": "紫阳县",
            "value": "610924"
        }, {
            "label": "岚皋县",
            "value": "610925"
        }, {
            "label": "平利县",
            "value": "610926"
        }, {
            "label": "镇坪县",
            "value": "610927"
        }, {
            "label": "旬阳县",
            "value": "610928"
        }, {
            "label": "白河县",
            "value": "610929"
        }],
        [{
            "label": "市辖区",
            "value": "611001"
        }, {
            "label": "商州区",
            "value": "611002"
        }, {
            "label": "洛南县",
            "value": "611021"
        }, {
            "label": "丹凤县",
            "value": "611022"
        }, {
            "label": "商南县",
            "value": "611023"
        }, {
            "label": "山阳县",
            "value": "611024"
        }, {
            "label": "镇安县",
            "value": "611025"
        }, {
            "label": "柞水县",
            "value": "611026"
        }]
    ],
    [
        [{
            "label": "市辖区",
            "value": "620101"
        }, {
            "label": "城关区",
            "value": "620102"
        }, {
            "label": "七里河区",
            "value": "620103"
        }, {
            "label": "西固区",
            "value": "620104"
        }, {
            "label": "安宁区",
            "value": "620105"
        }, {
            "label": "红古区",
            "value": "620111"
        }, {
            "label": "永登县",
            "value": "620121"
        }, {
            "label": "皋兰县",
            "value": "620122"
        }, {
            "label": "榆中县",
            "value": "620123"
        }],
        [{
            "label": "市辖区",
            "value": "620201"
        }],
        [{
            "label": "市辖区",
            "value": "620301"
        }, {
            "label": "金川区",
            "value": "620302"
        }, {
            "label": "永昌县",
            "value": "620321"
        }],
        [{
            "label": "市辖区",
            "value": "620401"
        }, {
            "label": "白银区",
            "value": "620402"
        }, {
            "label": "平川区",
            "value": "620403"
        }, {
            "label": "靖远县",
            "value": "620421"
        }, {
            "label": "会宁县",
            "value": "620422"
        }, {
            "label": "景泰县",
            "value": "620423"
        }],
        [{
            "label": "市辖区",
            "value": "620501"
        }, {
            "label": "秦州区",
            "value": "620502"
        }, {
            "label": "麦积区",
            "value": "620503"
        }, {
            "label": "清水县",
            "value": "620521"
        }, {
            "label": "秦安县",
            "value": "620522"
        }, {
            "label": "甘谷县",
            "value": "620523"
        }, {
            "label": "武山县",
            "value": "620524"
        }, {
            "label": "张家川回族自治县",
            "value": "620525"
        }],
        [{
            "label": "市辖区",
            "value": "620601"
        }, {
            "label": "凉州区",
            "value": "620602"
        }, {
            "label": "民勤县",
            "value": "620621"
        }, {
            "label": "古浪县",
            "value": "620622"
        }, {
            "label": "天祝藏族自治县",
            "value": "620623"
        }],
        [{
            "label": "市辖区",
            "value": "620701"
        }, {
            "label": "甘州区",
            "value": "620702"
        }, {
            "label": "肃南裕固族自治县",
            "value": "620721"
        }, {
            "label": "民乐县",
            "value": "620722"
        }, {
            "label": "临泽县",
            "value": "620723"
        }, {
            "label": "高台县",
            "value": "620724"
        }, {
            "label": "山丹县",
            "value": "620725"
        }],
        [{
            "label": "市辖区",
            "value": "620801"
        }, {
            "label": "崆峒区",
            "value": "620802"
        }, {
            "label": "泾川县",
            "value": "620821"
        }, {
            "label": "灵台县",
            "value": "620822"
        }, {
            "label": "崇信县",
            "value": "620823"
        }, {
            "label": "华亭县",
            "value": "620824"
        }, {
            "label": "庄浪县",
            "value": "620825"
        }, {
            "label": "静宁县",
            "value": "620826"
        }],
        [{
            "label": "市辖区",
            "value": "620901"
        }, {
            "label": "肃州区",
            "value": "620902"
        }, {
            "label": "金塔县",
            "value": "620921"
        }, {
            "label": "瓜州县",
            "value": "620922"
        }, {
            "label": "肃北蒙古族自治县",
            "value": "620923"
        }, {
            "label": "阿克塞哈萨克族自治县",
            "value": "620924"
        }, {
            "label": "玉门市",
            "value": "620981"
        }, {
            "label": "敦煌市",
            "value": "620982"
        }],
        [{
            "label": "市辖区",
            "value": "621001"
        }, {
            "label": "西峰区",
            "value": "621002"
        }, {
            "label": "庆城县",
            "value": "621021"
        }, {
            "label": "环县",
            "value": "621022"
        }, {
            "label": "华池县",
            "value": "621023"
        }, {
            "label": "合水县",
            "value": "621024"
        }, {
            "label": "正宁县",
            "value": "621025"
        }, {
            "label": "宁县",
            "value": "621026"
        }, {
            "label": "镇原县",
            "value": "621027"
        }],
        [{
            "label": "市辖区",
            "value": "621101"
        }, {
            "label": "安定区",
            "value": "621102"
        }, {
            "label": "通渭县",
            "value": "621121"
        }, {
            "label": "陇西县",
            "value": "621122"
        }, {
            "label": "渭源县",
            "value": "621123"
        }, {
            "label": "临洮县",
            "value": "621124"
        }, {
            "label": "漳县",
            "value": "621125"
        }, {
            "label": "岷县",
            "value": "621126"
        }],
        [{
            "label": "市辖区",
            "value": "621201"
        }, {
            "label": "武都区",
            "value": "621202"
        }, {
            "label": "成县",
            "value": "621221"
        }, {
            "label": "文县",
            "value": "621222"
        }, {
            "label": "宕昌县",
            "value": "621223"
        }, {
            "label": "康县",
            "value": "621224"
        }, {
            "label": "西和县",
            "value": "621225"
        }, {
            "label": "礼县",
            "value": "621226"
        }, {
            "label": "徽县",
            "value": "621227"
        }, {
            "label": "两当县",
            "value": "621228"
        }],
        [{
            "label": "市辖区",
            "value": "622901"
        }, {
            "label": "临夏县",
            "value": "622921"
        }, {
            "label": "康乐县",
            "value": "622922"
        }, {
            "label": "永靖县",
            "value": "622923"
        }, {
            "label": "广河县",
            "value": "622924"
        }, {
            "label": "和政县",
            "value": "622925"
        }, {
            "label": "东乡族自治县",
            "value": "622926"
        }, {
            "label": "积石山保安族东乡族撒拉族自治县",
            "value": "622927"
        }],
        [{
            "label": "市辖区",
            "value": "623001"
        }, {
            "label": "临潭县",
            "value": "623021"
        }, {
            "label": "卓尼县",
            "value": "623022"
        }, {
            "label": "舟曲县",
            "value": "623023"
        }, {
            "label": "迭部县",
            "value": "623024"
        }, {
            "label": "玛曲县",
            "value": "623025"
        }, {
            "label": "碌曲县",
            "value": "623026"
        }, {
            "label": "夏河县",
            "value": "623027"
        }]
    ],
    [
        [{
            "label": "市辖区",
            "value": "630101"
        }, {
            "label": "城东区",
            "value": "630102"
        }, {
            "label": "城中区",
            "value": "630103"
        }, {
            "label": "城西区",
            "value": "630104"
        }, {
            "label": "城北区",
            "value": "630105"
        }, {
            "label": "大通回族土族自治县",
            "value": "630121"
        }, {
            "label": "湟中县",
            "value": "630122"
        }, {
            "label": "湟源县",
            "value": "630123"
        }],
        [{
            "label": "乐都区",
            "value": "630202"
        }, {
            "label": "平安区",
            "value": "630203"
        }, {
            "label": "民和回族土族自治县",
            "value": "630222"
        }, {
            "label": "互助土族自治县",
            "value": "630223"
        }, {
            "label": "化隆回族自治县",
            "value": "630224"
        }, {
            "label": "循化撒拉族自治县",
            "value": "630225"
        }],
        [{
            "label": "门源回族自治县",
            "value": "632221"
        }, {
            "label": "祁连县",
            "value": "632222"
        }, {
            "label": "海晏县",
            "value": "632223"
        }, {
            "label": "刚察县",
            "value": "632224"
        }],
        [{
            "label": "同仁县",
            "value": "632321"
        }, {
            "label": "尖扎县",
            "value": "632322"
        }, {
            "label": "泽库县",
            "value": "632323"
        }, {
            "label": "河南蒙古族自治县",
            "value": "632324"
        }],
        [{
            "label": "共和县",
            "value": "632521"
        }, {
            "label": "同德县",
            "value": "632522"
        }, {
            "label": "贵德县",
            "value": "632523"
        }, {
            "label": "兴海县",
            "value": "632524"
        }, {
            "label": "贵南县",
            "value": "632525"
        }],
        [{
            "label": "玛沁县",
            "value": "632621"
        }, {
            "label": "班玛县",
            "value": "632622"
        }, {
            "label": "甘德县",
            "value": "632623"
        }, {
            "label": "达日县",
            "value": "632624"
        }, {
            "label": "久治县",
            "value": "632625"
        }, {
            "label": "玛多县",
            "value": "632626"
        }],
        [{
            "label": "市辖区",
            "value": "632701"
        }, {
            "label": "杂多县",
            "value": "632722"
        }, {
            "label": "称多县",
            "value": "632723"
        }, {
            "label": "治多县",
            "value": "632724"
        }, {
            "label": "囊谦县",
            "value": "632725"
        }, {
            "label": "曲麻莱县",
            "value": "632726"
        }],
        [{
            "label": "市辖区",
            "value": "632801"
        }, {
            "label": "德令哈市",
            "value": "632802"
        }, {
            "label": "乌兰县",
            "value": "632821"
        }, {
            "label": "都兰县",
            "value": "632822"
        }, {
            "label": "天峻县",
            "value": "632823"
        }]
    ],
    [
        [{
            "label": "市辖区",
            "value": "640101"
        }, {
            "label": "兴庆区",
            "value": "640104"
        }, {
            "label": "西夏区",
            "value": "640105"
        }, {
            "label": "金凤区",
            "value": "640106"
        }, {
            "label": "永宁县",
            "value": "640121"
        }, {
            "label": "贺兰县",
            "value": "640122"
        }, {
            "label": "灵武市",
            "value": "640181"
        }],
        [{
            "label": "市辖区",
            "value": "640201"
        }, {
            "label": "大武口区",
            "value": "640202"
        }, {
            "label": "惠农区",
            "value": "640205"
        }, {
            "label": "平罗县",
            "value": "640221"
        }],
        [{
            "label": "市辖区",
            "value": "640301"
        }, {
            "label": "利通区",
            "value": "640302"
        }, {
            "label": "红寺堡区",
            "value": "640303"
        }, {
            "label": "盐池县",
            "value": "640323"
        }, {
            "label": "同心县",
            "value": "640324"
        }, {
            "label": "青铜峡市",
            "value": "640381"
        }],
        [{
            "label": "市辖区",
            "value": "640401"
        }, {
            "label": "原州区",
            "value": "640402"
        }, {
            "label": "西吉县",
            "value": "640422"
        }, {
            "label": "隆德县",
            "value": "640423"
        }, {
            "label": "泾源县",
            "value": "640424"
        }, {
            "label": "彭阳县",
            "value": "640425"
        }],
        [{
            "label": "市辖区",
            "value": "640501"
        }, {
            "label": "沙坡头区",
            "value": "640502"
        }, {
            "label": "中宁县",
            "value": "640521"
        }, {
            "label": "海原县",
            "value": "640522"
        }]
    ],
    [
        [{
            "label": "市辖区",
            "value": "650101"
        }, {
            "label": "天山区",
            "value": "650102"
        }, {
            "label": "沙依巴克区",
            "value": "650103"
        }, {
            "label": "新市区",
            "value": "650104"
        }, {
            "label": "水磨沟区",
            "value": "650105"
        }, {
            "label": "头屯河区",
            "value": "650106"
        }, {
            "label": "达坂城区",
            "value": "650107"
        }, {
            "label": "米东区",
            "value": "650109"
        }, {
            "label": "乌鲁木齐县",
            "value": "650121"
        }],
        [{
            "label": "市辖区",
            "value": "650201"
        }, {
            "label": "独山子区",
            "value": "650202"
        }, {
            "label": "克拉玛依区",
            "value": "650203"
        }, {
            "label": "白碱滩区",
            "value": "650204"
        }, {
            "label": "乌尔禾区",
            "value": "650205"
        }],
        [{
            "label": "高昌区",
            "value": "650402"
        }, {
            "label": "鄯善县",
            "value": "650421"
        }, {
            "label": "托克逊县",
            "value": "650422"
        }],
        [{
            "label": "伊州区",
            "value": "650502"
        }, {
            "label": "巴里坤哈萨克自治县",
            "value": "650521"
        }, {
            "label": "伊吾县",
            "value": "650522"
        }],
        [{
            "label": "市辖区",
            "value": "652301"
        }, {
            "label": "阜康市",
            "value": "652302"
        }, {
            "label": "呼图壁县",
            "value": "652323"
        }, {
            "label": "玛纳斯县",
            "value": "652324"
        }, {
            "label": "奇台县",
            "value": "652325"
        }, {
            "label": "吉木萨尔县",
            "value": "652327"
        }, {
            "label": "木垒哈萨克自治县",
            "value": "652328"
        }],
        [{
            "label": "市辖区",
            "value": "652701"
        }, {
            "label": "阿拉山口市",
            "value": "652702"
        }, {
            "label": "精河县",
            "value": "652722"
        }, {
            "label": "温泉县",
            "value": "652723"
        }],
        [{
            "label": "市辖区",
            "value": "652801"
        }, {
            "label": "轮台县",
            "value": "652822"
        }, {
            "label": "尉犁县",
            "value": "652823"
        }, {
            "label": "若羌县",
            "value": "652824"
        }, {
            "label": "且末县",
            "value": "652825"
        }, {
            "label": "焉耆回族自治县",
            "value": "652826"
        }, {
            "label": "和静县",
            "value": "652827"
        }, {
            "label": "和硕县",
            "value": "652828"
        }, {
            "label": "博湖县",
            "value": "652829"
        }],
        [{
            "label": "市辖区",
            "value": "652901"
        }, {
            "label": "温宿县",
            "value": "652922"
        }, {
            "label": "库车县",
            "value": "652923"
        }, {
            "label": "沙雅县",
            "value": "652924"
        }, {
            "label": "新和县",
            "value": "652925"
        }, {
            "label": "拜城县",
            "value": "652926"
        }, {
            "label": "乌什县",
            "value": "652927"
        }, {
            "label": "阿瓦提县",
            "value": "652928"
        }, {
            "label": "柯坪县",
            "value": "652929"
        }],
        [{
            "label": "市辖区",
            "value": "653001"
        }, {
            "label": "阿克陶县",
            "value": "653022"
        }, {
            "label": "阿合奇县",
            "value": "653023"
        }, {
            "label": "乌恰县",
            "value": "653024"
        }],
        [{
            "label": "市辖区",
            "value": "653101"
        }, {
            "label": "疏附县",
            "value": "653121"
        }, {
            "label": "疏勒县",
            "value": "653122"
        }, {
            "label": "英吉沙县",
            "value": "653123"
        }, {
            "label": "泽普县",
            "value": "653124"
        }, {
            "label": "莎车县",
            "value": "653125"
        }, {
            "label": "叶城县",
            "value": "653126"
        }, {
            "label": "麦盖提县",
            "value": "653127"
        }, {
            "label": "岳普湖县",
            "value": "653128"
        }, {
            "label": "伽师县",
            "value": "653129"
        }, {
            "label": "巴楚县",
            "value": "653130"
        }, {
            "label": "塔什库尔干塔吉克自治县",
            "value": "653131"
        }],
        [{
            "label": "市辖区",
            "value": "653201"
        }, {
            "label": "和田县",
            "value": "653221"
        }, {
            "label": "墨玉县",
            "value": "653222"
        }, {
            "label": "皮山县",
            "value": "653223"
        }, {
            "label": "洛浦县",
            "value": "653224"
        }, {
            "label": "策勒县",
            "value": "653225"
        }, {
            "label": "于田县",
            "value": "653226"
        }, {
            "label": "民丰县",
            "value": "653227"
        }],
        [{
            "label": "伊宁市",
            "value": "654002"
        }, {
            "label": "奎屯市",
            "value": "654003"
        }, {
            "label": "霍尔果斯市",
            "value": "654004"
        }, {
            "label": "伊宁县",
            "value": "654021"
        }, {
            "label": "察布查尔锡伯自治县",
            "value": "654022"
        }, {
            "label": "霍城县",
            "value": "654023"
        }, {
            "label": "巩留县",
            "value": "654024"
        }, {
            "label": "新源县",
            "value": "654025"
        }, {
            "label": "昭苏县",
            "value": "654026"
        }, {
            "label": "特克斯县",
            "value": "654027"
        }, {
            "label": "尼勒克县",
            "value": "654028"
        }],
        [{
            "label": "市辖区",
            "value": "654201"
        }, {
            "label": "乌苏市",
            "value": "654202"
        }, {
            "label": "额敏县",
            "value": "654221"
        }, {
            "label": "沙湾县",
            "value": "654223"
        }, {
            "label": "托里县",
            "value": "654224"
        }, {
            "label": "裕民县",
            "value": "654225"
        }, {
            "label": "和布克赛尔蒙古自治县",
            "value": "654226"
        }],
        [{
            "label": "市辖区",
            "value": "654301"
        }, {
            "label": "布尔津县",
            "value": "654321"
        }, {
            "label": "富蕴县",
            "value": "654322"
        }, {
            "label": "福海县",
            "value": "654323"
        }, {
            "label": "哈巴河县",
            "value": "654324"
        }, {
            "label": "青河县",
            "value": "654325"
        }, {
            "label": "吉木乃县",
            "value": "654326"
        }],
        [{
            "label": "市辖区",
            "value": "659001"
        }, {
            "label": "阿拉尔市",
            "value": "659002"
        }, {
            "label": "图木舒克市",
            "value": "659003"
        }, {
            "label": "五家渠市",
            "value": "659004"
        }, {
            "label": "铁门关市",
            "value": "659006"
        }]
    ]
]
export default areaData;
city.js
/* eslint-disable */
var cityData = [
    [{
        "label": "北京市",
        "value": "110100"
    }],
    [{
        "label": "天津市",
        "value": "120100"
    }],
    [{
        "label": "石家庄市",
        "value": "130100"
    }, {
        "label": "唐山市",
        "value": "130200"
    }, {
        "label": "秦皇岛市",
        "value": "130300"
    }, {
        "label": "邯郸市",
        "value": "130400"
    }, {
        "label": "邢台市",
        "value": "130500"
    }, {
        "label": "保定市",
        "value": "130600"
    }, {
        "label": "张家口市",
        "value": "130700"
    }, {
        "label": "承德市",
        "value": "130800"
    }, {
        "label": "沧州市",
        "value": "130900"
    }, {
        "label": "廊坊市",
        "value": "131000"
    }, {
        "label": "衡水市",
        "value": "131100"
    }, {
        "label": "省直辖县级行政区划",
        "value": "139000"
    }],
    [{
        "label": "太原市",
        "value": "140100"
    }, {
        "label": "大同市",
        "value": "140200"
    }, {
        "label": "阳泉市",
        "value": "140300"
    }, {
        "label": "长治市",
        "value": "140400"
    }, {
        "label": "晋城市",
        "value": "140500"
    }, {
        "label": "朔州市",
        "value": "140600"
    }, {
        "label": "晋中市",
        "value": "140700"
    }, {
        "label": "运城市",
        "value": "140800"
    }, {
        "label": "忻州市",
        "value": "140900"
    }, {
        "label": "临汾市",
        "value": "141000"
    }, {
        "label": "吕梁市",
        "value": "141100"
    }],
    [{
        "label": "呼和浩特市",
        "value": "150100"
    }, {
        "label": "包头市",
        "value": "150200"
    }, {
        "label": "乌海市",
        "value": "150300"
    }, {
        "label": "赤峰市",
        "value": "150400"
    }, {
        "label": "通辽市",
        "value": "150500"
    }, {
        "label": "鄂尔多斯市",
        "value": "150600"
    }, {
        "label": "呼伦贝尔市",
        "value": "150700"
    }, {
        "label": "巴彦淖尔市",
        "value": "150800"
    }, {
        "label": "乌兰察布市",
        "value": "150900"
    }, {
        "label": "兴安盟",
        "value": "152200"
    }, {
        "label": "锡林郭勒盟",
        "value": "152500"
    }, {
        "label": "阿拉善盟",
        "value": "152900"
    }],
    [{
        "label": "沈阳市",
        "value": "210100"
    }, {
        "label": "大连市",
        "value": "210200"
    }, {
        "label": "鞍山市",
        "value": "210300"
    }, {
        "label": "抚顺市",
        "value": "210400"
    }, {
        "label": "本溪市",
        "value": "210500"
    }, {
        "label": "丹东市",
        "value": "210600"
    }, {
        "label": "锦州市",
        "value": "210700"
    }, {
        "label": "营口市",
        "value": "210800"
    }, {
        "label": "阜新市",
        "value": "210900"
    }, {
        "label": "辽阳市",
        "value": "211000"
    }, {
        "label": "盘锦市",
        "value": "211100"
    }, {
        "label": "铁岭市",
        "value": "211200"
    }, {
        "label": "朝阳市",
        "value": "211300"
    }, {
        "label": "葫芦岛市",
        "value": "211400"
    }],
    [{
        "label": "长春市",
        "value": "220100"
    }, {
        "label": "吉林市",
        "value": "220200"
    }, {
        "label": "四平市",
        "value": "220300"
    }, {
        "label": "辽源市",
        "value": "220400"
    }, {
        "label": "通化市",
        "value": "220500"
    }, {
        "label": "白山市",
        "value": "220600"
    }, {
        "label": "松原市",
        "value": "220700"
    }, {
        "label": "白城市",
        "value": "220800"
    }, {
        "label": "延边朝鲜族自治州",
        "value": "222400"
    }],
    [{
        "label": "哈尔滨市",
        "value": "230100"
    }, {
        "label": "齐齐哈尔市",
        "value": "230200"
    }, {
        "label": "鸡西市",
        "value": "230300"
    }, {
        "label": "鹤岗市",
        "value": "230400"
    }, {
        "label": "双鸭山市",
        "value": "230500"
    }, {
        "label": "大庆市",
        "value": "230600"
    }, {
        "label": "伊春市",
        "value": "230700"
    }, {
        "label": "佳木斯市",
        "value": "230800"
    }, {
        "label": "七台河市",
        "value": "230900"
    }, {
        "label": "牡丹江市",
        "value": "231000"
    }, {
        "label": "黑河市",
        "value": "231100"
    }, {
        "label": "绥化市",
        "value": "231200"
    }, {
        "label": "大兴安岭地区",
        "value": "232700"
    }],
    [{
        "label": "上海市",
        "value": "310100"
    }],
    [{
        "label": "南京市",
        "value": "320100"
    }, {
        "label": "无锡市",
        "value": "320200"
    }, {
        "label": "徐州市",
        "value": "320300"
    }, {
        "label": "常州市",
        "value": "320400"
    }, {
        "label": "苏州市",
        "value": "320500"
    }, {
        "label": "南通市",
        "value": "320600"
    }, {
        "label": "连云港市",
        "value": "320700"
    }, {
        "label": "淮安市",
        "value": "320800"
    }, {
        "label": "盐城市",
        "value": "320900"
    }, {
        "label": "扬州市",
        "value": "321000"
    }, {
        "label": "镇江市",
        "value": "321100"
    }, {
        "label": "泰州市",
        "value": "321200"
    }, {
        "label": "宿迁市",
        "value": "321300"
    }],
    [{
        "label": "杭州市",
        "value": "330100"
    }, {
        "label": "宁波市",
        "value": "330200"
    }, {
        "label": "温州市",
        "value": "330300"
    }, {
        "label": "嘉兴市",
        "value": "330400"
    }, {
        "label": "湖州市",
        "value": "330500"
    }, {
        "label": "绍兴市",
        "value": "330600"
    }, {
        "label": "金华市",
        "value": "330700"
    }, {
        "label": "衢州市",
        "value": "330800"
    }, {
        "label": "舟山市",
        "value": "330900"
    }, {
        "label": "台州市",
        "value": "331000"
    }, {
        "label": "丽水市",
        "value": "331100"
    }],
    [{
        "label": "合肥市",
        "value": "340100"
    }, {
        "label": "芜湖市",
        "value": "340200"
    }, {
        "label": "蚌埠市",
        "value": "340300"
    }, {
        "label": "淮南市",
        "value": "340400"
    }, {
        "label": "马鞍山市",
        "value": "340500"
    }, {
        "label": "淮北市",
        "value": "340600"
    }, {
        "label": "铜陵市",
        "value": "340700"
    }, {
        "label": "安庆市",
        "value": "340800"
    }, {
        "label": "黄山市",
        "value": "341000"
    }, {
        "label": "滁州市",
        "value": "341100"
    }, {
        "label": "阜阳市",
        "value": "341200"
    }, {
        "label": "宿州市",
        "value": "341300"
    }, {
        "label": "六安市",
        "value": "341500"
    }, {
        "label": "亳州市",
        "value": "341600"
    }, {
        "label": "池州市",
        "value": "341700"
    }, {
        "label": "宣城市",
        "value": "341800"
    }],
    [{
        "label": "福州市",
        "value": "350100"
    }, {
        "label": "厦门市",
        "value": "350200"
    }, {
        "label": "莆田市",
        "value": "350300"
    }, {
        "label": "三明市",
        "value": "350400"
    }, {
        "label": "泉州市",
        "value": "350500"
    }, {
        "label": "漳州市",
        "value": "350600"
    }, {
        "label": "南平市",
        "value": "350700"
    }, {
        "label": "龙岩市",
        "value": "350800"
    }, {
        "label": "宁德市",
        "value": "350900"
    }],
    [{
        "label": "南昌市",
        "value": "360100"
    }, {
        "label": "景德镇市",
        "value": "360200"
    }, {
        "label": "萍乡市",
        "value": "360300"
    }, {
        "label": "九江市",
        "value": "360400"
    }, {
        "label": "新余市",
        "value": "360500"
    }, {
        "label": "鹰潭市",
        "value": "360600"
    }, {
        "label": "赣州市",
        "value": "360700"
    }, {
        "label": "吉安市",
        "value": "360800"
    }, {
        "label": "宜春市",
        "value": "360900"
    }, {
        "label": "抚州市",
        "value": "361000"
    }, {
        "label": "上饶市",
        "value": "361100"
    }],
    [{
        "label": "济南市",
        "value": "370100"
    }, {
        "label": "青岛市",
        "value": "370200"
    }, {
        "label": "淄博市",
        "value": "370300"
    }, {
        "label": "枣庄市",
        "value": "370400"
    }, {
        "label": "东营市",
        "value": "370500"
    }, {
        "label": "烟台市",
        "value": "370600"
    }, {
        "label": "潍坊市",
        "value": "370700"
    }, {
        "label": "济宁市",
        "value": "370800"
    }, {
        "label": "泰安市",
        "value": "370900"
    }, {
        "label": "威海市",
        "value": "371000"
    }, {
        "label": "日照市",
        "value": "371100"
    }, {
        "label": "莱芜市",
        "value": "371200"
    }, {
        "label": "临沂市",
        "value": "371300"
    }, {
        "label": "德州市",
        "value": "371400"
    }, {
        "label": "聊城市",
        "value": "371500"
    }, {
        "label": "滨州市",
        "value": "371600"
    }, {
        "label": "菏泽市",
        "value": "371700"
    }],
    [{
        "label": "郑州市",
        "value": "410100"
    }, {
        "label": "开封市",
        "value": "410200"
    }, {
        "label": "洛阳市",
        "value": "410300"
    }, {
        "label": "平顶山市",
        "value": "410400"
    }, {
        "label": "安阳市",
        "value": "410500"
    }, {
        "label": "鹤壁市",
        "value": "410600"
    }, {
        "label": "新乡市",
        "value": "410700"
    }, {
        "label": "焦作市",
        "value": "410800"
    }, {
        "label": "濮阳市",
        "value": "410900"
    }, {
        "label": "许昌市",
        "value": "411000"
    }, {
        "label": "漯河市",
        "value": "411100"
    }, {
        "label": "三门峡市",
        "value": "411200"
    }, {
        "label": "南阳市",
        "value": "411300"
    }, {
        "label": "商丘市",
        "value": "411400"
    }, {
        "label": "信阳市",
        "value": "411500"
    }, {
        "label": "周口市",
        "value": "411600"
    }, {
        "label": "驻马店市",
        "value": "411700"
    }, {
        "label": "省直辖县级行政区划",
        "value": "419000"
    }],
    [{
        "label": "武汉市",
        "value": "420100"
    }, {
        "label": "黄石市",
        "value": "420200"
    }, {
        "label": "十堰市",
        "value": "420300"
    }, {
        "label": "宜昌市",
        "value": "420500"
    }, {
        "label": "襄阳市",
        "value": "420600"
    }, {
        "label": "鄂州市",
        "value": "420700"
    }, {
        "label": "荆门市",
        "value": "420800"
    }, {
        "label": "孝感市",
        "value": "420900"
    }, {
        "label": "荆州市",
        "value": "421000"
    }, {
        "label": "黄冈市",
        "value": "421100"
    }, {
        "label": "咸宁市",
        "value": "421200"
    }, {
        "label": "随州市",
        "value": "421300"
    }, {
        "label": "恩施土家族苗族自治州",
        "value": "422800"
    }, {
        "label": "省直辖县级行政区划",
        "value": "429000"
    }],
    [{
        "label": "长沙市",
        "value": "430100"
    }, {
        "label": "株洲市",
        "value": "430200"
    }, {
        "label": "湘潭市",
        "value": "430300"
    }, {
        "label": "衡阳市",
        "value": "430400"
    }, {
        "label": "邵阳市",
        "value": "430500"
    }, {
        "label": "岳阳市",
        "value": "430600"
    }, {
        "label": "常德市",
        "value": "430700"
    }, {
        "label": "张家界市",
        "value": "430800"
    }, {
        "label": "益阳市",
        "value": "430900"
    }, {
        "label": "郴州市",
        "value": "431000"
    }, {
        "label": "永州市",
        "value": "431100"
    }, {
        "label": "怀化市",
        "value": "431200"
    }, {
        "label": "娄底市",
        "value": "431300"
    }, {
        "label": "湘西土家族苗族自治州",
        "value": "433100"
    }],
    [{
        "label": "广州市",
        "value": "440100"
    }, {
        "label": "韶关市",
        "value": "440200"
    }, {
        "label": "深圳市",
        "value": "440300"
    }, {
        "label": "珠海市",
        "value": "440400"
    }, {
        "label": "汕头市",
        "value": "440500"
    }, {
        "label": "佛山市",
        "value": "440600"
    }, {
        "label": "江门市",
        "value": "440700"
    }, {
        "label": "湛江市",
        "value": "440800"
    }, {
        "label": "茂名市",
        "value": "440900"
    }, {
        "label": "肇庆市",
        "value": "441200"
    }, {
        "label": "惠州市",
        "value": "441300"
    }, {
        "label": "梅州市",
        "value": "441400"
    }, {
        "label": "汕尾市",
        "value": "441500"
    }, {
        "label": "河源市",
        "value": "441600"
    }, {
        "label": "阳江市",
        "value": "441700"
    }, {
        "label": "清远市",
        "value": "441800"
    }, {
        "label": "东莞市",
        "value": "441900"
    }, {
        "label": "中山市",
        "value": "442000"
    }, {
        "label": "潮州市",
        "value": "445100"
    }, {
        "label": "揭阳市",
        "value": "445200"
    }, {
        "label": "云浮市",
        "value": "445300"
    }],
    [{
        "label": "南宁市",
        "value": "450100"
    }, {
        "label": "柳州市",
        "value": "450200"
    }, {
        "label": "桂林市",
        "value": "450300"
    }, {
        "label": "梧州市",
        "value": "450400"
    }, {
        "label": "北海市",
        "value": "450500"
    }, {
        "label": "防城港市",
        "value": "450600"
    }, {
        "label": "钦州市",
        "value": "450700"
    }, {
        "label": "贵港市",
        "value": "450800"
    }, {
        "label": "玉林市",
        "value": "450900"
    }, {
        "label": "百色市",
        "value": "451000"
    }, {
        "label": "贺州市",
        "value": "451100"
    }, {
        "label": "河池市",
        "value": "451200"
    }, {
        "label": "来宾市",
        "value": "451300"
    }, {
        "label": "崇左市",
        "value": "451400"
    }],
    [{
        "label": "海口市",
        "value": "460100"
    }, {
        "label": "三亚市",
        "value": "460200"
    }, {
        "label": "三沙市",
        "value": "460300"
    }, {
        "label": "儋州市",
        "value": "460400"
    }, {
        "label": "省直辖县级行政区划",
        "value": "469000"
    }],
    [{
        "label": "重庆市",
        "value": "500100"
    }, {
        "label": "县",
        "value": "500200"
    }],
    [{
        "label": "成都市",
        "value": "510100"
    }, {
        "label": "自贡市",
        "value": "510300"
    }, {
        "label": "攀枝花市",
        "value": "510400"
    }, {
        "label": "泸州市",
        "value": "510500"
    }, {
        "label": "德阳市",
        "value": "510600"
    }, {
        "label": "绵阳市",
        "value": "510700"
    }, {
        "label": "广元市",
        "value": "510800"
    }, {
        "label": "遂宁市",
        "value": "510900"
    }, {
        "label": "内江市",
        "value": "511000"
    }, {
        "label": "乐山市",
        "value": "511100"
    }, {
        "label": "南充市",
        "value": "511300"
    }, {
        "label": "眉山市",
        "value": "511400"
    }, {
        "label": "宜宾市",
        "value": "511500"
    }, {
        "label": "广安市",
        "value": "511600"
    }, {
        "label": "达州市",
        "value": "511700"
    }, {
        "label": "雅安市",
        "value": "511800"
    }, {
        "label": "巴中市",
        "value": "511900"
    }, {
        "label": "资阳市",
        "value": "512000"
    }, {
        "label": "阿坝藏族羌族自治州",
        "value": "513200"
    }, {
        "label": "甘孜藏族自治州",
        "value": "513300"
    }, {
        "label": "凉山彝族自治州",
        "value": "513400"
    }],
    [{
        "label": "贵阳市",
        "value": "520100"
    }, {
        "label": "六盘水市",
        "value": "520200"
    }, {
        "label": "遵义市",
        "value": "520300"
    }, {
        "label": "安顺市",
        "value": "520400"
    }, {
        "label": "毕节市",
        "value": "520500"
    }, {
        "label": "铜仁市",
        "value": "520600"
    }, {
        "label": "黔西南布依族苗族自治州",
        "value": "522300"
    }, {
        "label": "黔东南苗族侗族自治州",
        "value": "522600"
    }, {
        "label": "黔南布依族苗族自治州",
        "value": "522700"
    }],
    [{
        "label": "昆明市",
        "value": "530100"
    }, {
        "label": "曲靖市",
        "value": "530300"
    }, {
        "label": "玉溪市",
        "value": "530400"
    }, {
        "label": "保山市",
        "value": "530500"
    }, {
        "label": "昭通市",
        "value": "530600"
    }, {
        "label": "丽江市",
        "value": "530700"
    }, {
        "label": "普洱市",
        "value": "530800"
    }, {
        "label": "临沧市",
        "value": "530900"
    }, {
        "label": "楚雄彝族自治州",
        "value": "532300"
    }, {
        "label": "红河哈尼族彝族自治州",
        "value": "532500"
    }, {
        "label": "文山壮族苗族自治州",
        "value": "532600"
    }, {
        "label": "西双版纳傣族自治州",
        "value": "532800"
    }, {
        "label": "大理白族自治州",
        "value": "532900"
    }, {
        "label": "德宏傣族景颇族自治州",
        "value": "533100"
    }, {
        "label": "怒江傈僳族自治州",
        "value": "533300"
    }, {
        "label": "迪庆藏族自治州",
        "value": "533400"
    }],
    [{
        "label": "拉萨市",
        "value": "540100"
    }, {
        "label": "日喀则市",
        "value": "540200"
    }, {
        "label": "昌都市",
        "value": "540300"
    }, {
        "label": "林芝市",
        "value": "540400"
    }, {
        "label": "山南市",
        "value": "540500"
    }, {
        "label": "那曲地区",
        "value": "542400"
    }, {
        "label": "阿里地区",
        "value": "542500"
    }],
    [{
        "label": "西安市",
        "value": "610100"
    }, {
        "label": "铜川市",
        "value": "610200"
    }, {
        "label": "宝鸡市",
        "value": "610300"
    }, {
        "label": "咸阳市",
        "value": "610400"
    }, {
        "label": "渭南市",
        "value": "610500"
    }, {
        "label": "延安市",
        "value": "610600"
    }, {
        "label": "汉中市",
        "value": "610700"
    }, {
        "label": "榆林市",
        "value": "610800"
    }, {
        "label": "安康市",
        "value": "610900"
    }, {
        "label": "商洛市",
        "value": "611000"
    }],
    [{
        "label": "兰州市",
        "value": "620100"
    }, {
        "label": "嘉峪关市",
        "value": "620200"
    }, {
        "label": "金昌市",
        "value": "620300"
    }, {
        "label": "白银市",
        "value": "620400"
    }, {
        "label": "天水市",
        "value": "620500"
    }, {
        "label": "武威市",
        "value": "620600"
    }, {
        "label": "张掖市",
        "value": "620700"
    }, {
        "label": "平凉市",
        "value": "620800"
    }, {
        "label": "酒泉市",
        "value": "620900"
    }, {
        "label": "庆阳市",
        "value": "621000"
    }, {
        "label": "定西市",
        "value": "621100"
    }, {
        "label": "陇南市",
        "value": "621200"
    }, {
        "label": "临夏回族自治州",
        "value": "622900"
    }, {
        "label": "甘南藏族自治州",
        "value": "623000"
    }],
    [{
        "label": "西宁市",
        "value": "630100"
    }, {
        "label": "海东市",
        "value": "630200"
    }, {
        "label": "海北藏族自治州",
        "value": "632200"
    }, {
        "label": "黄南藏族自治州",
        "value": "632300"
    }, {
        "label": "海南藏族自治州",
        "value": "632500"
    }, {
        "label": "果洛藏族自治州",
        "value": "632600"
    }, {
        "label": "玉树藏族自治州",
        "value": "632700"
    }, {
        "label": "海西蒙古族藏族自治州",
        "value": "632800"
    }],
    [{
        "label": "银川市",
        "value": "640100"
    }, {
        "label": "石嘴山市",
        "value": "640200"
    }, {
        "label": "吴忠市",
        "value": "640300"
    }, {
        "label": "固原市",
        "value": "640400"
    }, {
        "label": "中卫市",
        "value": "640500"
    }],
    [{
        "label": "乌鲁木齐市",
        "value": "650100"
    }, {
        "label": "克拉玛依市",
        "value": "650200"
    }, {
        "label": "吐鲁番市",
        "value": "650400"
    }, {
        "label": "哈密市",
        "value": "650500"
    }, {
        "label": "昌吉回族自治州",
        "value": "652300"
    }, {
        "label": "博尔塔拉蒙古自治州",
        "value": "652700"
    }, {
        "label": "巴音郭楞蒙古自治州",
        "value": "652800"
    }, {
        "label": "阿克苏地区",
        "value": "652900"
    }, {
        "label": "克孜勒苏柯尔克孜自治州",
        "value": "653000"
    }, {
        "label": "喀什地区",
        "value": "653100"
    }, {
        "label": "和田地区",
        "value": "653200"
    }, {
        "label": "伊犁哈萨克自治州",
        "value": "654000"
    }, {
        "label": "塔城地区",
        "value": "654200"
    }, {
        "label": "阿勒泰地区",
        "value": "654300"
    }, {
        "label": "自治区直辖县级行政区划",
        "value": "659000"
    }]
]
export default cityData;
province.js
/* eslint-disable */
var provinceData = [{
    "label": "北京市",
    "value": "110000"
}, {
    "label": "天津市",
    "value": "120000"
}, {
    "label": "河北省",
    "value": "130000"
}, {
    "label": "山西省",
    "value": "140000"
}, {
    "label": "内蒙古自治区",
    "value": "150000"
}, {
    "label": "辽宁省",
    "value": "210000"
}, {
    "label": "吉林省",
    "value": "220000"
}, {
    "label": "黑龙江省",
    "value": "230000"
}, {
    "label": "上海市",
    "value": "310000"
}, {
    "label": "江苏省",
    "value": "320000"
}, {
    "label": "浙江省",
    "value": "330000"
}, {
    "label": "安徽省",
    "value": "340000"
}, {
    "label": "福建省",
    "value": "350000"
}, {
    "label": "江西省",
    "value": "360000"
}, {
    "label": "山东省",
    "value": "370000"
}, {
    "label": "河南省",
    "value": "410000"
}, {
    "label": "湖北省",
    "value": "420000"
}, {
    "label": "湖南省",
    "value": "430000"
}, {
    "label": "广东省",
    "value": "440000"
}, {
    "label": "广西壮族自治区",
    "value": "450000"
}, {
    "label": "海南省",
    "value": "460000"
}, {
    "label": "重庆市",
    "value": "500000"
}, {
    "label": "四川省",
    "value": "510000"
}, {
    "label": "贵州省",
    "value": "520000"
}, {
    "label": "云南省",
    "value": "530000"
}, {
    "label": "西藏自治区",
    "value": "540000"
}, {
    "label": "陕西省",
    "value": "610000"
}, {
    "label": "甘肃省",
    "value": "620000"
}, {
    "label": "青海省",
    "value": "630000"
}, {
    "label": "宁夏回族自治区",
    "value": "640000"
}, {
    "label": "新疆维吾尔自治区",
    "value": "650000"
}, {
    "label": "台湾省",
    "value": "710000"
}, {
    "label": "香港特别行政区",
    "value": "810000"
}, {
    "label": "澳门特别行政区",
    "value": "820000"
}]
export default provinceData;
mpvueCityPicker.vue
<template>
  <div class="mpvue-picker">
    <div :class="{'pickerMask':showPicker}" @click="maskClick" catchtouchmove="true"></div>
    <div class="mpvue-picker-content " :class="{'mpvue-picker-view-show':showPicker}">
      <div class="mpvue-picker__hd" catchtouchmove="true">
        <div class="mpvue-picker__action" @click="pickerCancel">取消</div>
        <div class="mpvue-picker__action" :style="{color:themeColor}" @click="pickerConfirm">确定</div>
      </div>
      <picker-view indicator-style="height: 40px;" class="mpvue-picker-view" :value="pickerValue" @change="pickerChange">
        <block>
          <picker-view-column>
            <div class="picker-item" v-for="(item,index) in provinceDataList" :key="index">{{item.label}}</div>
          </picker-view-column>
          <picker-view-column>
            <div class="picker-item" v-for="(item,index) in cityDataList" :key="index">{{item.label}}</div>
          </picker-view-column>
          <picker-view-column>
            <div class="picker-item" v-for="(item,index) in areaDataList" :key="index">{{item.label}}</div>
          </picker-view-column>
        </block>
      </picker-view>
    </div>
  </div>
</template>

<script>
import provinceData from './city-data/province.js';
import cityData from './city-data/city.js';
import areaData from './city-data/area.js';
export default {
  data() {
    return {
      pickerValue: [0, 0, 0],
      provinceDataList: [],
      cityDataList: [],
      areaDataList: [],
            /* 是否显示控件 */
            showPicker: false,
    };
  },
  created() {
    this.init()
  },
  props: {
    /* 默认值 */
    pickerValueDefault: {
      type: Array,
      default(){
                return [0, 0, 0]
            }
    },
    /* 主题色 */
    themeColor: String
  },
    watch:{
        pickerValueDefault(){
            this.init();
        }
    },
  methods: {
        init() {
            this.handPickValueDefault(); // 对 pickerValueDefault 做兼容处理
            this.provinceDataList = provinceData;
            this.cityDataList = cityData[this.pickerValueDefault[0]];
            this.areaDataList = areaData[this.pickerValueDefault[0]][this.pickerValueDefault[1]];
            this.pickerValue = this.pickerValueDefault;
        
        },
    show() {
      setTimeout(() => {
        this.showPicker = true;
      }, 0);
    },
    maskClick() {
      this.pickerCancel();
    },
    pickerCancel() {
      this.showPicker = false;
      this._$emit('onCancel');
    },
    pickerConfirm(e) {
      this.showPicker = false;
      this._$emit('onConfirm');
    },
    showPickerView() {
      this.showPicker = true;
    },
    handPickValueDefault() {
                
      if (this.pickerValueDefault !== [0, 0, 0]) {
        if (this.pickerValueDefault[0] > provinceData.length - 1) {
          this.pickerValueDefault[0] = provinceData.length - 1;
        }
                
        if (this.pickerValueDefault[1] > cityData[this.pickerValueDefault[0]].length - 1) {
          this.pickerValueDefault[1] = cityData[this.pickerValueDefault[0]].length - 1;
        }
        if (this.pickerValueDefault[2] > areaData[this.pickerValueDefault[0]][this.pickerValueDefault[1]].length - 1) {
          this.pickerValueDefault[2] = areaData[this.pickerValueDefault[0]][this.pickerValueDefault[1]].length - 1;
        }
      }
    },
    pickerChange(e) {
      let changePickerValue = e.mp.detail.value;
      if (this.pickerValue[0] !== changePickerValue[0]) {
        // 第一级发生滚动
        this.cityDataList = cityData[changePickerValue[0]];
        this.areaDataList = areaData[changePickerValue[0]][0];
        changePickerValue[1] = 0;
        changePickerValue[2] = 0;
      } else if (this.pickerValue[1] !== changePickerValue[1]) {
        // 第二级滚动
        this.areaDataList =
          areaData[changePickerValue[0]][changePickerValue[1]];
        changePickerValue[2] = 0;
      }
      this.pickerValue = changePickerValue;
      this._$emit('onChange');
    },
    _$emit(emitName) {
      let pickObj = {
        label: this._getLabel(),
        value: this.pickerValue,
        cityCode: this._getCityCode()
      };
      this.$emit(emitName, pickObj);
    },
    _getLabel() {
      let pcikerLabel =
        this.provinceDataList[this.pickerValue[0]].label +
        '-' +
        this.cityDataList[this.pickerValue[1]].label +
        '-' +
        this.areaDataList[this.pickerValue[2]].label;
      return pcikerLabel;
    },
    _getCityCode() {
      return this.areaDataList[this.pickerValue[2]].value;
    }
  }
};
</script>

<style>
.pickerMask {
  position: fixed;
  z-index: 1000;
  top: 0;
  right: 0;
  left: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.6);
}
.mpvue-picker-content {
  position: fixed;
  bottom: 0;
  left: 0;
  width: 100%;
  transition: all 0.3s ease;
  transform: translateY(100%);
  z-index: 3000;
}
.mpvue-picker-view-show {
  transform: translateY(0);
}
.mpvue-picker__hd {
  display: flex;
  padding: 9px 15px;
  background-color: #fff;
  position: relative;
  text-align: center;
  font-size: 17px;
}
.mpvue-picker__hd:after {
  content: ' ';
  position: absolute;
  left: 0;
  bottom: 0;
  right: 0;
  height: 1px;
  border-bottom: 1px solid #e5e5e5;
  color: #e5e5e5;
  transform-origin: 0 100%;
  transform: scaleY(0.5);
}
.mpvue-picker__action {
  display: block;
  flex: 1;
  color: #1aad19;
}
.mpvue-picker__action:first-child {
  text-align: left;
  color: #888;
}
.mpvue-picker__action:last-child {
  text-align: right;
}
.picker-item {
  text-align: center;
  line-height: 40px;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 16px;
}
.mpvue-picker-view {
  position: relative;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 238px;
  background-color: rgba(255, 255, 255, 1);
}
</style>

mpvue-picker

mpvuePicker.vue
<template>
    <view class="mpvue-picker">
        <view :class="{'pickerMask':showPicker}" @click="maskClick" catchtouchmove="true"></view>
        <view class="mpvue-picker-content " :class="{'mpvue-picker-view-show':showPicker}">
            <view class="mpvue-picker__hd" catchtouchmove="true">
                <view class="mpvue-picker__action" @click="pickerCancel">取消</view>
                <view class="mpvue-picker__action" :style="{color:themeColor}" @click="pickerConfirm">确定</view>
            </view>
            <!-- 单列 -->
            <picker-view indicator-style="height: 40px;" class="mpvue-picker-view" :value="pickerValue" @change="pickerChange" v-if="mode==='selector' && pickerValueSingleArray.length > 0">
                <block>
                    <picker-view-column>
                        <view class="picker-item" v-for="(item,index) in pickerValueSingleArray" :key="index">{{item.label}}</view>
                    </picker-view-column>
                </block>
            </picker-view>
            <!-- 时间选择器 -->
            <picker-view indicator-style="height: 40px;" class="mpvue-picker-view" :value="pickerValue" @change="pickerChange" v-if="mode==='timeSelector'">
                <block>
                    <picker-view-column>
                        <view class="picker-item" v-for="(item,index) in pickerValueHour" :key="index">{{item.label}}</view>
                    </picker-view-column>
                    <picker-view-column>
                        <view class="picker-item" v-for="(item,index) in pickerValueMinute" :key="index">{{item.label}}</view>
                    </picker-view-column>
                </block>
            </picker-view>
            <!-- 多列选择 -->
            <picker-view indicator-style="height: 40px;" class="mpvue-picker-view" :value="pickerValue" @change="pickerChange" v-if="mode==='multiSelector'">
                <block v-for="(n,index) in pickerValueMulArray.length" :key="index">
                    <picker-view-column>
                        <view class="picker-item" v-for="(item,index1) in pickerValueMulArray[n]" :key="index1">{{item.label}}</view>
                    </picker-view-column>
                </block>
            </picker-view>
            <!-- 二级联动 -->
            <picker-view indicator-style="height: 40px;" class="mpvue-picker-view" :value="pickerValue" @change="pickerChangeMul" v-if="mode==='multiLinkageSelector' && deepLength===2">
                <block>
                    <picker-view-column>
                        <view class="picker-item" v-for="(item,index) in pickerValueMulTwoOne" :key="index">{{item.label}}</view>
                    </picker-view-column>
                    <picker-view-column>
                        <view class="picker-item" v-for="(item,index) in pickerValueMulTwoTwo" :key="index">{{item.label}}</view>
                    </picker-view-column>
                </block>
            </picker-view>
            <!-- 三级联动 -->
            <picker-view indicator-style="height: 40px;" class="mpvue-picker-view" :value="pickerValue" @change="pickerChangeMul" v-if="mode==='multiLinkageSelector' && deepLength===3">
                <block>
                    <picker-view-column>
                        <view class="picker-item" v-for="(item,index) in pickerValueMulThreeOne" :key="index">{{item.label}}</view>
                    </picker-view-column>
                    <picker-view-column>
                        <view class="picker-item" v-for="(item,index) in pickerValueMulThreeTwo" :key="index">{{item.label}}</view>
                    </picker-view-column>
                    <picker-view-column>
                        <view class="picker-item" v-for="(item,index) in pickerValueMulThreeThree" :key="index">{{item.label}}</view>
                    </picker-view-column>
                </block>
            </picker-view>
        </view>
    </view>
</template>

<script>
    export default {
        data() {
            return {
                pickerChangeValue: [],
                pickerValue: [],
                pickerValueArrayChange: true,
                modeChange: false,
                pickerValueSingleArray: [],
                pickerValueHour: [],
                pickerValueMinute: [],
                pickerValueMulArray: [],
                pickerValueMulTwoOne: [],
                pickerValueMulTwoTwo: [],
                pickerValueMulThreeOne: [],
                pickerValueMulThreeTwo: [],
                pickerValueMulThreeThree: [],
                /* 是否显示控件 */
                showPicker: false,
            };
        },
        props: {
            /* mode */
            mode: {
                type: String,
                default: 'selector'
            },
            /* picker 数值 */
            pickerValueArray: {
                type: Array,
                default(){
                    return []
                }
            },
            /* 默认值 */
            pickerValueDefault: {
                type: Array,
                default(){
                    return []
                }
            },
            /* 几级联动 */
            deepLength: {
                type: Number,
                default: 2
            },
            /* 主题色 */
            themeColor: String
        },
        watch: {
            pickerValueArray(oldVal, newVal) {
                this.pickerValueArrayChange = true;
            },
            mode(oldVal, newVal) {
                this.modeChange = true;
            },
            pickerValueArray(val){
                this.initPicker(val);
            }
        },
        methods: {
            initPicker(valueArray) {
                let pickerValueArray = valueArray;
                this.pickerValue = this.pickerValueDefault;
                // 初始化多级联动
                if (this.mode === 'selector') {
                    this.pickerValueSingleArray = valueArray;
                } else if (this.mode === 'timeSelector') {
                    this.modeChange = false;
                    let hourArray = [];
                    let minuteArray = [];
                    for (let i = 0; i < 24; i++) {
                        hourArray.push({
                            value: i,
                            label: i > 9 ? `${i} 时` : `0${i} 时`
                        });
                    }
                    for (let i = 0; i < 60; i++) {
                        minuteArray.push({
                            value: i,
                            label: i > 9 ? `${i} 分` : `0${i} 分`
                        });
                    }
                    this.pickerValueHour = hourArray;
                    this.pickerValueMinute = minuteArray;
                } else if (this.mode === 'multiSelector') {
                    this.pickerValueMulArray = valueArray;
                } else if (this.mode === 'multiLinkageSelector' && this.deepLength === 2) {
                    // 两级联动
                    let pickerValueMulTwoOne = [];
                    let pickerValueMulTwoTwo = [];
                    // 第一列
                    for (let i = 0, length = pickerValueArray.length; i < length; i++) {
                        pickerValueMulTwoOne.push(pickerValueArray[i]);
                    }
                    // 渲染第二列
                    // 如果有设定的默认值
                    if (this.pickerValueDefault.length === 2) {
                        let num = this.pickerValueDefault[0];
                        for (
                            let i = 0, length = pickerValueArray[num].children.length; i < length; i++
                        ) {
                            pickerValueMulTwoTwo.push(pickerValueArray[num].children[i]);
                        }
                    } else {
                        for (
                            let i = 0, length = pickerValueArray[0].children.length; i < length; i++
                        ) {
                            pickerValueMulTwoTwo.push(pickerValueArray[0].children[i]);
                        }
                    }
                    this.pickerValueMulTwoOne = pickerValueMulTwoOne;
                    this.pickerValueMulTwoTwo = pickerValueMulTwoTwo;
                } else if (
                    this.mode === 'multiLinkageSelector' &&
                    this.deepLength === 3
                ) {
                    let pickerValueMulThreeOne = [];
                    let pickerValueMulThreeTwo = [];
                    let pickerValueMulThreeThree = [];
                    // 第一列
                    for (let i = 0, length = pickerValueArray.length; i < length; i++) {
                        pickerValueMulThreeOne.push(pickerValueArray[i]);
                    }
                    // 渲染第二列
                    this.pickerValueDefault =
                        this.pickerValueDefault.length === 3 ?
                        this.pickerValueDefault :
                        [0, 0, 0];
                    if (this.pickerValueDefault.length === 3) {
                        let num = this.pickerValueDefault[0];
                        for (
                            let i = 0, length = pickerValueArray[num].children.length; i < length; i++
                        ) {
                            pickerValueMulThreeTwo.push(pickerValueArray[num].children[i]);
                        }
                        // 第三列
                        let numSecond = this.pickerValueDefault[1];
                        for (let i = 0, length = pickerValueArray[num].children[numSecond].children.length; i < length; i++) {
                            pickerValueMulThreeThree.push(
                                pickerValueArray[num].children[numSecond].children[i]
                            );
                        }
                    }
                    this.pickerValueMulThreeOne = pickerValueMulThreeOne;
                    this.pickerValueMulThreeTwo = pickerValueMulThreeTwo;
                    this.pickerValueMulThreeThree = pickerValueMulThreeThree;
                }
            },
            show() {
                setTimeout(() => {
                    if (this.pickerValueArrayChange || this.modeChange) {
                        this.initPicker(this.pickerValueArray);
                        this.showPicker = true;
                        this.pickerValueArrayChange = false;
                        this.modeChange = false;
                    } else {
                        this.showPicker = true;
                    }
                }, 0);
            },
            maskClick() {
                this.pickerCancel();
            },
            pickerCancel() {
                this.showPicker = false;
                this._initPickerVale();
                let pickObj = {
                    index: this.pickerValue,
                    value: this._getPickerLabelAndValue(this.pickerValue, this.mode).value,
                    label: this._getPickerLabelAndValue(this.pickerValue, this.mode).label
                };
                this.$emit('onCancel', pickObj);
            },
            pickerConfirm(e) {
                this.showPicker = false;
                this._initPickerVale();
                let pickObj = {
                    index: this.pickerValue,
                    value: this._getPickerLabelAndValue(this.pickerValue, this.mode).value,
                    label: this._getPickerLabelAndValue(this.pickerValue, this.mode).label
                };
                this.$emit('onConfirm', pickObj);
            },
            showPickerView() {
                this.showPicker = true;
            },
            pickerChange(e) {
                this.pickerValue = e.mp.detail.value;
                let pickObj = {
                    index: this.pickerValue,
                    value: this._getPickerLabelAndValue(this.pickerValue, this.mode).value,
                    label: this._getPickerLabelAndValue(this.pickerValue, this.mode).label
                };
                this.$emit('onChange', pickObj);
            },
            pickerChangeMul(e) {
                if (this.deepLength === 2) {
                    let pickerValueArray = this.pickerValueArray;
                    let changeValue = e.mp.detail.value;
                    // 处理第一列滚动
                    if (changeValue[0] !== this.pickerValue[0]) {
                        let pickerValueMulTwoTwo = [];
                        // 第一列滚动第二列数据更新
                        for (let i = 0, length = pickerValueArray[changeValue[0]].children.length; i < length; i++) {
                            pickerValueMulTwoTwo.push(pickerValueArray[changeValue[0]].children[i]);
                        }
                        this.pickerValueMulTwoTwo = pickerValueMulTwoTwo;
                        // 第二列初始化为 0
                        changeValue[1] = 0;
                    }
                    this.pickerValue = changeValue;
                } else if (this.deepLength === 3) {
                    let pickerValueArray = this.pickerValueArray;
                    let changeValue = e.mp.detail.value;
                    let pickerValueMulThreeTwo = [];
                    let pickerValueMulThreeThree = [];
                    // 重新渲染第二列
                    // 如果是第一列滚动
                    if (changeValue[0] !== this.pickerValue[0]) {
                        this.pickerValueMulThreeTwo = [];
                        for (let i = 0, length = pickerValueArray[changeValue[0]].children.length; i < length; i++) {
                            pickerValueMulThreeTwo.push(pickerValueArray[changeValue[0]].children[i]);
                        }
                        // 重新渲染第三列
                        for (let i = 0, length = pickerValueArray[changeValue[0]].children[0].children.length; i <
                            length; i++) {
                            pickerValueMulThreeThree.push(pickerValueArray[changeValue[0]].children[0].children[i]);
                        }
                        changeValue[1] = 0;
                        changeValue[2] = 0;
                        this.pickerValueMulThreeTwo = pickerValueMulThreeTwo;
                        this.pickerValueMulThreeThree = pickerValueMulThreeThree;
                    } else if (changeValue[1] !== this.pickerValue[1]) {
                        // 第二列滚动
                        // 重新渲染第三列
                        this.pickerValueMulThreeThree = [];
                        pickerValueMulThreeTwo = this.pickerValueMulThreeTwo;
                        for (let i = 0, length = pickerValueArray[changeValue[0]].children[changeValue[1]].children.length; i <
                            length; i++) {
                            pickerValueMulThreeThree.push(pickerValueArray[changeValue[0]].children[changeValue[1]].children[
                                i]);
                        }
                        changeValue[2] = 0;
                        this.pickerValueMulThreeThree = pickerValueMulThreeThree;
                    }
                    this.pickerValue = changeValue;
                }
                let pickObj = {
                    index: this.pickerValue,
                    value: this._getPickerLabelAndValue(this.pickerValue, this.mode).value,
                    label: this._getPickerLabelAndValue(this.pickerValue, this.mode).label
                };
                this.$emit('onChange', pickObj);
            },
            // 获取 pxikerLabel
            _getPickerLabelAndValue(value, mode) {
                let pickerLable;
                let pickerGetValue = [];
                // selector
                if (mode === 'selector') {
                    pickerLable = this.pickerValueSingleArray[value].label;
                    pickerGetValue.push(this.pickerValueSingleArray[value].value);
                } else if (mode === 'timeSelector') {
                    pickerLable = `${this.pickerValueHour[value[0]].label}-${this.pickerValueMinute[value[1]].label}`;
                    pickerGetValue.push(this.pickerValueHour[value[0]].value);
                    pickerGetValue.push(this.pickerValueHour[value[1]].value);
                } else if (mode === 'multiSelector') {
                    for (let i = 0; i < value.length; i++) {
                        if (i > 0) {
                            pickerLable += this.pickerValueMulArray[i][value[i]].label + (i === value.length - 1 ? '' :
                                '-');
                        } else {
                            pickerLable = this.pickerValueMulArray[i][value[i]].label + '-';
                        }
                        pickerGetValue.push(this.pickerValueMulArray[i][value[i]].value);
                    }
                } else if (mode === 'multiLinkageSelector') {
                    /* eslint-disable indent */
                    pickerLable =
                        this.deepLength === 2 ?
                        `${this.pickerValueMulTwoOne[value[0]].label}-${this.pickerValueMulTwoTwo[value[1]].label}` :
                        `${this.pickerValueMulThreeOne[value[0]].label}-${this.pickerValueMulThreeTwo[value[1]].label}-${this.pickerValueMulThreeThree[value[2]].label}`;
                    if (this.deepLength === 2) {
                        pickerGetValue.push(this.pickerValueMulTwoOne[value[0]].value);
                        pickerGetValue.push(this.pickerValueMulTwoTwo[value[1]].value);
                    } else {
                        pickerGetValue.push(this.pickerValueMulThreeOne[value[0]].value);
                        pickerGetValue.push(this.pickerValueMulThreeTwo[value[1]].value);
                        pickerGetValue.push(this.pickerValueMulThreeThree[value[2]].value);
                    }
                    /* eslint-enable indent */
                }
                return {
                    label: pickerLable,
                    value: pickerGetValue
                };
            },
            // 初始化 pickerValue 默认值
            _initPickerVale() {
                if (this.pickerValue.length === 0) {
                    if (this.mode === 'selector') {
                        this.pickerValue = [0];
                    } else if (this.mode === 'multiSelector') {
                        this.pickerValue = new Int8Array(this.pickerValueArray.length);
                    } else if (
                        this.mode === 'multiLinkageSelector' &&
                        this.deepLength === 2
                    ) {
                        this.pickerValue = [0, 0];
                    } else if (
                        this.mode === 'multiLinkageSelector' &&
                        this.deepLength === 3
                    ) {
                        this.pickerValue = [0, 0, 0];
                    }
                }
            }
        }
    };
</script>

<style>
    .pickerMask {
        position: fixed;
        z-index: 1000;
        top: 0;
        right: 0;
        left: 0;
        bottom: 0;
        background: rgba(0, 0, 0, 0.6);
    }

    .mpvue-picker-content {
        position: fixed;
        bottom: 0;
        left: 0;
        width: 100%;
        transition: all 0.3s ease;
        transform: translateY(100%);
        z-index: 3000;
    }

    .mpvue-picker-view-show {
        transform: translateY(0);
    }

    .mpvue-picker__hd {
        display: flex;
        padding: 9px 15px;
        background-color: #fff;
        position: relative;
        text-align: center;
        font-size: 17px;
    }

    .mpvue-picker__hd:after {
        content: ' ';
        position: absolute;
        left: 0;
        bottom: 0;
        right: 0;
        height: 1px;
        border-bottom: 1px solid #e5e5e5;
        color: #e5e5e5;
        transform-origin: 0 100%;
        transform: scaleY(0.5);
    }

    .mpvue-picker__action {
        display: block;
        flex: 1;
        color: #1aad19;
    }

    .mpvue-picker__action:first-child {
        text-align: left;
        color: #888;
    }

    .mpvue-picker__action:last-child {
        text-align: right;
    }

    .picker-item {
        text-align: center;
        line-height: 40px;
        font-size: 16px;
    }

    .mpvue-picker-view {
        position: relative;
        bottom: 0;
        left: 0;
        width: 100%;
        height: 238px;
        background-color: rgba(255, 255, 255, 1);
    }
</style>

payments

paymentsByAli.vue
<template>
    <view class='cell-group payment-method'>
        <view class='cell-item add-title-item' v-for="item in payments" :key="item.code" @click="toPayHandler(item.code)"
         v-if="!(type == 2 && item.code == 'balancepay')">
            <view class='cell-item-hd'>
                <image class='cell-hd-icon' :src='item.icon'></image>
            </view>
            <view class='cell-item-bd'>
                <view class="cell-bd-view">
                    <text class="cell-bd-text">{{ item.name }}</text>
                </view>
                <view class="cell-bd-view">
                    <text class="cell-bd-text address">{{ item.memo }}</text>
                </view>
            </view>
            <view class='cell-item-ft'>
                <image class='cell-ft-next icon' src='/static/image/right.png'></image>
            </view>
        </view>
        <view class="payment-pop" v-show="popShow">
            <view class="payment-pop-c">
                <image src="/static/image/wait-pay.png" style="width: 30px;
        height: 30px;"></image>
                <view class="text">支付中,请稍后...</view>
            </view>
            <view class="payment-pop-b">
                <button class="btn btn-c" @click="popBtn">支付失败</button>
                <button class="btn btn-o" @click="popBtn">支付成功</button>
            </view>
        </view>
    </view>
</template>

<script>
    import {
        apiBaseUrl
    } from '@/config/config.js';
    export default {
        props: {
            // 如果是商品订单此参数必须
            orderId: {
                type: String,
                default () {
                    return '';
                }
            },
            // 如果是充值订单此参数必须
            recharge: {
                type: Number,
                default () {
                    return 0;
                }
            },
            // 用户id
            uid: {
                type: Number,
                default () {
                    return 0;
                }
            },
            // 订单类型
            type: {
                type: Number,
                default () {
                    return 1;
                }
            }
        },
        data() {
            return {
                payments: [],
                popShow: false
            }
        },
        mounted() {
            this.getPayments();
        },
        methods: {
            // 获取可用支付方式列表
            getPayments() {
                this.$api.paymentList({}, res => {
                    if (res.status) {
                        this.payments = this.formatPayments(res.data);
                    }
                })
            },
            // 支付方式处理
            formatPayments(payments) {
                payments = payments.filter(item => item.code !== 'wechatpay');


                // 如果是充值订单 过滤余额支付 过滤非线上支付方式
                if (this.type === 2) {
                    payments = payments.filter(item => item.code !== 'balancepay' || item.is_online === 1)
                }

                // 设置logo图片
                payments.forEach(item => {
                    this.$set(item, 'icon', '/static/image/' + item.code + '.png');
                });

                return payments;
            },
            // 用户点击支付方式处理
            toPayHandler(code) {
                this.popShow = true;
                let data = {
                    payment_code: code,
                    payment_type: this.type
                }
                data['ids'] = (this.type == 1 || this.type == 5 || this.type == 6) ? this.orderId : this.uid

                // 判断订单支付类型
                if (this.type == 2 && this.recharge) {
                    data['params'] = {
                        money: this.recharge,
                        trade_type: 'JSAPI'
                    }
                } else if ((this.type == 5 || this.type == 6) && this.recharge) {
                    data['params'] = {
                        trade_type: 'JSAPI',
                        formid: this.orderId
                    }
                } else {
                    data['params'] = {
                        trade_type: 'JSAPI'
                    }
                }


                let _this = this;
                switch (code) {
                    case 'alipay':
                        this.$api.pay(data, res => {
                            if (res.status) {
                                uni.requestPayment({
                                    provider: 'alipay',
                                    tradeNO: res.data.trade_no,
                                    success: function(e) {
                                        if (e.errMsg === 'requestPayment:ok') {
                                            _this.$common.successToShow(res.msg, () => {
                                                _this.$common.redirectTo('/pages/goods/payment/result?id=' + res.data.payment_id);
                                            });
                                        }
                                    }
                                });
                            } else {
                                this.$common.errorToShow(res.msg);
                            }
                        })
                        break
                    case 'balancepay':
                        //用户余额支付
                        this.$api.pay(data, res => {
                            if (res.status) {
                                this.$common.redirectTo('/pages/goods/payment/result?id=' + res.data.payment_id);
                            } else {
                                this.$common.errorToShow(res.msg);
                            }
                        })
                        break;
                    case 'offline':
                        //线下支付
                        this.$common.modelShow('线下支付说明', '请联系客服进行线下支付', () => {}, false, '取消', '确定')
                        break;
                }

            },
            ,
            // 支付中显示隐藏
            popBtn() {
                this.popShow = false
            }
        }

    }
</script>

<style>
    .payment-method .cell-item-hd {
        min-width: 70upx;
    }

    .payment-method .cell-hd-icon {
        width: 70upx;
        height: 70upx;
    }

    .payment-method .cell-item-bd {
        border-left: 2upx solid #F0F0F0;
        padding-left: 30upx;
    }

    .payment-method .cell-bd-text {
        font-size: 28upx;
        color: #666;
    }

    .payment-method .address {
        font-size: 24upx;
        color: #999;
    }


    .payment-pop {
        position: fixed;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        width: 400rpx;
        height: 272rpx;
        background-color: #fff;
        text-align: center;
        box-shadow: 0 0 20rpx #ccc;
        /* border-radius: 10rpx; */
    }

    .payment-pop-c {
        padding: 50rpx 30rpx;
        /* line-height: 300rpx; */
        font-size: 32rpx;
        color: #999;
    }

    .payment-pop-b {
        position: absolute;
        bottom: 0;
        display: flex;
        width: 100%;
        justify-content: space-between;
    }

    .payment-pop-b .btn {
        flex: 1;
    }

    .payment-pop .text {
        font-size: 24upx;
    }
</style>
paymentsByApp.vue
<template>
    <view class='cell-group payment-method'>
        <view class='cell-item add-title-item' v-for="item in payments" :key="item.code" @click="toPayHandler(item.code)"
         v-if="!(type == 2 && item.code == 'balancepay')">
            <view class='cell-item-hd'>
                <image class='cell-hd-icon' :src='item.icon'></image>
            </view>
            <view class='cell-item-bd'>
                <view class="cell-bd-view">
                    <text class="cell-bd-text">{{ item.name }}</text>
                </view>
                <view class="cell-bd-view">
                    <text class="cell-bd-text address">{{ item.memo }}</text>
                </view>
            </view>
            <view class='cell-item-ft'>
                <image class='cell-ft-next icon' src='/static/image/right.png'></image>
            </view>
        </view>
        <view class="payment-pop" v-show="popShow">
            <view class="payment-pop-c">
                <image src="/static/image/wait-pay.png" style="width: 30px;
        height: 30px;"></image>
                <view class="text">支付中,请稍后...</view>
            </view>
            <view class="payment-pop-b">
                <button class="btn btn-c" @click="popBtn">支付失败</button>
                <button class="btn btn-o" @click="popBtn">支付成功</button>
            </view>
        </view>
    </view>
</template>

<script>
    import {
        apiBaseUrl
    } from '@/config/config.js'
    export default {
        props: {
            // 如果是商品订单此参数必须
            orderId: {
                type: String,
                default () {
                    return ''
                }
            },
            // 如果是充值订单此参数必须
            recharge: {
                type: Number,
                default () {
                    return 0
                }
            },
            // 用户id
            uid: {
                type: Number,
                default () {
                    return 0
                }
            },
            // 订单类型
            type: {
                type: Number,
                default () {
                    return 1
                }
            }
        },
        data() {
            return {
                payments: [],
                popShow: false
            }
        },
        mounted() {

            this.getPayments()
        },
        methods: {
            // 获取可用支付方式列表
            getPayments() {
                this.$api.paymentList({}, res => {
                    if (res.status) {
                        this.payments = this.formatPayments(res.data)
                    }
                })
            },
            // 支付方式处理
            formatPayments(payments) {
                // 如果是充值订单 过滤余额支付 过滤非线上支付方式
                if (this.type === 2) {
                    payments = payments.filter(item => item.code !== 'balancepay' || item.is_online === 1)
                }

                // 设置logo图片
                payments.forEach(item => {
                    this.$set(item, 'icon', '/static/image/' + item.code + '.png')
                })
                return payments
            },
            // 用户点击支付方式处理
            toPayHandler(code) {
                this.popShow = true;
                let _this = this

                let data = {
                    payment_code: code,
                    payment_type: _this.type
                }

                data['ids'] = (this.type == 1 || this.type == 5 || this.type == 6) ? this.orderId : this.uid
                if ((this.type == 5 || this.type == 6) && this.recharge) {
                    data['params'] = {
                        trade_type: 'APP',
                        formid: this.orderId
                    }
                }
                switch (code) {
                    case 'alipay':
                        /**
                         * 支付宝支付需要模拟GET提交数据
                         */
                        if (_this.type == 1 && _this.orderId) {
                            data['params'] = {
                                trade_type: 'APP'
                            }
                        } else if (_this.type == 2 && _this.recharge) {
                            data['params'] = {
                                trade_type: 'APP',
                                money: _this.recharge
                            }
                        }

                        _this.$api.pay(data, res => {
                            if (res.status) {
                                uni.requestPayment({
                                    provider: "alipay",
                                    orderInfo: res.data.data,
                                    success: function(data) {
                                        _this.$common.successToShow('支付成功', () => {
                                            _this.redirectHandler(res.data.payment_id)
                                        })
                                    }
                                });
                            } else {
                                _this.$comon.errorToShow(res.msg)
                            }
                        })
                        break
                    case 'wechatpay':
                        // 微信 H5支付
                        if (_this.type == 1 && _this.orderId) {
                            data['params'] = {
                                trade_type: 'APP'
                            }
                        } else if (_this.type == 2 && _this.recharge) {
                            data['params'] = {
                                trade_type: 'APP',
                                money: _this.recharge
                            }
                        }

                        // 微信app支付
                        _this.$api.pay(data, res => {
                            if (res.status) {
                                console.log(JSON.stringify(res));
                                // 调用微信支付  
                                uni.requestPayment({
                                    provider: "wxpay",
                                    orderInfo: {
                                        appid: res.data.appid,
                                        noncestr: res.data.noncestr,
                                        package: res.data.package,
                                        partnerid: res.data.partnerid,
                                        prepayid: res.data.prepayid,
                                        timestamp: res.data.timestamp,
                                        sign: res.data.sign,
                                    },
                                    success: function(data) {
                                        _this.$common.successToShow('支付成功', () => {
                                            _this.redirectHandler(res.data.payment_id)
                                        })
                                    },
                                    fail: function(res) {
                                        console.log(JSON.stringify(res));
                                    }
                                });
                            } else {
                                _this.$common.errorToShow(res.msg)
                            }
                        })
                        break
                    case 'balancepay':
                        /**
                         *  用户余额支付
                         * 
                         */
                        _this.$api.pay(data, res => {
                            if (res.status) {
                                _this.redirectHandler(res.data.payment_id)
                            } else {
                                _this.$common.errorToShow(res.msg)
                            }
                        })
                        break
                    case 'offline':
                        /**
                         * 线下支付
                         */
                        _this.$common.modelShow('线下支付说明', '请联系客服进行线下支付', () => {}, false, '取消', '确定')
                        break
                }
            },
            // 支付成功后跳转操作
            redirectHandler(paymentId) {
                this.$common.redirectTo('/pages/goods/payment/result?id=' + paymentId)
            },
            // 支付中显示隐藏
            popBtn() {
                this.popShow = false
            }
        }

    }
</script>

<style>
    .payment-method .cell-item-hd {
        min-width: 70upx;
    }

    .payment-method .cell-hd-icon {
        width: 70upx;
        height: 70upx;
    }

    .payment-method .cell-item-bd {
        border-left: 2upx solid #F0F0F0;
        padding-left: 30upx;
    }

    .payment-method .cell-bd-text {
        font-size: 28upx;
        color: #666;
    }

    .payment-method .address {
        font-size: 24upx;
        color: #999;
    }

    .payment-pop {
        position: fixed;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        width: 400rpx;
        height: 272rpx;
        background-color: #fff;
        text-align: center;
        box-shadow: 0 0 20rpx #ccc;
        /* border-radius: 10rpx; */
    }

    .payment-pop-c {
        padding: 50rpx 30rpx;
        /* line-height: 300rpx; */
        font-size: 32rpx;
        color: #999;
    }

    .payment-pop-b {
        position: absolute;
        bottom: 0;
        display: flex;
        width: 100%;
        justify-content: space-between;
    }

    .payment-pop-b .btn {
        flex: 1;
    }

    .payment-pop .text {
        font-size: 24upx;
    }
</style>
paymentsByH5.vue
<template>
    <view class='cell-group payment-method'>
        <view class='cell-item add-title-item' v-for="item in payments" :key="item.code" @click="toPayHandler(item.code)"
         v-if="!(type == 2 && item.code == 'balancepay')">
            <view class='cell-item-hd'>
                <image class='cell-hd-icon' :src='item.icon'></image>
            </view>
            <view class='cell-item-bd'>
                <view class="cell-bd-view">
                    <text class="cell-bd-text">{{ item.name }}</text>
                </view>
                <view class="cell-bd-view">
                    <text class="cell-bd-text address">{{ item.memo }}</text>
                </view>
            </view>
            <view class='cell-item-ft'>
                <image class='cell-ft-next icon' src='/static/image/right.png'></image>
            </view>
        </view>
        <view class="payment-pop" v-show="popShow">
            <view class="payment-pop-c">
                <image src="/static/image/wait-pay.png" style="width: 30px;
        height: 30px;"></image>
                <view class="text">支付中,请稍后...</view>
            </view>
            <view class="payment-pop-b">
                <button class="btn btn-c" @click="popBtn">支付失败</button>
                <button class="btn btn-o" @click="popBtn">支付成功</button>
            </view>
        </view>
    </view>
</template>

<script>
    import {
        baseUrl
    } from '@/config/config.js'
    export default {
        props: {
            // 如果是商品订单此参数必须
            orderId: {
                type: String,
                default () {
                    return ''
                }
            },
            // 如果是充值订单此参数必须
            recharge: {
                type: Number,
                default () {
                    return 0
                }
            },
            // 用户id
            uid: {
                type: Number,
                default () {
                    return 0
                }
            },
            // 订单类型
            type: {
                type: Number,
                default () {
                    return 1
                }
            }
        },
        data() {
            return {
                payments: [],
                openid: '',
                popShow: false
            }
        },
        mounted() {
            this.getPayments()
        },
        methods: {
            // 获取可用支付方式列表
            getPayments() {
                this.$api.paymentList({}, res => {
                    if (res.status) {
                        this.payments = this.formatPayments(res.data)
                    }
                })
            },
            // 支付方式处理
            formatPayments(payments) {
                // h5支付并且是在微信浏览器内 过滤支付宝支付
                if (this.$common.isWeiXinBrowser()) {
                    payments = payments.filter(item => item.code !== 'alipay')
                }

                // 如果是充值订单 过滤余额支付 过滤非线上支付方式
                if (this.type === 2) {
                    payments = payments.filter(
                        item => item.code !== 'balancepay' || item.is_online === 1
                    )
                }

                // 设置logo图片
                payments.forEach(item => {
                    this.$set(item, 'icon', '/static/image/' + item.code + '.png')
                })

                return payments
            },
            checkWXJSBridge(data) {
                let that = this
                let interval = setInterval(() => {
                    if (typeof window.WeixinJSBridge != 'undefined') {
                        clearTimeout(interval)
                        that.onBridgeReady(data)
                    }
                }, 200)
            },
            onBridgeReady(data) {
                var _this = this
                window.WeixinJSBridge.invoke(
                    'getBrandWCPayRequest', {
                        appId: data.appid, // 公众号名称,由商户传入
                        timeStamp: data.timeStamp, // 时间戳,自1970年以来的秒数
                        nonceStr: data.nonceStr, // 随机串
                        package: data.package,
                        signType: data.signType, // 微信签名方式:
                        paySign: data.paySign // 微信签名
                    },
                    function(res) {
                        if (res.err_msg === 'get_brand_wcpay_request:ok') {
                            _this.$common.successToShow('支付成功')
                        } else if (res.err_msg === 'get_brand_wcpay_request:cancel') {
                            _this.$common.errorToShow('取消支付')
                        } else {
                            _this.$common.errorToShow('支付失败')
                        }
                        setTimeout(() => {
                            _this.$common.redirectTo(
                                '/pages/goods/payment/result?id=' + data.payment_id
                            )
                        }, 1000)
                    }
                )
            },
            // 用户点击支付方式处理
            toPayHandler(code) {
                this.popShow = true;
                let data = {
                    payment_code: code,
                    payment_type: this.type
                }
                data['ids'] = (this.type == 1 || this.type == 5 || this.type == 6) ? this.orderId : this.uid
                switch (code) {
                    case 'alipay':
                        /**
                         * 支付宝支付需要模拟GET提交数据
                         */
                        if (this.type == 1 && this.orderId) {
                            data['params'] = {
                                trade_type: 'WAP',
                                return_url: baseUrl +
                                    'wap/pages/goods/payment/result'
                            }
                        } else if (this.type == 2 && this.recharge) {
                            data['params'] = {
                                money: this.recharge,
                                return_url: baseUrl + 'wap/pages/goods/payment/result'
                            }
                        } else if ((this.type == 5 || this.type == 6) && this.recharge) {
                            data['params'] = {
                                formid: this.orderId
                            }
                        }

                        this.$api.pay(data, res => {
                            if (res.status) {
                                const url = res.data.url
                                const data = res.data.data

                                // 模拟GET提交
                                let tempForm = document.createElement('form')
                                tempForm.id = 'aliPay'
                                tempForm.methods = 'post'
                                tempForm.action = url
                                tempForm.target = '_self'
                                let input = []
                                for (let k in data) {
                                    input[k] = document.createElement('input')
                                    input[k].type = 'hidden'
                                    input[k].name = k
                                    input[k].value = data[k]
                                    tempForm.appendChild(input[k])
                                }
                                tempForm.addEventListener('submit', function() {}, false)
                                document.body.appendChild(tempForm)
                                tempForm.dispatchEvent(new Event('submit'))
                                tempForm.submit()
                                document.body.removeChild(tempForm)
                            }
                        })
                        break
                    case 'wechatpay':

                        /**
                         * 微信支付有两种
                         * 判断是否在微信浏览器
                         *     微信jsapi支付
                         */
                        let isWeiXin = this.$common.isWeiXinBrowser()

                        if (isWeiXin) {
                            var transitUrl =
                                baseUrl +
                                'wap/pages/goods/payment/auth?order_id=' +
                                this.orderId +
                                '&type=' +
                                this.type;

                            if (this.type == 1 && this.orderId) {
                                // 微信jsapi支付
                                // if (this.openid) {
                                //   data['params'] = {
                                //     trade_type: 'JSAPI_OFFICIAL',
                                //     openid: this.openid
                                //   }
                                // } else {
                                //   data['params'] = {
                                //     trade_type: 'JSAPI_OFFICIAL',
                                //     url: window.location.href
                                //   }
                                // }
                                data['params'] = {
                                    trade_type: 'JSAPI_OFFICIAL',
                                    url: transitUrl
                                }
                            } else if (this.type == 2 && this.recharge) {
                                data['params'] = {
                                    trade_type: 'JSAPI_OFFICIAL',
                                    money: this.recharge,
                                    url: transitUrl + '&uid=' + this.uid + '&money=' + this.recharge
                                }
                                // if (this.openid) {
                                //   data['params'] = {
                                //     money: this.recharge,
                                //     openid: this.openid
                                //   }
                                // } else {
                                //   data['params'] = {
                                //     money: this.recharge,
                                //     url: window.location.href
                                //   }
                                // }
                            } else if ((this.type == 5 || this.type == 6) && this.recharge) {
                                data['params'] = {
                                    formid: this.orderId
                                }
                            }
                            this.$api.pay(data, res => {
                                if (!res.status && res.data == '10066') {
                                    window.location.href = res.msg
                                    return;
                                }
                                const data = res.data
                                this.checkWXJSBridge(data)
                            })
                        } else {
                            // 微信 H5支付
                            if (this.type == 1 && this.orderId) {
                                data['params'] = {
                                    trade_type: 'MWEB',
                                    return_url: baseUrl +
                                        'wap/pages/goods/payment/result'
                                }
                            } else if (this.type == 2 && this.recharge) {
                                data['params'] = {
                                    trade_type: 'MWEB',
                                    money: this.recharge,
                                    return_url: baseUrl + 'wap/pages/goods/payment/result'
                                }
                            } else if ((this.type == 5 || this.type == 6) && this.recharge) {
                                data['params'] = {
                                    formid: this.orderId
                                }
                            }
                            // 微信h5支付
                            this.$api.pay(data, res => {
                                if (res.status) {
                                    location.href = res.data.mweb_url
                                } else {
                                    this.$common.errorToShow(res.msg)
                                }
                            })
                        }
                        break
                    case 'balancepay':
                        /**
                         *  用户余额支付
                         *
                         */
                        if ((this.type == 5 || this.type == 6) && this.recharge) {
                            data['params'] = {
                                formid: this.orderId
                            }
                        }
                        this.$api.pay(data, res => {
                            if (res.status) {
                                this.$common.redirectTo(
                                    '/pages/goods/payment/result?id=' + res.data.payment_id
                                )
                            } else {
                                this.$common.errorToShow(res.msg)
                            }
                        })
                        break
                    case 'offline':
                        /**
                         * 线下支付
                         */
                        this.$common.modelShow(
                            '线下支付说明',
                            '请联系客服进行线下支付',
                            () => {},
                            false,
                            '取消',
                            '确定'
                        )
                        break
                }
            },
            // 支付中显示隐藏
            popBtn() {
                this.popShow = false
            }
        }
    }
</script>

<style>
    .payment-method .cell-item-hd {
        min-width: 70upx;
    }

    .payment-method .cell-hd-icon {
        width: 70upx;
        height: 70upx;
    }

    .payment-method .cell-item-bd {
        border-left: 2upx solid #f0f0f0;
        padding-left: 30upx;
    }

    .payment-method .cell-bd-text {
        font-size: 28upx;
        color: #666;
    }

    .payment-method .address {
        font-size: 24upx;
        color: #999;
    }



    .payment-pop {
        position: fixed;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        width: 400rpx;
        height: 272rpx;
        background-color: #fff;
        text-align: center;
        box-shadow: 0 0 20rpx #ccc;
        /* border-radius: 10rpx; */
    }

    .payment-pop-c {
        padding: 50rpx 30rpx;
        /* line-height: 300rpx; */
        font-size: 32rpx;
        color: #999;
    }

    .payment-pop-b {
        position: absolute;
        bottom: 0;
        display: flex;
        width: 100%;
        justify-content: space-between;
    }

    .payment-pop-b .btn {
        flex: 1;
    }

    .payment-pop .text {
        font-size: 24upx;
    }
</style>
paymentsByWx.vue
<template>
    <view class='cell-group payment-method payment-wx'>
        <form class='cell-item add-title-item' v-for="item in payments" :key="item.code" @submit="toPayHandler" report-submit="true"
         v-if="!(type == 2 && item.code == 'balancepay')">
            <input name="code" :value="item.code" class="no-show">
            <button class="btn" form-type="submit">
                <view class='cell-item-hd'>
                    <image class='cell-hd-icon' :src='item.icon'></image>
                </view>
                <view class='cell-item-bd'>
                    <view class="cell-bd-view">
                        <text class="cell-bd-text">{{ item.name }}</text>
                    </view>
                    <view class="cell-bd-view">
                        <text class="cell-bd-text address">{{ item.memo }}</text>
                    </view>
                </view>
                <view class='cell-item-ft'>
                    <image class='cell-ft-next icon' src='/static/image/right.png'></image>
                </view>
            </button>
        </form>
        <view class="payment-pop" v-show="popShow">
            <view class="payment-pop-c">
                <image src="/static/image/wait-pay.png"></image>
                <view class="text">支付中,请稍后...</view>
            </view>
            <view class="payment-pop-b">
                <button class="btn btn-c" @click="popBtn">支付失败</button>
                <button class="btn btn-o" @click="popBtn">支付成功</button>
            </view>
        </view>
    </view>
</template>

<script>
    import {
        apiBaseUrl
    } from '@/config/config.js'
    export default {
        props: {
            // 如果是商品订单此参数必须
            orderId: {
                type: String,
                default () {
                    return ''
                }
            },
            // 如果是充值订单此参数必须
            recharge: {
                type: Number,
                default () {
                    return 0
                }
            },
            // 用户id
            uid: {
                type: Number,
                default () {
                    return 0
                }
            },
            // 订单类型
            type: {
                type: Number,
                default () {
                    return 1
                }
            }
        },
        data() {
            return {
                payments: [],
                popShow: false
            }
        },
        mounted() {
            this.getPayments()
        },
        methods: {
            // 获取可用支付方式列表
            getPayments() {
                this.$api.paymentList({}, res => {
                    if (res.status) {
                        this.payments = this.formatPayments(res.data)
                    }
                })
            },
            // 支付方式处理
            formatPayments(payments) {
                // 过滤支付宝支付
                payments = payments.filter(item => item.code !== 'alipay')

                // 如果是充值订单 过滤余额支付 过滤非线上支付方式
                if (this.type === 2) {
                    payments = payments.filter(item => item.code !== 'balancepay' || item.is_online === 1)
                }

                // 设置logo图片
                payments.forEach(item => {
                    this.$set(item, 'icon', '/static/image/' + item.code + '.png')
                })

                return payments
            },
            // 用户点击支付方式处理
            toPayHandler(e) {
                this.popShow = true;
                let code = e.target.value.code;
                let formId = e.detail.formId;

                let data = {
                    payment_code: code,
                    payment_type: this.type,
                    params: {
                        formid: formId
                    }
                }
                data['ids'] = (this.type == 1 || this.type == 5 || this.type == 6) ? this.orderId : this.uid

                // 判断订单支付类型
                if (this.type == 2 && this.recharge) {
                    data['params'] = {
                        money: this.recharge
                    }
                } else if ((this.type == 5 || this.type == 6) && this.recharge) {
                    data['params'] = {
                        formid: this.orderId
                    }
                }
                let _this = this
                switch (code) {
                    case 'wechatpay':
                        this.$api.pay(data, res => {
                            if (res.status) {
                                uni.requestPayment({
                                    provider: 'wxpay',
                                    timeStamp: res.data.timeStamp,
                                    nonceStr: res.data.nonceStr,
                                    package: res.data.package,
                                    signType: res.data.signType,
                                    paySign: res.data.paySign,
                                    success: function(e) {
                                        if (e.errMsg === 'requestPayment:ok') {
                                            _this.$common.successToShow(res.msg, () => {
                                                _this.$common.redirectTo('/pages/goods/payment/result?id=' + res.data.payment_id)
                                            })
                                        }
                                    }
                                });
                            } else {
                                this.$common.errorToShow(res.msg)
                            }
                        })
                        break
                    case 'balancepay':
                        /**
                         *  用户余额支付
                         * 
                         */
                        this.$api.pay(data, res => {
                            if (res.status) {
                                this.$common.redirectTo('/pages/goods/payment/result?id=' + res.data.payment_id)
                            } else {
                                this.$common.errorToShow(res.msg)
                            }
                        })
                        break
                    case 'offline':
                        /**
                         * 线下支付
                         */
                        this.$common.modelShow('线下支付说明', '请联系客服进行线下支付', () => {}, false, '取消', '确定')
                        break
                }

            },
            // 支付中显示隐藏
            popBtn() {
                this.popShow = false
            }
        }

    }
</script>

<style>
    .payment-method .cell-item-hd {
        min-width: 70upx;
    }

    .payment-method .cell-hd-icon {
        width: 70upx;
        height: 70upx;
    }

    .payment-method .cell-item-bd {
        border-left: 2upx solid #F0F0F0;
        padding-left: 30upx;
    }

    .payment-method .cell-bd-text {
        font-size: 28upx;
        color: #666;
    }

    .payment-method .address {
        font-size: 24upx;
        color: #999;
    }

    .no-show {
        display: none;
    }

    .payment-wx .btn {
        background-color: #fff;
        line-height: 1.7;
        padding: 0;
        width: 724upx;
        position: relative;
        overflow: hidden;
        float: left;
    }

    .payment-wx .btn .cell-item-hd {
        min-width: 100upx;
    }

    .payment-pop {
        position: fixed;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        width: 400rpx;
        height: 272rpx;
        background-color: #fff;
        text-align: center;
        box-shadow: 0 0 20rpx #ccc;
        /* border-radius: 10rpx; */
    }

    .payment-pop-c {
        padding: 50rpx 30rpx;
        /* line-height: 300rpx; */
        font-size: 32rpx;
        color: #999;
    }

    .payment-pop-c image {
        width: 60upx;
        height: 60upx;
    }

    .payment-pop-b {
        position: absolute;
        bottom: 0;
        display: flex;
        width: 100%;
        justify-content: space-between;
    }

    .payment-pop-b .btn {
        flex: 1;
    }

    .payment-pop-b .btn-o {
        background-color: #FF7159;
    }

    .payment-pop .text {
        font-size: 24upx;
    }
</style>

posters-layer

index.vue
<style lang="less">
.posters-layer {
  position: fixed;
  top: -5000px;
  left: -5000px;
//   top: 0;
//   left: 0;
}
</style>

<template>
    <canvas
        canvas-id="canvasdrawer"
        :style="{width: width + 'px', height: height + 'px'}"
        class="posters-layer">
    </canvas>
</template>
<script>
const CACHE_KEYS = 'temp_canvasdrawer_pic_cache';
export default {
    data() {
        return {
            width: 100,
            height: 100,
            paintingData: { views: [] },
            index: 0,
            imageList: [],
            tempFileList: [],
            isPainting: false,
            ctx: null,
            cache: {},
        }
    },
    props: {
        postersData: {
            type: Object,
            default() {
                return { views: [] };
            }
        }
    },
    watch: {
        postersData(newVal, oldVal) {
            newVal = newVal || { views: [] };
            this.createPosters(newVal);
        }
    },
    mounted() {
        uni.removeStorageSync('CACHE_KEYS');
        this.cache = uni.getStorageSync('CACHE_KEYS') || {};
        this.ctx = uni.createCanvasContext('canvasdrawer', this);
        this.createPosters(this.postersData);
    },
    methods: {
        createPosters(newVal) {
            if (!newVal.width || !newVal.height) {
                return;
            };
            // newVal = newVal || { views: [] };
            newVal.views = newVal.views || [];
            uni.removeStorageSync('CACHE_KEYS')
            this.paintingData = newVal;
            this.ctx && this.ctx.clearActions();
            if (!this.isPainting) {
                if (newVal.width && newVal.height) {
                    this.isPainting = true;
                    try {
                        this.readyPigment();
                    }
                    catch(err) {
                        this.$emit('error');
                    }
                }
            }
        },
        readyPigment() {
            const { width, height, views, background, radius = 0 } = this.paintingData;
            this.width = width;
            this.height = height;
            const inter = setInterval(() => {
                if (this.ctx) {
                    clearInterval(inter);
                    this.ctx.clearActions();
                    this.ctx.closePath();
                    // begin another path
                    this.ctx.beginPath();
                    this.drawRect({
                        //  || 'rgba(255, 255, 255, 0)'
                        background: background,
                        top: 0,
                        left: 0,
                        radius,
                        width,
                        height
                    })
                    this.getImageList(views);
                    this.downLoadImages(0);
                }
            }, 100);
        },
        getImageList(views) {
            const imageList = [];
            for (let i = 0; i < views.length; i++) {
                if (views[i].type === 'image') {
                    imageList.push(views[i].url);
                }
            }
            this.imageList = imageList;
        },
        downLoadImages(index) {
            const imageList = this.imageList;
            const tempFileList = this.tempFileList;
            if (index < imageList.length) {
                // console.log(imageList[index])
                this.getImageInfo(imageList[index]).then(imgInfo => {
                    tempFileList.push(imgInfo)
                    this.tempFileList = tempFileList;
                    this.downLoadImages(index + 1);
                })
            } else {
                this.startPainting();
            }
        },
        tailorImageDraw(view, imgInfo) {
            // _views.tailor == 'center'
            let px = 1;
            let wMultiple = (view.width * px) / imgInfo.originWidth;
            let hMultiple = (view.height * px) / imgInfo.originHeight;
            let sizeNormal = false;
            if (wMultiple <= 1 && hMultiple <= 1) {
                let multiple = wMultiple > hMultiple ? wMultiple : hMultiple;
                // let tempW = imgInfo.originWidth * multiple;
                // let tempH = imgInfo.originHeight * multiple;
                let tempW = (view.width * px) / multiple;
                let tempH = (view.height * px) / multiple;
                let sx = (imgInfo.originWidth - tempW) / 2;
                let sy = (imgInfo.originHeight - tempH) / 2;
                let ex = sx + tempW;
                let ey = sy + tempH;
                view['sx'] = sx || 0;
                view['sy'] = sy || 0;
                view['ex'] = ex || 0;
                view['ey'] = ey || 0;
                sizeNormal = true;
            }
            const data = {
                ...view,
                ow: imgInfo.originWidth,
                oh: imgInfo.originHeight
            };
            // console.log(JSON.stringify(data));
            if (!sizeNormal) {
                delete data.tailor;
            }
            // this.drawImage(data);
            return data;
        },
        async startPainting() {
            const { tempFileList, paintingData: { views } } = this;
            for (let i = 0, imageIndex = 0; i < views.length; i++) {
                if (views[i].type === 'image') {
                    let _img = tempFileList[imageIndex];
                    let _views = views[i];
                    let drawData = {};
                    if (_views.tailor) {
                        _views = this.tailorImageDraw(_views, _img);
                    }
                    drawData = {
                        ..._views,
                        url: _img.localPath
                    };
                    this.drawImage(drawData);
                    // if (_views.radius) {
                    //     this.drawRoundRect(drawData);
                    // }
                    // else {
                    // }
                    imageIndex++;
                } else if (views[i].type === 'text') {
                    if (!this.ctx.measureText) {
                        uni.showModal({
                            title: '提示',
                            content: '当前微信版本过低,无法使用 measureText 功能,请升级到最新微信版本后重试。'
                        });
                    } else {
                        this.drawText(views[i]);
                    }
                } else if (views[i].type === 'rect') {
                    this.drawRect(views[i]);
                }
                else if (views[i].type === 'round') {
                    this.drawRound(views[i]);
                }
            }
            this.ctx.draw(true, () => {
                uni.setStorageSync('CACHE_KEYS', this.cache);
                this.saveImageToLocal();
            })
        },
        old_drawImage(params) {
            // console.log(params)
            const {
                url,
                top = 0,
                left = 0,
                width = 0,
                height = 0,
                sx = 0,
                sy = 0,
                ex = 0,
                ey = 0
            } = params;
            if ('tailor' in params) {
                this.ctx.drawImage(url, sx, sy, ex, ey, left, top, width, height);
            }
            else if (params.round === true) {
                this.drawRoundImage(params);
            }
            else {
                this.ctx.drawImage(url, left, top, width, height);
            }
        },
        old_drawRoundImage(params) {
            let ctx = this.ctx;
            let x = params.left;
            let y = params.top;
            let w = params.width;
            let h = params.height;
            let url = params.url;
            let r = w / 2;
            ctx.save();
            ctx.beginPath();
            ctx.arc(x + r, y + r, r, 0, 2 * Math.PI);
            ctx.setFillStyle(params.background || '#ffffff');
            ctx.fill();
            ctx.clip();
            // 这个地方想要的是头像,简单点就放了个矩形
            ctx.drawImage(url, x, y, w, h);
            ctx.restore();
        },
         _drawRadiusRect(params) {
            const {
                top = 0,
                left = 0,
                width = 0,
                height = 0,
                radius = 0,
             } = params;
            let x = left;
            let y = top;
            let w = width;
            let h = height;
            // let bgc = background;
            let r = radius;
            // let br = radius;
            this.ctx.beginPath();
            this.ctx.moveTo(x + r, y);    // 移动到左上角的点
            this.ctx.lineTo(x + w - r, y);
            this.ctx.arc(x + w - r, y + r, r, 2 * Math.PI * (3 / 4), 2 * Math.PI * (4 / 4));
            this.ctx.lineTo(x + w, y + h - r);
            this.ctx.arc(x + w - r, y + h - r, r, 0, 2 * Math.PI * (1 / 4));
            this.ctx.lineTo(x + r, y + h);
            this.ctx.arc(x + r, y + h - r, r, 2 * Math.PI * (1 / 4), 2 * Math.PI * (2 / 4));
            this.ctx.lineTo((x), (y + r));
            this.ctx.arc(x + r, y + r, r, 2 * Math.PI * (2 / 4), 2 * Math.PI * (3 / 4));

            // this.ctx.moveTo(x + r, y);
            // this.ctx.arcTo(x + w, y, x + w, y + h, r);
            // this.ctx.arcTo(x + w, y + h, x, y + h, r);
            // this.ctx.arcTo(x, y + h, x, y, r);
            // this.ctx.arcTo(x, y, x + w, y, r);
        },
        drawImage(params) {
            const {
                type = '',
                background,
                top = 0,
                left = 0,
                width = 0,
                height = 0,
                radius = 0,
                url = '',
                sx = 0,
                sy = 0,
                ex = 0,
                ey = 0
            } = params;
            let x = left;
            let y = top;
            let w = width;
            let h = height;
            let r = radius;
            this.ctx.save();
            if (radius) {
                this.ctx.beginPath();
                

                // if (radius === parseInt(width / 2)) {
                //     console.log('圆');
                //     this.ctx.beginPath();
                //     this.ctx.arc(left + radius, top + radius, radius, 0, 2 * Math.PI);
                //     this.ctx.setFillStyle(params.background || '#ffffff')
                //     this.ctx.fill()
                //     this.ctx.clip();
                //     this.ctx.drawImage(url, x, y, w, h);
                // }
                // else {
                // }
                this._drawRadiusRect(params);
                this.ctx.fill();
                this.ctx.clip();
            }
            if ('tailor' in params) {
                this.ctx.drawImage(url, sx, sy, ex, ey, left, top, width, height);
            }
            else {
                this.ctx.drawImage(url, left, top, width, height);
            }
            // this.drawImage(params);
            
            this.ctx.restore();
        },
        old_drawRound(params) {
            let ctx = this.ctx;
            let x = params.left;
            let y = params.top;
            let w = params.width;
            let h = params.height;
            let r = params.radius;
            ctx.save();
            ctx.beginPath();
            ctx.arc(x + r, y + r, r, 0, 2 * Math.PI);
            ctx.setFillStyle(params.background || '#ffffff');
            ctx.fill();
            ctx.clip();
            ctx.restore();
        },
        drawText(params) {
            let {
                MaxLineNumber = 2,
                breakWord = false,
                color = 'black',
                content = '',
                fontSize = 16,
                top = 0,
                left = 0,
                lineHeight = 20,
                textAlign = 'left',
                width,
                bolder = false,
                textDecoration = 'none'
            } = params;
            if (bolder) {
                top -= 0.3;
            }
            // this.ctx.save();
            // this.ctx.beginPath();
            // this.ctx.stroke();
            let _setStyle = () => {
                // this.ctx.save();
                this.ctx.closePath();
                this.ctx.beginPath();
                this.ctx.setTextBaseline('top');
                this.ctx.setFillStyle(color);
                this.ctx.setFontSize(fontSize);
                this.ctx.setTextAlign(textAlign);
            }
            _setStyle();
            if (!breakWord) {
                this.ctx.fillText(content, left, top);
                this.drawTextLine(left, top, textDecoration, color, fontSize, content);
            } else {
                let fillText = '';
                let fillTop = top;
                let lineNum = 1;
                for (let i = 0; i < content.length; i++) {
                    fillText += [content[i]];
                    // _setStyle();
                    if (this.ctx.measureText(fillText).width > width) {
                        if (lineNum === MaxLineNumber) {
                            if (i !== content.length) {
                                fillText = fillText.substring(0, fillText.length - 1) + '...';
                                // _setStyle();
                                this.ctx.fillText(fillText, left, fillTop);
                                this.drawTextLine(left, fillTop, textDecoration, color, fontSize, fillText);
                                fillText = '';
                                break;
                            }
                        }
                        // _setStyle();
                        this.ctx.fillText(fillText, left, fillTop);
                        this.drawTextLine(left, fillTop, textDecoration, color, fontSize, fillText);
                        fillText = '';
                        fillTop += lineHeight;
                        lineNum++;
                    }
                }
                // _setStyle();
                this.ctx.fillText(fillText, left, fillTop);
                this.drawTextLine(left, fillTop, textDecoration, color, fontSize, fillText);
            }
            // this.ctx.draw();
            if (bolder) {
                this.drawText({
                    ...params,
                    left: left - 0.3,
                    top: top,
                    bolder: false,
                    textDecoration: 'none'
                });
            }
        },
        drawTextLine(left, top, textDecoration, color, fontSize, content) {
            if (textDecoration === 'underline') {
                this.drawRect({
                    background: color,
                    top: top + fontSize * 1.2,
                    left: left - 1,
                    width: this.ctx.measureText(content).width + 2,
                    height: 1
                });
            } else if (textDecoration === 'line-through') {
                this.drawRect({
                    background: color,
                    top: top + fontSize * 0.6,
                    left: left - 1,
                    width: this.ctx.measureText(content).width + 2,
                    height: 1
                });
            }
        },
        drawRect(params) {
            // console.log(params)
            const { background, top = 0, left = 0, width = 0, height = 0 } = params
            this.ctx.save();
            this.ctx.setFillStyle(background);
            if (params.radius) {
                this._drawRadiusRect(params);
                this.ctx.fill();
            }
            else {
                this.ctx.setFillStyle(background);
                this.ctx.fillRect(left, top, width, height);
            }
            this.ctx.restore();
        },
        getImageInfo(url) {
            return new Promise((resolve, reject) => {
                /* 获得要在画布上绘制的图片 */
                if (this.cache[url]) {
                    resolve(this.cache[url]);
                } else {
                    const objExp = new RegExp(/^http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/);
                    if (objExp.test(url)) {
                        uni.getImageInfo({
                            src: url,
                            complete: res => {
                                if (res.errMsg === 'getImageInfo:ok') {
                                    const img = {
                                        url,
                                        originWidth: res.width,
                                        originHeight: res.height,
                                        localPath: res.path
                                    };
                                    this.cache[url] = img;
                                    // console.log(res);
                                    // resolve(res.path)
                                    resolve(img);
                                } else {
                                    reject(new Error('getImageInfo fail'));
                                }
                            }
                        });
                    } else {
                        this.cache[url] = {
                            url,
                            originWidth: 0,
                            originHeight: 0,
                            localPath: url
                        };
                        resolve(url);
                    }
                }
            })
        },
        saveImageToLocal() {
            const { width, height } = this;
            uni.canvasToTempFilePath({
                x: 0,
                y: 0,
                width,
                height,
                canvasId: 'canvasdrawer',
                success: res => {
                    if (res.errMsg === 'canvasToTempFilePath:ok') {
                        this.isPainting = false;
                        this.imageList = [];
                        this.tempFileList = [];
                        this.$emit('success', {
                            width,
                            height,
                            path: res.tempFilePath
                        });
                    }
                }
            }, this);
        }
    }
}
</script>
README.md
# 海报生成组件

## 组件使用

> 运行下面demo时,主要图片路径

<template>

<view>
    <posters-layer
        :postersData="postersData"
        @success="onSuccessCreatePosters"
        @error="onPostersError">
    </posters-layer>
    <img :src="posterImg.path" />
</view>

</template>
<script>
import postersLayer from '../../components/posters-layer/index';
export default {

data() {
    return {
        postersData: {},
        posterImg: {}
    };
},
components: {
    postersLayer
},
onLoad() {
    this.initPostersConfig();
},
methods: {
    initPostersConfig() {
        const config = {
            clear: true,
            width: 660,
            height: 850,
            background: '#ffffff',
            views: [
            {
                type: 'image',
                width: 660,
                height: 660,
                top: 0,
                left: 0,
                // 封面图,测试的时候填上
                url: 'http://127.0.0.1:8080/static/images/test/1.jpg'
            },
            {
                type: 'text',
                width: 400,
                height: 50,
                left: 20,
                top: 680,
                fontSize: 30,
                lineHeight: 40,
                bolder: true,
                breakWord: true,
                content: '        Apple/苹果 iPhone XR 移动联通电信全网通版 苹果xr iphonexr 苹果xr手机 iphone xr',
                MaxLineNumber: 2
            },
            {
                type: 'rect',
                width: 70,
                height: 34,
                left: 20,
                top: 684,
                background: '#ff4201',
                radius: 8
            },
            {
                type: 'text',
                width: 400,
                height: 50,
                left: 20,
                top: 690,
                fontSize: 24,
                lineHeight: 40,
                bolder: true,
                breakWord: true,
                content: ' 活动',
                color: '#ffffff',
                MaxLineNumber: 2
            },
            {
                type: 'text',
                width: 400,
                left: 20,
                top: 770,
                fontSize: 54,
                bolder: true,
                breakWord: true,
                content: '¥0.0',
                color: '#F40',
                MaxLineNumber: 2
            },
            {
                type: 'image',
                width: 140,
                height: 140,
                top: 680,
                left: 500,
                // 二维码图片路径,测试的时候填上
                url: 'http://127.0.0.1:8080/static/images/test/qr.png'
            },
            ]
        };
        this.postersData = config;
    },
    onSuccessCreatePosters(res) {
        this.posterImg = res;
    },
    onPostersError(res) {}
}

}
</script>



## 组件参数解释

### config字段


| 字段             | 类型                     | 必填 | 描述                                       |
| --------------- | ------------------------ | ---- | ------------------------------------------ |
| width           | Number(单位:px)         | 是   | 画布宽度                                   |
| height          | Number(单位:px)         | 是   | 画布高度                                   |
| background      | String                 | 否   | 画布背景颜色                                   |
| radius          | Number                  | 否   | 圆角 |
| views           | Array                  | 否   | 海报的所有元素             |

### views字段

#### 文本
| 字段             | 类型                     | 必填 | 描述 |
| --------------- | ------------------------ | ---- | ------------------------------------------ |
| type            | String                   | 是   | 类型,值:text                               | 
| width           | Number(单位:px)           | 是   | 宽度                                   | 
| height          | Number(单位:px)           | 否   | 高度                                   | 
| left            | Number(单位:px)           | 否   | 距离海报左边距                          |
| top             | Number(单位:px)           | 否   | 距离海报上边距                          |
| fontSize        | Number(单位:px)           | 否   | 字体大小,默认:16                       |
| lineHeight      | Number(单位:px)           | 否   | 行高,默认:20                           |
| breakWord       | Boolean                  | 否   | 是否自动换行,默认:false                   |
| bolder          | Boolean                  | 否   | 是否加粗,默认:false                      |
| textAlign       | String                   | 否   | 对齐方式,可选值:left、center、right,默认:left    |
| color           | String                   | 否   | 字体颜色                                  |
| content         | String                   | 是   | 文本内容                                 |
| MaxLineNumber   | Number                   | 否   | 显示多少行,超出省略                        |


### 矩形
| 字段             | 类型                     | 必填 | 描述 |
| --------------- | ------------------------ | ---- | ------------------------------------------ |
| type            | String                   | 是   | 类型,值:rect                              | 
| width           | Number(单位:px)           | 是   | 宽度                                       | 
| height          | Number(单位:px)           | 是   | 高度                                       | 
| left            | Number(单位:px)           | 否   | 距离海报左边距                               | 
| top             | Number(单位:px)           | 否   | 距离海报上边距                               | 
| radius          | Number(单位:px)           | 否   | 圆角半径,如果radius === width / 2,则是个圆,和CSS一样   | 
| background      | String                   | 否   | 填充背景色                                   | 

### 图片
| 字段             | 类型                     | 必填 | 描述 |
| --------------- | ------------------------ | ---- | ------------------------------------------ |
| type            | String                   | 是   | 类型,值:image                              | 
| tailor          | Number(单位:px)           | 否   | 裁剪方式,可选值:center                           | 
| radius          | Number(单位:px)           | 否   | 圆角半径,如果radius === width / 2,则是个圆,和CSS一样   | 
| width           | Number(单位:px)           | 是   | 宽度                               | 
| height          | Number(单位:px)           | 是   | 高度                               | 
| left            | Number(单位:px)           | 否   | 距离海报左边距                               | 
| top             | Number(单位:px)           | 否   | 距离海报上边距                               | 
| url             | String                   | 是   | 图片路径                               | 


## 事件

### `success` 海报生成成功时触发

### `error` 海报生成失败时触发

red-bag

index.vue
<template>
  <view class="wrapper" v-show="redBagShow">
    <view class="modal-bg" >
    </view>
    <view class="rb-wrapper">
      <view class="rb-content" @click="handleBtn">

      </view>
      <view class="close" @click="handleClose">
        <image src='../../static/image/close.png' class="img"></image>
      </view>
    </view>
  </view>
</template>

<script>
export default {
  name: 'redBag',
  components: {},
  props: {
    
  },
  data() {
    return {
      redBagShow: true
    }
  },
  watch: {},
  computed: {},
  methods: {
    handleClose() {
      this.redBagShow=false
    },
    handleBtn() {
      this.$emit('click')
      this.redBagShow=false
    }
  },
  created() {},
  mounted() {}
}
</script>
<style lang="scss" scoped>
.modal-bg {
  position: absolute;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  background: rgba(0, 0, 0, 0.4);
}
.rb-wrapper {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 60%;
  height: 600upx;
  transform: translate3d(-50%, -50%, 0);
  background: red;
  padding: 40upx;
  .rb-content{
    height: 100%;
  }
  .close {
    position: absolute;
    bottom: -120upx;
    left: 50%;
    margin-left: -30upx;
    width: 60upx;
    height: 60upx;
    border-radius: 50%;
    background: #ddd;
    .img {
      width: 100%;
      height: 100%;
    }
  }
}
</style>

share

share.vue
<template>
    
    <view style="width: 100%;height: 300upx;background: #FFFFFF;position: absolute;left:0;bottom: 0;">
        <!-- #ifdef H5 || APP-PLUS || MP-ALIPAY -->
        <view class="share-pop">
            <view class="share-item" 
            v-for="(item, index) in providerList"
            :key="index"
            @click="clickHandler(item)">
                <image :src="item.img" mode=""></image>
                <view class="">{{ item.name }}</view>
            </view>
        </view>
        <view class="button-bottom">
            <button class="btn btn-w btn-square" @click="close()">关闭</button>
        </view>
        <!-- #endif -->
        
        <!-- #ifdef MP-WEIXIN -->
        <view class="share-pop">
            <view class="share-item">
                
                <button class="btn" open-type="share">
                    <image src="../../../static/image/share-f.png" mode=""></image>
                    <view class="">
                        分享微信好友
                    </view>
                </button>
            </view>
            <view class="share-item" @click="createPoster()">
                <image src="../../../static/image/poster.png" mode=""></image>
                <view class="">生成海报</view>
            </view>
        </view>
        <view class="button-bottom">
            <button class="btn btn-w btn-square" @click="close()">关闭</button>
        </view>
        <!-- #endif -->
        
        <!-- #ifdef MP-ALIPAY -->
        <view class="share-pop">
            <view class="share-item">
                <image src="../../../static/image/share-f.png" mode=""></image>
                <button class="btn" open-type="share">分享给好友</button>
            </view>
            <view class="share-item" @click="createPoster()">
                <image src="../../../static/image/poster.png" mode=""></image>
                <view class="">生成海报</view>
            </view>
        </view>
        <view class="button-bottom">
            <button class="btn btn-w btn-square" @click="close()">关闭</button>
        </view>
        <!-- #endif -->
    </view>    
</template>

<script>
import { apiBaseUrl } from '@/config/config.js'    
export default {
    props: {
        // 商品id
        goodsId: {
            type: Number,
            default: 0
        },
        // 分享的图片
        shareImg: {
            type: String,
            default: ''
        },
        // 分享标题
        shareTitle: {
            type: String,
            default: ''
        },
        // 分享内容
        shareContent: {
            type: String,
            default: ''
        },
        // 分享链接
        shareHref: {
            type: String,
            default: ''
        }
    },
    data () {
        return {
            shareType: 0,
            providerList: [] // 分享通道 包含生成海报
        }
    },
    mounted () {
        /**
         * 
         * H5端分享两种 (微信浏览器内引导用户去分享, 其他浏览器)
         * 
         */
        // #ifdef H5
        if (this.$common.isWeiXinBrowser()) {
            // 微信浏览器里面
        } else {
            // 其他浏览器里面
            this.providerList = [
                {
                    name: '分享给好友',
                    cate: 'share',
                    id: 'share',
                    img: '../../../static/image/share-f.png',
                    sort: 0
                },
                {
                    name: '生成海报',
                    cate: 'poster',
                    id: 'poster',
                    img: '../../../static/image/poster.png',
                    sort: 1
                }
            ]
        }
        // #endif
        
        
        /**
         * 
         *  支付宝小程序中的分享
         * 
         */
        // #ifdef MP-ALIPAY
        this.providerList = [
            {
                name: '生成海报',
                cate: 'poster',
                id: 'poster',
                img: '../../../static/image/ic-img.png',
                sort: 1
            }
        ]
        // #endif
        
        
        /**
         * 
         *  H5+ 获取分享通道
         * 
         */
        // #ifdef APP-PLUS
        uni.getProvider({
            service: 'share',
            success: (e) => {
                let data = []
                for (let i = 0; i < e.provider.length; i++) {
                    switch (e.provider[i]) {
                        case 'weixin':
                            data.push({
                                name: '分享到微信好友',
                                cate: 'share',
                                id: 'weixin',
                                img: '../../../static/image/ic-wechat.png',
                                sort: 0
                            })
                            data.push({
                                name: '分享到微信朋友圈',
                                cate: 'share',
                                id: 'weixin',
                                type:'WXSenceTimeline',
                                img: '../../../static/image/circle-of-friends.png',
                                sort:1
                            })
                            break;
//                         case 'sinaweibo':
//                             data.push({
//                                 name: '分享到新浪微博',
//                                 cate: 'share',
//                                 id: 'sinaweibo',
//                                 img: '../../../static/image/sina-weibo.png',
//                                 sort:2
//                             })
//                             break;
                        case 'qq':
                            data.push({
                                name: '分享到QQ',
                                cate: 'share',
                                id: 'qq',
                                img: '../../../static/image/qq.png',
                                sort:3
                            })
                            break;
                        default:
                            break;
                    }
                }
                
                data.push({
                    name: '生成海报',
                    cate: 'poster',
                    id: 'poster',
                    img: '../../../static/image/poster.png',
                    sort: 5
                })
                this.providerList = data.sort((x,y) => {
                    return x.sort - y.sort
                });
            },
            fail: (e) => {
                // console.log('获取分享通道失败', e)
            }
        });
        // #endif
    },
    methods: {
        // 关闭弹出层
        close () {
            this.$emit('close')
        },
        // 点击操作
        clickHandler (e) {
            if (e.cate === 'poster') {
                this.createPoster()
            } else {
                // 去分享
                this.share(e)
            }
        },
        // 生成海报
        createPoster () {
            let data = {
                id: this.goodsId,
                type: 1
            }
            
            let pages = getCurrentPages()
            let page = pages[pages.length - 1]
            
            // #ifdef H5
            data.source = 1;
            data.return_url = apiBaseUrl + 'wap/pages/share/jump';
            // #endif
            
            // #ifdef MP-WEIXIN
            data.source = 2;
            data.return_url = 'pages/share/jump'; //page.route;
            // #endif
            
            // #ifdef MP-ALIPAY
            data.source = 3;
            data.return_url = 'pages/share/jump';//page.__proto__.route;
            // #endif
            
            let userToken = this.$db.get('userToken')
            
            if (userToken) {
                data.user_id = userToken
            }
            
            this.$api.createPoster(data, res => {
                if (res.status) {
                    this.close()
                    this.$common.navigateTo('/pages/share?poster=' + res.data)
                } else {
                    this.$common.errorToShow(res.msg)
                }
            })
        },
        // 分享操作
        async share (e) {
            // console.log('分享通道:'+ e.id +'; 分享类型:' + this.shareType);
//             if(!this.shareContent){
//                 uni.showModal({
//                     content:'分享内容不能为空',
//                     showCancel:false
//                 })
//                 return;
//             }
//             
//             if(!this.shareImg){
//                 uni.showModal({
//                     content:'分享图片不能为空',
//                     showCancel:false
//                 })
//                 return;
//             }
            
            // #ifdef APP-PLUS
            let shareOPtions = {
                provider: e.id,
                scene: e.type && e.type === 'WXSenceTimeline' ? 'WXSenceTimeline' : 'WXSceneSession', //WXSceneSession”分享到聊天界面,“WXSenceTimeline”分享到朋友圈,“WXSceneFavorite”分享到微信收藏     
                type: this.shareType,
                success: (e) => {
                    uni.showModal({
                        content: '分享成功',
                        showCancel:false
                    })
                },
                fail: (e) => {
                    uni.showModal({
                        content: e.errMsg,
                        showCancel:false
                    })
                },
                complete:function(){
                    // console.log('分享操作结束!')
                }
            }
            
            shareOPtions.summary = this.shareContent ? this.shareContent : ''
            shareOPtions.imageUrl = this.shareImg ? this.shareImg : ''
            shareOPtions.title = this.shareTitle ? this.shareTitle : ''
            shareOPtions.href = this.shareHref ? this.shareHref : ''
            
            if(shareOPtions.type === 0 && plus.os.name === 'iOS'){//如果是图文分享,且是ios平台,则压缩图片 
                shareOPtions.imageUrl = await this.compress()
            }
            if(shareOPtions.type === 1 && shareOPtions.provider === 'qq'){//如果是分享文字到qq,则必须加上href和title
                shareOPtions.href = this.shareHref
                shareOPtions.title = this.shareTitle
            }
            uni.share(shareOPtions);    
            // #endif
        },
        // 压缩图片 图文分享要求分享图片大小不能超过20Kb
        compress () {
            // console.log('开始压缩');
            let img = this.shareImg;
            return new Promise((res) => {
                var localPath = plus.io.convertAbsoluteFileSystem(img.replace('file://', ''));
                // console.log('after' + localPath);
                // 压缩size
                plus.io.resolveLocalFileSystemURL(localPath, (entry) => {
                    entry.file((file) => {// 可通过entry对象操作图片 
                        // console.log('getFile:' + JSON.stringify(file));
                        if(file.size > 20480) {// 压缩后size 大于20Kb
                            plus.zip.compressImage({
                                src: img,
                                dst: img.replace('.jpg', '2222.jpg').replace('.JPG', '2222.JPG'),
                                width: '10%',
                                height: '10%',
                                quality: 1,
                                overwrite: true
                            }, (event) => {
                                // console.log('success zip****' + event.size);
                                let newImg = img.replace('.jpg', '2222.jpg').replace('.JPG', '2222.JPG');
                                res(newImg);
                            }, function(error) {
                                uni.showModal({
                                    content:'分享图片太大,需要请重新选择图片!',
                                    showCancel:false
                                })
                            });
                        }
                    });
                }, (e) => {
                    // console.log('Resolve file URL failed: ' + e.message);
                    uni.showModal({
                        content:'分享图片太大,需要请重新选择图片!',
                        showCancel:false
                    })
                });
            })
        }
    }
}    
</script>

<style>
.share-pop{
    height: 300upx;
    width: 100%;
    display: flex;
}
.share-item{
    flex: 1;
    text-align: center;
    font-size: 26upx;
    color: #333;
    padding: 20upx 0;
}
.share-item image{
    width: 80upx;
    height: 80upx;
    margin: 20upx;
}    
.share-item .btn{
    line-height: 1;
    display: block;
    font-size: 26upx;
    background-color: #fff;
}
</style>
shareByAli.vue
<template>
    
    <view style="width: 100%;height: 300upx;background: #FFFFFF;position: absolute;left:0;bottom: 0;">

        <view class="share-pop">
            <view class="share-item">
                <button class="btn" open-type="share">
                    <image src="../../../static/image/share-f.png" mode=""></image>
                    <button class="btn" open-type="share">分享给好友</button>
                </button>
            </view>
            <view class="share-item" @click="createPoster()">
                <image src="../../../static/image/poster.png" mode=""></image>
                <view class="">生成海报</view>
            </view>
        </view>
        <view class="button-bottom">
            <button class="btn btn-w btn-square" @click="close()">关闭</button>
        </view>
    </view>    
</template>

<script>
import { apiBaseUrl } from '@/config/config.js'
export default {
    props: {
        // 商品id
        goodsId: {
            type: Number,
            default: 0
        },
        // 分享的图片
        shareImg: {
            type: String,
            default: ''
        },
        // 分享标题
        shareTitle: {
            type: String,
            default: ''
        },
        // 分享内容
        shareContent: {
            type: String,
            default: ''
        },
        // 分享链接
        shareHref: {
            type: String,
            default: ''
        },
        //分享类型
        shareType:{
            type:Number,
            default:1
        },
        //拼团id
        groupId:{
            type:Number,
            default:0
        },
        //拼团的团队id
        teamId:{
            type:Number,
            default:0
        }
    },
    data () {
        return {
            shareType: 0,
            providerList: [] // 分享通道 包含生成海报
        }
    },
    mounted () {
        
    },
    methods: {
        // 关闭弹出层
        close () {
            this.$emit('close')
        },
        // 生成海报
        createPoster () {
            let data = {
                id: this.goodsId,
                type: this.shareType,
                group_id :this.groupId,
                team_id :this.teamId,
            }
            
            let pages = getCurrentPages()
            let page = pages[pages.length - 1]
            
            data.source = 3;
            data.return_url = 'pages/share/jump';//page.__proto__.route;
            
            let userToken = this.$db.get('userToken')
            if (userToken) {
                data.token = userToken
            }
            
            this.$api.createPoster(data, res => {
                if (res.status) {
                    this.close()
                    this.$common.navigateTo('/pages/share?poster=' + res.data)
                } else {
                    this.$common.errorToShow(res.msg)
                }
            })
        },
        // 分享操作
        async share (e) {

        }
    }
}    
</script>

<style>
.share-pop{
    height: 300upx;
    width: 100%;
    display: flex;
}
.share-item{
    flex: 1;
    text-align: center;
    font-size: 26upx;
    color: #333;
    padding: 20upx 0;
}
.share-item image{
    width: 80upx;
    height: 80upx;
    margin: 20upx;
}    
.share-item .btn{
    line-height: 1;
    display: block;
    font-size: 26upx;
    background-color: #fff;
}
</style>
shareByApp.vue
<template>
    
    <view style="width: 100%;height: 300upx;background: #FFFFFF;position: absolute;left:0;bottom: 0;">
        <view class="share-pop">
            <view class="share-item" 
            v-for="(item, index) in providerList"
            :key="index"
            @click="clickHandler(item)">
                <image :src="item.img" mode=""></image>
                <view class="">{{ item.name }}</view>
            </view>
        </view>
        <view class="button-bottom">
            <button class="btn btn-w btn-square" @click="close()">关闭</button>
        </view>
    </view>    
</template>

<script>
import { apiBaseUrl } from '@/config/config.js'
export default {
    props: {
        // 商品id
        goodsId: {
            type: Number,
            default: 0
        },
        // 分享的图片
        shareImg: {
            type: String,
            default: ''
        },
        // 分享标题
        shareTitle: {
            type: String,
            default: ''
        },
        // 分享内容
        shareContent: {
            type: String,
            default: ''
        },
        // 分享链接
        shareHref: {
            type: String,
            default: ''
        }
    },
    data () {
        return {
            shareType: 0,
            providerList: [] // 分享通道 包含生成海报
        }
    },
    mounted () {
        /**
         * 
         *  H5+ 获取分享通道
         * 
         */
        uni.getProvider({
            service: 'share',
            success: (e) => {
                let data = []
                for (let i = 0; i < e.provider.length; i++) {
                    switch (e.provider[i]) {
                        case 'weixin':
                            data.push({
                                name: '分享到微信好友',
                                cate: 'share',
                                id: 'weixin',
                                img: '../../../static/image/ic-wechat.png',
                                sort: 0
                            })
                            data.push({
                                name: '分享到微信朋友圈',
                                cate: 'share',
                                id: 'weixin',
                                type:'WXSenceTimeline',
                                img: '../../../static/image/circle-of-friends.png',
                                sort:1
                            })
                            break;
//                         case 'sinaweibo':
//                             data.push({
//                                 name: '分享到新浪微博',
//                                 cate: 'share',
//                                 id: 'sinaweibo',
//                                 img: '../../../static/image/sina-weibo.png',
//                                 sort:2
//                             })
//                             break;
                        case 'qq':
                            data.push({
                                name: '分享到QQ',
                                cate: 'share',
                                id: 'qq',
                                img: '../../../static/image/qq.png',
                                sort:3
                            })
                            break;
                        default:
                            break;
                    }
                }
                
                data.push({
                    name: '生成海报',
                    cate: 'poster',
                    id: 'poster',
                    img: '../../../static/image/poster.png',
                    sort: 5
                })
                this.providerList = data.sort((x,y) => {
                    return x.sort - y.sort
                });
            },
            fail: (e) => {
                // console.log('获取分享通道失败', e)
            }
        });
    },
    methods: {
        // 关闭弹出层
        close () {
            this.$emit('close')
        },
        // 点击操作
        clickHandler (e) {
            if (e.cate === 'poster') {
                this.createPoster()
            } else {
                // 去分享
                this.share(e)
            }
        },
        // 生成海报
        createPoster () {
            let data = {
                id: this.goodsId,
                type: 1
            }
            
            let pages = getCurrentPages()
            let page = pages[pages.length - 1]
            
            data.source = 1;
            data.return_url = apiBaseUrl + 'wap/' + page.route;
            
            let userToken = this.$db.get('userToken')
            if (userToken) {
                data.token = userToken
            }
            
            this.$api.createPoster(data, res => {
                if (res.status) {
                    this.close()
                    this.$common.navigateTo('/pages/share?poster=' + res.data)
                } else {
                    this.$common.errorToShow(res.msg)
                }
            })
        },
        // 分享操作
        async share (e) {
            // console.log('分享通道:'+ e.id +'; 分享类型:' + this.shareType);
//             if(!this.shareContent){
//                 uni.showModal({
//                     content:'分享内容不能为空',
//                     showCancel:false
//                 })
//                 return;
//             }
//             
//             if(!this.shareImg){
//                 uni.showModal({
//                     content:'分享图片不能为空',
//                     showCancel:false
//                 })
//                 return;
//             }
            
            let shareOPtions = {
                provider: e.id,
                scene: e.type && e.type === 'WXSenceTimeline' ? 'WXSenceTimeline' : 'WXSceneSession', //WXSceneSession”分享到聊天界面,“WXSenceTimeline”分享到朋友圈,“WXSceneFavorite”分享到微信收藏     
                type: this.shareType,
                success: (e) => {
                    uni.showModal({
                        content: '分享成功',
                        showCancel:false
                    })
                },
                fail: (e) => {
                    uni.showModal({
                        content: e.errMsg,
                        showCancel:false
                    })
                },
                complete:function(){
                    // console.log('分享操作结束!')
                }
            }
            
            shareOPtions.summary = this.shareContent ? this.shareContent : ''
            shareOPtions.imageUrl = this.shareImg ? this.shareImg : ''
            shareOPtions.title = this.shareTitle ? this.shareTitle : ''
            shareOPtions.href = this.shareHref ? this.shareHref : ''
            
            if(shareOPtions.type === 0 && plus.os.name === 'iOS'){//如果是图文分享,且是ios平台,则压缩图片 
                shareOPtions.imageUrl = await this.compress()
            }
            if(shareOPtions.type === 1 && shareOPtions.provider === 'qq'){//如果是分享文字到qq,则必须加上href和title
                shareOPtions.href = this.shareHref
                shareOPtions.title = this.shareTitle
            }
            uni.share(shareOPtions);    
        },
        // 压缩图片 图文分享要求分享图片大小不能超过20Kb
        compress () {
            // console.log('开始压缩');
            let img = this.shareImg;
            return new Promise((res) => {
                var localPath = plus.io.convertAbsoluteFileSystem(img.replace('file://', ''));
                // console.log('after' + localPath);
                // 压缩size
                plus.io.resolveLocalFileSystemURL(localPath, (entry) => {
                    entry.file((file) => {// 可通过entry对象操作图片 
                        // console.log('getFile:' + JSON.stringify(file));
                        if(file.size > 20480) {// 压缩后size 大于20Kb
                            plus.zip.compressImage({
                                src: img,
                                dst: img.replace('.jpg', '2222.jpg').replace('.JPG', '2222.JPG'),
                                width: '10%',
                                height: '10%',
                                quality: 1,
                                overwrite: true
                            }, (event) => {
                                // console.log('success zip****' + event.size);
                                let newImg = img.replace('.jpg', '2222.jpg').replace('.JPG', '2222.JPG');
                                res(newImg);
                            }, function(error) {
                                uni.showModal({
                                    content:'分享图片太大,需要请重新选择图片!',
                                    showCancel:false
                                })
                            });
                        }
                    });
                }, (e) => {
                    // console.log('Resolve file URL failed: ' + e.message);
                    uni.showModal({
                        content:'分享图片太大,需要请重新选择图片!',
                        showCancel:false
                    })
                });
            })
        }
    }
}    
</script>

<style>
.share-pop{
    height: 300upx;
    width: 100%;
    display: flex;
}
.share-item{
    flex: 1;
    text-align: center;
    font-size: 26upx;
    color: #333;
    padding: 20upx 0;
}
.share-item image{
    width: 80upx;
    height: 80upx;
    margin: 20upx;
}    
.share-item .btn{
    line-height: 1;
    display: block;
    font-size: 26upx;
    background-color: #fff;
}
</style>
shareByh5.vue
<template>
    <view style="width: 100%;height: 300upx;background: #FFFFFF;position: absolute;left:0;bottom: 0;">
        <view class="share-pop">
            <view class="share-item" @click="copyUrl()">
                <image src="../../../static/image/share-f.png" mode=""></image>
                <view class="">复制链接</view>
            </view>
            <view class="share-item" @click="createPoster()">
                <image src="../../../static/image/poster.png" mode=""></image>
                <view class="">生成海报</view>
            </view>
        </view>
        <view class="button-bottom">
            <button class="btn btn-w btn-square" @click="close()">关闭</button>
        </view>
    </view>    
</template>

<script>
import { apiBaseUrl } from '@/config/config.js'    
export default {
    props: {
        // 商品id
        goodsId: {
            type: Number,
            default: 0
        },
        // 分享的图片
        shareImg: {
            type: String,
            default: ''
        },
        // 分享标题
        shareTitle: {
            type: String,
            default: ''
        },
        // 分享内容
        shareContent: {
            type: String,
            default: ''
        },
        // 分享链接
        shareHref: {
            type: String,
            default: ''
        },
        //分享类型
        shareType:{
            type:Number,
            default:1
        },
        //拼团id
        groupId:{
            type:Number,
            default:0
        },
        //拼团的团队id
        teamId:{
            type:Number,
            default:0
        }
    },
    mounted () {
        /**
         * 
         * H5端分享两种 (微信浏览器内引导用户去分享, 其他浏览器)
         * 
         */
    },
    methods: {
        // 关闭弹出层
        close () {
            this.$emit('close')
        },
        // 生成海报
        createPoster () {
            let data = {
                id: this.goodsId,
                type: this.shareType,
                group_id :this.groupId,
                team_id :this.teamId,
            }
            
            data.return_url = apiBaseUrl + 'wap/pages/share/jump';

            let userToken = this.$db.get('userToken')
            if (userToken) {
                data.token = userToken
            }
            
            this.$api.createPoster(data, res => {
                if (res.status) {
                    this.close()
                    this.$common.navigateTo('/pages/share?poster=' + res.data)
                } else {
                    this.$common.errorToShow(res.msg)
                }
            });
        },
        copyUrl () {
            let data = {
                id: this.goodsId,
                type: this.shareType,
                group_id :this.groupId,
                team_id :this.teamId,
            }
            
            data.return_url = apiBaseUrl + 'wap/pages/share/jump';
            let userToken = this.$db.get('userToken')
            if (userToken) {
                data.token = userToken
            }
            let _this = this;
            _this.$api.createShareUrl(data, res => {
                if(res.status) {
                    //todo::要复制的内容是 res.data
                    uni.setClipboardData({
                        data:res.data,
                        success:function(data){
                            _this.$common.successToShow('复制成功');
                        }, 
                        fail:function(err){
                            _this.$common.errorToShow('复制分享URL失败');
                        }
                    })
                } else {
                    _this.$common.errorToShow('复制分享URL失败');
                }
            });
        },
        // 分享操作
        share () {
            // h5分享 判断是否是微信浏览器 引导用户完成分享操作
            
            // 其他浏览器的分享 
        }
    }
}    
</script>

<style>
.share-pop{
    height: 300upx;
    width: 100%;
    display: flex;
}
.share-item{
    flex: 1;
    text-align: center;
    font-size: 26upx;
    color: #333;
    padding: 20upx 0;
}
.share-item image{
    width: 80upx;
    height: 80upx;
    margin: 20upx;
}    
.share-item .btn{
    line-height: 1;
    display: block;
    font-size: 26upx;
    background-color: #fff;
}
</style>
shareByWx.vue
<template>
    
    <view style="width: 100%;height: 300upx;background: #FFFFFF;position: absolute;left:0;bottom: 0;">

        <view class="share-pop">
            <view class="share-item">
                <button class="btn" open-type="share">
                    <image src="../../../static/image/share-f.png" mode=""></image>
                    <view class="">
                        分享微信好友
                    </view>
                </button>
            </view>
            <view class="share-item" @click="createPoster()">
                <image src="../../../static/image/poster.png" mode=""></image>
                <view class="">生成海报</view>
            </view>
        </view>
        <view class="button-bottom">
            <button class="btn btn-w btn-square" @click="close()">关闭</button>
        </view>
        
    </view>    
</template>

<script>
import { apiBaseUrl } from '@/config/config.js'    
export default {
    props: {
        // 商品id
        goodsId: {
            type: Number,
            default: 0
        },
        // 分享的图片
        shareImg: {
            type: String,
            default: ''
        },
        // 分享标题
        shareTitle: {
            type: String,
            default: ''
        },
        // 分享内容
        shareContent: {
            type: String,
            default: ''
        },
        // 分享链接
        shareHref: {
            type: String,
            default: ''
        },
        //分享类型
        shareType:{
            type:Number,
            default:1
        },
        //拼团id
        groupId:{
            type:Number,
            default:0
        },
        //拼团的团队id
        teamId:{
            type:Number,
            default:0
        }
    },
    data () {
        return {
            shareType: 0,
            providerList: [] // 分享通道 包含生成海报
        }
    },
    mounted () {
        
    },
    methods: {
        // 关闭弹出层
        close () {
            this.$emit('close')
        },
        // 生成海报
        createPoster () {
            let data = {
                id: this.goodsId,
                type: this.shareType,
                group_id :this.groupId,
                team_id :this.teamId,
            }
            
            let pages = getCurrentPages()
            let page = pages[pages.length - 1]
            
            data.source = 2;
            data.return_url = 'pages/share/jump';//page.route;
            
            let userToken = this.$db.get('userToken')
            if (userToken) {
                data.token = userToken
            }
            
            this.$api.createPoster(data, res => {
                if (res.status) {
                    this.close()
                    this.$common.navigateTo('/pages/share?poster=' + res.data)
                } else {
                    this.$common.errorToShow(res.msg)
                }
            })
        }
    }
}    
</script>

<style>
.share-pop{
    height: 300upx;
    width: 100%;
    display: flex;
}
.share-item{
    flex: 1;
    text-align: center;
    font-size: 26upx;
    color: #333;
    padding: 20upx 0;
}
.share-item image{
    width: 80upx;
    height: 80upx;
    margin: 20upx;
}    
.share-item .btn{
    line-height: 1;
    display: block;
    font-size: 26upx;
    background-color: #fff;
}
</style>

spec

spec.vue
<template>
    <view>
        <view class="goods-specs" v-for="(item, index) in spesData" :key="index">
            <text class="pop-m-title">{{ index }}</text>
            <view class="pop-m-bd">
                <view :class="spes.cla" v-for="(spes, key) in item" :key="key" @click="specChangeSpes(index, key)">
                    {{ spes.name }}
                </view>
            </view>
        </view>
    </view>
</template>
<script>
    export default {
        name: "spec",
        props: {
            // 默认picker选中项索引
            spesData: {
                required: true
            }
        },
        methods: {
            specChangeSpes(v, k){
                let newData = {
                    v: v,
                    k: k
                }
                this.$emit("changeSpes", newData);
            }
        }
    }
</script>
<style>

.goods-specs,.goods-number{
    padding: 26upx;
    border-top: 1px solid #f3f3f3;
}
.goods-specs:first-child{
    border: none;
}
.pop-m-title{
    margin-right: 10upx;
    color: #666;
}
.pop-m-item{
    display: inline-block;
    float: left;
    padding: 6upx 16upx;
    background-color: #fff;
    color: #333;
    margin-right: 16upx;
    margin-bottom: 10upx;
}
.pop-m-bd{
    overflow: hidden;
    margin-top: 10upx;
}
.selected{
    border: 2upx solid #333;
    background-color: #333;
    color: #fff;
}
.not-selected{
    border: 2upx solid #ccc;
}
.none{
    border: 2upx dashed #ccc;
    color: #888;
}
</style>

tki-qrcode

qrcode.js
//---------------------------------------------------------------------
//
// QR Code Generator for JavaScript
//
// Copyright (c) 2009 Kazuhiko Arase
//
// URL: [url=http://www.d-project.com/]http://www.d-project.com/[/url]
//
// Licensed under the MIT license:
//        [url=http://www.opensource.org/licenses/mit-license.php]http://www.opensource.org/licenses/mit-license.php[/url]
//
// The word 'QR Code' is registered trademark of
// DENSO WAVE INCORPORATED
//        [url=http://www.denso-wave.com/qrcode/faqpatent-e.html]http://www.denso-wave.com/qrcode/faqpatent-e.html[/url]
//
//---------------------------------------------------------------------
 
//---------------------------------------------------------------------
// qrcode
//代码第1588行为补充代码
//修改人:chenxing
//2017-02-27 16:21:32
//---------------------------------------------------------------------
 
/**
 * qrcode
 * @param typeNumber 1 to 40
 * @param errorCorrectLevel 'L','M','Q','H'
 */
var qrcode = function(typeNumber, errorCorrectLevel) {
 
    var PAD0 = 0xEC;
    var PAD1 = 0x11;
 
    var _typeNumber = typeNumber;
    var _errorCorrectLevel = QRErrorCorrectLevel[errorCorrectLevel];
    var _modules = null;
    var _moduleCount = 0;
    var _dataCache = null;
    var _dataList = new Array();
 
    var _this = {};
 
    var makeImpl = function(test, maskPattern) {
 
        _moduleCount = _typeNumber * 4 + 17;
        _modules = function(moduleCount) {
            var modules = new Array(moduleCount);
            for (var row = 0; row < moduleCount; row += 1) {
                modules[row] = new Array(moduleCount);
                for (var col = 0; col < moduleCount; col += 1) {
                    modules[row][col] = null;
                }
            }
            return modules;
        }(_moduleCount);
 
        setupPositionProbePattern(0, 0);
        setupPositionProbePattern(_moduleCount - 7, 0);
        setupPositionProbePattern(0, _moduleCount - 7);
        setupPositionAdjustPattern();
        setupTimingPattern();
        setupTypeInfo(test, maskPattern);
 
        if (_typeNumber >= 7) {
            setupTypeNumber(test);
        }
 
        if (_dataCache == null) {
            _dataCache = createData(_typeNumber, _errorCorrectLevel, _dataList);
        }
 
        mapData(_dataCache, maskPattern);
    };
 
    var setupPositionProbePattern = function(row, col) {
 
        for (var r = -1; r <= 7; r += 1) {
 
            if (row + r <= -1 || _moduleCount <= row + r) continue;
 
            for (var c = -1; c <= 7; c += 1) {
 
                if (col + c <= -1 || _moduleCount <= col + c) continue;
 
                if ( (0 <= r && r <= 6 && (c == 0 || c == 6) )
                     || (0 <= c && c <= 6 && (r == 0 || r == 6) )
                     || (2 <= r && r <= 4 && 2 <= c && c <= 4) ) {
                    _modules[row + r][col + c] = true;
                } else {
                    _modules[row + r][col + c] = false;
                }
            }
        }
    };
 
    var getBestMaskPattern = function() {
 
        var minLostPoint = 0;
        var pattern = 0;
 
        for (var i = 0; i < 8; i += 1) {
 
            makeImpl(true, i);
 
            var lostPoint = QRUtil.getLostPoint(_this);
 
            if (i == 0 || minLostPoint > lostPoint) {
                minLostPoint = lostPoint;
                pattern = i;
            }
        }
 
        return pattern;
    };
 
    var setupTimingPattern = function() {
 
        for (var r = 8; r < _moduleCount - 8; r += 1) {
            if (_modules[r][6] != null) {
                continue;
            }
            _modules[r][6] = (r % 2 == 0);
        }
 
        for (var c = 8; c < _moduleCount - 8; c += 1) {
            if (_modules[6][c] != null) {
                continue;
            }
            _modules[6][c] = (c % 2 == 0);
        }
    };
 
    var setupPositionAdjustPattern = function() {
 
        var pos = QRUtil.getPatternPosition(_typeNumber);
 
        for (var i = 0; i < pos.length; i += 1) {
 
            for (var j = 0; j < pos.length; j += 1) {
 
                var row = pos[i];
                var col = pos[j];
 
                if (_modules[row][col] != null) {
                    continue;
                }
 
                for (var r = -2; r <= 2; r += 1) {
 
                    for (var c = -2; c <= 2; c += 1) {
 
                        if (r == -2 || r == 2 || c == -2 || c == 2
                            || (r == 0 && c == 0) ) {
                            _modules[row + r][col + c] = true;
                        } else {
                            _modules[row + r][col + c] = false;
                        }
                    }
                }
            }
        }
    };
 
    var setupTypeNumber = function(test) {
 
        var bits = QRUtil.getBCHTypeNumber(_typeNumber);
 
        for (var i = 0; i < 18; i += 1) {
            var mod = (!test && ( (bits >> i) & 1) == 1);
            _modules[Math.floor(i / 3)][i % 3 + _moduleCount - 8 - 3] = mod;
        }
 
        for (var i = 0; i < 18; i += 1) {
            var mod = (!test && ( (bits >> i) & 1) == 1);
            _modules[i % 3 + _moduleCount - 8 - 3][Math.floor(i / 3)] = mod;
        }
    };
 
    var setupTypeInfo = function(test, maskPattern) {
 
        var data = (_errorCorrectLevel << 3) | maskPattern;
        var bits = QRUtil.getBCHTypeInfo(data);
 
        // vertical
        for (var i = 0; i < 15; i += 1) {
 
            var mod = (!test && ( (bits >> i) & 1) == 1);
 
            if (i < 6) {
                _modules[i][8] = mod;
            } else if (i < 8) {
                _modules[i + 1][8] = mod;
            } else {
                _modules[_moduleCount - 15 + i][8] = mod;
            }
        }
 
        // horizontal
        for (var i = 0; i < 15; i += 1) {
 
            var mod = (!test && ( (bits >> i) & 1) == 1);
 
            if (i < 8) {
                _modules[8][_moduleCount - i - 1] = mod;
            } else if (i < 9) {
                _modules[8][15 - i - 1 + 1] = mod;
            } else {
                _modules[8][15 - i - 1] = mod;
            }
        }
 
        // fixed module
        _modules[_moduleCount - 8][8] = (!test);
    };
 
    var mapData = function(data, maskPattern) {
 
        var inc = -1;
        var row = _moduleCount - 1;
        var bitIndex = 7;
        var byteIndex = 0;
        var maskFunc = QRUtil.getMaskFunction(maskPattern);
 
        for (var col = _moduleCount - 1; col > 0; col -= 2) {
 
            if (col == 6) col -= 1;
 
            while (true) {
 
                for (var c = 0; c < 2; c += 1) {
 
                    if (_modules[row][col - c] == null) {
 
                        var dark = false;
 
                        if (byteIndex < data.length) {
                            dark = ( ( (data[byteIndex] >>> bitIndex) & 1) == 1);
                        }
 
                        var mask = maskFunc(row, col - c);
 
                        if (mask) {
                            dark = !dark;
                        }
 
                        _modules[row][col - c] = dark;
                        bitIndex -= 1;
 
                        if (bitIndex == -1) {
                            byteIndex += 1;
                            bitIndex = 7;
                        }
                    }
                }
 
                row += inc;
 
                if (row < 0 || _moduleCount <= row) {
                    row -= inc;
                    inc = -inc;
                    break;
                }
            }
        }
    };
 
    var createBytes = function(buffer, rsBlocks) {
 
        var offset = 0;
 
        var maxDcCount = 0;
        var maxEcCount = 0;
 
        var dcdata = new Array(rsBlocks.length);
        var ecdata = new Array(rsBlocks.length);
 
        for (var r = 0; r < rsBlocks.length; r += 1) {
 
            var dcCount = rsBlocks[r].dataCount;
            var ecCount = rsBlocks[r].totalCount - dcCount;
 
            maxDcCount = Math.max(maxDcCount, dcCount);
            maxEcCount = Math.max(maxEcCount, ecCount);
 
            dcdata[r] = new Array(dcCount);
 
            for (var i = 0; i < dcdata[r].length; i += 1) {
                dcdata[r][i] = 0xff & buffer.getBuffer()[i + offset];
            }
            offset += dcCount;
 
            var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount);
            var rawPoly = qrPolynomial(dcdata[r], rsPoly.getLength() - 1);
 
            var modPoly = rawPoly.mod(rsPoly);
            ecdata[r] = new Array(rsPoly.getLength() - 1);
            for (var i = 0; i < ecdata[r].length; i += 1) {
                var modIndex = i + modPoly.getLength() - ecdata[r].length;
                ecdata[r][i] = (modIndex >= 0)? modPoly.getAt(modIndex) : 0;
            }
        }
 
        var totalCodeCount = 0;
        for (var i = 0; i < rsBlocks.length; i += 1) {
            totalCodeCount += rsBlocks[i].totalCount;
        }
 
        var data = new Array(totalCodeCount);
        var index = 0;
 
        for (var i = 0; i < maxDcCount; i += 1) {
            for (var r = 0; r < rsBlocks.length; r += 1) {
                if (i < dcdata[r].length) {
                    data[index] = dcdata[r][i];
                    index += 1;
                }
            }
        }
 
        for (var i = 0; i < maxEcCount; i += 1) {
            for (var r = 0; r < rsBlocks.length; r += 1) {
                if (i < ecdata[r].length) {
                    data[index] = ecdata[r][i];
                    index += 1;
                }
            }
        }
 
        return data;
    };
 
    var createData = function(typeNumber, errorCorrectLevel, dataList) {
 
        var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel);
 
        var buffer = qrBitBuffer();
 
        for (var i = 0; i < dataList.length; i += 1) {
            var data = dataList[i];
            buffer.put(data.getMode(), 4);
            buffer.put(data.getLength(), QRUtil.getLengthInBits(data.getMode(), typeNumber) );
            data.write(buffer);
        }
 
        // calc num max data.
        var totalDataCount = 0;
        for (var i = 0; i < rsBlocks.length; i += 1) {
            totalDataCount += rsBlocks[i].dataCount;
        }
 
        if (buffer.getLengthInBits() > totalDataCount * 8) {
            throw new Error('code length overflow. ('
                            + buffer.getLengthInBits()
                            + '>'
                            + totalDataCount * 8
                            + ')');
        }
 
        // end code
        if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) {
            buffer.put(0, 4);
        }
 
        // padding
        while (buffer.getLengthInBits() % 8 != 0) {
            buffer.putBit(false);
        }
 
        // padding
        while (true) {
 
            if (buffer.getLengthInBits() >= totalDataCount * 8) {
                break;
            }
            buffer.put(PAD0, 8);
 
            if (buffer.getLengthInBits() >= totalDataCount * 8) {
                break;
            }
            buffer.put(PAD1, 8);
        }
 
        return createBytes(buffer, rsBlocks);
    };
 
    _this.addData = function(data) {
        var newData = qr8BitByte(data);
        _dataList.push(newData);
        _dataCache = null;
    };
 
    _this.isDark = function(row, col) {
        if (row < 0 || _moduleCount <= row || col < 0 || _moduleCount <= col) {
            throw new Error(row + ',' + col);
        }
        return _modules[row][col];
    };
 
    _this.getModuleCount = function() {
        return _moduleCount;
    };
 
    _this.make = function() {
        makeImpl(false, getBestMaskPattern() );
    };
 
    _this.createTableTag = function(cellSize, margin) {
 
        cellSize = cellSize || 2;
        margin = (typeof margin == 'undefined')? cellSize * 4 : margin;
 
        var qrHtml = '';
 
        qrHtml += '<table style="';
        qrHtml += ' border-width: 0px; border-style: none;';
        qrHtml += ' border-collapse: collapse;';
        qrHtml += ' padding: 0px; margin: ' + margin + 'px;';
        qrHtml += '">';
        qrHtml += '<tbody>';
 
        for (var r = 0; r < _this.getModuleCount(); r += 1) {
 
            qrHtml += '<tr>';
 
            for (var c = 0; c < _this.getModuleCount(); c += 1) {
                qrHtml += '<td style="';
                qrHtml += ' border-width: 0px; border-style: none;';
                qrHtml += ' border-collapse: collapse;';
                qrHtml += ' padding: 0px; margin: 0px;';
                qrHtml += ' width: ' + cellSize + 'px;';
                qrHtml += ' height: ' + cellSize + 'px;';
                qrHtml += ' background-color: ';
                qrHtml += _this.isDark(r, c)? '#000000' : '#ffffff';
                qrHtml += ';';
                qrHtml += '"/>';
            }
 
            qrHtml += '</tr>';
        }
 
        qrHtml += '</tbody>';
        qrHtml += '</table>';
 
        return qrHtml;
    };
 
    _this.createImgTag = function(cellSize, margin, size) {
 
        cellSize = cellSize || 2;
        margin = (typeof margin == 'undefined')? cellSize * 4 : margin;
 
        var min = margin;
        var max = _this.getModuleCount() * cellSize + margin;
 
        return createImgTag(size, size, function(x, y) {
            if (min <= x && x < max && min <= y && y < max) {
                var c = Math.floor( (x - min) / cellSize);
                var r = Math.floor( (y - min) / cellSize);
                return _this.isDark(r, c)? 0 : 1;
            } else {
                return 1;
            }
        } );
    };
 
    return _this;
};
 
//---------------------------------------------------------------------
// qrcode.stringToBytes
//---------------------------------------------------------------------
 
qrcode.stringToBytes = function(s) {
    var bytes = new Array();
    for (var i = 0; i < s.length; i += 1) {
        var c = s.charCodeAt(i);
        bytes.push(c & 0xff);
    }
    return bytes;
};
 
//---------------------------------------------------------------------
// qrcode.createStringToBytes
//---------------------------------------------------------------------
 
/**
 * @param unicodeData base64 string of byte array.
 * [16bit Unicode],[16bit Bytes], ...
 * @param numChars
 */
qrcode.createStringToBytes = function(unicodeData, numChars) {
 
    // create conversion map.
 
    var unicodeMap = function() {
 
        var bin = base64DecodeInputStream(unicodeData);
        var read = function() {
            var b = bin.read();
            if (b == -1) throw new Error();
            return b;
        };
 
        var count = 0;
        var unicodeMap = {};
        while (true) {
            var b0 = bin.read();
            if (b0 == -1) break;
            var b1 = read();
            var b2 = read();
            var b3 = read();
            var k = String.fromCharCode( (b0 << 8) | b1);
            var v = (b2 << 8) | b3;
            unicodeMap[k] = v;
            count += 1;
        }
        if (count != numChars) {
            throw new Error(count + ' != ' + numChars);
        }
 
        return unicodeMap;
    }();
 
    var unknownChar = '?'.charCodeAt(0);
 
    return function(s) {
        var bytes = new Array();
        for (var i = 0; i < s.length; i += 1) {
            var c = s.charCodeAt(i);
            if (c < 128) {
                bytes.push(c);
            } else {
                var b = unicodeMap[s.charAt(i)];
                if (typeof b == 'number') {
                    if ( (b & 0xff) == b) {
                        // 1byte
                        bytes.push(b);
                    } else {
                        // 2bytes
                        bytes.push(b >>> 8);
                        bytes.push(b & 0xff);
                    }
                } else {
                    bytes.push(unknownChar);
                }
            }
        }
        return bytes;
    };
};
 
//---------------------------------------------------------------------
// QRMode
//---------------------------------------------------------------------
 
var QRMode = {
    MODE_NUMBER :                1 << 0,
    MODE_ALPHA_NUM :         1 << 1,
    MODE_8BIT_BYTE :         1 << 2,
    MODE_KANJI :                1 << 3
};
 
//---------------------------------------------------------------------
// QRErrorCorrectLevel
//---------------------------------------------------------------------
 
var QRErrorCorrectLevel = {
    L : 1,
    M : 0,
    Q : 3,
    H : 2
};
 
//---------------------------------------------------------------------
// QRMaskPattern
//---------------------------------------------------------------------
 
var QRMaskPattern = {
    PATTERN000 : 0,
    PATTERN001 : 1,
    PATTERN010 : 2,
    PATTERN011 : 3,
    PATTERN100 : 4,
    PATTERN101 : 5,
    PATTERN110 : 6,
    PATTERN111 : 7
};
 
//---------------------------------------------------------------------
// QRUtil
//---------------------------------------------------------------------
 
var QRUtil = function() {
 
    var PATTERN_POSITION_TABLE = [
        [],
        [6, 18],
        [6, 22],
        [6, 26],
        [6, 30],
        [6, 34],
        [6, 22, 38],
        [6, 24, 42],
        [6, 26, 46],
        [6, 28, 50],
        [6, 30, 54],
        [6, 32, 58],
        [6, 34, 62],
        [6, 26, 46, 66],
        [6, 26, 48, 70],
        [6, 26, 50, 74],
        [6, 30, 54, 78],
        [6, 30, 56, 82],
        [6, 30, 58, 86],
        [6, 34, 62, 90],
        [6, 28, 50, 72, 94],
        [6, 26, 50, 74, 98],
        [6, 30, 54, 78, 102],
        [6, 28, 54, 80, 106],
        [6, 32, 58, 84, 110],
        [6, 30, 58, 86, 114],
        [6, 34, 62, 90, 118],
        [6, 26, 50, 74, 98, 122],
        [6, 30, 54, 78, 102, 126],
        [6, 26, 52, 78, 104, 130],
        [6, 30, 56, 82, 108, 134],
        [6, 34, 60, 86, 112, 138],
        [6, 30, 58, 86, 114, 142],
        [6, 34, 62, 90, 118, 146],
        [6, 30, 54, 78, 102, 126, 150],
        [6, 24, 50, 76, 102, 128, 154],
        [6, 28, 54, 80, 106, 132, 158],
        [6, 32, 58, 84, 110, 136, 162],
        [6, 26, 54, 82, 110, 138, 166],
        [6, 30, 58, 86, 114, 142, 170]
    ];
    var G15 = (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0);
    var G18 = (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0);
    var G15_MASK = (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1);
 
    var _this = {};
 
    var getBCHDigit = function(data) {
        var digit = 0;
        while (data != 0) {
            digit += 1;
            data >>>= 1;
        }
        return digit;
    };
 
    _this.getBCHTypeInfo = function(data) {
        var d = data << 10;
        while (getBCHDigit(d) - getBCHDigit(G15) >= 0) {
            d ^= (G15 << (getBCHDigit(d) - getBCHDigit(G15) ) );
        }
        return ( (data << 10) | d) ^ G15_MASK;
    };
 
    _this.getBCHTypeNumber = function(data) {
        var d = data << 12;
        while (getBCHDigit(d) - getBCHDigit(G18) >= 0) {
            d ^= (G18 << (getBCHDigit(d) - getBCHDigit(G18) ) );
        }
        return (data << 12) | d;
    };
 
    _this.getPatternPosition = function(typeNumber) {
        return PATTERN_POSITION_TABLE[typeNumber - 1];
    };
 
    _this.getMaskFunction = function(maskPattern) {
 
        switch (maskPattern) {
 
            case QRMaskPattern.PATTERN000 :
                return function(i, j) { return (i + j) % 2 == 0; };
            case QRMaskPattern.PATTERN001 :
                return function(i, j) { return i % 2 == 0; };
            case QRMaskPattern.PATTERN010 :
                return function(i, j) { return j % 3 == 0; };
            case QRMaskPattern.PATTERN011 :
                return function(i, j) { return (i + j) % 3 == 0; };
            case QRMaskPattern.PATTERN100 :
                return function(i, j) { return (Math.floor(i / 2) + Math.floor(j / 3) ) % 2 == 0; };
            case QRMaskPattern.PATTERN101 :
                return function(i, j) { return (i * j) % 2 + (i * j) % 3 == 0; };
            case QRMaskPattern.PATTERN110 :
                return function(i, j) { return ( (i * j) % 2 + (i * j) % 3) % 2 == 0; };
            case QRMaskPattern.PATTERN111 :
                return function(i, j) { return ( (i * j) % 3 + (i + j) % 2) % 2 == 0; };
 
                default :
                throw new Error('bad maskPattern:' + maskPattern);
        }
    };
 
    _this.getErrorCorrectPolynomial = function(errorCorrectLength) {
        var a = qrPolynomial([1], 0);
        for (var i = 0; i < errorCorrectLength; i += 1) {
            a = a.multiply(qrPolynomial([1, QRMath.gexp(i)], 0) );
        }
        return a;
    };
 
    _this.getLengthInBits = function(mode, type) {
 
        if (1 <= type && type < 10) {
 
            // 1 - 9
 
            switch(mode) {
                case QRMode.MODE_NUMBER         : return 10;
                case QRMode.MODE_ALPHA_NUM         : return 9;
                case QRMode.MODE_8BIT_BYTE        : return 8;
                case QRMode.MODE_KANJI                : return 8;
                    default :
                    throw new Error('mode:' + mode);
            }
 
        } else if (type < 27) {
 
            // 10 - 26
 
            switch(mode) {
                case QRMode.MODE_NUMBER         : return 12;
                case QRMode.MODE_ALPHA_NUM         : return 11;
                case QRMode.MODE_8BIT_BYTE        : return 16;
                case QRMode.MODE_KANJI                : return 10;
                    default :
                    throw new Error('mode:' + mode);
            }
 
        } else if (type < 41) {
 
            // 27 - 40
 
            switch(mode) {
                case QRMode.MODE_NUMBER         : return 14;
                case QRMode.MODE_ALPHA_NUM        : return 13;
                case QRMode.MODE_8BIT_BYTE        : return 16;
                case QRMode.MODE_KANJI                : return 12;
                    default :
                    throw new Error('mode:' + mode);
            }
 
        } else {
            throw new Error('type:' + type);
        }
    };
 
    _this.getLostPoint = function(qrcode) {
 
        var moduleCount = qrcode.getModuleCount();
 
        var lostPoint = 0;
 
        // LEVEL1
 
        for (var row = 0; row < moduleCount; row += 1) {
            for (var col = 0; col < moduleCount; col += 1) {
 
                var sameCount = 0;
                var dark = qrcode.isDark(row, col);
 
                for (var r = -1; r <= 1; r += 1) {
 
                    if (row + r < 0 || moduleCount <= row + r) {
                        continue;
                    }
 
                    for (var c = -1; c <= 1; c += 1) {
 
                        if (col + c < 0 || moduleCount <= col + c) {
                            continue;
                        }
 
                        if (r == 0 && c == 0) {
                            continue;
                        }
 
                        if (dark == qrcode.isDark(row + r, col + c) ) {
                            sameCount += 1;
                        }
                    }
                }
 
                if (sameCount > 5) {
                    lostPoint += (3 + sameCount - 5);
                }
            }
        };
 
        // LEVEL2
 
        for (var row = 0; row < moduleCount - 1; row += 1) {
            for (var col = 0; col < moduleCount - 1; col += 1) {
                var count = 0;
                if (qrcode.isDark(row, col) ) count += 1;
                if (qrcode.isDark(row + 1, col) ) count += 1;
                if (qrcode.isDark(row, col + 1) ) count += 1;
                if (qrcode.isDark(row + 1, col + 1) ) count += 1;
                if (count == 0 || count == 4) {
                    lostPoint += 3;
                }
            }
        }
 
        // LEVEL3
 
        for (var row = 0; row < moduleCount; row += 1) {
            for (var col = 0; col < moduleCount - 6; col += 1) {
                if (qrcode.isDark(row, col)
                    && !qrcode.isDark(row, col + 1)
                    &&  qrcode.isDark(row, col + 2)
                    &&  qrcode.isDark(row, col + 3)
                    &&  qrcode.isDark(row, col + 4)
                    && !qrcode.isDark(row, col + 5)
                    &&  qrcode.isDark(row, col + 6) ) {
                    lostPoint += 40;
                }
            }
        }
 
        for (var col = 0; col < moduleCount; col += 1) {
            for (var row = 0; row < moduleCount - 6; row += 1) {
                if (qrcode.isDark(row, col)
                    && !qrcode.isDark(row + 1, col)
                    &&  qrcode.isDark(row + 2, col)
                    &&  qrcode.isDark(row + 3, col)
                    &&  qrcode.isDark(row + 4, col)
                    && !qrcode.isDark(row + 5, col)
                    &&  qrcode.isDark(row + 6, col) ) {
                    lostPoint += 40;
                }
            }
        }
 
        // LEVEL4
 
        var darkCount = 0;
 
        for (var col = 0; col < moduleCount; col += 1) {
            for (var row = 0; row < moduleCount; row += 1) {
                if (qrcode.isDark(row, col) ) {
                    darkCount += 1;
                }
            }
        }
 
        var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5;
        lostPoint += ratio * 10;
 
        return lostPoint;
    };
 
    return _this;
}();
 
//---------------------------------------------------------------------
// QRMath
//---------------------------------------------------------------------
 
var QRMath = function() {
 
    var EXP_TABLE = new Array(256);
    var LOG_TABLE = new Array(256);
 
    // initialize tables
    for (var i = 0; i < 8; i += 1) {
        EXP_TABLE[i] = 1 << i;
    }
    for (var i = 8; i < 256; i += 1) {
        EXP_TABLE[i] = EXP_TABLE[i - 4]
            ^ EXP_TABLE[i - 5]
            ^ EXP_TABLE[i - 6]
            ^ EXP_TABLE[i - 8];
    }
    for (var i = 0; i < 255; i += 1) {
        LOG_TABLE[EXP_TABLE[i] ] = i;
    }
 
    var _this = {};
 
    _this.glog = function(n) {
 
        if (n < 1) {
            throw new Error('glog(' + n + ')');
        }
 
        return LOG_TABLE[n];
    };
 
    _this.gexp = function(n) {
 
        while (n < 0) {
            n += 255;
        }
 
        while (n >= 256) {
            n -= 255;
        }
 
        return EXP_TABLE[n];
    };
 
    return _this;
}();
 
//---------------------------------------------------------------------
// qrPolynomial
//---------------------------------------------------------------------
 
function qrPolynomial(num, shift) {
 
    if (typeof num.length == 'undefined') {
        throw new Error(num.length + '/' + shift);
    }
 
    var _num = function() {
        var offset = 0;
        while (offset < num.length && num[offset] == 0) {
            offset += 1;
        }
        var _num = new Array(num.length - offset + shift);
        for (var i = 0; i < num.length - offset; i += 1) {
            _num[i] = num[i + offset];
        }
        return _num;
    }();
 
    var _this = {};
 
    _this.getAt = function(index) {
        return _num[index];
    };
 
    _this.getLength = function() {
        return _num.length;
    };
 
    _this.multiply = function(e) {
 
        var num = new Array(_this.getLength() + e.getLength() - 1);
 
        for (var i = 0; i < _this.getLength(); i += 1) {
            for (var j = 0; j < e.getLength(); j += 1) {
                num[i + j] ^= QRMath.gexp(QRMath.glog(_this.getAt(i) ) + QRMath.glog(e.getAt(j) ) );
            }
        }
 
        return qrPolynomial(num, 0);
    };
 
    _this.mod = function(e) {
 
        if (_this.getLength() - e.getLength() < 0) {
            return _this;
        }
 
        var ratio = QRMath.glog(_this.getAt(0) ) - QRMath.glog(e.getAt(0) );
 
        var num = new Array(_this.getLength() );
        for (var i = 0; i < _this.getLength(); i += 1) {
            num[i] = _this.getAt(i);
        }
 
        for (var i = 0; i < e.getLength(); i += 1) {
            num[i] ^= QRMath.gexp(QRMath.glog(e.getAt(i) ) + ratio);
        }
 
        // recursive call
        return qrPolynomial(num, 0).mod(e);
    };
 
    return _this;
};
 
//---------------------------------------------------------------------
// QRRSBlock
//---------------------------------------------------------------------
 
var QRRSBlock = function() {
 
 
    // [1: [L, M, Q, H], ..]
    var RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]];
 
    var qrRSBlock = function(totalCount, dataCount) {
        var _this = {};
        _this.totalCount = totalCount;
        _this.dataCount = dataCount;
        return _this;
    };
 
    var _this = {};
 
    var getRsBlockTable = function(typeNumber, errorCorrectLevel) {
 
        switch(errorCorrectLevel) {
            case QRErrorCorrectLevel.L :
                return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0];
            case QRErrorCorrectLevel.M :
                return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1];
            case QRErrorCorrectLevel.Q :
                return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2];
            case QRErrorCorrectLevel.H :
                return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3];
                default :
                return undefined;
        }
    };
 
    _this.getRSBlocks = function(typeNumber, errorCorrectLevel) {
 
        var rsBlock = getRsBlockTable(typeNumber, errorCorrectLevel);
 
        if (typeof rsBlock == 'undefined') {
            throw new Error('bad rs block [url=home.php?mod=space&uid=5302]@[/url] typeNumber:' + typeNumber +
                            '/errorCorrectLevel:' + errorCorrectLevel);
        }
 
        var length = rsBlock.length / 3;
 
        var list = new Array();
 
        for (var i = 0; i < length; i += 1) {
 
            var count = rsBlock[i * 3 + 0];
            var totalCount = rsBlock[i * 3 + 1];
            var dataCount = rsBlock[i * 3 + 2];
 
            for (var j = 0; j < count; j += 1) {
                list.push(qrRSBlock(totalCount, dataCount) );
            }
        }
 
        return list;
    };
 
    return _this;
}();
 
//---------------------------------------------------------------------
// qrBitBuffer
//---------------------------------------------------------------------
 
var qrBitBuffer = function() {
 
    var _buffer = new Array();
    var _length = 0;
 
    var _this = {};
 
    _this.getBuffer = function() {
        return _buffer;
    };
 
    _this.getAt = function(index) {
        var bufIndex = Math.floor(index / 8);
        return ( (_buffer[bufIndex] >>> (7 - index % 8) ) & 1) == 1;
    };
 
    _this.put = function(num, length) {
        for (var i = 0; i < length; i += 1) {
            _this.putBit( ( (num >>> (length - i - 1) ) & 1) == 1);
        }
    };
 
    _this.getLengthInBits = function() {
        return _length;
    };
 
    _this.putBit = function(bit) {
 
        var bufIndex = Math.floor(_length / 8);
        if (_buffer.length <= bufIndex) {
            _buffer.push(0);
        }
 
        if (bit) {
            _buffer[bufIndex] |= (0x80 >>> (_length % 8) );
        }
 
        _length += 1;
    };
 
    return _this;
};
 
//---------------------------------------------------------------------
// qr8BitByte
//---------------------------------------------------------------------
 
var qr8BitByte = function(data) {
 
    var _mode = QRMode.MODE_8BIT_BYTE;
    var _data = data;
    var _parsedData = [];
 
    var _this = {};
 
 
    // Added to support UTF-8 Characters
    for (var i = 0, l = _data.length; i < l; i++) {
        var byteArray = [];
        var code = _data.charCodeAt(i);
 
        if (code > 0x10000) {
            byteArray[0] = 0xF0 | ((code & 0x1C0000) >>> 18);
            byteArray[1] = 0x80 | ((code & 0x3F000) >>> 12);
            byteArray[2] = 0x80 | ((code & 0xFC0) >>> 6);
            byteArray[3] = 0x80 | (code & 0x3F);
        } else if (code > 0x800) {
            byteArray[0] = 0xE0 | ((code & 0xF000) >>> 12);
            byteArray[1] = 0x80 | ((code & 0xFC0) >>> 6);
            byteArray[2] = 0x80 | (code & 0x3F);
        } else if (code > 0x80) {
            byteArray[0] = 0xC0 | ((code & 0x7C0) >>> 6);
            byteArray[1] = 0x80 | (code & 0x3F);
        } else {
            byteArray[0] = code;
        }
 
        // Fix Unicode corruption bug
        _parsedData.push(byteArray);
    }
 
    _parsedData = Array.prototype.concat.apply([], _parsedData);
 
    if (_parsedData.length != _data.length) {
        _parsedData.unshift(191);
        _parsedData.unshift(187);
        _parsedData.unshift(239);
    }
 
    var _bytes = _parsedData;
 
    _this.getMode = function() {
        return _mode;
    };
 
    _this.getLength = function(buffer) {
        return _bytes.length;
    };
 
    _this.write = function(buffer) {
        for (var i = 0; i < _bytes.length; i += 1) {
            buffer.put(_bytes[i], 8);
        }
    };
 
    return _this;
};
 
//=====================================================================
// GIF Support etc.
//
 
//---------------------------------------------------------------------
// byteArrayOutputStream
//---------------------------------------------------------------------
 
var byteArrayOutputStream = function() {
 
    var _bytes = new Array();
 
    var _this = {};
 
    _this.writeByte = function(b) {
        _bytes.push(b & 0xff);
    };
 
    _this.writeShort = function(i) {
        _this.writeByte(i);
        _this.writeByte(i >>> 8);
    };
 
    _this.writeBytes = function(b, off, len) {
        off = off || 0;
        len = len || b.length;
        for (var i = 0; i < len; i += 1) {
            _this.writeByte(b[i + off]);
        }
    };
 
    _this.writeString = function(s) {
        for (var i = 0; i < s.length; i += 1) {
            _this.writeByte(s.charCodeAt(i) );
        }
    };
 
    _this.toByteArray = function() {
        return _bytes;
    };
 
    _this.toString = function() {
        var s = '';
        s += '[';
        for (var i = 0; i < _bytes.length; i += 1) {
            if (i > 0) {
                s += ',';
            }
            s += _bytes[i];
        }
        s += ']';
        return s;
    };
 
    return _this;
};
 
//---------------------------------------------------------------------
// base64EncodeOutputStream
//---------------------------------------------------------------------
 
var base64EncodeOutputStream = function() {
 
    var _buffer = 0;
    var _buflen = 0;
    var _length = 0;
    var _base64 = '';
 
    var _this = {};
 
    var writeEncoded = function(b) {
        _base64 += String.fromCharCode(encode(b & 0x3f) );
    };
 
    var encode = function(n) {
        if (n < 0) {
            // error.
        } else if (n < 26) {
            return 0x41 + n;
        } else if (n < 52) {
            return 0x61 + (n - 26);
        } else if (n < 62) {
            return 0x30 + (n - 52);
        } else if (n == 62) {
            return 0x2b;
        } else if (n == 63) {
            return 0x2f;
        }
        throw new Error('n:' + n);
    };
 
    _this.writeByte = function(n) {
 
        _buffer = (_buffer << 8) | (n & 0xff);
        _buflen += 8;
        _length += 1;
 
        while (_buflen >= 6) {
            writeEncoded(_buffer >>> (_buflen - 6) );
            _buflen -= 6;
        }
    };
 
    _this.flush = function() {
 
        if (_buflen > 0) {
            writeEncoded(_buffer << (6 - _buflen) );
            _buffer = 0;
            _buflen = 0;
        }
 
        if (_length % 3 != 0) {
            // padding
            var padlen = 3 - _length % 3;
            for (var i = 0; i < padlen; i += 1) {
                _base64 += '=';
            }
        }
    };
 
    _this.toString = function() {
        return _base64;
    };
 
    return _this;
};
 
//---------------------------------------------------------------------
// base64DecodeInputStream
//---------------------------------------------------------------------
 
var base64DecodeInputStream = function(str) {
 
    var _str = str;
    var _pos = 0;
    var _buffer = 0;
    var _buflen = 0;
 
    var _this = {};
 
    _this.read = function() {
 
        while (_buflen < 8) {
 
            if (_pos >= _str.length) {
                if (_buflen == 0) {
                    return -1;
                }
                throw new Error('unexpected end of file./' + _buflen);
            }
 
            var c = _str.charAt(_pos);
            _pos += 1;
 
            if (c == '=') {
                _buflen = 0;
                return -1;
            } else if (c.match(/^\s$/) ) {
                // ignore if whitespace.
                continue;
            }
 
            _buffer = (_buffer << 6) | decode(c.charCodeAt(0) );
            _buflen += 6;
        }
 
        var n = (_buffer >>> (_buflen - 8) ) & 0xff;
        _buflen -= 8;
        return n;
    };
 
    var decode = function(c) {
        if (0x41 <= c && c <= 0x5a) {
            return c - 0x41;
        } else if (0x61 <= c && c <= 0x7a) {
            return c - 0x61 + 26;
        } else if (0x30 <= c && c <= 0x39) {
            return c - 0x30 + 52;
        } else if (c == 0x2b) {
            return 62;
        } else if (c == 0x2f) {
            return 63;
        } else {
            throw new Error('c:' + c);
        }
    };
 
    return _this;
};
 
//---------------------------------------------------------------------
// gifImage (B/W)
//---------------------------------------------------------------------
 
var gifImage = function(width, height) {
 
    var _width = width;
    var _height = height;
    var _data = new Array(width * height);
 
    var _this = {};
 
    _this.setPixel = function(x, y, pixel) {
        _data[y * _width + x] = pixel;
    };
 
    _this.write = function(out) {
 
        //---------------------------------
        // GIF Signature
 
        out.writeString('GIF87a');
 
        //---------------------------------
        // Screen Descriptor
 
        out.writeShort(_width);
        out.writeShort(_height);
 
        out.writeByte(0x80); // 2bit
        out.writeByte(0);
        out.writeByte(0);
 
        //---------------------------------
        // Global Color Map
 
        // black
        out.writeByte(0x00);
        out.writeByte(0x00);
        out.writeByte(0x00);
 
        // white
        out.writeByte(0xff);
        out.writeByte(0xff);
        out.writeByte(0xff);
 
        //---------------------------------
        // Image Descriptor
 
        out.writeString(',');
        out.writeShort(0);
        out.writeShort(0);
        out.writeShort(_width);
        out.writeShort(_height);
        out.writeByte(0);
 
        //---------------------------------
        // Local Color Map
 
        //---------------------------------
        // Raster Data
 
        var lzwMinCodeSize = 2;
        var raster = getLZWRaster(lzwMinCodeSize);
 
        out.writeByte(lzwMinCodeSize);
 
        var offset = 0;
 
        while (raster.length - offset > 255) {
            out.writeByte(255);
            out.writeBytes(raster, offset, 255);
            offset += 255;
        }
 
        out.writeByte(raster.length - offset);
        out.writeBytes(raster, offset, raster.length - offset);
        out.writeByte(0x00);
 
        //---------------------------------
        // GIF Terminator
        out.writeString(';');
    };
 
    var bitOutputStream = function(out) {
 
        var _out = out;
        var _bitLength = 0;
        var _bitBuffer = 0;
 
        var _this = {};
 
        _this.write = function(data, length) {
 
            if ( (data >>> length) != 0) {
                throw new Error('length over');
            }
 
            while (_bitLength + length >= 8) {
                _out.writeByte(0xff & ( (data << _bitLength) | _bitBuffer) );
                length -= (8 - _bitLength);
                data >>>= (8 - _bitLength);
                _bitBuffer = 0;
                _bitLength = 0;
            }
 
            _bitBuffer = (data << _bitLength) | _bitBuffer;
            _bitLength = _bitLength + length;
        };
 
        _this.flush = function() {
            if (_bitLength > 0) {
                _out.writeByte(_bitBuffer);
            }
        };
 
        return _this;
    };
 
    var getLZWRaster = function(lzwMinCodeSize) {
 
        var clearCode = 1 << lzwMinCodeSize;
        var endCode = (1 << lzwMinCodeSize) + 1;
        var bitLength = lzwMinCodeSize + 1;
 
        // Setup LZWTable
        var table = lzwTable();
 
        for (var i = 0; i < clearCode; i += 1) {
            table.add(String.fromCharCode(i) );
        }
        table.add(String.fromCharCode(clearCode) );
        table.add(String.fromCharCode(endCode) );
 
        var byteOut = byteArrayOutputStream();
        var bitOut = bitOutputStream(byteOut);
 
        // clear code
        bitOut.write(clearCode, bitLength);
 
        var dataIndex = 0;
 
        var s = String.fromCharCode(_data[dataIndex]);
        dataIndex += 1;
 
        while (dataIndex < _data.length) {
 
            var c = String.fromCharCode(_data[dataIndex]);
            dataIndex += 1;
 
            if (table.contains(s + c) ) {
 
                s = s + c;
 
            } else {
 
                bitOut.write(table.indexOf(s), bitLength);
 
                if (table.size() < 0xfff) {
 
                    if (table.size() == (1 << bitLength) ) {
                        bitLength += 1;
                    }
 
                    table.add(s + c);
                }
 
                s = c;
            }
        }
 
        bitOut.write(table.indexOf(s), bitLength);
 
        // end code
        bitOut.write(endCode, bitLength);
 
        bitOut.flush();
 
        return byteOut.toByteArray();
    };
 
    var lzwTable = function() {
 
        var _map = {};
        var _size = 0;
 
        var _this = {};
 
        _this.add = function(key) {
            if (_this.contains(key) ) {
                throw new Error('dup key:' + key);
            }
            _map[key] = _size;
            _size += 1;
        };
 
        _this.size = function() {
            return _size;
        };
 
        _this.indexOf = function(key) {
            return _map[key];
        };
 
        _this.contains = function(key) {
            return typeof _map[key] != 'undefined';
        };
 
        return _this;
    };
 
    return _this;
};
 
var createImgTag = function(width, height, getPixel, alt) {
 
    var gif = gifImage(width, height);
    for (var y = 0; y < height; y += 1) {
        for (var x = 0; x < width; x += 1) {
            gif.setPixel(x, y, getPixel(x, y) );
        }
    }
 
    var b = byteArrayOutputStream();
    gif.write(b);
 
    var base64 = base64EncodeOutputStream();
    var bytes = b.toByteArray();
    for (var i = 0; i < bytes.length; i += 1) {
        base64.writeByte(bytes[i]);
    }
    base64.flush();
 
    var img = '';
    img += 'data:image/gif;base64,';
    img += base64;
 
    return img;
};
 
//---------------------------------------------------------------------
// returns qrcode function.
 
var createQrCodeImg = function(text, options) {
    options = options || {};
    var typeNumber = options.typeNumber || 4;
    var errorCorrectLevel = options.errorCorrectLevel || 'M';
    var size = options.size || 500;
 
    var qr;
 
    try {
        qr = qrcode(typeNumber, errorCorrectLevel || 'M');
        qr.addData(text);
        qr.make();
    } catch (e) {
        if(typeNumber >= 40) {
            throw new Error('Text too long to encode');
        } else {
            return gen(text, {
                size: size,
                errorCorrectLevel: errorCorrectLevel,
                typeNumber: typeNumber + 1
            });
        }
    }
 
    // calc cellsize and margin
    var cellsize = parseInt(size / qr.getModuleCount());
    var margin = parseInt((size - qr.getModuleCount() * cellsize) / 2);
 
    return qr.createImgTag(cellsize, margin, size);
};
// var module = {}; 需要注释这一行,否则微信小程序无法使用
export default {
    createQrCodeImg
}
tki-qrcode.vue
<template xlang="wxml" minapp="mpvue">
    <view class="_qrCode">
        <canvas class="_qrCodeCanvas" id="_myQrCodeCanvas" canvas-id="_myQrCodeCanvas" :style="{width:cpSize+'px',height:cpSize+'px'}" />
        <image v-show="show" :src="result" :style="{width:cpSize+'px',height:cpSize+'px'}" />
    </view>
</template>

<script>
import QRCode from "./qrcode.js"
let qrcode
export default {
    name: "tki-qrcode",
    props: {
        size: {
            type: Number,
            default: 200
        },
        unit: {
            type: String,
            default: 'upx'
        },
        show: {
            type: Boolean,
            default: true
        },
        val: {
            type: String,
            default: ''
        },
        background: {
            type: String,
            default: '#ffffff'
        },
        foreground: {
            type: String,
            default: '#000000'
        },
        pdground: {
            type: String,
            default: '#000000'
        },
        icon: {
            type: String,
            default: ''
        },
        iconSize: {
            type: Number,
            default: 40
        },
        lv: {
            type: Number,
            default: 3
        },
        onval: {
            type: Boolean,
            default: false
        },
        loadMake: {
            type: Boolean,
            default: false
        },
    },
    data() {
        return {
            result: '',
        }
    },
    methods: {
        _makeCode() {
            let that = this
            if (!this._empty(this.val)) {
                qrcode = new QRCode({
                    context: that,
                    text: that.val, // 生成内容
                    size: that.cpSize, // 二维码大小
                    background: that.background, // 背景色
                    foreground: that.foreground, // 前景色
                    pdground: that.pdground, // 定位角点颜色
                    correctLevel: that.lv, // 容错级别
                    image: that.icon, // 二维码图标
                    imageSize: that.iconSize,// 二维码图标大小
                    cbResult: function (res) { // 生成二维码的回调
                        that._result(res)
                    },
                });
            } else {
                uni.showToast({
                    title: '二维码内容不能为空',
                    icon: 'none',
                    duration: 1000,
                    complete: function () {
                        setTimeout(function() {
                            uni.hideToast();
                        },1000);
                    }
                });
            }
        },
        _clearCode() {
            this._result('')
            qrcode.clear()
        },
        _saveCode() {
            let that = this;
            if (this.result != "") {
                uni.saveImageToPhotosAlbum({
                    filePath: that.result,
                    success: function () {
                        uni.showToast({
                            title: '二维码保存成功',
                            icon: 'success',
                            duration: 1000,
                            complete: function () {
                                setTimeout(function() {
                                    uni.hideToast();
                                },1000);
                            }
                        });
                    }
                });
            }
        },
        _result(res) {
            this.result = res;
            this.$emit('result', res)
        },
        _empty(v) {
            let tp = typeof v,
                rt = false;
            if (tp == "number" && String(v) == "") {
                rt = true
            } else if (tp == "undefined") {
                rt = true
            } else if (tp == "object") {
                if (JSON.stringify(v) == "{}" || JSON.stringify(v) == "[]" || v == null) rt = true
            } else if (tp == "string") {
                if (v == "" || v == "undefined" || v == "null" || v == "{}" || v == "[]") rt = true
            } else if (tp == "function") {
                rt = false
            }
            return rt
        }
    },
    watch: {
        size: function (n, o) {
            if (n != o && !this._empty(n)) {
                this.cSize = n
                if (!this._empty(this.val)) {
                    setTimeout(() => {
                        this._makeCode()
                    }, 100);
                }
            }
        },
        val: function (n, o) {
            if (this.onval) {
                if (n != o && !this._empty(n)) {
                    setTimeout(() => {
                        this._makeCode()
                    }, 0);
                }
            }
        }
    },
    computed: {
        cpSize() {
            if(this.unit == "upx"){
                return uni.upx2px(this.size)
            }else{
                return this.size
            }
        }
    },
    mounted: function () {
        if (this.loadMake) {
            if (!this._empty(this.val)) {
                setTimeout(() => {
                    this._makeCode()
                }, 0);
            }
        }
    },
}
</script>
<style>
._qrCode {
  position: relative;
}
._qrCodeCanvas {
  position: fixed;
  top: -99999upx;
  left: -99999upx;
  z-index: -99999;
}
</style>

u-charts

component.vue
<template>
    <canvas v-if="canvasId" :id="canvasId" :canvasId="canvasId" :style="{'width':cWidth*pixelRatio+'px','height':cHeight*pixelRatio+'px', 'transform': 'scale('+(1/pixelRatio)+')','margin-left':-cWidth*(pixelRatio-1)/2+'px','margin-top':-cHeight*(pixelRatio-1)/2+'px'}"
     @touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd" @error="error">
    </canvas>
</template>

<script>
    import uCharts from './u-charts.js';
    var canvases = {};
    
    export default {
        props: {
            chartType: {
                required: true,
                type: String,
                default: 'column'
            },
            opts: {
                required: true,
                type: Object,
                default () {
                    return null;
                },
            },
            canvasId: {
                type: String,
                default: 'u-canvas',
            },
            cWidth: {
                default: 375,
            },
            cHeight: {
                default: 250,
            },
            pixelRatio: {
                type: Number,
                default: 1,
            },
        },
        mounted() {
            this.init();
        },
        methods: {
            init() {
                switch (this.chartType) {
                    case 'column':
                        this.initColumnChart();
                        break;
                    case 'line':
                        this.initLineChart();
                        break;
                    default:
                        break;
                }
            },
            initColumnChart() {
                canvases[this.canvasId] = new uCharts({
                    $this: this,
                    canvasId: this.canvasId,
                    type: 'column',
                    legend: true,
                    fontSize: 11,
                    background: '#FFFFFF',
                    pixelRatio: this.pixelRatio,
                    animation: true,
                    categories: this.opts.categories,
                    series: this.opts.series,
                    enableScroll: true,
                    xAxis: {
                        disableGrid: true,
                        itemCount: 4,
                        scrollShow: true
                    },
                    yAxis: {
                        //disabled:true
                    },
                    dataLabel: true,
                    width: this.cWidth * this.pixelRatio,
                    height: this.cHeight * this.pixelRatio,
                    extra: {
                        column: {
                            type: 'group',
                        }
                    }
                });
            },
            initLineChart() {
                canvases[this.canvasId] = new uCharts({
                    $this: this,
                    canvasId: this.canvasId,
                    type: 'line',
                    fontSize: 11,
                    legend: true,
                    dataLabel: false,
                    dataPointShape: true,
                    background: '#FFFFFF',
                    pixelRatio: this.pixelRatio,
                    categories: this.opts.categories,
                    series: this.opts.series,
                    animation: true,
                    enableScroll: true,
                    xAxis: {
                        type: 'grid',
                        gridColor: '#CCCCCC',
                        gridType: 'dash',
                        dashLength: 8,
                        itemCount: 4,
                        scrollShow: true
                    },
                    yAxis: {
                        gridType: 'dash',
                        gridColor: '#CCCCCC',
                        dashLength: 8,
                        splitNumber: 5,
                        min: 10,
                        max: 180,
                        format: (val) => {
                            return val.toFixed(0) + '元'
                        }
                    },
                    width: this.cWidth * this.pixelRatio,
                    height: this.cHeight * this.pixelRatio,
                    extra: {
                        line: {
                            type: 'straight'
                        }
                    }
                });
            },
            // 这里仅作为示例传入两个参数,cid为canvas-id,newdata为更新的数据,需要更多参数请自行修改
            changeData(cid,newdata) {
                canvases[cid].updateData({
                    series: newdata.series,
                    categories: newdata.categories
                });
            },
            touchStart(e) {
                canvases[this.canvasId].showToolTip(e, {
                    format: function(item, category) {
                        return category + ' ' + item.name + ':' + item.data
                    }
                });
                canvases[this.canvasId].scrollStart(e);
            },
            touchMove(e) {
                canvases[this.canvasId].scroll(e);
            },
            touchEnd(e) {
                canvases[this.canvasId].scrollEnd(e);
            },
            error(e) {
                // console.log(e)
            }
        },
    };
</script>

<style scoped>
    .charts {
        width: 100%;
        height: 100%;
        flex: 1;
        background-color: #FFFFFF;
    }
</style>
u-charts.js
/*
 * uCharts v1.7.0.20190713
 * uni-app平台高性能跨全端图表,支持H5、APP、小程序(微信/支付宝/百度/头条)
 * Copyright (c) 2019 QIUN秋云 https://www.ucharts.cn All rights reserved.
 * Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
 * 
 * uCharts官方网站
 * https://www.uCharts.cn
 * 
 * 开源地址:
 * https://gitee.com/uCharts/uCharts
 * 
 * uni-app插件市场地址:
 * http://ext.dcloud.net.cn/plugin?id=271
 * 
 * 
 */

'use strict';

var config = {
    yAxisWidth: 15,
    yAxisSplit: 5,
    xAxisHeight: 15,
    xAxisLineHeight: 15,
    legendHeight: 15,
    yAxisTitleWidth: 15,
    padding: 12,
    pixelRatio: 1, //适配H5高分屏
    rotate: false, //横屏模式
    columePadding: 3,
    fontSize: 13,
    //dataPointShape: ['diamond', 'circle', 'triangle', 'rect'],
    dataPointShape: ['circle', 'circle', 'circle', 'circle'], //仿F2图例样式改为圆点
    colors: ['#1890ff', '#2fc25b', '#facc14', '#f04864', '#8543e0', '#90ed7d'],
    pieChartLinePadding: 15,
    pieChartTextPadding: 5,
    xAxisTextPadding: 3,
    titleColor: '#333333',
    titleFontSize: 20,
    subtitleColor: '#999999',
    subtitleFontSize: 15,
    toolTipPadding: 3,
    toolTipBackground: '#000000',
    toolTipOpacity: 0.7,
    toolTipLineHeight: 20,
    radarGridCount: 3,
    radarLabelTextMargin: 15,
    gaugeLabelTextMargin: 15
};

// Object.assign polyfill
// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
function assign(target, varArgs) {
    if (target == null) {
        // TypeError if undefined or null
        throw new TypeError('Cannot convert undefined or null to object');
    }

    var to = Object(target);

    for (var index = 1; index < arguments.length; index++) {
        var nextSource = arguments[index];

        if (nextSource != null) {
            // Skip over if undefined or null
            for (var nextKey in nextSource) {
                // Avoid bugs when hasOwnProperty is shadowed
                if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
                    to[nextKey] = nextSource[nextKey];
                }
            }
        }
    }
    return to;
}

var util = {
    toFixed: function toFixed(num, limit) {
        limit = limit || 2;
        if (this.isFloat(num)) {
            num = num.toFixed(limit);
        }
        return num;
    },
    isFloat: function isFloat(num) {
        return num % 1 !== 0;
    },
    approximatelyEqual: function approximatelyEqual(num1, num2) {
        return Math.abs(num1 - num2) < 1e-10;
    },
    isSameSign: function isSameSign(num1, num2) {
        return Math.abs(num1) === num1 && Math.abs(num2) === num2 || Math.abs(num1) !== num1 && Math.abs(num2) !== num2;
    },
    isSameXCoordinateArea: function isSameXCoordinateArea(p1, p2) {
        return this.isSameSign(p1.x, p2.x);
    },
    isCollision: function isCollision(obj1, obj2) {
        obj1.end = {};
        obj1.end.x = obj1.start.x + obj1.width;
        obj1.end.y = obj1.start.y - obj1.height;
        obj2.end = {};
        obj2.end.x = obj2.start.x + obj2.width;
        obj2.end.y = obj2.start.y - obj2.height;
        var flag = obj2.start.x > obj1.end.x || obj2.end.x < obj1.start.x || obj2.end.y > obj1.start.y || obj2.start.y <
            obj1.end.y;

        return !flag;
    }
};

//兼容H5点击事件
function getH5Offset(e) {
    e.mp={changedTouches:[]};
    e.mp.changedTouches.push({x:e.offsetX,y:e.offsetY});
    return e;
}

// hex 转 rgba
function hexToRgb(hexValue, opc) {
    var rgx = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
    var hex = hexValue.replace(rgx, function(m, r, g, b) {
        return r + r + g + g + b + b;
    });
    var rgb = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
    var r = parseInt(rgb[1], 16);
    var g = parseInt(rgb[2], 16);
    var b = parseInt(rgb[3], 16);
    return 'rgba(' + r + ',' + g + ',' + b + ',' + opc + ')';
}

function findRange(num, type, limit) {
    if (isNaN(num)) {
        throw new Error('[wxCharts] unvalid series data!');
    }
    limit = limit || 10;
    type = type ? type : 'upper';
    var multiple = 1;
    while (limit < 1) {
        limit *= 10;
        multiple *= 10;
    }
    if (type === 'upper') {
        num = Math.ceil(num * multiple);
    } else {
        num = Math.floor(num * multiple);
    }
    while (num % limit !== 0) {
        if (type === 'upper') {
            num++;
        } else {
            num--;
        }
    }

    return num / multiple;
}

function calCandleMA(dayArr, nameArr, colorArr, kdata) {
    let seriesTemp = [];
    for (let k = 0; k < dayArr.length; k++) {
        let seriesItem = {
            data: [],
            name: nameArr[k],
            color: colorArr[k]
        };
        for (let i = 0, len = kdata.length; i < len; i++) {
            if (i < dayArr[k]) {
                seriesItem.data.push(null);
                continue;
            }
            let sum = 0;
            for (let j = 0; j < dayArr[k]; j++) {
                sum += kdata[i - j][1];
            }
            seriesItem.data.push(+(sum / dayArr[k]).toFixed(3));
        }
        seriesTemp.push(seriesItem);
    }
    return seriesTemp;
}

function calValidDistance(distance, chartData, config, opts) {

    var dataChartAreaWidth = opts.width - config.padding - chartData.xAxisPoints[0];
    var dataChartWidth = chartData.eachSpacing * opts.categories.length;
    var validDistance = distance;
    if (distance >= 0) {
        validDistance = 0;
    } else if (Math.abs(distance) >= dataChartWidth - dataChartAreaWidth) {
        validDistance = dataChartAreaWidth - dataChartWidth;
    }
    return validDistance;
}

function isInAngleRange(angle, startAngle, endAngle) {
    function adjust(angle) {
        while (angle < 0) {
            angle += 2 * Math.PI;
        }
        while (angle > 2 * Math.PI) {
            angle -= 2 * Math.PI;
        }

        return angle;
    }

    angle = adjust(angle);
    startAngle = adjust(startAngle);
    endAngle = adjust(endAngle);
    if (startAngle > endAngle) {
        endAngle += 2 * Math.PI;
        if (angle < startAngle) {
            angle += 2 * Math.PI;
        }
    }

    return angle >= startAngle && angle <= endAngle;
}

function calRotateTranslate(x, y, h) {
    var xv = x;
    var yv = h - y;

    var transX = xv + (h - yv - xv) / Math.sqrt(2);
    transX *= -1;

    var transY = (h - yv) * (Math.sqrt(2) - 1) - (h - yv - xv) / Math.sqrt(2);

    return {
        transX: transX,
        transY: transY
    };
}

function createCurveControlPoints(points, i) {

    function isNotMiddlePoint(points, i) {
        if (points[i - 1] && points[i + 1]) {
            return points[i].y >= Math.max(points[i - 1].y, points[i + 1].y) || points[i].y <= Math.min(points[i - 1].y, points[
                i + 1].y);
        } else {
            return false;
        }
    }

    var a = 0.2;
    var b = 0.2;
    var pAx = null;
    var pAy = null;
    var pBx = null;
    var pBy = null;
    if (i < 1) {
        pAx = points[0].x + (points[1].x - points[0].x) * a;
        pAy = points[0].y + (points[1].y - points[0].y) * a;
    } else {
        pAx = points[i].x + (points[i + 1].x - points[i - 1].x) * a;
        pAy = points[i].y + (points[i + 1].y - points[i - 1].y) * a;
    }

    if (i > points.length - 3) {
        var last = points.length - 1;
        pBx = points[last].x - (points[last].x - points[last - 1].x) * b;
        pBy = points[last].y - (points[last].y - points[last - 1].y) * b;
    } else {
        pBx = points[i + 1].x - (points[i + 2].x - points[i].x) * b;
        pBy = points[i + 1].y - (points[i + 2].y - points[i].y) * b;
    }

    // fix issue https://github.com/xiaolin3303/wx-charts/issues/79
    if (isNotMiddlePoint(points, i + 1)) {
        pBy = points[i + 1].y;
    }
    if (isNotMiddlePoint(points, i)) {
        pAy = points[i].y;
    }

    return {
        ctrA: {
            x: pAx,
            y: pAy
        },
        ctrB: {
            x: pBx,
            y: pBy
        }
    };
}

function convertCoordinateOrigin(x, y, center) {
    return {
        x: center.x + x,
        y: center.y - y
    };
}

function avoidCollision(obj, target) {
    if (target) {
        // is collision test
        while (util.isCollision(obj, target)) {
            if (obj.start.x > 0) {
                obj.start.y--;
            } else if (obj.start.x < 0) {
                obj.start.y++;
            } else {
                if (obj.start.y > 0) {
                    obj.start.y++;
                } else {
                    obj.start.y--;
                }
            }
        }
    }
    return obj;
}

function fillSeriesColor(series, config) {
    var index = 0;
    return series.map(function(item) {
        if (!item.color) {
            item.color = config.colors[index];
            index = (index + 1) % config.colors.length;
        }
        return item;
    });
}

function fillSeriesType(series, opts) {
    return series.map(function(item) {
        if (!item.type) {
            item.type = opts.type;
        }
        return item;
    });
}

function getDataRange(minData, maxData) {
    var limit = 0;
    var range = maxData - minData;
    if (range >= 10000) {
        limit = 1000;
    } else if (range >= 1000) {
        limit = 100;
    } else if (range >= 100) {
        limit = 10;
    } else if (range >= 10) {
        limit = 5;
    } else if (range >= 1) {
        limit = 1;
    } else if (range >= 0.1) {
        limit = 0.1;
    } else {
        limit = 0.01;
    }
    return {
        minRange: findRange(minData, 'lower', limit),
        maxRange: findRange(maxData, 'upper', limit)
    };
}

function measureText(text) {
    var fontSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : config.fontSize;

    // wx canvas 未实现measureText方法, 此处自行实现
    // 适配修改初始字体10px为其他大小的方法
    text = String(text);
    var text = text.split('');
    var width = 0;
    for (let i = 0; i < text.length; i++) {
        let item = text[i];
        if (/[a-zA-Z]/.test(item)) {
            width += 7;
        } else if (/[0-9]/.test(item)) {
            width += 5.5;
        } else if (/\./.test(item)) {
            width += 2.7;
        } else if (/-/.test(item)) {
            width += 3.25;
        } else if (/[\u4e00-\u9fa5]/.test(item)) {
            width += 10;
        } else if (/\(|\)/.test(item)) {
            width += 3.73;
        } else if (/\s/.test(item)) {
            width += 2.5;
        } else if (/%/.test(item)) {
            width += 8;
        } else {
            width += 10;
        }
    }
    return width * fontSize / 10;
}

function dataCombine(series) {
    return series.reduce(function(a, b) {
        return (a.data ? a.data : a).concat(b.data);
    }, []);
}

function dataCombineStack(series) {
    var sum = new Array(series[0].data.length);
    for (var j = 0; j < sum.length; j++) {
        sum[j] = 0;
    }
    for (var i = 0; i < series.length; i++) {
        for (var j = 0; j < sum.length; j++) {
            sum[j] += series[i].data[j];
        }
    }
    return series.reduce(function(a, b) {
        return (a.data ? a.data : a).concat(b.data).concat(sum);
    }, []);
}

function getTouches(touches, opts, e) {
    let x, y;
    if (touches.clientX) {
        if (opts.rotate) { //适配横屏
            y = opts.height - touches.clientX * opts.pixelRatio;
            x = (touches.pageY - e.currentTarget.offsetTop - (opts.height / opts.pixelRatio / 2) * (opts.pixelRatio - 1)) *
                opts.pixelRatio;
        } else {
            x = touches.clientX * opts.pixelRatio;
            y = (touches.pageY - e.currentTarget.offsetTop - (opts.height / opts.pixelRatio / 2) * (opts.pixelRatio - 1)) *
                opts.pixelRatio;
        }
    } else {
        if (opts.rotate) { //适配横屏
            y = opts.height - touches.x * opts.pixelRatio;
            x = touches.y * opts.pixelRatio;
        } else {
            x = touches.x * opts.pixelRatio;
            y = touches.y * opts.pixelRatio;
        }
    }
    return {
        x: x,
        y: y
    }
}

function getSeriesDataItem(series, index) {
    var data = [];
    for (let i = 0; i < series.length; i++) {
        let item = series[i];
        if (item.data[index] !== null && typeof item.data[index] !== 'undefined') {
            let seriesItem = {};
            seriesItem.color = item.color;
            seriesItem.type = item.type;
            seriesItem.style = item.style;
            seriesItem.shape = item.shape;
            seriesItem.disableLegend = item.disableLegend;
            seriesItem.name = item.name;
            seriesItem.data = item.format ? item.format(item.data[index]) : item.data[index];
            data.push(seriesItem);
        }
    }
    return data;
}

function getMaxTextListLength(list) {
    var lengthList = list.map(function(item) {
        return measureText(item);
    });
    return Math.max.apply(null, lengthList);
}

function getRadarCoordinateSeries(length) {
    var eachAngle = 2 * Math.PI / length;
    var CoordinateSeries = [];
    for (var i = 0; i < length; i++) {
        CoordinateSeries.push(eachAngle * i);
    }

    return CoordinateSeries.map(function(item) {
        return -1 * item + Math.PI / 2;
    });
}

function getToolTipData(seriesData, calPoints, index, categories) {
    var option = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};

    var textList = seriesData.map(function(item) {
        return {
            text: option.format ? option.format(item, categories[index]) : item.name + ': ' + item.data,
            color: item.color
        };
    });
    var validCalPoints = [];
    var offset = {
        x: 0,
        y: 0
    };
    for (let i = 0; i < calPoints.length; i++) {
        let points = calPoints[i];
        if (typeof points[index] !== 'undefined' && points[index] !== null) {
            validCalPoints.push(points[index]);
        }
    }
    for (let i = 0; i < validCalPoints.length; i++) {
        let item = validCalPoints[i];
        offset.x = Math.round(item.x);
        offset.y += item.y;
    }
    offset.y /= validCalPoints.length;
    return {
        textList: textList,
        offset: offset
    };
}

function getMixToolTipData(seriesData, calPoints, index, categories) {
    var option = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
    var textList = seriesData.map(function(item) {
        return {
            text: option.format ? option.format(item, categories[index]) : item.name + ': ' + item.data,
            color: item.color,
            disableLegend: item.disableLegend ? true : false
        };
    });
    textList = textList.filter(function(item) {
        if (item.disableLegend !== true) {
            return item;
        }
    });
    var validCalPoints = [];
    var offset = {
        x: 0,
        y: 0
    };
    for (let i = 0; i < calPoints.length; i++) {
        let points = calPoints[i];
        if (typeof points[index] !== 'undefined' && points[index] !== null) {
            validCalPoints.push(points[index]);
        }
    }
    for (let i = 0; i < validCalPoints.length; i++) {
        let item = validCalPoints[i];
        offset.x = Math.round(item.x);
        offset.y += item.y;
    }
    offset.y /= validCalPoints.length;
    return {
        textList: textList,
        offset: offset
    };
}

function getCandleToolTipData(series, seriesData, calPoints, index, categories, extra) {
    var option = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : {};
    let upColor = extra.color.upFill;
    let downColor = extra.color.downFill;
    //颜色顺序为开盘,收盘,最低,最高
    let color = [upColor, upColor, downColor, upColor];
    var textList = [];
    let text0 = {
        text: categories[index],
        color: null
    };
    textList.push(text0);
    seriesData.map(function(item) {
        //console.log(color)
        if (index == 0 && item.data[1] - item.data[0] < 0) {
            color[1] = downColor;
        } else {
            if (item.data[0] < series[index - 1][1]) {
                color[0] = downColor;
            }
            if (item.data[1] < item.data[0]) {
                color[1] = downColor;
            }
            if (item.data[2] > series[index - 1][1]) {
                color[2] = upColor;
            }
            if (item.data[3] < series[index - 1][1]) {
                color[3] = downColor;
            }
        }

        let text1 = {
            text: '开盘:' + item.data[0],
            color: color[0]
        };
        let text2 = {
            text: '收盘:' + item.data[1],
            color: color[1]
        };
        let text3 = {
            text: '最低:' + item.data[2],
            color: color[2]
        };
        let text4 = {
            text: '最高:' + item.data[3],
            color: color[3]
        };
        textList.push(text1, text2, text3, text4);
    });
    var validCalPoints = [];
    var offset = {
        x: 0,
        y: 0
    };
    for (let i = 0; i < calPoints.length; i++) {
        let points = calPoints[i];
        if (typeof points[index] !== 'undefined' && points[index] !== null) {
            validCalPoints.push(points[index]);
        }
    }
    offset.x = Math.round(validCalPoints[0][0].x);
    return {
        textList: textList,
        offset: offset
    };
}

function findCurrentIndex(currentPoints, xAxisPoints, opts, config) {
    var offset = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;
    var currentIndex = -1;
    if (isInExactChartArea(currentPoints, opts, config)) {
        xAxisPoints.forEach(function(item, index) {
            if (currentPoints.x + offset > item) {
                currentIndex = index;
            }
        });
    }

    return currentIndex;
}

function isInExactChartArea(currentPoints, opts, config) {
    return currentPoints.x < opts.width - config.padding && currentPoints.x > config.padding + config.yAxisWidth + config.yAxisTitleWidth &&
        currentPoints.y > config.padding && currentPoints.y < opts.height - config.legendHeight - config.xAxisHeight - config
        .padding;
}

function findRadarChartCurrentIndex(currentPoints, radarData, count) {
    var eachAngleArea = 2 * Math.PI / count;
    var currentIndex = -1;
    if (isInExactPieChartArea(currentPoints, radarData.center, radarData.radius)) {
        var fixAngle = function fixAngle(angle) {
            if (angle < 0) {
                angle += 2 * Math.PI;
            }
            if (angle > 2 * Math.PI) {
                angle -= 2 * Math.PI;
            }
            return angle;
        };

        var angle = Math.atan2(radarData.center.y - currentPoints.y, currentPoints.x - radarData.center.x);
        angle = -1 * angle;
        if (angle < 0) {
            angle += 2 * Math.PI;
        }

        var angleList = radarData.angleList.map(function(item) {
            item = fixAngle(-1 * item);

            return item;
        });

        angleList.forEach(function(item, index) {
            var rangeStart = fixAngle(item - eachAngleArea / 2);
            var rangeEnd = fixAngle(item + eachAngleArea / 2);
            if (rangeEnd < rangeStart) {
                rangeEnd += 2 * Math.PI;
            }
            if (angle >= rangeStart && angle <= rangeEnd || angle + 2 * Math.PI >= rangeStart && angle + 2 * Math.PI <=
                rangeEnd) {
                currentIndex = index;
            }
        });
    }

    return currentIndex;
}

function findPieChartCurrentIndex(currentPoints, pieData) {
    var currentIndex = -1;
    if (isInExactPieChartArea(currentPoints, pieData.center, pieData.radius)) {
        var angle = Math.atan2(pieData.center.y - currentPoints.y, currentPoints.x - pieData.center.x);
        angle = -angle;
        for (var i = 0, len = pieData.series.length; i < len; i++) {
            var item = pieData.series[i];
            if (isInAngleRange(angle, item._start_, item._start_ + item._proportion_ * 2 * Math.PI)) {
                currentIndex = i;
                break;
            }
        }
    }

    return currentIndex;
}

function isInExactPieChartArea(currentPoints, center, radius) {
    return Math.pow(currentPoints.x - center.x, 2) + Math.pow(currentPoints.y - center.y, 2) <= Math.pow(radius, 2);
}

function splitPoints(points) {
    var newPoints = [];
    var items = [];
    points.forEach(function(item, index) {
        if (item !== null) {
            items.push(item);
        } else {
            if (items.length) {
                newPoints.push(items);
            }
            items = [];
        }
    });
    if (items.length) {
        newPoints.push(items);
    }

    return newPoints;
}

function calLegendData(series, opts, config) {
    if (opts.legend === false) {
        return {
            legendList: [],
            legendHeight: 0
        };
    }
    //适配H5高分屏
    var padding = 5 * opts.pixelRatio;
    var marginTop = 8 * opts.pixelRatio;
    var shapeWidth = 15 * opts.pixelRatio;
    var legendList = [];
    var widthCount = 0;
    var currentRow = [];
    for (let i = 0; i < series.length; i++) {
        let item = series[i];
        let itemWidth = 3 * padding + shapeWidth + measureText(item.name || 'undefined');
        if (widthCount + itemWidth > opts.width) {
            legendList.push(currentRow);
            widthCount = itemWidth;
            currentRow = [item];
        } else {
            widthCount += itemWidth;
            currentRow.push(item);
        }
    }
    if (currentRow.length) {
        legendList.push(currentRow);
    }

    return {
        legendList: legendList,
        legendHeight: legendList.length * (config.fontSize + marginTop) + padding
    };
}

function calCategoriesData(categories, opts, config) {
    var result = {
        angle: 0,
        xAxisHeight: config.xAxisHeight
    };

    var _getXAxisPoints = getXAxisPoints(categories, opts, config),
        eachSpacing = _getXAxisPoints.eachSpacing;

    // get max length of categories text


    var categoriesTextLenth = categories.map(function(item) {
        return measureText(item);
    });

    var maxTextLength = Math.max.apply(this, categoriesTextLenth);

    if (opts.xAxis.rotateLabel == true && maxTextLength + 2 * config.xAxisTextPadding > eachSpacing) {
        result.angle = 45 * Math.PI / 180;
        result.xAxisHeight = 2 * config.xAxisTextPadding + maxTextLength * Math.sin(result.angle);
    }

    return result;
}

function getRadarDataPoints(angleList, center, radius, series, opts) {
    var process = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 1;

    var radarOption = opts.extra.radar || {};
    radarOption.max = radarOption.max || 0;
    var maxData = Math.max(radarOption.max, Math.max.apply(null, dataCombine(series)));

    var data = [];
    for (let i = 0; i < series.length; i++) {
        let each = series[i];
        let listItem = {};
        listItem.color = each.color;
        listItem.data = [];
        each.data.forEach(function(item, index) {
            let tmp = {};
            tmp.angle = angleList[index];

            tmp.proportion = item / maxData;
            tmp.position = convertCoordinateOrigin(radius * tmp.proportion * process * Math.cos(tmp.angle), radius * tmp.proportion *
                process * Math.sin(tmp.angle), center);
            listItem.data.push(tmp);
        });

        data.push(listItem);
    }

    return data;
}

function getPieDataPoints(series, radius) {
    var process = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;

    var count = 0;
    var _start_ = 0;
    for (let i = 0; i < series.length; i++) {
        let item = series[i];
        item.data = item.data === null ? 0 : item.data;
        count += item.data;
    }
    for (let i = 0; i < series.length; i++) {
        let item = series[i];
        item.data = item.data === null ? 0 : item.data;
        if (count === 0) {
            item._proportion_ = 1 / series.length * process;
        } else {
            item._proportion_ = item.data / count * process;
        }
        item._radius_=radius;
    }
    for (let i = 0; i < series.length; i++) {
        let item = series[i];
        item._start_ = _start_;
        _start_ += 2 * item._proportion_ * Math.PI;
    }

    return series;
}

function getRoseDataPoints(series, type, minRadius, radius) {
    var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
    var count = 0;
    var _start_ = 0;
    
    var dataArr=[];
    for (let i = 0; i < series.length; i++) {
        let item = series[i];
        item.data = item.data === null ? 0 : item.data;
        count += item.data;
        dataArr.push(item.data);
    }
    var minData = dataArr.pop();
    var maxData = dataArr.shift();
    var radiusLength = radius - minRadius;
    
    for (let i = 0; i < series.length; i++) {
        let item = series[i];
        item.data = item.data === null ? 0 : item.data;
        if (count === 0 || type == 'area') {
            item._proportion_ = 1 / series.length * process;
        } else {
            item._proportion_ = item.data / count * process;
        }
        item._radius_ = minRadius + radiusLength * ( (item.data - minData)/(maxData-minData) );
    }
    for (let i = 0; i < series.length; i++) {
        let item = series[i];
        item._start_ = _start_;
        _start_ += 2 * item._proportion_ * Math.PI;
    }

    return series;
}

function getArcbarDataPoints(series, arcbarOption) {
    var process = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
    if (process == 1) {
        process = 0.999999;
    }
    for (let i = 0; i < series.length; i++) {
        let item = series[i];
        item.data = item.data === null ? 0 : item.data;
        let totalAngle;
        if (arcbarOption.type == 'default') {
            totalAngle = arcbarOption.startAngle - arcbarOption.endAngle + 1;
        } else {
            totalAngle = 2;
        }
        item._proportion_ = totalAngle * item.data * process + arcbarOption.startAngle;
        if (item._proportion_ >= 2) {
            item._proportion_ = item._proportion_ % 2;
        }
    }
    return series;
}

function getGaugeAxisPoints(categories, startAngle, endAngle) {
    let totalAngle = startAngle - endAngle + 1;
    let tempStartAngle = startAngle;
    for (let i = 0; i < categories.length; i++) {
        categories[i].value = categories[i].value === null ? 0 : categories[i].value;
        categories[i]._startAngle_ = tempStartAngle;
        categories[i]._endAngle_ = totalAngle * categories[i].value + startAngle;
        if (categories[i]._endAngle_ >= 2) {
            categories[i]._endAngle_ = categories[i]._endAngle_ % 2;
        }
        tempStartAngle = categories[i]._endAngle_;
    }
    return categories;
}

function getGaugeDataPoints(series, categories, gaugeOption) {
    let process = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1;
    for (let i = 0; i < series.length; i++) {
        let item = series[i];
        item.data = item.data === null ? 0 : item.data;
        if (gaugeOption.pointer.color == 'auto') {
            for (let i = 0; i < categories.length; i++) {
                if (item.data <= categories[i].value) {
                    item.color = categories[i].color;
                    break;
                }
            }
        } else {
            item.color = gaugeOption.pointer.color;
        }
        let totalAngle = gaugeOption.startAngle - gaugeOption.endAngle + 1;
        item._endAngle_ = totalAngle * item.data + gaugeOption.startAngle;
        item._oldAngle_ = gaugeOption.oldAngle;
        if (gaugeOption.oldAngle < gaugeOption.endAngle) {
            item._oldAngle_ += 2;
        }
        if (item.data >= gaugeOption.oldData) {
            item._proportion_ = (item._endAngle_ - item._oldAngle_) * process + gaugeOption.oldAngle;
        } else {
            item._proportion_ = item._oldAngle_ - (item._oldAngle_ - item._endAngle_) * process;
        }
        if (item._proportion_ >= 2) {
            item._proportion_ = item._proportion_ % 2;
        }
    }
    return series;
}


function getPieTextMaxLength(series) {
    series = getPieDataPoints(series);
    let maxLength = 0;
    for (let i = 0; i < series.length; i++) {
        let item = series[i];
        let text = item.format ? item.format(+item._proportion_.toFixed(2)) : util.toFixed(item._proportion_ * 100) + '%';
        maxLength = Math.max(maxLength, measureText(text));
    }

    return maxLength;
}

function fixColumeData(points, eachSpacing, columnLen, index, config, opts) {
    return points.map(function(item) {
        if (item === null) {
            return null;
        }
        item.width = Math.ceil((eachSpacing - 2 * config.columePadding) / columnLen);

        if (opts.extra.column && opts.extra.column.width && +opts.extra.column.width > 0) {
            item.width = Math.min(item.width, +opts.extra.column.width);
        } 
        item.x += (index + 0.5 - columnLen / 2) * item.width;
        return item;
    });
}

function fixColumeMeterData(points, eachSpacing, columnLen, index, config, opts, border) {
    return points.map(function(item) {
        if (item === null) {
            return null;
        }
        item.width = eachSpacing - 2 * config.columePadding;

        if (opts.extra.column && opts.extra.column.width && +opts.extra.column.width > 0) {
            item.width = Math.min(item.width, +opts.extra.column.width);
        } else {
            item.width = Math.min(item.width, 25);
        }
        if (index > 0) {
            item.width -= 2 * border;
        }
        return item;
    });
}

function fixColumeStackData(points, eachSpacing, columnLen, index, config, opts, series) {

    return points.map(function(item, indexn) {

        if (item === null) {
            return null;
        }
        item.width = eachSpacing - 2 * config.columePadding;

        if (opts.extra.column && opts.extra.column.width && +opts.extra.column.width > 0) {
            item.width = Math.min(item.width, +opts.extra.column.width);
        } else {
            item.width = Math.min(item.width, 25);
        }
        return item;
    });
}

function getXAxisPoints(categories, opts, config) {
    var yAxisTotalWidth = config.yAxisWidth + config.yAxisTitleWidth;
    var spacingValid = opts.width - 2 * config.padding - yAxisTotalWidth;
    var dataCount = opts.enableScroll ? Math.min(opts.xAxis.itemCount, categories.length) : categories.length;
    var eachSpacing = spacingValid / dataCount;

    var xAxisPoints = [];
    var startX = config.padding + yAxisTotalWidth;
    var endX = opts.width - config.padding;
    categories.forEach(function(item, index) {
        xAxisPoints.push(startX + index * eachSpacing);
    });
    if (opts.enableScroll === true) {
        xAxisPoints.push(startX + categories.length * eachSpacing);
    } else {
        xAxisPoints.push(endX);
    }

    return {
        xAxisPoints: xAxisPoints,
        startX: startX,
        endX: endX,
        eachSpacing: eachSpacing
    };
}

function getCandleDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config) {
    var process = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : 1;

    var points = [];
    var validHeight = opts.height - 2 * config.padding - config.xAxisHeight - config.legendHeight;
    data.forEach(function(item, index) {
        if (item === null) {
            points.push(null);
        } else {
            var cPoints = [];
            item.forEach(function(items, indexs) {
                var point = {};
                point.x = xAxisPoints[index] + Math.round(eachSpacing / 2);
                var value = items.value || items;
                var height = validHeight * (value - minRange) / (maxRange - minRange);
                height *= process;
                point.y = opts.height - config.xAxisHeight - config.legendHeight - Math.round(height) - config.padding;
                cPoints.push(point);
            });
            points.push(cPoints);
        }
    });

    return points;
}

function getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config) {
    var process = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : 1;

    var points = [];
    var validHeight = opts.height - 2 * config.padding - config.xAxisHeight - config.legendHeight;
    data.forEach(function(item, index) {
        if (item === null) {
            points.push(null);
        } else {
            var point = {};
            point.color = item.color;
            point.x = xAxisPoints[index] + Math.round(eachSpacing / 2);
            var value = item;
            if (typeof item === 'object' && item !== null) {
                value = item.value
            }
            var height = validHeight * (value - minRange) / (maxRange - minRange);
            height *= process;
            point.y = opts.height - config.xAxisHeight - config.legendHeight - Math.round(height) - config.padding;
            points.push(point);
        }
    });

    return points;
}

function getStackDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, seriesIndex, stackSeries) {
    var process = arguments.length > 9 && arguments[9] !== undefined ? arguments[9] : 1;
    var points = [];
    var validHeight = opts.height - 2 * config.padding - config.xAxisHeight - config.legendHeight;

    data.forEach(function(item, index) {
        if (item === null) {
            points.push(null);
        } else {
            var point = {};
            point.color = item.color;
            point.x = xAxisPoints[index] + Math.round(eachSpacing / 2);

            if (seriesIndex > 0) {
                var value = 0;
                for (let i = 0; i <= seriesIndex; i++) {
                    value += stackSeries[i].data[index];
                }
                var value0 = value - item;
                var height = validHeight * (value - minRange) / (maxRange - minRange);
                var height0 = validHeight * (value0 - minRange) / (maxRange - minRange);
            } else {
                var value = item;
                var height = validHeight * (value - minRange) / (maxRange - minRange);
                var height0 = 0;
            }
            var heightc = height0;
            height *= process;
            heightc *= process;
            point.y = opts.height - config.xAxisHeight - config.legendHeight - Math.round(height) - config.padding;
            point.y0 = opts.height - config.xAxisHeight - config.legendHeight - Math.round(heightc) - config.padding;
            points.push(point);
        }
    });

    return points;
}

function getYAxisTextList(series, opts, config, stack) {
    var data;
    if (stack == 'stack') {
        //data = dataCombine(series);
        data = dataCombineStack(series);
    } else {
        data = dataCombine(series);
    }

    var sorted = [];
    // remove null from data
    data = data.filter(function(item) {
        //return item !== null;
        if (typeof item === 'object' && item !== null) {
            //判断是否为数组
            if (item.constructor == Array) {
                return item !== null;
            } else {
                return item.value !== null;
            }
        } else {
            return item !== null;
        }
    });
    //var minData = Math.min.apply(this, data);
    //var maxData = Math.max.apply(this, data);
    data.map(function(item) {
        if (typeof item === 'object') {
            if (item.constructor == Array) {
                item.map(function(subitem) {
                    sorted.push(subitem);
                })
            } else {
                sorted.push(item.value);
            }
        } else {
            sorted.push(item);
        }
        //typeof item === 'object' ? sorted.push(item.value) : sorted.push(item)
    })
    var minData = 0;
    var maxData = 0;
    if (sorted.length > 0) {
        minData = Math.min.apply(this, sorted);
        maxData = Math.max.apply(this, sorted);
    }
    if (typeof opts.yAxis.min === 'number') {
        minData = Math.min(opts.yAxis.min, minData);
    }
    if (typeof opts.yAxis.max === 'number') {
        maxData = Math.max(opts.yAxis.max, maxData);
    }

    // fix issue https://github.com/xiaolin3303/wx-charts/issues/9
    if (minData === maxData) {
        var rangeSpan = maxData || 10;
        //minData -= rangeSpan;
        maxData += rangeSpan;
    }

    var dataRange = getDataRange(minData, maxData);
    var minRange = dataRange.minRange;
    var maxRange = dataRange.maxRange;

    var range = [];
    var eachRange = (maxRange - minRange) / config.yAxisSplit;

    for (var i = 0; i <= config.yAxisSplit; i++) {
        range.push(minRange + eachRange * i);
    }
    return range.reverse();
}

function calYAxisData(series, opts, config) {
    //堆叠图重算Y轴
    var columnstyle = assign({}, opts.extra.column || {
        "type": ""
    });

    var ranges = getYAxisTextList(series, opts, config, columnstyle.type);
    var yAxisWidth = config.yAxisWidth;
    var rangesFormat = ranges.map(function(item) {
        item = util.toFixed(item, 2);
        item = opts.yAxis.format ? opts.yAxis.format(Number(item)) : item;
        yAxisWidth = Math.max(yAxisWidth, measureText(item) + 5);
        return item;
    });
    if (opts.yAxis.disabled === true) {
        yAxisWidth = 0;
    }

    return {
        rangesFormat: rangesFormat,
        ranges: ranges,
        yAxisWidth: yAxisWidth
    };
}

function calTooltipYAxisData(point, series, opts, config, eachSpacing) {
    var ranges = getYAxisTextList(series, opts, config);
    var spacingValid = opts.height - 2 * config.padding - config.xAxisHeight - config.legendHeight;
    let maxVal = ranges[0];
    let minVal = ranges[ranges.length - 1];
    let minAxis = config.padding;
    let maxAxis = config.padding + spacingValid;
    let item = maxVal - (maxVal - minVal) * (point - minAxis) / (maxAxis - minAxis);
    item = opts.yAxis.format ? opts.yAxis.format(Number(item)) : item;
    return item;
}

function contextRotate(context, opts) {
    if (opts.rotateLock !== true) {
        context.translate(opts.height, 0);
        context.rotate(90 * Math.PI / 180);
    } else if (opts._rotate_ !== true) {
        context.translate(opts.height, 0);
        context.rotate(90 * Math.PI / 180);
        opts._rotate_ = true;
    }
}

function drawPointShape(points, color, shape, context, opts) {
    context.beginPath();
    context.setStrokeStyle("#ffffff");
    context.setLineWidth(1 * opts.pixelRatio);
    context.setFillStyle(color);
    if (shape === 'diamond') {
        points.forEach(function(item, index) {
            if (item !== null) {
                context.moveTo(item.x, item.y - 4.5);
                context.lineTo(item.x - 4.5, item.y);
                context.lineTo(item.x, item.y + 4.5);
                context.lineTo(item.x + 4.5, item.y);
                context.lineTo(item.x, item.y - 4.5);
            }
        });
    } else if (shape === 'circle') {
        points.forEach(function(item, index) {
            if (item !== null) {
                context.moveTo(item.x + 3.5 * opts.pixelRatio, item.y);
                context.arc(item.x, item.y, 4 * opts.pixelRatio, 0, 2 * Math.PI, false);
            }
        });
    } else if (shape === 'rect') {
        points.forEach(function(item, index) {
            if (item !== null) {
                context.moveTo(item.x - 3.5, item.y - 3.5);
                context.rect(item.x - 3.5, item.y - 3.5, 7, 7);
            }
        });
    } else if (shape === 'triangle') {
        points.forEach(function(item, index) {
            if (item !== null) {
                context.moveTo(item.x, item.y - 4.5);
                context.lineTo(item.x - 4.5, item.y + 4.5);
                context.lineTo(item.x + 4.5, item.y + 4.5);
                context.lineTo(item.x, item.y - 4.5);
            }
        });
    }
    context.closePath();
    context.fill();
    context.stroke();
}

function drawRingTitle(opts, config, context) {
    var titlefontSize = opts.title.fontSize || config.titleFontSize;
    var subtitlefontSize = opts.subtitle.fontSize || config.subtitleFontSize;
    var title = opts.title.name || '';
    var subtitle = opts.subtitle.name || '';
    var titleFontColor = opts.title.color || config.titleColor;
    var subtitleFontColor = opts.subtitle.color || config.subtitleColor;
    var titleHeight = title ? titlefontSize : 0;
    var subtitleHeight = subtitle ? subtitlefontSize : 0;
    var margin = 5;
    if (subtitle) {
        var textWidth = measureText(subtitle, subtitlefontSize);
        var startX = (opts.width - textWidth) / 2 + (opts.subtitle.offsetX || 0);
        var startY = ((opts.height - config.legendHeight + subtitlefontSize) / 2) + (opts.subtitle.offsetY || 0);
        if (title) {
            startY -= (titleHeight + margin) / 2;
        }
        context.beginPath();
        context.setFontSize(subtitlefontSize);
        context.setFillStyle(subtitleFontColor);
        context.fillText(subtitle, startX, startY);
        context.closePath();
        context.stroke();
    }
    if (title) {
        var _textWidth = measureText(title, titlefontSize);
        var _startX = (opts.width - _textWidth) / 2 + (opts.title.offsetX || 0);
        var _startY = ((opts.height - config.legendHeight + titlefontSize) / 2) + (opts.title.offsetY || 0);
        if (subtitle) {
            _startY += (subtitleHeight + margin) / 2;
        }
        context.beginPath();
        context.setFontSize(titlefontSize);
        context.setFillStyle(titleFontColor);
        context.fillText(title, _startX, _startY);
        context.closePath();
        context.stroke();
    }
}

function drawPointText(points, series, config, context) {
    // 绘制数据文案
    var data = series.data;
    points.forEach(function(item, index) {
        if (item !== null) {
            //var formatVal = series.format ? series.format(data[index]) : data[index];
            context.beginPath();
            context.setFontSize(series.textSize || config.fontSize);
            context.setFillStyle(series.textColor || '#666666');
            var value = data[index]
            if (typeof data[index] === 'object' && data[index] !== null) {
                value = data[index].value
            }
            var formatVal = series.format ? series.format(value) : value;
            context.fillText(formatVal, item.x - measureText(formatVal,series.textSize || config.fontSize) / 2, item.y - 2);
            context.closePath();
            context.stroke();
        }
    });

}

function drawGaugeLabel(gaugeOption, radius, centerPosition, opts, config, context) {
    radius -= gaugeOption.width / 2 + config.gaugeLabelTextMargin;

    let totalAngle = gaugeOption.startAngle - gaugeOption.endAngle + 1;
    let splitAngle = totalAngle / gaugeOption.splitLine.splitNumber;
    let totalNumber = gaugeOption.endNumber - gaugeOption.startNumber;
    let splitNumber = totalNumber / gaugeOption.splitLine.splitNumber;
    let nowAngle = gaugeOption.startAngle;
    let nowNumber = gaugeOption.startNumber;
    for (let i = 0; i < gaugeOption.splitLine.splitNumber + 1; i++) {
        var pos = {
            x: radius * Math.cos(nowAngle * Math.PI),
            y: radius * Math.sin(nowAngle * Math.PI)
        };
        var labelText = gaugeOption.labelFormat ? gaugeOption.labelFormat(nowNumber) : nowNumber;
        pos.x += centerPosition.x - measureText(labelText) / 2;
        pos.y += centerPosition.y;
        var startX = pos.x;
        var startY = pos.y;
        context.beginPath();
        context.setFontSize(config.fontSize);
        context.setFillStyle(gaugeOption.labelColor || '#666666');
        context.fillText(labelText, startX, startY + config.fontSize / 2);
        context.closePath();
        context.stroke();

        nowAngle += splitAngle;
        if (nowAngle >= 2) {
            nowAngle = nowAngle % 2;
        }
        nowNumber += splitNumber;
    }

}

function drawRadarLabel(angleList, radius, centerPosition, opts, config, context) {
    var radarOption = opts.extra.radar || {};
    radius += config.radarLabelTextMargin;

    angleList.forEach(function(angle, index) {
        var pos = {
            x: radius * Math.cos(angle),
            y: radius * Math.sin(angle)
        };
        var posRelativeCanvas = convertCoordinateOrigin(pos.x, pos.y, centerPosition);
        var startX = posRelativeCanvas.x;
        var startY = posRelativeCanvas.y;
        if (util.approximatelyEqual(pos.x, 0)) {
            startX -= measureText(opts.categories[index] || '') / 2;
        } else if (pos.x < 0) {
            startX -= measureText(opts.categories[index] || '');
        }
        context.beginPath();
        context.setFontSize(config.fontSize);
        context.setFillStyle(radarOption.labelColor || '#666666');
        context.fillText(opts.categories[index] || '', startX, startY + config.fontSize / 2);
        context.closePath();
        context.stroke();
    });

}

function drawPieText(series, opts, config, context, radius, center) {
    var lineRadius = config.pieChartLinePadding;
    var textObjectCollection = [];
    var lastTextObject = null;

    var seriesConvert = series.map(function(item) {
        var arc = 2 * Math.PI - (item._start_ + 2 * Math.PI * item._proportion_ / 2);
        var text = item.format ? item.format(+item._proportion_.toFixed(2)) : util.toFixed(item._proportion_ * 100) + '%';
        var color = item.color;
        var radius = item._radius_;
        return {
            arc: arc,
            text: text,
            color: color,
            radius: radius,
            textColor: item.textColor,
            textSize: item.textSize,
        };
    });
    for (let i = 0; i < seriesConvert.length; i++) {
        let item = seriesConvert[i];
        // line end
        let orginX1 = Math.cos(item.arc) * (item.radius+lineRadius);
        let orginY1 = Math.sin(item.arc) * (item.radius+lineRadius);

        // line start
        let orginX2 = Math.cos(item.arc) * item.radius;
        let orginY2 = Math.sin(item.arc) * item.radius;

        // text start
        let orginX3 = orginX1 >= 0 ? orginX1 + config.pieChartTextPadding : orginX1 - config.pieChartTextPadding;
        let orginY3 = orginY1;
        let textWidth = measureText(item.text);
        let startY = orginY3;

        if (lastTextObject && util.isSameXCoordinateArea(lastTextObject.start, {
                x: orginX3
            })) {
            if (orginX3 > 0) {
                startY = Math.min(orginY3, lastTextObject.start.y);
            } else if (orginX1 < 0) {
                startY = Math.max(orginY3, lastTextObject.start.y);
            } else {
                if (orginY3 > 0) {
                    startY = Math.max(orginY3, lastTextObject.start.y);
                } else {
                    startY = Math.min(orginY3, lastTextObject.start.y);
                }
            }
        }
        if (orginX3 < 0) {
            orginX3 -= textWidth;
        }

        let textObject = {
            lineStart: {
                x: orginX2,
                y: orginY2
            },
            lineEnd: {
                x: orginX1,
                y: orginY1
            },
            start: {
                x: orginX3,
                y: startY
            },
            width: textWidth,
            height: config.fontSize,
            text: item.text,
            color: item.color,
            textColor: item.textColor,
            textSize: item.textSize
        };
        lastTextObject = avoidCollision(textObject, lastTextObject);
        textObjectCollection.push(lastTextObject);
    }

    for (let i = 0; i < textObjectCollection.length; i++) {
        let item = textObjectCollection[i];
        let lineStartPoistion = convertCoordinateOrigin(item.lineStart.x, item.lineStart.y, center);
        let lineEndPoistion = convertCoordinateOrigin(item.lineEnd.x, item.lineEnd.y, center);
        let textPosition = convertCoordinateOrigin(item.start.x, item.start.y, center);
        context.setLineWidth(1 * opts.pixelRatio);
        context.setFontSize(config.fontSize);
        context.beginPath();
        context.setStrokeStyle(item.color);
        context.setFillStyle(item.color);
        context.moveTo(lineStartPoistion.x, lineStartPoistion.y);
        let curveStartX = item.start.x < 0 ? textPosition.x + item.width : textPosition.x;
        let textStartX = item.start.x < 0 ? textPosition.x - 5 : textPosition.x + 5;
        context.quadraticCurveTo(lineEndPoistion.x, lineEndPoistion.y, curveStartX, textPosition.y);
        context.moveTo(lineStartPoistion.x, lineStartPoistion.y);
        context.stroke();
        context.closePath();
        context.beginPath();
        context.moveTo(textPosition.x + item.width, textPosition.y);
        context.arc(curveStartX, textPosition.y, 2, 0, 2 * Math.PI);
        context.closePath();
        context.fill();
        context.beginPath();
        context.setFontSize(item.textSize||config.fontSize);
        context.setFillStyle(item.textColor||'#666666');
        context.fillText(item.text, textStartX, textPosition.y + 3);
        context.closePath();
        context.stroke();
        context.closePath();
    }
}

function drawToolTipSplitLine(offsetX, opts, config, context) {
    var toolTipOption = opts.extra.tooltip || {};
    toolTipOption.gridType = toolTipOption.gridType == undefined ? 'solid' : toolTipOption.gridType;
    toolTipOption.dashLength = toolTipOption.dashLength == undefined ? 4 : toolTipOption.dashLength;
    var startY = config.padding;
    var endY = opts.height - config.padding - config.xAxisHeight - config.legendHeight;

    if (toolTipOption.gridType == 'dash') {
        context.setLineDash([toolTipOption.dashLength, toolTipOption.dashLength]);
    }
    context.beginPath();
    context.setStrokeStyle(toolTipOption.gridColor || '#cccccc');
    context.setLineWidth(1 * opts.pixelRatio);
    context.moveTo(offsetX, startY);
    context.lineTo(offsetX, endY);
    context.closePath();
    context.stroke();
    context.setLineDash([]);

    if (toolTipOption.xAxisLabel) {
        let labelText = opts.categories[opts.tooltip.index];
        context.setFontSize(config.fontSize);
        let textWidth = context.measureText(labelText).width;

        let textX = offsetX - config.toolTipPadding - 0.5 * textWidth;
        let textY = endY;
        context.beginPath();
        context.setFillStyle(hexToRgb(toolTipOption.labelBgColor || config.toolTipBackground, toolTipOption.labelBgOpacity ||
            config.toolTipOpacity));
        context.setStrokeStyle(toolTipOption.labelBgColor || config.toolTipBackground);
        context.setLineWidth(1 * opts.pixelRatio);
        context.rect(textX, textY, textWidth + 2 * config.toolTipPadding, config.fontSize + 2 * config.toolTipPadding);
        context.closePath();
        context.stroke();
        context.fill();

        context.beginPath();
        context.setFontSize(config.fontSize);
        context.setFillStyle(toolTipOption.labelFontColor || config.fontColor);
        context.fillText(labelText, textX + 2 * config.toolTipPadding, textY + config.toolTipPadding + config.fontSize);
        context.closePath();
        context.stroke();
    }
}

function drawToolTipHorizentalLine(opts, config, context, eachSpacing, xAxisPoints) {
    var toolTipOption = opts.extra.tooltip || {};
    toolTipOption.gridType = toolTipOption.gridType == undefined ? 'solid' : toolTipOption.gridType;
    toolTipOption.dashLength = toolTipOption.dashLength == undefined ? 4 : toolTipOption.dashLength;
    var startX = config.padding + config.yAxisWidth + config.yAxisTitleWidth;
    var endX = opts.width - config.padding;

    if (toolTipOption.gridType == 'dash') {
        context.setLineDash([toolTipOption.dashLength, toolTipOption.dashLength]);
    }
    context.beginPath();
    context.setStrokeStyle(toolTipOption.gridColor || '#cccccc');
    context.setLineWidth(1 * opts.pixelRatio);
    context.moveTo(startX, opts.tooltip.offset.y);
    context.lineTo(endX, opts.tooltip.offset.y);
    context.closePath();
    context.stroke();
    context.setLineDash([]);

    if (toolTipOption.yAxisLabel) {

        let labelText = calTooltipYAxisData(opts.tooltip.offset.y, opts.series, opts, config, eachSpacing);
        context.setFontSize(config.fontSize);
        let textWidth = context.measureText(labelText).width;

        let textX = startX - 2 * config.toolTipPadding - textWidth;
        let textY = opts.tooltip.offset.y;
        context.beginPath();
        context.setFillStyle(hexToRgb(toolTipOption.labelBgColor || config.toolTipBackground, toolTipOption.labelBgOpacity ||
            config.toolTipOpacity));
        context.setStrokeStyle(toolTipOption.labelBgColor || config.toolTipBackground);
        context.setLineWidth(1 * opts.pixelRatio);
        context.rect(textX, textY - 0.5 * config.fontSize - config.toolTipPadding, textWidth + 2 * config.toolTipPadding,
            config.fontSize + 2 * config.toolTipPadding);
        context.closePath();
        context.stroke();
        context.fill();

        context.beginPath();
        context.setFontSize(config.fontSize);
        context.setFillStyle(toolTipOption.labelFontColor || config.fontColor);
        context.fillText(labelText, textX + config.toolTipPadding, textY + 0.5 * config.fontSize);
        context.closePath();
        context.stroke();
    }
}


function drawToolTipSplitArea(offsetX, opts, config, context, eachSpacing) {
    var toolTipOption = opts.extra.tooltip || {
        activeBgColor: '#000000',
        activeBgOpacity: 0.08
    };
    toolTipOption.activeBgColor = toolTipOption.activeBgColor ? toolTipOption.activeBgColor : '#000000';
    toolTipOption.activeBgOpacity = toolTipOption.activeBgOpacity ? toolTipOption.activeBgOpacity : 0.08;
    var startY = config.padding;
    var endY = opts.height - config.padding - config.xAxisHeight - config.legendHeight;
    context.beginPath();
    context.setFillStyle(hexToRgb(toolTipOption.activeBgColor, toolTipOption.activeBgOpacity));
    context.rect(offsetX - eachSpacing / 2, startY, eachSpacing, endY - startY);
    context.closePath();
    context.fill();
}

function drawToolTip(textList, offset, opts, config, context, eachSpacing, xAxisPoints) {
    var toolTipOption = opts.extra.tooltip || {
        bgColor: '#000000',
        bgOpacity: 0.7,
        fontColor: '#FFFFFF'
    };
    toolTipOption.bgColor = toolTipOption.bgColor ? toolTipOption.bgColor : '#000000';
    toolTipOption.bgOpacity = toolTipOption.bgOpacity ? toolTipOption.bgOpacity : 0.7;
    toolTipOption.fontColor = toolTipOption.fontColor ? toolTipOption.fontColor : '#FFFFFF';
    var legendWidth = 4 * opts.pixelRatio;
    var legendMarginRight = 5 * opts.pixelRatio;
    var arrowWidth = 8 * opts.pixelRatio;
    var isOverRightBorder = false;
    if (opts.type == 'line' || opts.type == 'area' || opts.type == 'candle' || opts.type == 'mix') {
        drawToolTipSplitLine(opts.tooltip.offset.x, opts, config, context);
    }

    offset = assign({
        x: 0,
        y: 0
    }, offset);
    offset.y -= 8 * opts.pixelRatio;
    var textWidth = textList.map(function(item) {
        return measureText(item.text);
    });

    var toolTipWidth = legendWidth + legendMarginRight + 4 * config.toolTipPadding + Math.max.apply(null, textWidth);
    var toolTipHeight = 2 * config.toolTipPadding + textList.length * config.toolTipLineHeight;

    // if beyond the right border
    if (offset.x - Math.abs(opts._scrollDistance_) + arrowWidth + toolTipWidth > opts.width) {
        isOverRightBorder = true;
    }

    // draw background rect
    context.beginPath();
    context.setFillStyle(hexToRgb(toolTipOption.bgColor || config.toolTipBackground, toolTipOption.bgOpacity || config.toolTipOpacity));
    if (isOverRightBorder) {
        context.moveTo(offset.x, offset.y + 10 * opts.pixelRatio);
        context.lineTo(offset.x - arrowWidth, offset.y + 10 * opts.pixelRatio - 5 * opts.pixelRatio);
        context.lineTo(offset.x - arrowWidth, offset.y);
        context.lineTo(offset.x - arrowWidth - Math.round(toolTipWidth), offset.y);
        context.lineTo(offset.x - arrowWidth - Math.round(toolTipWidth), offset.y + toolTipHeight);
        context.lineTo(offset.x - arrowWidth, offset.y + toolTipHeight);
        context.lineTo(offset.x - arrowWidth, offset.y + 10 * opts.pixelRatio + 5 * opts.pixelRatio);
        context.lineTo(offset.x, offset.y + 10 * opts.pixelRatio);
    } else {
        context.moveTo(offset.x, offset.y + 10 * opts.pixelRatio);
        context.lineTo(offset.x + arrowWidth, offset.y + 10 * opts.pixelRatio - 5 * opts.pixelRatio);
        context.lineTo(offset.x + arrowWidth, offset.y);
        context.lineTo(offset.x + arrowWidth + Math.round(toolTipWidth), offset.y);
        context.lineTo(offset.x + arrowWidth + Math.round(toolTipWidth), offset.y + toolTipHeight);
        context.lineTo(offset.x + arrowWidth, offset.y + toolTipHeight);
        context.lineTo(offset.x + arrowWidth, offset.y + 10 * opts.pixelRatio + 5 * opts.pixelRatio);
        context.lineTo(offset.x, offset.y + 10 * opts.pixelRatio);
    }

    context.closePath();
    context.fill();

    // draw legend
    textList.forEach(function(item, index) {
        if (item.color !== null) {
            context.beginPath();
            context.setFillStyle(item.color);
            var startX = offset.x + arrowWidth + 2 * config.toolTipPadding;
            var startY = offset.y + (config.toolTipLineHeight - config.fontSize) / 2 + config.toolTipLineHeight * index +
                config.toolTipPadding + 1;
            if (isOverRightBorder) {
                startX = offset.x - toolTipWidth - arrowWidth + 2 * config.toolTipPadding;
            }
            context.fillRect(startX, startY, legendWidth, config.fontSize);
            context.closePath();
        }
    });

    // draw text list

    textList.forEach(function(item, index) {
        var startX = offset.x + arrowWidth + 2 * config.toolTipPadding + legendWidth + legendMarginRight;
        if (isOverRightBorder) {
            startX = offset.x - toolTipWidth - arrowWidth + 2 * config.toolTipPadding + +legendWidth + legendMarginRight;
        }
        var startY = offset.y + (config.toolTipLineHeight - config.fontSize) / 2 + config.toolTipLineHeight * index +
            config.toolTipPadding;
        context.beginPath();
        context.setFontSize(config.fontSize);
        context.setFillStyle(toolTipOption.fontColor);
        context.fillText(item.text, startX, startY + config.fontSize);
        context.closePath();
        context.stroke();
    });
}

function drawYAxisTitle(title, opts, config, context) {
    var startX = config.xAxisHeight + (opts.height - config.xAxisHeight - measureText(title)) / 2;
    context.save();
    context.beginPath();
    context.setFontSize(config.fontSize);
    context.setFillStyle(opts.yAxis.titleFontColor || '#333333');
    context.translate(0, opts.height);
    context.rotate(-90 * Math.PI / 180);
    context.fillText(title, startX, config.padding + 0.5 * config.fontSize);
    context.closePath();
    context.stroke();
    context.restore();
}

function drawColumnDataPoints(series, opts, config, context) {
    var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
    var columnOption = opts.extra.column || {
        type: {},
        meter: {}
    };
    columnOption.type = columnOption.type == undefined ? 'group' : columnOption.type;
    columnOption.meter = columnOption.meter || {}
    columnOption.meter.border = columnOption.meter.border == undefined ? 4 : columnOption.meter.border;
    columnOption.meter.fillColor = columnOption.meter.fillColor == undefined ? '#FFFFFF' : columnOption.meter.fillColor;
    var _calYAxisData = calYAxisData(series, opts, config),
        ranges = _calYAxisData.ranges;

    var _getXAxisPoints = getXAxisPoints(opts.categories, opts, config),
        xAxisPoints = _getXAxisPoints.xAxisPoints,
        eachSpacing = _getXAxisPoints.eachSpacing;

    var minRange = ranges.pop();
    var maxRange = ranges.shift();
    var calPoints = [];

    context.save();
    if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) {
        context.translate(opts._scrollDistance_, 0);
    }
    if (opts.tooltip && opts.tooltip.textList && opts.tooltip.textList.length && process === 1) {
        drawToolTipSplitArea(opts.tooltip.offset.x, opts, config, context, eachSpacing);
    }

    series.forEach(function(eachSeries, seriesIndex) {
        var data = eachSeries.data;
        switch (columnOption.type) {
            case 'group':
                var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
                var tooltipPoints = getStackDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config,
                    seriesIndex, series, process);
                calPoints.push(tooltipPoints);
                points = fixColumeData(points, eachSpacing, series.length, seriesIndex, config, opts);
                points.forEach(function(item, index) {
                    if (item !== null) {
                        context.beginPath();
                        context.setFillStyle(item.color || eachSeries.color);
                        var startX = item.x - item.width / 2 + 1;
                        var height = opts.height - item.y - config.padding - config.xAxisHeight - config.legendHeight;
                        context.moveTo(startX, item.y);
                        context.fillRect(startX, item.y, item.width - 2, height);
                        context.closePath();
                        context.fill();
                    }
                });
                break;
            case 'stack':
                // 绘制堆叠数据图
                var points = getStackDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, seriesIndex,
                    series, process);
                calPoints.push(points);
                points = fixColumeStackData(points, eachSpacing, series.length, seriesIndex, config, opts, series);

                points.forEach(function(item, index) {
                    if (item !== null) {
                        context.beginPath();
                        context.setFillStyle(item.color || eachSeries.color);
                        var startX = item.x - item.width / 2 + 1;
                        var height = opts.height - item.y - config.padding - config.xAxisHeight - config.legendHeight;
                        var height0 = opts.height - item.y0 - config.padding - config.xAxisHeight - config.legendHeight;
                        if (seriesIndex > 0) {
                            height -= height0;
                        }
                        context.moveTo(startX, item.y);
                        context.fillRect(startX, item.y, item.width - 2, height);
                        context.closePath();
                        context.fill();
                    }
                });
                break;
            case 'meter':
                // 绘制温度计数据图
                var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
                calPoints.push(points);
                points = fixColumeMeterData(points, eachSpacing, series.length, seriesIndex, config, opts, columnOption.meter.border);
                if (seriesIndex == 0) {
                    points.forEach(function(item, index) {
                        if (item !== null) {
                            //画背景颜色
                            context.beginPath();
                            context.setFillStyle(columnOption.meter.fillColor);
                            var startX = item.x - item.width / 2 ;
                            var height = opts.height - item.y - config.padding - config.xAxisHeight - config.legendHeight;
                            context.moveTo(startX, item.y);
                            context.fillRect(startX, item.y, item.width, height);
                            context.closePath();
                            context.fill();
                            //画边框线
                            if(columnOption.meter.border>0){
                                context.beginPath();
                                context.setStrokeStyle(eachSeries.color);
                                context.setLineWidth(columnOption.meter.border * opts.pixelRatio);
                                context.moveTo(startX + columnOption.meter.border*0.5, item.y + height);
                                context.lineTo(startX + columnOption.meter.border*0.5, item.y + columnOption.meter.border*0.5);
                                context.lineTo(startX + item.width - columnOption.meter.border*0.5, item.y + columnOption.meter.border*0.5);
                                context.lineTo(startX + item.width - columnOption.meter.border*0.5, item.y + height);
                                context.stroke();
                            }
                        }
                    });
                } else {
                    points.forEach(function(item, index) {
                        if (item !== null) {
                            context.beginPath();
                            context.setFillStyle(item.color || eachSeries.color);
                            var startX = item.x - item.width / 2;
                            var height = opts.height - item.y - config.padding - config.xAxisHeight - config.legendHeight;
                            context.moveTo(startX, item.y);
                            context.fillRect(startX, item.y, item.width, height);
                            context.closePath();
                            context.fill();
                        }
                    });
                }
                break;
        }
    });
    if (opts.dataLabel !== false && process === 1) {
        series.forEach(function(eachSeries, seriesIndex) {
            var data = eachSeries.data;
            switch (columnOption.type) {
                case 'group':
                    var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
                    points = fixColumeData(points, eachSpacing, series.length, seriesIndex, config, opts);

                    drawPointText(points, eachSeries, config, context);
                    break;
                case 'stack':
                    var points = getStackDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, seriesIndex,
                        series, process);
                    drawPointText(points, eachSeries, config, context);
                    break;
                case 'meter':
                    var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
                    drawPointText(points, eachSeries, config, context);
                    break;
            }
        });
    }

    context.restore();

    return {
        xAxisPoints: xAxisPoints,
        calPoints: calPoints,
        eachSpacing: eachSpacing
    };
}

function drawCandleDataPoints(series, seriesMA, opts, config, context) {
    var process = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 1;
    var candleOption = opts.extra.candle || {
        color: {},
        average: {}
    };
    candleOption.color.upLine = candleOption.color.upLine ? candleOption.color.upLine : '#f04864';
    candleOption.color.upFill = candleOption.color.upFill ? candleOption.color.upFill : '#f04864';
    candleOption.color.downLine = candleOption.color.downLine ? candleOption.color.downLine : '#2fc25b';
    candleOption.color.downFill = candleOption.color.downFill ? candleOption.color.downFill : '#2fc25b';
    candleOption.average.show = candleOption.average.show === true ? true : false;
    candleOption.average.name = candleOption.average.name ? candleOption.average.name : [];
    candleOption.average.day = candleOption.average.day ? candleOption.average.day : [];
    candleOption.average.color = candleOption.average.color ? candleOption.average.color : ['#1890ff', '#2fc25b',
        '#facc14', '#f04864', '#8543e0', '#90ed7d'
    ];
    opts.extra.candle = candleOption;

    var _calYAxisData5 = calYAxisData(series, opts, config),
        ranges = _calYAxisData5.ranges;

    var _getXAxisPoints5 = getXAxisPoints(opts.categories, opts, config),
        xAxisPoints = _getXAxisPoints5.xAxisPoints,
        eachSpacing = _getXAxisPoints5.eachSpacing;

    var minRange = ranges.pop();
    var maxRange = ranges.shift();
    var calPoints = [];

    context.save();
    if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) {
        context.translate(opts._scrollDistance_, 0);
    }
    //画均线
    if (candleOption.average.show) {
        seriesMA.forEach(function(eachSeries, seriesIndex) {
            var data = eachSeries.data;
            var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
            //calPoints.push(points);
            var splitPointList = splitPoints(points);

            splitPointList.forEach(function(points, index) {
                context.beginPath();
                context.setStrokeStyle(eachSeries.color);
                context.setLineWidth(1);
                if (points.length === 1) {
                    context.moveTo(points[0].x, points[0].y);
                    context.arc(points[0].x, points[0].y, 1, 0, 2 * Math.PI);
                } else {
                    context.moveTo(points[0].x, points[0].y);
                    points.forEach(function(item, index) {
                        if (index > 0) {
                            var ctrlPoint = createCurveControlPoints(points, index - 1);
                            context.bezierCurveTo(ctrlPoint.ctrA.x, ctrlPoint.ctrA.y, ctrlPoint.ctrB.x, ctrlPoint.ctrB.y, item.x, item
                                .y);
                        }
                    });
                    context.moveTo(points[0].x, points[0].y);
                }
                context.closePath();
                context.stroke();
            });
        });
    }
    //画K线
    series.forEach(function(eachSeries, seriesIndex) {
        var data = eachSeries.data;
        var points = getCandleDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
        calPoints.push(points);
        var splitPointList = splitPoints(points);
        splitPointList = splitPointList[0];

        splitPointList.forEach(function(points, index) {
            context.beginPath();
            //如果上涨
            if (data[index][1] - data[index][0] > 0) {
                context.setStrokeStyle(candleOption.color.upLine);
                context.setFillStyle(candleOption.color.upFill);
                context.setLineWidth(1 * opts.pixelRatio);
                context.moveTo(points[3].x, points[3].y); //顶点
                context.lineTo(points[1].x, points[1].y); //收盘中间点
                context.lineTo(points[1].x - eachSpacing / 4, points[1].y); //收盘左侧点
                context.lineTo(points[0].x - eachSpacing / 4, points[0].y); //开盘左侧点
                context.lineTo(points[0].x, points[0].y); //开盘中间点
                context.lineTo(points[2].x, points[2].y); //底点
                context.lineTo(points[0].x, points[0].y); //开盘中间点
                context.lineTo(points[0].x + eachSpacing / 4, points[0].y); //开盘右侧点
                context.lineTo(points[1].x + eachSpacing / 4, points[1].y); //收盘右侧点
                context.lineTo(points[1].x, points[1].y); //收盘中间点
                context.moveTo(points[3].x, points[3].y); //顶点
            } else {
                context.setStrokeStyle(candleOption.color.downLine);
                context.setFillStyle(candleOption.color.downFill);
                context.setLineWidth(1 * opts.pixelRatio);
                context.moveTo(points[3].x, points[3].y); //顶点
                context.lineTo(points[0].x, points[0].y); //开盘中间点
                context.lineTo(points[0].x - eachSpacing / 4, points[0].y); //开盘左侧点
                context.lineTo(points[1].x - eachSpacing / 4, points[1].y); //收盘左侧点
                context.lineTo(points[1].x, points[1].y); //收盘中间点
                context.lineTo(points[2].x, points[2].y); //底点
                context.lineTo(points[1].x, points[1].y); //收盘中间点
                context.lineTo(points[1].x + eachSpacing / 4, points[1].y); //收盘右侧点
                context.lineTo(points[0].x + eachSpacing / 4, points[0].y); //开盘右侧点
                context.lineTo(points[0].x, points[0].y); //开盘中间点
                context.moveTo(points[3].x, points[3].y); //顶点
            }
            context.closePath();
            context.fill();
            context.stroke();
        });
    });


    context.restore();



    return {
        xAxisPoints: xAxisPoints,
        calPoints: calPoints,
        eachSpacing: eachSpacing
    };
}

function drawAreaDataPoints(series, opts, config, context) {
    var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
    var areaOption = opts.extra.area || {
        type: 'straight',
        opacity: 0.5,
        addLine: false,
        width: 2
    };
    areaOption.type = areaOption.type ? areaOption.type : 'straight';
    areaOption.opacity = areaOption.opacity ? areaOption.opacity : 0.2;
    areaOption.addLine = areaOption.addLine == true ? true : false;
    areaOption.width = areaOption.width ? areaOption.width : 2;
    var _calYAxisData2 = calYAxisData(series, opts, config),
        ranges = _calYAxisData2.ranges;

    var _getXAxisPoints2 = getXAxisPoints(opts.categories, opts, config),
        xAxisPoints = _getXAxisPoints2.xAxisPoints,
        eachSpacing = _getXAxisPoints2.eachSpacing;

    var minRange = ranges.pop();
    var maxRange = ranges.shift();
    var endY = opts.height - config.padding - config.xAxisHeight - config.legendHeight;
    var calPoints = [];

    context.save();
    if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) {
        context.translate(opts._scrollDistance_, 0);
    }

    if (opts.tooltip && opts.tooltip.textList && opts.tooltip.textList.length && process === 1) {
        drawToolTipSplitLine(opts.tooltip.offset.x, opts, config, context);
    }


    series.forEach(function(eachSeries, seriesIndex) {
        let data = eachSeries.data;
        let points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
        calPoints.push(points);

        let splitPointList = splitPoints(points);

        for (let i = 0; i < splitPointList.length; i++) {
            let points = splitPointList[i];
            // 绘制区域数
            context.beginPath();
            context.setStrokeStyle(hexToRgb(eachSeries.color, areaOption.opacity));
            context.setFillStyle(hexToRgb(eachSeries.color, areaOption.opacity));
            context.setLineWidth(areaOption.width * opts.pixelRatio);
            if (points.length > 1) {
                let firstPoint = points[0];
                let lastPoint = points[points.length - 1];

                context.moveTo(firstPoint.x, firstPoint.y);
                if (areaOption.type === 'curve') {
                    points.forEach(function(item, index) {
                        if (index > 0) {
                            let ctrlPoint = createCurveControlPoints(points, index - 1);
                            context.bezierCurveTo(ctrlPoint.ctrA.x, ctrlPoint.ctrA.y, ctrlPoint.ctrB.x, ctrlPoint.ctrB.y, item.x, item
                                .y);
                        }
                    });
                } else {
                    points.forEach(function(item, index) {
                        if (index > 0) {
                            context.lineTo(item.x, item.y);
                        }
                    });
                }

                context.lineTo(lastPoint.x, endY);
                context.lineTo(firstPoint.x, endY);
                context.lineTo(firstPoint.x, firstPoint.y);
            } else {
                let item = points[0];
                context.moveTo(item.x - eachSpacing / 2, item.y);
                context.lineTo(item.x + eachSpacing / 2, item.y);
                context.lineTo(item.x + eachSpacing / 2, endY);
                context.lineTo(item.x - eachSpacing / 2, endY);
                context.moveTo(item.x - eachSpacing / 2, item.y);
            }
            context.closePath();
            context.fill();


            //画连线
            if (areaOption.addLine) {
                context.beginPath();
                context.setStrokeStyle(eachSeries.color);
                context.setLineWidth(areaOption.width * opts.pixelRatio);
                if (points.length === 1) {
                    context.moveTo(points[0].x, points[0].y);
                    context.arc(points[0].x, points[0].y, 1, 0, 2 * Math.PI);
                } else {
                    context.moveTo(points[0].x, points[0].y);
                    if (areaOption.type === 'curve') {
                        points.forEach(function(item, index) {
                            if (index > 0) {
                                let ctrlPoint = createCurveControlPoints(points, index - 1);
                                context.bezierCurveTo(ctrlPoint.ctrA.x, ctrlPoint.ctrA.y, ctrlPoint.ctrB.x, ctrlPoint.ctrB.y, item.x,
                                    item.y);
                            }
                        });
                    } else {
                        points.forEach(function(item, index) {
                            if (index > 0) {
                                context.lineTo(item.x, item.y);
                            }
                        });
                    }
                    context.moveTo(points[0].x, points[0].y);
                }
                context.closePath();
                context.stroke();
            }
        }

        //画点
        if (opts.dataPointShape !== false) {
            var shape = config.dataPointShape[seriesIndex % config.dataPointShape.length];
            drawPointShape(points, eachSeries.color, shape, context, opts);
        }

    });
    if (opts.dataLabel !== false && process === 1) {
        series.forEach(function(eachSeries, seriesIndex) {
            var data = eachSeries.data;
            var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
            drawPointText(points, eachSeries, config, context);
        });
    }

    context.restore();

    return {
        xAxisPoints: xAxisPoints,
        calPoints: calPoints,
        eachSpacing: eachSpacing
    };
}

function drawLineDataPoints(series, opts, config, context) {
    var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;
    var lineOption = opts.extra.line || {
        type: 'straight',
        width: 2
    };
    lineOption.type = lineOption.type ? lineOption.type : 'straight';
    lineOption.width = lineOption.width ? lineOption.width : 2;
    var _calYAxisData3 = calYAxisData(series, opts, config),
        ranges = _calYAxisData3.ranges;

    var _getXAxisPoints3 = getXAxisPoints(opts.categories, opts, config),
        xAxisPoints = _getXAxisPoints3.xAxisPoints,
        eachSpacing = _getXAxisPoints3.eachSpacing;

    var minRange = ranges.pop();
    var maxRange = ranges.shift();
    var calPoints = [];

    context.save();
    if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) {
        context.translate(opts._scrollDistance_, 0);
    }

    if (opts.tooltip && opts.tooltip.textList && opts.tooltip.textList.length && process === 1) {
        drawToolTipSplitLine(opts.tooltip.offset.x, opts, config, context);
    }

    series.forEach(function(eachSeries, seriesIndex) {
        var data = eachSeries.data;
        var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
        calPoints.push(points);
        var splitPointList = splitPoints(points);

        splitPointList.forEach(function(points, index) {
            context.beginPath();
            context.setStrokeStyle(eachSeries.color);
            context.setLineWidth(lineOption.width * opts.pixelRatio);
            if (points.length === 1) {
                context.moveTo(points[0].x, points[0].y);
                context.arc(points[0].x, points[0].y, 1, 0, 2 * Math.PI);
            } else {
                context.moveTo(points[0].x, points[0].y);
                if (lineOption.type === 'curve') {
                    points.forEach(function(item, index) {
                        if (index > 0) {
                            var ctrlPoint = createCurveControlPoints(points, index - 1);
                            context.bezierCurveTo(ctrlPoint.ctrA.x, ctrlPoint.ctrA.y, ctrlPoint.ctrB.x, ctrlPoint.ctrB.y, item.x, item
                                .y);
                        }
                    });
                } else {
                    points.forEach(function(item, index) {
                        if (index > 0) {
                            context.lineTo(item.x, item.y);
                        }
                    });
                }
                context.moveTo(points[0].x, points[0].y);
            }
            context.closePath();
            context.stroke();
        });

        if (opts.dataPointShape !== false) {
            var shape = config.dataPointShape[seriesIndex % config.dataPointShape.length];
            drawPointShape(points, eachSeries.color, shape, context, opts);
        }
    });
    if (opts.dataLabel !== false && process === 1) {
        series.forEach(function(eachSeries, seriesIndex) {
            var data = eachSeries.data;
            var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
            drawPointText(points, eachSeries, config, context);
        });
    }

    context.restore();

    return {
        xAxisPoints: xAxisPoints,
        calPoints: calPoints,
        eachSpacing: eachSpacing
    };
}

function drawMixDataPoints(series, opts, config, context) {
    var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;

    var _calYAxisData6 = calYAxisData(series, opts, config),
        ranges = _calYAxisData6.ranges;

    var _getXAxisPoints6 = getXAxisPoints(opts.categories, opts, config),
        xAxisPoints = _getXAxisPoints6.xAxisPoints,
        eachSpacing = _getXAxisPoints6.eachSpacing;

    var minRange = ranges.pop();
    var maxRange = ranges.shift();
    var endY = opts.height - config.padding - config.xAxisHeight - config.legendHeight;
    var calPoints = [];

    var columnIndex = 0;
    var columnLength = 0;
    series.forEach(function(eachSeries, seriesIndex) {
        if (eachSeries.type == 'column') {
            columnLength += 1;
        }
    });
    context.save();
    if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) {
        context.translate(opts._scrollDistance_, 0);
    }

    if (opts.tooltip && opts.tooltip.textList && opts.tooltip.textList.length && process === 1) {
        drawToolTipSplitLine(opts.tooltip.offset.x, opts, config, context);
    }

    series.forEach(function(eachSeries, seriesIndex) {
        var data = eachSeries.data;
        var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
        calPoints.push(points);

        // 绘制柱状数据图
        if (eachSeries.type == 'column') {
            points = fixColumeData(points, eachSpacing, columnLength, columnIndex, config, opts);
            points.forEach(function(item, index) {
                if (item !== null) {
                    context.beginPath();
                    context.setFillStyle(item.color || eachSeries.color);
                    var startX = item.x - item.width / 2 + 1;
                    var height = opts.height - item.y - config.padding - config.xAxisHeight - config.legendHeight;
                    context.moveTo(startX, item.y);
                    context.rect(startX, item.y, item.width - 2, height);
                    context.closePath();
                    context.fill();
                }
            });
            columnIndex += 1;
        }

        //绘制区域图数据

        if (eachSeries.type == 'area') {
            let splitPointList = splitPoints(points);
            for (let i = 0; i < splitPointList.length; i++) {
                let points = splitPointList[i];
                // 绘制区域数据
                context.beginPath();
                context.setStrokeStyle(eachSeries.color);
                context.setFillStyle(eachSeries.color);
                context.setGlobalAlpha(0.2);
                context.setLineWidth(2 * opts.pixelRatio);
                if (points.length > 1) {
                    var firstPoint = points[0];
                    let lastPoint = points[points.length - 1];
                    context.moveTo(firstPoint.x, firstPoint.y);
                    if (eachSeries.style === 'curve') {
                        points.forEach(function(item, index) {
                            if (index > 0) {
                                var ctrlPoint = createCurveControlPoints(points, index - 1);
                                context.bezierCurveTo(ctrlPoint.ctrA.x, ctrlPoint.ctrA.y, ctrlPoint.ctrB.x, ctrlPoint.ctrB.y, item.x,
                                    item.y);
                            }
                        });
                    } else {
                        points.forEach(function(item, index) {
                            if (index > 0) {
                                context.lineTo(item.x, item.y);
                            }
                        });
                    }
                    context.lineTo(lastPoint.x, endY);
                    context.lineTo(firstPoint.x, endY);
                    context.lineTo(firstPoint.x, firstPoint.y);
                } else {
                    let item = points[0];
                    context.moveTo(item.x - eachSpacing / 2, item.y);
                    context.lineTo(item.x + eachSpacing / 2, item.y);
                    context.lineTo(item.x + eachSpacing / 2, endY);
                    context.lineTo(item.x - eachSpacing / 2, endY);
                    context.moveTo(item.x - eachSpacing / 2, item.y);
                }
                context.closePath();
                context.fill();
                context.setGlobalAlpha(1);
            }
        }
        
        // 绘制折线数据图
        if (eachSeries.type == 'line') {
            var splitPointList = splitPoints(points);
            splitPointList.forEach(function(points, index) {
                context.beginPath();
                context.setStrokeStyle(eachSeries.color);
                context.setLineWidth(2 * opts.pixelRatio);
                if (points.length === 1) {
                    context.moveTo(points[0].x, points[0].y);
                    context.arc(points[0].x, points[0].y, 1, 0, 2 * Math.PI);
                } else {
                    context.moveTo(points[0].x, points[0].y);
                    if (eachSeries.style == 'curve') {
                        points.forEach(function(item, index) {
                            if (index > 0) {
                                var ctrlPoint = createCurveControlPoints(points, index - 1);
                                context.bezierCurveTo(ctrlPoint.ctrA.x, ctrlPoint.ctrA.y, ctrlPoint.ctrB.x, ctrlPoint.ctrB.y, item.x,
                                    item.y);
                            }
                        });
                    } else {
                        points.forEach(function(item, index) {
                            if (index > 0) {
                                context.lineTo(item.x, item.y);
                            }
                        });
                    }
                    context.moveTo(points[0].x, points[0].y);
                }
                context.closePath();
                context.stroke();
            });
        }

        // 绘制点数据图
        if (eachSeries.type == 'point') {
            points.forEach(function(pointsa, index) {
                if(pointsa){
                    context.beginPath();
                    context.setFillStyle(eachSeries.color);
                    context.setStrokeStyle('#FFFFFF');
                    context.setLineWidth(1 * opts.pixelRatio);
                    context.moveTo(pointsa.x + 3.5 * opts.pixelRatio, pointsa.y);
                    context.arc(pointsa.x, pointsa.y, 4* opts.pixelRatio, 0, 2 * Math.PI);
                    context.closePath();
                    context.fill();
                    context.stroke();
                }
            });
        }

        if (eachSeries.addPoint == true && eachSeries.type !== 'column') {
            var shape = config.dataPointShape[seriesIndex % config.dataPointShape.length];
            drawPointShape(points, eachSeries.color, shape, context, opts);
        }
    });
    if (opts.dataLabel !== false && process === 1) {
        var columnIndex = 0;
        series.forEach(function(eachSeries, seriesIndex) {
            var data = eachSeries.data;
            var points = getDataPoints(data, minRange, maxRange, xAxisPoints, eachSpacing, opts, config, process);
            if (eachSeries.type !== 'column') {
                drawPointText(points, eachSeries, config, context);
            } else {
                points = fixColumeData(points, eachSpacing, columnLength, columnIndex, config, opts);
                drawPointText(points, eachSeries, config, context);
                columnIndex += 1;
            }

        });
    }

    context.restore();

    return {
        xAxisPoints: xAxisPoints,
        calPoints: calPoints,
        eachSpacing: eachSpacing
    };
}

function drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints) {
    var toolTipOption = opts.extra.tooltip || {};
    if (toolTipOption.horizentalLine && opts.tooltip && process === 1 && (opts.type == 'line' || opts.type == 'area' ||
            opts.type == 'column' || opts.type == 'candle' || opts.type == 'mix')) {
        drawToolTipHorizentalLine(opts, config, context, eachSpacing, xAxisPoints)
    }
    context.save();
    if (opts._scrollDistance_ && opts._scrollDistance_ !== 0 && opts.enableScroll === true) {
        context.translate(opts._scrollDistance_, 0);
    }
    if (opts.tooltip && opts.tooltip.textList && opts.tooltip.textList.length && process === 1) {
        drawToolTip(opts.tooltip.textList, opts.tooltip.offset, opts, config, context, eachSpacing, xAxisPoints);
    }
    context.restore();

}

function drawXAxis(categories, opts, config, context) {

    var _getXAxisPoints4 = getXAxisPoints(categories, opts, config),
        xAxisPoints = _getXAxisPoints4.xAxisPoints,
        startX = _getXAxisPoints4.startX,
        endX = _getXAxisPoints4.endX,
        eachSpacing = _getXAxisPoints4.eachSpacing;

    var startY = opts.height - config.padding - config.xAxisHeight - config.legendHeight;
    var endY = config.padding;


    //绘制滚动条
    if (opts.enableScroll && opts.xAxis.scrollShow) {
        var scrollY = opts.height - config.padding - config.legendHeight + 6 * opts.pixelRatio;
        var scrollScreenWidth = endX - startX;
        var scrollTotalWidth = eachSpacing * (xAxisPoints.length - 1);
        var scrollWidth = scrollScreenWidth * scrollScreenWidth / scrollTotalWidth;
        var scrollLeft = 0;
        if (opts._scrollDistance_) {
            scrollLeft = -opts._scrollDistance_ * (scrollScreenWidth) / scrollTotalWidth;
        }
        context.beginPath();
        context.setLineCap('round');
        context.setLineWidth(6 * opts.pixelRatio);
        context.setStrokeStyle(opts.xAxis.scrollBackgroundColor || "#EFEBEF");
        context.moveTo(startX, scrollY);
        context.lineTo(endX, scrollY);
        context.stroke();
        context.closePath();
        context.beginPath();
        context.setLineCap('round');
        context.setLineWidth(6 * opts.pixelRatio);
        context.setStrokeStyle(opts.xAxis.scrollColor || "#A6A6A6");
        context.moveTo(startX + scrollLeft, scrollY);
        context.lineTo(startX + scrollLeft + scrollWidth, scrollY);
        context.stroke();
        context.setLineCap('butt');
        context.closePath();
    }

    context.save();

    if (opts._scrollDistance_ && opts._scrollDistance_ !== 0) {
        context.translate(opts._scrollDistance_, 0);
    }

    context.beginPath();
    context.setStrokeStyle(opts.xAxis.gridColor || "#cccccc");
    context.setLineCap('butt');
    context.setLineWidth(1 * opts.pixelRatio);
    if (opts.xAxis.gridType == 'dash') {
        context.setLineDash([opts.xAxis.dashLength, opts.xAxis.dashLength]);
    }
    if (opts.xAxis.disableGrid !== true) {
        if (opts.xAxis.type === 'calibration') {
            xAxisPoints.forEach(function(item, index) {
                if (index > 0) {
                    context.moveTo(item - eachSpacing / 2, startY);
                    context.lineTo(item - eachSpacing / 2, startY + 4 * opts.pixelRatio);
                }
            });
        } else {
            opts.xAxis.gridEval = opts.xAxis.gridEval || 1; 
            xAxisPoints.forEach(function(item, index) {
                if(index % opts.xAxis.gridEval == 0){
                    context.moveTo(item, startY);
                    context.lineTo(item, endY);
                }
            });
        }
    }
    context.closePath();
    context.stroke();
    context.setLineDash([]);

    //不绘制X轴
    if (opts.xAxis.disabled !== true) {
        // 对X轴列表做抽稀处理
        let validWidth = opts.width - 2 * config.padding - config.yAxisWidth - config.yAxisTitleWidth;
        //默认全部显示X轴标签
        let maxXAxisListLength = categories.length;
        //如果设置了X轴单屏数量
        if (opts.xAxis.labelCount) {
            //如果设置X轴密度
            if (opts.xAxis.itemCount) {
                maxXAxisListLength = Math.ceil(categories.length / opts.xAxis.itemCount * opts.xAxis.labelCount);
            } else {
                maxXAxisListLength = opts.xAxis.labelCount;
            }
            maxXAxisListLength -= 1;
        }

        let ratio = Math.ceil(categories.length / maxXAxisListLength);

        let newCategories = [];
        let cgLength = categories.length;
        for (let i = 0; i < cgLength; i++) {
            if (i % ratio !== 0) {
                newCategories.push("");
            } else {
                newCategories.push(categories[i]);
            }
        }
        newCategories[cgLength - 1] = categories[cgLength - 1];
        /*
        categories = categories.map(function (item, index) {
            return index % ratio !== 0 ? '' : item;
        });*/

        var xAxisFontSize = opts.xAxis.fontSize || config.fontSize;
        if (config._xAxisTextAngle_ === 0) {
            newCategories.forEach(function(item, index) {
                var offset = eachSpacing / 2 - measureText(item,xAxisFontSize) / 2;
                context.beginPath();
                context.setFontSize(xAxisFontSize);
                context.setFillStyle(opts.xAxis.fontColor || '#666666');
                context.fillText(item, xAxisPoints[index] + offset, startY + xAxisFontSize + 5);
                context.closePath();
                context.stroke();
            });

        } else {
            newCategories.forEach(function(item, index) {
                context.save();
                context.beginPath();
                context.setFontSize(xAxisFontSize);
                context.setFillStyle(opts.xAxis.fontColor || '#666666');
                var textWidth = measureText(item);
                var offset = eachSpacing / 2 - textWidth;

                var _calRotateTranslate = calRotateTranslate(xAxisPoints[index] + eachSpacing / 2, startY + xAxisFontSize / 2 + 5, opts.height),
                    transX = _calRotateTranslate.transX,
                    transY = _calRotateTranslate.transY;

                context.rotate(-1 * config._xAxisTextAngle_);
                context.translate(transX, transY);
                context.fillText(item, xAxisPoints[index] + offset, startY + xAxisFontSize + 5);
                context.closePath();
                context.stroke();
                context.restore();
            });
        }
    }
    context.restore();

}

function drawYAxisGrid(categories, opts, config, context) {
    if (opts.yAxis.disableGrid === true) {
        return;
    }
    var spacingValid = opts.height - 2 * config.padding - config.xAxisHeight - config.legendHeight;
    var eachSpacing = Math.floor(spacingValid / config.yAxisSplit);
    var yAxisTotalWidth = config.yAxisWidth + config.yAxisTitleWidth;
    var startX = config.padding + yAxisTotalWidth;
    var _getXAxisPoints4 = getXAxisPoints(categories, opts, config),
        xAxisPoints = _getXAxisPoints4.xAxisPoints,
        xAxiseachSpacing = _getXAxisPoints4.eachSpacing;
    var TotalWidth = xAxiseachSpacing * (xAxisPoints.length - 1);
    var endX = startX + TotalWidth;

    var points = [];
    for (var i = 0; i < config.yAxisSplit; i++) {
        points.push(config.padding + eachSpacing * i);
    }
    points.push(config.padding + eachSpacing * config.yAxisSplit + 2);

    context.save();
    if (opts._scrollDistance_ && opts._scrollDistance_ !== 0) {
        context.translate(opts._scrollDistance_, 0);
    }

    if (opts.yAxis.gridType == 'dash') {
        context.setLineDash([opts.yAxis.dashLength, opts.yAxis.dashLength]);
    }
    context.beginPath();
    context.setStrokeStyle(opts.yAxis.gridColor || "#cccccc");

    context.setLineWidth(1 * opts.pixelRatio);
    points.forEach(function(item, index) {
        context.moveTo(startX, item);
        context.lineTo(endX, item);
    });
    context.closePath();
    context.stroke();
    context.setLineDash([]);

    context.restore();
}

function drawYAxis(series, opts, config, context) {
    if (opts.yAxis.disabled === true) {
        return;
    }

    var _calYAxisData4 = calYAxisData(series, opts, config),
        rangesFormat = _calYAxisData4.rangesFormat;

    var yAxisTotalWidth = config.yAxisWidth + config.yAxisTitleWidth;

    var spacingValid = opts.height - 2 * config.padding - config.xAxisHeight - config.legendHeight;
    var eachSpacing = Math.floor(spacingValid / config.yAxisSplit);
    var startX = config.padding + yAxisTotalWidth;
    var endX = opts.width - config.padding;
    var endY = opts.height - config.padding - config.xAxisHeight - config.legendHeight + config.xAxisTextPadding;

    // set YAxis background
    context.beginPath();
    context.setFillStyle(opts.background || '#ffffff');
    if (opts._scrollDistance_ < 0) {
        context.fillRect(0, 0, startX, endY + config.xAxisHeight);
    }
    context.fillRect(endX, 0, opts.width, endY + config.xAxisHeight);
    context.closePath();
    context.stroke();

    var points = [];
    for (var i = 0; i <= config.yAxisSplit; i++) {
        points.push(config.padding + eachSpacing * i);
    }

    var yAxisFontSize = opts.yAxis.fontSize || config.fontSize;
    rangesFormat.forEach(function(item, index) {
        var pos = points[index] ? points[index] : endY;
        context.beginPath();
        context.setFontSize(yAxisFontSize);
        context.setFillStyle(opts.yAxis.fontColor || '#666666');
        context.fillText(item, config.padding + config.yAxisTitleWidth, pos + yAxisFontSize / 2);
        context.closePath();
        context.stroke();
    });


    if (opts.yAxis.title) {
        drawYAxisTitle(opts.yAxis.title, opts, config, context);
    }
}

function drawLegend(series, opts, config, context) {
    if (opts.legend === false) {
        return;
    }
    // each legend shape width 15px
    // the spacing between shape and text in each legend is the `padding`
    // each legend spacing is the `padding`
    // legend margin top `config.padding`

    var _calLegendData = calLegendData(series, opts, config),
        legendList = _calLegendData.legendList;

    var padding = 5 * opts.pixelRatio;
    var marginTop = 10 * opts.pixelRatio;
    var shapeWidth = 15 * opts.pixelRatio;
    legendList.forEach(function(itemList, listIndex) {
        var width = 0;
        for (let i = 0; i < itemList.length; i++) {
            let item = itemList[i];
            item.name = item.name || 'undefined';
            width += 3 * padding + measureText(item.name) + shapeWidth;
        }
        var startX = (opts.width - width) / 2 + padding;
        var startY = opts.height - config.padding - config.legendHeight + listIndex * (config.fontSize + marginTop) +
            padding + marginTop;

        context.setFontSize(config.fontSize);
        for (let i = 0; i < itemList.length; i++) {
            let item = itemList[i];
            switch (opts.type) {
                case 'line':
                    context.beginPath();
                    context.setLineWidth(1 * opts.pixelRatio);
                    context.setStrokeStyle(item.color);
                    context.setFillStyle(item.color);
                    context.moveTo(startX + 7.5 * opts.pixelRatio, startY + 5 * opts.pixelRatio);
                    context.arc(startX + 7.5 * opts.pixelRatio, startY + 5 * opts.pixelRatio, 6 * opts.pixelRatio, 0, 2 * Math.PI);
                    context.closePath();
                    context.fill();
                    context.stroke();
                    break;
                case 'pie':
                    context.beginPath();
                    context.setLineWidth(1 * opts.pixelRatio);
                    context.setStrokeStyle(item.color);
                    context.setFillStyle(item.color);
                    context.moveTo(startX + 7.5 * opts.pixelRatio, startY + 5 * opts.pixelRatio);
                    context.arc(startX + 7.5 * opts.pixelRatio, startY + 5 * opts.pixelRatio, 6 * opts.pixelRatio, 0, 2 * Math.PI);
                    context.closePath();
                    context.fill();
                    context.stroke();
                    break;
                case 'ring':
                case 'rose':
                    context.beginPath();
                    context.setLineWidth(1 * opts.pixelRatio);
                    context.setStrokeStyle(item.color);
                    context.setFillStyle(item.color);
                    context.moveTo(startX + 7.5 * opts.pixelRatio, startY + 5 * opts.pixelRatio);
                    context.arc(startX + 7.5 * opts.pixelRatio, startY + 5 * opts.pixelRatio, 6 * opts.pixelRatio, 0, 2 * Math.PI);
                    context.closePath();
                    context.fill();
                    context.stroke();
                    break;
                    //圆弧进度图不显示图例
                case 'gauge':
                    break;
                case 'arcbar':
                    break;
                default:
                    context.beginPath();
                    context.setLineWidth(1 * opts.pixelRatio);
                    context.setStrokeStyle(item.color);
                    context.setFillStyle(item.color);
                    context.moveTo(startX, startY);
                    context.fillRect(startX, startY, 15 * opts.pixelRatio, 10 * opts.pixelRatio);
                    context.closePath();
                    context.fill();
                    context.stroke();
            }
            startX += padding + shapeWidth;
            context.beginPath();
            context.setFontSize(config.fontSize);
            context.setFillStyle(opts.extra.legendTextColor || '#333333');
            context.fillText(item.name, startX, startY + 6 * opts.pixelRatio + 3 * opts.pixelRatio);
            context.closePath();
            context.stroke();
            startX += measureText(item.name) + 2 * padding;
        }
    });
}

function drawPieDataPoints(series, opts, config, context) {
    var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;

    var pieOption = opts.extra.pie || {};
    var centerPosition = {
        x: opts.width / 2,
        y: (opts.height - config.legendHeight) / 2
    };
    var radius = Math.min(centerPosition.x - config.pieChartLinePadding - config.pieChartTextPadding - config._pieTextMaxLength_,
        centerPosition.y - config.pieChartLinePadding - config.pieChartTextPadding);
    if (opts.dataLabel) {
        radius -= 10;
    } else {
        radius -= 2 * config.padding;
    }
    series = getPieDataPoints(series, radius, process);

    var activeRadius = config.pieChartLinePadding / 2;

    series = series.map(function(eachSeries) {
        eachSeries._start_ += (pieOption.offsetAngle || 0) * Math.PI / 180;
        return eachSeries;
    });
    series.forEach(function(eachSeries, seriesIndex) {
        if (opts.tooltip) {
            if (opts.tooltip.index == seriesIndex) {
                context.beginPath();
                context.setFillStyle(hexToRgb(eachSeries.color, opts.extra.pie.activeOpacity || 0.5));
                context.moveTo(centerPosition.x, centerPosition.y);
                context.arc(centerPosition.x, centerPosition.y, eachSeries._radius_+activeRadius, eachSeries._start_, eachSeries._start_ + 2 *
                    eachSeries._proportion_ * Math.PI);
                context.closePath();
                context.fill();
            }
        }
        context.beginPath();
        context.setLineWidth(2 * opts.pixelRatio);
        context.lineJoin = "round";
        context.setStrokeStyle('#ffffff');
        context.setFillStyle(eachSeries.color);
        context.moveTo(centerPosition.x, centerPosition.y);
        context.arc(centerPosition.x, centerPosition.y, eachSeries._radius_, eachSeries._start_, eachSeries._start_ + 2 * eachSeries._proportion_ *
            Math.PI);
        context.closePath();
        context.fill();
        if (opts.disablePieStroke !== true) {
            context.stroke();
        }
    });

    if (opts.type === 'ring') {
        var innerPieWidth = radius * 0.6;
        if (typeof opts.extra.pie.ringWidth === 'number' && opts.extra.pie.ringWidth > 0) {
            innerPieWidth = Math.max(0, radius - opts.extra.pie.ringWidth);
        }
        context.beginPath();
        context.setFillStyle(opts.background || '#ffffff');
        context.moveTo(centerPosition.x, centerPosition.y);
        context.arc(centerPosition.x, centerPosition.y, innerPieWidth, 0, 2 * Math.PI);
        context.closePath();
        context.fill();
    }

    if (opts.dataLabel !== false && process === 1) {
        var valid = false;
        for (var i = 0, len = series.length; i < len; i++) {
            if (series[i].data > 0) {
                valid = true;
                break;
            }
        }

        if (valid) {
            drawPieText(series, opts, config, context, radius, centerPosition);
        }
    }

    if (process === 1 && opts.type === 'ring') {
        drawRingTitle(opts, config, context);
    }

    return {
        center: centerPosition,
        radius: radius,
        series: series
    };
}

function drawRoseDataPoints(series, opts, config, context) {
    var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;

    var roseOption = opts.extra.rose || {};
    roseOption.type = roseOption.type || 'area';
    var centerPosition = {
        x: opts.width / 2,
        y: (opts.height - config.legendHeight) / 2
    };
    var radius = Math.min(centerPosition.x - config.pieChartLinePadding - config.pieChartTextPadding - config._pieTextMaxLength_,
        centerPosition.y - config.pieChartLinePadding - config.pieChartTextPadding);
    if (opts.dataLabel) {
        radius -= 10;
    } else {
        radius -= 2 * config.padding;
    }
    var minRadius = roseOption.minRadius || radius*0.5;
    
    series = getRoseDataPoints(series, roseOption.type, minRadius, radius, process);

    var activeRadius = config.pieChartLinePadding / 2;


    series = series.map(function(eachSeries) {
        eachSeries._start_ += (roseOption.offsetAngle || 0) * Math.PI / 180;
        return eachSeries;
    });
    
    series.forEach(function(eachSeries, seriesIndex) {
        if (opts.tooltip) {
            if (opts.tooltip.index == seriesIndex) {
                context.beginPath();
                context.setFillStyle(hexToRgb(eachSeries.color, roseOption.activeOpacity || 0.5));
                context.moveTo(centerPosition.x, centerPosition.y);
                context.arc(centerPosition.x, centerPosition.y, activeRadius+eachSeries._radius_, eachSeries._start_, eachSeries._start_ + 2 * eachSeries._proportion_ * Math.PI);
                context.closePath();
                context.fill();
            }
        }
        context.beginPath();
        context.setLineWidth(2 * opts.pixelRatio);
        context.lineJoin = "round";
        context.setStrokeStyle('#ffffff');
        context.setFillStyle(eachSeries.color);
        context.moveTo(centerPosition.x, centerPosition.y);
        context.arc(centerPosition.x, centerPosition.y, eachSeries._radius_ , eachSeries._start_, eachSeries._start_ + 2 * eachSeries._proportion_ *Math.PI);
        context.closePath();
        context.fill();
        if (opts.disablePieStroke !== true) {
            context.stroke();
        }
    });


    if (opts.dataLabel !== false && process === 1) {
        // fix https://github.com/xiaolin3303/wx-charts/issues/132
        var valid = false;
        for (var i = 0, len = series.length; i < len; i++) {
            if (series[i].data > 0) {
                valid = true;
                break;
            }
        }

        if (valid) {
            drawPieText(series, opts, config, context, radius, centerPosition);
        }
    }

    return {
        center: centerPosition,
        radius: radius,
        series: series
    };
}

function drawArcbarDataPoints(series, opts, config, context) {
    var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;

    var arcbarOption = opts.extra.arcbar || {};
    arcbarOption.startAngle = arcbarOption.startAngle ? arcbarOption.startAngle : 0.75;
    arcbarOption.endAngle = arcbarOption.endAngle ? arcbarOption.endAngle : 0.25;
    arcbarOption.type = arcbarOption.type ? arcbarOption.type : 'default';

    series = getArcbarDataPoints(series, arcbarOption, process);
    var centerPosition = {
        x: opts.width / 2,
        y: (opts.height) / 2
    };
    var radius = Math.min(centerPosition.x, centerPosition.y);

    if (typeof arcbarOption.width === 'number' && arcbarOption.width > 0) {
        arcbarOption.width = arcbarOption.width;
    } else {
        arcbarOption.width = 12 * opts.pixelRatio;
    }
    radius -= config.padding + arcbarOption.width / 2;

    //背景颜色
    context.setLineWidth(arcbarOption.width); // 设置圆环的宽度
    context.setStrokeStyle(arcbarOption.backgroundColor || '#E9E9E9'); // 设置圆环的颜色
    context.setLineCap('round'); // 设置圆环端点的形状
    context.beginPath(); //开始一个新的路径
    if (arcbarOption.type == 'default') {
        context.arc(centerPosition.x, centerPosition.y, radius, arcbarOption.startAngle * Math.PI, arcbarOption.endAngle *
            Math.PI, false);
    } else {
        context.arc(centerPosition.x, centerPosition.y, radius, 0, 2 * Math.PI, false);
    }

    context.stroke(); //对当前路径进行描边

    for (let i = 0; i < series.length; i++) {
        let eachSeries = series[i];
        context.setLineWidth(arcbarOption.width);
        context.setStrokeStyle(eachSeries.color);
        context.setLineCap('round');
        context.beginPath();
        context.arc(centerPosition.x, centerPosition.y, radius, arcbarOption.startAngle * Math.PI, eachSeries._proportion_ *
            Math.PI, false);
        context.stroke();
    }
    drawRingTitle(opts, config, context);
    return {
        center: centerPosition,
        radius: radius,
        series: series
    };
}

function drawGaugeDataPoints(categories, series, opts, config, context) {
    var process = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 1;
    var gaugeOption = opts.extra.gauge || {};
    gaugeOption.startAngle = gaugeOption.startAngle ? gaugeOption.startAngle : 0.75;
    if (gaugeOption.oldAngle == undefined) {
        gaugeOption.oldAngle = gaugeOption.startAngle;
    }
    if (gaugeOption.oldData == undefined) {
        gaugeOption.oldData = 0;
    }
    gaugeOption.endAngle = gaugeOption.endAngle ? gaugeOption.endAngle : 0.25;
    categories = getGaugeAxisPoints(categories, gaugeOption.startAngle, gaugeOption.endAngle);
    var centerPosition = {
        x: opts.width / 2,
        y: (opts.height) / 2
    };
    var radius = Math.min(centerPosition.x, centerPosition.y);
    if (typeof gaugeOption.width === 'number' && gaugeOption.width > 0) {
        gaugeOption.width = gaugeOption.width;
    } else {
        gaugeOption.width = 15 * opts.pixelRatio;
    }
    radius -= config.padding + gaugeOption.width / 2;
    var innerRadius = radius - gaugeOption.width;



    //画背景
    context.setLineWidth(gaugeOption.width);
    context.setLineCap('butt');
    for (let i = 0; i < categories.length; i++) {
        let eachCategories = categories[i];
        context.beginPath();
        context.setStrokeStyle(eachCategories.color);
        context.arc(centerPosition.x, centerPosition.y, radius, eachCategories._startAngle_ * Math.PI, eachCategories._endAngle_ *
            Math.PI, false);
        context.stroke();
    }
    context.save();

    //画刻度线
    let totalAngle = gaugeOption.startAngle - gaugeOption.endAngle + 1;
    gaugeOption.splitLine.fixRadius = gaugeOption.splitLine.fixRadius ? gaugeOption.splitLine.fixRadius : 0;
    gaugeOption.splitLine.splitNumber = gaugeOption.splitLine.splitNumber ? gaugeOption.splitLine.splitNumber : 10;
    gaugeOption.splitLine.width = gaugeOption.splitLine.width ? gaugeOption.splitLine.width : 15 * opts.pixelRatio;
    gaugeOption.splitLine.color = gaugeOption.splitLine.color ? gaugeOption.splitLine.color : '#FFFFFF';
    gaugeOption.splitLine.childNumber = gaugeOption.splitLine.childNumber ? gaugeOption.splitLine.childNumber : 5;
    gaugeOption.splitLine.childWidth = gaugeOption.splitLine.childWidth ? gaugeOption.splitLine.childWidth : 5 * opts.pixelRatio;

    let splitAngle = totalAngle / gaugeOption.splitLine.splitNumber;
    let childAngle = totalAngle / gaugeOption.splitLine.splitNumber / gaugeOption.splitLine.childNumber;
    let startX = -radius - gaugeOption.width * 0.5 - gaugeOption.splitLine.fixRadius;
    let endX = -radius - gaugeOption.width * 0.5 - gaugeOption.splitLine.fixRadius + gaugeOption.splitLine.width;
    let childendX = -radius - gaugeOption.width * 0.5 - gaugeOption.splitLine.fixRadius + gaugeOption.splitLine.childWidth;

    context.translate(centerPosition.x, centerPosition.y);
    context.rotate((gaugeOption.startAngle - 1) * Math.PI);

    for (let i = 0; i < gaugeOption.splitLine.splitNumber + 1; i++) {
        context.beginPath();
        context.setStrokeStyle(gaugeOption.splitLine.color);
        context.setLineWidth(2 * opts.pixelRatio);
        context.moveTo(startX, 0);
        context.lineTo(endX, 0);
        context.stroke();
        context.rotate(splitAngle * Math.PI);
    }
    context.restore();

    context.save();
    context.translate(centerPosition.x, centerPosition.y);
    context.rotate((gaugeOption.startAngle - 1) * Math.PI);

    for (let i = 0; i < gaugeOption.splitLine.splitNumber * gaugeOption.splitLine.childNumber + 1; i++) {
        context.beginPath();
        context.setStrokeStyle(gaugeOption.splitLine.color);
        context.setLineWidth(1 * opts.pixelRatio);
        context.moveTo(startX, 0);
        context.lineTo(childendX, 0);
        context.stroke();
        context.rotate(childAngle * Math.PI);
    }
    context.restore();

    //画指针
    gaugeOption.pointer.width = gaugeOption.pointer.width ? gaugeOption.pointer.width : 15 * opts.pixelRatio;
    if (gaugeOption.pointer.color == undefined || gaugeOption.pointer.color == 'auto') {
        gaugeOption.pointer.color == 'auto';
    } else {
        gaugeOption.pointer.color == gaugeOption.pointer.color;
    }
    series = getGaugeDataPoints(series, categories, gaugeOption, process);

    for (let i = 0; i < series.length; i++) {
        let eachSeries = series[i];
        context.save();
        context.translate(centerPosition.x, centerPosition.y);
        context.rotate((eachSeries._proportion_ - 1) * Math.PI);
        context.beginPath();
        context.setFillStyle(eachSeries.color);
        context.moveTo(gaugeOption.pointer.width, 0);
        context.lineTo(0, -gaugeOption.pointer.width / 2);
        context.lineTo(-innerRadius, 0);
        context.lineTo(0, gaugeOption.pointer.width / 2);
        context.lineTo(gaugeOption.pointer.width, 0);
        context.closePath();
        context.fill();
        context.beginPath();
        context.setFillStyle('#FFFFFF');
        context.arc(0, 0, gaugeOption.pointer.width / 6, 0, 2 * Math.PI, false);
        context.fill();
        context.restore();
    }

    if (opts.dataLabel !== false) {
        drawGaugeLabel(gaugeOption, radius, centerPosition, opts, config, context);
    }

    drawRingTitle(opts, config, context);

    if (process === 1 && opts.type === 'gauge') {
        gaugeOption.oldAngle = series[0]._proportion_;
        gaugeOption.oldData = series[0].data;
    }
    return {
        center: centerPosition,
        radius: radius,
        innerRadius: innerRadius,
        categories: categories,
        totalAngle: totalAngle
    };
}

function drawRadarDataPoints(series, opts, config, context) {
    var process = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 1;

    var radarOption = opts.extra.radar || {};
    var coordinateAngle = getRadarCoordinateSeries(opts.categories.length);
    var centerPosition = {
        x: opts.width / 2,
        y: (opts.height - config.legendHeight) / 2
    };

    var radius = Math.min(centerPosition.x - (getMaxTextListLength(opts.categories) + config.radarLabelTextMargin),
        centerPosition.y - config.radarLabelTextMargin);

    radius -= config.padding;

    // draw grid
    context.beginPath();
    context.setLineWidth(1 * opts.pixelRatio);
    context.setStrokeStyle(radarOption.gridColor || "#cccccc");
    coordinateAngle.forEach(function (angle) {
        var pos = convertCoordinateOrigin(radius * Math.cos(angle), radius * Math.sin(angle), centerPosition);
        context.moveTo(centerPosition.x, centerPosition.y);
        context.lineTo(pos.x, pos.y);
    });
    context.stroke();
    context.closePath();

    // draw split line grid

    var _loop = function _loop(i) {
        var startPos = {};
        context.beginPath();
        context.setLineWidth(1 * opts.pixelRatio);
        context.setStrokeStyle(radarOption.gridColor || "#cccccc");
        coordinateAngle.forEach(function (angle, index) {
            var pos = convertCoordinateOrigin(radius / config.radarGridCount * i * Math.cos(angle), radius / config.radarGridCount * i * Math.sin(angle), centerPosition);
            if (index === 0) {
                startPos = pos;
                context.moveTo(pos.x, pos.y);
            } else {
                context.lineTo(pos.x, pos.y);
            }
        });
        context.lineTo(startPos.x, startPos.y);
        context.stroke();
        context.closePath();
    };

    for (var i = 1; i <= config.radarGridCount; i++) {
        _loop(i);
    }

    var radarDataPoints = getRadarDataPoints(coordinateAngle, centerPosition, radius, series, opts, process);

    radarDataPoints.forEach(function(eachSeries, seriesIndex) {
        // 绘制区域数据
        context.beginPath();
        context.setFillStyle(eachSeries.color);
        context.setGlobalAlpha(0.3);
        eachSeries.data.forEach(function(item, index) {
            if (index === 0) {
                context.moveTo(item.position.x, item.position.y);
            } else {
                context.lineTo(item.position.x, item.position.y);
            }
        });
        context.closePath();
        context.fill();
        context.setGlobalAlpha(1);

        if (opts.dataPointShape !== false) {
            var shape = config.dataPointShape[seriesIndex % config.dataPointShape.length];
            var points = eachSeries.data.map(function(item) {
                return item.position;
            });
            drawPointShape(points, eachSeries.color, shape, context, opts);
        }
    });
    // draw label text
    drawRadarLabel(coordinateAngle, radius, centerPosition, opts, config, context);

    return {
        center: centerPosition,
        radius: radius,
        angleList: coordinateAngle
    };
}

function drawCanvas(opts, context) {
    context.draw();
}

var Timing = {
    easeIn: function easeIn(pos) {
        return Math.pow(pos, 3);
    },

    easeOut: function easeOut(pos) {
        return Math.pow(pos - 1, 3) + 1;
    },

    easeInOut: function easeInOut(pos) {
        if ((pos /= 0.5) < 1) {
            return 0.5 * Math.pow(pos, 3);
        } else {
            return 0.5 * (Math.pow(pos - 2, 3) + 2);
        }
    },

    linear: function linear(pos) {
        return pos;
    }
};

function Animation(opts) {
    this.isStop = false;
    opts.duration = typeof opts.duration === 'undefined' ? 1000 : opts.duration;
    opts.timing = opts.timing || 'linear';

    var delay = 17;

    var createAnimationFrame = function createAnimationFrame() {

        if (typeof requestAnimationFrame !== 'undefined') {
            return requestAnimationFrame;
        } else if (typeof setTimeout !== 'undefined') {

            return function(step, delay) {
                setTimeout(function() {
                    var timeStamp = +new Date();
                    step(timeStamp);
                }, delay);
            };
        } else {

            return function(step) {
                step(null);
            };
        }
    };
    var animationFrame = createAnimationFrame();
    var startTimeStamp = null;

    var _step = function step(timestamp) {

        if (timestamp === null || this.isStop === true) {
            opts.onProcess && opts.onProcess(1);
            opts.onAnimationFinish && opts.onAnimationFinish();
            return;
        }
        if (startTimeStamp === null) {
            startTimeStamp = timestamp;
        }
        if (timestamp - startTimeStamp < opts.duration) {
            var process = (timestamp - startTimeStamp) / opts.duration;
            var timingFunction = Timing[opts.timing];
            process = timingFunction(process);

            opts.onProcess && opts.onProcess(process);
            animationFrame(_step, delay);
        } else {
            opts.onProcess && opts.onProcess(1);
            opts.onAnimationFinish && opts.onAnimationFinish();
        }
    };
    _step = _step.bind(this);
    animationFrame(_step, delay);
}

// stop animation immediately
// and tigger onAnimationFinish
Animation.prototype.stop = function() {
    this.isStop = true;
};

function drawCharts(type, opts, config, context) {
    var _this = this;
    var series = opts.series;
    var categories = opts.categories;
    series = fillSeriesColor(series, config);
    series = fillSeriesType(series, opts);
    let seriesMA = null;
    
    if (type == 'candle') {
        let average = assign({}, opts.extra.candle.average);
        if (average.show) {
            seriesMA = calCandleMA(average.day, average.name, average.color, series[0].data);
            opts.seriesMA = seriesMA;
        }
    }

    var _calLegendData = calLegendData(series, opts, config),
        legendHeight = _calLegendData.legendHeight;

    config.legendHeight = legendHeight;

    var _calYAxisData = calYAxisData(series, opts, config),
        yAxisWidth = _calYAxisData.yAxisWidth;

    config.yAxisWidth = yAxisWidth;
    if (categories && categories.length) {
        var _calCategoriesData = calCategoriesData(categories, opts, config),
            xAxisHeight = _calCategoriesData.xAxisHeight,
            angle = _calCategoriesData.angle;

        config.xAxisHeight = xAxisHeight;
        config._xAxisTextAngle_ = angle;
    }
    if (type === 'pie' || type === 'ring' || type === 'rose') {
        config._pieTextMaxLength_ = opts.dataLabel === false ? 0 : getPieTextMaxLength(series);
    }

    var duration = opts.animation ? opts.duration : 0;
    this.animationInstance && this.animationInstance.stop();

    switch (type) {
        case 'line':
            this.animationInstance = new Animation({
                timing: 'easeIn',
                duration: duration,
                onProcess: function onProcess(process) {
                    context.clearRect(0, 0, opts.width, opts.height);
                    if (opts.rotate) {
                        contextRotate(context, opts);
                    }
                    drawYAxisGrid(categories, opts, config, context);
                    drawXAxis(categories, opts, config, context);
                    var _drawLineDataPoints = drawLineDataPoints(series, opts, config, context, process),
                        xAxisPoints = _drawLineDataPoints.xAxisPoints,
                        calPoints = _drawLineDataPoints.calPoints,
                        eachSpacing = _drawLineDataPoints.eachSpacing;

                    _this.chartData.xAxisPoints = xAxisPoints;
                    _this.chartData.calPoints = calPoints;
                    _this.chartData.eachSpacing = eachSpacing;
                    drawLegend(opts.series, opts, config, context);
                    drawYAxis(series, opts, config, context);
                    drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints);
                    drawCanvas(opts, context);

                },
                onAnimationFinish: function onAnimationFinish() {
                    _this.event.trigger('renderComplete');
                }
            });

            break;
        case 'mix':
            this.animationInstance = new Animation({
                timing: 'easeIn',
                duration: duration,
                onProcess: function onProcess(process) {
                    context.clearRect(0, 0, opts.width, opts.height);
                    if (opts.rotate) {
                        contextRotate(context, opts);
                    }
                    drawYAxisGrid(categories, opts, config, context);
                    drawXAxis(categories, opts, config, context);
                    var _drawMixDataPoints = drawMixDataPoints(series, opts, config, context, process),
                        xAxisPoints = _drawMixDataPoints.xAxisPoints,
                        calPoints = _drawMixDataPoints.calPoints,
                        eachSpacing = _drawMixDataPoints.eachSpacing;

                    _this.chartData.xAxisPoints = xAxisPoints;
                    _this.chartData.calPoints = calPoints;
                    _this.chartData.eachSpacing = eachSpacing;
                    drawLegend(opts.series, opts, config, context);
                    drawYAxis(series, opts, config, context);
                    drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints);
                    drawCanvas(opts, context);
                },
                onAnimationFinish: function onAnimationFinish() {
                    _this.event.trigger('renderComplete');
                }
            });

            break;
        case 'column':
            this.animationInstance = new Animation({
                timing: 'easeIn',
                duration: duration,
                onProcess: function onProcess(process) {
                    context.clearRect(0, 0, opts.width, opts.height);
                    if (opts.rotate) {
                        contextRotate(context, opts);
                    }
                    drawYAxisGrid(categories, opts, config, context);
                    drawXAxis(categories, opts, config, context);
                    var _drawColumnDataPoints = drawColumnDataPoints(series, opts, config, context, process),
                        xAxisPoints = _drawColumnDataPoints.xAxisPoints,
                        calPoints = _drawColumnDataPoints.calPoints,
                        eachSpacing = _drawColumnDataPoints.eachSpacing;
                    _this.chartData.xAxisPoints = xAxisPoints;
                    _this.chartData.calPoints = calPoints;
                    _this.chartData.eachSpacing = eachSpacing;
                    drawLegend(opts.series, opts, config, context);
                    drawYAxis(series, opts, config, context);
                    drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints);
                    drawCanvas(opts, context);
                },
                onAnimationFinish: function onAnimationFinish() {
                    _this.event.trigger('renderComplete');
                }
            });
            break;
        case 'area':
            this.animationInstance = new Animation({
                timing: 'easeIn',
                duration: duration,
                onProcess: function onProcess(process) {
                    context.clearRect(0, 0, opts.width, opts.height);
                    if (opts.rotate) {
                        contextRotate(context, opts);
                    }
                    drawYAxisGrid(categories, opts, config, context);
                    drawXAxis(categories, opts, config, context);
                    var _drawAreaDataPoints = drawAreaDataPoints(series, opts, config, context, process),
                        xAxisPoints = _drawAreaDataPoints.xAxisPoints,
                        calPoints = _drawAreaDataPoints.calPoints,
                        eachSpacing = _drawAreaDataPoints.eachSpacing;

                    _this.chartData.xAxisPoints = xAxisPoints;
                    _this.chartData.calPoints = calPoints;
                    _this.chartData.eachSpacing = eachSpacing;
                    drawLegend(opts.series, opts, config, context);
                    drawYAxis(series, opts, config, context);
                    drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints);

                    drawCanvas(opts, context);
                },
                onAnimationFinish: function onAnimationFinish() {
                    _this.event.trigger('renderComplete');
                }
            });
            break;
        case 'ring':
        case 'pie':
            this.animationInstance = new Animation({
                timing: 'easeInOut',
                duration: duration,
                onProcess: function onProcess(process) {
                    context.clearRect(0, 0, opts.width, opts.height);
                    if (opts.rotate) {
                        contextRotate(context, opts);
                    }
                    _this.chartData.pieData = drawPieDataPoints(series, opts, config, context, process);
                    drawLegend(opts.series, opts, config, context);
                    drawToolTipBridge(opts, config, context, process);
                    drawCanvas(opts, context);
                },
                onAnimationFinish: function onAnimationFinish() {
                    _this.event.trigger('renderComplete');
                }
            });
            break;
        case 'rose':
            this.animationInstance = new Animation({
                timing: 'easeInOut',
                duration: duration,
                onProcess: function onProcess(process) {
                    context.clearRect(0, 0, opts.width, opts.height);
                    if (opts.rotate) {
                        contextRotate(context, opts);
                    }
                    _this.chartData.pieData = drawRoseDataPoints(series, opts, config, context, process);
                    drawLegend(opts.series, opts, config, context);
                    drawToolTipBridge(opts, config, context, process);
                    drawCanvas(opts, context);
                },
                onAnimationFinish: function onAnimationFinish() {
                    _this.event.trigger('renderComplete');
                }
            });
            break;
        case 'radar':
            this.animationInstance = new Animation({
                timing: 'easeInOut',
                duration: duration,
                onProcess: function onProcess(process) {
                    context.clearRect(0, 0, opts.width, opts.height);
                    if (opts.rotate) {
                        contextRotate(context, opts);
                    }
                    _this.chartData.radarData = drawRadarDataPoints(series, opts, config, context, process);
                    drawLegend(opts.series, opts, config, context);
                    drawToolTipBridge(opts, config, context, process);
                    drawCanvas(opts, context);
                },
                onAnimationFinish: function onAnimationFinish() {
                    _this.event.trigger('renderComplete');
                }
            });
            break;
        case 'arcbar':
            this.animationInstance = new Animation({
                timing: 'easeInOut',
                duration: duration,
                onProcess: function onProcess(process) {
                    context.clearRect(0, 0, opts.width, opts.height);
                    if (opts.rotate) {
                        contextRotate(context, opts);
                    }
                    _this.chartData.arcbarData = drawArcbarDataPoints(series, opts, config, context, process);
                    drawCanvas(opts, context);
                },
                onAnimationFinish: function onAnimationFinish() {
                    _this.event.trigger('renderComplete');
                }
            });
            break;
        case 'gauge':
            this.animationInstance = new Animation({
                timing: 'easeInOut',
                duration: duration,
                onProcess: function onProcess(process) {
                    context.clearRect(0, 0, opts.width, opts.height);
                    if (opts.rotate) {
                        contextRotate(context, opts);
                    }
                    _this.chartData.gaugeData = drawGaugeDataPoints(categories, series, opts, config, context, process);
                    drawCanvas(opts, context);
                },
                onAnimationFinish: function onAnimationFinish() {
                    _this.event.trigger('renderComplete');
                }
            });
            break;
        case 'candle':
            this.animationInstance = new Animation({
                timing: 'easeIn',
                duration: duration,
                onProcess: function onProcess(process) {
                    context.clearRect(0, 0, opts.width, opts.height);
                    if (opts.rotate) {
                        contextRotate(context, opts);
                    }
                    drawYAxisGrid(categories, opts, config, context);
                    drawXAxis(categories, opts, config, context);
                    var _drawCandleDataPoints = drawCandleDataPoints(series, seriesMA, opts, config, context, process),
                        xAxisPoints = _drawCandleDataPoints.xAxisPoints,
                        calPoints = _drawCandleDataPoints.calPoints,
                        eachSpacing = _drawCandleDataPoints.eachSpacing;

                    _this.chartData.xAxisPoints = xAxisPoints;
                    _this.chartData.calPoints = calPoints;
                    _this.chartData.eachSpacing = eachSpacing;
                    if (seriesMA) {
                        drawLegend(seriesMA, opts, config, context);
                    } else {
                        drawLegend(opts.series, opts, config, context);
                    }
                    drawYAxis(series, opts, config, context);
                    drawToolTipBridge(opts, config, context, process, eachSpacing, xAxisPoints);
                    drawCanvas(opts, context);
                },
                onAnimationFinish: function onAnimationFinish() {
                    _this.event.trigger('renderComplete');
                }
            });
            break;
    }
}

// simple event implement

function Event() {
    this.events = {};
}

Event.prototype.addEventListener = function(type, listener) {
    this.events[type] = this.events[type] || [];
    this.events[type].push(listener);
};

Event.prototype.trigger = function() {
    for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
        args[_key] = arguments[_key];
    }

    var type = args[0];
    var params = args.slice(1);
    if (!!this.events[type]) {
        this.events[type].forEach(function(listener) {
            try {
                listener.apply(null, params);
            } catch (e) {
                // console.error(e);
            }
        });
    }
};

var Charts = function Charts(opts) {
    opts.pixelRatio = opts.pixelRatio ? opts.pixelRatio : 1;
    opts.fontSize = opts.fontSize ? opts.fontSize * opts.pixelRatio : 13 * opts.pixelRatio;
    opts.title = assign({}, opts.title);
    opts.subtitle = assign({}, opts.subtitle);
    opts.yAxis = assign({}, {
        gridType:'solid',
        dashLength:4 * opts.pixelRatio
    },opts.yAxis);
    opts.xAxis = assign({}, {
        rotateLabel:false,
        type:'calibration',
        gridType:'solid',
        dashLength:4 * opts.pixelRatio,
        scrollAlign:'left'
    },opts.xAxis);
    opts.extra = assign({}, opts.extra);
    opts.rotate = opts.rotate ? true : false;
    opts.animation = opts.animation ? true : false;
    var config$$1 = assign({}, config);
    config$$1.yAxisTitleWidth = opts.yAxis.disabled !== true && opts.yAxis.title ? config$$1.yAxisTitleWidth : 0;
    if (opts.type == 'pie' || opts.type == 'ring' ) {
        config$$1.pieChartLinePadding = opts.dataLabel === false ? 0 : opts.extra.pie.labelWidth*opts.pixelRatio || config$$1.pieChartLinePadding *opts.pixelRatio;
    }
    if (opts.type == 'rose' ) {
        config$$1.pieChartLinePadding = opts.dataLabel === false ? 0 : opts.extra.rose.labelWidth*opts.pixelRatio || config$$1.pieChartLinePadding *opts.pixelRatio;
    }
    config$$1.pieChartTextPadding = opts.dataLabel === false ? 0 : config$$1.pieChartTextPadding * opts.pixelRatio;
    config$$1.yAxisSplit = opts.yAxis.splitNumber ? opts.yAxis.splitNumber : config.yAxisSplit;
    //屏幕旋转
    config$$1.rotate = opts.rotate;
    if (opts.rotate) {
        let tempWidth = opts.width;
        let tempHeight = opts.height;
        opts.width = tempHeight;
        opts.height = tempWidth;
    }

    //适配高分屏
    config$$1.yAxisWidth = config.yAxisWidth * opts.pixelRatio;
    config$$1.xAxisHeight = config.xAxisHeight * opts.pixelRatio;
    if (opts.enableScroll && opts.xAxis.scrollShow) {
        config$$1.xAxisHeight += 6 * opts.pixelRatio;
    }
    config$$1.xAxisLineHeight = config.xAxisLineHeight * opts.pixelRatio;
    config$$1.legendHeight = config.legendHeight * opts.pixelRatio;
    config$$1.padding = config.padding * opts.pixelRatio;
    config$$1.fontSize = opts.fontSize;
    config$$1.titleFontSize = config.titleFontSize * opts.pixelRatio;
    config$$1.subtitleFontSize = config.subtitleFontSize * opts.pixelRatio;
    config$$1.toolTipPadding = config.toolTipPadding * opts.pixelRatio;
    config$$1.toolTipLineHeight = config.toolTipLineHeight * opts.pixelRatio;
    config$$1.columePadding = config.columePadding * opts.pixelRatio;

    this.opts = opts;
    this.config = config$$1;
    opts.$this = opts.$this ? opts.$this : this;
    this.context = uni.createCanvasContext(opts.canvasId, opts.$this);
    /* 兼容原生H5
    this.context = document.getElementById(opts.canvasId).getContext("2d");
    this.context.setStrokeStyle = function(e){ return this.strokeStyle=e; }
    this.context.setLineWidth = function(e){ return this.lineWidth=e; }
    this.context.setLineCap = function(e){ return this.lineCap=e; }
    this.context.setFontSize = function(e){ return this.font=e+"px sans-serif"; }
    this.context.setFillStyle = function(e){ return this.fillStyle=e; }
    this.context.draw = function(){ }
    */
    this.chartData = {};
    this.event = new Event();

    this.scrollOption = {
        currentOffset: 0,
        startTouchX: 0,
        distance: 0,
        lastMoveTime: 0
    };

    //计算右对齐偏移距离
    if (opts.enableScroll && opts.xAxis.scrollAlign == 'right') {
        let _calYAxisData = calYAxisData(opts.series, opts, config$$1),
            yAxisWidth = _calYAxisData.yAxisWidth;
        config$$1.yAxisWidth = yAxisWidth;
        let offsetLeft = 0;
        let _getXAxisPoints0 = getXAxisPoints(opts.categories, opts, config$$1),
            xAxisPoints = _getXAxisPoints0.xAxisPoints,
            startX = _getXAxisPoints0.startX,
            endX = _getXAxisPoints0.endX,
            eachSpacing = _getXAxisPoints0.eachSpacing;
        let totalWidth = eachSpacing * (xAxisPoints.length - 1);
        let screenWidth = endX - startX;
        offsetLeft = screenWidth - totalWidth;
        this.scrollOption = {
            currentOffset: offsetLeft,
            startTouchX: offsetLeft,
            distance: 0,
            lastMoveTime: 0
        };
        opts._scrollDistance_ = offsetLeft;
    }

    drawCharts.call(this, opts.type, opts, config$$1, this.context);
};

Charts.prototype.updateData = function() {
    let data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
    this.opts = assign({}, this.opts, data);
    let scrollPosition = data.scrollPosition || 'current';
    switch (scrollPosition) {
        case 'current':
            this.opts._scrollDistance_ = this.scrollOption.currentOffset;
            break;
        case 'left':
            this.opts._scrollDistance_ = 0;
            this.scrollOption = {
                currentOffset: 0,
                startTouchX: 0,
                distance: 0,
                lastMoveTime: 0
            };
            break;
        case 'right':
            let _calYAxisData = calYAxisData(this.opts.series, this.opts, this.config),
                yAxisWidth = _calYAxisData.yAxisWidth;
            this.config.yAxisWidth = yAxisWidth;
            let offsetLeft = 0;
            let _getXAxisPoints0 = getXAxisPoints(this.opts.categories, this.opts, this.config),
                xAxisPoints = _getXAxisPoints0.xAxisPoints,
                startX = _getXAxisPoints0.startX,
                endX = _getXAxisPoints0.endX,
                eachSpacing = _getXAxisPoints0.eachSpacing;
            let totalWidth = eachSpacing * (xAxisPoints.length - 1);
            let screenWidth = endX - startX;
            offsetLeft = screenWidth - totalWidth;
            this.scrollOption = {
                currentOffset: offsetLeft,
                startTouchX: offsetLeft,
                distance: 0,
                lastMoveTime: 0
            };
            this.opts._scrollDistance_ = offsetLeft;
            break;
    }
    drawCharts.call(this, this.opts.type, this.opts, this.config, this.context);
};

Charts.prototype.zoom = function() {
    var val = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.opts.xAxis.itemCount;
    if (this.opts.enableScroll !== true) {
        // console.log('请启用滚动条后使用!')
        return;
    }
    //当前屏幕中间点
    let centerPoint = Math.round(Math.abs(this.scrollOption.currentOffset) / this.chartData.eachSpacing) + Math.round(
        this.opts.xAxis.itemCount / 2);
    this.opts.animation = false;
    this.opts.xAxis.itemCount = val.itemCount;
    //重新计算x轴偏移距离
    let _calYAxisData = calYAxisData(this.opts.series, this.opts, this.config),
        yAxisWidth = _calYAxisData.yAxisWidth;
    this.config.yAxisWidth = yAxisWidth;
    let offsetLeft = 0;
    let _getXAxisPoints0 = getXAxisPoints(this.opts.categories, this.opts, this.config),
        xAxisPoints = _getXAxisPoints0.xAxisPoints,
        startX = _getXAxisPoints0.startX,
        endX = _getXAxisPoints0.endX,
        eachSpacing = _getXAxisPoints0.eachSpacing;
    let centerLeft = eachSpacing * centerPoint;
    let screenWidth = endX - startX;
    let MaxLeft = screenWidth - eachSpacing * (xAxisPoints.length - 1);
    offsetLeft = screenWidth / 2 - centerLeft;
    if (offsetLeft > 0) {
        offsetLeft = 0;
    }
    if (offsetLeft < MaxLeft) {
        offsetLeft = MaxLeft;
    }
    this.scrollOption = {
        currentOffset: offsetLeft,
        startTouchX: offsetLeft,
        distance: 0,
        lastMoveTime: 0
    };
    this.opts._scrollDistance_ = offsetLeft;

    drawCharts.call(this, this.opts.type, this.opts, this.config, this.context);
};

Charts.prototype.stopAnimation = function() {
    this.animationInstance && this.animationInstance.stop();
};

Charts.prototype.addEventListener = function(type, listener) {
    this.event.addEventListener(type, listener);
};

Charts.prototype.getCurrentDataIndex = function(e) {
    var touches = null;
    if(e.changedTouches){
        touches = e.changedTouches[0];
    }else{
        touches = e.mp.changedTouches[0];
    }
    if (touches) {
        var _touches$ = getTouches(touches, this.opts, e);
        if (this.opts.type === 'pie' || this.opts.type === 'ring' || this.opts.type === 'rose') {
            return findPieChartCurrentIndex({
                x: _touches$.x,
                y: _touches$.y
            }, this.chartData.pieData);
        } else if (this.opts.type === 'radar') {
            return findRadarChartCurrentIndex({
                x: _touches$.x,
                y: _touches$.y
            }, this.chartData.radarData, this.opts.categories.length);
        } else {
            return findCurrentIndex({
                x: _touches$.x,
                y: _touches$.y
            }, this.chartData.xAxisPoints, this.opts, this.config, Math.abs(this.scrollOption.currentOffset));
        }
    }
    return -1;
};

Charts.prototype.showToolTip = function(e) {
    var option = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
    var touches = null;
    if(e.changedTouches){
        touches = e.changedTouches[0];
    }else{
        touches = e.mp.changedTouches[0];
    }
    if(!touches){
        // console.log("touchError");
        return;
    }
    var _touches$ = getTouches(touches, this.opts, e);

    if (this.opts.type === 'line' || this.opts.type === 'area' || this.opts.type === 'column') {
        var index = this.getCurrentDataIndex(e);
        var currentOffset = this.scrollOption.currentOffset;

        var opts = assign({}, this.opts, {
            _scrollDistance_: currentOffset,
            animation: false
        });
        if (index > -1) {

            var seriesData = getSeriesDataItem(this.opts.series, index);
            if (seriesData.length !== 0) {
                var _getToolTipData = getToolTipData(seriesData, this.chartData.calPoints, index, this.opts.categories, option),
                    textList = _getToolTipData.textList,
                    offset = _getToolTipData.offset;
                offset.y = _touches$.y;
                opts.tooltip = {
                    textList: textList,
                    offset: offset,
                    option: option,
                    index: index
                };
            }
        }
        drawCharts.call(this, opts.type, opts, this.config, this.context);
    }
    if (this.opts.type === 'mix') {

        var index = this.getCurrentDataIndex(e);
        var currentOffset = this.scrollOption.currentOffset;

        var opts = assign({}, this.opts, {
            _scrollDistance_: currentOffset,
            animation: false
        });
        if (index > -1) {
            var seriesData = getSeriesDataItem(this.opts.series, index);
            if (seriesData.length !== 0) {
                var _getMixToolTipData = getMixToolTipData(seriesData, this.chartData.calPoints, index, this.opts.categories,option),
                    textList = _getMixToolTipData.textList,
                    offset = _getMixToolTipData.offset;
                offset.y = _touches$.y;
                opts.tooltip = {
                    textList: textList,
                    offset: offset,
                    option: option,
                    index: index
                };
            }
        }
        drawCharts.call(this, opts.type, opts, this.config, this.context);
    }
    if (this.opts.type === 'candle') {

        var index = this.getCurrentDataIndex(e);
        var currentOffset = this.scrollOption.currentOffset;

        var opts = assign({}, this.opts, {
            _scrollDistance_: currentOffset,
            animation: false
        });
        if (index > -1) {
            var seriesData = getSeriesDataItem(this.opts.series, index);
            if (seriesData.length !== 0) {
                var _getToolTipData = getCandleToolTipData(this.opts.series[0].data, seriesData, this.chartData.calPoints, index,this.opts.categories, this.opts.extra.candle, option),
                    textList = _getToolTipData.textList,
                    offset = _getToolTipData.offset;
                offset.y = _touches$.y;
                opts.tooltip = {
                    textList: textList,
                    offset: offset,
                    option: option,
                    index: index
                };
            }
        }
        drawCharts.call(this, opts.type, opts, this.config, this.context);
    }
    if (this.opts.type === 'pie' || this.opts.type === 'ring' || this.opts.type === 'rose') {
        var index = this.getCurrentDataIndex(e);
        var currentOffset = this.scrollOption.currentOffset;

        var opts = assign({}, this.opts, {
            _scrollDistance_: currentOffset,
            animation: false
        });
        if (index > -1) {

            var seriesData = this.opts.series[index];
            var textList = [{
                text: option.format ? option.format(seriesData) : seriesData.name + ': ' + seriesData.data,
                color: seriesData.color
            }];
            var offset = {
                x: _touches$.x,
                y: _touches$.y
            };

            opts.tooltip = {
                textList: textList,
                offset: offset,
                option: option,
                index: index
            };
        }
        drawCharts.call(this, opts.type, opts, this.config, this.context);
    }
    if (this.opts.type === 'radar') {
        var index = this.getCurrentDataIndex(e);
        var currentOffset = this.scrollOption.currentOffset;
    
        var opts = assign({}, this.opts, {
            _scrollDistance_: currentOffset,
            animation: false
        });
        if (index > -1) {
    
            var seriesData = getSeriesDataItem(this.opts.series, index);
            if (seriesData.length !== 0) {
                var textList = seriesData.map(function(item) {
                        return {
                            text: option.format ? option.format(item) : item.name + ': ' + item.data,
                            color: item.color
                        };
                });
                var offset = {
                    x: _touches$.x,
                    y: _touches$.y
                };
                opts.tooltip = {
                    textList: textList,
                    offset: offset,
                    option: option,
                    index: index
                };
            }
        }
        drawCharts.call(this, opts.type, opts, this.config, this.context);
    }
};

Charts.prototype.translate = function(distance) {
    this.scrollOption = {
        currentOffset: distance,
        startTouchX: distance,
        distance: 0,
        lastMoveTime: 0
    };
    let opts = assign({}, this.opts, {
        _scrollDistance_: distance,
        animation: false
    });
    drawCharts.call(this, this.opts.type, opts, this.config, this.context);
};

Charts.prototype.scrollStart = function(e) {
    var touches = null;
    if(e.changedTouches){
        touches = e.changedTouches[0];
    }else{
        touches = e.mp.changedTouches[0];
    }
    var _touches$ = getTouches(touches, this.opts, e);
    if (touches && this.opts.enableScroll === true) {
        this.scrollOption.startTouchX = _touches$.x;
    }
};

Charts.prototype.scroll = function(e) {
    if (this.scrollOption.lastMoveTime === 0) {
        this.scrollOption.lastMoveTime = Date.now();
    }
    let Limit = this.opts.extra.touchMoveLimit || 20;
    let currMoveTime = Date.now();
    let duration = currMoveTime - this.scrollOption.lastMoveTime;
    if (duration < Math.floor(1000 / Limit)) return;

    this.scrollOption.lastMoveTime = currMoveTime;

    var touches = null;
    if(e.changedTouches){
        touches = e.changedTouches[0];
    }else{
        touches = e.mp.changedTouches[0];
    }
    var _touches$ = getTouches(touches, this.opts, e);
    if (touches && this.opts.enableScroll === true) {
        var _distance;
        _distance = _touches$.x - this.scrollOption.startTouchX;
        var currentOffset = this.scrollOption.currentOffset;

        var validDistance = calValidDistance(currentOffset + _distance, this.chartData, this.config, this.opts);

        this.scrollOption.distance = _distance = validDistance - currentOffset;
        var opts = assign({}, this.opts, {
            _scrollDistance_: currentOffset + _distance,
            animation: false
        });
        drawCharts.call(this, opts.type, opts, this.config, this.context);
        return currentOffset + _distance;
    }
};

Charts.prototype.scrollEnd = function(e) {
    if (this.opts.enableScroll === true) {
        var _scrollOption = this.scrollOption,
            currentOffset = _scrollOption.currentOffset,
            distance = _scrollOption.distance;

        this.scrollOption.currentOffset = currentOffset + distance;
        this.scrollOption.distance = 0;
    }
};
if ( typeof module === "object" && typeof module.exports === "object" ) {
    module.exports = Charts;
    //export default Charts;//建议使用nodejs的module导出方式,如报错请使用export方式导出
}
u-charts.min.js
'use strict';var config={yAxisWidth:15,yAxisSplit:5,xAxisHeight:15,xAxisLineHeight:15,legendHeight:15,yAxisTitleWidth:15,padding:12,pixelRatio:1,rotate:!1,columePadding:3,fontSize:13,dataPointShape:["circle","circle","circle","circle"],colors:["#1890ff","#2fc25b","#facc14","#f04864","#8543e0","#90ed7d"],pieChartLinePadding:15,pieChartTextPadding:5,xAxisTextPadding:3,titleColor:"#333333",titleFontSize:20,subtitleColor:"#999999",subtitleFontSize:15,toolTipPadding:3,toolTipBackground:"#000000",toolTipOpacity:.7,toolTipLineHeight:20,radarGridCount:3,radarLabelTextMargin:15,gaugeLabelTextMargin:15};function assign(e){if(null==e)throw new TypeError("Cannot convert undefined or null to object");for(var t,i=Object(e),o=1;o<arguments.length;o++)if(t=arguments[o],null!=t)for(var a in t)Object.prototype.hasOwnProperty.call(t,a)&&(i[a]=t[a]);return i}var util={toFixed:function(e,t){return t=t||2,this.isFloat(e)&&(e=e.toFixed(t)),e},isFloat:function(e){return 0!=e%1},approximatelyEqual:function(e,t){return 1e-10>Math.abs(e-t)},isSameSign:function(e,t){var i=Math.abs;return i(e)===e&&i(t)===t||i(e)!==e&&i(t)!==t},isSameXCoordinateArea:function(e,t){return this.isSameSign(e.x,t.x)},isCollision:function(e,t){e.end={},e.end.x=e.start.x+e.width,e.end.y=e.start.y-e.height,t.end={},t.end.x=t.start.x+t.width,t.end.y=t.start.y-t.height;var i=t.start.x>e.end.x||t.end.x<e.start.x||t.end.y>e.start.y||t.start.y<e.end.y;return!i}};function getH5Offset(t){return t.mp={changedTouches:[]},t.mp.changedTouches.push({x:t.offsetX,y:t.offsetY}),t}function hexToRgb(e,t){var i=/^#?([a-f\d])([a-f\d])([a-f\d])$/i,o=e.replace(i,function(e,t,i,o){return t+t+i+i+o+o}),a=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(o),n=parseInt(a[1],16),l=parseInt(a[2],16),r=parseInt(a[3],16);return"rgba("+n+","+l+","+r+","+t+")"}function findRange(e,t,i){if(isNaN(e))throw new Error("[wxCharts] unvalid series data!");i=i||10,t=t?t:"upper";for(var o=1;1>i;)i*=10,o*=10;for(e="upper"===t?Math.ceil(e*o):Math.floor(e*o);0!=e%i;)"upper"===t?e++:e--;return e/o}function calCandleMA(e,t,i,o){let a=[];for(let n,l=0;l<e.length;l++){n={data:[],name:t[l],color:i[l]};for(let t=0,i=o.length;t<i;t++){if(t<e[l]){n.data.push(null);continue}let i=0;for(let a=0;a<e[l];a++)i+=o[t-a][1];n.data.push(+(i/e[l]).toFixed(3))}a.push(n)}return a}function calValidDistance(e,t,i,o){var a=o.width-i.padding-t.xAxisPoints[0],n=t.eachSpacing*o.categories.length,l=e;return 0<=e?l=0:Math.abs(e)>=n-a&&(l=a-n),l}function isInAngleRange(e,t,i){function o(e){for(;0>e;)e+=2*a;for(;e>2*a;)e-=2*a;return e}var a=Math.PI;return e=o(e),t=o(t),i=o(i),t>i&&(i+=2*a,e<t&&(e+=2*a)),e>=t&&e<=i}function calRotateTranslate(e,t,i){var o=e,a=i-t,n=o+(i-a-o)/1.4142135623730951;n*=-1;return{transX:n,transY:(i-a)*(1.4142135623730951-1)-(i-a-o)/1.4142135623730951}}function createCurveControlPoints(e,t){function i(e,t){return!!(e[t-1]&&e[t+1])&&(e[t].y>=Math.max(e[t-1].y,e[t+1].y)||e[t].y<=Math.min(e[t-1].y,e[t+1].y))}var o=.2,a=.2,n=null,l=null,r=null,s=null;if(1>t?(n=e[0].x+(e[1].x-e[0].x)*o,l=e[0].y+(e[1].y-e[0].y)*o):(n=e[t].x+(e[t+1].x-e[t-1].x)*o,l=e[t].y+(e[t+1].y-e[t-1].y)*o),t>e.length-3){var d=e.length-1;r=e[d].x-(e[d].x-e[d-1].x)*a,s=e[d].y-(e[d].y-e[d-1].y)*a}else r=e[t+1].x-(e[t+2].x-e[t].x)*a,s=e[t+1].y-(e[t+2].y-e[t].y)*a;return i(e,t+1)&&(s=e[t+1].y),i(e,t)&&(l=e[t].y),{ctrA:{x:n,y:l},ctrB:{x:r,y:s}}}function convertCoordinateOrigin(e,t,i){return{x:i.x+e,y:i.y-t}}function avoidCollision(e,t){if(t)for(;util.isCollision(e,t);)0<e.start.x?e.start.y--:0>e.start.x?e.start.y++:0<e.start.y?e.start.y++:e.start.y--;return e}function fillSeriesColor(e,t){var i=0;return e.map(function(e){return e.color||(e.color=t.colors[i],i=(i+1)%t.colors.length),e})}function fillSeriesType(e,t){return e.map(function(e){return e.type||(e.type=t.type),e})}function getDataRange(e,t){var i=0,o=t-e;return i=1e4<=o?1e3:1e3<=o?100:100<=o?10:10<=o?5:1<=o?1:.1<=o?.1:.01,{minRange:findRange(e,"lower",i),maxRange:findRange(t,"upper",i)}}function measureText(e){var t=1<arguments.length&&arguments[1]!==void 0?arguments[1]:config.fontSize;e=e+"";var e=e.split(""),o=0;for(let t,a=0;a<e.length;a++)t=e[a],o+=/[a-zA-Z]/.test(t)?7:/[0-9]/.test(t)?5.5:/\./.test(t)?2.7:/-/.test(t)?3.25:/[\u4e00-\u9fa5]/.test(t)?10:/\(|\)/.test(t)?3.73:/\s/.test(t)?2.5:/%/.test(t)?8:10;return o*t/10}function dataCombine(e){return e.reduce(function(e,t){return(e.data?e.data:e).concat(t.data)},[])}function dataCombineStack(e){for(var t=Array(e[0].data.length),o=0;o<t.length;o++)t[o]=0;for(var a=0;a<e.length;a++)for(var o=0;o<t.length;o++)t[o]+=e[a].data[o];return e.reduce(function(e,i){return(e.data?e.data:e).concat(i.data).concat(t)},[])}function getTouches(t,i,o){let e,a;return t.clientX?i.rotate?(a=i.height-t.clientX*i.pixelRatio,e=(t.pageY-o.currentTarget.offsetTop-i.height/i.pixelRatio/2*(i.pixelRatio-1))*i.pixelRatio):(e=t.clientX*i.pixelRatio,a=(t.pageY-o.currentTarget.offsetTop-i.height/i.pixelRatio/2*(i.pixelRatio-1))*i.pixelRatio):i.rotate?(a=i.height-t.x*i.pixelRatio,e=t.y*i.pixelRatio):(e=t.x*i.pixelRatio,a=t.y*i.pixelRatio),{x:e,y:a}}function getSeriesDataItem(e,t){var i=[];for(let o,a=0;a<e.length;a++)if(o=e[a],null!==o.data[t]&&"undefined"!=typeof o.data[t]){let e={};e.color=o.color,e.type=o.type,e.style=o.style,e.shape=o.shape,e.disableLegend=o.disableLegend,e.name=o.name,e.data=o.format?o.format(o.data[t]):o.data[t],i.push(e)}return i}function getMaxTextListLength(e){var t=e.map(function(e){return measureText(e)});return Math.max.apply(null,t)}function getRadarCoordinateSeries(e){for(var t=Math.PI,o=[],a=0;a<e;a++)o.push(2*t/e*a);return o.map(function(e){return-1*e+t/2})}function getToolTipData(e,t,o,i){var a=4<arguments.length&&void 0!==arguments[4]?arguments[4]:{},n=e.map(function(e){return{text:a.format?a.format(e,i[o]):e.name+": "+e.data,color:e.color}}),l=[],r={x:0,y:0};for(let a,n=0;n<t.length;n++)a=t[n],"undefined"!=typeof a[o]&&null!==a[o]&&l.push(a[o]);for(let a,n=0;n<l.length;n++)a=l[n],r.x=Math.round(a.x),r.y+=a.y;return r.y/=l.length,{textList:n,offset:r}}function getMixToolTipData(e,t,o,i){var a=4<arguments.length&&void 0!==arguments[4]?arguments[4]:{},n=e.map(function(e){return{text:a.format?a.format(e,i[o]):e.name+": "+e.data,color:e.color,disableLegend:!!e.disableLegend}});n=n.filter(function(e){if(!0!==e.disableLegend)return e});var l=[],r={x:0,y:0};for(let a,n=0;n<t.length;n++)a=t[n],"undefined"!=typeof a[o]&&null!==a[o]&&l.push(a[o]);for(let a,n=0;n<l.length;n++)a=l[n],r.x=Math.round(a.x),r.y+=a.y;return r.y/=l.length,{textList:n,offset:r}}function getCandleToolTipData(e,t,o,a,i,n){6<arguments.length&&void 0!==arguments[6]?arguments[6]:{};let l=n.color.upFill,r=n.color.downFill,s=[l,l,r,l];var d=[];let h={text:i[a],color:null};d.push(h),t.map(function(t){0==a&&0>t.data[1]-t.data[0]?s[1]=r:(t.data[0]<e[a-1][1]&&(s[0]=r),t.data[1]<t.data[0]&&(s[1]=r),t.data[2]>e[a-1][1]&&(s[2]=l),t.data[3]<e[a-1][1]&&(s[3]=r));let i={text:"\u5F00\u76D8\uFF1A"+t.data[0],color:s[0]},o={text:"\u6536\u76D8\uFF1A"+t.data[1],color:s[1]},n={text:"\u6700\u4F4E\uFF1A"+t.data[2],color:s[2]},h={text:"\u6700\u9AD8\uFF1A"+t.data[3],color:s[3]};d.push(i,o,n,h)});var c=[],x={x:0,y:0};for(let l,r=0;r<o.length;r++)l=o[r],"undefined"!=typeof l[a]&&null!==l[a]&&c.push(l[a]);return x.x=Math.round(c[0][0].x),{textList:d,offset:x}}function findCurrentIndex(e,t,i,o){var a=4<arguments.length&&void 0!==arguments[4]?arguments[4]:0,n=-1;return isInExactChartArea(e,i,o)&&t.forEach(function(t,i){e.x+a>t&&(n=i)}),n}function isInExactChartArea(e,t,i){return e.x<t.width-i.padding&&e.x>i.padding+i.yAxisWidth+i.yAxisTitleWidth&&e.y>i.padding&&e.y<t.height-i.legendHeight-i.xAxisHeight-i.padding}function findRadarChartCurrentIndex(e,t,i){var o=Math.PI,a=2*o/i,n=-1;if(isInExactPieChartArea(e,t.center,t.radius)){var l=function(e){return 0>e&&(e+=2*o),e>2*o&&(e-=2*o),e},r=Math.atan2(t.center.y-e.y,e.x-t.center.x);r=-1*r,0>r&&(r+=2*o);var s=t.angleList.map(function(e){return e=l(-1*e),e});s.forEach(function(e,t){var i=l(e-a/2),s=l(e+a/2);s<i&&(s+=2*o),(r>=i&&r<=s||r+2*o>=i&&r+2*o<=s)&&(n=t)})}return n}function findPieChartCurrentIndex(e,t){var o=-1;if(isInExactPieChartArea(e,t.center,t.radius)){var a=Math.atan2(t.center.y-e.y,e.x-t.center.x);a=-a;for(var n,l=0,r=t.series.length;l<r;l++)if(n=t.series[l],isInAngleRange(a,n._start_,n._start_+2*n._proportion_*Math.PI)){o=l;break}}return o}function isInExactPieChartArea(e,t,i){var o=Math.pow;return o(e.x-t.x,2)+o(e.y-t.y,2)<=o(i,2)}function splitPoints(e){var t=[],i=[];return e.forEach(function(e){null===e?(i.length&&t.push(i),i=[]):i.push(e)}),i.length&&t.push(i),t}function calLegendData(e,t,i){if(!1===t.legend)return{legendList:[],legendHeight:0};var o=5*t.pixelRatio,a=8*t.pixelRatio,n=15*t.pixelRatio,l=[],r=0,s=[];for(let a=0;a<e.length;a++){let i=e[a],d=3*o+n+measureText(i.name||"undefined");r+d>t.width?(l.push(s),r=d,s=[i]):(r+=d,s.push(i))}return s.length&&l.push(s),{legendList:l,legendHeight:l.length*(i.fontSize+a)+o}}function calCategoriesData(e,t,i){var o={angle:0,xAxisHeight:i.xAxisHeight},a=getXAxisPoints(e,t,i),n=a.eachSpacing,l=e.map(function(e){return measureText(e)}),r=Math.max.apply(this,l);return!0==t.xAxis.rotateLabel&&r+2*i.xAxisTextPadding>n&&(o.angle=45*Math.PI/180,o.xAxisHeight=2*i.xAxisTextPadding+r*Math.sin(o.angle)),o}function getRadarDataPoints(e,t,i,o,a){var n=Math.max,l=5<arguments.length&&void 0!==arguments[5]?arguments[5]:1,r=a.extra.radar||{};r.max=r.max||0;var s=n(r.max,n.apply(null,dataCombine(o))),d=[];for(let n=0;n<o.length;n++){let a=o[n],r={};r.color=a.color,r.data=[],a.data.forEach(function(o,a){let n={};n.angle=e[a],n.proportion=o/s,n.position=convertCoordinateOrigin(i*n.proportion*l*Math.cos(n.angle),i*n.proportion*l*Math.sin(n.angle),t),r.data.push(n)}),d.push(r)}return d}function getPieDataPoints(e,t){var o=2<arguments.length&&arguments[2]!==void 0?arguments[2]:1,a=0,n=0;for(let o,n=0;n<e.length;n++)o=e[n],o.data=null===o.data?0:o.data,a+=o.data;for(let n,l=0;l<e.length;l++)n=e[l],n.data=null===n.data?0:n.data,n._proportion_=0===a?1/e.length*o:n.data/a*o,n._radius_=t;for(let o,a=0;a<e.length;a++)o=e[a],o._start_=n,n+=2*o._proportion_*Math.PI;return e}function getRoseDataPoints(e,t,o,a){var n=4<arguments.length&&arguments[4]!==void 0?arguments[4]:1,l=0,r=0,s=[];for(let n,r=0;r<e.length;r++)n=e[r],n.data=null===n.data?0:n.data,l+=n.data,s.push(n.data);var d=s.pop(),h=s.shift();for(let r,s=0;s<e.length;s++)r=e[s],r.data=null===r.data?0:r.data,r._proportion_=0===l||"area"==t?1/e.length*n:r.data/l*n,r._radius_=o+(a-o)*((r.data-d)/(h-d));for(let n,l=0;l<e.length;l++)n=e[l],n._start_=r,r+=2*n._proportion_*Math.PI;return e}function getArcbarDataPoints(e,t){var o=2<arguments.length&&arguments[2]!==void 0?arguments[2]:1;1==o&&(o=.999999);for(let a,n=0;n<e.length;n++){a=e[n],a.data=null===a.data?0:a.data;let i;i="default"==t.type?t.startAngle-t.endAngle+1:2,a._proportion_=i*a.data*o+t.startAngle,2<=a._proportion_&&(a._proportion_%=2)}return e}function getGaugeAxisPoints(e,t,o){let a=t;for(let n=0;n<e.length;n++)e[n].value=null===e[n].value?0:e[n].value,e[n]._startAngle_=a,e[n]._endAngle_=(t-o+1)*e[n].value+t,2<=e[n]._endAngle_&&(e[n]._endAngle_%=2),a=e[n]._endAngle_;return e}function getGaugeDataPoints(e,t,o){let a=3<arguments.length&&arguments[3]!==void 0?arguments[3]:1;for(let n,l=0;l<e.length;l++){if(n=e[l],n.data=null===n.data?0:n.data,"auto"==o.pointer.color){for(let e=0;e<t.length;e++)if(n.data<=t[e].value){n.color=t[e].color;break}}else n.color=o.pointer.color;let i=o.startAngle-o.endAngle+1;n._endAngle_=i*n.data+o.startAngle,n._oldAngle_=o.oldAngle,o.oldAngle<o.endAngle&&(n._oldAngle_+=2),n._proportion_=n.data>=o.oldData?(n._endAngle_-n._oldAngle_)*a+o.oldAngle:n._oldAngle_-(n._oldAngle_-n._endAngle_)*a,2<=n._proportion_&&(n._proportion_%=2)}return e}function getPieTextMaxLength(e){e=getPieDataPoints(e);let t=0;for(let o=0;o<e.length;o++){let i=e[o],a=i.format?i.format(+i._proportion_.toFixed(2)):util.toFixed(100*i._proportion_)+"%";t=Math.max(t,measureText(a))}return t}function fixColumeData(e,t,i,o,a,n){return e.map(function(e){return null===e?null:(e.width=Math.ceil((t-2*a.columePadding)/i),n.extra.column&&n.extra.column.width&&0<+n.extra.column.width&&(e.width=Math.min(e.width,+n.extra.column.width)),e.x+=(o+.5-i/2)*e.width,e)})}function fixColumeMeterData(e,t,i,o,a,n,l){var r=Math.min;return e.map(function(e){return null===e?null:(e.width=t-2*a.columePadding,e.width=n.extra.column&&n.extra.column.width&&0<+n.extra.column.width?r(e.width,+n.extra.column.width):r(e.width,25),0<o&&(e.width-=2*l),e)})}function fixColumeStackData(e,t,i,o,a,n){var l=Math.min;return e.map(function(e){return null===e?null:(e.width=t-2*a.columePadding,e.width=n.extra.column&&n.extra.column.width&&0<+n.extra.column.width?l(e.width,+n.extra.column.width):l(e.width,25),e)})}function getXAxisPoints(e,t,i){var o=i.yAxisWidth+i.yAxisTitleWidth,a=t.width-2*i.padding-o,n=t.enableScroll?Math.min(t.xAxis.itemCount,e.length):e.length,l=a/n,r=[],s=i.padding+o,d=t.width-i.padding;return e.forEach(function(e,t){r.push(s+t*l)}),!0===t.enableScroll?r.push(s+e.length*l):r.push(d),{xAxisPoints:r,startX:s,endX:d,eachSpacing:l}}function getCandleDataPoints(e,t,i,o,a,n,l){var r=Math.round,s=7<arguments.length&&void 0!==arguments[7]?arguments[7]:1,d=[],h=n.height-2*l.padding-l.xAxisHeight-l.legendHeight;return e.forEach(function(e,c){if(null===e)d.push(null);else{var x=[];e.forEach(function(e){var d={x:o[c]+r(a/2)},p=e.value||e,g=h*(p-t)/(i-t);g*=s,d.y=n.height-l.xAxisHeight-l.legendHeight-r(g)-l.padding,x.push(d)}),d.push(x)}}),d}function getDataPoints(e,t,i,o,a,n,l){var r=Math.round,s=7<arguments.length&&void 0!==arguments[7]?arguments[7]:1,d=[],h=n.height-2*l.padding-l.xAxisHeight-l.legendHeight;return e.forEach(function(e,c){if(null===e)d.push(null);else{var x={color:e.color,x:o[c]+r(a/2)},p=e;"object"==typeof e&&null!=e&&(p=e.value);var g=h*(p-t)/(i-t);g*=s,x.y=n.height-l.xAxisHeight-l.legendHeight-r(g)-l.padding,d.push(x)}}),d}function getStackDataPoints(e,t,i,o,a,n,l,r,s){var d=Math.round,h=9<arguments.length&&void 0!==arguments[9]?arguments[9]:1,c=[],x=n.height-2*l.padding-l.xAxisHeight-l.legendHeight;return e.forEach(function(e,p){if(null===e)c.push(null);else{var g={color:e.color,x:o[p]+d(a/2)};if(0<r){var y=0;for(let e=0;e<=r;e++)y+=s[e].data[p];var f=y-e,u=x*(y-t)/(i-t),m=x*(f-t)/(i-t)}else var y=e,u=x*(y-t)/(i-t),m=0;var T=m;u*=h,T*=h,g.y=n.height-l.xAxisHeight-l.legendHeight-d(u)-l.padding,g.y0=n.height-l.xAxisHeight-l.legendHeight-d(T)-l.padding,c.push(g)}}),c}function getYAxisTextList(e,t,o,a){var n,l=Math.min,r=Math.max;n="stack"==a?dataCombineStack(e):dataCombine(e);var s=[];n=n.filter(function(e){return"object"==typeof e&&null!==e?e.constructor==Array?null!==e:null!==e.value:null!==e}),n.map(function(e){"object"==typeof e?e.constructor==Array?e.map(function(e){s.push(e)}):s.push(e.value):s.push(e)});var d=0,h=0;if(0<s.length&&(d=l.apply(this,s),h=r.apply(this,s)),"number"==typeof t.yAxis.min&&(d=l(t.yAxis.min,d)),"number"==typeof t.yAxis.max&&(h=r(t.yAxis.max,h)),d===h){var c=h||10;h+=c}for(var x=getDataRange(d,h),p=x.minRange,g=x.maxRange,y=[],f=(g-p)/o.yAxisSplit,u=0;u<=o.yAxisSplit;u++)y.push(p+f*u);return y.reverse()}function calYAxisData(e,t,i){var o=assign({},t.extra.column||{type:""}),a=getYAxisTextList(e,t,i,o.type),n=i.yAxisWidth,l=a.map(function(e){return e=util.toFixed(e,2),e=t.yAxis.format?t.yAxis.format(+e):e,n=Math.max(n,measureText(e)+5),e});return!0===t.yAxis.disabled&&(n=0),{rangesFormat:l,ranges:a,yAxisWidth:n}}function calTooltipYAxisData(e,t,i,o){var a=getYAxisTextList(t,i,o),n=i.height-2*o.padding-o.xAxisHeight-o.legendHeight;let l=a[0],r=a[a.length-1],s=o.padding,d=o.padding+n,h=l-(l-r)*(e-s)/(d-s);return h=i.yAxis.format?i.yAxis.format(+h):h,h}function contextRotate(e,t){var i=Math.PI;!0===t.rotateLock?!0!==t._rotate_&&(e.translate(t.height,0),e.rotate(90*i/180),t._rotate_=!0):(e.translate(t.height,0),e.rotate(90*i/180))}function drawPointShape(e,t,i,o,a){o.beginPath(),o.setStrokeStyle("#ffffff"),o.setLineWidth(1*a.pixelRatio),o.setFillStyle(t),"diamond"===i?e.forEach(function(e){null!==e&&(o.moveTo(e.x,e.y-4.5),o.lineTo(e.x-4.5,e.y),o.lineTo(e.x,e.y+4.5),o.lineTo(e.x+4.5,e.y),o.lineTo(e.x,e.y-4.5))}):"circle"===i?e.forEach(function(e){null!==e&&(o.moveTo(e.x+3.5*a.pixelRatio,e.y),o.arc(e.x,e.y,4*a.pixelRatio,0,2*Math.PI,!1))}):"rect"===i?e.forEach(function(e){null!==e&&(o.moveTo(e.x-3.5,e.y-3.5),o.rect(e.x-3.5,e.y-3.5,7,7))}):"triangle"==i&&e.forEach(function(e){null!==e&&(o.moveTo(e.x,e.y-4.5),o.lineTo(e.x-4.5,e.y+4.5),o.lineTo(e.x+4.5,e.y+4.5),o.lineTo(e.x,e.y-4.5))}),o.closePath(),o.fill(),o.stroke()}function drawRingTitle(e,t,i){var o=e.title.fontSize||t.titleFontSize,a=e.subtitle.fontSize||t.subtitleFontSize,n=e.title.name||"",l=e.subtitle.name||"",r=e.title.color||t.titleColor,s=e.subtitle.color||t.subtitleColor,d=n?o:0,h=l?a:0,c=5;if(l){var x=measureText(l,a),p=(e.width-x)/2+(e.subtitle.offsetX||0),g=(e.height-t.legendHeight+a)/2+(e.subtitle.offsetY||0);n&&(g-=(d+c)/2),i.beginPath(),i.setFontSize(a),i.setFillStyle(s),i.fillText(l,p,g),i.closePath(),i.stroke()}if(n){var y=measureText(n,o),f=(e.width-y)/2+(e.title.offsetX||0),u=(e.height-t.legendHeight+o)/2+(e.title.offsetY||0);l&&(u+=(h+c)/2),i.beginPath(),i.setFontSize(o),i.setFillStyle(r),i.fillText(n,f,u),i.closePath(),i.stroke()}}function drawPointText(e,t,i,o){var a=t.data;e.forEach(function(e,n){if(null!==e){o.beginPath(),o.setFontSize(t.textSize||i.fontSize),o.setFillStyle(t.textColor||"#666666");var l=a[n];"object"==typeof a[n]&&null!==a[n]&&(l=a[n].value);var r=t.format?t.format(l):l;o.fillText(r,e.x-measureText(r,t.textSize||i.fontSize)/2,e.y-2),o.closePath(),o.stroke()}})}function drawGaugeLabel(e,t,i,o,a,n){var l=Math.PI;t-=e.width/2+a.gaugeLabelTextMargin;let r=e.startAngle-e.endAngle+1,s=r/e.splitLine.splitNumber,d=e.endNumber-e.startNumber,h=d/e.splitLine.splitNumber,c=e.startAngle,x=e.startNumber;for(let r=0;r<e.splitLine.splitNumber+1;r++){var p={x:t*Math.cos(c*l),y:t*Math.sin(c*l)},g=e.labelFormat?e.labelFormat(x):x;p.x+=i.x-measureText(g)/2,p.y+=i.y;var y=p.x,f=p.y;n.beginPath(),n.setFontSize(a.fontSize),n.setFillStyle(e.labelColor||"#666666"),n.fillText(g,y,f+a.fontSize/2),n.closePath(),n.stroke(),c+=s,2<=c&&(c%=2),x+=h}}function drawRadarLabel(e,t,i,o,a,n){var l=o.extra.radar||{};t+=a.radarLabelTextMargin,e.forEach(function(e,r){var s={x:t*Math.cos(e),y:t*Math.sin(e)},d=convertCoordinateOrigin(s.x,s.y,i),h=d.x,c=d.y;util.approximatelyEqual(s.x,0)?h-=measureText(o.categories[r]||"")/2:0>s.x&&(h-=measureText(o.categories[r]||"")),n.beginPath(),n.setFontSize(a.fontSize),n.setFillStyle(l.labelColor||"#666666"),n.fillText(o.categories[r]||"",h,c+a.fontSize/2),n.closePath(),n.stroke()})}function drawPieText(e,t,o,a,i,n){var l=Math.cos,r=Math.sin,s=Math.min,d=Math.max,h=Math.PI,c=o.pieChartLinePadding,x=[],p=null,g=e.map(function(e){var t=2*h-(e._start_+2*h*e._proportion_/2),i=e.format?e.format(+e._proportion_.toFixed(2)):util.toFixed(100*e._proportion_)+"%",o=e.color,a=e._radius_;return{arc:t,text:i,color:o,radius:a,textColor:e.textColor,textSize:e.textSize}});for(let h=0;h<g.length;h++){let e=g[h],t=l(e.arc)*(e.radius+c),i=r(e.arc)*(e.radius+c),a=l(e.arc)*e.radius,n=r(e.arc)*e.radius,y=0<=t?t+o.pieChartTextPadding:t-o.pieChartTextPadding,f=i,u=measureText(e.text),m=f;p&&util.isSameXCoordinateArea(p.start,{x:y})&&(0<y?m=s(f,p.start.y):0>t?m=d(f,p.start.y):0<f?m=d(f,p.start.y):m=s(f,p.start.y)),0>y&&(y-=u);let T={lineStart:{x:a,y:n},lineEnd:{x:t,y:i},start:{x:y,y:m},width:u,height:o.fontSize,text:e.text,color:e.color,textColor:e.textColor,textSize:e.textSize};p=avoidCollision(T,p),x.push(p)}for(let l=0;l<x.length;l++){let e=x[l],i=convertCoordinateOrigin(e.lineStart.x,e.lineStart.y,n),r=convertCoordinateOrigin(e.lineEnd.x,e.lineEnd.y,n),s=convertCoordinateOrigin(e.start.x,e.start.y,n);a.setLineWidth(1*t.pixelRatio),a.setFontSize(o.fontSize),a.beginPath(),a.setStrokeStyle(e.color),a.setFillStyle(e.color),a.moveTo(i.x,i.y);let d=0>e.start.x?s.x+e.width:s.x,c=0>e.start.x?s.x-5:s.x+5;a.quadraticCurveTo(r.x,r.y,d,s.y),a.moveTo(i.x,i.y),a.stroke(),a.closePath(),a.beginPath(),a.moveTo(s.x+e.width,s.y),a.arc(d,s.y,2,0,2*h),a.closePath(),a.fill(),a.beginPath(),a.setFontSize(e.textSize||o.fontSize),a.setFillStyle(e.textColor||"#666666"),a.fillText(e.text,c,s.y+3),a.closePath(),a.stroke(),a.closePath()}}function drawToolTipSplitLine(e,t,i,o){var a=t.extra.tooltip||{};a.gridType=null==a.gridType?"solid":a.gridType,a.dashLength=null==a.dashLength?4:a.dashLength;var n=i.padding,l=t.height-i.padding-i.xAxisHeight-i.legendHeight;if("dash"==a.gridType&&o.setLineDash([a.dashLength,a.dashLength]),o.beginPath(),o.setStrokeStyle(a.gridColor||"#cccccc"),o.setLineWidth(1*t.pixelRatio),o.moveTo(e,n),o.lineTo(e,l),o.closePath(),o.stroke(),o.setLineDash([]),a.xAxisLabel){let n=t.categories[t.tooltip.index];o.setFontSize(i.fontSize);let r=o.measureText(n).width,s=e-i.toolTipPadding-.5*r,d=l;o.beginPath(),o.setFillStyle(hexToRgb(a.labelBgColor||i.toolTipBackground,a.labelBgOpacity||i.toolTipOpacity)),o.setStrokeStyle(a.labelBgColor||i.toolTipBackground),o.setLineWidth(1*t.pixelRatio),o.rect(s,d,r+2*i.toolTipPadding,i.fontSize+2*i.toolTipPadding),o.closePath(),o.stroke(),o.fill(),o.beginPath(),o.setFontSize(i.fontSize),o.setFillStyle(a.labelFontColor||i.fontColor),o.fillText(n,s+2*i.toolTipPadding,d+i.toolTipPadding+i.fontSize),o.closePath(),o.stroke()}}function drawToolTipHorizentalLine(e,t,i,o){var a=e.extra.tooltip||{};a.gridType=null==a.gridType?"solid":a.gridType,a.dashLength=null==a.dashLength?4:a.dashLength;var n=t.padding+t.yAxisWidth+t.yAxisTitleWidth,l=e.width-t.padding;if("dash"==a.gridType&&i.setLineDash([a.dashLength,a.dashLength]),i.beginPath(),i.setStrokeStyle(a.gridColor||"#cccccc"),i.setLineWidth(1*e.pixelRatio),i.moveTo(n,e.tooltip.offset.y),i.lineTo(l,e.tooltip.offset.y),i.closePath(),i.stroke(),i.setLineDash([]),a.yAxisLabel){let l=calTooltipYAxisData(e.tooltip.offset.y,e.series,e,t,o);i.setFontSize(t.fontSize);let r=i.measureText(l).width,s=n-2*t.toolTipPadding-r,d=e.tooltip.offset.y;i.beginPath(),i.setFillStyle(hexToRgb(a.labelBgColor||t.toolTipBackground,a.labelBgOpacity||t.toolTipOpacity)),i.setStrokeStyle(a.labelBgColor||t.toolTipBackground),i.setLineWidth(1*e.pixelRatio),i.rect(s,d-.5*t.fontSize-t.toolTipPadding,r+2*t.toolTipPadding,t.fontSize+2*t.toolTipPadding),i.closePath(),i.stroke(),i.fill(),i.beginPath(),i.setFontSize(t.fontSize),i.setFillStyle(a.labelFontColor||t.fontColor),i.fillText(l,s+t.toolTipPadding,d+.5*t.fontSize),i.closePath(),i.stroke()}}function drawToolTipSplitArea(e,t,i,o,a){var n=t.extra.tooltip||{activeBgColor:"#000000",activeBgOpacity:.08};n.activeBgColor=n.activeBgColor?n.activeBgColor:"#000000",n.activeBgOpacity=n.activeBgOpacity?n.activeBgOpacity:.08;var l=i.padding,r=t.height-i.padding-i.xAxisHeight-i.legendHeight;o.beginPath(),o.setFillStyle(hexToRgb(n.activeBgColor,n.activeBgOpacity)),o.rect(e-a/2,l,a,r-l),o.closePath(),o.fill()}function drawToolTip(e,t,i,o,a){var n=Math.round,l=i.extra.tooltip||{bgColor:"#000000",bgOpacity:.7,fontColor:"#FFFFFF"};l.bgColor=l.bgColor?l.bgColor:"#000000",l.bgOpacity=l.bgOpacity?l.bgOpacity:.7,l.fontColor=l.fontColor?l.fontColor:"#FFFFFF";var r=4*i.pixelRatio,s=5*i.pixelRatio,d=8*i.pixelRatio,h=!1;("line"==i.type||"area"==i.type||"candle"==i.type||"mix"==i.type)&&drawToolTipSplitLine(i.tooltip.offset.x,i,o,a),t=assign({x:0,y:0},t),t.y-=8*i.pixelRatio;var c=e.map(function(e){return measureText(e.text)}),x=r+s+4*o.toolTipPadding+Math.max.apply(null,c),p=2*o.toolTipPadding+e.length*o.toolTipLineHeight;t.x-Math.abs(i._scrollDistance_)+d+x>i.width&&(h=!0),a.beginPath(),a.setFillStyle(hexToRgb(l.bgColor||o.toolTipBackground,l.bgOpacity||o.toolTipOpacity)),h?(a.moveTo(t.x,t.y+10*i.pixelRatio),a.lineTo(t.x-d,t.y+10*i.pixelRatio-5*i.pixelRatio),a.lineTo(t.x-d,t.y),a.lineTo(t.x-d-n(x),t.y),a.lineTo(t.x-d-n(x),t.y+p),a.lineTo(t.x-d,t.y+p),a.lineTo(t.x-d,t.y+10*i.pixelRatio+5*i.pixelRatio),a.lineTo(t.x,t.y+10*i.pixelRatio)):(a.moveTo(t.x,t.y+10*i.pixelRatio),a.lineTo(t.x+d,t.y+10*i.pixelRatio-5*i.pixelRatio),a.lineTo(t.x+d,t.y),a.lineTo(t.x+d+n(x),t.y),a.lineTo(t.x+d+n(x),t.y+p),a.lineTo(t.x+d,t.y+p),a.lineTo(t.x+d,t.y+10*i.pixelRatio+5*i.pixelRatio),a.lineTo(t.x,t.y+10*i.pixelRatio)),a.closePath(),a.fill(),e.forEach(function(e,i){if(null!==e.color){a.beginPath(),a.setFillStyle(e.color);var n=t.x+d+2*o.toolTipPadding,l=t.y+(o.toolTipLineHeight-o.fontSize)/2+o.toolTipLineHeight*i+o.toolTipPadding+1;h&&(n=t.x-x-d+2*o.toolTipPadding),a.fillRect(n,l,r,o.fontSize),a.closePath()}}),e.forEach(function(e,i){var n=t.x+d+2*o.toolTipPadding+r+s;h&&(n=t.x-x-d+2*o.toolTipPadding+ +r+s);var c=t.y+(o.toolTipLineHeight-o.fontSize)/2+o.toolTipLineHeight*i+o.toolTipPadding;a.beginPath(),a.setFontSize(o.fontSize),a.setFillStyle(l.fontColor),a.fillText(e.text,n,c+o.fontSize),a.closePath(),a.stroke()})}function drawYAxisTitle(e,t,i,o){var a=i.xAxisHeight+(t.height-i.xAxisHeight-measureText(e))/2;o.save(),o.beginPath(),o.setFontSize(i.fontSize),o.setFillStyle(t.yAxis.titleFontColor||"#333333"),o.translate(0,t.height),o.rotate(-90*Math.PI/180),o.fillText(e,a,i.padding+.5*i.fontSize),o.closePath(),o.stroke(),o.restore()}function drawColumnDataPoints(e,t,i,o){var a=4<arguments.length&&void 0!==arguments[4]?arguments[4]:1,n=t.extra.column||{type:{},meter:{}};n.type=null==n.type?"group":n.type,n.meter=n.meter||{},n.meter.border=null==n.meter.border?4:n.meter.border,n.meter.fillColor=null==n.meter.fillColor?"#FFFFFF":n.meter.fillColor;var l=calYAxisData(e,t,i),r=l.ranges,s=getXAxisPoints(t.categories,t,i),d=s.xAxisPoints,h=s.eachSpacing,c=r.pop(),x=r.shift(),p=[];return o.save(),t._scrollDistance_&&0!==t._scrollDistance_&&!0===t.enableScroll&&o.translate(t._scrollDistance_,0),t.tooltip&&t.tooltip.textList&&t.tooltip.textList.length&&1===a&&drawToolTipSplitArea(t.tooltip.offset.x,t,i,o,h),e.forEach(function(l,r){var s=l.data;switch(n.type){case"group":var g=getDataPoints(s,c,x,d,h,t,i,a),y=getStackDataPoints(s,c,x,d,h,t,i,r,e,a);p.push(y),g=fixColumeData(g,h,e.length,r,i,t),g.forEach(function(e){if(null!==e){o.beginPath(),o.setFillStyle(e.color||l.color);var a=e.x-e.width/2+1,n=t.height-e.y-i.padding-i.xAxisHeight-i.legendHeight;o.moveTo(a,e.y),o.fillRect(a,e.y,e.width-2,n),o.closePath(),o.fill()}});break;case"stack":var g=getStackDataPoints(s,c,x,d,h,t,i,r,e,a);p.push(g),g=fixColumeStackData(g,h,e.length,r,i,t,e),g.forEach(function(e){if(null!==e){o.beginPath(),o.setFillStyle(e.color||l.color);var a=e.x-e.width/2+1,n=t.height-e.y-i.padding-i.xAxisHeight-i.legendHeight,s=t.height-e.y0-i.padding-i.xAxisHeight-i.legendHeight;0<r&&(n-=s),o.moveTo(a,e.y),o.fillRect(a,e.y,e.width-2,n),o.closePath(),o.fill()}});break;case"meter":var g=getDataPoints(s,c,x,d,h,t,i,a);p.push(g),g=fixColumeMeterData(g,h,e.length,r,i,t,n.meter.border),0==r?g.forEach(function(e){if(null!==e){o.beginPath(),o.setFillStyle(n.meter.fillColor);var a=e.x-e.width/2,r=t.height-e.y-i.padding-i.xAxisHeight-i.legendHeight;o.moveTo(a,e.y),o.fillRect(a,e.y,e.width,r),o.closePath(),o.fill(),0<n.meter.border&&(o.beginPath(),o.setStrokeStyle(l.color),o.setLineWidth(n.meter.border*t.pixelRatio),o.moveTo(a+.5*n.meter.border,e.y+r),o.lineTo(a+.5*n.meter.border,e.y+.5*n.meter.border),o.lineTo(a+e.width-.5*n.meter.border,e.y+.5*n.meter.border),o.lineTo(a+e.width-.5*n.meter.border,e.y+r),o.stroke())}}):g.forEach(function(e){if(null!==e){o.beginPath(),o.setFillStyle(e.color||l.color);var a=e.x-e.width/2,n=t.height-e.y-i.padding-i.xAxisHeight-i.legendHeight;o.moveTo(a,e.y),o.fillRect(a,e.y,e.width,n),o.closePath(),o.fill()}});}}),!1!==t.dataLabel&&1===a&&e.forEach(function(l,r){var s=l.data;switch(n.type){case"group":var p=getDataPoints(s,c,x,d,h,t,i,a);p=fixColumeData(p,h,e.length,r,i,t),drawPointText(p,l,i,o);break;case"stack":var p=getStackDataPoints(s,c,x,d,h,t,i,r,e,a);drawPointText(p,l,i,o);break;case"meter":var p=getDataPoints(s,c,x,d,h,t,i,a);drawPointText(p,l,i,o);}}),o.restore(),{xAxisPoints:d,calPoints:p,eachSpacing:h}}function drawCandleDataPoints(e,t,i,o,a){var n=5<arguments.length&&void 0!==arguments[5]?arguments[5]:1,l=i.extra.candle||{color:{},average:{}};l.color.upLine=l.color.upLine?l.color.upLine:"#f04864",l.color.upFill=l.color.upFill?l.color.upFill:"#f04864",l.color.downLine=l.color.downLine?l.color.downLine:"#2fc25b",l.color.downFill=l.color.downFill?l.color.downFill:"#2fc25b",l.average.show=!0===l.average.show,l.average.name=l.average.name?l.average.name:[],l.average.day=l.average.day?l.average.day:[],l.average.color=l.average.color?l.average.color:["#1890ff","#2fc25b","#facc14","#f04864","#8543e0","#90ed7d"],i.extra.candle=l;var r=calYAxisData(e,i,o),s=r.ranges,d=getXAxisPoints(i.categories,i,o),h=d.xAxisPoints,c=d.eachSpacing,x=s.pop(),p=s.shift(),g=[];return a.save(),i._scrollDistance_&&0!==i._scrollDistance_&&!0===i.enableScroll&&a.translate(i._scrollDistance_,0),l.average.show&&t.forEach(function(e){var t=e.data,l=getDataPoints(t,x,p,h,c,i,o,n),r=splitPoints(l);r.forEach(function(t){a.beginPath(),a.setStrokeStyle(e.color),a.setLineWidth(1),1===t.length?(a.moveTo(t[0].x,t[0].y),a.arc(t[0].x,t[0].y,1,0,2*Math.PI)):(a.moveTo(t[0].x,t[0].y),t.forEach(function(e,i){if(0<i){var o=createCurveControlPoints(t,i-1);a.bezierCurveTo(o.ctrA.x,o.ctrA.y,o.ctrB.x,o.ctrB.y,e.x,e.y)}}),a.moveTo(t[0].x,t[0].y)),a.closePath(),a.stroke()})}),e.forEach(function(e){var t=e.data,r=getCandleDataPoints(t,x,p,h,c,i,o,n);g.push(r);var s=splitPoints(r);s=s[0],s.forEach(function(e,o){a.beginPath(),0<t[o][1]-t[o][0]?(a.setStrokeStyle(l.color.upLine),a.setFillStyle(l.color.upFill),a.setLineWidth(1*i.pixelRatio),a.moveTo(e[3].x,e[3].y),a.lineTo(e[1].x,e[1].y),a.lineTo(e[1].x-c/4,e[1].y),a.lineTo(e[0].x-c/4,e[0].y),a.lineTo(e[0].x,e[0].y),a.lineTo(e[2].x,e[2].y),a.lineTo(e[0].x,e[0].y),a.lineTo(e[0].x+c/4,e[0].y),a.lineTo(e[1].x+c/4,e[1].y),a.lineTo(e[1].x,e[1].y),a.moveTo(e[3].x,e[3].y)):(a.setStrokeStyle(l.color.downLine),a.setFillStyle(l.color.downFill),a.setLineWidth(1*i.pixelRatio),a.moveTo(e[3].x,e[3].y),a.lineTo(e[0].x,e[0].y),a.lineTo(e[0].x-c/4,e[0].y),a.lineTo(e[1].x-c/4,e[1].y),a.lineTo(e[1].x,e[1].y),a.lineTo(e[2].x,e[2].y),a.lineTo(e[1].x,e[1].y),a.lineTo(e[1].x+c/4,e[1].y),a.lineTo(e[0].x+c/4,e[0].y),a.lineTo(e[0].x,e[0].y),a.moveTo(e[3].x,e[3].y)),a.closePath(),a.fill(),a.stroke()})}),a.restore(),{xAxisPoints:h,calPoints:g,eachSpacing:c}}function drawAreaDataPoints(e,t,i,o){var a=4<arguments.length&&void 0!==arguments[4]?arguments[4]:1,n=t.extra.area||{type:"straight",opacity:.5,addLine:!1,width:2};n.type=n.type?n.type:"straight",n.opacity=n.opacity?n.opacity:.2,n.addLine=!0==n.addLine,n.width=n.width?n.width:2;var l=calYAxisData(e,t,i),r=l.ranges,s=getXAxisPoints(t.categories,t,i),d=s.xAxisPoints,h=s.eachSpacing,c=r.pop(),x=r.shift(),p=t.height-i.padding-i.xAxisHeight-i.legendHeight,g=[];return o.save(),t._scrollDistance_&&0!==t._scrollDistance_&&!0===t.enableScroll&&o.translate(t._scrollDistance_,0),t.tooltip&&t.tooltip.textList&&t.tooltip.textList.length&&1===a&&drawToolTipSplitLine(t.tooltip.offset.x,t,i,o),e.forEach(function(e,l){let r=e.data,s=getDataPoints(r,c,x,d,h,t,i,a);g.push(s);let y=splitPoints(s);for(let a,r=0;r<y.length;r++){if(a=y[r],o.beginPath(),o.setStrokeStyle(hexToRgb(e.color,n.opacity)),o.setFillStyle(hexToRgb(e.color,n.opacity)),o.setLineWidth(n.width*t.pixelRatio),1<a.length){let e=a[0],t=a[a.length-1];o.moveTo(e.x,e.y),"curve"===n.type?a.forEach(function(e,t){if(0<t){let i=createCurveControlPoints(a,t-1);o.bezierCurveTo(i.ctrA.x,i.ctrA.y,i.ctrB.x,i.ctrB.y,e.x,e.y)}}):a.forEach(function(e,t){0<t&&o.lineTo(e.x,e.y)}),o.lineTo(t.x,p),o.lineTo(e.x,p),o.lineTo(e.x,e.y)}else{let e=a[0];o.moveTo(e.x-h/2,e.y),o.lineTo(e.x+h/2,e.y),o.lineTo(e.x+h/2,p),o.lineTo(e.x-h/2,p),o.moveTo(e.x-h/2,e.y)}o.closePath(),o.fill(),n.addLine&&(o.beginPath(),o.setStrokeStyle(e.color),o.setLineWidth(n.width*t.pixelRatio),1===a.length?(o.moveTo(a[0].x,a[0].y),o.arc(a[0].x,a[0].y,1,0,2*Math.PI)):(o.moveTo(a[0].x,a[0].y),"curve"===n.type?a.forEach(function(e,t){if(0<t){let i=createCurveControlPoints(a,t-1);o.bezierCurveTo(i.ctrA.x,i.ctrA.y,i.ctrB.x,i.ctrB.y,e.x,e.y)}}):a.forEach(function(e,t){0<t&&o.lineTo(e.x,e.y)}),o.moveTo(a[0].x,a[0].y)),o.closePath(),o.stroke())}if(!1!==t.dataPointShape){var f=i.dataPointShape[l%i.dataPointShape.length];drawPointShape(s,e.color,f,o,t)}}),!1!==t.dataLabel&&1===a&&e.forEach(function(e){var n=e.data,l=getDataPoints(n,c,x,d,h,t,i,a);drawPointText(l,e,i,o)}),o.restore(),{xAxisPoints:d,calPoints:g,eachSpacing:h}}function drawLineDataPoints(e,t,i,o){var a=4<arguments.length&&void 0!==arguments[4]?arguments[4]:1,n=t.extra.line||{type:"straight",width:2};n.type=n.type?n.type:"straight",n.width=n.width?n.width:2;var l=calYAxisData(e,t,i),r=l.ranges,s=getXAxisPoints(t.categories,t,i),d=s.xAxisPoints,h=s.eachSpacing,c=r.pop(),x=r.shift(),p=[];return o.save(),t._scrollDistance_&&0!==t._scrollDistance_&&!0===t.enableScroll&&o.translate(t._scrollDistance_,0),t.tooltip&&t.tooltip.textList&&t.tooltip.textList.length&&1===a&&drawToolTipSplitLine(t.tooltip.offset.x,t,i,o),e.forEach(function(e,l){var r=e.data,s=getDataPoints(r,c,x,d,h,t,i,a);p.push(s);var g=splitPoints(s);if(g.forEach(function(i){o.beginPath(),o.setStrokeStyle(e.color),o.setLineWidth(n.width*t.pixelRatio),1===i.length?(o.moveTo(i[0].x,i[0].y),o.arc(i[0].x,i[0].y,1,0,2*Math.PI)):(o.moveTo(i[0].x,i[0].y),"curve"===n.type?i.forEach(function(e,t){if(0<t){var a=createCurveControlPoints(i,t-1);o.bezierCurveTo(a.ctrA.x,a.ctrA.y,a.ctrB.x,a.ctrB.y,e.x,e.y)}}):i.forEach(function(e,t){0<t&&o.lineTo(e.x,e.y)}),o.moveTo(i[0].x,i[0].y)),o.closePath(),o.stroke()}),!1!==t.dataPointShape){var y=i.dataPointShape[l%i.dataPointShape.length];drawPointShape(s,e.color,y,o,t)}}),!1!==t.dataLabel&&1===a&&e.forEach(function(e){var n=e.data,l=getDataPoints(n,c,x,d,h,t,i,a);drawPointText(l,e,i,o)}),o.restore(),{xAxisPoints:d,calPoints:p,eachSpacing:h}}function drawMixDataPoints(e,t,i,o){var a=Math.PI,n=4<arguments.length&&void 0!==arguments[4]?arguments[4]:1,l=calYAxisData(e,t,i),r=l.ranges,s=getXAxisPoints(t.categories,t,i),d=s.xAxisPoints,h=s.eachSpacing,c=r.pop(),x=r.shift(),p=t.height-i.padding-i.xAxisHeight-i.legendHeight,g=[],y=0,f=0;if(e.forEach(function(e){"column"==e.type&&(f+=1)}),o.save(),t._scrollDistance_&&0!==t._scrollDistance_&&!0===t.enableScroll&&o.translate(t._scrollDistance_,0),t.tooltip&&t.tooltip.textList&&t.tooltip.textList.length&&1===n&&drawToolTipSplitLine(t.tooltip.offset.x,t,i,o),e.forEach(function(e,l){var r=e.data,s=getDataPoints(r,c,x,d,h,t,i,n);if(g.push(s),"column"==e.type&&(s=fixColumeData(s,h,f,y,i,t),s.forEach(function(a){if(null!==a){o.beginPath(),o.setFillStyle(a.color||e.color);var n=a.x-a.width/2+1,l=t.height-a.y-i.padding-i.xAxisHeight-i.legendHeight;o.moveTo(n,a.y),o.rect(n,a.y,a.width-2,l),o.closePath(),o.fill()}}),y+=1),"area"==e.type){let a=splitPoints(s);for(let n,l=0;l<a.length;l++){if(n=a[l],o.beginPath(),o.setStrokeStyle(e.color),o.setFillStyle(e.color),o.setGlobalAlpha(.2),o.setLineWidth(2*t.pixelRatio),1<n.length){var u=n[0];let t=n[n.length-1];o.moveTo(u.x,u.y),"curve"===e.style?n.forEach(function(e,t){if(0<t){var i=createCurveControlPoints(n,t-1);o.bezierCurveTo(i.ctrA.x,i.ctrA.y,i.ctrB.x,i.ctrB.y,e.x,e.y)}}):n.forEach(function(e,t){0<t&&o.lineTo(e.x,e.y)}),o.lineTo(t.x,p),o.lineTo(u.x,p),o.lineTo(u.x,u.y)}else{let e=n[0];o.moveTo(e.x-h/2,e.y),o.lineTo(e.x+h/2,e.y),o.lineTo(e.x+h/2,p),o.lineTo(e.x-h/2,p),o.moveTo(e.x-h/2,e.y)}o.closePath(),o.fill(),o.setGlobalAlpha(1)}}if("line"==e.type){var m=splitPoints(s);m.forEach(function(i){o.beginPath(),o.setStrokeStyle(e.color),o.setLineWidth(2*t.pixelRatio),1===i.length?(o.moveTo(i[0].x,i[0].y),o.arc(i[0].x,i[0].y,1,0,2*a)):(o.moveTo(i[0].x,i[0].y),"curve"==e.style?i.forEach(function(e,t){if(0<t){var a=createCurveControlPoints(i,t-1);o.bezierCurveTo(a.ctrA.x,a.ctrA.y,a.ctrB.x,a.ctrB.y,e.x,e.y)}}):i.forEach(function(e,t){0<t&&o.lineTo(e.x,e.y)}),o.moveTo(i[0].x,i[0].y)),o.closePath(),o.stroke()})}if("point"==e.type&&s.forEach(function(i){i&&(o.beginPath(),o.setFillStyle(e.color),o.setStrokeStyle("#FFFFFF"),o.setLineWidth(1*t.pixelRatio),o.moveTo(i.x+3.5*t.pixelRatio,i.y),o.arc(i.x,i.y,4*t.pixelRatio,0,2*a),o.closePath(),o.fill(),o.stroke())}),!0==e.addPoint&&"column"!==e.type){var T=i.dataPointShape[l%i.dataPointShape.length];drawPointShape(s,e.color,T,o,t)}}),!1!==t.dataLabel&&1===n){var y=0;e.forEach(function(e){var a=e.data,l=getDataPoints(a,c,x,d,h,t,i,n);"column"===e.type?(l=fixColumeData(l,h,f,y,i,t),drawPointText(l,e,i,o),y+=1):drawPointText(l,e,i,o)})}return o.restore(),{xAxisPoints:d,calPoints:g,eachSpacing:h}}function drawToolTipBridge(e,t,i,o,a,n){var l=e.extra.tooltip||{};l.horizentalLine&&e.tooltip&&1===o&&("line"==e.type||"area"==e.type||"column"==e.type||"candle"==e.type||"mix"==e.type)&&drawToolTipHorizentalLine(e,t,i,a,n),i.save(),e._scrollDistance_&&0!==e._scrollDistance_&&!0===e.enableScroll&&i.translate(e._scrollDistance_,0),e.tooltip&&e.tooltip.textList&&e.tooltip.textList.length&&1===o&&drawToolTip(e.tooltip.textList,e.tooltip.offset,e,t,i,a,n),i.restore()}function drawXAxis(e,t,i,o){var a=Math.ceil,n=getXAxisPoints(e,t,i),l=n.xAxisPoints,r=n.startX,s=n.endX,d=n.eachSpacing,h=t.height-i.padding-i.xAxisHeight-i.legendHeight,c=i.padding;if(t.enableScroll&&t.xAxis.scrollShow){var x=t.height-i.padding-i.legendHeight+6*t.pixelRatio,p=s-r,g=d*(l.length-1),y=0;t._scrollDistance_&&(y=-t._scrollDistance_*p/g),o.beginPath(),o.setLineCap("round"),o.setLineWidth(6*t.pixelRatio),o.setStrokeStyle(t.xAxis.scrollBackgroundColor||"#EFEBEF"),o.moveTo(r,x),o.lineTo(s,x),o.stroke(),o.closePath(),o.beginPath(),o.setLineCap("round"),o.setLineWidth(6*t.pixelRatio),o.setStrokeStyle(t.xAxis.scrollColor||"#A6A6A6"),o.moveTo(r+y,x),o.lineTo(r+y+p*p/g,x),o.stroke(),o.setLineCap("butt"),o.closePath()}if(o.save(),t._scrollDistance_&&0!==t._scrollDistance_&&o.translate(t._scrollDistance_,0),o.beginPath(),o.setStrokeStyle(t.xAxis.gridColor||"#cccccc"),o.setLineCap("butt"),o.setLineWidth(1*t.pixelRatio),"dash"==t.xAxis.gridType&&o.setLineDash([t.xAxis.dashLength,t.xAxis.dashLength]),!0!==t.xAxis.disableGrid&&("calibration"===t.xAxis.type?l.forEach(function(e,i){0<i&&(o.moveTo(e-d/2,h),o.lineTo(e-d/2,h+4*t.pixelRatio))}):(t.xAxis.gridEval=t.xAxis.gridEval||1,l.forEach(function(e,i){0==i%t.xAxis.gridEval&&(o.moveTo(e,h),o.lineTo(e,c))}))),o.closePath(),o.stroke(),o.setLineDash([]),!0!==t.xAxis.disabled){let n=t.width-2*i.padding-i.yAxisWidth-i.yAxisTitleWidth,r=e.length;t.xAxis.labelCount&&(r=t.xAxis.itemCount?a(e.length/t.xAxis.itemCount*t.xAxis.labelCount):t.xAxis.labelCount,r-=1);let s=a(e.length/r),c=[],x=e.length;for(let t=0;t<x;t++)0==t%s?c.push(e[t]):c.push("");c[x-1]=e[x-1];var f=t.xAxis.fontSize||i.fontSize;0===i._xAxisTextAngle_?c.forEach(function(e,i){var a=d/2-measureText(e,f)/2;o.beginPath(),o.setFontSize(f),o.setFillStyle(t.xAxis.fontColor||"#666666"),o.fillText(e,l[i]+a,h+f+5),o.closePath(),o.stroke()}):c.forEach(function(e,a){o.save(),o.beginPath(),o.setFontSize(f),o.setFillStyle(t.xAxis.fontColor||"#666666");var n=measureText(e),r=calRotateTranslate(l[a]+d/2,h+f/2+5,t.height),s=r.transX,c=r.transY;o.rotate(-1*i._xAxisTextAngle_),o.translate(s,c),o.fillText(e,l[a]+(d/2-n),h+f+5),o.closePath(),o.stroke(),o.restore()})}o.restore()}function drawYAxisGrid(e,t,o,a){if(!0!==t.yAxis.disableGrid){for(var n=t.height-2*o.padding-o.xAxisHeight-o.legendHeight,l=Math.floor(n/o.yAxisSplit),r=o.yAxisWidth+o.yAxisTitleWidth,s=o.padding+r,d=getXAxisPoints(e,t,o),h=d.xAxisPoints,c=d.eachSpacing,x=c*(h.length-1),p=s+x,g=[],y=0;y<o.yAxisSplit;y++)g.push(o.padding+l*y);g.push(o.padding+l*o.yAxisSplit+2),a.save(),t._scrollDistance_&&0!==t._scrollDistance_&&a.translate(t._scrollDistance_,0),"dash"==t.yAxis.gridType&&a.setLineDash([t.yAxis.dashLength,t.yAxis.dashLength]),a.beginPath(),a.setStrokeStyle(t.yAxis.gridColor||"#cccccc"),a.setLineWidth(1*t.pixelRatio),g.forEach(function(e){a.moveTo(s,e),a.lineTo(p,e)}),a.closePath(),a.stroke(),a.setLineDash([]),a.restore()}}function drawYAxis(e,t,o,a){if(!0!==t.yAxis.disabled){var n=calYAxisData(e,t,o),l=n.rangesFormat,r=o.yAxisWidth+o.yAxisTitleWidth,s=t.height-2*o.padding-o.xAxisHeight-o.legendHeight,d=Math.floor(s/o.yAxisSplit),h=o.padding+r,c=t.width-o.padding,x=t.height-o.padding-o.xAxisHeight-o.legendHeight+o.xAxisTextPadding;a.beginPath(),a.setFillStyle(t.background||"#ffffff"),0>t._scrollDistance_&&a.fillRect(0,0,h,x+o.xAxisHeight),a.fillRect(c,0,t.width,x+o.xAxisHeight),a.closePath(),a.stroke();for(var p=[],g=0;g<=o.yAxisSplit;g++)p.push(o.padding+d*g);var y=t.yAxis.fontSize||o.fontSize;l.forEach(function(e,i){var n=p[i]?p[i]:x;a.beginPath(),a.setFontSize(y),a.setFillStyle(t.yAxis.fontColor||"#666666"),a.fillText(e,o.padding+o.yAxisTitleWidth,n+y/2),a.closePath(),a.stroke()}),t.yAxis.title&&drawYAxisTitle(t.yAxis.title,t,o,a)}}function drawLegend(e,t,o,a){var n=Math.PI;if(!1!==t.legend){var i=calLegendData(e,t,o),l=i.legendList,r=5*t.pixelRatio,s=10*t.pixelRatio,d=15*t.pixelRatio;l.forEach(function(e,i){var l=0;for(let t,o=0;o<e.length;o++)t=e[o],t.name=t.name||"undefined",l+=3*r+measureText(t.name)+d;var h=(t.width-l)/2+r,c=t.height-o.padding-o.legendHeight+i*(o.fontSize+s)+r+s;a.setFontSize(o.fontSize);for(let l,s=0;s<e.length;s++){switch(l=e[s],t.type){case"line":a.beginPath(),a.setLineWidth(1*t.pixelRatio),a.setStrokeStyle(l.color),a.setFillStyle(l.color),a.moveTo(h+7.5*t.pixelRatio,c+5*t.pixelRatio),a.arc(h+7.5*t.pixelRatio,c+5*t.pixelRatio,6*t.pixelRatio,0,2*n),a.closePath(),a.fill(),a.stroke();break;case"pie":a.beginPath(),a.setLineWidth(1*t.pixelRatio),a.setStrokeStyle(l.color),a.setFillStyle(l.color),a.moveTo(h+7.5*t.pixelRatio,c+5*t.pixelRatio),a.arc(h+7.5*t.pixelRatio,c+5*t.pixelRatio,6*t.pixelRatio,0,2*n),a.closePath(),a.fill(),a.stroke();break;case"ring":case"rose":a.beginPath(),a.setLineWidth(1*t.pixelRatio),a.setStrokeStyle(l.color),a.setFillStyle(l.color),a.moveTo(h+7.5*t.pixelRatio,c+5*t.pixelRatio),a.arc(h+7.5*t.pixelRatio,c+5*t.pixelRatio,6*t.pixelRatio,0,2*n),a.closePath(),a.fill(),a.stroke();break;case"gauge":break;case"arcbar":break;default:a.beginPath(),a.setLineWidth(1*t.pixelRatio),a.setStrokeStyle(l.color),a.setFillStyle(l.color),a.moveTo(h,c),a.fillRect(h,c,15*t.pixelRatio,10*t.pixelRatio),a.closePath(),a.fill(),a.stroke();}h+=r+d,a.beginPath(),a.setFontSize(o.fontSize),a.setFillStyle(t.extra.legendTextColor||"#333333"),a.fillText(l.name,h,c+6*t.pixelRatio+3*t.pixelRatio),a.closePath(),a.stroke(),h+=measureText(l.name)+2*r}})}}function drawPieDataPoints(e,t,o,a){var n=Math.PI,l=4<arguments.length&&void 0!==arguments[4]?arguments[4]:1,r=t.extra.pie||{},s={x:t.width/2,y:(t.height-o.legendHeight)/2},d=Math.min(s.x-o.pieChartLinePadding-o.pieChartTextPadding-o._pieTextMaxLength_,s.y-o.pieChartLinePadding-o.pieChartTextPadding);d-=t.dataLabel?10:2*o.padding,e=getPieDataPoints(e,d,l);var h=o.pieChartLinePadding/2;if(e=e.map(function(e){return e._start_+=(r.offsetAngle||0)*n/180,e}),e.forEach(function(e,i){t.tooltip&&t.tooltip.index==i&&(a.beginPath(),a.setFillStyle(hexToRgb(e.color,t.extra.pie.activeOpacity||.5)),a.moveTo(s.x,s.y),a.arc(s.x,s.y,e._radius_+h,e._start_,e._start_+2*e._proportion_*n),a.closePath(),a.fill()),a.beginPath(),a.setLineWidth(2*t.pixelRatio),a.lineJoin="round",a.setStrokeStyle("#ffffff"),a.setFillStyle(e.color),a.moveTo(s.x,s.y),a.arc(s.x,s.y,e._radius_,e._start_,e._start_+2*e._proportion_*n),a.closePath(),a.fill(),!0!==t.disablePieStroke&&a.stroke()}),"ring"===t.type){var c=.6*d;"number"==typeof t.extra.pie.ringWidth&&0<t.extra.pie.ringWidth&&(c=Math.max(0,d-t.extra.pie.ringWidth)),a.beginPath(),a.setFillStyle(t.background||"#ffffff"),a.moveTo(s.x,s.y),a.arc(s.x,s.y,c,0,2*n),a.closePath(),a.fill()}if(!1!==t.dataLabel&&1===l){for(var x=!1,p=0,g=e.length;p<g;p++)if(0<e[p].data){x=!0;break}x&&drawPieText(e,t,o,a,d,s)}return 1===l&&"ring"===t.type&&drawRingTitle(t,o,a),{center:s,radius:d,series:e}}function drawRoseDataPoints(e,t,o,a){var n=Math.PI,l=4<arguments.length&&void 0!==arguments[4]?arguments[4]:1,r=t.extra.rose||{};r.type=r.type||"area";var s={x:t.width/2,y:(t.height-o.legendHeight)/2},d=Math.min(s.x-o.pieChartLinePadding-o.pieChartTextPadding-o._pieTextMaxLength_,s.y-o.pieChartLinePadding-o.pieChartTextPadding);d-=t.dataLabel?10:2*o.padding;var h=r.minRadius||.5*d;e=getRoseDataPoints(e,r.type,h,d,l);var c=o.pieChartLinePadding/2;if(e=e.map(function(e){return e._start_+=(r.offsetAngle||0)*n/180,e}),e.forEach(function(e,i){t.tooltip&&t.tooltip.index==i&&(a.beginPath(),a.setFillStyle(hexToRgb(e.color,r.activeOpacity||.5)),a.moveTo(s.x,s.y),a.arc(s.x,s.y,c+e._radius_,e._start_,e._start_+2*e._proportion_*n),a.closePath(),a.fill()),a.beginPath(),a.setLineWidth(2*t.pixelRatio),a.lineJoin="round",a.setStrokeStyle("#ffffff"),a.setFillStyle(e.color),a.moveTo(s.x,s.y),a.arc(s.x,s.y,e._radius_,e._start_,e._start_+2*e._proportion_*n),a.closePath(),a.fill(),!0!==t.disablePieStroke&&a.stroke()}),!1!==t.dataLabel&&1===l){for(var x=!1,p=0,g=e.length;p<g;p++)if(0<e[p].data){x=!0;break}x&&drawPieText(e,t,o,a,d,s)}return{center:s,radius:d,series:e}}function drawArcbarDataPoints(e,t,i,o){var a=Math.PI,n=4<arguments.length&&void 0!==arguments[4]?arguments[4]:1,l=t.extra.arcbar||{};l.startAngle=l.startAngle?l.startAngle:.75,l.endAngle=l.endAngle?l.endAngle:.25,l.type=l.type?l.type:"default",e=getArcbarDataPoints(e,l,n);var r={x:t.width/2,y:t.height/2},s=Math.min(r.x,r.y);l.width="number"==typeof l.width&&0<l.width?l.width:12*t.pixelRatio,s-=i.padding+l.width/2,o.setLineWidth(l.width),o.setStrokeStyle(l.backgroundColor||"#E9E9E9"),o.setLineCap("round"),o.beginPath(),"default"==l.type?o.arc(r.x,r.y,s,l.startAngle*a,l.endAngle*a,!1):o.arc(r.x,r.y,s,0,2*a,!1),o.stroke();for(let n,d=0;d<e.length;d++)n=e[d],o.setLineWidth(l.width),o.setStrokeStyle(n.color),o.setLineCap("round"),o.beginPath(),o.arc(r.x,r.y,s,l.startAngle*a,n._proportion_*a,!1),o.stroke();return drawRingTitle(t,i,o),{center:r,radius:s,series:e}}function drawGaugeDataPoints(e,t,o,i,a){var n=Math.PI,l=5<arguments.length&&void 0!==arguments[5]?arguments[5]:1,r=o.extra.gauge||{};r.startAngle=r.startAngle?r.startAngle:.75,null==r.oldAngle&&(r.oldAngle=r.startAngle),null==r.oldData&&(r.oldData=0),r.endAngle=r.endAngle?r.endAngle:.25,e=getGaugeAxisPoints(e,r.startAngle,r.endAngle);var s={x:o.width/2,y:o.height/2},d=Math.min(s.x,s.y);r.width="number"==typeof r.width&&0<r.width?r.width:15*o.pixelRatio,d-=i.padding+r.width/2;var h=d-r.width;a.setLineWidth(r.width),a.setLineCap("butt");for(let l,r=0;r<e.length;r++)l=e[r],a.beginPath(),a.setStrokeStyle(l.color),a.arc(s.x,s.y,d,l._startAngle_*n,l._endAngle_*n,!1),a.stroke();a.save();let c=r.startAngle-r.endAngle+1;r.splitLine.fixRadius=r.splitLine.fixRadius?r.splitLine.fixRadius:0,r.splitLine.splitNumber=r.splitLine.splitNumber?r.splitLine.splitNumber:10,r.splitLine.width=r.splitLine.width?r.splitLine.width:15*o.pixelRatio,r.splitLine.color=r.splitLine.color?r.splitLine.color:"#FFFFFF",r.splitLine.childNumber=r.splitLine.childNumber?r.splitLine.childNumber:5,r.splitLine.childWidth=r.splitLine.childWidth?r.splitLine.childWidth:5*o.pixelRatio;let x=c/r.splitLine.splitNumber,p=c/r.splitLine.splitNumber/r.splitLine.childNumber,g=-d-.5*r.width-r.splitLine.fixRadius,y=-d-.5*r.width-r.splitLine.fixRadius+r.splitLine.width,f=-d-.5*r.width-r.splitLine.fixRadius+r.splitLine.childWidth;a.translate(s.x,s.y),a.rotate((r.startAngle-1)*n);for(let l=0;l<r.splitLine.splitNumber+1;l++)a.beginPath(),a.setStrokeStyle(r.splitLine.color),a.setLineWidth(2*o.pixelRatio),a.moveTo(g,0),a.lineTo(y,0),a.stroke(),a.rotate(x*n);a.restore(),a.save(),a.translate(s.x,s.y),a.rotate((r.startAngle-1)*n);for(let l=0;l<r.splitLine.splitNumber*r.splitLine.childNumber+1;l++)a.beginPath(),a.setStrokeStyle(r.splitLine.color),a.setLineWidth(1*o.pixelRatio),a.moveTo(g,0),a.lineTo(f,0),a.stroke(),a.rotate(p*n);a.restore(),r.pointer.width=r.pointer.width?r.pointer.width:15*o.pixelRatio,null==r.pointer.color||"auto"==r.pointer.color?"auto"==r.pointer.color:r.pointer.color==r.pointer.color,t=getGaugeDataPoints(t,e,r,l);for(let l,d=0;d<t.length;d++)l=t[d],a.save(),a.translate(s.x,s.y),a.rotate((l._proportion_-1)*n),a.beginPath(),a.setFillStyle(l.color),a.moveTo(r.pointer.width,0),a.lineTo(0,-r.pointer.width/2),a.lineTo(-h,0),a.lineTo(0,r.pointer.width/2),a.lineTo(r.pointer.width,0),a.closePath(),a.fill(),a.beginPath(),a.setFillStyle("#FFFFFF"),a.arc(0,0,r.pointer.width/6,0,2*n,!1),a.fill(),a.restore();return!1!==o.dataLabel&&drawGaugeLabel(r,d,s,o,i,a),drawRingTitle(o,i,a),1===l&&"gauge"===o.type&&(r.oldAngle=t[0]._proportion_,r.oldData=t[0].data),{center:s,radius:d,innerRadius:h,categories:e,totalAngle:c}}function drawRadarDataPoints(e,t,o,a){var n=Math.cos,l=Math.sin,r=4<arguments.length&&void 0!==arguments[4]?arguments[4]:1,s=t.extra.radar||{},d=getRadarCoordinateSeries(t.categories.length),h={x:t.width/2,y:(t.height-o.legendHeight)/2},c=Math.min(h.x-(getMaxTextListLength(t.categories)+o.radarLabelTextMargin),h.y-o.radarLabelTextMargin);c-=o.padding,a.beginPath(),a.setLineWidth(1*t.pixelRatio),a.setStrokeStyle(s.gridColor||"#cccccc"),d.forEach(function(e){var t=convertCoordinateOrigin(c*n(e),c*l(e),h);a.moveTo(h.x,h.y),a.lineTo(t.x,t.y)}),a.stroke(),a.closePath();for(var x=function(e){var i={};a.beginPath(),a.setLineWidth(1*t.pixelRatio),a.setStrokeStyle(s.gridColor||"#cccccc"),d.forEach(function(t,r){var s=convertCoordinateOrigin(c/o.radarGridCount*e*n(t),c/o.radarGridCount*e*l(t),h);0===r?(i=s,a.moveTo(s.x,s.y)):a.lineTo(s.x,s.y)}),a.lineTo(i.x,i.y),a.stroke(),a.closePath()},p=1;p<=o.radarGridCount;p++)x(p);var g=getRadarDataPoints(d,h,c,e,t,r);return g.forEach(function(e,i){if(a.beginPath(),a.setFillStyle(e.color),a.setGlobalAlpha(.3),e.data.forEach(function(e,t){0===t?a.moveTo(e.position.x,e.position.y):a.lineTo(e.position.x,e.position.y)}),a.closePath(),a.fill(),a.setGlobalAlpha(1),!1!==t.dataPointShape){var n=o.dataPointShape[i%o.dataPointShape.length],l=e.data.map(function(e){return e.position});drawPointShape(l,e.color,n,a,t)}}),drawRadarLabel(d,c,h,t,o,a),{center:h,radius:c,angleList:d}}function drawCanvas(e,t){t.draw()}var Timing={easeIn:function(e){return Math.pow(e,3)},easeOut:function(e){return Math.pow(e-1,3)+1},easeInOut:function(e){var t=Math.pow;return 1>(e/=.5)?.5*t(e,3):.5*(t(e-2,3)+2)},linear:function(e){return e}};function Animation(e){this.isStop=!1,e.duration="undefined"==typeof e.duration?1e3:e.duration,e.timing=e.timing||"linear";var t=function(){return"undefined"==typeof requestAnimationFrame?"undefined"==typeof setTimeout?function(e){e(null)}:function(e,t){setTimeout(function(){var t=+new Date;e(t)},t)}:requestAnimationFrame}(),i=null,o=function(a){if(null===a||!0===this.isStop)return e.onProcess&&e.onProcess(1),void(e.onAnimationFinish&&e.onAnimationFinish());if(null===i&&(i=a),a-i<e.duration){var n=(a-i)/e.duration,l=Timing[e.timing];n=l(n),e.onProcess&&e.onProcess(n),t(o,17)}else e.onProcess&&e.onProcess(1),e.onAnimationFinish&&e.onAnimationFinish()};o=o.bind(this),t(o,17)}Animation.prototype.stop=function(){this.isStop=!0};function drawCharts(e,t,i,o){var a=this,n=t.series,l=t.categories;n=fillSeriesColor(n,i),n=fillSeriesType(n,t);let r=null;if("candle"==e){let e=assign({},t.extra.candle.average);e.show&&(r=calCandleMA(e.day,e.name,e.color,n[0].data),t.seriesMA=r)}var s=calLegendData(n,t,i),d=s.legendHeight;i.legendHeight=d;var h=calYAxisData(n,t,i),c=h.yAxisWidth;if(i.yAxisWidth=c,l&&l.length){var x=calCategoriesData(l,t,i),p=x.xAxisHeight,g=x.angle;i.xAxisHeight=p,i._xAxisTextAngle_=g}("pie"===e||"ring"===e||"rose"===e)&&(i._pieTextMaxLength_=!1===t.dataLabel?0:getPieTextMaxLength(n));var y=t.animation?t.duration:0;this.animationInstance&&this.animationInstance.stop(),"line"===e?this.animationInstance=new Animation({timing:"easeIn",duration:y,onProcess:function(e){o.clearRect(0,0,t.width,t.height),t.rotate&&contextRotate(o,t),drawYAxisGrid(l,t,i,o),drawXAxis(l,t,i,o);var r=drawLineDataPoints(n,t,i,o,e),s=r.xAxisPoints,d=r.calPoints,h=r.eachSpacing;a.chartData.xAxisPoints=s,a.chartData.calPoints=d,a.chartData.eachSpacing=h,drawLegend(t.series,t,i,o),drawYAxis(n,t,i,o),drawToolTipBridge(t,i,o,e,h,s),drawCanvas(t,o)},onAnimationFinish:function(){a.event.trigger("renderComplete")}}):"mix"===e?this.animationInstance=new Animation({timing:"easeIn",duration:y,onProcess:function(e){o.clearRect(0,0,t.width,t.height),t.rotate&&contextRotate(o,t),drawYAxisGrid(l,t,i,o),drawXAxis(l,t,i,o);var r=drawMixDataPoints(n,t,i,o,e),s=r.xAxisPoints,d=r.calPoints,h=r.eachSpacing;a.chartData.xAxisPoints=s,a.chartData.calPoints=d,a.chartData.eachSpacing=h,drawLegend(t.series,t,i,o),drawYAxis(n,t,i,o),drawToolTipBridge(t,i,o,e,h,s),drawCanvas(t,o)},onAnimationFinish:function(){a.event.trigger("renderComplete")}}):"column"===e?this.animationInstance=new Animation({timing:"easeIn",duration:y,onProcess:function(e){o.clearRect(0,0,t.width,t.height),t.rotate&&contextRotate(o,t),drawYAxisGrid(l,t,i,o),drawXAxis(l,t,i,o);var r=drawColumnDataPoints(n,t,i,o,e),s=r.xAxisPoints,d=r.calPoints,h=r.eachSpacing;a.chartData.xAxisPoints=s,a.chartData.calPoints=d,a.chartData.eachSpacing=h,drawLegend(t.series,t,i,o),drawYAxis(n,t,i,o),drawToolTipBridge(t,i,o,e,h,s),drawCanvas(t,o)},onAnimationFinish:function(){a.event.trigger("renderComplete")}}):"area"===e?this.animationInstance=new Animation({timing:"easeIn",duration:y,onProcess:function(e){o.clearRect(0,0,t.width,t.height),t.rotate&&contextRotate(o,t),drawYAxisGrid(l,t,i,o),drawXAxis(l,t,i,o);var r=drawAreaDataPoints(n,t,i,o,e),s=r.xAxisPoints,d=r.calPoints,h=r.eachSpacing;a.chartData.xAxisPoints=s,a.chartData.calPoints=d,a.chartData.eachSpacing=h,drawLegend(t.series,t,i,o),drawYAxis(n,t,i,o),drawToolTipBridge(t,i,o,e,h,s),drawCanvas(t,o)},onAnimationFinish:function(){a.event.trigger("renderComplete")}}):"ring"===e||"pie"===e?this.animationInstance=new Animation({timing:"easeInOut",duration:y,onProcess:function(e){o.clearRect(0,0,t.width,t.height),t.rotate&&contextRotate(o,t),a.chartData.pieData=drawPieDataPoints(n,t,i,o,e),drawLegend(t.series,t,i,o),drawToolTipBridge(t,i,o,e),drawCanvas(t,o)},onAnimationFinish:function(){a.event.trigger("renderComplete")}}):"rose"===e?this.animationInstance=new Animation({timing:"easeInOut",duration:y,onProcess:function(e){o.clearRect(0,0,t.width,t.height),t.rotate&&contextRotate(o,t),a.chartData.pieData=drawRoseDataPoints(n,t,i,o,e),drawLegend(t.series,t,i,o),drawToolTipBridge(t,i,o,e),drawCanvas(t,o)},onAnimationFinish:function(){a.event.trigger("renderComplete")}}):"radar"===e?this.animationInstance=new Animation({timing:"easeInOut",duration:y,onProcess:function(e){o.clearRect(0,0,t.width,t.height),t.rotate&&contextRotate(o,t),a.chartData.radarData=drawRadarDataPoints(n,t,i,o,e),drawLegend(t.series,t,i,o),drawToolTipBridge(t,i,o,e),drawCanvas(t,o)},onAnimationFinish:function(){a.event.trigger("renderComplete")}}):"arcbar"===e?this.animationInstance=new Animation({timing:"easeInOut",duration:y,onProcess:function(e){o.clearRect(0,0,t.width,t.height),t.rotate&&contextRotate(o,t),a.chartData.arcbarData=drawArcbarDataPoints(n,t,i,o,e),drawCanvas(t,o)},onAnimationFinish:function(){a.event.trigger("renderComplete")}}):"gauge"===e?this.animationInstance=new Animation({timing:"easeInOut",duration:y,onProcess:function(e){o.clearRect(0,0,t.width,t.height),t.rotate&&contextRotate(o,t),a.chartData.gaugeData=drawGaugeDataPoints(l,n,t,i,o,e),drawCanvas(t,o)},onAnimationFinish:function(){a.event.trigger("renderComplete")}}):"candle"===e?this.animationInstance=new Animation({timing:"easeIn",duration:y,onProcess:function(e){o.clearRect(0,0,t.width,t.height),t.rotate&&contextRotate(o,t),drawYAxisGrid(l,t,i,o),drawXAxis(l,t,i,o);var s=drawCandleDataPoints(n,r,t,i,o,e),d=s.xAxisPoints,h=s.calPoints,c=s.eachSpacing;a.chartData.xAxisPoints=d,a.chartData.calPoints=h,a.chartData.eachSpacing=c,r?drawLegend(r,t,i,o):drawLegend(t.series,t,i,o),drawYAxis(n,t,i,o),drawToolTipBridge(t,i,o,e,c,d),drawCanvas(t,o)},onAnimationFinish:function(){a.event.trigger("renderComplete")}}):void 0}function Event(){this.events={}}Event.prototype.addEventListener=function(e,t){this.events[e]=this.events[e]||[],this.events[e].push(t)},Event.prototype.trigger=function(){for(var e=arguments.length,t=Array(e),i=0;i<e;i++)t[i]=arguments[i];var o=t[0],a=t.slice(1);!this.events[o]||this.events[o].forEach(function(e){try{e.apply(null,a)}catch(t){console.error(t)}})};var Charts=function(e){e.pixelRatio=e.pixelRatio?e.pixelRatio:1,e.fontSize=e.fontSize?e.fontSize*e.pixelRatio:13*e.pixelRatio,e.title=assign({},e.title),e.subtitle=assign({},e.subtitle),e.yAxis=assign({},{gridType:"solid",dashLength:4*e.pixelRatio},e.yAxis),e.xAxis=assign({},{rotateLabel:!1,type:"calibration",gridType:"solid",dashLength:4*e.pixelRatio,scrollAlign:"left"},e.xAxis),e.extra=assign({},e.extra),e.rotate=!!e.rotate,e.animation=!!e.animation;var t=assign({},config);if(t.yAxisTitleWidth=!0!==e.yAxis.disabled&&e.yAxis.title?t.yAxisTitleWidth:0,("pie"==e.type||"ring"==e.type)&&(t.pieChartLinePadding=!1===e.dataLabel?0:e.extra.pie.labelWidth*e.pixelRatio||t.pieChartLinePadding*e.pixelRatio),"rose"==e.type&&(t.pieChartLinePadding=!1===e.dataLabel?0:e.extra.rose.labelWidth*e.pixelRatio||t.pieChartLinePadding*e.pixelRatio),t.pieChartTextPadding=!1===e.dataLabel?0:t.pieChartTextPadding*e.pixelRatio,t.yAxisSplit=e.yAxis.splitNumber?e.yAxis.splitNumber:config.yAxisSplit,t.rotate=e.rotate,e.rotate){let t=e.width,i=e.height;e.width=i,e.height=t}if(t.yAxisWidth=config.yAxisWidth*e.pixelRatio,t.xAxisHeight=config.xAxisHeight*e.pixelRatio,e.enableScroll&&e.xAxis.scrollShow&&(t.xAxisHeight+=6*e.pixelRatio),t.xAxisLineHeight=config.xAxisLineHeight*e.pixelRatio,t.legendHeight=config.legendHeight*e.pixelRatio,t.padding=config.padding*e.pixelRatio,t.fontSize=e.fontSize,t.titleFontSize=config.titleFontSize*e.pixelRatio,t.subtitleFontSize=config.subtitleFontSize*e.pixelRatio,t.toolTipPadding=config.toolTipPadding*e.pixelRatio,t.toolTipLineHeight=config.toolTipLineHeight*e.pixelRatio,t.columePadding=config.columePadding*e.pixelRatio,this.opts=e,this.config=t,e.$this=e.$this?e.$this:this,this.context=uni.createCanvasContext(e.canvasId,e.$this),this.chartData={},this.event=new Event,this.scrollOption={currentOffset:0,startTouchX:0,distance:0,lastMoveTime:0},e.enableScroll&&"right"==e.xAxis.scrollAlign){let i=calYAxisData(e.series,e,t),o=i.yAxisWidth;t.yAxisWidth=o;let a=0,n=getXAxisPoints(e.categories,e,t),l=n.xAxisPoints,r=n.startX,s=n.endX,d=n.eachSpacing,h=d*(l.length-1);a=s-r-h,this.scrollOption={currentOffset:a,startTouchX:a,distance:0,lastMoveTime:0},e._scrollDistance_=a}drawCharts.call(this,e.type,e,t,this.context)};Charts.prototype.updateData=function(){let e=0<arguments.length&&arguments[0]!==void 0?arguments[0]:{};this.opts=assign({},this.opts,e);let t=e.scrollPosition||"current";switch(t){case"current":this.opts._scrollDistance_=this.scrollOption.currentOffset;break;case"left":this.opts._scrollDistance_=0,this.scrollOption={currentOffset:0,startTouchX:0,distance:0,lastMoveTime:0};break;case"right":let e=calYAxisData(this.opts.series,this.opts,this.config),i=e.yAxisWidth;this.config.yAxisWidth=i;let o=0,a=getXAxisPoints(this.opts.categories,this.opts,this.config),n=a.xAxisPoints,l=a.startX,r=a.endX,s=a.eachSpacing,d=s*(n.length-1);o=r-l-d,this.scrollOption={currentOffset:o,startTouchX:o,distance:0,lastMoveTime:0},this.opts._scrollDistance_=o;}drawCharts.call(this,this.opts.type,this.opts,this.config,this.context)},Charts.prototype.zoom=function(){var e=Math.round,t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:this.opts.xAxis.itemCount;if(!0!==this.opts.enableScroll)return void console.log("\u8BF7\u542F\u7528\u6EDA\u52A8\u6761\u540E\u4F7F\u7528\uFF01");let i=e(Math.abs(this.scrollOption.currentOffset)/this.chartData.eachSpacing)+e(this.opts.xAxis.itemCount/2);this.opts.animation=!1,this.opts.xAxis.itemCount=t.itemCount;let o=calYAxisData(this.opts.series,this.opts,this.config),a=o.yAxisWidth;this.config.yAxisWidth=a;let n=0,l=getXAxisPoints(this.opts.categories,this.opts,this.config),r=l.xAxisPoints,s=l.startX,d=l.endX,h=l.eachSpacing,c=d-s,x=c-h*(r.length-1);n=c/2-h*i,0<n&&(n=0),n<x&&(n=x),this.scrollOption={currentOffset:n,startTouchX:n,distance:0,lastMoveTime:0},this.opts._scrollDistance_=n,drawCharts.call(this,this.opts.type,this.opts,this.config,this.context)},Charts.prototype.stopAnimation=function(){this.animationInstance&&this.animationInstance.stop()},Charts.prototype.addEventListener=function(e,t){this.event.addEventListener(e,t)},Charts.prototype.getCurrentDataIndex=function(t){var e=null;if(e=t.changedTouches?t.changedTouches[0]:t.mp.changedTouches[0],e){var i=getTouches(e,this.opts,t);return"pie"===this.opts.type||"ring"===this.opts.type||"rose"===this.opts.type?findPieChartCurrentIndex({x:i.x,y:i.y},this.chartData.pieData):"radar"===this.opts.type?findRadarChartCurrentIndex({x:i.x,y:i.y},this.chartData.radarData,this.opts.categories.length):findCurrentIndex({x:i.x,y:i.y},this.chartData.xAxisPoints,this.opts,this.config,Math.abs(this.scrollOption.currentOffset))}return-1},Charts.prototype.showToolTip=function(t){var e=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{},i=null;if(i=t.changedTouches?t.changedTouches[0]:t.mp.changedTouches[0],!i)return void console.log("touchError");var o=getTouches(i,this.opts,t);if("line"===this.opts.type||"area"===this.opts.type||"column"===this.opts.type){var a=this.getCurrentDataIndex(t),n=this.scrollOption.currentOffset,l=assign({},this.opts,{_scrollDistance_:n,animation:!1});if(-1<a){var r=getSeriesDataItem(this.opts.series,a);if(0!==r.length){var s=getToolTipData(r,this.chartData.calPoints,a,this.opts.categories,e),d=s.textList,h=s.offset;h.y=o.y,l.tooltip={textList:d,offset:h,option:e,index:a}}}drawCharts.call(this,l.type,l,this.config,this.context)}if("mix"===this.opts.type){var a=this.getCurrentDataIndex(t),n=this.scrollOption.currentOffset,l=assign({},this.opts,{_scrollDistance_:n,animation:!1});if(-1<a){var r=getSeriesDataItem(this.opts.series,a);if(0!==r.length){var c=getMixToolTipData(r,this.chartData.calPoints,a,this.opts.categories,e),d=c.textList,h=c.offset;h.y=o.y,l.tooltip={textList:d,offset:h,option:e,index:a}}}drawCharts.call(this,l.type,l,this.config,this.context)}if("candle"===this.opts.type){var a=this.getCurrentDataIndex(t),n=this.scrollOption.currentOffset,l=assign({},this.opts,{_scrollDistance_:n,animation:!1});if(-1<a){var r=getSeriesDataItem(this.opts.series,a);if(0!==r.length){var s=getCandleToolTipData(this.opts.series[0].data,r,this.chartData.calPoints,a,this.opts.categories,this.opts.extra.candle,e),d=s.textList,h=s.offset;h.y=o.y,l.tooltip={textList:d,offset:h,option:e,index:a}}}drawCharts.call(this,l.type,l,this.config,this.context)}if("pie"===this.opts.type||"ring"===this.opts.type||"rose"===this.opts.type){var a=this.getCurrentDataIndex(t),n=this.scrollOption.currentOffset,l=assign({},this.opts,{_scrollDistance_:n,animation:!1});if(-1<a){var r=this.opts.series[a],d=[{text:e.format?e.format(r):r.name+": "+r.data,color:r.color}],h={x:o.x,y:o.y};l.tooltip={textList:d,offset:h,option:e,index:a}}drawCharts.call(this,l.type,l,this.config,this.context)}if("radar"===this.opts.type){var a=this.getCurrentDataIndex(t),n=this.scrollOption.currentOffset,l=assign({},this.opts,{_scrollDistance_:n,animation:!1});if(-1<a){var r=getSeriesDataItem(this.opts.series,a);if(0!==r.length){var d=r.map(function(t){return{text:e.format?e.format(t):t.name+": "+t.data,color:t.color}}),h={x:o.x,y:o.y};l.tooltip={textList:d,offset:h,option:e,index:a}}}drawCharts.call(this,l.type,l,this.config,this.context)}},Charts.prototype.translate=function(e){this.scrollOption={currentOffset:e,startTouchX:e,distance:0,lastMoveTime:0};let t=assign({},this.opts,{_scrollDistance_:e,animation:!1});drawCharts.call(this,this.opts.type,t,this.config,this.context)},Charts.prototype.scrollStart=function(t){var e=null;e=t.changedTouches?t.changedTouches[0]:t.mp.changedTouches[0];var i=getTouches(e,this.opts,t);e&&!0===this.opts.enableScroll&&(this.scrollOption.startTouchX=i.x)},Charts.prototype.scroll=function(t){0===this.scrollOption.lastMoveTime&&(this.scrollOption.lastMoveTime=Date.now());let e=this.opts.extra.touchMoveLimit||20,i=Date.now(),o=i-this.scrollOption.lastMoveTime;if(!(o<Math.floor(1e3/e))){this.scrollOption.lastMoveTime=i;var a=null;a=t.changedTouches?t.changedTouches[0]:t.mp.changedTouches[0];var n=getTouches(a,this.opts,t);if(a&&!0===this.opts.enableScroll){var l=n.x-this.scrollOption.startTouchX;var r=this.scrollOption.currentOffset,s=calValidDistance(r+l,this.chartData,this.config,this.opts);this.scrollOption.distance=l=s-r;var d=assign({},this.opts,{_scrollDistance_:r+l,animation:!1});return drawCharts.call(this,d.type,d,this.config,this.context),r+l}}},Charts.prototype.scrollEnd=function(){if(!0===this.opts.enableScroll){var e=this.scrollOption,t=e.currentOffset,i=e.distance;this.scrollOption.currentOffset=t+i,this.scrollOption.distance=0}},"object"==typeof module&&"object"==typeof module.exports&&(module.exports=Charts);

u-parse

components
wxParseAudio.vue
<template>
  <!--增加audio标签支持-->
  <audio
    :id="node.attr.id"
    :class="node.classStr"
    :style="node.styleStr"
    :src="node.attr.src"
    :loop="node.attr.loop"
    :poster="node.attr.poster"
    :name="node.attr.name"
    :author="node.attr.author"
    controls></audio>
</template>

<script>
export default {
  name: 'wxParseAudio',
  props: {
    node: {
      type: Object,
      default() {
        return {};
      },
    },
  },
};
</script>
wxParseImg.vue
<template>
  <image
    :mode="node.attr.mode"
    :lazy-load="node.attr.lazyLoad"
    :class="node.classStr"
    :style="newStyleStr || node.styleStr"
    :data-src="node.attr.src"
    :src="node.attr.src"
    @tap="wxParseImgTap"
    @load="wxParseImgLoad"
    />
</template>

<script>
export default {
  name: 'wxParseImg',
  data() {
    return {
      newStyleStr: '',
      preview: true,
    };
  },
  props: {
    node: {
      type: Object,
      default() {
        return {};
      },
    },
  },
  methods: {
    wxParseImgTap(e) {
      if (!this.preview) return;
      const { src } = e.currentTarget.dataset;
      if (!src) return;
      let parent = this.$parent;
      while(!parent.preview || typeof parent.preview !== 'function') {// TODO 遍历获取父节点执行方法
          parent = parent.$parent;
      }
      parent.preview(src, e);
    },
    // 图片视觉宽高计算函数区
    wxParseImgLoad(e) {
      const { src } = e.currentTarget.dataset;
      if (!src) return;
      const { width, height } = e.mp.detail;
      const recal = this.wxAutoImageCal(width, height);
      const { imageheight, imageWidth } = recal;
      const { padding, mode } = this.node.attr;
      const { styleStr } = this.node;
      const imageHeightStyle = mode === 'widthFix' ? '' : `height: ${imageheight}px;`;
      this.newStyleStr = `${styleStr}; ${imageHeightStyle}; width: ${imageWidth}px; padding: 0 ${+padding}px;`;
    },
    // 计算视觉优先的图片宽高
    wxAutoImageCal(originalWidth, originalHeight) {
      // 获取图片的原始长宽
      const { padding } = this.node.attr;
      const windowWidth = this.node.$screen.width - (2 * padding);
      const results = {};

      if (originalWidth < 60 || originalHeight < 60) {
        const { src } = this.node.attr;
                let parent = this.$parent;
                while(!parent.preview || typeof parent.preview !== 'function') {
                    parent = parent.$parent;
                }
                parent.removeImageUrl(src);
        this.preview = false;
      }

      // 判断按照那种方式进行缩放
      if (originalWidth > windowWidth) {
        // 在图片width大于手机屏幕width时候
        results.imageWidth = windowWidth;
        results.imageheight = windowWidth * (originalHeight / originalWidth);
      } else {
        // 否则展示原来的数据
        results.imageWidth = originalWidth;
        results.imageheight = originalHeight;
      }

      return results;
    },
  },
};
</script>
wxParseTemplate0.vue
<template>
    <view>
        <!--判断是否是标签节点-->
        <block v-if="node.node == 'element'">
            <block v-if="node.tag == 'button'">
                <button type="default" size="mini">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </button>
            </block>

            <!--li类型-->
            <block v-else-if="node.tag == 'li'">
                <view :class="node.classStr" :style="node.styleStr">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </view>
            </block>

            <!--video类型-->
            <block v-else-if="node.tag == 'video'">
                <wx-parse-video :node="node" />
            </block>

            <!--audio类型-->
            <block v-else-if="node.tag == 'audio'">
                <wx-parse-audio :node="node" />
            </block>

            <!--img类型-->
            <block v-else-if="node.tag == 'img'">
                <wx-parse-img :node="node" />
            </block>

            <!--a类型-->
            <block v-else-if="node.tag == 'a'">
                <view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </view>
            </block>

            <!--table类型-->
            <block v-else-if="node.tag == 'table'">
                <view :class="node.classStr" class="table" :style="node.styleStr">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </view>
            </block>

            <!--br类型-->
            <block v-else-if="node.tag == 'br'">
                <text>\n</text>
            </block>

            <!--其他标签-->
            <block v-else>
                <view :class="node.classStr" :style="node.styleStr">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </view>
            </block>

        </block>

        <!--判断是否是文本节点-->
        <block v-else-if="node.node == 'text'">{{node.text}}</block>
    </view>
</template>

<script>
    import wxParseTemplate from './wxParseTemplate1';
    import wxParseImg from './wxParseImg';
    import wxParseVideo from './wxParseVideo';
    import wxParseAudio from './wxParseAudio';

    export default {
        name: 'wxParseTemplate0',
        props: {
            node: {},
        },
        components: {
            wxParseTemplate,
            wxParseImg,
            wxParseVideo,
            wxParseAudio,
        },
        methods: {
            wxParseATap(e) {
                const {
                    href
                } = e.currentTarget.dataset;// TODO currentTarget才有dataset
                if (!href) return;
                let parent = this.$parent;
                while(!parent.preview || typeof parent.preview !== 'function') {// TODO 遍历获取父节点执行方法
                    parent = parent.$parent;
                }
                parent.navigate(href, e);
            },
        },
    };
</script>
wxParseTemplate1.vue
<template>
    <view :class="(node.tag == 'li' ? node.classStr : (node.node==='text'?'text':''))">
        <!--判断是否是标签节点-->
        <block v-if="node.node == 'element'">
            <block v-if="node.tag == 'button'">
                <button type="default" size="mini">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </button>
            </block>

            <!--li类型-->
            <block v-else-if="node.tag == 'li'">
                <!-- <view :class="node.classStr" :style="node.styleStr"> -->
                <view :style="node.styleStr">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </view>
            </block>

            <!--video类型-->
            <block v-else-if="node.tag == 'video'">
                <wx-parse-video :node="node" />
            </block>

            <!--audio类型-->
            <block v-else-if="node.tag == 'audio'">
                <wx-parse-audio :node="node" />
            </block>

            <!--img类型-->
            <block v-else-if="node.tag == 'img'">
                <wx-parse-img :node="node" />
            </block>

            <!--a类型-->
            <block v-else-if="node.tag == 'a'">
                <view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </view>
            </block>

            <!--br类型-->
            <block v-else-if="node.tag == 'br'">
                <text>\n</text>
            </block>

            <!--其他标签-->
            <block v-else>
                <view :class="node.classStr" :style="node.styleStr">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </view>
            </block>

        </block>

        <!--判断是否是文本节点-->
        <block v-else-if="node.node == 'text'">{{node.text}}</block>
    </view>
</template>

<script>
    import wxParseTemplate from './wxParseTemplate2';
    import wxParseImg from './wxParseImg';
    import wxParseVideo from './wxParseVideo';
    import wxParseAudio from './wxParseAudio';

    export default {
        name: 'wxParseTemplate1',
        props: {
            node: {},
        },
        components: {
            wxParseTemplate,
            wxParseImg,
            wxParseVideo,
            wxParseAudio,
        },
        methods: {
            wxParseATap(e) {
                const {
                    href
                } = e.currentTarget.dataset;
                if (!href) return;
                let parent = this.$parent;
                while(!parent.preview || typeof parent.preview !== 'function') {
                    parent = parent.$parent;
                }
                parent.navigate(href, e);
            },
        },
    };
</script>
wxParseTemplate10.vue
<template>
    <view>
        <!--判断是否是标签节点-->
        <block v-if="node.node == 'element'">
            <block v-if="node.tag == 'button'">
                <button type="default" size="mini">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </button>
            </block>

            <!--li类型-->
            <block v-else-if="node.tag == 'li'">
                <view :class="node.classStr" :style="node.styleStr">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </view>
            </block>

            <!--video类型-->
            <block v-else-if="node.tag == 'video'">
                <wx-parse-video :node="node" />
            </block>

            <!--audio类型-->
            <block v-else-if="node.tag == 'audio'">
                <wx-parse-audio :node="node" />
            </block>

            <!--img类型-->
            <block v-else-if="node.tag == 'img'">
                <wx-parse-img :node="node" />
            </block>

            <!--a类型-->
            <block v-else-if="node.tag == 'a'">
                <view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </view>
            </block>

            <!--br类型-->
            <block v-else-if="node.tag == 'br'">
                <text>\n</text>
            </block>

            <!--其他标签-->
            <block v-else>
                <view :class="node.classStr" :style="node.styleStr">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </view>
            </block>
        </block>

        <!--判断是否是文本节点-->
        <block v-else-if="node.node == 'text'">{{node.text}}</block>
    </view>
</template>

<script>
    import wxParseTemplate from './wxParseTemplate11';
    import wxParseImg from './wxParseImg';
    import wxParseVideo from './wxParseVideo';
    import wxParseAudio from './wxParseAudio';

    export default {
        name: 'wxParseTemplate10',
        props: {
            node: {},
        },
        components: {
            wxParseTemplate,
            wxParseImg,
            wxParseVideo,
            wxParseAudio,
        },
        methods: {
            wxParseATap(e) {
                const {
                    href
                } = e.currentTarget.dataset;
                if (!href) return;
                let parent = this.$parent;
                while(!parent.preview || typeof parent.preview !== 'function') {
                    parent = parent.$parent;
                }
                parent.navigate(href, e);
            },
        },
    };
</script>
wxParseTemplate11.vue
<template>
    <view>
        <!--判断是否是标签节点-->
        <block v-if="node.node == 'element'">
            <!--button类型-->
            <block v-if="node.tag == 'button'">
                <button type="default" size="mini">
                </button>
            </block>

            <!--li类型-->
            <block v-else-if="node.tag == 'li'">
                <view :class="node.classStr" :style="node.styleStr">
                    {{node.text}}
                </view>
            </block>

            <!--video类型-->
            <block v-else-if="node.tag == 'video'">
                <wx-parse-video :node="node" />
            </block>

            <!--audio类型-->
            <block v-else-if="node.tag == 'audio'">
                <wx-parse-audio :node="node" />
            </block>

            <!--img类型-->
            <block v-else-if="node.tag == 'img'">
                <wx-parse-img :node="node" />
            </block>

            <!--a类型-->
            <block v-else-if="node.tag == 'a'">
                <view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
                    {{node.text}}
                </view>
            </block>

            <!--br类型-->
            <block v-else-if="node.tag == 'br'">
                <text>\n</text>
            </block>

            <!--其他标签-->
            <block v-else>
                <view :class="node.classStr" :style="node.styleStr">
                    {{node.text}}
                </view>
            </block>
        </block>

        <!--判断是否是文本节点-->
        <block v-else-if="node.node == 'text'">{{node.text}}</block>
    </view>
</template>

<script>
    import wxParseImg from './wxParseImg';
    import wxParseVideo from './wxParseVideo';
    import wxParseAudio from './wxParseAudio';

    export default {
        name: 'wxParseTemplate11',
        props: {
            node: {},
        },
        components: {
            wxParseImg,
            wxParseVideo,
            wxParseAudio,
        },
        methods: {
            wxParseATap(e) {
                const {
                    href
                } = e.currentTarget.dataset;
                if (!href) return;
                let parent = this.$parent;
                while(!parent.preview || typeof parent.preview !== 'function') {
                    parent = parent.$parent;
                }
                parent.navigate(href, e);
            },
        },
    };
</script>
wxParseTemplate2.vue
<template>
    <view>
        <!--判断是否是标签节点-->
        <block v-if="node.node == 'element'">
            <block v-if="node.tag == 'button'">
                <button type="default" size="mini">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </button>
            </block>

            <!--li类型-->
            <block v-else-if="node.tag == 'li'">
                <view :class="node.classStr" :style="node.styleStr">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </view>
            </block>

            <!--video类型-->
            <block v-else-if="node.tag == 'video'">
                <wx-parse-video :node="node" />
            </block>

            <!--audio类型-->
            <block v-else-if="node.tag == 'audio'">
                <wx-parse-audio :node="node" />
            </block>

            <!--img类型-->
            <block v-else-if="node.tag == 'img'">
                <wx-parse-img :node="node" />
            </block>

            <!--a类型-->
            <block v-else-if="node.tag == 'a'">
                <view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </view>
            </block>

            <!--br类型-->
            <block v-else-if="node.tag == 'br'">
                <text>\n</text>
            </block>

            <!--其他标签-->
            <block v-else>
                <view :class="node.classStr" :style="node.styleStr">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </view>
            </block>

        </block>

        <!--判断是否是文本节点-->
        <block v-else-if="node.node == 'text'">{{node.text}}</block>
    </view>
</template>

<script>
    import wxParseTemplate from './wxParseTemplate3';
    import wxParseImg from './wxParseImg';
    import wxParseVideo from './wxParseVideo';
    import wxParseAudio from './wxParseAudio';

    export default {
        name: 'wxParseTemplate2',
        props: {
            node: {},
        },
        components: {
            wxParseTemplate,
            wxParseImg,
            wxParseVideo,
            wxParseAudio,
        },
        methods: {
            wxParseATap(e) {
                const {
                    href
                } = e.currentTarget.dataset;
                if (!href) return;
                let parent = this.$parent;
                while(!parent.preview || typeof parent.preview !== 'function') {
                    parent = parent.$parent;
                }
                parent.navigate(href, e);
            },
        },
    };
</script>
wxParseTemplate3.vue
<template>
    <view>
        <!--判断是否是标签节点-->
        <block v-if="node.node == 'element'">
            <block v-if="node.tag == 'button'">
                <button type="default" size="mini">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </button>
            </block>

            <!--li类型-->
            <block v-else-if="node.tag == 'li'">
                <view :class="node.classStr" :style="node.styleStr">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </view>
            </block>

            <!--video类型-->
            <block v-else-if="node.tag == 'video'">
                <wx-parse-video :node="node" />
            </block>

            <!--audio类型-->
            <block v-else-if="node.tag == 'audio'">
                <wx-parse-audio :node="node" />
            </block>

            <!--img类型-->
            <block v-else-if="node.tag == 'img'">
                <wx-parse-img :node="node" />
            </block>

            <!--a类型-->
            <block v-else-if="node.tag == 'a'">
                <view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </view>
            </block>

            <!--br类型-->
            <block v-else-if="node.tag == 'br'">
                <text>\n</text>
            </block>

            <!--其他标签-->
            <block v-else>
                <view :class="node.classStr" :style="node.styleStr">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </view>
            </block>

        </block>

        <!--判断是否是文本节点-->
        <block v-else-if="node.node == 'text'">{{node.text}}</block>
    </view>
</template>

<script>
    import wxParseTemplate from './wxParseTemplate4';
    import wxParseImg from './wxParseImg';
    import wxParseVideo from './wxParseVideo';
    import wxParseAudio from './wxParseAudio';

    export default {
        name: 'wxParseTemplate3',
        props: {
            node: {},
        },
        components: {
            wxParseTemplate,
            wxParseImg,
            wxParseVideo,
            wxParseAudio,
        },
        methods: {
            wxParseATap(e) {
                const {
                    href
                } = e.currentTarget.dataset;
                if (!href) return;
                let parent = this.$parent;
                while(!parent.preview || typeof parent.preview !== 'function') {
                    parent = parent.$parent;
                }
                parent.navigate(href, e);
            },
        },
    };
</script>
wxParseTemplate4.vue
<template>
    <view>
        <!--判断是否是标签节点-->
        <block v-if="node.node == 'element'">
            <block v-if="node.tag == 'button'">
                <button type="default" size="mini">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </button>
            </block>

            <!--li类型-->
            <block v-else-if="node.tag == 'li'">
                <view :class="node.classStr" :style="node.styleStr">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </view>
            </block>

            <!--video类型-->
            <block v-else-if="node.tag == 'video'">
                <wx-parse-video :node="node" />
            </block>

            <!--audio类型-->
            <block v-else-if="node.tag == 'audio'">
                <wx-parse-audio :node="node" />
            </block>

            <!--img类型-->
            <block v-else-if="node.tag == 'img'">
                <wx-parse-img :node="node" />
            </block>

            <!--a类型-->
            <block v-else-if="node.tag == 'a'">
                <view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </view>
            </block>

            <!--br类型-->
            <block v-else-if="node.tag == 'br'">
                <text>\n</text>
            </block>

            <!--其他标签-->
            <block v-else>
                <view :class="node.classStr" :style="node.styleStr">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </view>
            </block>

        </block>

        <!--判断是否是文本节点-->
        <block v-else-if="node.node == 'text'">{{node.text}}</block>
    </view>
</template>

<script>
    import wxParseTemplate from './wxParseTemplate5';
    import wxParseImg from './wxParseImg';
    import wxParseVideo from './wxParseVideo';
    import wxParseAudio from './wxParseAudio';

    export default {
        name: 'wxParseTemplate4',
        props: {
            node: {},
        },
        components: {
            wxParseTemplate,
            wxParseImg,
            wxParseVideo,
            wxParseAudio,
        },
        methods: {
            wxParseATap(e) {
                const {
                    href
                } = e.currentTarget.dataset;
                if (!href) return;
                let parent = this.$parent;
                while(!parent.preview || typeof parent.preview !== 'function') {
                    parent = parent.$parent;
                }
                parent.navigate(href, e);
            },
        },
    };
</script>
wxParseTemplate5.vue
<template>
    <view>
        <!--判断是否是标签节点-->
        <block v-if="node.node == 'element'">
            <block v-if="node.tag == 'button'">
                <button type="default" size="mini">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </button>
            </block>

            <!--li类型-->
            <block v-else-if="node.tag == 'li'">
                <view :class="node.classStr" :style="node.styleStr">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </view>
            </block>

            <!--video类型-->
            <block v-else-if="node.tag == 'video'">
                <wx-parse-video :node="node" />
            </block>

            <!--audio类型-->
            <block v-else-if="node.tag == 'audio'">
                <wx-parse-audio :node="node" />
            </block>

            <!--img类型-->
            <block v-else-if="node.tag == 'img'">
                <wx-parse-img :node="node" />
            </block>

            <!--a类型-->
            <block v-else-if="node.tag == 'a'">
                <view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </view>
            </block>

            <!--br类型-->
            <block v-else-if="node.tag == 'br'">
                <text>\n</text>
            </block>

            <!--其他标签-->
            <block v-else>
                <view :class="node.classStr" :style="node.styleStr">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </view>
            </block>

        </block>

        <!--判断是否是文本节点-->
        <block v-else-if="node.node == 'text'">{{node.text}}</block>
    </view>
</template>

<script>
    import wxParseTemplate from './wxParseTemplate6';
    import wxParseImg from './wxParseImg';
    import wxParseVideo from './wxParseVideo';
    import wxParseAudio from './wxParseAudio';

    export default {
        name: 'wxParseTemplate5',
        props: {
            node: {},
        },
        components: {
            wxParseTemplate,
            wxParseImg,
            wxParseVideo,
            wxParseAudio,
        },
        methods: {
            wxParseATap(e) {
                const {
                    href
                } = e.currentTarget.dataset;
                if (!href) return;
                let parent = this.$parent;
                while(!parent.preview || typeof parent.preview !== 'function') {
                    parent = parent.$parent;
                }
                parent.navigate(href, e);
            },
        },
    };
</script>
wxParseTemplate6.vue
<template>
    <view>
        <!--判断是否是标签节点-->
        <block v-if="node.node == 'element'">
            <block v-if="node.tag == 'button'">
                <button type="default" size="mini">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </button>
            </block>

            <!--li类型-->
            <block v-else-if="node.tag == 'li'">
                <view :class="node.classStr" :style="node.styleStr">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </view>
            </block>

            <!--video类型-->
            <block v-else-if="node.tag == 'video'">
                <wx-parse-video :node="node" />
            </block>

            <!--audio类型-->
            <block v-else-if="node.tag == 'audio'">
                <wx-parse-audio :node="node" />
            </block>

            <!--img类型-->
            <block v-else-if="node.tag == 'img'">
                <wx-parse-img :node="node" />
            </block>

            <!--a类型-->
            <block v-else-if="node.tag == 'a'">
                <view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </view>
            </block>

            <!--br类型-->
            <block v-else-if="node.tag == 'br'">
                <text>\n</text>
            </block>

            <!--其他标签-->
            <block v-else>
                <view :class="node.classStr" :style="node.styleStr">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </view>
            </block>

        </block>

        <!--判断是否是文本节点-->
        <block v-else-if="node.node == 'text'">{{node.text}}</block>
    </view>
</template>

<script>
    import wxParseTemplate from './wxParseTemplate7';
    import wxParseImg from './wxParseImg';
    import wxParseVideo from './wxParseVideo';
    import wxParseAudio from './wxParseAudio';

    export default {
        name: 'wxParseTemplate6',
        props: {
            node: {},
        },
        components: {
            wxParseTemplate,
            wxParseImg,
            wxParseVideo,
            wxParseAudio,
        },
        methods: {
            wxParseATap(e) {
                const {
                    href
                } = e.currentTarget.dataset;
                if (!href) return;
                let parent = this.$parent;
                while(!parent.preview || typeof parent.preview !== 'function') {
                    parent = parent.$parent;
                }
                parent.navigate(href, e);
            },
        },
    };
</script>
wxParseTemplate7.vue
<template>
    <view>
        <!--判断是否是标签节点-->
        <block v-if="node.node == 'element'">
            <block v-if="node.tag == 'button'">
                <button type="default" size="mini">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </button>
            </block>

            <!--li类型-->
            <block v-else-if="node.tag == 'li'">
                <view :class="node.classStr" :style="node.styleStr">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </view>
            </block>

            <!--video类型-->
            <block v-else-if="node.tag == 'video'">
                <wx-parse-video :node="node" />
            </block>

            <!--audio类型-->
            <block v-else-if="node.tag == 'audio'">
                <wx-parse-audio :node="node" />
            </block>

            <!--img类型-->
            <block v-else-if="node.tag == 'img'">
                <wx-parse-img :node="node" />
            </block>

            <!--a类型-->
            <block v-else-if="node.tag == 'a'">
                <view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </view>
            </block>

            <!--br类型-->
            <block v-else-if="node.tag == 'br'">
                <text>\n</text>
            </block>

            <!--其他标签-->
            <block v-else>
                <view :class="node.classStr" :style="node.styleStr">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </view>
            </block>

        </block>

        <!--判断是否是文本节点-->
        <block v-else-if="node.node == 'text'">{{node.text}}</block>
    </view>
</template>

<script>
    import wxParseTemplate from './wxParseTemplate8';
    import wxParseImg from './wxParseImg';
    import wxParseVideo from './wxParseVideo';
    import wxParseAudio from './wxParseAudio';

    export default {
        name: 'wxParseTemplate7',
        props: {
            node: {},
        },
        components: {
            wxParseTemplate,
            wxParseImg,
            wxParseVideo,
            wxParseAudio,
        },
        methods: {
            wxParseATap(e) {
                const {
                    href
                } = e.currentTarget.dataset;
                if (!href) return;
                let parent = this.$parent;
                while(!parent.preview || typeof parent.preview !== 'function') {
                    parent = parent.$parent;
                }
                parent.navigate(href, e);
            },
        },
    };
</script>
wxParseTemplate8.vue
<template>
    <view>
        <!--判断是否是标签节点-->
        <block v-if="node.node == 'element'">
            <block v-if="node.tag == 'button'">
                <button type="default" size="mini">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </button>
            </block>

            <!--li类型-->
            <block v-else-if="node.tag == 'li'">
                <view :class="node.classStr" :style="node.styleStr">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </view>
            </block>

            <!--video类型-->
            <block v-else-if="node.tag == 'video'">
                <wx-parse-video :node="node" />
            </block>

            <!--audio类型-->
            <block v-else-if="node.tag == 'audio'">
                <wx-parse-audio :node="node" />
            </block>

            <!--img类型-->
            <block v-else-if="node.tag == 'img'">
                <wx-parse-img :node="node" />
            </block>

            <!--a类型-->
            <block v-else-if="node.tag == 'a'">
                <view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </view>
            </block>

            <!--br类型-->
            <block v-else-if="node.tag == 'br'">
                <text>\n</text>
            </block>

            <!--其他标签-->
            <block v-else>
                <view :class="node.classStr" :style="node.styleStr">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </view>
            </block>

        </block>

        <!--判断是否是文本节点-->
        <block v-else-if="node.node == 'text'">{{node.text}}</block>
    </view>
</template>

<script>
    import wxParseTemplate from './wxParseTemplate9';
    import wxParseImg from './wxParseImg';
    import wxParseVideo from './wxParseVideo';
    import wxParseAudio from './wxParseAudio';

    export default {
        name: 'wxParseTemplate8',
        props: {
            node: {},
        },
        components: {
            wxParseTemplate,
            wxParseImg,
            wxParseVideo,
            wxParseAudio,
        },
        methods: {
            wxParseATap(e) {
                const {
                    href
                } = e.currentTarget.dataset;
                if (!href) return;
                let parent = this.$parent;
                while(!parent.preview || typeof parent.preview !== 'function') {
                    parent = parent.$parent;
                }
                parent.navigate(href, e);
            },
        },
    };
</script>
wxParseTemplate9.vue
<template>
    <view>
        <!--判断是否是标签节点-->
        <block v-if="node.node == 'element'">
            <block v-if="node.tag == 'button'">
                <button type="default" size="mini">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </button>
            </block>

            <!--li类型-->
            <block v-else-if="node.tag == 'li'">
                <view :class="node.classStr" :style="node.styleStr">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </view>
            </block>

            <!--video类型-->
            <block v-else-if="node.tag == 'video'">
                <wx-parse-video :node="node" />
            </block>

            <!--audio类型-->
            <block v-else-if="node.tag == 'audio'">
                <wx-parse-audio :node="node" />
            </block>

            <!--img类型-->
            <block v-else-if="node.tag == 'img'">
                <wx-parse-img :node="node" />
            </block>

            <!--a类型-->
            <block v-else-if="node.tag == 'a'">
                <view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </view>
            </block>

            <!--br类型-->
            <block v-else-if="node.tag == 'br'">
                <text>\n</text>
            </block>

            <!--其他标签-->
            <block v-else>
                <view :class="node.classStr" :style="node.styleStr">
                    <block v-for="(node, index) of node.nodes" :key="index">
                        <wx-parse-template :node="node" />
                    </block>
                </view>
            </block>

        </block>

        <!--判断是否是文本节点-->
        <block v-else-if="node.node == 'text'">{{node.text}}</block>
    </view>
</template>

<script>
    import wxParseTemplate from './wxParseTemplate10';
    import wxParseImg from './wxParseImg';
    import wxParseVideo from './wxParseVideo';
    import wxParseAudio from './wxParseAudio';

    export default {
        name: 'wxParseTemplate9',
        props: {
            node: {},
        },
        components: {
            wxParseTemplate,
            wxParseImg,
            wxParseVideo,
            wxParseAudio,
        },
        methods: {
            wxParseATap(e) {
                const {
                    href
                } = e.currentTarget.dataset;
                if (!href) return;
                let parent = this.$parent;
                while(!parent.preview || typeof parent.preview !== 'function') {
                    parent = parent.$parent;
                }
                parent.navigate(href, e);
            },
        },
    };
</script>
wxParseVideo.vue
<template>
  <!--增加video标签支持,并循环添加-->
  <view :class="node.classStr" :style="node.styleStr">
    <video :class="node.classStr" class="video-video" :src="node.attr.src"></video>
  </view>
</template>

<script>
export default {
  name: 'wxParseVideo',
  props: {
    node: {},
  },
};
</script>
libs
html2json.js
/**
 * html2Json 改造来自: https://github.com/Jxck/html2json
 *
 *
 * author: Di (微信小程序开发工程师)
 * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com)
 *               垂直微信小程序开发交流社区
 *
 * github地址: https://github.com/icindy/wxParse
 *
 * for: 微信小程序富文本解析
 * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184
 */

import wxDiscode from './wxDiscode';
import HTMLParser from './htmlparser';

function makeMap(str) {
  const obj = {};
  const items = str.split(',');
  for (let i = 0; i < items.length; i += 1) obj[items[i]] = true;
  return obj;
}

// Block Elements - HTML 5
const block = makeMap('br,code,address,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,ins,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video');

// Inline Elements - HTML 5
const inline = makeMap('a,abbr,acronym,applet,b,basefont,bdo,big,button,cite,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var');

// Elements that you can, intentionally, leave open
// (and which close themselves)
const closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr');

function removeDOCTYPE(html) {
  const isDocument = /<body.*>([^]*)<\/body>/.test(html);
  return isDocument ? RegExp.$1 : html;
}

function trimHtml(html) {
  return html
    .replace(/<!--.*?-->/gi, '')
    .replace(/\/\*.*?\*\//gi, '')
    .replace(/[ ]+</gi, '<')
    .replace(/<script[^]*<\/script>/gi, '')
    .replace(/<style[^]*<\/style>/gi, '');
}

function getScreenInfo() {
  const screen = {};
  wx.getSystemInfo({
    success: (res) => {
      screen.width = res.windowWidth;
      screen.height = res.windowHeight;
    },
  });
  return screen;
}

function html2json(html, customHandler, imageProp, host) {
  // 处理字符串
  html = removeDOCTYPE(html);
  html = trimHtml(html);
  html = wxDiscode.strDiscode(html);
  // 生成node节点
  const bufArray = [];
  const results = {
    nodes: [],
    imageUrls: [],
  };

    const screen = getScreenInfo();
  function Node(tag) {
    this.node = 'element';
    this.tag = tag;
        
        this.$screen = screen;
  }

  HTMLParser(html, {
    start(tag, attrs, unary) {
      // node for this element
      const node = new Node(tag);

      if (bufArray.length !== 0) {
        const parent = bufArray[0];
        if (parent.nodes === undefined) {
          parent.nodes = [];
        }
      }

      if (block[tag]) {
        node.tagType = 'block';
      } else if (inline[tag]) {
        node.tagType = 'inline';
      } else if (closeSelf[tag]) {
        node.tagType = 'closeSelf';
      }

      node.attr = attrs.reduce((pre, attr) => {
        const { name } = attr;
        let { value } = attr;
        if (name === 'class') {
          node.classStr = value;
        }
        // has multi attibutes
        // make it array of attribute
        if (name === 'style') {
          node.styleStr = value;
        }
        if (value.match(/ /)) {
          value = value.split(' ');
        }

        // if attr already exists
        // merge it
        if (pre[name]) {
          if (Array.isArray(pre[name])) {
            // already array, push to last
            pre[name].push(value);
          } else {
            // single value, make it array
            pre[name] = [pre[name], value];
          }
        } else {
          // not exist, put it
          pre[name] = value;
        }

        return pre;
      }, {});

      // 优化样式相关属性
      if (node.classStr) {
        node.classStr += ` ${node.tag}`;
      } else {
        node.classStr = node.tag;
      }
      if (node.tagType === 'inline') {
        node.classStr += ' inline';
      }

      // 对img添加额外数据
      if (node.tag === 'img') {
        let imgUrl = node.attr.src;
        imgUrl = wxDiscode.urlToHttpUrl(imgUrl, imageProp.domain);
        Object.assign(node.attr, imageProp, {
          src: imgUrl || '',
        });
        if (imgUrl) {
          results.imageUrls.push(imgUrl);
        }
      }

      // 处理a标签属性
      if (node.tag === 'a') {
        node.attr.href = node.attr.href || '';
      }

      // 处理font标签样式属性
      if (node.tag === 'font') {
        const fontSize = [
          'x-small',
          'small',
          'medium',
          'large',
          'x-large',
          'xx-large',
          '-webkit-xxx-large',
        ];
        const styleAttrs = {
          color: 'color',
          face: 'font-family',
          size: 'font-size',
        };
        if (!node.styleStr) node.styleStr = '';
        Object.keys(styleAttrs).forEach((key) => {
          if (node.attr[key]) {
            const value = key === 'size' ? fontSize[node.attr[key] - 1] : node.attr[key];
            node.styleStr += `${styleAttrs[key]}: ${value};`;
          }
        });
      }

      // 临时记录source资源
      if (node.tag === 'source') {
        results.source = node.attr.src;
      }

      if (customHandler.start) {
        customHandler.start(node, results);
      }

      if (unary) {
        // if this tag doesn't have end tag
        // like <img src="hoge.png"/>
        // add to parents
        const parent = bufArray[0] || results;
        if (parent.nodes === undefined) {
          parent.nodes = [];
        }
        parent.nodes.push(node);
      } else {
        bufArray.unshift(node);
      }
    },
    end(tag) {
      // merge into parent tag
      const node = bufArray.shift();
      if (node.tag !== tag) {
        // console.error('invalid state: mismatch end tag');
      }

      // 当有缓存source资源时于于video补上src资源
      if (node.tag === 'video' && results.source) {
        node.attr.src = results.source;
        delete results.source;
      }

      if (customHandler.end) {
        customHandler.end(node, results);
      }

      if (bufArray.length === 0) {
        results.nodes.push(node);
      } else {
        const parent = bufArray[0];
        if (!parent.nodes) {
          parent.nodes = [];
        }
        parent.nodes.push(node);
      }
    },
    chars(text) {
      if (!text.trim()) return;

      const node = {
        node: 'text',
        text,
      };

      if (customHandler.chars) {
        customHandler.chars(node, results);
      }

      if (bufArray.length === 0) {
        results.nodes.push(node);
      } else {
        const parent = bufArray[0];
        if (parent.nodes === undefined) {
          parent.nodes = [];
        }
        parent.nodes.push(node);
      }
    },
  });

  return results;
}

export default html2json;
htmlparser.js
/**
 *
 * htmlParser改造自: https://github.com/blowsie/Pure-JavaScript-HTML5-Parser
 *
 * author: Di (微信小程序开发工程师)
 * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com)
 *               垂直微信小程序开发交流社区
 *
 * github地址: https://github.com/icindy/wxParse
 *
 * for: 微信小程序富文本解析
 * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184
 */
// Regular Expressions for parsing tags and attributes

const startTag = /^<([-A-Za-z0-9_]+)((?:\s+[a-zA-Z0-9_:][-a-zA-Z0-9_:.]*(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/;
const endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/;
const attr = /([a-zA-Z0-9_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g;

function makeMap(str) {
  const obj = {};
  const items = str.split(',');
  for (let i = 0; i < items.length; i += 1) obj[items[i]] = true;
  return obj;
}

// Empty Elements - HTML 5
const empty = makeMap('area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr');

// Block Elements - HTML 5
const block = makeMap('address,code,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,ins,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video');

// Inline Elements - HTML 5
const inline = makeMap('a,abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var');

// Elements that you can, intentionally, leave open
// (and which close themselves)
const closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr');

// Attributes that have their values filled in disabled="disabled"
const fillAttrs = makeMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected');

function HTMLParser(html, handler) {
  let index;
  let chars;
  let match;
  let last = html;
  const stack = [];

  stack.last = () => stack[stack.length - 1];

  function parseEndTag(tag, tagName) {
    // If no tag name is provided, clean shop
    let pos;
    if (!tagName) {
      pos = 0;
    } else {
      // Find the closest opened tag of the same type
      tagName = tagName.toLowerCase();
      for (pos = stack.length - 1; pos >= 0; pos -= 1) {
        if (stack[pos] === tagName) break;
      }
    }
    if (pos >= 0) {
      // Close all the open elements, up the stack
      for (let i = stack.length - 1; i >= pos; i -= 1) {
        if (handler.end) handler.end(stack[i]);
      }

      // Remove the open elements from the stack
      stack.length = pos;
    }
  }

  function parseStartTag(tag, tagName, rest, unary) {
    tagName = tagName.toLowerCase();

    if (block[tagName]) {
      while (stack.last() && inline[stack.last()]) {
        parseEndTag('', stack.last());
      }
    }

    if (closeSelf[tagName] && stack.last() === tagName) {
      parseEndTag('', tagName);
    }

    unary = empty[tagName] || !!unary;

    if (!unary) stack.push(tagName);

    if (handler.start) {
      const attrs = [];

      rest.replace(attr, function genAttr(matches, name) {
        const value = arguments[2] || arguments[3] || arguments[4] || (fillAttrs[name] ? name : '');

        attrs.push({
          name,
          value,
          escaped: value.replace(/(^|[^\\])"/g, '$1\\"'), // "
        });
      });

      if (handler.start) {
        handler.start(tagName, attrs, unary);
      }
    }
  }

  while (html) {
    chars = true;

    if (html.indexOf('</') === 0) {
      match = html.match(endTag);

      if (match) {
        html = html.substring(match[0].length);
        match[0].replace(endTag, parseEndTag);
        chars = false;
      }

      // start tag
    } else if (html.indexOf('<') === 0) {
      match = html.match(startTag);

      if (match) {
        html = html.substring(match[0].length);
        match[0].replace(startTag, parseStartTag);
        chars = false;
      }
    }

    if (chars) {
      index = html.indexOf('<');
      let text = '';
      while (index === 0) {
        text += '<';
        html = html.substring(1);
        index = html.indexOf('<');
      }
      text += index < 0 ? html : html.substring(0, index);
      html = index < 0 ? '' : html.substring(index);

      if (handler.chars) handler.chars(text);
    }

    if (html === last) throw new Error(`Parse Error: ${html}`);
    last = html;
  }

  // Clean up any remaining tags
  parseEndTag();
}

export default HTMLParser;
wxDiscode.js
// HTML 支持的数学符号
function strNumDiscode(str) {
  str = str.replace(/&forall;/g, '∀');
  str = str.replace(/&part;/g, '∂');
  str = str.replace(/&exist;/g, '∃');
  str = str.replace(/&empty;/g, '∅');
  str = str.replace(/&nabla;/g, '∇');
  str = str.replace(/&isin;/g, '∈');
  str = str.replace(/&notin;/g, '∉');
  str = str.replace(/&ni;/g, '∋');
  str = str.replace(/&prod;/g, '∏');
  str = str.replace(/&sum;/g, '∑');
  str = str.replace(/&minus;/g, '−');
  str = str.replace(/&lowast;/g, '∗');
  str = str.replace(/&radic;/g, '√');
  str = str.replace(/&prop;/g, '∝');
  str = str.replace(/&infin;/g, '∞');
  str = str.replace(/&ang;/g, '∠');
  str = str.replace(/&and;/g, '∧');
  str = str.replace(/&or;/g, '∨');
  str = str.replace(/&cap;/g, '∩');
  str = str.replace(/&cup;/g, '∪');
  str = str.replace(/&int;/g, '∫');
  str = str.replace(/&there4;/g, '∴');
  str = str.replace(/&sim;/g, '∼');
  str = str.replace(/&cong;/g, '≅');
  str = str.replace(/&asymp;/g, '≈');
  str = str.replace(/&ne;/g, '≠');
  str = str.replace(/&le;/g, '≤');
  str = str.replace(/&ge;/g, '≥');
  str = str.replace(/&sub;/g, '⊂');
  str = str.replace(/&sup;/g, '⊃');
  str = str.replace(/&nsub;/g, '⊄');
  str = str.replace(/&sube;/g, '⊆');
  str = str.replace(/&supe;/g, '⊇');
  str = str.replace(/&oplus;/g, '⊕');
  str = str.replace(/&otimes;/g, '⊗');
  str = str.replace(/&perp;/g, '⊥');
  str = str.replace(/&sdot;/g, '⋅');
  return str;
}

// HTML 支持的希腊字母
function strGreeceDiscode(str) {
  str = str.replace(/&Alpha;/g, 'Α');
  str = str.replace(/&Beta;/g, 'Β');
  str = str.replace(/&Gamma;/g, 'Γ');
  str = str.replace(/&Delta;/g, 'Δ');
  str = str.replace(/&Epsilon;/g, 'Ε');
  str = str.replace(/&Zeta;/g, 'Ζ');
  str = str.replace(/&Eta;/g, 'Η');
  str = str.replace(/&Theta;/g, 'Θ');
  str = str.replace(/&Iota;/g, 'Ι');
  str = str.replace(/&Kappa;/g, 'Κ');
  str = str.replace(/&Lambda;/g, 'Λ');
  str = str.replace(/&Mu;/g, 'Μ');
  str = str.replace(/&Nu;/g, 'Ν');
  str = str.replace(/&Xi;/g, 'Ν');
  str = str.replace(/&Omicron;/g, 'Ο');
  str = str.replace(/&Pi;/g, 'Π');
  str = str.replace(/&Rho;/g, 'Ρ');
  str = str.replace(/&Sigma;/g, 'Σ');
  str = str.replace(/&Tau;/g, 'Τ');
  str = str.replace(/&Upsilon;/g, 'Υ');
  str = str.replace(/&Phi;/g, 'Φ');
  str = str.replace(/&Chi;/g, 'Χ');
  str = str.replace(/&Psi;/g, 'Ψ');
  str = str.replace(/&Omega;/g, 'Ω');

  str = str.replace(/&alpha;/g, 'α');
  str = str.replace(/&beta;/g, 'β');
  str = str.replace(/&gamma;/g, 'γ');
  str = str.replace(/&delta;/g, 'δ');
  str = str.replace(/&epsilon;/g, 'ε');
  str = str.replace(/&zeta;/g, 'ζ');
  str = str.replace(/&eta;/g, 'η');
  str = str.replace(/&theta;/g, 'θ');
  str = str.replace(/&iota;/g, 'ι');
  str = str.replace(/&kappa;/g, 'κ');
  str = str.replace(/&lambda;/g, 'λ');
  str = str.replace(/&mu;/g, 'μ');
  str = str.replace(/&nu;/g, 'ν');
  str = str.replace(/&xi;/g, 'ξ');
  str = str.replace(/&omicron;/g, 'ο');
  str = str.replace(/&pi;/g, 'π');
  str = str.replace(/&rho;/g, 'ρ');
  str = str.replace(/&sigmaf;/g, 'ς');
  str = str.replace(/&sigma;/g, 'σ');
  str = str.replace(/&tau;/g, 'τ');
  str = str.replace(/&upsilon;/g, 'υ');
  str = str.replace(/&phi;/g, 'φ');
  str = str.replace(/&chi;/g, 'χ');
  str = str.replace(/&psi;/g, 'ψ');
  str = str.replace(/&omega;/g, 'ω');
  str = str.replace(/&thetasym;/g, 'ϑ');
  str = str.replace(/&upsih;/g, 'ϒ');
  str = str.replace(/&piv;/g, 'ϖ');
  str = str.replace(/&middot;/g, '·');
  return str;
}

function strcharacterDiscode(str) {
  // 加入常用解析
  str = str.replace(/&nbsp;/g, ' ');
  str = str.replace(/&ensp;/g, ' ');
  str = str.replace(/&emsp;/g, ' ');
  str = str.replace(/&quot;/g, "'");
  str = str.replace(/&amp;/g, '&');
  str = str.replace(/&lt;/g, '<');
  str = str.replace(/&gt;/g, '>');
  str = str.replace(/&#8226;/g, '•');

  return str;
}

// HTML 支持的其他实体
function strOtherDiscode(str) {
  str = str.replace(/&OElig;/g, 'Œ');
  str = str.replace(/&oelig;/g, 'œ');
  str = str.replace(/&Scaron;/g, 'Š');
  str = str.replace(/&scaron;/g, 'š');
  str = str.replace(/&Yuml;/g, 'Ÿ');
  str = str.replace(/&fnof;/g, 'ƒ');
  str = str.replace(/&circ;/g, 'ˆ');
  str = str.replace(/&tilde;/g, '˜');
  str = str.replace(/&ensp;/g, '');
  str = str.replace(/&emsp;/g, '');
  str = str.replace(/&thinsp;/g, '');
  str = str.replace(/&zwnj;/g, '');
  str = str.replace(/&zwj;/g, '');
  str = str.replace(/&lrm;/g, '');
  str = str.replace(/&rlm;/g, '');
  str = str.replace(/&ndash;/g, '–');
  str = str.replace(/&mdash;/g, '—');
  str = str.replace(/&lsquo;/g, '‘');
  str = str.replace(/&rsquo;/g, '’');
  str = str.replace(/&sbquo;/g, '‚');
  str = str.replace(/&ldquo;/g, '“');
  str = str.replace(/&rdquo;/g, '”');
  str = str.replace(/&bdquo;/g, '„');
  str = str.replace(/&dagger;/g, '†');
  str = str.replace(/&Dagger;/g, '‡');
  str = str.replace(/&bull;/g, '•');
  str = str.replace(/&hellip;/g, '…');
  str = str.replace(/&permil;/g, '‰');
  str = str.replace(/&prime;/g, '′');
  str = str.replace(/&Prime;/g, '″');
  str = str.replace(/&lsaquo;/g, '‹');
  str = str.replace(/&rsaquo;/g, '›');
  str = str.replace(/&oline;/g, '‾');
  str = str.replace(/&euro;/g, '€');
  str = str.replace(/&trade;/g, '™');

  str = str.replace(/&larr;/g, '←');
  str = str.replace(/&uarr;/g, '↑');
  str = str.replace(/&rarr;/g, '→');
  str = str.replace(/&darr;/g, '↓');
  str = str.replace(/&harr;/g, '↔');
  str = str.replace(/&crarr;/g, '↵');
  str = str.replace(/&lceil;/g, '⌈');
  str = str.replace(/&rceil;/g, '⌉');

  str = str.replace(/&lfloor;/g, '⌊');
  str = str.replace(/&rfloor;/g, '⌋');
  str = str.replace(/&loz;/g, '◊');
  str = str.replace(/&spades;/g, '♠');
  str = str.replace(/&clubs;/g, '♣');
  str = str.replace(/&hearts;/g, '♥');

  str = str.replace(/&diams;/g, '♦');
  str = str.replace(/&#39;/g, "'");
  return str;
}

function strDiscode(str) {
  str = strNumDiscode(str);
  str = strGreeceDiscode(str);
  str = strcharacterDiscode(str);
  str = strOtherDiscode(str);
  return str;
}

function urlToHttpUrl(url, domain) {
  if (/^\/\//.test(url)) {
    return `https:${url}`;
  } else if (/^\//.test(url)) {
    return `https://${domain}${url}`;
  }
  return url;
}

export default {
  strDiscode,
  urlToHttpUrl,
};
readme.md
## uParse 适用于 uni-app/mpvue 的富文本解析组件

> 支持 Html、Markdown 解析,Fork自: [mpvue-wxParse](https://github.com/F-loat/mpvue-wxParse)


## 属性

| 名称             | 类型          | 默认值        | 描述               |
| -----------------|--------------- | ------------- | ----------------  |
| loading          | Boolean        | false         | 数据加载状态       |
| className        | String         | —             | 自定义 class 名称  |
| content          | String         | —             | 渲染内容           |
| noData           | String         | 数据不能为空   | 空数据时的渲染展示  |
| startHandler     | Function       | 见源码         | 自定义 parser 函数 |
| endHandler       | Function       | null          | 自定义 parser 函数 |
| charsHandler     | Function       | null          | 自定义 parser 函数 |
| imageProp        | Object         | 见下文        | 图片相关参数        |

### 自定义 parser 函数具体介绍

* 传入的参数为当前节点 `node` 对象及解析结果 `results` 对象,例如 `startHandler(node, results)`
* 无需返回值,通过对传入的参数直接操作来完成需要的改动
* 自定义函数会在原解析函数处理之后执行

### imageProp 对象具体属性

| 名称              | 类型           | 默认值        | 描述                |
| -----------------|--------------- | ------------- | ------------------ |
| mode             | String         | 'aspectFit'   | 图片裁剪、缩放的模式 |
| padding          | Number         | 0             | 图片内边距          |
| lazyLoad         | Boolean        | false         | 图片懒加载          |
| domain           | String         | ''            | 图片服务域名        |

## 事件

| 名称             | 参数              | 描述              |
| -----------------|----------------- | ----------------  |
| preview          | 图片地址,原始事件 | 预览图片时触发     |
| navigate         | 链接地址,原始事件 | 点击链接时触发     |

## 基本使用方法

<template>
<div>

<u-parse :content="article" @preview="preview" @navigate="navigate" />

</div>
</template>

<script>
import uParse from '@/components/u-parse/u-parse.vue'

export default {
components: {

uParse

},
data () {

return {
  article: '<div>我是HTML代码</div>'
}

},
methods: {

preview(src, e) {
  // do something
},
navigate(href, e) {
  // do something
}

}
}
</script>

<style>
@import url("@/components/u-parse/u-parse.css");
</style>



## 渲染 Markdown

> 先将 markdown 转换为 html 即可

npm install marked

import marked from 'marked'
import uParse from '@/components/u-parse/u-parse.vue'

export default {
components: {

uParse

},
data () {

return {
  article: marked(`#hello, markdown!`)
}

}
}

u-parse.css
/**
 * author: Di (微信小程序开发工程师)
 * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com)
 *         垂直微信小程序开发交流社区
 *
 * github地址: https://github.com/icindy/wxParse
 *
 * for: 微信小程序富文本解析
 * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184
 */

.wxParse {
  width: 100%;
  font-family: Helvetica, sans-serif;
  font-size: 30upx;
  color: #666;
  line-height: 1.8;
}

.wxParse view {
  word-break: hyphenate;
}

.wxParse .inline {
  display: inline;
  margin: 0;
  padding: 0;
}

.wxParse .div {
  margin: 0;
  padding: 0;
}

.wxParse .h1 .text {
  font-size: 2em;
  margin: 0.67em 0;
}
.wxParse .h2 .text {
  font-size: 1.5em;
  margin: 0.83em 0;
}
.wxParse .h3 .text {
  font-size: 1.17em;
  margin: 1em 0;
}
.wxParse .h4 .text {
  margin: 1.33em 0;
}
.wxParse .h5 .text {
  font-size: 0.83em;
  margin: 1.67em 0;
}
.wxParse .h6 .text {
  font-size: 0.67em;
  margin: 2.33em 0;
}

.wxParse .h1 .text,
.wxParse .h2 .text,
.wxParse .h3 .text,
.wxParse .h4 .text,
.wxParse .h5 .text,
.wxParse .h6 .text,
.wxParse .b,
.wxParse .strong {
  font-weight: bolder;
}


.wxParse .p {
  margin: 1em 0;
}

.wxParse .i,
.wxParse .cite,
.wxParse .em,
.wxParse .var,
.wxParse .address {
  font-style: italic;
}

.wxParse .pre,
.wxParse .tt,
.wxParse .code,
.wxParse .kbd,
.wxParse .samp {
  font-family: monospace;
}
.wxParse .pre {
  overflow: auto;
  background: #f5f5f5;
  padding: 16upx;
  white-space: pre;
  margin: 1em 0upx;
}
.wxParse .code {
  display: inline;
  background: #f5f5f5;
}

.wxParse .big {
  font-size: 1.17em;
}

.wxParse .small,
.wxParse .sub,
.wxParse .sup {
  font-size: 0.83em;
}

.wxParse .sub {
  vertical-align: sub;
}
.wxParse .sup {
  vertical-align: super;
}

.wxParse .s,
.wxParse .strike,
.wxParse .del {
  text-decoration: line-through;
}

.wxParse .strong,
.wxParse .s {
  display: inline;
}

.wxParse .a {
  color: deepskyblue;
}

.wxParse .video {
  text-align: center;
  margin: 22upx 0;
}

.wxParse .video-video {
  width: 100%;
}

.wxParse .img {
  display: inline-block;
  width: 0;
  height: 0;
  max-width: 100%;
  overflow: hidden;
}

.wxParse .blockquote {
  margin: 10upx 0;
  padding: 22upx 0 22upx 22upx;
  font-family: Courier, Calibri, "宋体";
  background: #f5f5f5;
  border-left: 6upx solid #dbdbdb;
}
.wxParse .blockquote .p {
  margin: 0;
}

.wxParse .ul, .wxParse .ol {
  display: block;
  margin: 1em 0;
  padding-left: 33upx;
}
.wxParse .ol {
  list-style-type: disc;
}
.wxParse .ol {
  list-style-type: decimal;
}
.wxParse .ol>weixin-parse-template,.wxParse .ul>weixin-parse-template {
  display: list-item;
  align-items: baseline;
  text-align: match-parent;
}

.wxParse .ol>.li,.wxParse .ul>.li {
  display: list-item;
  align-items: baseline;
  text-align: match-parent;
}
.wxParse .ul .ul, .wxParse .ol .ul {
  list-style-type: circle;
}
.wxParse .ol .ol .ul, .wxParse .ol .ul .ul, .wxParse .ul .ol .ul, .wxParse .ul .ul .ul {
    list-style-type: square;
}

.wxParse .u {
  text-decoration: underline;
}
.wxParse .hide {
  display: none;
}
.wxParse .del {
  display: inline;
}
.wxParse .figure {
  overflow: hidden;
}

.wxParse .table {
  width: 100%;
}
.wxParse .thead, .wxParse .tfoot, .wxParse .tr {
  display: flex;
  flex-direction: row;
}
.wxParse .tr {
  width:100%;
  display: flex;
  border-right: 2upx solid #e0e0e0;
  border-bottom: 2upx solid #e0e0e0;
}
.wxParse .th,
.wxParse .td {
  display: flex;
  width: 1276upx;
  overflow: auto;
  flex: 1;
  padding: 11upx;
  border-left: 2upx solid #e0e0e0;
}
.wxParse .td:last {
  border-top: 2upx solid #e0e0e0;
}
.wxParse .th {
  background: #f0f0f0;
  border-top: 2upx solid #e0e0e0;
}
u-parse.vue
<!--**
 * forked from:https://github.com/F-loat/mpvue-wxParse
 *
 * github地址: https://github.com/dcloudio/uParse
 *
 * for: uni-app框架下 富文本解析
 */-->

<template>
<!--基础元素-->
<div class="wxParse" :class="className" v-if="!loading">
  <block v-for="(node,index) of nodes" :key="index">
    <wxParseTemplate :node="node" />
  </block>
</div>
</template>

<script>
import HtmlToJson from './libs/html2json';
import wxParseTemplate from './components/wxParseTemplate0';

export default {
  name: 'wxParse',
  props: {
    loading: {
      type: Boolean,
      default: false,
    },
    className: {
      type: String,
      default: '',
    },
    content: {
      type: String,
      default: '',
    },
    noData: {
      type: String,
      default: '<div style="color: #999;text-align: center;">加载中...</div>',
    },
    startHandler: {
      type: Function,
      default() {
        return (node) => {
          node.attr.class = null;
          node.attr.style = null;
        };
      },
    },
    endHandler: {
      type: Function,
      default: null,
    },
    charsHandler: {
      type: Function,
      default: null,
    },
    imageProp: {
      type: Object,
      default() {
        return {
          mode: 'aspectFit',
          padding: 0,
          lazyLoad: false,
          domain: '',
        };
      },
    },
  },
  components: {
    wxParseTemplate,
  },
  data() {
    return {
      imageUrls: [],
    };
  },
  computed: {
    nodes() {
      const {
        content,
        noData,
        imageProp,
        startHandler,
        endHandler,
        charsHandler,
      } = this;
      const parseData = content || noData;
      const customHandler = {
        start: startHandler,
        end: endHandler,
        chars: charsHandler,
      };
      const results = HtmlToJson(parseData, customHandler, imageProp, this);
      this.imageUrls = results.imageUrls;
      return results.nodes;
    },
  },
  methods: {
    navigate(href, $event) {
      this.$emit('navigate', href, $event);
    },
    preview(src, $event) {
      if (!this.imageUrls.length) return;
      uni.previewImage({
        current: src,
        urls: this.imageUrls,
      });
      this.$emit('preview', src, $event);
    },
    removeImageUrl(src) {
      const { imageUrls } = this;
      imageUrls.splice(imageUrls.indexOf(src), 1);
    },
  },
};
</script>

uni-countdown

readme.md
### CountDown 倒计时

倒计时组件,组件名:``uni-countdown``,代码块: uCountDown。

**使用方式:**

在 ``script`` 中引用组件 

import uniCountdown from "@/components/uni-countdown/uni-countdown.vue"
export default {

components: {uniCountdown}

}


一般用法

<uni-countdown

:day="1" 
:hour="1" 
:minute="12" 
:second="40">

</uni-countdown>


不显示天数

<uni-countdown

:show-day="false" 
:hour="12" 
:minute="12" 
:second="12">

</uni-countdown>


修改颜色

<uni-countdown

color="#FFFFFF" 
background-color="#00B26A" 
border-color="#00B26A" 
:day="1" 
:hour="2" 
:minute="30" 
:second="0">

</uni-countdown>


实际效果参考:[https://github.com/dcloudio/uni-ui](https://github.com/dcloudio/uni-ui)

**uniCountDown 属性说明:**

|属性名|类型|默认值    |说明|
|---|----|---|---|
|background-color|String|#FFFFFF|背景色|
|border-color|String|#000000|边框颜色|
|color    |String    |#000000|文字颜色|
|splitor-color|String|#000000|割符号颜色|
|day|Number|0|天数|
|hour|Number|0|小时|
|minute|Number|0|分钟|
|second|Number|0|秒|
|show-day|Boolean|true|是否显示天数|
|show-colon|Boolean|true|是否以冒号为分隔符|

**uniCountDown 事件说明:**

|事件称名|说明|返回参数|
|---|----|---|
|timeup|倒计时时间到触发事件|-|
uni-countdown.vue
<template>
    <view class="uni-countdown">
        <view v-if="showDay && d!=0" class="uni-countdown__number" :style="{borderColor:borderColor, color:color, background:backgroundColor}">{{d}}</view>
        <view v-if="showDay  && d!=0" class="uni-countdown__splitor" :style="{color:textColor}">天</view>
        <view class="uni-countdown__number" :style="{borderColor:borderColor, color:color, background:backgroundColor}">{{h}}</view>
        <view class="uni-countdown__splitor" :style="{color:textColor}">{{showColon ? ':' : '时'}}</view>
        <view class="uni-countdown__number" :style="{borderColor:borderColor, color:color, background:backgroundColor}">{{i}}</view>
        <view class="uni-countdown__splitor" :style="{color:textColor}">{{showColon ? ':' : '分'}}</view>
        <view class="uni-countdown__number" :style="{borderColor:borderColor, color:color, background:backgroundColor}">{{s}}</view>
        <view v-if="!showColon" class="uni-countdown__splitor" :style="{color:textColor}">秒</view>
    </view>
</template>
<script>
    export default {
        name: "uni-countdown",
        props: {
            showDay: {
                type: Boolean,
                default: true
            },
            showColon: {
                type: Boolean,
                default: true
            },
            backgroundColor: {
                type: String,
                default: "#FFFFFF"
            },
            borderColor: {
                type: String,
                default: "#000000"
            },
            color: {
                type: String,
                // value: "#000000"
            },
            textColor: {
                type: String,
                default: "#000000"
            },
            splitorColor: {
                type: String,
                default: "#000"
            },
            day: {
                type: Number,
                default: 0
            },
            hour: {
                type: Number,
                default: 0
            },
            minute: {
                type: Number,
                default: 0
            },
            second: {
                type: Number,
                default: 0
            }
        },
        data() {
            return {
                timer: null,
                d: '00',
                h: '00',
                i: '00',
                s: '00',
                leftTime: 0,
                seconds: 0
            }
        },
        created: function(e) {
            this.seconds = this.toSeconds(this.day, this.hour, this.minute, this.second)
            this.countDown()
            this.timer = setInterval(() => {
                this.seconds--
                if (this.seconds < 0) {
                    this.timeUp()
                    return
                }
                this.countDown()
            }, 1000)
        },
        beforeDestroy() {
            clearInterval(this.timer)
        },
        methods: {
            toSeconds(day, hours, minutes, seconds) {
                return (day * 60 * 60 * 24) + (hours * 60 * 60) + (minutes * 60) + seconds
            },
            timeUp() {
                clearInterval(this.timer)
                this.$emit('timeup')
            },
            countDown() {
                let seconds = this.seconds
                let [day, hour, minute, second] = [0, 0, 0, 0]
                if (seconds > 0) {
                    day = Math.floor(seconds / (60 * 60 * 24))
                    hour = Math.floor(seconds / (60 * 60)) - (day * 24)
                    minute = Math.floor(seconds / 60) - (day * 24 * 60) - (hour * 60)
                    second = Math.floor(seconds) - (day * 24 * 60 * 60) - (hour * 60 * 60) - (minute * 60)
                } else {
                    this.timeUp()
                }
                if (day < 10) {
                    day = '0' + day
                }
                if (hour < 10) {
                    hour = '0' + hour
                }
                if (minute < 10) {
                    minute = '0' + minute
                }
                if (second < 10) {
                    second = '0' + second
                }
                this.d = day
                this.h = hour
                this.i = minute
                this.s = second
            }
        }
    }
</script>
<style lang="scss">
    $countdown-height:44upx;

    .uni-countdown {
        padding: 2upx 0;
        display: inline-flex;
        flex-wrap: nowrap;
        justify-content: center;

        &__splitor {
            justify-content: center;
            line-height: $countdown-height;
            padding: 0 5upx;
            font-size: 24upx;
            // color: #d0d0d0;
        }

        &__number {
            line-height: $countdown-height;
            justify-content: center;
            height: $countdown-height;
            border-radius: $uni-border-radius-base;
            // margin: 0 5upx;
            font-size:  24upx;
            // border: 1px solid #000000;
            font-size: $uni-font-size-sm;
            // padding: 0 10upx;
        }
    }
</style>

uni-fab

uni-fab.vue
<template>
    <view>
        <view
            class="fab-box fab" 
            :class="{
                leftBottom: leftBottom,
                rightBottom: rightBottom,
                leftTop: leftTop,
                rightTop: rightTop
            }"
        >
            <view
                class="fab-circle"
                :class="{
                    left: horizontal === 'left' && direction === 'horizontal',
                    top: vertical === 'top' && direction === 'vertical',
                    bottom: vertical === 'bottom' && direction === 'vertical',
                    right: horizontal === 'right' && direction === 'horizontal'
                }"
                :style="{ 'background-color': styles.buttonColor }"
                @click="open"
            >
                <image class="icon icon-jia" src="../../../static/image/menu.png" mode="" :class="{ active: showContent }"></image>
                <!-- <text class="icon icon-jia" :class="{ active: showContent }"></text> -->
            </view>
            <view
                class="fab-content"
                :class="{
                    left: horizontal === 'left',
                    right: horizontal === 'right',
                    flexDirection: direction === 'vertical',
                    flexDirectionStart: flexDirectionStart,
                    flexDirectionEnd: flexDirectionEnd
                }"
                :style="{ width: boxWidth, height: boxHeight, background: styles.backgroundColor }"
            >
                <view v-if="flexDirectionStart || horizontalLeft" class="fab-item first"></view>
                <view
                    class="fab-item"
                    v-for="(item, index) in content"
                    :key="index"
                    :class="{ active: showContent }"
                    :style="{
                        color: item.active ? styles.selectedColor : styles.color
                    }"
                    @click="taps(index, item)"
                >
                    <image
                        class="content-image icon"
                        :src="item.active ? item.selectedIconPath : item.iconPath"
                        mode=""
                    ></image>
                    <text class="text">{{ item.text }}</text>
                </view>
                <view v-if="flexDirectionEnd || horizontalRight" class="fab-item first"></view>
            </view>
        </view>
    </view>
</template>

<script>
export default {
    props: {
        pattern: {
            type: Object,
            default: () => {
                return {};
            }
        },
        horizontal: {
            type: String,
            default: 'left'
        },
        vertical: {
            type: String,
            default: 'bottom'
        },
        direction: {
            type: String,
            default: 'horizontal'
        },
        content: {
            type: Array,
            default: () => {
                return [];
            }
        }
    },
    data() {
        return {
            fabShow: false,
            flug: true,
            showContent: false,
            styles: {
                color: '#3c3e49',
                selectedColor: '#007AFF',
                backgroundColor: '#fff',
                buttonColor: '#3c3e49'
            }
        };
    },
    created() {
        if (this.top === 0) {
            this.fabShow = true;
        }
        // 初始化样式
        this.styles = Object.assign({}, this.styles, this.pattern);
    },
    methods: {
        open() {
            this.showContent = !this.showContent;
        },
        /**
         * 按钮点击事件
         */
        taps(index, item) {
            this.$emit('trigger', {
                index,
                item
            });
        },
        /**
         * 获取 位置信息
         */
        getPosition(types, paramA, paramB) {
            if (types === 0) {
                return this.horizontal === paramA && this.vertical === paramB;
            } else if (types === 1) {
                return this.direction === paramA && this.vertical === paramB;
            } else if (types === 2) {
                return this.direction === paramA && this.horizontal === paramB;
            } else {
                return this.showContent && this.direction === paramA
                    ? this.contentWidth
                    : this.contentWidthMin;
            }
        }
    },
    watch: {
        pattern(newValue, oldValue) {
            // console.log(JSON.stringify(newValue));
            this.styles = Object.assign({}, this.styles, newValue);
        }
    },
    computed: {
        contentWidth(e) {
            return uni.upx2px((this.content.length + 1) * 90 + 20) + 'px';
        },
        contentWidthMin() {
            return uni.upx2px(90) + 'px';
        },
        // 动态计算宽度
        boxWidth() {
            return this.getPosition(3, 'horizontal');
        },
        // 动态计算高度
        boxHeight() {
            return this.getPosition(3, 'vertical');
        },
        // 计算左下位置
        leftBottom() {
            return this.getPosition(0, 'left', 'bottom');
        },
        // 计算右下位置
        rightBottom() {
            return this.getPosition(0, 'right', 'bottom');
        },
        // 计算左上位置
        leftTop() {
            return this.getPosition(0, 'left', 'top');
        },
        rightTop() {
            return this.getPosition(0, 'right', 'top');
        },
        flexDirectionStart() {
            return this.getPosition(1, 'vertical', 'top');
        },
        flexDirectionEnd() {
            return this.getPosition(1, 'vertical', 'bottom');
        },
        horizontalLeft() {
            return this.getPosition(2, 'horizontal', 'left');
        },
        horizontalRight() {
            return this.getPosition(2, 'horizontal', 'right');
        }
    }
};
</script>

<style scoped>
.fab-box {
    position: fixed;
    display: flex;
    justify-content: center;
    align-items: center;
    z-index: 2;
}

.fab-box.top {
    width: 60upx;
    height: 60upx;
    right: 30upx;
    bottom: 60upx;
    border: 1px #5989b9 solid;
    background: #6699cc;
    border-radius: 10upx;
    color: #fff;
    transition: all 0.3;
    opacity: 0;
}

.fab-box.active {
    opacity: 1;
}

.fab-box.fab {
    z-index: 10;
}

.fab-box.fab.leftBottom {
    left: 30upx;
    bottom: 130upx;
}

.fab-box.fab.leftTop {
    left: 30upx;
    top: 80upx;
    /* #ifdef H5 */
    top: calc(80upx + var(--window-top));
    /* #endif */
}

.fab-box.fab.rightBottom {
    right: 30upx;
    bottom: 130upx;
}

.fab-box.fab.rightTop {
    right: 30upx;
    top: 80upx;
    /* #ifdef H5 */
    top: calc(80upx + var(--window-top));
    /* #endif */
}

.fab-circle {
    display: flex;
    justify-content: center;
    align-items: center;
    position: absolute;
    width: 90upx;
    height: 90upx;
    background: #3c3e49;
    /* background: #5989b9; */
    border-radius: 50%;
    box-shadow: 0 0 5px 2px rgba(0, 0, 0, 0.2);
    z-index: 11;
}

.fab-circle.left {
    left: 0;
}

.fab-circle.right {
    right: 0;
}

.fab-circle.top {
    top: 0;
}

.fab-circle.bottom {
    bottom: 0;
}

.fab-circle .icon-jia {
    color: #ffffff;
    font-size: 50upx;
    transition: all 0.3s;
}

.fab-circle .icon-jia.active {
    transform: rotate(90deg);
}

.fab-content {
    background: #6699cc;
    box-sizing: border-box;
    display: flex;
    border-radius: 100upx;
    overflow: hidden;
    box-shadow: 0 0 5px 2px rgba(0, 0, 0, 0.1);
    transition: all 0.2s;
    width: 110upx;
}

.fab-content.left {
    justify-content: flex-start;
}

.fab-content.right {
    justify-content: flex-end;
}

.fab-content.flexDirection {
    flex-direction: column;
    justify-content: flex-end;
}

.fab-content.flexDirectionStart {
    flex-direction: column;
    justify-content: flex-start;
}

.fab-content.flexDirectionEnd {
    flex-direction: column;
    justify-content: flex-end;
}

.fab-content .fab-item {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    width: 90upx;
    height: 90upx;
    font-size: 24upx;
    color: #fff;
    opacity: 0;
    transition: opacity 0.2s;
}

.fab-content .fab-item.active {
    opacity: 1;
}

.fab-content .fab-item .content-image {
    width: 60upx;
    height: 60upx;
    margin-bottom: 10upx;
}

.fab-content .fab-item.first {
    width: 110upx;
}

/* @font-face {
    font-family: 'iconfont';
    src: url('https://at.alicdn.com/t/font_1028200_xhbo4rn58rp.ttf?t=1548214263520')
        format('truetype');
}

.icon {
    font-family: 'iconfont' !important;
    font-size: 16px;
    font-style: normal;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

.icon-jia:before {
    content: '\e630';
}

.icon-arrow-up:before {
    content: '\e603';
} */
</style>

uni-icon

readme.md
### Icon 图标

用于展示 icon,组件名:``uni-icon``,代码块: uIcon。

**使用方式:**

在 ``script`` 中引用组件 

import uniIcon from "@/components/uni-icon/uni-icon.vue"
export default {

components: {uniIcon}

}


在 ``template`` 中使用组件

<uni-icon type="contact" size="30"></uni-icon>


实际效果参考:[https://github.com/dcloudio/uni-ui](https://github.com/dcloudio/uni-ui)

**Icon 属性说明:**

|属性名        |类型|默认值    |说明|
|---|----|---|---|
|type    |String    |-|图标图案,参考下表|
|color    |String    |-|图标颜色    |
|size    |Number    |24|图标大小|
|@click    |EventHandle|-|点击 Icon 触发事件|

**type 类型:**

<div>
  <link rel="stylesheet" type="text/css" href="https://img-cdn-qiniu.dcloud.net.cn/uniapp/doc/icon1.1.css"/>
  <ul class="icon-group">
      <li class="icon-item"><span class="uni-icon uni-icon-contact"></span><span>contact</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-person"></span><span>person</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-personadd"></span><span>personadd</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-contact-filled"></span><span>contact-filled</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-person-filled"></span><span>person-filled</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-personadd-filled"></span><span>personadd-filled</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-phone"></span><span>phone</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-email"></span><span>email</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-chatbubble"></span><span>chatbubble</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-chatboxes"></span><span>chatboxes</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-phone-filled"></span><span>phone-filled</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-email-filled"></span><span>email-filled</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-chatbubble-filled"></span><span>chatbubble-filled</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-chatboxes-filled"></span><span>chatboxes-filled</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-weibo"></span><span>weibo</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-weixin"></span><span>weixin</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-pengyouquan"></span><span>pengyouquan</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-chat"></span><span>chat</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-qq"></span><span>qq</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-videocam"></span><span>videocam</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-camera"></span><span>camera</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-mic"></span><span>mic</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-location"></span><span>location</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-mic-filled"></span><span>mic-filled</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-location-filled"></span><span>location-filled</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-micoff"></span><span>micoff</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-image"></span><span>image</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-map"></span><span>map</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-compose"></span><span>compose</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-trash"></span><span>trash</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-upload"></span><span>upload</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-download"></span><span>download</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-close"></span><span>close</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-redo"></span><span>redo</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-undo"></span><span>undo</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-refresh"></span><span>refresh</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-star"></span><span>star</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-plus"></span><span>plus</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-minus"></span><span>minus</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-circle"></span><span>circle</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-clear"></span><span>clear</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-refresh-filled"></span><span>refresh-filled</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-star-filled"></span><span>star-filled</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-plus-filled"></span><span>plus-filled</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-minus-filled"></span><span>minus-filled</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-circle-filled"></span><span>circle-filled</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-checkbox-filled"></span><span>checkbox-filled</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-closeempty"></span><span>closeempty</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-refreshempty"></span><span>refreshempty</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-reload"></span><span>reload</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-starhalf"></span><span>starhalf</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-spinner"></span><span>spinner</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-spinner-cycle"></span><span>spinner-cycle</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-search"></span><span>search</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-plusempty"></span><span>plusempty</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-forward"></span><span>forward</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-back"></span><span>back</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-checkmarkempty"></span><span>checkmarkempty</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-home"></span><span>home</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-navigate"></span><span>navigate</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-gear"></span><span>gear</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-paperplane"></span><span>paperplane</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-info"></span><span>info</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-help"></span><span>help</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-locked"></span><span>locked</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-more"></span><span>more</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-flag"></span><span>flag</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-home-filled"></span><span>home-filled</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-gear-filled"></span><span>gear-filled</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-info-filled"></span><span>info-filled</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-help-filled"></span><span>help-filled</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-more-filled"></span><span>more-filled</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-settings"></span><span>settings</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-list"></span><span>list</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-bars"></span><span>bars</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-loop"></span><span>loop</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-paperclip"></span><span>paperclip</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-eye"></span><span>eye</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-arrowup"></span><span>arrowup</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-arrowdown"></span><span>arrowdown</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-arrowleft"></span><span>arrowleft</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-arrowright"></span><span>arrowright</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-arrowthinup"></span><span>arrowthinup</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-arrowthindown"></span><span>arrowthindown</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-arrowthinleft"></span><span>arrowthinleft</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-arrowthinright"></span><span>arrowthinright</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-pulldown"></span><span>pulldown</span></li>
      <li class="icon-item"><span class="uni-icon uni-icon-scan"></span><span>scan</span></li>
  </ul>
</div>
uni-icon.vue
<template>
    <view class="uni-icon" :class="['uni-icon-'+type]" :style="{color:color,'font-size':fontSize}" @click="onClick()"></view>
</template>

<script>
    export default {
        name: 'uni-icon',
        props: {
            /**
             * 图标类型
             */
            type: String,
            /**
             * 图标颜色
             */
            color: String,
            /**
             * 图标大小
             */
            size: [Number, String]
        },
        computed: {
            fontSize() {
                return `${this.size}px`
            }
        },
        methods: {
            onClick() {
                this.$emit('click')
            }
        }
    }
</script>

<style>
    @font-face {
        font-family: uniicons;
        font-weight: normal;
        font-style: normal;
        src: url(data:font/truetype;charset=utf-8;base64,AAEAAAAQAQAABAAARkZUTYBH1lsAAHcQAAAAHEdERUYAJwBmAAB28AAAAB5PUy8yWe1cyQAAAYgAAABgY21hcGBhbBUAAAK0AAACQmN2dCAMpf40AAAPKAAAACRmcGdtMPeelQAABPgAAAmWZ2FzcAAAABAAAHboAAAACGdseWZsfgfZAAAQEAAAYQxoZWFkDdbyjwAAAQwAAAA2aGhlYQd+AyYAAAFEAAAAJGhtdHgkeBuYAAAB6AAAAMpsb2NhPEknLgAAD0wAAADCbWF4cAIjA3IAAAFoAAAAIG5hbWVceWDDAABxHAAAAg1wb3N05pkPsQAAcywAAAO8cHJlcKW5vmYAAA6QAAAAlQABAAAAAQAA6ov1dV8PPPUAHwQAAAAAANJrTZkAAAAA2DhhuQAA/yAEAAMgAAAACAACAAAAAAAAAAEAAAMg/yAAXAQAAAAAAAQAAAEAAAAAAAAAAAAAAAAAAAAFAAEAAABgAXoADAAAAAAAAgBGAFQAbAAAAQQBogAAAAAABAP/AfQABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAIABgMAAAAAAAAAAAABEAAAAAAAAAAAAAAAUGZFZAGAAB3mEgMs/ywAXAMgAOAAAAABAAAAAAMYAs0AAAAgAAEBdgAiAAAAAAFVAAAD6QAsBAAAYADAAMAAYADAAMAAoACAAIAAYACgAIAAgABgALMAQABAAAUAVwBeAIABAAD0AQAA9AEAAEAAVgCgAOAAwADAAFEAfgCAAGAAQABgAGAAYAA+AFEAYABAAGAAYAA0AGAAPgFAAQAAgABAAAAAJQCBAQABQAFAASwAgABgAIAAwABgAGAAwADBAQAAgACAAGAAYADBAEAARABAABcBXwATAMAAwAFAAUABQAFAAMAAwAEeAF8AVQBAAAAAAAADAAAAAwAAABwAAQAAAAABPAADAAEAAAAcAAQBIAAAAEQAQAAFAAQAAAAdAHjhAuEy4gPiM+Jk4wPjM+Ng42TkCeQR5BPkNOQ55EPkZuRo5HLlCOUw5TLlNeU35WDlY+Vl5WjlieWQ5hL//wAAAAAAHQB44QDhMOIA4jDiYOMA4zLjYONj5ADkEOQT5DTkN+RA5GDkaORw5QDlMOUy5TTlN+Vg5WLlZeVn5YDlkOYS//8AAf/k/4sfBB7XHgod3h2yHRcc6Ry9HLscIBwaHBkb+Rv3G/Eb1RvUG80bQBsZGxgbFxsWGu4a7RrsGusa1BrOGk0AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBgAAAQAAAAAAAAABAgAAAAIAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsAAssCBgZi2wASwgZCCwwFCwBCZasARFW1ghIyEbilggsFBQWCGwQFkbILA4UFghsDhZWSCwCkVhZLAoUFghsApFILAwUFghsDBZGyCwwFBYIGYgiophILAKUFhgGyCwIFBYIbAKYBsgsDZQWCGwNmAbYFlZWRuwACtZWSOwAFBYZVlZLbACLCBFILAEJWFkILAFQ1BYsAUjQrAGI0IbISFZsAFgLbADLCMhIyEgZLEFYkIgsAYjQrIKAAIqISCwBkMgiiCKsAArsTAFJYpRWGBQG2FSWVgjWSEgsEBTWLAAKxshsEBZI7AAUFhlWS2wBCywCCNCsAcjQrAAI0KwAEOwB0NRWLAIQyuyAAEAQ2BCsBZlHFktsAUssABDIEUgsAJFY7ABRWJgRC2wBiywAEMgRSCwACsjsQQEJWAgRYojYSBkILAgUFghsAAbsDBQWLAgG7BAWVkjsABQWGVZsAMlI2FERC2wByyxBQVFsAFhRC2wCCywAWAgILAKQ0qwAFBYILAKI0JZsAtDSrAAUlggsAsjQlktsAksILgEAGIguAQAY4ojYbAMQ2AgimAgsAwjQiMtsAosS1RYsQcBRFkksA1lI3gtsAssS1FYS1NYsQcBRFkbIVkksBNlI3gtsAwssQANQ1VYsQ0NQ7ABYUKwCStZsABDsAIlQrIAAQBDYEKxCgIlQrELAiVCsAEWIyCwAyVQWLAAQ7AEJUKKiiCKI2GwCCohI7ABYSCKI2GwCCohG7AAQ7ACJUKwAiVhsAgqIVmwCkNHsAtDR2CwgGIgsAJFY7ABRWJgsQAAEyNEsAFDsAA+sgEBAUNgQi2wDSyxAAVFVFgAsA0jQiBgsAFhtQ4OAQAMAEJCimCxDAQrsGsrGyJZLbAOLLEADSstsA8ssQENKy2wECyxAg0rLbARLLEDDSstsBIssQQNKy2wEyyxBQ0rLbAULLEGDSstsBUssQcNKy2wFiyxCA0rLbAXLLEJDSstsBgssAcrsQAFRVRYALANI0IgYLABYbUODgEADABCQopgsQwEK7BrKxsiWS2wGSyxABgrLbAaLLEBGCstsBsssQIYKy2wHCyxAxgrLbAdLLEEGCstsB4ssQUYKy2wHyyxBhgrLbAgLLEHGCstsCEssQgYKy2wIiyxCRgrLbAjLCBgsA5gIEMjsAFgQ7ACJbACJVFYIyA8sAFgI7ASZRwbISFZLbAkLLAjK7AjKi2wJSwgIEcgILACRWOwAUViYCNhOCMgilVYIEcgILACRWOwAUViYCNhOBshWS2wJiyxAAVFVFgAsAEWsCUqsAEVMBsiWS2wJyywByuxAAVFVFgAsAEWsCUqsAEVMBsiWS2wKCwgNbABYC2wKSwAsANFY7ABRWKwACuwAkVjsAFFYrAAK7AAFrQAAAAAAEQ+IzixKAEVKi2wKiwgPCBHILACRWOwAUViYLAAQ2E4LbArLC4XPC2wLCwgPCBHILACRWOwAUViYLAAQ2GwAUNjOC2wLSyxAgAWJSAuIEewACNCsAIlSYqKRyNHI2EgWGIbIVmwASNCsiwBARUUKi2wLiywABawBCWwBCVHI0cjYbAGRStlii4jICA8ijgtsC8ssAAWsAQlsAQlIC5HI0cjYSCwBCNCsAZFKyCwYFBYILBAUVizAiADIBuzAiYDGllCQiMgsAlDIIojRyNHI2EjRmCwBEOwgGJgILAAKyCKimEgsAJDYGQjsANDYWRQWLACQ2EbsANDYFmwAyWwgGJhIyAgsAQmI0ZhOBsjsAlDRrACJbAJQ0cjRyNhYCCwBEOwgGJgIyCwACsjsARDYLAAK7AFJWGwBSWwgGKwBCZhILAEJWBkI7ADJWBkUFghGyMhWSMgILAEJiNGYThZLbAwLLAAFiAgILAFJiAuRyNHI2EjPDgtsDEssAAWILAJI0IgICBGI0ewACsjYTgtsDIssAAWsAMlsAIlRyNHI2GwAFRYLiA8IyEbsAIlsAIlRyNHI2EgsAUlsAQlRyNHI2GwBiWwBSVJsAIlYbABRWMjIFhiGyFZY7ABRWJgIy4jICA8ijgjIVktsDMssAAWILAJQyAuRyNHI2EgYLAgYGawgGIjICA8ijgtsDQsIyAuRrACJUZSWCA8WS6xJAEUKy2wNSwjIC5GsAIlRlBYIDxZLrEkARQrLbA2LCMgLkawAiVGUlggPFkjIC5GsAIlRlBYIDxZLrEkARQrLbA3LLAuKyMgLkawAiVGUlggPFkusSQBFCstsDgssC8riiAgPLAEI0KKOCMgLkawAiVGUlggPFkusSQBFCuwBEMusCQrLbA5LLAAFrAEJbAEJiAuRyNHI2GwBkUrIyA8IC4jOLEkARQrLbA6LLEJBCVCsAAWsAQlsAQlIC5HI0cjYSCwBCNCsAZFKyCwYFBYILBAUVizAiADIBuzAiYDGllCQiMgR7AEQ7CAYmAgsAArIIqKYSCwAkNgZCOwA0NhZFBYsAJDYRuwA0NgWbADJbCAYmGwAiVGYTgjIDwjOBshICBGI0ewACsjYTghWbEkARQrLbA7LLAuKy6xJAEUKy2wPCywLyshIyAgPLAEI0IjOLEkARQrsARDLrAkKy2wPSywABUgR7AAI0KyAAEBFRQTLrAqKi2wPiywABUgR7AAI0KyAAEBFRQTLrAqKi2wPyyxAAEUE7ArKi2wQCywLSotsEEssAAWRSMgLiBGiiNhOLEkARQrLbBCLLAJI0KwQSstsEMssgAAOistsEQssgABOistsEUssgEAOistsEYssgEBOistsEcssgAAOystsEgssgABOystsEkssgEAOystsEossgEBOystsEsssgAANystsEwssgABNystsE0ssgEANystsE4ssgEBNystsE8ssgAAOSstsFAssgABOSstsFEssgEAOSstsFIssgEBOSstsFMssgAAPCstsFQssgABPCstsFUssgEAPCstsFYssgEBPCstsFcssgAAOCstsFgssgABOCstsFkssgEAOCstsFossgEBOCstsFsssDArLrEkARQrLbBcLLAwK7A0Ky2wXSywMCuwNSstsF4ssAAWsDArsDYrLbBfLLAxKy6xJAEUKy2wYCywMSuwNCstsGEssDErsDUrLbBiLLAxK7A2Ky2wYyywMisusSQBFCstsGQssDIrsDQrLbBlLLAyK7A1Ky2wZiywMiuwNistsGcssDMrLrEkARQrLbBoLLAzK7A0Ky2waSywMyuwNSstsGossDMrsDYrLbBrLCuwCGWwAyRQeLABFTAtAABLuADIUlixAQGOWbkIAAgAYyCwASNEILADI3CwDkUgIEu4AA5RS7AGU1pYsDQbsChZYGYgilVYsAIlYbABRWMjYrACI0SzCgkFBCuzCgsFBCuzDg8FBCtZsgQoCUVSRLMKDQYEK7EGAUSxJAGIUViwQIhYsQYDRLEmAYhRWLgEAIhYsQYBRFlZWVm4Af+FsASNsQUARAAAAAAAAAAAAAAAAAAAAAAAAAAAMgAyAxj/4QMg/yADGP/hAyD/IAAAACgAKAAoAWQCCgO0BYoGDgaiB4gIgAjICXYJ8Ap6CrQLGAtsDPgN3A50D1wRyhIyEzATnhQaFHIUvBVAFeIXHBd8GEoYkBjWGTIZjBnoGmAaohsCG1QblBvqHCgcehyiHOAdDB1qHaQd6h4IHkYenh7YHzggmiDkIQwhJCE8IVwhviIcJGYkiCT0JYYmACZ4J3YntijEKQ4peim6KsQsECw+LLwtSC3eLfYuDi4mLj4uiC7QLxYvXC94L5owBjCGAAAAAgAiAAABMgKqAAMABwApQCYAAAADAgADVwACAQECSwACAgFPBAEBAgFDAAAHBgUEAAMAAxEFDyszESERJzMRIyIBEO7MzAKq/VYiAmYAAAAFACz/4QO8AxgAFgAwADoAUgBeAXdLsBNQWEBKAgEADQ4NAA5mAAMOAQ4DXgABCAgBXBABCQgKBgleEQEMBgQGDF4ACwQLaQ8BCAAGDAgGWAAKBwUCBAsKBFkSAQ4ODVEADQ0KDkIbS7AXUFhASwIBAA0ODQAOZgADDgEOA14AAQgIAVwQAQkICggJCmYRAQwGBAYMXgALBAtpDwEIAAYMCAZYAAoHBQIECwoEWRIBDg4NUQANDQoOQhtLsBhQWEBMAgEADQ4NAA5mAAMOAQ4DXgABCAgBXBABCQgKCAkKZhEBDAYEBgwEZgALBAtpDwEIAAYMCAZYAAoHBQIECwoEWRIBDg4NUQANDQoOQhtATgIBAA0ODQAOZgADDgEOAwFmAAEIDgEIZBABCQgKCAkKZhEBDAYEBgwEZgALBAtpDwEIAAYMCAZYAAoHBQIECwoEWRIBDg4NUQANDQoOQllZWUAoU1M7OzIxFxdTXlNeW1g7UjtSS0M3NTE6MjoXMBcwURExGBEoFUATFisBBisBIg4CHQEhNTQmNTQuAisBFSEFFRQWFA4CIwYmKwEnIQcrASInIi4CPQEXIgYUFjMyNjQmFwYHDgMeATsGMjYnLgEnJicBNTQ+AjsBMhYdAQEZGxpTEiUcEgOQAQoYJx6F/koCogEVHyMODh8OIC3+SSwdIhQZGSATCHcMEhIMDRISjAgGBQsEAgQPDiVDUVBAJBcWCQUJBQUG/qQFDxoVvB8pAh8BDBknGkwpEBwEDSAbEmGINBc6OiUXCQEBgIABExsgDqc/ERoRERoRfBoWEyQOEA0IGBoNIxETFAF35AsYEwwdJuMAAAIAYP+AA6ACwAAHAFcASEBFSklDOTg2JyYcGRcWDAQDTw8CAQQCQAAEAwEDBAFmAAAFAQIDAAJZAAMEAQNNAAMDAVEAAQMBRQkITEswLQhXCVcTEAYQKwAgBhAWIDYQJTIeAhUUByYnLgE1NDc1Nj8DPgE3Njc2NzYvATUmNzYmJyYnIwYHDgEXFgcUBxUOARceARcWFxYVMBUUBhQPARQjDgEHJjU0PgQCrP6o9PQBWPT+YE2OZjxYUWkEAgEBAQICAgECAg0FEwgHCAEECgQOEyhNI0woFA4ECgQBBAEEBQ4IBA4IAQECASlwHFkbMUdTYwLA9P6o9PQBWNE8Zo5NimohHwEGDgMDBgMDBgYGAwUDHSIWLCMUAgEVORM6GjMFBTMaOhM5FQEBAQoTGhkgCSEeECAIAwUCAQEBDCgMaos0Y1NHMRsAAAAAAwDA/+ADQAJgAAAAUwDAATZLsAtQWEAck5KFAAQBC56alYR6BQABqadzQkA/EQoICgADQBtLsAxQWEAck5KFAAQBC56alYR6BQABqadzQkA/EQoIBwADQBtAHJOShQAEAQuempWEegUAAamnc0JAPxEKCAoAA0BZWUuwC1BYQDUDAQELAAsBAGYEAQAKCwAKZAAKBwsKB2QJCAIHBgsHBmQAAgALAQILWQwBBgYFUAAFBQsFQhtLsAxQWEAvAwEBCwALAQBmBAEABwsAB2QKCQgDBwYLBwZkAAIACwECC1kMAQYGBVAABQULBUIbQDUDAQELAAsBAGYEAQAKCwAKZAAKBwsKB2QJCAIHBgsHBmQAAgALAQILWQwBBgYFUAAFBQsFQllZQB5VVIuKZWRiYV9eXVxUwFXATk05OC8uJyUfHhMSDQ4rCQEuAScmJy4BPwE2Nz4DNTcyPgE3PgE1NC4DIzc+ATc2JiMiDgEVHgEfASIHFBYXHgMXMxYXFh8DBgcOAQcOBAcGFSE0LgMHITY3Njc+ATcyNjI+ATI+ATI3Njc2Jz0CNCY9AycuAScmLwEuAicmJyY+ATc1JicmNzYyFxYHDgIHMQYVHgEHBgcUDgEVBw4CBw4BDwEdAQYdARQGFRQXHgIXFhceARcWFx4CFwGVAUIQRAMeCgMBAQEMBgIEBAMBAgUJAwELAwMDAgEDAgYBAVBGL0YgAQYCAwsBCwECBQQFAQIHBwMFBwMBAQIFGAsGExETEghpAoASFyEU4v7tBQwWIAkZEQEFAwQDBAMEAwIpEAwBAQUDCgMFBwEBCAkBBAQCAgcBCQEBHSByIB0BAQUDAQEBCwMEBQkJAQIEBQEDCgMFAQEMBxwPBwgYERkJIRUEBQUCAY3+uwYLAQYMBCkSExMRBRARDwUFAQwLByYLBQcEAgEJBiwaNlEoPCMaKgkIEwskCQYKBQIBLhEHCQ8FRAsDBQoDAQMDBAQDJUMSIRUUCEQHCBALBAUCAQEBAQEBCRQOMggJBwQFAgMCCAcFEggOKgcEBQQDExIMCAkDDBswKR0hIR0pFSYNAwUGAhINEhMDBAUEBwkWFQQIEAcHCAIDBAkEDAYyDgkOBQECBAIFBAsQAwQFAwAABADA/+ADQAJgAAsADABfAMwBckuwC1BYQByfnpEMBAcEqqahkIYFBge1s39OTEsdFggQBgNAG0uwDFBYQByfnpEMBAcEqqahkIYFBge1s39OTEsdFggNBgNAG0Acn56RDAQHBKqmoZCGBQYHtbN/TkxLHRYIEAYDQFlZS7ALUFhARwkBBwQGBAcGZgoBBhAEBhBkABANBBANZA8OAg0MBA0MZAAIABEBCBFZAgEABQEDBAADVwABAAQHAQRXEgEMDAtQAAsLCwtCG0uwDFBYQEEJAQcEBgQHBmYKAQYNBAYNZBAPDgMNDAQNDGQACAARAQgRWQIBAAUBAwQAA1cAAQAEBwEEVxIBDAwLUAALCwsLQhtARwkBBwQGBAcGZgoBBhAEBhBkABANBBANZA8OAg0MBA0MZAAIABEBCBFZAgEABQEDBAADVwABAAQHAQRXEgEMDAtQAAsLCwtCWVlAJGFgl5ZxcG5ta2ppaGDMYcxaWUVEOzozMSsqHx4RERERERATFCsBIzUjFSMVMxUzNTMFAS4BJyYnLgE/ATY3PgM1NzI+ATc+ATU0LgMjNz4BNzYmIyIOARUeAR8BIgcUFhceAxczFhcWHwMGBw4BBw4EBwYVITQuAwchNjc2Nz4BNzI2Mj4BMj4BMjc2NzYnPQI0Jj0DJy4BJyYvAS4CJyYnJj4BNzUmJyY3NjIXFgcOAgcxBhUeAQcGBxQOARUHDgIHDgEPAR0BBh0BFAYVFBceAhcWFx4BFxYXHgIXA0AyHDIyHDL+VQFCEEQDHgoDAQEBDAYCBAQDAQIFCQMBCwMDAwIBAwIGAQFQRi9GIAEGAgMLAQsBAgUEBQECBwcDBQcDAQECBRgLBhMRExIIaQKAEhchFOL+7QUMFiAJGREBBQMEAwQDBAMCKRAMAQEFAwoDBQcBAQgJAQQEAgIHAQkBAR0gciAdAQEFAwEBAQsDBAUJCQECBAUBAwoDBQEBDAccDwcIGBEZCSEVBAUFAgHuMjIcMjJF/rsGCwEGDAQpEhMTEQUQEQ8FBQEMCwcmCwUHBAIBCQYsGjZRKDwjGioJCBMLJAkGCgUCAS4RBwkPBUQLAwUKAwEDAwQEAyVDEiEVFAhEBwgQCwQFAgEBAQEBAQkUDjIICQcEBQIDAggHBRIIDioHBAUEAxMSDAgJAwwbMCkdISEdKRUmDQMFBgISDRITAwQFBAcJFhUECBAHBwgCAwQJBAwGMg4JDgUBAgQCBQQLEAMEBQMAAAIAYP+AA6ACwAAHAEQAMkAvQRsaCwQCAwFAAAAAAwIAA1kEAQIBAQJNBAECAgFRAAECAUUJCCckCEQJRBMQBRArACAGEBYgNhABIiYnPgE3PgE1NCcmJyYnJj8BNTYmJyY+Ajc2NzMWFx4BBwYXMBceAQcOAQcOBRUUFhcWFw4CAqz+qPT0AVj0/mBWmTUccCgEAggOBBMJBwgBAgQEAgIGDgooTCNNKBQOBAoEAQQBBAUPBwIGBwgFBAIDaVEjWm0CwPT+qPT0AVj910hADCgMAQYOIBAeIRUtIxQBAgcxFgcZGh8OMwUFMxo6EzkVAwoTGhkgCQsYFBAOEQgOBgEfISs9IQAAAAEAwP/gA0ACYABSADdANEE/PhAJBQUAAUADAQECAAIBAGYEAQAFAgAFZAACAgVPAAUFCwVCTUw4Ny4tJiQeHRIRBg4rJS4BJyYnLgE/ATY3PgM1NzI+ATc+ATU0LgMjNz4BNzYmIyIOARUeAR8BIgcUFhceAxczFhcWHwMGBw4BBw4EBwYVITQuAwLXEEQDHgoDAQEBDAYCBAQDAQIFCQMBCwMDAwIBAwIGAQFQRi9GIAEGAgMLAQsBAgUEBQECBwcDBQcDAQECBRgLBhMRExIIaQKAEhchFEgGCwEGDAQpEhMTEQUQEQ8FBQEMCwcmCwUHBAIBCQYsGjZRKDwjGioJCBMLJAkGCgUCAS4RBwkPBUQLAwUKAwEDAwQEAyVDEiEVFAgAAAAAAgDA/+ADQAJgAAsAXgDAQApNS0ocFQULBgFAS7ALUFhALgAIAQAIXAkBBwQGAAdeCgEGCwQGC2QCAQAFAQMEAANYAAEABAcBBFcACwsLC0IbS7AMUFhALQAIAQhoCQEHBAYAB14KAQYLBAYLZAIBAAUBAwQAA1gAAQAEBwEEVwALCwsLQhtALgAIAQhoCQEHBAYEBwZmCgEGCwQGC2QCAQAFAQMEAANYAAEABAcBBFcACwsLC0JZWUAUWVhEQzo5MjAqKR4dEREREREQDBQrASM1IxUjFTMVMzUzAy4BJyYnLgE/ATY3PgM1NzI+ATc+ATU0LgMjNz4BNzYmIyIOARUeAR8BIgcUFhceAxczFhcWHwMGBw4BBw4EBwYVITQuAwNAMhwyMhwyaRBEAx4KAwEBAQwGAgQEAwECBQkDAQsDAwMCAQMCBgEBUEYvRiABBgIDCwELAQIFBAUBAgcHAwUHAwEBAgUYCwYTERMSCGkCgBIXIRQB7jIyHDIy/nYGCwEGDAQpEhMTEQUQEQ8FBQEMCwcmCwUHBAIBCQYsGjZRKDwjGioJCBMLJAkGCgUCAS4RBwkPBUQLAwUKAwEDAwQEAyVDEiEVFAgAAAIAoP/AA3cCgABJAIwAXEBZYgEGB3l3EhAEAAYCQAADAgcCAwdmAAYHAAcGAGYAAgAHBgIHWQAAAAkBAAlZAAEACAUBCFkABQQEBU0ABQUEUQAEBQRFhYOAfmVjYWBPTUJALSwqKCQiChArJS4BIyIOAQcGIyImLwEmLwEmLwEuAy8BLgI1ND4CNzYnJi8BJiMiBwYjBw4CBw4BFB4BFx4BFx4BFx4BMzI+Ajc2JyYHBgcGIyInLgEnLgY2NzY3MDcyNTYzMhYfAR4BBwYXHgIfAR4BFxYXFh8BFh8BFjMyNjc2MzIeAhcWBwYDQBtnJQYMCgQwCgQKCwIlFgQBAgQGBg0QDAEKCAgCBgkHIR4QMQIdJhwkAQEBDhcPBAQECBQQI0gzLDo2NWEkFhYjIBI2KwYdJCYKFUBoNDkrGSglISMTBAMECSECAR0TDBULAi4jFSACAQoLDAEXFQsBAgMBAxYnAhwRDR8fBgoPKykjChsGBIEbOwIEAh8HCgIfGAMCAwMGBw0TDQELCgwEAwgLDgksPyE7AyQXAQEJFhgMDRYiJDMdQGE1LjAnJioCChoWQTcGaSsEAUomLy0ZLzI1PzMmGA4cFQEBEgwNAjlKHCwYCRMODgEZFwsBAwIBBBciAhgPFAQRGBoKGxYRAAADAIAAIAOAAiAAAwAGABMAPEA5EhEODQwJCAQIAwIBQAQBAQACAwECVwUBAwAAA0sFAQMDAE8AAAMAQwcHAAAHEwcTBgUAAwADEQYPKxMRIREBJSEBERcHFzcXNxc3JzcRgAMA/oD+ugKM/VrmiASeYGCeBIjmAiD+AAIA/uj4/kABrK+bBItJSYsEm6/+VAACAID/4AOAAmAAJwBVAGpAZzQyIQMEABQBAQJKAQgBThgCDAk/AQcMBUAABAACAAQCZgUDAgIBAAIBZAsKAggBCQEICWYACQwBCQxkAAYAAAQGAFkAAQAMBwEMWQAHBwsHQlFPTUtJSEZFRUQ+PCkoERIRISYQDRQrADIeARUUBwYjIiciIycjJiciByMHDgEPAT4DNTQnJicmJyY1NDYkIg4BFRQXHgIXJjUxFhUUBwYWFzMyPwI2PwEzIzY3MhcVMzIVFjMyPgE0JgGhvqNeY2WWVDcBAgECDw4REAEEBQsCTwsLBQENAgEDATVeAWrQsWc9AQMCAQIHJAIJCAYDBANlAQoJAQELCwsKAgE9WmiwZmcCQEqAS29MTxMBBAEGAgEEASMhJBMFAhYTAwEEAUNPS39qU45UWkwBBAQBAwELDAJyBgwCAQEsAQMEAwEDAQEUTYqnjgAAAAADAGD/gAOgAsAACQARABgAnrUUAQYFAUBLsApQWEA6AAEACAABCGYABgUFBl0AAgAAAQIAVwwBCAALBAgLVwAEAAMJBANXCgEJBQUJSwoBCQkFTwcBBQkFQxtAOQABAAgAAQhmAAYFBmkAAgAAAQIAVwwBCAALBAgLVwAEAAMJBANXCgEJBQUJSwoBCQkFTwcBBQkFQ1lAFgoKGBcWFRMSChEKEREREhEREREQDRYrEyEVMzUhETM1IzcRIRczNTMRAyMVJyERIYACACD9wODA4AFFgBtgIGBu/s4CAAKgwOD+QCCg/kCAgAHA/mBtbQGAAAAAAQCg/8ADdwKAAEkANkAzEhACAAMBQAACAwJoAAMAA2gAAQAEAAEEZgAAAQQATQAAAARRAAQABEVCQC0sKigkIgUQKyUuASMiDgEHBiMiJi8BJi8BJi8BLgMvAS4CNTQ+Ajc2JyYvASYjIgcGIwcOAgcOARQeARceARceARceATMyPgI3NicmA0AbZyUGDAoEMAoECgsCJRYEAQIEBgYNEAwBCggIAgYJByEeEDECHSYcJAEBAQ4XDwQEBAgUECNIMyw6NjVhJBYWIyASNisGgRs7AgQCHwcKAh8YAwIDAwYHDRMNAQsKDAQDCAsOCSw/ITsDJBcBAQkWGAwNFiIkMx1AYTUuMCcmKgIKGhZBNwYAAAAAAgCAACADgAIgAAwADwArQCgPCwoHBgUCAQgAAQFAAAEAAAFLAAEBAE8CAQABAEMAAA4NAAwADAMOKyURBRcHJwcnByc3JREBIQEDgP76iASeYGCeBIj++gLv/SEBcCAB5MebBItJSYsEm8f+HAIA/ugAAAABAID/4AOAAmAALQBBQD4iDAoDAgAmAQYDFwEBBgNABQQCAgADAAIDZgADBgADBmQAAAAGAQAGWQABAQsBQiknJSMhIB4dHRwWFBAHDysAIg4BFRQXHgIXJjUxFhUUBwYWFzMyPwI2PwEzIzY3MhcVMzIVFjMyPgE0JgJo0LFnPQEDAgECByQCCQgGAwQDZQEKCQEBCwsLCgIBPVposGZnAmBTjlRaTAEEBAEDAQsMAnIGDAIBASwBAwQDAQMBARRNiqeOAAAAAAIAYP+AA6ACwAAFAA0AbUuwClBYQCkAAQYDBgEDZgAEAwMEXQAAAAIGAAJXBwEGAQMGSwcBBgYDTwUBAwYDQxtAKAABBgMGAQNmAAQDBGkAAAACBgACVwcBBgEDBksHAQYGA08FAQMGA0NZQA4GBgYNBg0RERIRERAIFCsBIREzNSEFESEXMzUzEQKg/cDgAWD+wAFFgBtgAsD+QOAg/kCAgAHAAAAAAAcAs//hAygCZwA3AEYAWABmAHEAjwC7AQBAIZkBCwkZFBMDAAd2AQQABQEMA0wpAgIMBUB+AQUlAQ0CP0uwC1BYQFQACQgLCAkLZgAKCwELCgFmAAAHBAEAXg8BBA0HBA1kAA0DBw0DZAAMAwIDDAJmDgECAmcACAALCggLWQABBQMBTQYBBQAHAAUHWQABAQNRAAMBA0UbQFUACQgLCAkLZgAKCwELCgFmAAAHBAcABGYPAQQNBwQNZAANAwcNA2QADAMCAwwCZg4BAgJnAAgACwoIC1kAAQUDAU0GAQUABwAFB1kAAQEDUQADAQNFWUAmc3I5OLW0srGko6CfmJeUkoSDgH99fHKPc49BPzhGOUYeHREQEA4rAS4CNj8BNicuAQ4BDwEOASImJzUmPgI3NC4CBgcOBBUOAR0BHgQXFj4CNzYnJgMGLgI1NDY3NhYVFAcGJw4DFxUUHgEXFjY3PgEuAQcGJjU0Njc2HgIVFAY3BiYnJjY3NhYXFjcyPgE3NTYuBA8BIgYVFDM2HgMOARUUFxYnLgEGIg4BByMPAQYVFB4BMzY3NjIeAxcWBw4CFRQWMjY3Mz4BLgMChQcIAQEBARgdCiAgHQkKBQgGAwEBAQECAQMMFSUZGTMnIBAXFwQiLz86ISdXT0IPJEAQ6yVFMh5tTU9sQjVYHSgQCAEBDg0vUhoMAhIzPg8UEw4IDgkGFS8FCwIDAgUGCwIG9AQHBQECBxAVFhIFBgcKERAWDgYDAQEOAgsJExEODwYFAQEBEgcLBwEVAw4VGRkZCRMLAQEDDhUMAQEJARAZISIBLgEGBgYCAjIlDAkHCgUFAgIBAwQDCAcMBA4XGg4BCwsrLywbAShPFBQsRSsfDgMEEidCKmM0Df7mAhUnOSFBXwUETEFKNyv7BSAnJg0NBQ4gCB4YKRQ8NyK0AhMPEBsCAQUJDQgQGUEFAQYFEAQFAQYNtAUIBgIeLRkRBAEBAQwJFgYHCRYPFAcCEwIB/gMDAQMCAQEBBhgJDgkBBgECCxAeEzcyAgYQBw0PChAqSjcuHxQAAAYAQP+kA8ACmwAOABkAPABHAE8AcwCJQIZSAQQLZl4CDQBfOjEDBg0DQDk0AgY9CgEHCAsIBwtmEQELBAgLBGQQAg8DAAENAQANZg4BDQYBDQZkAAYGZwAMCQEIBwwIWQUBBAEBBE0FAQQEAVEDAQEEAUVRUBAPAQBtamloVlRQc1FzTUxJSENBPj0wLiIfHh0WFQ8ZEBkGBAAOAQ4SDislIiY0NjMyHgMVFA4BIyIuATU0NjIWFAYFNC4BJyYrASIOBhUUFx4BMzI3FzAXHgE+ATUnPgEAIiY0NjMyHgEVFDYyFhQGIiY0FzIXLgEjIg4DFRQWFwcUBhQeAT8BHgEzMDsCLgE1ND4BAw4QFxcQBgwKBwQLEdMKEgsXIBcXAWpEdUcGBQkdNjIsJh4VCwgXlWFBOj4BAgUEAxIsMv1UIBcXEAsSCr0hFhYhFtoGCxG0dzVhTzshPTYYAQUJClgcOyADBAMEBFCI4RchFwQICQwHChILCxIKERcXIRc4P2tCBAEKEhohJyowGR0dT2gZKgEBAQEHBkIiXgFEFyAXChILEDcXIBcXIEEBZogcM0VVLUBvJ1kBBAoDAwQ9CgoPHQ9HeEYAAAgAQP9hA8EC4gAHABAAFAAYAB0AJgAvADcAZkBjMCATAwIENiECAQI3HQwBBAABLRwCAwAsJxoXBAUDBUAAAQIAAgEAZgAAAwIAA2QIAQQGAQIBBAJXBwEDBQUDSwcBAwMFUQAFAwVFHx4VFRERKigeJh8mFRgVGBEUERQSFQkQKyUBBhUUFyEmASEWFwE+ATU0JyYnBwEWFz8BETY3JwMiBxEBLgMDFjMyNjcRBgcBDgQHFwFd/vcUGAEPBgJI/vEFBQEJCgo1RIK//m5EgL/bf0C/00pGARMQHyEilEBDJkgiBQX+pxguKSQfDL6cAQlAREpGBgEbBQb+9x9CIkuIgEDA/lp/P77E/oNEgb8ByRj+8QETBQcFA/yTFAwMAQ4FBAIvDSAmKi8ZvgAAAAAFAAX/QgP7AwAAIQA0AEAAUABgAMFADggBAgUWAQECAkAQAQE9S7ALUFhAKQoBAAADBAADWQ0IDAYEBAkHAgUCBAVZCwECAQECTQsBAgIBUQABAgFFG0uwFlBYQCINCAwGBAQJBwIFAgQFWQsBAgABAgFVAAMDAFEKAQAACgNCG0ApCgEAAAMEAANZDQgMBgQECQcCBQIEBVkLAQIBAQJNCwECAgFRAAECAUVZWUAmUlFCQSMiAQBbWVFgUmBKSEFQQlA8OzY1LSsiNCM0GhgAIQEhDg4rASIOAhUUFhcWDgQPAT4ENx4BMzI+AjU0LgEDIi4BNTQ+AzMyHgIVFA4BAiIGFRQeATI+ATU0JSIOAhUUFjMyPgI1NCYhIgYVFB4DMzI+ATQuAQIFZ72KUmlbAQgOExIQBQUIHVBGUBgaNxxnuoZPhueKdMF0K1BogkRVm29CcL5PPSoUISciFP7ODxoTDCoeDxsUDCsBsR8pBw0SFgwUIRQUIQMARHSgWGWyPBctJCEYEQUEAQYTFiQUBQVEdKBYdchz/PRTm2E6bllDJTphhUlhmlQBpycfFSMVFSMVHycKEhsPIC0MFRwQHycnHw0XEw4IFSMqIBEAAAEAV/9uA6kC0QF5AaJBjQFiAIYAdAByAHEAbgBtAGwAawBqAGkAYAAhABQAEwASABEAEAAMAAsACgAFAAQAAwACAAEAAAAbAAsAAAFHAUYBRQADAAIACwFgAV0BXAFbAVoBWQFYAUoAqACnAJ0AkACPAI4AjQCMABAADQACAJsAmgCZAJQAkwCSAAYAAQANAS4BLQEqALUAtACzAAYACQABAScBJgElASQBIwEiASEBIAEfAR4BHQEcARsBGgEZARgBFgEVARQBEwESAREBEAEPAQ4BDQEMAO0AzADLAMkAyADHAMYAxADDAMIAwQDAAL8AvgC9ALwAKwAFAAkBCgDoAOcA0wAEAAMABQAHAEABRACHAAIACwCcAJEAAgANAQsAAQAFAAMAP0BFDAELAAIACwJmAAINAAINZAANAQANAWQAAQkAAQlkCgEJBQAJBWQEAQMFBwUDB2YIAQcHZwAACwUASwAAAAVPBgEFAAVDQR4BVwFUAUMBQgFBAT8BLAErASkBKAD9APoA+AD3AOwA6wDqAOkA2wDaANkA2ACmAKUAmACVADkANwAOAA4rEy8CNT8FNT8HNT8iOwEfMRUHFQ8DHQEfERUPDSsCLwwjDwwfDRUXBx0BBxUPDyMHIy8NIycjJw8JIw8BKwIvFDU3NTc9AT8PMz8BMzUvESsBNSMPARUPDSsCLwg1PxfRAgEBAgEDAgQFAQECAgICAgMBAgMEAgMDBAQEBQYDAwcHBwkJCQsICAkKCQsLCwsMCw0NGQ0nDQ0ODA0NDQ0MDAwLCwkFBAkIBwcGBwUFBgQHBAMDAgICBAMCAQIBAgUDAgQDAgICAQEBAQMCAgMMCQQGBQYGBwQDAwMCAwIDAQEBAgQBAgICAwIDAgQDAgMDBAICAwIEBAQDBAUFAQECAgIEBQcGBgcHAwUKAQEFFgkJCQgEAgMDAQIBAQICBAMDAwYGBwgJBAQKCgsLDAslDgwNDQ4ODQ0ODQcGBAQLDAcIBQcKCwcGEAgIDAgICAonFhYLCwoKCgkJCAgGBwIDAgICAQIBAQEBAgEDAgEEAwQCBQMFBQUGBgcHAgEBBAoGCAcICQQEBAMFAwQDAwIBAQEDAQEBBQIEAwUEBQUGBgUHBwECAQICAgIBAQIBAQECAQMDAwMEBQUFBwcHBgcIBAUGBwsIAUsFBwQOBgYHBwgHBQUHBwkDBAQCEwoLDQ4HCQcICggJCQUECgoJCgkKCgcGBwUFBQUEAwQDAgIEAQIBAwMDBAQFBgUHBwYEAwcIBwgICAkICQgRCQgJCAcJDw0MChACAwgFBgYHCAgIBAYEBAYFCgUGAgEFEQ0ICgoLDA4JCAkICQgPEA4TBwwLCgQEBAQCBAMCAQIDAQEDAgQGBgUGCgsBAgMDCw8RCQoKCgUFCgEBAwsFBQcGAwQEBAQEBAQDAwMDAgMFBQMCBQMEAwQBAQMCAgICAQECAQIEAgQFBAICAgEBAQUEBQYDAwYCAgMBAQICAgECAwIEAwQEBQIDAgMDAwYDAwMEBAMHBAUEBQIDBQICAwECAgICAQEBAQECAggFBwcKCgYGBwcHCAkJCAsBAQICAgMIBQQFBgQFBQMEAgIDAQYEBAUFCwcWEAgJCQgKCgkKCQsJCwkKCAgIBAUGBQoGAAAABABeACADogIgABMAKAAsADEAN0A0MTAvLiwrKikIAgMBQAQBAAADAgADWQACAQECTQACAgFRAAECAUUCACYjGRYLCAATAhMFDisBISIOARURFBYzITI2NRE0LgMTFAYjISIuBTURNDYzBTIWFRcVFxEHESc1NwJf/kYSIRQrHAG6HCcHDBAUFRMO/kYECAcHBQQCFg8Bug4TXsQigIACIBEeEv6IHCsqHQF4CxQQDAb+Rw8WAgQFBwcIBAF4DRIBEQ1pq2sBgDz+90OEQwAAAAYAgAAAA4ACQAAfAEkAUQBZAF0AZQDfS7AoUFhAUgAPCw4HD14AEA4SDhASZgABCQEIAwEIWQADAAcDSwQCEwMACgEHCwAHWQALAA4QCw5ZABIAEQ0SEVkADQAMBg0MWQAGBQUGTQAGBgVSAAUGBUYbQFMADwsOCw8OZgAQDhIOEBJmAAEJAQgDAQhZAAMABwNLBAITAwAKAQcLAAdZAAsADhALDlkAEgARDRIRWQANAAwGDQxZAAYFBQZNAAYGBVIABQYFRllALAEAZWRhYF1cW1pXVlNST05LSkZEOjg3Ni8tJiMaFxIQDw4NDAgFAB8BHxQOKwEjJicuASsBIgYHBgcjNSMVIyIGFREUFjMhMjY1ETQmExQOASMhIiY1ETQ+AjsBNz4BNzY/ATMwOwEeAhceAx8BMzIeARUkIgYUFjI2NAYiJjQ2MhYUNzMVIwQUFjI2NCYiA0N7AwYwJBCxECMuCAQbRBsbKCkaAoAaIyMDBw4I/YANFgYJDQeICQQPAyYNDLEBAQEDBQMFDxgSCgmKCQ0H/ueOZGSOZHF0UVF0UTUiIv8AJTYlJTYB4AMHNSEfNAgFICAkGf6gGygoGwFgGiP+YwoPChYNAWAGCwcFBgUTBCoMCAECAwMFERwUCwYHDggCZI5kZI7SUXRRUXTgImk2JSU2JQADAQD/YAMAAuAACwAXADEATUBKDAsCBQMCAwUCZgAAAAMFAANZAAIAAQQCAVkABAoBBgcEBlkJAQcICAdLCQEHBwhPAAgHCEMYGBgxGDEuLSwrERETEycVFxUQDRcrACIGFREUFjI2NRE0AxQGIiY1ETQ2MhYVFxUUDgEjIiY9ASMVFBYXFSMVITUjNT4BPQECQYJdXYJdIEpoSkpoSmA7ZjtagiaLZZIBQopjhwLgYkX+y0ViYkUBNUX+hjhPTzgBNThPTziZnzxkO4Bbn59lkwd+JCR+B5NlnwAABAD0/2ADDALgABIAJAAsADkARkBDFhQTDAoGBgMEAUAYCAIDPQAAAAECAAFZAAIABQQCBVkGAQQDAwRNBgEEBANRAAMEA0UuLTQzLTkuOSopJiUhIBAHDysAIgYVFB8CGwE3Nj8BPgI1NAcVBg8BCwEmJy4BNTQ2MhYVFCYiBhQWMjY0ByImNTQ+ATIeARQOAQJv3p0TAQP19QEBAQEGCQQyAQEC1tgBAQgKisSKt2pLS2pLgCc3GSwyLBkZLALgm24zMgMG/fcCCQIDAQMQISIRb8gBAQME/jkBywMBFi4XYYiIYS63S2pLS2qTNycZLBkZLDIsGQACAQD/YAMAAuAACwAlAEFAPgoJAgMBAAEDAGYAAQAAAgEAWQACCAEEBQIEWQcBBQYGBUsHAQUFBk8ABgUGQwwMDCUMJRERERETEykVEAsXKyQyNjURNCYiBhURFCUVFA4BIyImPQEjFRQWFxUjFSE1IzU+AT0BAb+CXV2CXQF8O2Y7WoImi2WSAUKKY4ddYkUBNUViYkX+y0XhnzxkO4Bbn59lkwd+JCR+B5NlnwAAAAIA9P9gAwwC4AASAB8AK0AoDAoIBgQBPQMBAQIBaQAAAgIATQAAAAJRAAIAAkUUExoZEx8UHxAEDysAIgYVFB8CGwE3Nj8BPgI1NAUiJjU0PgEyHgEUDgECb96dEwED9fUBAQEBBgkE/vQnNxksMiwZGSwC4JtuMzIDBv33AgkCAwEDECEiEW/DNycZLBkZLDIsGQAFAQD/YAMwAuAAAwAKABUAHQA1AF9AXAcBAgEcGxQGBAACIQEEACABAwQEQAUBAgEAAQIAZgABCgEABAEAWQAEBgEDBwQDWQkBBwgIB0sJAQcHCE8ACAcIQwUENTQzMjEwLy4rKiQiHx4YFxAOBAoFCgsOKwE3AQclMjcDFRQWNxE0JiMiDgEHATY3NSMVFAcXNgc2NycGIyIuAz0BIxUUFhcVIxUhNSMBERwCAxz+7CUg413fXEIZLyYPARIJYiIiFDDqMi0TLTMjQzYpFyaLZZIBQooC0BD8kBD9EQGB60VipwE1RWIQHRP+LRoan59ANSJDqwMXIBYWKTVDI6CfZZMHfiQkAAADAED/oAPAAqAABwAXADoAkEALMQEBBzowAgMFAkBLsBhQWEAwAAYBAAEGAGYABAAFBQReCAECAAcBAgdZAAEAAAQBAFkABQMDBU0ABQUDUgADBQNGG0AxAAYBAAEGAGYABAAFAAQFZggBAgAHAQIHWQABAAAEAQBZAAUDAwVNAAUFA1IAAwUDRllAFAoINjMuLCUjGxkSDwgXChcTEAkQKwAyNjQmIgYUASEiBhURFBYzITI2NRE0JgMmIyIGDwEOBCMiJy4CLwEmIyIHAxE+ATMhMh4BFRMCuFA4OFA4AQj88BchIRcDEBchIeULDwcLByYCBAUEBQMNCQEDAwFsDRQUDv0CDgoCzAYMBwEBYDhQODhQAQghGP1yGCEhGAKOGCH+dQwGBSACAgMBAQgBAgQBdA8P/s8CCQoNBgsH/fcAAAAIAFb/PQO3AskAKQA2AFUAYwBxAIAAkQCdALJAr3IBBwxNAQYHcAELCTg3IBMEAgVMRUQZBAACKgEBAAZAVVROAwQMPgAGBwkHBglmAAUOAg4FAmYAAgAOAgBkAAABDgABZAABAWcADAALBAwLWQAJAAoDCQpZAAQAAw0EA1kSAQ0AEAgNEFkRAQcACA8HCFkADw4OD00ADw8OUQAODw5FgoFXVpiWk5KKiIGRgpF/fnd2bWxlZF1cVmNXY1FQSUhAPjIwIyIdHBcVEw4rAScPAScmDwEOARURFB4DNj8BFxYzMj8BFhcWMjc2NxcWMjY3NjURNAEuATU0PgEzMhYVFAY3Jz4BNTQuASMiBhUUFwcnLgEjBg8BETcXFjI2PwEXBSIGFREUFjI2NRE0LgEXIg4CHQEUFjI2PQEmNxUUHgEyPgE9ATQuASMGAyIOAhUUFjMyPgI1NC4BBiImNDYzMh4CFRQDqbcL28kHB9MGBgIEBAYGA83KAwQEAx4vQwUUBWQsTgMGBQIH/vw2XCdDKD1WXakzBgUxVDJMayYWyQIDAgQDusHKAgUFAtyi/aoICwsPCwUIzAQHBQMLDwsDxAUICgkFBQkFDzAOGRILKBwOGRMLEx8GGhMTDQcLCQUCnyoBZFQDA1ICCQb9vAMGBQMCAQFQVQECDV5mCAiXbhIBAgIGCAJFDvzVVbUqJ0QnVjwqtZoMERwMMVUxbEspUgpUAQEBAUgCHExVAQEBZCU1Cwf+kAgLCwgBcAUIBUcDBQcDjQcLCweND1K6BQkEBAkFugUIBQP+nQsSGQ4cKAoTGQ4SIBJkExoTBQkMBg0AAAAAAwCg/+ADgAKgAAkAEgAjAEFAPh4SEQ0MBQIGDgkIAwQBAkAABQYFaAAGAgZoAAQBAAEEAGYAAgABBAIBVwAAAANPAAMDCwNCEicYEREREAcVKykBESE3IREhEQcFJwEnARUzASc3Jy4CIyIPATMfATc+ATU0AuD94AGgIP4gAmAg/vsTAVYW/phAAWkXRhkCBwcECwgZARYqGAQEAgAg/cABwCCYEwFXF/6YQQFoF0AZAwMCCBgXKhkECgUMAAAABgDg/6ADIAKgACAALwBCAEYASgBOALhAC0A5ODAeEAYICwFAS7AUUFhAQQAKAwwDCl4OAQwNAwwNZA8BDQsDDQtkAAsICAtcAAEABgABBlkHAgIACQUCAwoAA1cACAQECE0ACAgEUgAECARGG0BDAAoDDAMKDGYOAQwNAwwNZA8BDQsDDQtkAAsIAwsIZAABAAYAAQZZBwICAAkFAgMKAANXAAgEBAhNAAgIBFIABAgERllAGU5NTEtKSUhHRkVEQ0JBNBY1GjMRFTMQEBcrASM1NCYrASIOAh0BIxUzExQWMyEyPgc1EzMlND4COwEyHgMdASMBFRQGIyEiJi8BLgQ9AQMhBzMRIxMjAzMDIxMzAyCgIhmLCxYQCaAqLyMYARoFCwkJCAYFBAIuKf59BQgLBYsFCQcGA8YBDhEM/uYDBgMEAwQDAgEwAbPoHByOHRYezh0VHgI9KBkiCRAWDCgd/bsZIgIDBgYICAoKBgJFRQYLCAUDBgcJBSj9nwENEQECAgIEBQUGAwECRED+HgHi/h4B4v4eAAAAAAIAwP+gA0AC4AALABQAP0A8FBEQDw4NDAcDPgAGAAEABgFmBwUCAwIBAAYDAFcAAQQEAUsAAQEEUAAEAQREAAATEgALAAsREREREQgTKwEVMxEhETM1IREhESUnNxcHJxEjEQJA4P3A4P8AAoD+QheVlRduIAIAIP3gAiAg/aACYDQXlZUXbf4aAeYAAgDA/6ADQAKgAAsAFAA+QDsUERAPDg0MBwEAAUAABgMGaAcFAgMCAQABAwBXAAEEBAFLAAEBBFAABAEERAAAExIACwALEREREREIEysBFTMRIREzNSERIREFBxc3JwcRIxECQOD9wOD/AAKA/kIXlZUXbiACACD94AIgIP2gAmDZF5WVF20B5v4aAAADAFH/cQOvAsAADgAdACkAJ0AkKSgnJiUkIyIhIB8eDAE9AAABAQBNAAAAAVEAAQABRRkYEgIPKwEuASIGBw4BHgI+AiYDDgEuAjY3PgEyFhcWEAMHJwcXBxc3FzcnNwMmPJuemzxQOTmg1tagOTloScXFkjQ0STePkI83b9WoqBioqBioqBipqQJGPD4+PFDW1qA5OaDW1v4cSTQ0ksXFSTY5OTZw/sQBXqinF6ioF6eoGKioAAAAAgB+AAADgAJgABMAIgBBQD4WCgIDBBsXEhAJBQABAkAVCwICPgAAAQBpAAIFAQQDAgRZAAMBAQNNAAMDAVEAAQMBRRQUFCIUIhsUFhAGEis7ATc2Nz4CNxUJARUGBwYXMBUwATUNATUiBgcmPgWAFSZKThwrQCYBgP6At2hjAgGgASj+2IyvRQEBDBg4T4M+dyMMDwwBoAEAAQChCGhkpQYBYIHBwoJcdwcZRkBOOCcAAAAAAgCAAAADgAJgAB8AKgA6QDclDAIDBCQgDQAEAgECQCYLAgA+AAIBAmkAAAAEAwAEWQADAQEDTQADAwFRAAEDAUUUHBYUGQUTKyUwNTQuAicuASc1CQE1HgEXHgEfATMwPQcnLgEjFS0BFSAXFgOAAxAsIzWLXv6AAYA3TCorSiMmFSBFr4z+2AEoAQRZI0AGGipRUSM1NwSh/wD/AKACExMUTjg+BwcIBwcIBggTd1yCwsGBtEkAAAMAYP+AA6ACwAAVAB0ALgBdQFoNAQIICwEEAQJADAEBAT8JAQQBAAEEAGYABQAIAgUIWQACAAEEAgFZAAAAAwcAA1kKAQcGBgdNCgEHBwZRAAYHBkUfHgAAJyYeLh8uGxoXFgAVABUTFBUiCxIrARQGIyIuATQ+ATMVNycVIgYUFjI2NQIgBhAWIDYQASIuATU0PgIyHgIUDgIC2H5aO2M6OmM7wMBqlpbUllT+qPT0AVj0/mBnsGY8Zo6ajmY8PGaOASBafjpjdmM6b2+AWJbUlpVrAaD0/qj09AFY/ddmsGdNjmY8PGaOmo5mPAAAAAIAQP+AA8ACwAAJABMALkArEAICAD4TDQwLCgkIBwYFCgI9AQEAAgIASwEBAAACTwMBAgACQxIaEhAEEisBIQsBIQUDJQUDFycHNychNxchBwPA/qlpaf6pARhtARUBFW4u1dVV2AEGUlIBBtgBggE+/sLE/sLFxQE+6JiY9ZX395UAAAMAYP+AA6ACwAAHABoAJgBHQEQAAAADBAADWQkBBQgBBgcFBlcABAAHAgQHVwoBAgEBAk0KAQICAVEAAQIBRQkIJiUkIyIhIB8eHRwbEA4IGgkaExALECsAIAYQFiA2EAEiLgE0PgEzMh4EFRQOAgMjFSMVMxUzNTM1IwKs/qj09AFY9P5gZ7BmZrBnNGNTRzEbPGaOPSHv7yHw8ALA9P6o9PQBWP3XZrDOsGYbMUdTYzRNjmY8An3wIe/vIQAAAAMAYP+AA6ACwAAHABgAHAA8QDkABAMFAwQFZgAFAgMFAmQAAAADBAADWQYBAgEBAk0GAQICAVIAAQIBRgkIHBsaGREQCBgJGBMQBxArACAGEBYgNhABIi4BNTQ+AjIeAhQOAgEhFSECrP6o9PQBWPT+YGewZjxmjpqOZjw8Zo7+swIA/gACwPT+qPT0AVj912awZ02OZjw8Zo6ajmY8AY0iAAAAAgBg/4ADoALAAAcAGAApQCYAAAADAgADWQQBAgEBAk0EAQICAVEAAQIBRQkIERAIGAkYExAFECsAIAYQFiA2EAEiLgE1ND4CMh4CFA4CAqz+qPT0AVj0/mBnsGY8Zo6ajmY8PGaOAsD0/qj09AFY/ddmsGdNjmY8PGaOmo5mPAACAD7/XgPCAuIAEQArACpAJwQBAAADAgADWQACAQECTQACAgFRAAECAUUCACYjGRYMCQARAhEFDisBISIOAhURFBYzITI2NRE0JhMUDgIjISIuBTURNDYzITIeAxUDW/1KFSYcEDwrArYrPDwPCA4TCv08BgsKCQcFAx4VAsQIEAwKBQLiEBwmFf1KKzw8KwK2Kzz83AoTDggDBQcJCgsGAsQVHgUKDBAIAAAAAgBR/3EDrwLAAA4AGgAZQBYaGRgXFhUUExIREA8MAD0AAABfEgEPKwEuASIGBw4BHgI+AiYDBycHJzcnNxc3FwcDJjybnps8UDk5oNbWoDk5thioqBioqBioqBipAkY8Pj48UNbWoDk5oNbW/oIYqKcXqKgXp6gYqAAAAAIAYP+AA6ACwAAHABwAQ0BADgEDABABBgQCQA8BBAE/AAYEBQQGBWYAAAADBAADWQAEAAUCBAVZAAIBAQJNAAICAVEAAQIBRRIVFBMTExAHFSsAIAYQFiA2EAAiJjQ2MzUXBzUiDgEVFBYyNjUzFAKs/qj09AFY9P7K1JaWasDAO2M6f7N+KALA9P6o9PQBWP5UltSWWIBvbzpjO1l/flpqAAAAAQBA/4ADwALAAAkAGEAVAgEAPgkIBwYFBQA9AQEAAF8SEAIQKwEhCwEhBQMlBQMDwP6paWn+qQEYbQEVARVuAYIBPv7CxP7CxcUBPgAAAAACAGD/gAOgAsAABwATADZAMwcBBQYCBgUCZgQBAgMGAgNkAAAABgUABlcAAwEBA0sAAwMBUgABAwFGERERERETExAIFisAIAYQFiA2EAcjFSM1IzUzNTMVMwKs/qj09AFY9KDwIu7uIvACwPT+qPT0AVi+7u4i8PAAAAAAAgBg/4ADoALAAAcACwAhQB4AAAADAgADVwACAQECSwACAgFRAAECAUURExMQBBIrACAGEBYgNhAHITUhAqz+qPT0AVj0oP4AAgACwPT+qPT0AVi+IgAAAAMANP9TA80C7AAHABgAKgA5QDYAAQQABAEAZgAABQQABWQAAwYBBAEDBFkABQICBU0ABQUCUgACBQJGGhkjIRkqGioXFRMSBxIrABQWMjY0JiIFFA4CIi4CND4CMh4CASIOAhUUHgEzMj4CNTQuAQEufK57e64CI0h8qryre0lJe6u8qnxI/jRRlGtAa7htUZRrP2u4AXeve3uve9Ndq3tJSXuru6t7SUl7qwEyQGqUUmy4az9rlFFtuGsAAgBg/4ADoALAAAcAEgAnQCQSERAPDgUCAAFAAAACAGgAAgEBAk0AAgIBUgABAgFGJBMQAxErACAGEBYgNhABBiMiJi8BNxc3FwKs/qj09AFY9P4gCQkECgRwJF76IwLA9P6o9PQBWP7BCQUEcCNe+yQAAAACAD7/XgPCAuIAFAAcACpAJxwbGhkYFgYBAAFAAgEAAQEATQIBAAABUQABAAFFAgAKBwAUAhQDDisBISIGFREUFjMhMjY1ETQuBQEnByc3FwEXA1v9Sis8PCsCtis8BQsOEhQX/kQFBcogrwFjIALiPCv9Sis8PCsCtgwXFREOCwX9bwUFyiCvAWMgAAEBQABgAsAB4AALAAazCAABJisBBycHFwcXNxc3JzcCqKioGKioGKioGKmpAeCpqBeoqBenqBepqAAAAAEBAAAgAwACeAAUADlANggBBAIBQAcBAgE/BgEBPgAEAgMCBANmAAEAAgQBAlkAAwAAA00AAwMAUQAAAwBFEhUUExAFEyskIiY0NjM1Fwc1Ig4BFRQWMjY1MxQCatSWlmrAwDtjOn+zfiggltSWWIBvbzpjO1l/flpqAAABAID/oAQAAqAAJgA4QDUbGgoJCAcGBQQJAgEBQAQBAAABAgABWQACAwMCTQACAgNRAAMCA0UBAB8dFxUQDgAmASYFDisBMh4BFTcXByc3FzQuAiMiDgEUHgEzMj4BNxcOASMiLgE1ND4CAgBosWduEo2FEmY5YIRJYaVgYKVhTYtjGBknyH1osWc9Z44CoGaxaGkSiIgSaUmEYDhgpcKlYD5uRwd0kmexaE6OZz0AAAIAQP+AA8ACwAAJAA8AKkAnCgcCAD4PDg0EAwIBAAgCPQEBAAICAEsBAQAAAk8AAgACQxISFQMRKyUDJQUDJSELASElFyEHFycBWG0BFQEVbQEY/qlpaf6pAcBSAQbYVdW+/sLFxQE+xAE+/sLU9pX1lwAAAgAA/yAEAAMgABQAKwA8QDkABQECAQUCZgACBAECBGQABAcBAwQDVQABAQBRBgEAAAoBQhYVAQAmJSEfFSsWKw8OCggAFAEUCA4rASIOAgc+AjMyEhUUFjI2NTQuAQMyPgM3DgMjIgI1NCYiBhUUHgECAGe7iVIDA3C+b6z0OFA4ieyLUpt8XzYCAkRvmFOs9DhQOInsAyBPhrlmd8l0/vq6KDg4KIvsifwAMl16mVJZonRFAQa6KDg4KIvsiQAADAAl/0QD2wL6AA8AHQAuADwATgBfAHAAgACVAKcAtADDAG1AapWBcAMBAE49AgYBLh4CBQa1AQkKlgECCQVAAAoFCQUKCWYACQIFCQJkCwEAAAEGAAFZCAEGBwEFCgYFWQQBAgMDAk0EAQICA1EAAwIDRQEAuLeYlzs4NDErKCMgHRwXFhEQCgkADwEPDA4rATIeAx0BFAYiJj0BNDYTMhYdARQGIiY9ATQ2MwEUBisBIi4BNTQ2OwEyHgEVIRQGKwEiJjU0NjsBMhYlFhQGDwEGJicmNj8BPgEeARcBFgYPAQ4BLgEnJjY/ATYWFwEeAQ8BDgEnLgE/AT4CFhcBHgEPAQ4BJy4BNj8BPgEXAz4BHgEfARYGBwYmLwEuAT4DNwE2MhYfARYGBw4BLgEvASY2NwE+AR8BHgEOAS8BLgEBPgEyHwEeAQ4BLwEuATcCAAUJBwYDEhgSEgwMEhIYEhIMAdsSDH4IDggSDH4IDgj9BBIMfgwSEgx+DBICvAQIB20KGAcGBwptBgwKCgP9agYGC20FDAsJAwcHC2wLGAYB6AsGBj8GGAoLBwc/AwkLDAX+ggsGBj8GGAsHCAEDPwcYCl0GDAsJAz8GBgsKGAc/AgIBAgMGAwF/Bw8OBD8GBgsFDAsJAz8HBwv91AYYCm0LBgwYC2wLBwKcBQ4PB20LBgwYC20KBwYC+gMFCAkFfQ0REQ19DRH9BBENfgwSEgx+DREBIQwRCA0IDREIDQkMEREMDRER4QgPDgQ/BgYLCxgGPwMBAwcF/oILGAY/AwEDBwULGAY/BgcKAiwGGAttCwYGBhgLbQUHAwED/WoGGAttCwYGBA4QB20LBgYClgMBAwcFbQsYBgYGC20DCAgHBwYC/WoECAdtCxgGAwEDBwVtCxgGAegLBgY/BhgWBgY/Bhj+jQcIBD8GGBYGBj8GGAsAAgCB/6ADgQKgAA8AIAAtQCoOAQIDAgFADwACAT0AAAACAwACWQADAQEDTQADAwFRAAEDAUUoGCMmBBIrBSc2NTQuASMiBhQWMzI3FwEuATU0NjIWFRQOBCMiA4HjQ1KMUn6ysn5rVOL9niYpn+GgEyM0PUUkcTHiVGtSjVGy/LNE4wEPJmQ2caCfcSVFPTQjEwAAAAEBAAAgAwACIAALACVAIgAEAwEESwUBAwIBAAEDAFcABAQBTwABBAFDEREREREQBhQrASMVIzUjNTM1MxUzAwDwIu7uIvABDu7uIvDwAAAAAQFA/+ACwAJgAAUABrMDAQEmKwE3CQEnAQFAQQE//sFBAP8CH0H+wP7AQQD/AAAAAQFA/+ACwAJgAAUABrMDAQEmKwEnCQE3AwLAQf7BAT9B/wIfQf7A/sBBAP8AAAAAAQEsAIQCywG9AAoAEkAPCgkIBwYFAD4AAABfIQEPKyUGIyImLwE3FzcXAcAJCQQKBHAkXvojjQkFBHAjXvskAAQAgP+gA4ACoAAIABEAGwAfAExASR0cGxoYFxYTERAPCAENBAcBQAABBwE/GRICBj4ABgAHBAYHVwAEAAEDBAFXBQEDAAADSwUBAwMATwIBAAMAQxkWERESERESCBYrCQERMxEzETMRAyMRIREjESUFAQc1IxUHFQkBNSUHNTMCAP7A4MDgIKD/AKABIAEg/uDAgEABgAGA/aBAQAJA/wD+YAEA/wABoP6AAQD/AAFx5uYBb5pawDMpATP+zSmAM4YAAAADAGD/gAOgAsAAGQAhACUAPkA7IgEEACUBAQQCQAAEAAEABAFmAAIFAQAEAgBZAAEDAwFNAAEBA1EAAwEDRQEAJCMfHhsaEA4AGQEZBg4rATIeARceARQGBw4EIyIuAScuATQ+AyAGEBYgNhAnBSERAgAzYVckNjo6NhYxNTk7HzNhVyQ2Ojpti/n+qPT0AVj04P5BAP8CnxoyJDeLmos3FSQbEwkaMiQ3i5qMbDoh9P6o9PQBWBTA/wAAAAQAgP+gA4ACoAASAB4ApgE3AW5LsCZQWEBhAAcAHQUHHVkJAQUfGwIaBgUaWQgBBh4BHAAGHFkhAQAAAwQAA1kKIgIEIAEZEgQZWRgBEhEBCwISC1kAAgABFAIBWRYBFA8BDRMUDVkAFQAOFQ5VFwETEwxREAEMDAsMQhtAZwAHAB0FBx1ZCQEFHxsCGgYFGlkIAQYeARwABhxZIQEAAAMEAANZCiICBCABGRIEGVkYARIRAQsCEgtZAAIAARQCAVkWARQPAQ0TFA1ZFwETEAEMFRMMWQAVDg4VTQAVFQ5RAA4VDkVZQUwAIQAfAAEAAAE2ATMBIwEiAR4BHAEQAQ0BBgEEAP8A/QD8APsA7wDsAOcA5ADZANcA0wDRAMsAyADBAL8AvAC6AKwAqQCfAJwAkgCRAI4AjACHAIQAfwB9AHkAdwBqAGcAWgBXAEwASgBGAEQAPAA5ADQAMgAtACsAHwCmACEApgAaABkAFAATAA0ADAAAABIAAQASACMADisBIg4CBwYVFB4BFxYyNjU0JyYCIiY1ND4BMh4BFRQ3IyImNTQ/ATY0LwEmIyIPAQ4CIyImPQE0JisBIgYdARQOAyMiJi8BJiMiDwEGFB8BFhUUDgErASIOAg8BDgMdARQWOwEyHgEVFA4BDwEGFB8BFjMyPwE+ATMyFh0BFBY7ATI2PQE0NjMyHwEWMj8BNjQvASY1NDY7ATI2PQI0LgEXFRQrASIHDgIVFB4BHwEWDwEGIyIvASYjIgYdARQOAisBIiY9ATQnJiMiBg8BBiMiLwEmND8BNjU0JyYrASImPQE0NjsBMjc2NTQmLwEmND8BNjMwMzIeAR8BFjMyPgE3Nj0BNDsBMh4BHQEUHwEeBDMyPwE+ATIWHwEeARUUDwEGFRQeARcWOwEyFQICFCUiIA04DRkSOJ9xOTgNhV0qSldKK68eExsPFA4OLQ4VFQ4TBAsNBhMdHBQ8FR0FCAwOCAkRBxMOFRUOLQ4OEw8MFQwfBAkICAMGAwQDAh4UHwwVDAMHBRMODi0NFhQPEwYRChMcHRQ9FB4bExQOEw4qDi0ODhQPGxMeFBsMFgIPHiAXBwoGBgsIEw0NLAUICAQTGCEfLwMFBgQ8BwsXGB8QHgsSBQgIBC0FBRIaFxYhHwcLCwcfIBcWDQwSBQUsBQgDAgMDARMXIQsTEgcYET0ECAQYCAQJCQoKBiEYEgIHBwcCLQIDBRMZBQoIFiEeDwHgBw8VDThQGjAsEjhwUE85OP6gXkIrSisrSitCkhsTFA0TDykOLA4OEgUHBBsTHhQeHhQfBw4LCAUIBxMODiwOKQ8SDhQMFgwCAwQDBgMHCAkFPBUdDBYMBwwKBRIPKQ4sDg4TBwgbEx4VHR0VHhMbEBMODi0OKQ8TDRQTHBwUHx4OFw1QHhAYBxIUCwoVEgcTDAwtBQUSGi0hHgQHBAMKCB4gFxcNDBMFBS0FDgUSGCEgFxcLBj0HCxcXIBAeCxIFDgUtBAECARMZBQoHFyAfEgUIBR8fGAYDBQQDARkSAwICAi0CBgQHBRMXIQsTEQgXEgAAAwDA/+ADQAJgAAMABgAJAAq3CAcGBQMCAyYrEx8BCQIDEwEnwOlzAST+iAE45uL+tqYBLWfmAoD+bwFM/g8B9f7GSQAEAGD/gAOgAsAABwARABkAKgBRQE4ABwAKAQcKWQABAAACAQBZAAIAAwQCA1cLBgIEAAUJBAVXDAEJCAgJTQwBCQkIUQAICQhFGxoICCMiGiobKhcWExIIEQgREREREhMSDRQrABQWMjY0JiITESMVMxUjFTM1EiAGEBYgNhABIi4BNTQ+AjIeAhQOAgHPFyIXFyI6YCAggGz+qPT0AVj0/mBnsGY8Zo6ajmY8PGaOAdkiFxciF/6AAQAQ8BAQAlD0/qj09AFY/ddmsGdNjmY8PGaOmo5mPAAEAGD/gAOgAsAABwAYADMAQABeQFsABQYHBgUHZgAHCAYHCGQAAAADBAADWQsBBAAGBQQGWQwBCAAJAggJWQoBAgEBAk0KAQICAVEAAQIBRTU0GhkJCDk4NEA1QCsqIR8eHRkzGjMREAgYCRgTEA0QKwAgBhAWIDYQASIuATU0PgIyHgIUDgIDIg4BFTMmMzIWFRQGBw4CBzM+ATc+ATU0JgMiBhQWMjY1NC4DAqz+qPT0AVj0/mBnsGY8Zo6ajmY8PGaORis8ICYCYSQyFRIXGQsBJgENIBoaRjEPExQcFAQGCAsCwPT+qPT0AVj912awZ02OZjw8Zo6ajmY8AlkbOCldLSMWJREVJikdKiEfGC4fMjv+ixMcFBQOBQsIBgMAAAAABQDA/4ADQALAAAsAEwAXACkAMQBYQFUnIAIJCgFAAAAABAEABFkFDAMDAQAHCAEHVwAIAAsKCAtZAAoACQYKCVkABgICBksABgYCTwACBgJDAAAvLisqJCMbGhcWFRQTEg8OAAsACxETEw0RKwE1NCYiBh0BIxEhESU0NjIWHQEhASERIQc0JiIGFRQWFxUUFjI2PQE+AQYiJjQ2MhYUAtB6rHpwAoD+EGeSZ/6gAdD9wAJA4CU2JRsVCQ4JFRszGhMTGhMBYJBWenpWkP4gAeCQSWdnSZD+QAGgoBslJRsWIwVSBwkJB1IFIwoTGhMTGgAAAAYAwQDgA0ABYAAHAA8AHgAnAC8ANwBFQEIKDQYDAggMBAMAAQIAWQkFAgEDAwFNCQUCAQEDUQsHAgMBA0UgHxEQNTQxMC0sKSgkIx8nICcYFhAeER4TExMQDhIrADIWFAYiJjQ2IgYUFjI2NCUyHgEVFAYjIi4CNTQ2NyIGFBYyNjQmBDIWFAYiJjQ2IgYUFjI2NAHxHhUVHhU/NiUlNiX+wQoQChUPBw4JBhUPGyUlNSYmAdYeFRUeFT82JSU2JQFEFR4VFR4xJTYlJTYJChAKDxUGCQ4HDxUcJTYlJTYlHBUeFRUeMSU2JSU2AAAAAAIBAP/gAwACYAAwAEsBIUuwC1BYQB4vFwIJA0s+AgoBPQEFCDEBBwUtKgIGBwVAGwEHAT8bS7AMUFhAHi8XAgkDSz4CCgI9AQUIMQEHBS0qAgYHBUAbAQcBPxtAHi8XAgkDSz4CCgE9AQUIMQEHBS0qAgYHBUAbAQcBP1lZS7ALUFhALwAACQEJAAFmAAMACQADCVkCAQEACggBClkACAAFBwgFWQAHAAYEBwZZAAQECwRCG0uwDFBYQC8BAQAJAgkAAmYAAwAJAAMJWQACAAoIAgpZAAgABQcIBVkABwAGBAcGWQAEBAsEQhtALwAACQEJAAFmAAMACQADCVkCAQEACggBClkACAAFBwgFWQAHAAYEBwZZAAQECwRCWVlAD0pIQkAkLDQjFikxEhALFysBIg4EIyIuAS8BJicuAiMiDgEPARkBMxE+ATMyHgEXFjMyPgM3PgE3ETUGAwYjIicuAiMiDgEHET4BMzIXHgQzMjcC4AISCBEMDwcOGh4JGxIHHCEzFipAEgUHIA0zKBMqNQ5aMQgREgsUAwoPBwwUNxYuVw03LRUYKhsLDTMoLVMGJxIgHA4XOAJAAwEBAQECBQIGBAEGBwYLCAMF/rf+5AEfBQgIDwMTAQIBAgEBAgEBOiEC/sMHEgMPCQQFAwETBQgSAQkDBgIHAAACAID/oAOAAqAACAASADVAMhIRDw4NCggBAAkBAwFAEAkCAz4AAQMAAwEAZgADAQADSwADAwBPAgEAAwBDFBEREgQSKwkBETMRMxEzEQEHNSMVBxUJATUCAP7A4MDg/sDAgEABgAGAAkD/AP5gAQD/AAGgAWCaWsAzKQEz/s0pAAIAgP+gA4ACoACBAI4ApLaIhwIHAAFAS7AmUFhAMQADAA8AAw9ZBhACAA0BBw4AB1kEAQILAQkIAglZAA4ACg4KVQUBAQEIUQwBCAgLCEIbQDcAAwAPAAMPWQYQAgANAQcOAAdZAA4JCg5NBAECCwEJCAIJWQUBAQwBCAoBCFkADg4KUQAKDgpFWUAmAgCMi4WEe3hramdlX1xXVVFPRUI8OSwqJSMbGBMRDQwAgQKBEQ4rASMiJjU0PwE2NC8BJiIPAQ4BIyImPQE0JisBIg4BHQEUDgIjIi4BLwEmIyIPAQYUHwEeAxUUBisBIg4BHQEUFjsBMhYVFA8BBhQfARYzMj8BPgEzMhYdARQWOwEyNj0BND4BMzIfARYyPwE+ATQmLwEmNTQ+ATsBMjY9AjYmBxQGIiY1MTQ+ATIeAQNRHhMbDxQODi0OKg4TBxEKExwdFD0NFg0IDREJBwwKBRMOFRUOLQ4OEwQFBAIbEh8NFw4eFB8SGw8TDg4tDRYUDxMGEgkTHB0UPRQdDRUNEw8TDikPLAcICAcTDwwVDB8UGgEbw16FXSpKV0orAW8cExMOEw4pDywODhMHCBsSHxQeDhcNHwkQDQcDBwUTDg4sDikPEgQICAkFExwNFg48FRwcExQOEg8pDiwODhMHCBsTHhQeHRUeDBUNEBIODiwHExITBxMNFA0VDRwUHx4VHE9CXl5CK0orK0oAAAMAYP+AA6ACwAAHABEAGwA3QDQAAAACAwACWQADAAcGAwdXAAYIAQUEBgVXAAQBAQRLAAQEAVEAAQQBRREREREUFBMTEAkXKwAgBhAWIDYQJDIWFRQGIiY1NBMjNTM1IzUzETMCrP6o9PQBWPT+RiIXFyIXcYAgIGAgAsD0/qj09AFYJBcREBgYEBH+hxDwEP8AAAADAGD/gAOgAsAABwAUAC4ASEBFAAUHBgcFBmYABgQHBgRkAAAABwUAB1kABAADAgQDWggBAgEBAk0IAQICAVIAAQIBRgkIKignJiUjGRgNDAgUCRQTEAkQKwAgBhAWIDYQASImNDYyFhUUDgM3DgEHIzQ+Ajc+ATU0JiMiFyM2MzIWFRQGAqz+qPT0AVj0/mkPExMdFAQGCAs+IA0BJgcOFhESFTIkYQImAYYzRhoCwPT+qPT0AVj+eBQcExMOBgoIBwPnICEqFiEfGxARJhUjLV18OzIeLwADAMEA4ANAAWAABwAQABgAK0AoBAYCAwABAQBNBAYCAwAAAVEFAwIBAAFFCQgWFRIRDQwIEAkQExAHECsAIgYUFjI2NCUiBhQWMjY0JiAiBhQWMjY0Ahs2JSU2Jf7BGyUlNSYmAgA2JSU2JQFgJTYlJTYlJTYlJTYlJTYlJTYAAAwAQP/QA8ACcAAHAA8AFwAfACcALwA1ADsAQwBLAFMAWwEES7AhUFhAYgACAAJoAAMBCgEDCmYACggBCghkAAsJBgkLBmYABgQJBgRkAAcFB2kYFwIUFgEVARQVVwAAAAEDAAFZDwEMDgENCQwNWAAIAAkLCAlZEwEQEgERBRARWAAEBAVRAAUFCwVCG0BnAAIAAmgAAwEKAQMKZgAKCAEKCGQACwkGCQsGZgAGBAkGBGQABwUHaRgXAhQWARUBFBVXAAAAAQMAAVkPAQwOAQ0JDA1YAAgACQsICVkABBAFBE0TARASAREFEBFYAAQEBVEABQQFRVlALVRUVFtUW1pZT05NTEpJSEc/Pj08Ozo5ODMyMTAtLCkoJSQTExMTExMTExAZFysAMhYUBiImNDYiBhQWMjY0AjIWFAYiJjQ2IgYUFjI2NAAyFhQGIiY0NiIGFBYyNjQXIRUhNjQiFBcjNTMBMxUjNjU0JgcUFhUhNSEGEzMVIzY1NCYnBhUUFhUhNQKzGhMTGhM6NCYmNCZNGhMTGhM6NCYmNCb+MxoTExoTOjQmJjQmHwIh/d8BwAGhoQI+oaEBAb8B/d8CIQG/oaEBAb4BAf3fAlATGhMTGjMmNCYmNP3mExoTExozJjQmJjQBFhMaExMaMyY0JiY0CiAIEBAIIP7wIAgIBAgMBAgEIAgCKCAICAQIBAgIBAgEIAAJAEQAIAO8AssAFQAnADMARABQAF0AcQB+AIwBEkuwClBYQF4XAQwLAwoMXgANAgoLDV4ABwAIAQcIWQABEgEACQEAWQAJFQEGCwkGWQADEwECDQMCWQALFgEKDwsKWQAPGQEQBQ8QWQAFFAEEEQUEWQARDg4RTQAREQ5RGAEOEQ5FG0BgFwEMCwMLDANmAA0CCgINCmYABwAIAQcIWQABEgEACQEAWQAJFQEGCwkGWQADEwECDQMCWQALFgEKDwsKWQAPGQEQBQ8QWQAFFAEEEQUEWQARDg4RTQAREQ5RGAEOEQ5FWUBGgH9zcl9eUlE1NCooGBYCAISDf4yAjHl4cn5zfmlnXnFfcVhXUV1SXUxLRkU9OzRENUQwLSgzKjMhHhYnGCcOCwAVAhUaDisBISIuBTU0NjMhMh4DFRQGByEiLgI1NDYzITIeAhUUBgchIiY0NjMhMhYUBgEiJjU0PgIzMh4BFRQOAiYiDgEUHgEyPgE0JgMiJjU0PgEyHgEUDgEnIg4BFRQeAzMyPgE1NC4DAyImNTQ+ATIeARQOASciBhQWMjY1NC4EA5r93QQHBwYFAwIUDgIjBQsIBgQUDv3dBg0JBhQOAiMHDAkGFA793Q4UFA4CIw4UFP0DKzwRGyYVGzAbEBwmCxMPCQkPExAJCRkrPBwvNzAbGzAbCg8JAwYJCgYJEAkEBggLBSs8HC83MBsbMBsOFBQcFAMEBggJAkICAwUGBwcEDhQDBgkKBg4U7wYJDAcOFAUJDQcOFO8UHRQUHRQBmjwqFSYbERwvHBUlHBCICQ8TEAkJEBMP/pI8KhwvHBwvNzAbiAkPCgULCAYECRAJBgoJBgP+iTwqHC8cHC83MBuJFB0UFA4FCQcHBAMAAwBA/+EDvwJnAAMABwALACZAIwACAAMAAgNXAAAAAQQAAVcABAQFTwAFBQsFQhEREREREAYUKxMhFSERIRUhESEVIUADf/yBA3/8gQN//IEBPDABWzD92S8AAAAEABf/iAPpArgABQAiADkAPwA9QDo/Pj08Ozo5LSwjIiEfHhQTBgUEAwIBABcCAQFAAAAAAQIAAVkAAgMDAk0AAgIDUQADAgNFLx4XLQQSKwEHJwcXNycwPQEuAyMiDgIHFz4BMh4BFxUUBgcXNjUxBw4BIi4BNTQ2NycGHQMeAjMyNjcBBxc3FzcD01NVFWppUQFBbZdSN2lcTRscMrDMrGUBAQEgAlAysMytZQEBIAICb7ptbsA2/RxpFlNTFgEgU1MWamkYAQJTlWxAHTZNMBBZZ2SsZg4GDgcEFRa4WWdkrWYKFAoEFRYCBANsuGtwYAFIaRdTUxcAAAABAV//nwKgAqAASQBLQEg6AQAFRx8KAwIDAkAABQAFaAcBAAMAaAADAgNoAAIABAECBFkAAQYGAU0AAQEGUgAGAQZGAQBDQTc2LSslIx0bCAcASQFJCA4rASIOARURFAYiJjcwETQ2NzYXHgEVERQOAgcGIyImNTARNCYjIg4BFQMUFjMWNz4CNRM0JyYiBwYHMB0DBhYzFjc2NRE2JgKJBgsGRVtFARIQIyMQEQICBAIGCAkNDQkHCgYBKRwdFAYJBAE4Gz8aOAEBYEBDLi8BDQHqBgsG/no9QUM9AdYXIwkVFQojF/4/BgoICAMHFhMBWgoNBgsG/qcqLwEZCBQXDQHBSyIQDyFLeI19VFFeAS8wTwGFCg4AAwAT//YD7QJJABcAIwAxAJpLsA9QWEAiBwEEAgUCBF4ABQMDBVwAAQYBAgQBAlkAAwMAUgAAAAsAQhtLsBhQWEAkBwEEAgUCBAVmAAUDAgUDZAABBgECBAECWQADAwBSAAAACwBCG0ApBwEEAgUCBAVmAAUDAgUDZAABBgECBAECWQADAAADTQADAwBSAAADAEZZWUAUJSQZGCsqJDElMSAfGCMZIykmCBArARQOBCMiLgM0PgMzMhcWFxYlIg4CFRQWMjY0JgciDgEVFBYyNjU0LgID7SE8WmqGRlGddVsvL1t2nFHInWMdCP4TMFhAJYvFi4tjKUYoWH5YGCg4ASAYPkM/Mx8rRFBNPE1QRCpwR0sW4iZCWjFljo7KjlgpSCpAW1tAIDkqGAAAAQDAAGADQAHgAAUABrMCAAEmKyU3CQEXAQMZJ/7A/sAnARlgKQFX/qkpAS0AAAAAAQDAAGADQAHgAAUABrMCAAEmKwEXCQE3AQMZJ/7A/sAnARkB4Cn+qQFXKf7TAAAAAQFA/+ACwAJgAAUABrMDAQEmKwEnCQE3AQLAKf6pAVcp/tMCOSf+wP7AJwEZAAAAAQFA/+ACwAJgAAUABrMDAQEmKwE3CQEnAQFAKQFX/qkpAS0COSf+wP7AJwEZAAAAAQFA/+ACwAJgACEAJUAiGRgTCwQFAAIBQAAAAgECAAFmAAICAVEAAQELAUIsFREDESsBBiIvAREUBiImNREHBicmNDc2NzYzMhYfAR4BHwEeARUUArsEDQWVCQ4JlQwKBQWuAgYFAwUBAgFYLCsDAgGkBASF/ccHCQkHAjmECwoFDgSfAQUCAQIBUCgnAgYDBwAAAAEBQP/gAsACYAAgACRAIRgTCwQEAgABQAAAAQIBAAJmAAEBAlEAAgILAkIsFREDESslJiIPARE0JiIGFREnJgcGFBcWFxYzMjY3PgE/AT4BNTQCuwQNBZUJDgmVDAoFBa4CBgUEBgEBWCwrAwKcBASFAjkHCQkH/ceECwoFDgSfAQUDAgFQKCcCBgMHAAAAAAEAwABgA0AB4AAdACpAJxYSAgABAUAAAgECaAADAANpAAEAAAFNAAEBAFIAAAEARhwUIyMEEislNi8BITI2NCYjITc2JyYiBwYHBhUUFx4BHwEWMzYBfAoKhQI5BwkJB/3HhAsKBQ4EnwEFBQFQKCcEBwdlCgyVCQ4JlQwKBQWuAgYFBwQBWCwrBQEAAQDAAGADQAHhAB4AJUAiFxMCAAEBQAACAAJpAAEAAAFNAAEBAFEAAAEARR0cIyMDECslJj8BISImNDYzIScmNz4BFhcWFxYVFAcOAQ8BBiMmAoQKCoX9xwcJCQcCOYQLCgMJCAOfAQUFAVAoJwQHB2UKDJUJDgmVDAoDAwIErgIGBQcEAVgsKwUBAAABAR7/pwLaAn8ABgAWQBMAAQA9AAEAAWgCAQAAXxEREQMRKwUTIxEjESMB/N6Rm5BZASgBsP5QAAEAX/97A6ECvQALAAAJAgcJARcJATcJAQNt/pL+lDQBbf6TNAFsAW40/pEBbwK9/pIBbDP+lP6UMwFs/pIzAW4BbQAABABV/3EDqgLIABMAJwA+AEQAAAUGLgE0Nz4BNCYnJjQ+ARceARQGJw4BJjQ3PgE0JicmNDYWFx4BFAYDJyMiJicRPgE3Mzc+AR4BFREUDgEmJzcRByMRMwMwCBgQCTI2NTIJEBgJOj4/rAgYEQgYGRgXCBEYCB8gIuHIpxchAQEhF6fFDh8eEBAbHw4f1Lq4FAkBEhgJNIaXhTQJGBIBCTycsJxSCAESFwkZPkU+GQkXEQEIIVNcU/7ggiEYAbkXIQGTCgMPGxD9HBAaDwEIMALkn/5HAAAABQBA/3wDwAK8AAsAHwAzAEgAXQAAJSEiJjQ2MyEyFhQGAyMiJjQ2OwEyNj0BNDYyFh0BDgEFIy4BJzU0NjIWHQEUFjsBMhYUBgMiJj0BPgE3MzIWFAYrASIGHQEUBiEiJj0BNCYrASImNDY7AR4BFxUUBgOg/MAOEhIOA0AOEhJuwA4SEg7ADhISHBIBNv33oCk2ARIcEhIOoA4SEu4OEgE2KaAOEhIOoA4SEgLyDhISDsAOEhIOwCk2ARL8EhwSEhwS/oASHBISDqAOEhIOoCk2AQE2KaAOEhIOoA4SEhwSAiASDqApNgESHBISDqAOEhIOoA4SEhwSATYpoA4SAAAADACWAAEAAAAAAAEACAASAAEAAAAAAAIABgApAAEAAAAAAAMAHABqAAEAAAAAAAQADwCnAAEAAAAAAAUALwEXAAEAAAAAAAYADwFnAAMAAQQJAAEAEAAAAAMAAQQJAAIADAAbAAMAAQQJAAMAOAAwAAMAAQQJAAQAHgCHAAMAAQQJAAUAXgC3AAMAAQQJAAYAHgFHAGkAYwBvAG4AZgBvAG4AdAAAaWNvbmZvbnQAAE0AZQBkAGkAdQBtAABNZWRpdW0AAGkAYwBvAG4AZgBvAG4AdAAgAE0AZQBkAGkAdQBtADoAVgBlAHIAcwBpAG8AbgAgADEALgAwADAAAGljb25mb250IE1lZGl1bTpWZXJzaW9uIDEuMDAAAGkAYwBvAG4AZgBvAG4AdAAgAE0AZQBkAGkAdQBtAABpY29uZm9udCBNZWRpdW0AAFYAZQByAHMAaQBvAG4AIAAxAC4AMAAwACAARABlAGMAZQBtAGIAZQByACAAMQAzACwAIAAyADAAMQA4ACwAIABpAG4AaQB0AGkAYQBsACAAcgBlAGwAZQBhAHMAZQAAVmVyc2lvbiAxLjAwIERlY2VtYmVyIDEzLCAyMDE4LCBpbml0aWFsIHJlbGVhc2UAAGkAYwBvAG4AZgBvAG4AdAAtAE0AZQBkAGkAdQBtAABpY29uZm9udC1NZWRpdW0AAAAAAAIAAAAAAAD/UQAyAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAAEAAgBbAQIBAwEEAQUBBgEHAQgBCQEKAQsBDAENAQ4BDwEQAREBEgETARQBFQEWARcBGAEZARoBGwEcAR0BHgEfASABIQEiASMBJAElASYBJwEoASkBKgErASwBLQEuAS8BMAExATIBMwE0ATUBNgE3ATgBOQE6ATsBPAE9AT4BPwFAAUEBQgFDAUQBRQFGAUcBSAFJAUoBSwFMAU0BTgFPAVABUQFSAVMBVAFVAVYBVwFYAVkBWgFbAVwBXQd1bmlFMTAwB3VuaUUxMDEHdW5pRTEwMgd1bmlFMTMwB3VuaUUxMzEHdW5pRTEzMgd1bmlFMjAwB3VuaUUyMDEHdW5pRTIwMgd1bmlFMjAzB3VuaUUyMzAHdW5pRTIzMQd1bmlFMjMyB3VuaUUyMzMHdW5pRTI2MAd1bmlFMjYxB3VuaUUyNjIHdW5pRTI2Mwd1bmlFMjY0B3VuaUUzMDAHdW5pRTMwMQd1bmlFMzAyB3VuaUUzMDMHdW5pRTMzMgd1bmlFMzMzB3VuaUUzNjAHdW5pRTM2Mwd1bmlFMzY0B3VuaUU0MDAHdW5pRTQwMQd1bmlFNDAyB3VuaUU0MDMHdW5pRTQwNAd1bmlFNDA1B3VuaUU0MDYHdW5pRTQwNwd1bmlFNDA4B3VuaUU0MDkHdW5pRTQxMAd1bmlFNDExB3VuaUU0MTMHdW5pRTQzNAd1bmlFNDM3B3VuaUU0MzgHdW5pRTQzOQd1bmlFNDQwB3VuaUU0NDEHdW5pRTQ0Mgd1bmlFNDQzB3VuaUU0NjAHdW5pRTQ2MQd1bmlFNDYyB3VuaUU0NjMHdW5pRTQ2NAd1bmlFNDY1B3VuaUU0NjYHdW5pRTQ2OAd1bmlFNDcwB3VuaUU0NzEHdW5pRTQ3Mgd1bmlFNTAwB3VuaUU1MDEHdW5pRTUwMgd1bmlFNTAzB3VuaUU1MDQHdW5pRTUwNQd1bmlFNTA2B3VuaUU1MDcHdW5pRTUwOAd1bmlFNTMwB3VuaUU1MzIHdW5pRTUzNAd1bmlFNTM1B3VuaUU1MzcHdW5pRTU2MAd1bmlFNTYyB3VuaUU1NjMHdW5pRTU2NQd1bmlFNTY3B3VuaUU1NjgHdW5pRTU4MAd1bmlFNTgxB3VuaUU1ODIHdW5pRTU4Mwd1bmlFNTg0B3VuaUU1ODUHdW5pRTU4Ngd1bmlFNTg3B3VuaUU1ODgHdW5pRTU4OQRFdXJvBEV1cm8AAQAB//8ADwABAAAADAAAABYAAAACAAEAAQBfAAEABAAAAAIAAAAAAAAAAQAAAADVpCcIAAAAANJrTZkAAAAA2DhhuQ==) format('truetype');
    }

    .uni-icon {
        font-family: uniicons;
        font-size: 24px;
        font-weight: normal;
        font-style: normal;
        line-height: 1;
        display: inline-block;
        text-decoration: none;
        -webkit-font-smoothing: antialiased;
    }

    .uni-icon.uni-active {
        color: #007aff;
    }

    .uni-icon-contact:before {
        content: '\e100';
    }

    .uni-icon-person:before {
        content: '\e101';
    }

    .uni-icon-personadd:before {
        content: '\e102';
    }

    .uni-icon-contact-filled:before {
        content: '\e130';
    }

    .uni-icon-person-filled:before {
        content: '\e131';
    }

    .uni-icon-personadd-filled:before {
        content: '\e132';
    }

    .uni-icon-phone:before {
        content: '\e200';
    }

    .uni-icon-email:before {
        content: '\e201';
    }

    .uni-icon-chatbubble:before {
        content: '\e202';
    }

    .uni-icon-chatboxes:before {
        content: '\e203';
    }

    .uni-icon-phone-filled:before {
        content: '\e230';
    }

    .uni-icon-email-filled:before {
        content: '\e231';
    }

    .uni-icon-chatbubble-filled:before {
        content: '\e232';
    }

    .uni-icon-chatboxes-filled:before {
        content: '\e233';
    }

    .uni-icon-weibo:before {
        content: '\e260';
    }

    .uni-icon-weixin:before {
        content: '\e261';
    }

    .uni-icon-pengyouquan:before {
        content: '\e262';
    }

    .uni-icon-chat:before {
        content: '\e263';
    }

    .uni-icon-qq:before {
        content: '\e264';
    }

    .uni-icon-videocam:before {
        content: '\e300';
    }

    .uni-icon-camera:before {
        content: '\e301';
    }

    .uni-icon-mic:before {
        content: '\e302';
    }

    .uni-icon-location:before {
        content: '\e303';
    }

    .uni-icon-mic-filled:before,
    .uni-icon-speech:before {
        content: '\e332';
    }

    .uni-icon-location-filled:before {
        content: '\e333';
    }

    .uni-icon-micoff:before {
        content: '\e360';
    }

    .uni-icon-image:before {
        content: '\e363';
    }

    .uni-icon-map:before {
        content: '\e364';
    }

    .uni-icon-compose:before {
        content: '\e400';
    }

    .uni-icon-trash:before {
        content: '\e401';
    }

    .uni-icon-upload:before {
        content: '\e402';
    }

    .uni-icon-download:before {
        content: '\e403';
    }

    .uni-icon-close:before {
        content: '\e404';
    }

    .uni-icon-redo:before {
        content: '\e405';
    }

    .uni-icon-undo:before {
        content: '\e406';
    }

    .uni-icon-refresh:before {
        content: '\e407';
    }

    .uni-icon-star:before {
        content: '\e408';
    }

    .uni-icon-plus:before {
        content: '\e409';
    }

    .uni-icon-minus:before {
        content: '\e410';
    }

    .uni-icon-circle:before,
    .uni-icon-checkbox:before {
        content: '\e411';
    }

    .uni-icon-close-filled:before,
    .uni-icon-clear:before {
        content: '\e434';
    }

    .uni-icon-refresh-filled:before {
        content: '\e437';
    }

    .uni-icon-star-filled:before {
        content: '\e438';
    }

    .uni-icon-plus-filled:before {
        content: '\e439';
    }

    .uni-icon-minus-filled:before {
        content: '\e440';
    }

    .uni-icon-circle-filled:before {
        content: '\e441';
    }

    .uni-icon-checkbox-filled:before {
        content: '\e442';
    }

    .uni-icon-closeempty:before {
        content: '\e460';
    }

    .uni-icon-refreshempty:before {
        content: '\e461';
    }

    .uni-icon-reload:before {
        content: '\e462';
    }

    .uni-icon-starhalf:before {
        content: '\e463';
    }

    .uni-icon-spinner:before {
        content: '\e464';
    }

    .uni-icon-spinner-cycle:before {
        content: '\e465';
    }

    .uni-icon-search:before {
        content: '\e466';
    }

    .uni-icon-plusempty:before {
        content: '\e468';
    }

    .uni-icon-forward:before {
        content: '\e470';
    }

    .uni-icon-back:before,
    .uni-icon-left-nav:before {
        content: '\e471';
    }

    .uni-icon-checkmarkempty:before {
        content: '\e472';
    }

    .uni-icon-home:before {
        content: '\e500';
    }

    .uni-icon-navigate:before {
        content: '\e501';
    }

    .uni-icon-gear:before {
        content: '\e502';
    }

    .uni-icon-paperplane:before {
        content: '\e503';
    }

    .uni-icon-info:before {
        content: '\e504';
    }

    .uni-icon-help:before {
        content: '\e505';
    }

    .uni-icon-locked:before {
        content: '\e506';
    }

    .uni-icon-more:before {
        content: '\e507';
    }

    .uni-icon-flag:before {
        content: '\e508';
    }

    .uni-icon-home-filled:before {
        content: '\e530';
    }

    .uni-icon-gear-filled:before {
        content: '\e532';
    }

    .uni-icon-info-filled:before {
        content: '\e534';
    }

    .uni-icon-help-filled:before {
        content: '\e535';
    }

    .uni-icon-more-filled:before {
        content: '\e537';
    }

    .uni-icon-settings:before {
        content: '\e560';
    }

    .uni-icon-list:before {
        content: '\e562';
    }

    .uni-icon-bars:before {
        content: '\e563';
    }

    .uni-icon-loop:before {
        content: '\e565';
    }

    .uni-icon-paperclip:before {
        content: '\e567';
    }

    .uni-icon-eye:before {
        content: '\e568';
    }

    .uni-icon-arrowup:before {
        content: '\e580';
    }

    .uni-icon-arrowdown:before {
        content: '\e581';
    }

    .uni-icon-arrowleft:before {
        content: '\e582';
    }

    .uni-icon-arrowright:before {
        content: '\e583';
    }

    .uni-icon-arrowthinup:before {
        content: '\e584';
    }

    .uni-icon-arrowthindown:before {
        content: '\e585';
    }

    .uni-icon-arrowthinleft:before {
        content: '\e586';
    }

    .uni-icon-arrowthinright:before {
        content: '\e587';
    }

    .uni-icon-pulldown:before {
        content: '\e588';
    }

    .uni-icon-closefill:before {
        content: '\e589';
    }

    .uni-icon-sound:before {
        content: "\e590";
    }

    .uni-icon-scan:before {
        content: "\e612";
    }
</style>

uni-load-more

readme.md
### LoadMore 加载更多

用于列表中,做滚动加载使用,展示 loading 的各种状态,组件名:``uni-load-more``,代码块: uLoadMore。

**使用方式:**

在 ``script`` 中引用组件 

import uniLoadMore from "@/components/uni-load-more/uni-load-more.vue"
export default {

components: {uniLoadMore}

}


在 ``template`` 中使用组件

<uni-load-more status="loading"></uni-load-more>


实际效果参考:[https://github.com/dcloudio/uni-ui](https://github.com/dcloudio/uni-ui)

**属性说明:**

|属性名        |类型|默认值    |说明|
|---|----|---|---|
|status    |String    |more|loading 的状态,可选值:more(loading前)、loading(loading中)、noMore(没有更多了)|
|show-icon    |Boolean    |true|是否显示 loading 图标|
|color    |String    |#777777|图标和文字颜色    |
|content-text    |Object    |```{contentdown: "上拉显示更多",contentrefresh: "正在加载...",contentnomore: "没有更多数据了"}```|各状态文字说明|

uni-load-more.vue
<template>
    <view class="uni-load-more">
        <view class="uni-load-more__img" v-show="status === 'loading' && showIcon">
            <view class="load1">
                <view :style="{background:color}"></view>
                <view :style="{background:color}"></view>
                <view :style="{background:color}"></view>
                <view :style="{background:color}"></view>
            </view>
            <view class="load2">
                <view :style="{background:color}"></view>
                <view :style="{background:color}"></view>
                <view :style="{background:color}"></view>
                <view :style="{background:color}"></view>
            </view>
            <view class="load3">
                <view :style="{background:color}"></view>
                <view :style="{background:color}"></view>
                <view :style="{background:color}"></view>
                <view :style="{background:color}"></view>
            </view>
        </view>
        <text class="uni-load-more__text" :style="{color:color}">{{status === 'more' ? contentText.contentdown : (status === 'loading' ? contentText.contentrefresh : contentText.contentnomore)}}</text>
    </view>
</template>

<script>
    export default {
        name: "uni-load-more",
        props: {
            status: {
                //上拉的状态:more-loading前;loading-loading中;noMore-没有更多了
                type: String,
                default: 'more'
            },
            showIcon: {
                type: Boolean,
                default: true
            },
            color: {
                type: String,
                default: "#999"
            },
            contentText: {
                type: Object,
                default () {
                    return {
                        contentdown: "上拉显示更多",
                        contentrefresh: "正在加载...",
                        contentnomore: "没有更多数据了"
                    };
                }
            }
        },
        data() {
            return {}
        }
    }
</script>

<style lang="scss">
    .uni-load-more {
        display: flex;
        flex-direction: row;
        height: 80upx;
        align-items: center;
        justify-content: center;

        &__text {
            font-size: 26upx;
            color: $uni-text-color-grey;
        }

        &__img {
            height: 24px;
            width: 24px;
            margin-right: 10px;

            &>view {
                position: absolute;

                view {
                    width: 6px;
                    height: 2px;
                    border-top-left-radius: 1px;
                    border-bottom-left-radius: 1px;
                    background: $uni-text-color-grey;
                    position: absolute;
                    opacity: 0.2;
                    transform-origin: 50%;
                    animation: load 1.56s ease infinite;

                    &:nth-child(1) {
                        transform: rotate(90deg);
                        top: 2px;
                        left: 9px;
                    }

                    &:nth-child(2) {
                        transform: rotate(180deg);
                        top: 11px;
                        right: 0px;
                    }

                    &:nth-child(3) {
                        transform: rotate(270deg);
                        bottom: 2px;
                        left: 9px;
                    }

                    &:nth-child(4) {
                        top: 11px;
                        left: 0px;
                    }
                }
            }
        }
    }

    .load1,
    .load2,
    .load3 {
        height: 24px;
        width: 24px;
    }

    .load2 {
        transform: rotate(30deg);
    }

    .load3 {
        transform: rotate(60deg);
    }


    .load1 view:nth-child(1) {
        animation-delay: 0s;
    }

    .load2 view:nth-child(1) {
        animation-delay: 0.13s;
    }

    .load3 view:nth-child(1) {
        animation-delay: 0.26s;
    }

    .load1 view:nth-child(2) {
        animation-delay: 0.39s;
    }

    .load2 view:nth-child(2) {
        animation-delay: 0.52s;
    }

    .load3 view:nth-child(2) {
        animation-delay: 0.65s;
    }

    .load1 view:nth-child(3) {
        animation-delay: 0.78s;
    }

    .load2 view:nth-child(3) {
        animation-delay: 0.91s;
    }

    .load3 view:nth-child(3) {
        animation-delay: 1.04s;
    }

    .load1 view:nth-child(4) {
        animation-delay: 1.17s;
    }

    .load2 view:nth-child(4) {
        animation-delay: 1.30s;
    }

    .load3 view:nth-child(4) {
        animation-delay: 1.43s;
    }

    @-webkit-keyframes load {
        0% {
            opacity: 1;
        }

        100% {
            opacity: 0.2;
        }
    }
</style>

uni-number-box

readme.md
### NumberBox 数字输入框

带加减按钮的数字输入框,组件名:``uni-number-box``,代码块: uNumberBox。

**使用方式:**

在 ``script`` 中引用组件 

import uniNumberBox from "@/components/uni-number-box/uni-number-box.vue"
export default {

components: {uniNumberBox}

}


在 ``template`` 中使用组件

<uni-number-box></uni-number-box>
<uni-number-box :min="0" :max="9"></uni-number-box>
<uni-number-box @change="bindChange"></uni-number-box>


实际效果参考:[https://github.com/dcloudio/uni-ui](https://github.com/dcloudio/uni-ui)

**NumberBox 属性说明:**

|属性名        |类型    |默认值    |说明                    |
|---        |----    |---    |---                    |
|value        |Number    |0        |输入框当前值            |
|min        |Number    |0        |最小值                    |
|max        |Number    |100    |最大值                    |
|step        |Number    |1        |每次点击改变的间隔大小    |
|disabled    |Boolean|false    |是否为禁用状态            |

**事件说明:**

|事件名称    |说明        |
|---|---|
|change    |输入框值改变时触发的事件,参数为输入框当前的 value|
uni-number-box.vue
<template>
    <view class="uni-numbox">
        <view class="uni-numbox__minus" :class="{'uni-numbox--disabled': disableSubtract||disabled}" @click="_calcValue('subtract')">-</view>
        <input class="uni-numbox__value" type="number" :disabled="disabled" :value="inputValue" @blur="_onBlur">
        <view class="uni-numbox__plus" :class="{'uni-numbox--disabled': disableAdd||disabled}" @click="_calcValue('add')">+</view>
    </view>
</template>
<script>
    export default {
        name: 'uni-number-box',
        props: {
            value: {
                type: Number,
                default: 1
            },
            min: {
                type: Number,
                default: 0
            },
            max: {
                type: Number,
                default: 9999
            },
            step: {
                type: Number,
                default: 1
            },
            disabled: {
                type: Boolean,
                default: false
            }
        },
        data() {
            return {
                inputValue: this.value
            }
        },
        computed: {
            disableSubtract() {
                return this.inputValue <= this.min
            },
            disableAdd() {
                return this.inputValue >= this.max
            }
        },
        watch: {
            value(val) {
                this.inputValue = val;
            },
            inputValue(val) {
                this.$emit('change', val);
            }
        },
        methods: {
            _calcValue(type) {
                if (this.disabled) {
                    return
                }
                const scale = this._getDecimalScale()
                let value = this.inputValue * scale
                let step = this.step * scale
                if (type === 'subtract') {
                    value -= step
                } else if (type === 'add') {
                    value += step
                }
                if (value < this.min || value > this.max) {
                    return
                }
                this.inputValue = value / scale;
            },
            _getDecimalScale() {
                let scale = 1
                // 浮点型
                if (~~this.step !== this.step) {
                    scale = Math.pow(10, (this.step + '').split('.')[1].length)
                }
                return scale
            },
            _onBlur(event) {
                let value = event.detail.value
                if (!value) {
                    this.inputValue = 0
                    return
                }
                value = +value;
                if (value > this.max) {
                    value = this.max
                } else if (value < this.min) {
                    value = this.min
                }
                this.inputValue = value
            }
        }
    }
</script>
<style lang="scss">
    $numbox-btn-width:44upx;
    $numbox-input-width:44upx;
    $numbox-height:52upx;
    $uni-font-size-xxl:32upx;

    .uni-numbox {
        display: inline-flex;
        flex-direction: row;
        justify-content: flex-start;
        height: $numbox-height;
        position: relative;

        &:after {
            content: '';
            position: absolute;
            transform-origin: center;
            box-sizing: border-box;
            pointer-events: none;
            top: -50%;
            left: -50%;
            right: -50%;
            bottom: -50%;
            // border: 1px solid $uni-border-color;
            border-radius: $uni-border-radius-lg;
            transform: scale(.5);
        }

        &__minus,
        &__plus {
            margin: 0;
            // background-color: $uni-bg-color-grey;
            width: $numbox-btn-width;
            font-size: $uni-font-size-xxl;
            height: 100%;
            line-height: $numbox-height;
            text-align: center;
            color: $uni-text-color;
            position: relative;
        }

        &__value {
            position: relative;
            background-color: $uni-bg-color;
            width: $numbox-input-width;
            height: 100%;
            text-align: center;
            min-height: 40upx;
            font-size: 26upx;
            &:after {
                content: '';
                position: absolute;
                transform-origin: center;
                box-sizing: border-box;
                pointer-events: none;
                top: -50%;
                left: -50%;
                right: -50%;
                bottom: -50%;
                border-style: solid;
                border-color: $uni-border-color;
                border-left-width: 0px;
                border-right-width: 0px;
                border-top-width: 0;
                border-bottom-width: 0;
                transform: scale(.5);
            }
        }

        &--disabled {
            color: $uni-text-color-disable;
        }
    }
</style>

uni-rate

readme.md
### Rate 评分

评分组件,组件名:``uni-rate``,代码块: uRate。

**使用方式:**

在 ``script`` 中引用组件 

import uniRate from "@/components/uni-rate/uni-rate.vue"
export default {

components: {uniRate}

}


基本用法

<uni-rate value="2"></uni-rate>


自定义星星大小

<uni-rate size="18" value="5"></uni-rate>


设置评分数

<uni-rate max="10" value="5"></uni-rate>


不可点击状态

<uni-rate disabled="true" value="3.5"></uni-rate>


实际效果参考:[https://github.com/dcloudio/uni-ui](https://github.com/dcloudio/uni-ui)

**属性说明:**

|属性名|类型|默认值    |说明|
|---|----|---|---|
|value|Number|0|当前评分|
|max|Number|5|最大的评分|
|size|Number|24|星星的大小|
|margin|Number|0|星星的间距|
|color|String|#ececec|星星的颜色|
|active-color|String|#ffca3e|选中状态的星星的颜色|
|is-fill|Boolean|true|星星的类型,是否为实心类型|
|disabled|Boolean|false|是否为不可点击状态|

**事件说明:**

|事件称名|说明|返回参数|
|---|----|---|
|change|Rate 的 value 改变时触发事件,返回参数为Rate的value|{value:Number}|
uni-rate.vue
<template>
    <view class="uni-rate">
        <view class="uni-rate-icon" v-for="(star,index) in stars" :key="index" :style="{marginLeft:margin+'px'}" @click="onClick(index)">
            <uni-icon :size="size" :color="color" :type="isFill === false || isFill === 'false' ? 'star' : 'star-filled'"></uni-icon>
            <view class="uni-rate-icon-on" :style="{width:star.activeWitch}">
                <uni-icon :size="size" :color="activeColor" type="star-filled"></uni-icon>
            </view>
        </view>
    </view>
</template>

<script>
    import uniIcon from '../uni-icon/uni-icon.vue'
    export default {
        name: "uni-rate",
        components: {
            uniIcon
        },
        props: {
            isFill: { //星星的类型,是否镂空
                type: [Boolean, String],
                default: true
            },
            color: { //星星的颜色
                type: String,
                default: '#ececec'
            },
            activeColor: { //星星选中状态颜色
                type: String,
                default: '#ffca3e'
            },
            size: { //星星的大小
                type: [Number, String],
                default: 24
            },
            value: { //当前评分
                type: [Number, String],
                default: 0
            },
            max: { //最大评分
                type: [Number, String],
                default: 5
            },
            margin: { //星星的间距
                type: [Number, String],
                default: 0
            },
            disabled: { //是否可点击
                type: [Boolean, String],
                default: false
            },
            id: {
                type: [Number, String],
                default: 1
            }
        },
        data() {
            // console.log('data')
            return {
                maxSync: this.max,
                valueSync: this.value
            }
        },
        computed: {
            stars() {
                const max = Number(this.maxSync) ? Number(this.maxSync) : 5
                const value = Number(this.valueSync) ? Number(this.valueSync) : 0
                const starList = []
                const floorValue = Math.floor(value)
                const ceilValue = Math.ceil(value)
                for (let i = 0; i < max; i++) {
                    if (floorValue > i) {
                        starList.push({
                            activeWitch: '100%'
                        })
                    } else if (ceilValue - 1 === i) {
                        starList.push({
                            activeWitch: (value - floorValue) * 100 + '%'
                        })
                    } else {
                        starList.push({
                            activeWitch: '0'
                        })
                    }
                }
                return starList
            }
        },
        methods: {
            onClick(index) {
                if (this.disabled === true || this.disabled === 'true') {
                    return
                }
                this.valueSync = index + 1
                this.$emit('change', {
                    id: this.id,
                    value: this.valueSync
                })
            }
        }
    }
</script>

<style lang="scss">
    .uni-rate {
        line-height: 0;
        font-size: 0;
        display: flex;
        flex-direction: row;

        &-icon {
            position: relative;
            line-height: 0;
            font-size: 0;
            display: inline-block;

            &-on {
                position: absolute;
                top: 0;
                left: 0;
                overflow: hidden;
            }
        }
    }
</style>

uni-segmented-control

uni-segmented-control.vue
<template>
    <view class="segmented-control" :class="styleType" :style="wrapStyle">
        <view v-for="(item, index) in values" class="segmented-control-item" :class="styleType" :key="index" :style="index === currentIndex ? activeStyle : itemStyle" @click="onClick(index)">
            {{item}}
        </view>
    </view>
</template>

<script>
    export default {
        name: 'uni-segmented-control',
        props: {
            current: {
                type: Number,
                default: 0
            },
            values: {
                type: Array,
                default () {
                    return [];
                }
            },
            activeColor: {
                type: String,
                default: '#007aff'
            },
            styleType: {
                type: String,
                default: 'button'
            }
        },
        data() {
            return {
                currentIndex: this.current
            }
        },
        watch: {
            current(val) {
                if (val !== this.currentIndex) {
                    this.currentIndex = val;
                }
            }
        },
        computed: {
            wrapStyle() {
                let styleString = '';
                switch (this.styleType) {
                    case 'text':
                        styleString = `border:0;`;
                        break;
                    default:
                        styleString = `border-color: ${this.activeColor}`;
                        break;
                }
                return styleString;
            },
            itemStyle() {
                let styleString = '';
                switch (this.styleType) {
                    case 'text':
                        styleString = `color:#999;border-left:0;`;
                        break;
                    default:
                        styleString = `color:${this.activeColor};border-color:${this.activeColor};`;
                        break;
                }
                return styleString;
            },
            activeStyle() {
                let styleString = '';
                switch (this.styleType) {
                    case 'text':
                        styleString = `color:${this.activeColor};border-left:0;border-bottom-style:solid;border-bottom-width:4upx`;
                        break;
                    default:
                        styleString = `color:#fff;border-color:${this.activeColor};background-color:${this.activeColor}`;
                        break;
                }
                return styleString;
            }
        },
        methods: {
            onClick(index) {
                if (this.currentIndex !== index) {
                    this.currentIndex = index;
                    this.$emit('clickItem', index);
                }
            }
        },
    }
</script>

<style>
    .segmented-control {
        display: flex;
        flex-direction: row;
        justify-content: center;
        width: 75%;
        font-size: 28upx;
        border-radius: 10upx;
        box-sizing: border-box;
        margin: 0 auto;
        overflow: hidden;
    }

    .segmented-control.button {
        border: 2upx solid;
    }

    .segmented-control.text {
        border: 0;
        border-radius: 0upx;
    }

    .segmented-control-item {
        flex: 1;
        text-align: center;
        line-height: 60upx;
        box-sizing: border-box;
    }

    .segmented-control-item.button {
        border-left: 1upx solid;
    }

    .segmented-control-item.text {
        border-left: 0;
    }

    .segmented-control-item:first-child {
        border-left-width: 0;
    }
</style>

uni-swipe-action

readme.md
### SwipeAction 滑动操作

通过滑动触发选项的容器,组件名:``uni-swipe-action``

**使用方式:**

在 ``script`` 中引用组件 

import uniSwipeAction from "@/components/uni-swipe-action"
export default {

components: {uniSwipeAction}

}


一般用法

<uni-swipe-action :options="[

{
    text: '取消',
    style: {
        backgroundColor: '#007aff'
    }
}, {
    text: '确认',
    style: {
        backgroundColor: '#dd524d'
    }
}

]">

<view class='cont'>SwipeAction 基础使用场景</view>

</uni-swipe-action>



禁止滑动

<uni-swipe-action :disabled="true" :options="[

{
    text: '取消',
    style: {
        backgroundColor: '#007aff'
    }
}, {
    text: '确认',
    style: {
        backgroundColor: '#dd524d'
    }
}

]">

<view class='cont'>点击按钮自动关闭</view>

</uni-swipe-action>



传递点击事件

<uni-swipe-action @click="bindClick" :options="[

{
    text: '取消',
    style: {
        backgroundColor: '#007aff'
    }
}, {
    text: '确认',
    style: {
        backgroundColor: '#dd524d'
    }
}

]">

<view class='cont'>点击选项时触发事件</view>

</uni-swipe-action>


与 List 组件使用

<uni-list>

<uni-swipe-action :options="options1">
    <uni-list-item title="item1" show-arrow="false"></uni-list-item>
</uni-swipe-action>
<uni-swipe-action :options="options2">
    <uni-list-item title="item2" show-arrow="false"></uni-list-item>
</uni-swipe-action>
<uni-swipe-action :options="options3">
    <uni-list-item title="item3" show-arrow="false"></uni-list-item>
</uni-swipe-action>

</uni-list>


**SwipeAction 属性说明:**

|属性名|类型|默认值|是否必填    |说明|
|:--|:--|:--|:--|:--|
|is-opened|Boolean|false|否|是否为开启状态|
|disabled|Boolean|false|否|是否禁止滑动|
|auto-close|Boolean|true|否|在组件开启状态时点击组件,是否自动关闭|
|options|Array<Object>|-|是|组件选项内容及样式|

options 参数说明

|参数|类型|是否必填|说明|
|:--|:--|:--|:--|
|text|String|是|按钮的文字|
|style|Object|否|按钮样式{backgroundColor,color,fontSize},backgroundColor默认为:#C7C6CD,color默认为:#FFFFFF,fontSize默认为:28upx|

**SwipeAction 事件说明:**

|事件称名|说明|返回参数|
|:--|:---|:--|
|click|点击选项按钮时触发事件|{text,style,index} ,text(按钮文字)、style(按钮的样式)、index(下标)|
|opened|完全打开时触发|-|
|closed|完全关闭时触发|-|

uni-swipe-action.vue
<template>
    <view class="uni-swipe-action">
        <view class="uni-swipe-action__container" :class="!isMoving ? 'animtion' : ''" @touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd" @touchcancel="touchEnd" @click="bindClickCont" :style="{'transform':transformX,'-webkit-transform':transformX}">
            <view class="uni-swipe-action__content">
                <slot></slot>
            </view>
            <view class="uni-swipe-action__btn-group" :id="elId">
                <div v-for="(item,index) in options" :key="index" class="uni-swipe-action--btn" :style="{backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD',color: item.style && item.style.color ? item.style.color : '#FFFFFF',fontSize: item.style && item.style.fontSize ? item.style.fontSize : '28upx'}" @click="bindClickBtn(item,index)">
                    {{item.text}}
                </div>
            </view>
        </view>
    </view>
</template>

<script>
    export default {
        name: 'uni-swipe-action',
        props: {
            isOpened: {
                type: Boolean,
                default: false
            },
            disabled: {
                type: Boolean,
                default: false
            },
            autoClose: {
                type: Boolean,
                default: true
            },
            options: Array
        },
        watch: {
            isOpened(newValue, oldValue) {
                this.isShowBtn = newValue ? true : false;
                this.endMove();
            }
        },
        data() {
            const elId = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`
            return {
                elId: elId,
                moveLength: 0,
                isMoving: false,
                direction: '',
                startX: 0,
                startY: 0,
                isShowBtn: false,
                btnGroupWidth: 0
            }
        },
        // #ifdef H5
        mounted() {
            let view = uni.createSelectorQuery().select(`#${this.elId}`);
            view.fields({
                size: true
            }, data => {
                this.btnGroupWidth = data.width;
            }).exec();
            if (this.isOpened === true) {
                this.isShowBtn = true;
                this.endMove();
            }
        },
        // #endif
        // #ifndef H5
        onReady() {
            let view = uni.createSelectorQuery().select(`#${this.elId}`);
            view.fields({
                size: true
            }, data => {
                this.btnGroupWidth = data.width;
            }).exec();
            if (this.isOpened === true) {
                this.isShowBtn = true;
                this.endMove();
            }
        },
        // #endif
        computed: {
            transformX() {
                return `translateX(${this.moveLength}px)`
            }
        },
        methods: {
            bindClickBtn(item, index) {
                this.$emit('click', {
                    text: item.text,
                    style: item.style,
                    index: index,
                    key: item.key
                })
            },
            bindClickCont(e) {
                if (this.isShowBtn && this.autoClose === true) {
                    this.isShowBtn = false;
                    this.endMove();
                }
            },
            touchStart(event) {
                this.startX = event.touches[0].pageX;
                this.startY = event.touches[0].pageY;
            },
            touchMove(event) {
                if (this.direction === 'Y' || this.disabled === true) {
                    return;
                }
                var moveY = event.touches[0].pageY - this.startY,
                    moveX = event.touches[0].pageX - this.startX;
                if (!this.isMoving && Math.abs(moveY) > Math.abs(moveX)) { //纵向滑动
                    this.direction = 'Y';
                    return;
                }
                this.direction = moveX > 0 ? 'right' : 'left';
                this.isMoving = true;
            },
            touchEnd(event) {
                this.isMoving = false;
                if (this.direction !== 'right' && this.direction !== 'left') {
                    this.direction = '';
                    return;
                }
                if (this.direction == 'right') {
                    this.isShowBtn = false
                } else {
                    this.isShowBtn = true
                }
                this.endMove()
            },
            endMove() {
                if (this.direction === 'Y' || this.disabled === true) {
                    this.direction = '';
                    return;
                }
                if (this.isShowBtn) {
                    this.moveLength = -this.btnGroupWidth;
                    this.$emit('opened');
                } else {
                    this.moveLength = 0;
                    this.$emit('closed');
                }
                this.direction = '';
            }
        }
    }
</script>

<style>
    @charset "UTF-8";

    .uni-swipe-action {
        width: 100%;
        overflow: hidden
    }

    .uni-swipe-action__container {
        background-color: #fff;
        width: 200%;
        display: flex;
        flex-direction: row;
        flex-wrap: wrap
    }

    .uni-swipe-action__container.animtion {
        transition: transform 350ms cubic-bezier(.165, .84, .44, 1)
    }

    .uni-swipe-action__content {
        width: 50%
    }

    .uni-swipe-action__btn-group {
        display: flex;
        flex-direction: row
    }

    .uni-swipe-action--btn {
        padding: 0 32upx;
        color: #fff;
        background-color: #c7c6cd;
        font-size: 28upx;
        display: inline-flex;
        text-align: center;
        flex-direction: row;
        align-items: center
    }
</style>

config

api.js

import {
    apiBaseUrl
} from './config.js';
import * as common from './common.js' //引入common
import * as db from './db.js' //引入common
// 需要登陆的,都写到这里,否则就是不需要登陆的接口
const methodsToken = [
    'user.info',
    'user.editinfo',
    'user.changeavatar',
    'user.logout',
    'user.addgoodsbrowsing',
    'user.delgoodsbrowsing',
    'user.goodsbrowsing',
    'user.goodscollection',
    'user.goodscollectionlist',
    'user.vuesaveusership',
    'user.saveusership',
    'user.getshipdetail',
    'user.setdefship',
    'user.editship',
    'user.removeship',
    'user.getusership',
    'user.pay',
    'user.orderevaluate',
    'user.getuserdefaultship',
    'user.issign',
    'user.sign',
    'user.mypoint',
    'user.userpointlog',
    'user.getbankcardlist',
    'user.getdefaultbankcard',
    'user.addbankcard',
    'user.removebankcard',
    'user.setdefaultbankcard',
    'user.getbankcardinfo',
    'user.editpwd',
    'user.forgotpwd',
    'user.recommend',
    'user.balancelist',
    'user.sharecode',
    'user.cash',
    'user.cashlist',
    'user.myinvite',
    'user.activationinvite',
    'coupon.getcoupon',
    'coupon.usercoupon',
    'cart.add',
    'cart.del',
    'cart.getlist',
    'cart.setnums',
    'cart.getnumber',
    'order.cancel',
    'order.del',
    'order.details',
    'order.confirm',
    'order.getlist',
    'order.create',
    'order.getship',
    'order.getorderlist',
    'order.getorderstatusnum',
    'order.aftersaleslist',
    'order.aftersalesinfo',
    'order.aftersalesstatus',
    'order.addaftersales',
    'order.sendreship',
    'order.iscomment',
    'payments.getinfo',
    'user.getuserpoint',
    'coupon.getcouponkey',
    'store.isclerk',
    'store.storeladinglist',
    'store.ladinginfo',
    'store.lading',
    'store.ladingdel',
    'distribution_center-api-info',
    'distribution_center-api-applydistribution',
    'distribution_center-api-setstore',
    'distribution_center-api-myorder',
    'pintuan.pintuanteam',
    'lottery-api-getLotteryConfig',
    'lottery-api-lottery',
    'lottery-api-lotteryLog'
];

const post = (method, data, callback) => {
    uni.showLoading({
        title: '加载中'
    });

    // 判断token是否存在
    if (methodsToken.indexOf(method) >= 0) {
        // 获取用户token
        let userToken = db.get("userToken");
        if (!userToken) {
            common.jumpToLogin();
            return false;
        } else {
            data.token = userToken;
        }
    }

    data.method = method;

    uni.request({
        url: apiBaseUrl + 'api.html',
        data: data,
        header: {
            'Accept': 'application/json',
            'Content-Type': 'application/json',
            // 'Content-Type': 'application/x-www-form-urlencoded', //自定义请求头信息
        },
        method: 'POST',
        success: (response) => {
            uni.hideLoading();
            const result = response.data
            if (!result.status) {
                // 登录信息过期或者未登录
                if (result.data === 14007 || result.data === 14006) {
                    db.del("userToken");
                    uni.showToast({
                        title: result.msg,
                        icon: 'none',
                        duration: 1000,
                        complete: function() {
                            setTimeout(function() {
                                uni.hideToast();
                                // #ifdef H5 || APP-PLUS
                                uni.navigateTo({
                                    url: '/pages/login/login/index1'
                                })
                                // #endif
                                // #ifdef MP-WEIXIN || MP-ALIPAY    
                                uni.navigateTo({
                                    url: '/pages/login/choose/index',
                                    animationType: 'pop-in',
                                    animationDuration: 200
                                });
                                // #endif
                            }, 1000)
                        }
                    });
                }
            }
            callback(result);
        },
        complete: () => {
            uni.hideLoading();
        },
        fail: (error) => {
            uni.hideLoading();
            if (error && error.response) {
                showError(error.response);
            }
        },
    });

}

//插件post
const pluginsPost = (method, data, callback) => {
    uni.showLoading({
        title: '加载中'
    });

    // 判断token是否存在
    if (methodsToken.indexOf(method) >= 0) {
        // 获取用户token
        let userToken = db.get("userToken");
        if (!userToken) {
            common.jumpToLogin();
            return false;
        } else {
            data.token = userToken;
        }
    }
    uni.request({
        url: apiBaseUrl + 'plugins/' + method + '.html',
        data: data,
        header: {
            'Accept': 'application/json',
            'Content-Type': 'application/json',
            // 'Content-Type': 'application/x-www-form-urlencoded', //自定义请求头信息
        },
        method: 'POST',
        success: (response) => {
            uni.hideLoading();
            const result = response.data
            if (!result.status) {
                // 登录信息过期或者未登录
                if (result.data === 14007 || result.data === 14006) {
                    db.del("userToken");
                    uni.showToast({
                        title: result.msg,
                        icon: 'none',
                        duration: 1000,
                        complete: function() {
                            setTimeout(function() {
                                uni.hideToast();
                                // #ifdef H5 || APP-PLUS
                                uni.navigateTo({
                                    url: '/pages/login/login/index1'
                                })
                                // #endif
                                // #ifdef MP-WEIXIN || MP-ALIPAY    
                                uni.navigateTo({
                                    url: '/pages/login/choose/index',
                                    animationType: 'pop-in',
                                    animationDuration: 200
                                });
                                // #endif
                            }, 1000);
                        }
                    });
                }
            }
            callback(result);
        },
        fail: (error) => {
            uni.hideLoading();
            if (error && error.response) {
                showError(error.response);
            }
        },
        complete: () => {
            setTimeout(function() {
                uni.hideLoading();
            }, 250);
        }
    });

}

const get = (url, callback) => {
    uni.showLoading({
        title: '加载中'
    });
    uni.request({
        url: url,
        header: {
            'Accept': 'application/json',
            'Content-Type': 'application/x-www-form-urlencoded', //自定义请求头信息
        },
        method: 'GET',
        success: (response) => {
            uni.hideLoading();
            callback(response.data);
        },
        fail: (error) => {
            uni.hideLoading();
            if (error && error.response) {
                showError(error.response);
            }
        },
        complete: () => {
            setTimeout(function() {
                uni.hideLoading();
            }, 250);
        }
    });
}

const showError = error => {
    let errorMsg = ''
    switch (error.status) {
        case 400:
            errorMsg = '请求参数错误'
            break
        case 401:
            errorMsg = '未授权,请登录'
            break
        case 403:
            errorMsg = '跨域拒绝访问'
            break
        case 404:
            errorMsg = `请求地址出错: ${error.config.url}`
            break
        case 408:
            errorMsg = '请求超时'
            break
        case 500:
            errorMsg = '服务器内部错误'
            break
        case 501:
            errorMsg = '服务未实现'
            break
        case 502:
            errorMsg = '网关错误'
            break
        case 503:
            errorMsg = '服务不可用'
            break
        case 504:
            errorMsg = '网关超时'
            break
        case 505:
            errorMsg = 'HTTP版本不受支持'
            break
        default:
            errorMsg = error.msg
            break
    }

    uni.showToast({
        title: errorMsg,
        icon: 'none',
        duration: 1000,
        complete: function() {
            setTimeout(function() {
                uni.hideToast();
            }, 1000);
        }
    });
}

// 文件上传
export const uploadFiles = (callback) => {
    uni.chooseImage({
        success: (chooseImageRes) => {
            uni.showLoading({
                title: '上传中...'
            });
            const tempFilePaths = chooseImageRes.tempFilePaths;
            const uploadTask = uni.uploadFile({
                url: apiBaseUrl + 'api.html', //仅为示例,非真实的接口地址
                filePath: tempFilePaths[0],
                fileType: 'image',
                name: 'file',
                headers: {
                    'Accept': 'application/json',
                    'Content-Type': 'multipart/form-data',
                },
                formData: {
                    'method': 'images.upload',
                    'upfile': tempFilePaths[0]
                },
                success: (uploadFileRes) => {
                    callback(JSON.parse(uploadFileRes.data));
                },
                fail: (error) => {
                    if (error && error.response) {
                        showError(error.response);
                    }
                },
                complete: () => {
                    setTimeout(function() {
                        uni.hideLoading();
                    }, 250);
                }
            });
            //                     uploadTask.onProgressUpdate((res) => {
            //             console.log('上传进度' + res.progress);
            //             console.log('已经上传的数据长度' + res.totalBytesSent);
            //             console.log('预期需要上传的数据总长度' + res.totalBytesExpectedToSend);
            //
            //             // 测试条件,取消上传任务。
            //             if (res.progress > 50) {
            //                 uploadTask.abort();
            //             }
            //                     });
        }
    });
}

// 上传图片
export const uploadImage = (num, callback) => {
    uni.chooseImage({
        count: num,
        success: (res) => {
            uni.showLoading({
                title: '上传中...'
            });
            let tempFilePaths = res.tempFilePaths
            for (var i = 0; i < tempFilePaths.length; i++) {
                uni.uploadFile({
                    url: apiBaseUrl + 'api.html',
                    filePath: tempFilePaths[i],
                    fileType: 'image',
                    name: 'file',
                    headers: {
                        'Accept': 'application/json',
                        'Content-Type': 'multipart/form-data',
                    },
                    formData: {
                        'method': 'images.upload',
                        'upfile': tempFilePaths[i]
                    },
                    success: (uploadFileRes) => {
                        callback(JSON.parse(uploadFileRes.data));
                    },
                    fail: (error) => {
                        if (error && error.response) {
                            showError(error.response);
                        }
                    },
                    complete: () => {
                        setTimeout(function() {
                            uni.hideLoading();
                        }, 250);
                    },
                });
            }
        }
    });
}

// 获取店铺配置
export const shopConfig = (callback) => get(apiBaseUrl + 'api/common/jshopconf', callback);

// 用户注册
export const reg = (data, callback) => post('user.reg', data, callback);

// 用户登录
export const login = (data, callback) => post('user.login', data, callback);

// 用户信息
export const userInfo = (data, callback) => post('user.info', data, callback);

// 上传头像
export const changeAvatar = (data, callback) => post('user.changeavatar', data, callback);

// 编辑用户信息
export const editInfo = (data, callback) => post('user.editinfo', data, callback);

// 发送短信验证码
export const sms = (data, callback) => post('user.sms', data, callback);

// 短信验证码登录
export const smsLogin = (data, callback) => post('user.smslogin', data, callback);

// 退出登录
export const logout = (data, callback) => post('user.logout', data, callback);

// 获取首页幻灯片
export const slider = (data, callback) => post('advert.getAdvertList', data, callback);

// 获取广告
export const advert = (data, callback) => post('advert.getcarousellists', data, callback);

// 获取公告列表
export const notice = (data, callback) => post('notice.noticeList', data, callback);

// 获取公告详情
export const noticeInfo = (data, callback) => post('notice.noticeInfo', data, callback);

// 获取文章详情
export const articleInfo = (data, callback) => post('articles.getArticleDetail', data, callback);

// 获取文章列表
export const articleList = (data, callback) => post('articles.getArticleList', data, callback);

// 获取商品分类
export const categories = (data, callback) => post('categories.getallcat', data, callback);

// 获取商品列表
export const goodsList = (data, callback) => post('goods.getlist', data, callback);

// 获取商品详情
export const goodsDetail = (data, callback) => post('goods.getdetial', data, callback);

// 获取商品参数信息
export const goodsParams = (data, callback) => post('goods.getgoodsparams', data, callback);

// 获取设置默认货品
export const getProductInfo = (data, callback) => post('goods.getproductinfo', data, callback);

// 获取商品评论信息
export const goodsComment = (data, callback) => post('goods.getgoodscomment', data, callback);

// 添加购物车
export const addCart = (data, callback) => post('cart.add', data, callback);

// 移除购物车
export const removeCart = (data, callback) => post('cart.del', data, callback);

// 获取购物车列表
export const cartList = (data, callback) => post('cart.getlist', data, callback);

// 设置购物车商品数量
export const setCartNum = (data, callback) => post('cart.setnums', data, callback);

// 获取购物车数量
export const getCartNum = (data, callback) => post('cart.getnumber', data, callback);

// 获取用户的收货地址列表
export const userShip = (data, callback) => post('user.getusership', data, callback);

// 获取用户默认收货地址
export const userDefaultShip = (data, callback) => post('user.getuserdefaultship', data, callback);

// 存储用户收货地址
export const saveUserShip = (data, callback) => post('user.vuesaveusership', data, callback);

// 微信存储收货地址
export const saveUserShipWx = (data, callback) => post('user.saveusership', data, callback);

//获取区域ID
export const getAreaId = (data, callback) => post('user.getareaid', data, callback);

// 获取收货地址详情
export const shipDetail = (data, callback) => post('user.getshipdetail', data, callback);

// 收货地址编辑
export const editShip = (data, callback) => post('user.editship', data, callback);

// 收货地址删除
export const removeShip = (data, callback) => post('user.removeship', data, callback);

// 设置默认收货地址
export const setDefShip = (data, callback) => post('user.setdefship', data, callback);

// 生成订单
export const createOrder = (data, callback) => post('order.create', data, callback);

// 获取状态订单列表
export const getOrderList = (data, callback) => post('order.getlist', data, callback);

// 取消订单
export const cancelOrder = (data, callback) => post('order.cancel', data, callback);

// 删除订单
export const delOrder = (data, callback) => post('order.del', data, callback);

// 获取订单详情
export const orderDetail = (data, callback) => post('order.details', data, callback);

// 确认收货
export const confirmOrder = (data, callback) => post('order.confirm', data, callback);

// 获取配送方式
export const orderShip = (data, callback) => post('order.getship', data, callback);

// 获取全部订单列表
export const orderList = (data, callback) => post('order.getorderlist', data, callback);

// 获取订单不同状态的数量
export const getOrderStatusSum = (data, callback) => post('order.getorderstatusnum', data, callback);

// 售后单列表
export const afterSalesList = (data, callback) => post('order.aftersaleslist', data, callback);

// 售后单详情
export const afterSalesInfo = (data, callback) => post('order.aftersalesinfo', data, callback);

// 订单售后状态
export const afterSalesStatus = (data, callback) => post('order.aftersalesstatus', data, callback);

// 添加售后单
export const addAfterSales = (data, callback) => post('order.addaftersales', data, callback);

// 用户发送退货包裹
export const sendShip = (data, callback) => post('order.sendreship', data, callback);

// 添加商品浏览足迹
export const addGoodsBrowsing = (data, callback) => post('user.addgoodsbrowsing', data, callback);

// 删除商品浏览足迹
export const delGoodsBrowsing = (data, callback) => post('user.delgoodsbrowsing', data, callback);

// 获取商品浏览足迹
export const goodsBrowsing = (data, callback) => post('user.goodsbrowsing', data, callback);

// 商品收藏 关注/取消
export const goodsCollection = (data, callback) => post('user.goodscollection', data, callback);

// 获取商品收藏关注列表
export const goodsCollectionList = (data, callback) => post('user.goodscollectionlist', data, callback);

// 获取店铺支付方式列表
export const paymentList = (data, callback) => post('payments.getlist', data, callback);

// 获取支付单详情
export const paymentInfo = (data, callback) => post('payments.getinfo', data, callback);

// 支付接口
export const pay = (data, callback) => post('user.pay', data, callback);

// 订单评价接口
export const orderEvaluate = (data, callback) => post('user.orderevaluate', data, callback);

// 判断是否签到
export const isSign = (data, callback) => post('user.issign', data, callback);

// 签到接口
export const sign = (data, callback) => post('user.sign', data, callback);

// 我的积分
export const myPoint = (data, callback) => post('user.mypoint', data, callback);

// 积分记录
export const pointLog = (data, callback) => post('user.userpointlog', data, callback);

// 物流信息接口
export const logistics = (data, callback) => post('order.logisticbyapi', data, callback);

// 优惠券列表
export const couponList = (data, callback) => post('coupon.couponlist', data, callback);

// 优惠券详情
export const couponDetail = (data, callback) => post('coupon.coupondetail', data, callback);

// 用户领取优惠券
export const getCoupon = (data, callback) => post('coupon.getcoupon', data, callback);

// 用户已领取的优惠券列表
export const userCoupon = (data, callback) => post('coupon.usercoupon', data, callback);

// 获取店铺设置
export const getSetting = (data, callback) => post('user.getsetting', data, callback);

// 获取商户配置信息
export const getSellerSetting = (data, callback) => post('user.getsellersetting', data, callback);

// 获取我的银行卡列表
export const getBankCardList = (data, callback) => post('user.getbankcardlist', data, callback);

// 获取默认的银行卡
export const getDefaultBankCard = (data, callback) => post('user.getdefaultbankcard', data, callback);

// 添加银行卡
export const addBankCard = (data, callback) => post('user.addbankcard', data, callback);

// 删除银行卡
export const removeBankCard = (data, callback) => post('user.removebankcard', data, callback);

// 设置默认银行卡
export const setDefaultBankCard = (data, callback) => post('user.setdefaultbankcard', data, callback);

// 获取银行卡信息
export const getBankCardInfo = (data, callback) => post('user.getbankcardinfo', data, callback);

// 获取银行卡组织信息
export const getBankCardOrganization = (data, callback) => post('user.getbankcardorganization', data, callback);

// 用户修改密码
export const editPwd = (data, callback) => post('user.editpwd', data, callback);

// 用户找回密码
export const forgotPwd = (data, callback) => post('user.forgotpwd', data, callback);

// 获取用户余额明细
export const getBalanceList = (data, callback) => post('user.balancelist', data, callback);

// 用户推荐列表
export const recommendList = (data, callback) => post('user.recommend', data, callback);

// 邀请码
export const shareCode = (data, callback) => post('user.sharecode', data, callback);

// 用户提现
export const userToCash = (data, callback) => post('user.cash', data, callback);

// 用户提现列表
export const cashList = (data, callback) => post('user.cashlist', data, callback);

// 绑定授权登录
export const trustBind = (data, callback) => post('user.trustbind', data, callback);

// 获取用户信息
// export const trustLogin = (data, callback) => post('user.trustcallback', data, callback);

// 判断用户下单可以使用多少积分
export const usablePoint = (data, callback) => post('user.getuserpoint', data, callback);

// 门店列表
export const storeList = (data, callback) => post('store.getstorelist', data, callback);

// 判断是否开启门店自提
export const switchStore = (data, callback) => post('store.getstoreswitch', data, callback);

// 获取默认的门店
export const defaultStore = (data, callback) => post('store.getdefaultstore', data, callback);

// 判断是否开启积分
export const isPoint = (data, callback) => post('user.ispoint', data, callback);

// 用户输入code领取优惠券
export const couponKey = (data, callback) => post('coupon.getcouponkey', data, callback);

// 判断是否是店员
export const isStoreUser = (data, callback) => post('store.isclerk', data, callback);

// 获取店铺提货单列表
export const storeLadingList = (data, callback) => post('store.storeladinglist', data, callback);

// 获取提货单详情
export const ladingInfo = (data, callback) => post('store.ladinginfo', data, callback);

// 店铺提单操作
export const ladingExec = (data, callback) => post('store.lading', data, callback);

// 提货单删除
export const ladingDel = (data, callback) => post('store.ladingdel', data, callback);

// 获取活动列表
export const activityList = (data, callback) => post('group.getlist', data, callback);

// 获取活动详情
export const activityDetail = (data, callback) => post('group.getgoodsdetial', data, callback);

//小程序解析code
export const login1 = (data, callback) => post('user.wxapplogin1', data, callback);

//小程序登录第二步
export const login2 = (data, callback) => post('user.wxapplogin2', data, callback);

//支付宝小程序解析code
export const alilogin1 = (data, callback) => post('user.alipayapplogin1', data, callback);

//取下级地址列表
export const getAreaList = (data, callback) => post('user.getarealist', data, callback);

//取搜索页推荐关键字
export const getRecommendKeys = (callback) => post('store.getrecommendkeys', {}, callback);

// 获取我的邀请信息
export const myInvite = (callback) => post('user.myinvite', {}, callback);

// 设置我的上级邀请人
export const setMyInvite = (data, callback) => post('user.activationinvite', data, callback);

// 获取小程序二维码
export const getInviteQRCode = (data, callback) => post('store.getinviteqrcode', data, callback);

// 生成海报
export const createPoster = (data, callback) => post('user.getposter', data, callback);

// 获取秒杀团购
export const getGroup = (data, callback) => post('group.getlist', data, callback);

// 获取秒杀团购详情
export const groupInfo = (data, callback) => post('group.getgoodsdetial', data, callback);

// 自定义页面
export const getPageConfig = (data, callback) => post('pages.getpageconfig', data, callback);

//万能表单
export const getFormDetial = (data, callback) => post('form.getformdetial', data, callback);

//提交表单
export const addSubmitForm = (data, callback) => post('form.addsubmit', data, callback);

//公众号授权获取openid
export const getOpenId = (data, callback) => post('user.officiallogin', data, callback);

// 获取授权登录方式
export const getTrustLogin = (data, callback) => post('user.gettrustlogin', data, callback);

// APP信任登录
export const appTrustLogin = (data, callback) => post('user.uniapplogin', data, callback);

// 获取分销商进度状态
export const getDistributioninfo = (data, callback) => pluginsPost('distribution_center-api-info', data, callback);

// 申请分销商
export const applyDistribution = (data, callback) => pluginsPost('distribution_center-api-applydistribution', data,
    callback);

// 店铺设置
export const setStore = (data, callback) => pluginsPost('distribution_center-api-setstore', data, callback);

//我的分销订单
export const getStoreInfo = (data, callback) => pluginsPost('distribution_center-api-getstoreinfo', data, callback);

//我的分销订单
export const getDistributionOrder = (data, callback) => pluginsPost('distribution_center-api-myorder', data, callback);

// 拼团列表
export const pintuanList = (data, callback) => post('pintuan.list', data, callback);

// 拼团商品详情
export const pintuanGoodsInfo = (data, callback) => post('pintuan.goodsinfo', data, callback);

// 拼团货品详情
export const pintuanProductInfo = (data, callback) => post('pintuan.productinfo', data, callback);

//微信图文消息
export const messageDetail = (data, callback) => post('articles.getweixinmessage', data, callback);

//获取APP版本
export const getAppVersion = (data, callback) => pluginsPost('app-api-checkVersion', data, callback);

//获取APP版本
export const getOrderPintuanTeamInfo = (data, callback) => post('pintuan.pintuanteam', data, callback);

//抽奖规则
export const lotteryConfig = (callback) => pluginsPost('lottery-api-getLotteryConfig', {}, callback);

//抽奖操作
export const lottery = (callback) => pluginsPost('lottery-api-lottery', {}, callback);

//获取我的抽奖记录
export const myLottery = (data, callback) => pluginsPost('lottery-api-lotteryLog', data, callback);

//生成分享URL
export const createShareUrl = (data, callback) => post('user.shareurl', data, callback);

common.js

import * as db from './db.js' //引入common
import store from './../store'
//把obj对象里的值覆盖到newobj里面
function deepCopy(newobj, obj) {
    if (typeof obj != 'object') {
        return obj
    }
    for (var attr in obj) {
        var a = {}
        if (newobj[attr]) {
            a = newobj[attr]
        }
        newobj[attr] = deepCopy(a, obj[attr])
    }
    return newobj
}

//跳转到登陆页面
function jumpToLogin(method) {
    var now_time = Date.parse(new Date())
    var value = db.get('jump_to_login')
    if (!value) {
        value = 0
    }
    if (now_time - value > 3000) {
        //db.set('jump_to_login',now_time); //暂时屏蔽登录时间查询
        // 将当前页面route存vuex中 登录注册后跳转
        let pages = getCurrentPages()
        let page = pages[pages.length - 1]
        // 获取页面参数信息
        let pagePath = ''
        // #ifdef H5 || MP-WEIXIN || APP-PLUS     || APP-PLUS-NVUE
        if (page.route.indexOf('pages/goods/index/index') !== -1) {
            //商品详情页
            if (page.goodsId) {
                pagePath = '/' + page.route + '?id=' + page.goodsId;
            } else {
                pagePath = '/pages/index/index';
            }
        }
        if (page.route.indexOf('pages/goods/index/group') !== -1) {
            //团购秒杀详情页
            if (page.goodsId && page.groupId) {
                pagePath = '/' + page.route + '?id=' + page.goodsId + '&group_id' + page.groupId;
            } else {
                pagePath = '/pages/index/index';
            }
        }
        // #endif

        // #ifdef MP-ALIPAY
        if (page.__proto__.route.indexOf('pages/goods/index/index') !== -1) {
            //商品详情页
            if (page.rootVM.goodsId) {
                pagePath = '/' + page.__proto__.route + '?id=' + page.rootVM.goodsId;
            } else {
                pagePath = '/pages/index/index';
            }
        }
        if (page.__proto__.route.indexOf('pages/goods/index/group') !== -1) {
            //团购秒杀详情页
            if (page.rootVM.goodsId && page.rootVM.groupId) {
                pagePath = '/' + page.__proto__.route + '?id=' + page.rootVM.goodsId + '&group_id' + page.rootVM.groupId;
            } else {
                pagePath = '/pages/index/index';
            }
        }
        // #endif
        if (pagePath) {
            store.commit({
                type: 'redirect',
                page: pagePath
            })
        }
        uni.showToast({
            title: '请先登录!',
            icon: 'none',
            duration: 1000,
            success: function(res) {
                // #ifdef H5 || APP-PLUS
                setTimeout(() => {
                    uni.hideToast();
                    uni.navigateTo({
                        url: '/pages/login/login/index1'
                    })
                }, 1000)
                // #endif
                // #ifdef MP-WEIXIN || MP-ALIPAY
                setTimeout(() => {
                    uni.hideToast();
                    uni.navigateTo({
                        url: '/pages/login/choose/index',
                        animationType: 'pop-in',
                        animationDuration: 200
                    })
                }, 500)
                // #endif
            }
        })
    }
}

//当出错的时候,显示错误信息,并且跳转 弃用
/* function errorToBack(msg = '出错了,请重试',delta=1){
  uni.showToast({
    title: msg,
    icon: 'none',
    duration: 2000,
  });
  if(delta > 0){
    setTimeout(function () {
      uni.navigateBack({
        delta: delta
      })
    }, 1000);
  }
} */
//操作成功后,的提示信息
function successToShow(msg = '保存成功', callback = function() {}) {


    setTimeout(function() {
        uni.showToast({
            title: msg,
            icon: 'success',
            duration: 1000,
            success() {
                setTimeout(function() {
                    callback()
                }, 500)
            }
        })
    }, 100)
    /*  uni.showToast({
        title: msg,
        icon: 'success',
        duration: 1000
      }) */
}

//操作失败的提示信息
function errorToShow(msg = '操作失败', callback = function() {}) {
    setTimeout(function() {
        uni.showToast({
            title: msg,
            icon: 'none',
            duration: 1500,
            success() {
                setTimeout(function() {
                    callback()
                }, 1500)
            }
        })
    },100)

}

//加载显示
function loadToShow(msg = '加载中') {
    uni.showToast({
        title: msg,
        icon: 'loading'
    })
}

//加载隐藏
function loadToHide() {
    uni.hideToast()
}

// 提示框
function modelShow(
    title = '提示',
    content = '确认执行此操作吗?',
    callback = () => {},
    showCancel = true,
    cancelText = '取消',
    confirmText = '确定'
) {
    uni.showModal({
        title: title,
        content: content,
        showCancel: showCancel,
        cancelText: cancelText,
        confirmText: confirmText,
        cancelText: cancelText,
        success: function(res) {
            if (res.confirm) {
                // 用户点击确定操作
                setTimeout(() => {
                    callback()
                }, 500)
            } else if (res.cancel) {
                // 用户取消操作
            }
        }
    })
}

//时间戳转时间格式
function timeToDate(date, flag = false) {
    var date = new Date(date * 1000) //如果date为13位不需要乘1000
    var Y = date.getFullYear() + '-'
    var M =
        (date.getMonth() + 1 < 10 ?
            '0' + (date.getMonth() + 1) :
            date.getMonth() + 1) + '-'
    var D = (date.getDate() < 10 ? '0' + date.getDate() : date.getDate()) + ' '
    var h = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ':'
    var m =
        (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()) + ':'
    var s = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
    if (flag) {
        return Y + M + D
    } else {
        return Y + M + D + h + m + s
    }
}

function time2date(micro_second) {
    var time = {}
    // 总秒数
    var second = Math.floor(micro_second)
    // 天数
    time.day = PrefixInteger(Math.floor(second / 3600 / 24), 2)
    // 小时
    time.hour = PrefixInteger(Math.floor((second / 3600) % 24), 2)
    // 分钟
    time.minute = PrefixInteger(Math.floor((second / 60) % 60), 2)
    // 秒
    time.second = PrefixInteger(Math.floor(second % 60), 2)

    var newtime = ''
    if (time.day > 0) {
        newtime =
            time.day +
            '天' +
            time.hour +
            '小时' +
            time.minute +
            '分' +
            time.second +
            '秒'
    } else {
        if (time.hour != 0) {
            newtime = time.hour + '小时' + time.minute + '分' + time.second + '秒'
        } else {
            newtime = time.minute + '分' + time.second + '秒'
        }
    }
    return newtime
}

function timeToDateObj(micro_second) {
    var time = {}
    // 总秒数
    var second = Math.floor(micro_second)
    // 天数
    time.day = Math.floor(second / 3600 / 24)
    // 小时
    time.hour = Math.floor((second / 3600) % 24)
    // 分钟
    time.minute = Math.floor((second / 60) % 60)
    // 秒
    time.second = Math.floor(second % 60)

    return time

}

//货币格式化
function formatMoney(number, places, symbol, thousand, decimal) {
    number = number || 0
    places = !isNaN((places = Math.abs(places))) ? places : 2
    symbol = symbol !== undefined ? symbol : '¥'
    thousand = thousand || ','
    decimal = decimal || '.'
    var negative = number < 0 ? '-' : '',
        i = parseInt((number = Math.abs(+number || 0).toFixed(places)), 10) + '',
        j = (j = i.length) > 3 ? j % 3 : 0
    return (
        symbol +
        negative +
        (j ? i.substr(0, j) + thousand : '') +
        i.substr(j).replace(/(\d{3})(?=\d)/g, '$1' + thousand) +
        (places ?
            decimal +
            Math.abs(number - i)
            .toFixed(places)
            .slice(2) :
            '')
    )
}

function throttle(fn, context, delay) {
    clearTimeout(fn.timeoutId)
    fn.timeoutId = setTimeout(function() {
        fn.call(context)
    }, delay)
}

// 时间格式化输出,如11:03 25:19 每1s都会调用一次
function dateformat(micro_second) {
    var time = {}
    // 总秒数
    var second = Math.floor(micro_second / 1000) // 天数
    time.day = PrefixInteger(Math.floor(second / 3600 / 24), 2) // 小时
    time.hour = PrefixInteger(Math.floor((second / 3600) % 24), 2) // 分钟
    time.minute = PrefixInteger(Math.floor((second / 60) % 60), 2) // 秒
    time.second = PrefixInteger(Math.floor(second % 60), 2)
    return time
}

//不足位数前面补0
function PrefixInteger(num, length) {
    return (Array(length).join('0') + num).slice(-length)
}

//验证是否是手机号
function isPhoneNumber(str) {
    var myreg = /^[1][3,4,5,6,7,8,9][0-9]{9}$/
    if (!myreg.test(str)) {
        return false
    } else {
        return true
    }
}

/**
 *
 * 对象参数转为url参数
 *
 */
function builderUrlParams(url, data) {
    if (typeof url == 'undefined' || url == null || url == '') {
        return ''
    }
    if (typeof data == 'undefined' || data == null || typeof data != 'object') {
        return ''
    }
    url += url.indexOf('?') != -1 ? '' : '?'
    for (var k in data) {
        url += (url.indexOf('=') != -1 ? '&' : '') + k + '=' + encodeURI(data[k])
    }
    return url
}

/**
 * 使用循环的方式判断一个元素是否存在于一个数组中
 * @param {Object} arr 数组
 * @param {Object} value 元素值
 */
function isInArray(arr, value) {
    for (var i = 0; i < arr.length; i++) {
        if (value === arr[i]) {
            return true
        }
    }
    return false
}
/**
 * 统一跳转
 */
function navigateTo(url) {
    uni.navigateTo({
        url: url,
        animationType: 'pop-in',
        animationDuration: 300
    })
}

/**
 *  关闭当前页面并跳转
 */
function redirectTo(url) {
    uni.redirectTo({
        url: url,
        animationType: 'pop-in',
        animationDuration: 300
    })
}

/**
 * 获取url参数
 *
 * @param {*} name
 * @param {*} [url=window.location.serach]
 * @returns
 */
function getQueryString(name, url) {
    var url = url || window.location.href
    var reg = new RegExp('(^|&|/?)' + name + '=([^&|/?]*)(&|/?|$)', 'i')
    var r = url.substr(1).match(reg)
    if (r != null) {
        return r[2]
    }
    return null
}

/**
 *
 *  判断是否在微信浏览器 true是
 */
function isWeiXinBrowser() {
    // #ifdef H5
    // window.navigator.userAgent属性包含了浏览器类型、版本、操作系统类型、浏览器引擎类型等信息,这个属性可以用来判断浏览器类型
    let ua = window.navigator.userAgent.toLowerCase()
    // 通过正则表达式匹配ua中是否含有MicroMessenger字符串
    if (ua.match(/MicroMessenger/i) == 'micromessenger') {
        return true
    } else {
        return false
    }
    // #endif

    return false
}

/**
 * 金额相加
 * @param {Object} value1
 * @param {Object} value2
 */
function moneySum(value1, value2) {
    return (parseFloat(value1) + parseFloat(value2)).toFixed(2);
}
/**
 * 金额相减
 * @param {Object} value1
 * @param {Object} value2
 */
function moneySub(value1, value2) {
    let res = (parseFloat(value1) - parseFloat(value2)).toFixed(2);
    return res > 0 ? res : 0;
}


/**
 * 分享URL解压缩
 * @param {Object} url
 */
function shareParameterEncode(url) {
    let urlArray = url.split('-');
    let newUrl = 'type=' + urlArray[0] + '&invite=' + urlArray[1] + '&id=' + urlArray[2] + '&team_id=' + urlArray[3] +
        '&id_type=' + urlArray[4] + '&page_code=' + urlArray[5] + '&group_id=' + urlArray[6];
    return newUrl;
}


/**
 * 分享URL压缩
 * @param {Object} url
 */
function shareParameterDecode(url) {
    var urlArray = url.split('&');
    var allParameter = {
        'type': '',
        'invite': '',
        'id': '',
        'team_id': '',
        'id_type': '',
        'page_code': '',
        'group_id': '',
    };
    for (var i = 0; i < urlArray.length; i++) {
        var parameter = urlArray[i].split('=');
        allParameter[parameter[0]] = parameter[1];
    }
    var newUrl = allParameter.type + '-' + allParameter.invite + '-' + allParameter.id + '-' + allParameter.team_id + '-' +
        allParameter.id_type + '-' + allParameter.page_code + '-' + allParameter.group_id;
    return newUrl;
}

export {
    deepCopy,
    jumpToLogin,
    timeToDate,
    formatMoney,
    /* errorToBack, */
    successToShow,
    throttle,
    errorToShow,
    time2date,
    isPhoneNumber,
    isInArray,
    loadToShow,
    loadToHide,
    navigateTo,
    redirectTo,
    modelShow,
    builderUrlParams,
    isWeiXinBrowser,
    dateformat,
    getQueryString,
    timeToDateObj,
    moneySum,
    moneySub,
    shareParameterEncode,
    shareParameterDecode
}

config.js


export const apiBaseUrl = 'http://www.b2c.com/'
// #ifdef H5
export const baseUrl=process.env.NODE_ENV === 'development'?window.location.origin+'/':apiBaseUrl
// #endif
export const paymentType = {
  //支付单类型
  order: 1, //订单
  recharge: 2, //充值
  form_order: 5, //表单付款码
  form_pay: 6 //表单订单
}

db.js

import * as common from './common.js' //引入common

//取值
function get(key,sync = true) {
    try {
        if(sync){
            return uni.getStorageSync(key);
        }else{
            let data = '';
            uni.getStorage({
                key:key,
                success: function (res) {
                    data = res.data;
                }
            });
            return data;
        }
    } catch (e) {
        return false;
    }
}

//赋值
function set(key, value, sync = true) {
    try {
        if (sync) {
            return uni.setStorageSync(key, value);
        } else {
            uni.setStorage({
                key: key,
                data: value
            });
        }
    } catch (e) {

    }
}

//移除
function del(key, sync = true){
    try {
        if (sync) {
            return uni.removeStorageSync(key);
        } else {
            uni.removeStorage({
                key: key
            });
        }
    } catch (e) {
        return false;
    }
}

//清空
function clear(sync = true){
    try {
        if (sync) {
            return uni.clearStorageSync();
        } else {
            uni.clearStorage();
        }
    } catch (e) {
        return false;
    }
}

//获取用户token,如果缓存有,直接返回,如果没有,就先微信登陆,然后服务器登陆,最后返回token
function userToken(callback) {
    var token = get('userToken');
    if (token){
        callback(token);
    }else{
        //如果没有登陆,就去登陆
        common.jumpToLogin();
    }
}

export {
    get,
    set,
    del,
    clear,
    userToken
}

mixins.js

export const orders = {
    mounted() {},
    methods: {
        // 查看订单详情
        orderDetail(orderId) {
            this.$common.navigateTo(
                '/pages/member/order/orderdetail?order_id=' + orderId
            )
        },
        // 取消订单

        // 去支付
        toPay(orderId) {
            this.$common.navigateTo(
                '/pages/goods/payment/index?order_id=' + orderId + '&type=1'
            )
        },
        // 确认收货

        // 去评价
        toEvaluate(orderId) {
            this.$common.navigateTo(
                '/pages/member/order/evaluate?order_id=' + orderId
            )
        },
        // 申请售后

        // 查看物流信息
        showExpress(code, no, address = '') {
            let params = encodeURIComponent(
                'code=' + code + '&no=' + no + '&add=' + address
            )

            this.$common.navigateTo(
                '/pages/member/order/express_delivery?params=' + params
            )
        }
    }
}

/**
 *  商品接口信息
 *
 */
export const goods = {
    mounted() {},
    methods: {
        // 查看商品详情
        goodsDetail(goodsId) {
            this.$common.navigateTo('/pages/goods/index/index?id=' + goodsId)
        },
        // 跳转商品列表页
        goodsList(obj = {}) {
            let url = '/pages/classify/index'
            if (Object.keys(obj).length) {
                url = this.$common.builderUrlParams(url, obj)
            }
            this.$common.navigateTo(url)
        },
        // 团购秒杀详情
        groupDetail(id, group_id) {
            this.$common.navigateTo(
                '/pages/goods/index/group?id=' + id + '&group_id=' + group_id
            )
        },
        //拼团详情页
        pintuanDetail(id, team_id) {
            if (team_id) {
                this.$common.navigateTo(
                    '/pages/goods/index/pintuan?id=' + id + '&team_id=' + team_id
                )
            } else {
                this.$common.navigateTo('/pages/goods/index/pintuan?id=' + id)
            }
        }
    }
}

/**
 *
 *  返回操作处理
 *
 */
export const goBack = {
    onBackPress(options) {
        if (options.from === 'navigateBack') {
            return false
        }
        let loginPages = ['/pages/cart/index/index', '/pages/member/index/index']
        let backPage = this.$store.state.redirectPage
        if (loginPages.indexOf(backPage) > -1) {
            this.$store.commit({
                type: 'redirect',
                page: ''
            })
            uni.switchTab({
                url: '/pages/index/index'
            })
            return true
        }
    }
}

/* Function Info
 * Author:      zhf
 * CreateTime:  2019/7/12 下午12:10:00
 * LastEditor:  zhf
 * ModifyTime:  2019/7/12 下午12:10:00
 * Description: 登录成功统一跳转处理
 */

export const jumpBackPage = {
    methods: {
        handleBack() {
            let redirect = this.$store.state.redirectPage
            this.$store.commit({
                type: 'redirect',
                page: ''
            })
            let switchTabs = ['/pages/index/index', '/pages/member/index/index']
            if (switchTabs.indexOf(redirect) > -1) {
                uni.switchTab({
                    url: redirect
                })
            } else if (redirect) {
                uni.redirectTo({
                    url: redirect
                })
            } else {
                uni.switchTab({
                    url: '/pages/index/index'
                })
            }
        }
    }
}

/* Function Info
 * Author:      zhf
 * CreateTime:  2019/7/12 下午12:10:28
 * LastEditor:  zhf
 * ModifyTime:  2019/7/12 下午12:10:28
 * Description: 操作判断登录处理
 */

export const checkLogin = {
    methods: {
        checkIsLogin() {
            uni.showToast({
                title: '请先登录!',
                icon: 'none',
                duration: 800,
                success: function(res) {
                    // #ifdef H5 || APP-PLUS
                    setTimeout(() => {
                        uni.hideToast()
                        uni.navigateTo({
                            url: '/pages/login/login/index1'
                        })
                    }, 800)
                    // #endif
                    // #ifdef MP-WEIXIN || MP-ALIPAY
                    setTimeout(() => {
                        uni.hideToast()
                        uni.navigateTo({
                            url: '/pages/login/choose/index',
                            animationType: 'pop-in',
                            animationDuration: 200
                        })
                    }, 500)
                    // #endif
                }
            })
        }
    }
}


/**
 * 工具函数
 */

export const tools = {
    methods: {
        copyData(data) {
            var _this = this;
            uni.setClipboardData({
                data: data,
                success: function() {
                    _this.$common.errorToShow('复制成功')
                }
            });
        }
    }
}

index.html

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="author" content="novice@jihainet.com" />
    <meta name="viewport"
        content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <title>
        <%= htmlWebpackPlugin.options.title %>
    </title>
<!--     <script type="text/javascript">
        let url = window.location.origin;
        if(!/Android|webOS|iPhone|iPod|BlackBerry/i.test(navigator.userAgent)) {
            window.location.href= url + '/web/';
        }
    </script> -->
    <script>
        document.addEventListener('DOMContentLoaded', function () {
            document.documentElement.style.fontSize = document.documentElement.clientWidth / 20 + 'px'
        })
    </script>
    <!-- <script src="https://cdn.bootcss.com/vConsole/3.3.2/vconsole.min.js"></script>
    <script>
        var vConsole = new VConsole();
    </script> -->
    <link rel="stylesheet" href="<%= BASE_URL %>static/index.css" />
</head>

<body>
    <div id="app"></div>
</body>
<script>
    (function (w, d, s, n, a, e) {
        w[n] = w[n] || function () {
            (w[n].z = w[n].z || []).push(arguments)
        };
        a = d.createElement(s), e = d.getElementsByTagName(s)[0];
        a.async = 1;
        a.charset = "UTF-8";
        a.src = "https://pubres.aihecong.com/hecong.js";
        e.parentNode.insertBefore(a, e)
    })(window, document, "script", "_AIHECONG");
</script>


</html>

main.js

import Vue from 'vue'
import App from './App'
import * as Api from './config/api.js'

import * as Common from './config/common.js'
import * as Db from './config/db.js'
import * as Config from './config/config.js'
import store from './store'
import './common/uni-H5Api'

Vue.config.productionTip = false
Vue.prototype.$api = Api;
Vue.prototype.$common = Common;
Vue.prototype.$db = Db;
Vue.prototype.$config = Config;
Vue.prototype.$store = store;

App.mpType = 'app'

const app = new Vue({
    ...App
})
app.$mount()

manifest.json

{
    "name" : "Jshop云商",
    "appid" : "__UNI__60F611E",
    "description" : "Jshop云商",
    "versionName" : "2.0",
    "versionCode" : 15,
    "transformPx" : false,
    "app-plus" : {
        /* 5+App特有相关 */
        "modules" : {
            "Payment" : {}
        },
        /* 模块配置 */
        "distribute" : {
            /* 应用发布信息 */
            "android" : {
                /* android打包配置 */
                "permissions" : [
                    "<uses-feature android:name=\"android.hardware.camera\"/>",
                    "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
                    "<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
                    "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
                    "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
                    "<uses-permission android:name=\"android.permission.CALL_PHONE\"/>",
                    "<uses-permission android:name=\"android.permission.CAMERA\"/>",
                    "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
                    "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
                    "<uses-permission android:name=\"android.permission.INTERNET\"/>",
                    "<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
                    "<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>",
                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
                    "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
                    "<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
                    "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
                    "<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",
                    "<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
                ]
            },
            "ios" : {},
            /* ios打包配置 */
            "sdkConfigs" : {
                "payment" : {
                    "weixin" : {
                        "appid" : "wxf62e2f29f15741af"
                    },
                    "alipay" : {
                        "scheme" : ""
                    }
                }
            }
        },
        "splashscreen" : {
            "waiting" : true
        }
    },
    /* SDK配置 */
    "quickapp" : {},
    /* 快应用特有相关 */
    "mp-weixin" : {
        "appid" : "wxaec38ca2e5cdc46a",
        "setting" : {
            "urlCheck" : true,
            "postcss" : true,
            "minified" : true,
            "es6" : true
        },
        "permission" : {
            "scope.userLocation" : {
                "desc" : "用于获取您附近的门店列表"
            }
        },
        "usingComponents" : false
    },
    "h5" : {
        "title" : "Jshop云商",
        "domain" : "https://wmp.uneedabox.com",
        "router" : {
            "base" : "/wap/",
            "mode" : "history"
        },
        "template" : "index.html",
        "devServer" : {
            "port" : 8080,
            "disableHostCheck" : true,
            "https" : false
        },
        "sdkConfigs" : {
            "maps" : {
                "qqmap" : {
                    "key" : "AEIBZ-H5TRI-A6VGA-5KRNA-QKKK6-JGB33"
                }
            }
        }
    }
}

pages

activity

index.vue
<template>
    <view class="conbox">
        <view class="container">
            <image src="../../static/img/bg.png" class="cont" mode=""></image>
            <image src="../../static/img/caidai.png" class="caidai" mode=""></image>
            <view class="header">
                <view class="header-title">
                    <view class="left">
                        免费次数:<text style="color: #E4431A;">{{chishu}}</text>
                    </view>
                    <view class="left">
                        账户积分:<text style="color: #E4431A;">{{jifen}}</text>
                    </view>
                    <view class="right" @click="getmyPrize">
                        抽奖记录 >
                    </view>
                </view>
            </view>
            <view class="main">
                <view class="canvas-container">
                    <view :animation="animationData" class="canvas-content" id="zhuanpano" style="">
                    <!-- <view :animation="animationData" class="canvas-content" id="zhuanpano"  :style="[{transform:'rotate('+runDeg+')'}]"> -->
                        <!-- <canvas class="canvas" canvas-id="canvas"></canvas> -->
                        <view class="canvas-line">
                            <view class="canvas-litem" v-for="(item,index1) in awardsList" :key="index1" :style="[{transform:'rotate('+item.lineTurn+')'}]"></view>
                        </view>
                        <view class="canvas-list">
                            <view class="canvas-item" :style="[{zIndex:index2}]" v-for="(iteml,index2) in awardsList" :key="index2">
                                <view class="canvas-item-text" :style="[{transform:'rotate('+iteml.turn+')'}]">
                                    <text>{{iteml.award}}</text>
                                    <image class="canvas-item-text-img" src="../../static/img/kongjiang.png" v-if="iteml.type == 0"></image>
                                    <image class="canvas-item-text-img" src="../../static/img/jifen.png" v-if="iteml.type == 1"></image>
                                    <image class="canvas-item-text-img" src="../../static/img/youhuiquan.png" v-if="iteml.type == 2"></image>
                                    <image class="canvas-item-text-img" src="../../static/img/yue.png" v-if="iteml.type == 3"></image>
                                    <image class="canvas-item-text-img" src="../../static/img/shangpin.png" v-if="iteml.type == 4"></image>
                                </view>
                            </view>
                        </view>
                    </view>
                    <view @tap="playReward" class="canvas-btn" v-bind:class="btnDisabled">开始 </view>
                </view>
            </view>
            <view class="typecheckbox"></view>
            <!-- 规则 -->
            <view class="guize">
                <view class="title">
                    规则说明
                </view>
                <view class="g_item" v-for="(v, k) in awardsConfig.rule" :key="k">
                    {{v}}
                </view>
            </view>
            <view class="typecheckbox2"></view>
            <!-- 抽奖记录 -->
            <view class="shadowbox" v-if="r_flg" @click="closeshadow">
                <view class="myrewards" @click.stop="openshadow">
                    <view class="title">
                        抽奖记录
                    </view>
                    <view class="itembox">
                        <view class="item" v-for="(items,i) in myPrizelist" :key="i">
                            <div class="t">
                                <text class="left">{{items.name}}</text>
                                <text class="right">{{items.ctime_name}}</text>
                            </div>
                            <div class="b">
                                {{items.prize_content}}
                            </div>
                        </view>
                    </view>
                </view>
            </view>
        </view>
    </view>
</template>

<script>
    export default {
        data() {
            return {
                awardsConfig: {
                    chance: true, //是否有抽奖机会
                    prize: [], //奖品列表 
                },
                awardsList: {},
                animationData: {},
                btnDisabled: '',
                thanksarr: [], //存储谢谢参与的索引
                chishu: 0,
                mold: 1,
                r_flg: 0,
                myPrizelist:[],
                jifen: 0
            }
        },
        onLoad: function() {
            // 获取奖品列表
            this.initdata(this)
        },
        onReady: function(e) {

        },
        methods: {
            // 查看奖品
            getmyPrize(){
                this.$api.myLottery({page: 1, limit: 1000}, res => {
                    this.myPrizelist = res.data
                    this.r_flg=1
                })
            },
            openshadow(){
                this.r_flg=1
            },
            closeshadow(){
                this.r_flg=0
            },
            // 初始化抽奖数据
            initdata:function(that){
                this.$api.lotteryConfig(res => {
                    if(res.status){
                        this.awardsConfig = res.data
                        this.chishu = res.data.user.day_remaining;
                        this.jifen = res.data.user.jifen;
                        // 获取奖品的个数
                        let awarrlength = this.awardsConfig.prize.length
                        // 为每一项追加index属性
                        this.awardsConfig.prize.forEach(function(element, index) {
                            element.index = index
                        });
                        
                        // 画转盘
                        this.drawAwardRoundel();
                    }else{
                        this.$common.errorToShow(res.msg, () => {
                            uni.navigateBack({
                                delta: 1
                            });
                        });
                    }
                });
            },
            //画抽奖圆盘  
            drawAwardRoundel: function() {
                // 拿到奖品列表
                var awards = this.awardsConfig.prize;
                var awardsList = [];
                // 每份奖品所占角度
                var turnNum = 1 / awards.length * 360; // 文字旋转 turn 值  
                // 奖项列表  
                for (var i = 0; i < awards.length; i++) {
                    awardsList.push({
                        turn: i * turnNum + 'deg', //每个奖品块旋转的角度
                        lineTurn: i * turnNum + turnNum / 2 + 'deg', //奖品分割线的旋转角度
                        award: awards[i].title, //奖品的名字,
                        type: awards[i].type,
                        id: awards[i].id,
                    });
                }
                if(this.chishu < 1 && this.jifen < this.awardsConfig.integral_exchange) {
                    this.btnDisabled = 'disabled';
                }else{
                    if(!this.awardsConfig.user.lottery){
                        this.btnDisabled = 'disabled';
                    }else{
                        this.btnDisabled = '';
                    }
                }
                
                this.awardsList = awardsList;
            },
            //发起抽奖  
            playReward: function() {
                if(this.chishu < 1) {
                    if(this.jifen < this.awardsConfig.integral_exchange) {
                        this.$common.errorToShow('抽奖次数已经用完');
                        return false;
                    } else if (this.jifen >= this.awardsConfig.integral_exchange) {
                        this.$common.modelShow('提示', '本次抽奖将消耗'+this.awardsConfig.integral_exchange+'积分,确认吗?', res => {
                            this.lottery();
                        });
                    }
                }else{
                    this.lottery();
                }
            },
            lottery: function () {
                // 抽奖
                this.$api.lottery(res => {
                    if(res.status) {
                        let awardIndex = 0;
                        let awardInfo = res.data.result;
                        
                        //获取抽奖结果
                        this.awardsList.forEach(function(element, index) {
                            if (element.id == awardInfo.id) {
                                awardIndex = index;
                            }
                        })
                        
                        //中奖index  
                        let awardsNum = this.awardsConfig.prize;
                        let runNum = 4; //旋转8周
                        let duration = 3686; //时长
                                        
                        // 旋转角度  
                        this.runDeg = this.runDeg || 0;
                        let preDeg = this.runDeg;
                        this.runDeg = this.runDeg + (360 - this.runDeg % 360) + (360 * runNum - awardIndex * (360 / awardsNum.length)) + 1;
                        
                        //创建动画  
                        if(process.env.VUE_APP_PLATFORM == 'h5'){
                            // document.styleSheets[0]
                            document.getElementById('zhuanpano').style='animation:rotate_before 4s 0ms ease forwards;'
                            if(document.styleSheets[0].cssRules.length>0){
                                Array.from(document.styleSheets[0].cssRules).forEach(function(element,index){
                                    if(element.name == 'rotate_before'){
                                        // 删除上次插入的动画
                                        document.styleSheets[0].deleteRule(index)
                                    }
                                })
                            }
                            
                            // console.log(document.styleSheets[0].cssRules)
                            // console.log("@keyframes rotate_before{from{ transform: rotate("+preDeg+"deg); }to{ transform: rotate("+this.runDeg+"deg);}}")
                            // 插入定义的动画
                            document.styleSheets[0].insertRule("@keyframes rotate_before{from{ transform: rotate("+preDeg+"deg); }to{ transform: rotate("+this.runDeg+"deg);}}",8);
                        }else{
                            var animationRun = uni.createAnimation({
                                duration: duration,
                                timingFunction: 'ease'
                            })
                            animationRun.rotate(this.runDeg).step();
                            this.animationData = animationRun.export();
                        }
                        //                     // #ifndef H5
                        //                     console.log(document.styleSheets)
                        //                     document.getElementById('zhuanpano')
                        //                     // #endif
                        this.btnDisabled = 'disabled';
                        
                        // 中奖提示  
                        var awardsConfig = this.awardsConfig;
                        var awardType = awardsConfig.prize[awardIndex].type;
                        this.jifen = this.chishu <= 0 ? (this.jifen - awardsConfig.integral_exchange >= 0 ? this.jifen - awardsConfig.integral_exchange : 0) : this.jifen;
                        this.chishu = this.chishu > 1 ? this.chishu - 1 : 0;
                        if (awardType != 0) {
                            let msg = this.getPrizeMsg(awardsConfig.prize[awardIndex].type, awardsConfig.prize[awardIndex].val);
                            setTimeout(function() {
                                this.$common.modelShow('恭喜', '获得' + (awardsConfig.prize[awardIndex].title) + ',' + msg, res => {
                                    setTimeout(function(){
                                        document.getElementById('zhuanpano').style=''
                                    },1000)
                                }, false);
                                if(!res.data.is_lottery.lottery){
                                    this.btnDisabled = 'disabled';
                                }else{
                                    this.btnDisabled = '';
                                }
                            }.bind(this), duration);
                        } else {
                            setTimeout(function() {
                                this.$common.modelShow('很遗憾', '没中奖,再接再厉!', res => {
                                    setTimeout(function(){
                                        document.getElementById('zhuanpano').style=''
                                    },1000)
                                }, false);
                                if(!res.data.is_lottery.lottery){
                                    this.btnDisabled = 'disabled';
                                }else{
                                    this.btnDisabled = '';
                                }
                            }.bind(this), duration);
                        }
                    } else {
                        this.$common.modelShow('提示', res.msg);
                    }
                });
            },
            //获取显示的奖品信息
            getPrizeMsg: function(type, val){
                let msg = '';
                switch(type){
                    case 1: //积分
                        msg = '积分:' + val + '个';
                        break;
                    case 2: //优惠券
                        msg = '优惠券:“' + val + '” 一张';
                        break;
                    case 3: //余额
                        msg = '余额:' + val + '元';
                        break;
                    case 4: //商品
                        msg = '商品:“' + val + '”';
                        break;
                    default: //默认
                        break;
                }
                return msg;
            }
        }
    }
</script>
<style scoped>
    .conbox {
        width: 750upx;
        height: 100vh;
        overflow-x: hidden;
        overflow-y: scroll;
    }

    .container,
    image.cont {
        width: 750upx;
        min-height: 100vh;
        height: auto;
        position: relative;
    }

    image.cont {
        height: 100%;
        position: absolute;
        z-index: 0;
    }

    image.caidai {
        position: absolute;
        top: 0;
        left: 0;
        width: 750upx;
        height: 1024upx;
    }

    .header {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        /* height: 246upx; */
        padding-top: 48upx;
        padding-bottom: 40upx;
        box-sizing: border-box;
        position: relative;
        z-index: 3;
    }

    .header-title {
        width: 100%;
        height: 60upx;
        display: flex;
        align-items: center;
        padding: 0 48upx;
        box-sizing: border-box;
        justify-content: space-between;
    }

    .header-title>view {
        padding: 8upx 16upx;
        border: 1px solid #d89720;
        color: #d89720;
        font-size: 28upx;
        border-radius: 26upx;
    }

    /* 转盘 */
    .canvas-container {
        margin: 0 auto;
        position: relative;
        width: 600upx;
        height: 600upx;
        background: url(../../static/img/circle.png) no-repeat;
        background-size: cover;
        border-radius: 50%;
    }

    .canvas {
        width: 100%;
        height: 100%;
        display: block !important;
        border-radius: 50%;
    }

    .canvas-content {
        position: absolute;
        left: 0;
        top: 0;
        z-index: 1;
        display: block;
        width: 600upx;
        height: 600upx;
        border-radius: inherit;
        /* background-clip: padding-box; */
        /* background-color: #ffcb3f; */
    }

    .canvas-element {
        position: relative;
        z-index: 1;
        width: inherit;
        height: inherit;
        border-radius: 50%;
    }

    .canvas-list {
        position: absolute;
        left: 0;
        top: 0;
        width: inherit;
        height: inherit;
        z-index: 9999;
    }

    .canvas-item {
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
        color: #e4370e;
        /* text-shadow: 0 1upx 1upx rgba(255, 255, 255, 0.6); */
    }

    .canvas-item-text {
        position: relative;
        display: block;
        padding-top: 46upx;
        margin: 0 auto;
        text-align: center;
        -webkit-transform-origin: 50% 300upx;
        transform-origin: 50% 300upx;
        display: flex;
        flex-direction: column;
        align-items: center;
        color: #FB778B;
    }

    .canvas-item-text text {
        font-size: 30upx;
    }

    .canvas-item-text-img {
        width: 50upx;
        height: 50upx;
        padding-top: 30upx;
    }

    /* 分隔线 */
    .canvas-line {
        position: absolute;
        left: 0;
        top: 0;
        width: inherit;
        height: inherit;
        z-index: 99;
    }

    .canvas-litem {
        position: absolute;
        left: 300upx;
        top: 0;
        width: 3upx;
        height: 300upx;
        background-color: rgba(228, 55, 14, 0.4);
        overflow: hidden;
        -webkit-transform-origin: 50% 300upx;
        transform-origin: 50% 300upx;
    }

    /**  
* 抽奖按钮  
*/
    .canvas-btn {
        position: absolute;
        left: 260upx;
        top: 260upx;
        z-index: 400;
        width: 80upx;
        height: 80upx;
        border-radius: 50%;
        color: #f4e9cc;
        background-color: #e44025;
        line-height: 80upx;
        text-align: center;
        font-size: 26upx;
        text-shadow: 0 -1px 1px rgba(0, 0, 0, 0.6);
        box-shadow: 0 3px 5px rgba(0, 0, 0, 0.6);
        text-decoration: none;
    }

    .canvas-btn::after {
        position: absolute;
        display: block;
        content: ' ';
        left: 12upx;
        top: -44upx;
        width: 0;
        height: 0;
        overflow: hidden;
        border-width: 30upx;
        border-style: solid;
        border-color: transparent;
        border-bottom-color: #e44025;
    }

    .canvas-btn.disabled {
        pointer-events: none;
        background: #b07a7b;
        color: #ccc;
    }

    .canvas-btn.disabled::after {
        border-bottom-color: #b07a7b;
    }

    .canvas-btn-table {
        color: #A83FDB;
        width: 120upx;
        text-align: center;
        position: absolute;
        left: 240upx;
        top: 360upx;
        font-size: 26upx;
        background-color: #FFFFFF;
        opacity: 0.9;
    }

    .typecheckbox {
        width: 100%;
        position: relative;
        z-index: 3;
        display: flex;
        justify-content: space-between;
        padding: 20upx;
        box-sizing: border-box;
        color: #fff;
        font-size: 28upx;
        top: -120upx;
        flex-direction: column;
        height: 180upx;
        align-items: flex-end;
        /* padding-top: 46upx; */
    }
    
    .typecheckbox2{
        width: 100%;
        position: relative;
        z-index: 3;
        display: flex;
        justify-content: space-between;
        padding: 20upx;
        box-sizing: border-box;
        color: #fff;
        font-size: 28upx;
        top: -120upx;
        flex-direction: column;
        height: 120upx;
        align-items: flex-end;
        /* padding-top: 46upx; */
    }

    .typecheckbox view {
        border: 1px solid #FF3637;
        background: transparent;
        color: #FF3637;
        display: flex;
        height: 60upx;
        width: 140upx;
        border-radius: 50upx;
        align-items: center;
        justify-content: center;
        display: flex;
        margin-left: 20upx;
    }

    .typecheckbox view.active {
        background: #FF3637;
        color: #fff;
    }

    .guize {
        width: 502upx;
        min-height: 300upx;
        display: flex;
        flex-direction: column;
        position: relative;
        z-index: 3;
        background-image: linear-gradient(-180deg, #F48549 0%, #F2642E 100%);
        border: 18upx solid #E4431A;
        border-radius: 16px;
        margin: 0 auto;
        margin-top: -104upx;
        padding: 48upx;
        /* box-sizing: border-box; */
        color: #fff;
    }

    .guize .title {
        text-align: center;
        margin-bottom: 28upx;
    }

    .guize .g_item {
        font-family: PingFang-SC-Medium;
        font-size: 24upx;
        color: #FFFFFF;
        letter-spacing: 0.5px;
        text-align: justify;
        line-height: 20px;
    }

    .shadowbox {
        width: 750upx;
        height: 100vh;
        position: fixed;
        top: 0;
        left: 0;
        z-index: 999;
        background: rgba(0, 0, 0, .6);
        display: flex;
        justify-content: center;
        align-items: center;

    }

    .myrewards {
        width: 600upx;
        min-height: 80upx;
        background: #FFEEDF;
        border: 10upx solid #F2692F;
        color: #333;
        font-size: 24upx;
        font-family: PingFang-SC-Medium;
        border-radius: 40upx;
        padding:0 24upx 20upx;
    }

    .myrewards .title {
        font-family: PingFang-SC-Bold;
        font-size: 16px;
        color: #E4431A;
        letter-spacing: 0.57px;
        display: flex;
        padding-top: 36upx;
        justify-content: center;
    }

    .myrewards .itembox {

        max-height: 320upx;
        overflow-y: auto;
    }

    .myrewards .item {
        width: 100%;
        padding: 12upx 0;
        box-sizing: border-box;
        border-bottom: 1upx dashed #CCCCCC;

    }
    .myrewards .item .t{
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom:10upx;
    }
    .myrewards .item .b{
        font-size: 12px;
        color:#999999;
        text-align: left;
    }
</style>

article

index.vue
<template>
    <view class="content">
        <view class="article">
            <view class="article-title" v-if="shopLogo && shopName">
                <img :src="shopLogo" alt="" class='shop-logo'>
                <text class='shop-name'>{{ shopName }}</text>
                <text class="fsz24 color-9 article-time">{{ info.ctime }}</text>
            </view>
            <!-- <view class="article-time">
            </view> -->
            <view class="article-content">
                <jshopContent :content="info.content" v-if="info.content"></jshopContent>
            </view>
        </view>
    </view>
</template>

<script>
    import jshopContent from '@/components/jshop/jshop-content.vue'
    export default {
        components: {
            jshopContent
        },
        data() {
            return {
                myShareCode: '', //分享Code
                idType: 1, //1文章 2公告 3微信图文消息
                id: 0,
                info: {}
            }
        },
        onLoad(e) {
            this.idType = e.id_type;
            this.id = e.id;

            if (!this.idType && !this.id) {
                this.$common.errorToShow('请求出错', res => {
                    uni.switchTab({
                        url: '/pages/index/index'
                    });
                });
            } else if (this.idType == 1) {
                this.articleDetail();
            } else if (this.idType == 2) {
                uni.setNavigationBarTitle({
                    title: '公告详情'
                });
                this.noticeDetail();
            } else if (this.idType == 3) {
                uni.setNavigationBarTitle({
                    title: '图文消息'
                });

                this.messageDetail();
            }

            this.getMyShareCode();
        },
        computed: {
            shopName() {
                return this.$store.state.config.shop_name
            },
            shopLogo() {
                return this.$store.state.config.shop_logo
            }
        },
        methods: {
            articleDetail() {
                let data = {
                    article_id: this.id
                }
                this.$api.articleInfo(data, res => {
                    if (res.status) {
                        this.info = res.data
                        uni.setNavigationBarTitle({
                            title: this.info.title
                        });
                    } else {
                        this.$common.errorToShow(res.msg, res => {
                            uni.navigateBack({
                                delta: 1
                            });
                        });
                    }
                })
            },
            noticeDetail() {
                let data = {
                    id: this.id
                }
                this.$api.noticeInfo(data, res => {
                    if (res.status) {
                        this.info = res.data
                        uni.setNavigationBarTitle({
                            title: this.info.title
                        });
                    } else {
                        this.$common.errorToShow(res.msg)
                    }
                })
            },
            //微信图文消息
            messageDetail() {
                let data = {
                    id: this.id
                }
                this.$api.messageDetail(data, res => {
                    if (res.status) {
                        this.info  = res.data
                        uni.setNavigationBarTitle({
                            title: this.info.title
                        });
                    } else {
                        this.$common.errorToShow(res.msg)
                    }
                })
            },
            getMyShareCode() {
                let userToken = this.$db.get("userToken");
                if (userToken && userToken != '') {
                    // 获取我的分享码
                    this.$api.shareCode({}, res => {
                        if (res.status) {
                            this.myShareCode = res.data ? res.data : '';
                        }
                    });
                }
            }
        },
        //分享
        onShareAppMessage() {
            let myInviteCode = this.myShareCode ? this.myShareCode : '';
            let ins = this.$common.shareParameterDecode('type=4&id=' + this.id + '&id_type=' + this.idType + '&invite=' +
                myInviteCode);
            let path = '/pages/share/jump?scene=' + ins;
            return {
                title: this.info.title,
                // #ifdef MP-ALIPAY
                //desc: this.goodsInfo.brief,
                // #endif
                //imageUrl: this.goodsInfo.album[0],
                path: path
            }
        }
    }
</script>

<style>
    .content {
        /*  #ifdef  H5  */
        height: calc(100vh - 90upx);
        /*  #endif  */
        /*  #ifndef  H5  */
        height: 100vh;
        /*  #endif  */
        background-color: #fff;
    }

    .article {
        padding: 20upx;
    }

    .article-title {
        font-size: 32upx;
        color: #333;
        margin-bottom: 20upx;
        /* text-align: center; */
        position: relative;
        height: 100upx;
    }

    .article-time {
        /* text-align: right; */
        margin-left: 20upx;
    }

    .article-content {
        font-size: 28upx !important;
        color: #666;
        line-height: 1.6;
        margin-top: 20upx;
    }

    .article-content p img {
        width: 100% !important;
    }

    .shop-logo {
        width: 60upx;
        height: 60upx;
        border-radius: 50%;
        position: absolute;
        top: 50%;
        transform: translateY(-50%);
    }

    .shop-name {
        line-height: 100upx;
        margin-left: 80upx;
    }
</style>
list.vue
<template>
    <view class="content">
        <view class='cell-group margin-cell-group'>
            <view class='cell-item'
            v-for="item in list"
            :key="item.id"
            @click="articleDetail(item.id)"
            >
                <view class="cell-title-img">
                    <image :src="item.cover" mode="aspectFill"></image>
                </view>
                <view class="cell-item-bd">
                    <view class="article-title ">
                        {{ item.title }}
                    </view>
                    <view class="article-time">
                        {{ item.ctime }}
                    </view>
                </view>
            </view>
        </view>
        <uni-load-more
        :status="loadStatus"
        ></uni-load-more>
    </view>
</template>

<script>
import uniLoadMore from '@/components/uni-load-more/uni-load-more.vue'
export default {
    components: { uniLoadMore },
    data () {
        return {
            cid: 0, // 文章分类id
            page: 1,
            limit: 10,
            list: [],
            loadStatus: 'more'
        }
    },
    onLoad (options) {
        this.cid = options.cid
        if (!this.cid) {
            this.$common.errorToShow('未指定文章分类', () => {
                uni.navigateBack({
                    delta: 1
                })
            })
        } else {
            this.articleList()
        }
    },
    onReachBottom () {
        if (this.loadStatus === 'more') {
            this.articleList()
        }
    },
    methods: {
        articleList () {
            let data = {
                page: this.page,
                limit: this.limit,
                type_id:this.cid
            }
            
            this.loadStatus = 'loading'
            
            this.$api.articleList(data, res => {
                if (res.status) {
                    const _list = res.data.list
                    
                    this.list = [...this.list, ..._list]
                    
                    if (res.data.count > this.list.length) {
                        this.loadStatus = 'more'
                        this.page ++
                    } else {
                        // 数据已加载完毕
                        this.loadStatus = 'noMore'
                    }
                } else {
                    // 接口请求出错了
                    this.$common.errorToShow(res.msg)
                }
            })
        },
        // 查看文章详情
        articleDetail (articleId) {
            this.$common.navigateTo('/pages/article/index?id=' + articleId +'&id_type=1')
        }
    }
}    
</script>

<style>
.cell-title-img{
    width: 160upx;
    height: 160upx;
}
.cell-title-img image{
    width: 100%;
    height: 100%;
}
.cell-item-bd{
    padding-right: 0;
    vertical-align: top;
    position: relative;
}
.article-title{
    font-size: 28upx;
    color: #333;
    width: 100%;
    min-height: 80upx;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
}
.article-time{
    font-size: 24upx;
    color: #999;
    display: inline-block;
    min-width: 220upx;
    min-height: 32upx;
    position: absolute;
    bottom: 0;
}

</style>

author.vue

<template>
  <view class="content">
    <view class="content-c">
      <image class="load-img" src="/static/image/loading.gif" mode=""></image>
      <view class="load-text color-9">信息加载中.....</view>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      code: '',
      type: '',
      state: ''
    }
  },
  onLoad(options) {
    // 获取url上的参数
    this.code = this.getUrlParam('code')
    this.state = this.getUrlParam('state')
    this.type = options.type
    var _this = this
    setTimeout(function() {
      _this.userTrustLogin()
    }, 100)
  },
  methods: {
    // 获取url地址参数
    getUrlParam(paraName) {
      let url = window.location.toString()
      let arrObj = url.split('?')
      if (arrObj.length > 1) {
        let arrPara = arrObj[1].split('&')
        let arr
        for (let i = 0; i < arrPara.length; i++) {
          arr = arrPara[i].split('=')
          if (arr != null && arr[0] == paraName) {
            if (arr[1].indexOf('#')) {
              let str
              str = arr[1].split('#')
              return str[0]
            }
            return arr[1]
          }
        }
        return ''
      } else {
        return ''
      }
    },
    // 第三方登录
    userTrustLogin() {
      let data = {
        scope: 1,
        code: this.code,
        state: this.state,
        invitecode: this.$db.get('invitecode') || ''
      }
      this.$api.getOpenId(data, res => {
        if (res.status) {
          if (res.data.token) {
            this.$db.set('userToken', res.data.token)
            this.redirectHandler()
          } else if (res.data.user_wx_id) {
            uni.redirectTo({
              url: '/pages/login/login/index?user_wx_id=' + res.data.user_wx_id
            })
          }
        } else {
          this.$common.errorToShow(res.msg)
        }
      })
    },
    redirectHandler() {
      this.$db.del('invitecode')
      let redirectPage = this.$db.get('redirectPage')
      if (redirectPage) {
        this.$db.del('redirectPage')
        this.$common.redirectTo(redirectPage)
      } else {
        uni.reLaunch({
          url: '/pages/index/index'
        })
      }
    }
  }
}
</script>

<style>
.content {
  position: relative;
  height: 80vh;
}
.content-c {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
}
.load-img {
  width: 100upx;
  height: 100upx;
}
.load-text {
  font-size: 26upx;
}
</style>

cart

index
index.vue
<template>
    <view class="content" v-if="cartData.list && cartData.list.length > 0">
        <view class="content-top">
            <view class="cell-group margin-cell-group">
                <view class="cell-item">
                    <view class="cell-item-hd">
                        <image class="cell-hd-icon" src="/static/image/homepage.png" style="width: 32upx;height: 32upx;"></image>
                    </view>
                    <view class="cell-item-bd">
                        <text class="cell-bd-text">{{ shopName }}</text>
                    </view>
                    <view class="cell-item-ft">
                        <text class="cell-bd-text" @click="editBtn" v-if="!editStatus">编辑</text>
                        <text class="cell-bd-text" @click="editNoBtn" v-else>完成</text>
                        <!-- <image class='cell-ft-next icon' src='/static/image/right.png'></image> -->
                    </view>
                </view>
            </view>
            <view class="img-list cart-list">
                <checkbox-group class="cart-checkbox" v-for="(item, index) in cartData.list" :key="index" :val="item.id" @change="checkboxChange(item.id)">
                    <view class="">
                        <label class="uni-list-cell uni-list-cell-pd">
                            <view class="cart-checkbox-c">
                                <checkbox color="#FF7159" :checked="item.is_select" :value="item.id" :disabled="item.stockNo" v-if="item.stockNo" class="checkboxNo" />
                                <checkbox color="#FF7159" :checked="item.is_select" :value="item.id" v-else/>
                            </view>
                        </label>
                        <view class="img-list-item">
                            <image class="img-list-item-l little-img have-none" :src="item.products.image_path" mode="aspectFill"></image>
                            <view class="img-list-item-r little-right">
                                <view class="little-right-t">
                                    <view class="goods-name list-goods-name" @click="goodsDetail(item.products.goods_id)">
                                        {{ item.products.name }}
                                    </view>
                                    <view class="goods-price red-price">
                                        ¥{{ item.products.price }}
                                    </view>
                                </view>
                                <view class="romotion-tip" v-if="item.products.promotion_list">
                                    <view class="romotion-tip-item" v-for="(v, k) in item.products.promotion_list" :key="k" :class="v.type !== 2 ? 'bg-gray' : ''">
                                        {{v.name}}
                                    </view>
                                </view>
                                <view class="goods-item-c">
                                    <view class="goods-buy">
                                        <!-- 商品规格 -->
                                        <view class="goods-salesvolume" v-if="item.products.spes_desc">
                                            {{ item.products.spes_desc }}
                                        </view>
                                        <view class="goods-salesvolume" v-else></view>
                                        <view class="goods-numbox">
                                            <text v-if="item.stockNo && !editStatus" class="stockError">库存不足</text>
                                            <text v-else-if="item.stockTension && !editStatus" class="stockError stockTension">库存紧张</text>
                                            <uni-number-box v-on:change="bindChange($event, item)" :min="1" :max="item.maxStock" :value="item.nums" v-if="!editStatus"></uni-number-box>
                                            <view v-else="" @click="del(index,item.id)" class='click-del'>
                                                <image class="icon" src="/static/image/delete.png" mode=""></image>
                                            </view>
                                        </view>
                                    </view>
                                </view>
                            </view>
                        </view>
                    </view>
                </checkbox-group>
            </view>
        </view>
        <view class="cart-bottom">
            <checkbox-group class="cart-checkbox" @change="checkboxAllButton">
                <label class="uni-list-cell uni-list-cell-pd">
                    <view class="cart-checkbox-c">
                        <checkbox :checked="checkboxAll" color="#FF7159" /> 全选
                    </view>
                </label>
                <view class="cart-bottom-right">
                    <view class="cart-bottom-right-t" v-if="!editStatus">
                        合计:
                        <view class="goods-price red-price">¥{{ cartData.amount }}</view>
                    </view>
                    <button class="btn btn-square btn-b" v-if="!editStatus" @click="settlement" hover-class="btn-hover2">去结算</button>
                    <view v-else>
                        <button class="btn btn-square btn-b" @click="delList">删除</button>
                        <!-- <button class="btn btn-square"  @click="collection">收藏</button> -->
                    </view>
                </view>
            </checkbox-group>
        </view>
    </view>
    <!-- 购物车为空 -->
    <!-- <view class='cart-none' v-else-if="cartData.list && cartData.list.length < 1 && isLoad == true">
        <image class="cart-none-img" src="/static/image/car.png" mode=""></image>
        <view class='cart-none-t'>购物车快饿瘪了 T.T</view>
        <view class='cart-none-m'>快给我挑点宝贝吧</view>
        <navigator class="cart-none-b" url='../../index/index' hover-class="btn-hover" open-type="switchTab">去逛逛</navigator>
    </view> -->
    <view class='cart-none' v-else>
        <image class="cart-none-img" src="/static/image/car.png" mode=""></image>
        <view class='cart-none-t'>购物车快饿瘪了 T.T</view>
        <view class='cart-none-m'>快给我挑点宝贝吧</view>
        <navigator class="cart-none-b" url='../../index/index' hover-class="btn-hover" open-type="switchTab">去逛逛</navigator>
    </view>
</template>

<script>
import uniNumberBox from '@/components/uni-number-box/uni-number-box.vue'
import { goods } from '@/config/mixins.js'
export default {
  mixins: [goods],
  data() {
    return {
      startX: 0, //开始坐标
      startY: 0,
      cartData: {}, //购物车数据
      cartIds: [], //选中ids
      checkboxAll: false, //全选按钮
      total: 0.0, //总价
      goSettlement: false, //去结算按钮
      cartId: '',
      cartNum: '',
      isLoad: false,
      cartNums: 0,
      editStatus: false
    }
  },
  components: { uniNumberBox },
  //页面加载
  onShow: function() {
    let userToken = this.$db.get('userToken')
    if (userToken) {
      this.getCartData(); //获取购物车数据
    }
  },
  computed: {
    // 从vuex中获取店铺名称
    shopName() {
      return this.$store.state.config.shop_name
    },
    goods_stocks_warn() {
      return this.$store.state.config.goods_stocks_warn
    }
  },
  methods: {
    checkboxChange: function(e) {
      let _this = this
      let id = e
      let cartData = _this.cartData
      for (let key in cartData.list) {
        if (cartData.list[key].id == id) {
          if (cartData.list[key].is_select == true) {
            cartData.list[key].is_select = false
          } else {
            cartData.list[key].is_select = true
          }
        }
      }
      _this.cartData = cartData
      _this.setNumsData()
      _this.isAllCheckbox()
    },

    //数组转字符串
    arrayToStr: function(array) {
      return array.toString()
    },

    //获取购物车数据
    getCartData: function() {
      let _this = this
      let cartIds = _this.arrayToStr(_this.cartIds)
      let data = {
        ids: cartIds,
        display: 'all'
      }
      this.$api.cartList(data, function(res) {
        if (res.status) {
          let data = res.data
          _this.showHandle(data) //数量设置
        }
      })
    },

    //渲染前配置数据
    showHandle: function(data, flag = true) {
      let _this = this
      let goSettlement = false
      for (let i in data.list) {
        //不可能购买0件
        if (data.list[i].nums < 1) {
          data.list[i].nums = 1
        }
        //不能买大于库存的数量(库存不足)
        let stockNo = false
        let maxStock = data.list[i].products.stock
        if (data.list[i].nums > data.list[i].products.stock) {
          //data.list[i].nums = data.list[i].products.stock;
          stockNo = true
          maxStock = data.list[i].nums
        }
        data.list[i].maxStock = maxStock
        data.list[i].stockNo = stockNo

        //库存紧张
        let stockTension = false
        if (_this.goods_stocks_warn >= data.list[i].products.stock) {
          stockTension = true
        }
        data.list[i].stockTension = stockTension

        //设置样式
        data.list[i].minStatus = 'normal'
        data.list[i].maxStatus = 'normal'
        if (data.list[i].nums == 1) {
          data.list[i].minStatus = 'disabled'
        }
        if (data.list[i].nums == data.list[i].products.stock) {
          data.list[i].maxStatus = 'disabled'
        }

        //设置规格参数
        data.list[i].spes = []
        if (data.list[i].products.spes_desc != null) {
          let spesArray = data.list[i].products.spes_desc.split(',')
          for (let key in spesArray) {
            let spesOne = spesArray[key].split(':')
            data.list[i].spes.push(spesOne[1])
          }
        }
        //添加左滑效果
        data.list[i].isTouchMove = false
        //是否可以去支付
        if (data.list[i].is_select) {
          goSettlement = true
        }
        //id转换为字符串
        data.list[i].id = _this.arrayToStr(data.list[i].id)

        //选中状态
        if (flag) {
          if (data.list[i].is_select) {
            if (_this.cartIds.indexOf(data.list[i].id) < 0) {
              _this.cartIds.push(data.list[i].id)
            }
          }
        }
      }

      data.goods_pmt = _this.$common.formatMoney(data.goods_pmt, 2, '')
      data.order_pmt = _this.$common.formatMoney(data.order_pmt, 2, '')
      data.amount = _this.$common.formatMoney(data.amount, 2, '')
      let isLoad = false
      if (data.list.length < 1) {
        isLoad = true
      }
      let n = 0
      for (let i in data.promotion_list) {
        n++
      }

      _this.goSettlement = goSettlement
      _this.isLoad = isLoad
      _this.cartNums = n

      if (flag) {
        _this.cartData = data
      } else {
        _this.getCartData()
      }

      _this.isAllCheckbox()
    },

    //是否全选
    isAllCheckbox: function() {
      let _this = this
      let cartData = _this.cartData.list
      let goSettlement = false
      let flag = true
      for (let key in cartData) {
        if (
          cartData[key].is_select == false &&
          cartData[key].stockNo == false
        ) {
          flag = false
        }
        if (cartData[key].is_select == true) {
          goSettlement = true
        }
      }
      if (cartData.length <= 0) {
        flag = false
      }

      _this.checkboxAll = flag
      _this.goSettlement = goSettlement
    },

    //全选操作
    checkboxAllButton: function(e) {
      if (this.checkboxAll == true) {
        this.checkboxAll = false
        this.setAllCheckbox(false)
      } else {
        this.checkboxAll = true
        this.setAllCheckbox(true)
      }
    },

    //全选设置
    setAllCheckbox: function(e) {
      let _this = this
      let cartData = _this.cartData
      if (e) {
        //全选
        for (let key in cartData.list) {
          if (cartData.list[key].stockNo == false) {
            cartData.list[key].is_select = true
          }
        }
      } else {
        //全不选
        for (let key in cartData.list) {
          cartData.list[key].is_select = false
        }
      }

      _this.cartData = cartData
      _this.setNumsData()
      _this.isAllCheckbox()
    },

    //设置刷新数据
    setNumsData: function() {
      let _this = this
      let cartData = _this.cartData
      let cartIds = []
      for (let key in cartData.list) {
        if (cartData.list[key].is_select) {
          cartIds.push(cartData.list[key].id)
        } else {
          //                     if (cartData.list[key].products.promotion_list) {
          //                         for (let k in cartData.list[key].products.promotion_list) {
          //                             cartData.list[key].products.promotion_list[k].type = 1;
          //                         }
          //                     }
        }
      }
      _this.cartIds = cartIds
      _this.cartData = cartData
      if (cartIds.length == 0) {
        let cartData = _this.cartData
        for (let k in cartData.promotion_list) {
          cartData.promotion_list[k].type = 1
        }
        cartData.goods_pmt = '0.00'
        cartData.order_pmt = '0.00'
        cartData.amount = '0.00'
        _this.cartData = cartData
      } else {
        _this.getCartData()
      }
    },

    //购物车数量调整
    bindChange(value, e) {
      let _this = this
      let id = e.id
      let num = value
      let cartData = _this.cartData
      let changeSelected = false
      for (let key in cartData.list) {
        if (cartData.list[key].id == id) {
          if (num <= cartData.list[key].products.stock) {
            cartData.list[key].nums = num
            changeSelected = true
          }
        }
      }
      if (changeSelected) {
        _this.cartData = cartData
        _this.cartId = id
        _this.cartNum = num
        _this.$common.throttle(_this.bindCartNumberOperation, _this, 350)
      } else {
        //_this.$common.errorToShow('数量错误1');
      }
      return false
    },

    //数量减一操作
    bindCartNumberOperation: function() {
      let _this = this
      _this.setCartNum(_this.cartId, _this.cartNum)
    },

    //设置购物车数量
    setCartNum: function(id, nums) {
      let _this = this
      let data = {
        id: id,
        nums: nums
      }
      _this.$api.setCartNum(data, function(res) {
        if (_this.cartIds.indexOf(id) > -1) {
          //_this.getCartData();
          if (res.status) {
            _this.$nextTick(function() {
              _this.showHandle(res.data, false)
            })
          } else {
            _this.$common.errorToShow(res.msg)
          }
        } else {
          _this.$nextTick(function() {
            _this.showHandle(res.data, false)
          })
        }
      })
    },

    //删除事件
    del: function(index, id) {
      let _this = this
      let cartid = id //cart_id
      //移除渲染
      _this.cartData.list.splice(index, 1)
      _this.cartData = _this.cartData
      _this.isLoad = true

      //移除数据库
      let data = {
        ids: cartid
      }
      _this.$api.removeCart(data, function(res) {
        if (res.status) {
          _this.$common.successToShow(res.msg)
        }
        _this.setNumsData()
        _this.isAllCheckbox()
      })
    },

    //收藏
    collection: function(e) {
      let _this = this
      app.db.userToken(function(token) {
        let data = {
          goods_id: e.currentTarget.dataset.goodsid
        }
        app.api.goodsCollection(data, function(res) {
          for (let k in _this.cartData.list) {
            if (
              _this.cartData.list[k].products.goods_id ==
              e.currentTarget.dataset.goodsid
            ) {
              if (res.msg == '收藏成功') {
                _this.cartData.list[k].isCollection = true
              } else {
                _this.cartData.list[k].isCollection = false
              }
            }
          }
          wx.showToast({
            title: res.msg,
            complete: function () {
                setTimeout(function() {
                    uni.hideToast();
                },1000);
            }
          })
        })
      })
    },

    //去结算
    settlement: function(e) {
      let _this = this
      if (_this.goSettlement) {
        let cartData = _this.cartData.list
        let newData = ''
        for (let key in cartData) {
          if (cartData[key].is_select == true) {
            newData += ',' + cartData[key].id
          }
        }
        if (newData.substr(0, 1) == ',') {
          newData = newData.substr(1)
        }
        if (newData.length > 0) {
          _this.$common.navigateTo(
            '/pages/goods/place-order/index?cart_ids=' + JSON.stringify(newData)
          )
          return true
        } else {
          //没有选择不跳转
        }
      }
    },

    //手指触摸动作开始 记录起点X坐标
    touchstart: function(e) {
      //开始触摸时 重置所有删除
      let _this = this
      _this.cartData.list.forEach(function(v, i) {
        if (v.isTouchMove)
          //只操作为true的
          v.isTouchMove = false
      })
      _this.setData({
        startX: e.changedTouches[0].clientX,
        startY: e.changedTouches[0].clientY,
        cartData: _this.cartData
      })
    },

    //滑动事件处理
    touchmove: function(e) {
      let _this = this
      let index = e.currentTarget.dataset.index //当前索引
      let startX = _this.startX //开始X坐标
      let startY = _this.startY //开始Y坐标
      let touchMoveX = e.changedTouches[0].clientX //滑动变化坐标
      let touchMoveY = e.changedTouches[0].clientY //滑动变化坐标
      let angle = _this.angle(
        { X: startX, Y: startY },
        { X: touchMoveX, Y: touchMoveY }
      ) //获取滑动角度
      _this.cartData.list.forEach(function(v, i) {
        v.isTouchMove = false
        //滑动超过30度角 return
        if (Math.abs(angle) > 30) return
        if (i == index) {
          if (touchMoveX > startX)
            //右滑
            v.isTouchMove = false
          else
            //左滑
            v.isTouchMove = true
        }
      })
      //更新数据
      _this.setData({
        cartData: _this.cartData
      })
    },

    //计算滑动角度
    angle: function(start, end) {
      let _X = end.X - start.X,
        _Y = end.Y - start.Y
      //返回角度 /Math.atan()返回数字的反正切值
      return 360 * Math.atan(_Y / _X) / (2 * Math.PI)
    },
    //点击编辑
    editBtn: function() {
      this.editStatus = true
    },
    //点击完成
    editNoBtn: function() {
      let _this = this
      this.editStatus = false
      let is_select = false
      for (let i in _this.cartData.list) {
        if (_this.cartData.list[i].is_select) {
          is_select = true
          break
        }
      }
      if (is_select) {
        _this.getCartData()
      }
    },

    delList: function() {
      let _this = this
      let ids = []
      for (let k in _this.cartData.list) {
        if (_this.cartData.list[k].is_select) {
          ids += _this.cartData.list[k].id + ','
        }
      }
      let data = {
        ids: ids
      }
      _this.$api.removeCart(data, function(res) {
        if (res.status) {
          _this.$common.successToShow(res.msg)
        }
        _this.setNumsData()
        _this.isAllCheckbox()
      })
    }
  }
}
</script>
<style>
.cell-item-hd {
  max-width: 40upx;
  min-width: 40upx;
}
.margin-cell-group {
  margin: 0 0 2upx 0;
}
.little-right .goods-salesvolume {
  float: none;
}
.cart-bottom {
  /*  #ifdef  H5  */
  bottom: 50px;
  /*  #endif  */
  /*  #ifndef  H5  */
  bottom: 0;
  /*  #endif  */
  z-index: 99;
  height: 90upx;
  width: 100%;
  background-color: #fff;
  position: fixed;

  overflow: hidden;
  box-shadow: 0 0 20upx #ccc;
}
.cart-bottom-right {
  height: 90upx;
  float: right;
  overflow: hidden;
}
.cart-bottom-right-t {
  display: inline-block;
  height: 100%;
  line-height: 90upx;
  margin-right: 20upx;
  font-size: 28upx;
  color: #666;
}
.cart-bottom-right-t .red-price {
  float: none;
}
.btn-square {
  float: right;
}
.cart-bottom .cart-checkbox-c {
  color: #333;
  font-size: 30upx;
}
.cart-none {
  text-align: center;
  padding: 200upx 0;
}
.cart-none-img {
  width: 252upx;
  height: 228upx;
  margin-bottom: 40upx;
}
.cart-none-t {
  color: #666;
  font-size: 28upx;
}
.cart-none-m {
  color: #666;
  font-size: 28upx;
  margin-bottom: 40upx;
}
.cart-none-b {
  /* border: 2upx solid #ccc; */
  display: inline-block;
  padding: 16upx 40upx;
  font-size: 30upx;
  color: #666;
  background-color: #e3e3e3;
}
.stockError {
  font-size: 12px;
  color: #ffffff;
  background-color: #ff7159;
  padding: 1px 3px;
  border-radius: 3px;
}
.stockTension {
  background-color: #ffc107;
}
/* #ifdef MP-ALIPAY */
label {
  display: block;
}
/* #endif */
.click-del{
    overflow: hidden;
    height: 52upx;
}
.click-del .icon{
    float: right;
}
</style>

classify

classify.vue
<template>
    <view class="classify">
        <!-- 二级小图 -->
        <view class="goods-box" v-if="cate_style == 3">
            <view class="goods-list">
                <scroll-view scroll-y="true">
                    <view class="goods-li" :class="{active:index==ins}" @click="active(index)" v-for="(tab,index) in beans" :key="index">
                        <view class="shelectedZhu"></view>
                        {{tab.name}}
                    </view>
                </scroll-view>
            </view>
            <view class="goods-grid">
                <scroll-view class="goods-content" scroll-y="true">
                    <view class="goods-banner" v-if="advert.tpl1_class_banner1">
                        <image mode="widthFix" v-for="item in advert.tpl1_class_banner1" :key="item.id" :src="item.img" @click="showSliderInfo(item.type, item.val)"/>
                    </view>
                    <view class="goods-item">
                        <view class="goods-item-box" v-if="isChild">
                            <view class="goods-items" v-for="(item, index) in beans[ins].child" :key="index" @click="goClass(item.id)">
                                <image class="goods-item-img" :src="item.image_url" alt="" mode="aspectFill"/>
                                <view class="goods-item-name">{{item.name}}</view>
                            </view>
                        </view>
                    </view>
                </scroll-view>
            </view>
        </view>
        
        <!-- 一级小图 -->
        <view class="goods-box level1-s" v-if="cate_style == 2">
            <view class="goods-grid">
                <scroll-view class="goods-content" scroll-y="true">
                    <view class="goods-item">
                        <view class="goods-item-box">
                            <view class="goods-items" v-for="(item, index) in beans" :key="index" @click="goClass(item.id)">
                                <image class="goods-item-img" :src="item.image_url" alt="" mode="aspectFill"/>
                                <view class="goods-item-name">{{item.name}}</view>
                            </view>
                        </view>
                    </view>
                </scroll-view>
            </view>
        </view>
        
        <!-- 一级大图 -->
        <view class="goods-box level1-b" v-if="cate_style == 1">
            <view class="goods-grid">
                <scroll-view class="goods-content" scroll-y="true">
                    <view class="goods-item">
                        <view class="goods-item-box">
                            <view class="goods-items" v-for="(item, index) in beans" :key="index" @click="goClass(item.id)">
                                <image class="goods-item-img" :src="item.image_url" alt="" mode="aspectFill"/>
                                <view class="goods-item-name">{{item.name}}</view>
                            </view>
                        </view>
                    </view>
                </scroll-view>
            </view>
        </view>
    </view>
</template>

<script>
var _this;
import { mapGetters } from 'vuex'
import { goods } from '@/config/mixins.js'
export default {
    mixins: [goods],
    data() {
        return {
            dataList: null,
            ins: 0,
            beans:[],
            advert: {},
            isChild: false
        };
    },
    computed: {
        cate_style () {
            return this.$store.state.config.cate_style ? this.$store.state.config.cate_style : 3;
        }
    },
    methods: {
        //切换样式 请求分类数据
        active (index) {
            this.ins = index;
            this.isChild = this.beans[index].hasOwnProperty('child');
        },
        categories () {
            this.$api.categories({}, res => {
                if(res.status){
                    for(var i = 0; i < res.data.length; i++){
                        if (i == 0) {
                            res.data[i].active = true;
                        }
                    }
                    this.beans = res.data;
                    this.isChild = this.beans[0].hasOwnProperty('child');
                }
            });
        },
        goClass (cat_id) {
            uni.navigateTo({
                url: '/pages/classify/index?id=' + cat_id
            });
        },
        getBanner() {
            this.$api.advert({
                codes: 'tpl1_class_banner1'
            }, res => {
                this.advert = res.data.list;
            });
        },
        // 广告点击查看详情
        showSliderInfo(type, val) {
            if (type == 1) {
                // URL
                // #ifdef H5
                window.location.href = val
                // #endif
            } else if (type == 2) {
                // 商品详情
                this.goodsDetail(val)
            } else if (type == 3) {
                // 文章详情
                this.$common.navigateTo('/pages/article/index?id=' + val +'&id_type=1')
            } else if (type == 4) {
                // 文章列表
                this.$common.navigateTo('/pages/article/list?cid=' + val)
            }
        },
    },
    onLoad () {
        this.categories();
        this.getBanner();
    },
};
</script>

<style>
.classify {
    /*  #ifdef  H5  */
    height: calc(100vh - 188upx);
    /*  #endif  */
    /*  #ifndef  H5  */
    height: 100vh;
    /*  #endif  */
}
.goods-box {
    height: 100%;
    overflow: hidden;
}
.goods-list {
    overflow: auto;
    height: 100%;
    width: 160upx;
    float: left;
    display: inline-block;
    background-color: #f8f8f8;
}
.goods-li{
    font-size: 24upx;
    color: #666;
    height: 100upx;
    line-height: 100upx;
    text-align: center;
    position: relative;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.goods-li.active{
    background-color: #fff;    
}
.shelectedZhu {
    height: 56upx;
    width: 8upx;
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
}
.goods-li.active .shelectedZhu{
    background-color: #333;
}
.goods-content{
    width: 590upx;
    display: inline-block;
    float: left;
    padding: 20upx;
    box-sizing: border-box;
}
.goods-grid{
    height: 100%;
    overflow: auto;
    background-color: #fff;
}
.goods-banner{
    width: 100%;
    /* height: 200upx; */
    margin-bottom: 20upx;
}
.goods-banner image{
    width: 100%;
    height: 100%;
}
.goods-item{
    
}
.goods-item-box{
    overflow: hidden;
}
.goods-items{
    width: 170upx;
    margin-right: 20upx;
    margin-bottom: 20upx;
    display: inline-block;
    
}
.goods-items:nth-child(3n){
    margin-right: 0;
}
.goods-item-img{
    width: 170upx;
    height: 170upx;
}
.goods-item-name{
    text-align: center;
    color: #666;
    font-size: 26upx;
}
.level1-s .goods-content,.level1-b .goods-content{
    width: 100%;
}
.level1-s .goods-items{
    width: 222upx;
}
.level1-s .goods-item-img{
    width: 222upx;
    height: 222upx;
}
.level1-b .goods-items{
    width: 100%;
}
.level1-b .goods-item-img{
    width: 100%;
    height: 222upx;
}
</style>
index.vue
<template>
    <view class="content">
        <!-- 搜索框 -->
        <view class="search">
            <view class="search-c" @click="goSearch">
                <view class="search-input search-input-p" v-bind:class="$store.state.searchStyle">
                    <view class="search-input-p-c">
                    {{ searchKey }}
                    </view>
                </view>
                <image class="icon search-icon" src="/static/image/zoom.png"></image>
            </view>
        </view>

        <!-- 条件筛选 -->
        <view class="screen">
            <view class="screen-item" @click="comprehensive">
                <text class="screen-item-text">综合</text>
                <view class='screen-item-icon'>
                    <image v-if="searchData.order.key == 'sort' && searchData.order.sort == 'asc'" class="screen-item-icon-img" src="/static/image/bottom-black.png"></image>
                    <image v-else class="screen-item-icon-img" src="/static/image/bottom-gray.png" ></image>
                </view>
            </view>
            <view class="screen-item" @click="priceSort">
                <text class="screen-item-text">价格</text>
                <view class="screen-item-icon">
                    <image v-if="searchData.order.key == 'price' && searchData.order.sort == 'asc'" class="screen-item-icon-img" src="/static/image/top-black.png"></image>
                    <image v-else-if="!(searchData.order.key == 'price' && searchData.order.sort == 'asc')" class="screen-item-icon-img" src="/static/image/top-gray.png"></image>
                    <image v-if="searchData.order.key == 'price' && searchData.order.sort == 'desc'" class="screen-item-icon-img" src="/static/image/bottom-black.png"></image>
                    <image v-if="!(searchData.order.key == 'price' && searchData.order.sort == 'desc')" class="screen-item-icon-img" src="/static/image/bottom-gray.png" ></image>
                </view>
            </view>
            <view class="screen-item" @click="salesVolume">
                <text class="screen-item-text">销量</text>
                <view class="screen-item-icon">
                    <image v-if="searchData.order.key == 'buy_count' && searchData.order.sort == 'asc'" class="screen-item-icon-img" src="/static/image/top-black.png"></image>
                    <image v-else-if="!(searchData.order.key == 'buy_count' && searchData.order.sort == 'asc')" class="screen-item-icon-img" src="/static/image/top-gray.png"></image>
                    <image v-if="searchData.order.key == 'buy_count' && searchData.order.sort == 'desc'" class="screen-item-icon-img" src="/static/image/bottom-black.png"></image>
                    <image v-if="!(searchData.order.key == 'buy_count' && searchData.order.sort == 'desc')" class="screen-item-icon-img" src="/static/image/bottom-gray.png"></image>
                </view>
            </view>
            <view class="screen-item">
                <view class="screen-item-icon" style-type="button" :current="current" @click="listGrid">
                    <image class="list-grid" src="/static/image/switch-ic-side-2.png" v-if="current == 0"></image>
                    <image class="list-grid" src="/static/image/switch-ic-list.png" v-else-if="current == 1"></image>
                </view>
            </view>
            <view class="screen-item screents" v-if="screents" @click="toshow()">
                <text class="screen-item-text">筛选</text>
                <image class="filter-img" src="/static/image/top.png"></image>
            </view>
            <view class="screen-item screents" v-else-if="screentc" @click="toclose()">
                <text class="screen-item-text">筛选</text>
                <image class="filter-img" src="/static/image/bottom.png"></image>
            </view>
        </view>
        
        <!-- 高级赛选 -->
        <lvv-popup position="top" ref="lvvpopref" style="background: none;">
            <view class="fliter-c">
                <scroll-view scroll-y="true" style="height: 100%;">
                    <view class="fliter-item">
                        <view class='cell-item right-img'>
                            <view class='cell-item-hd'>
                                <view class='cell-hd-title'>价格区间</view>
                            </view>
                        </view>
                        <view class="fliter-i-c">
                            <view class="fic-item">
                                <input class="fic-item-input" type="number" v-model="sPrice" />
                            </view>
                            <view class="fic-item-line"></view>
                            <view class="fic-item">
                                <input class="fic-item-input" type="number" v-model="ePrice" />
                            </view>
                        </view>
                    </view>
                    <view class="fliter-item" v-if="cat_list.length > 0">
                        <view class='cell-item right-img'>
                            <view class='cell-item-hd'>
                                <view class='cell-hd-title'>分类</view>
                            </view>
                        </view>
                        <view class="fliter-i-c">
                            <view v-for="item in cat_list" :key="item.goods_cat_id" v-if="item.goods_cat_id && item.name" @click="selectKey('cat_list', item.goods_cat_id)">
                                <view class="fic-item" v-if="!item.isSelect">
                                    <view class="fic-item-text two-line" >
                                        {{item.name}}
                                    </view>
                                </view>
                                <view class="fic-item fic-item-active" v-else-if="item.isSelect">
                                    <view class="fic-item-text two-line">
                                        {{item.name}}
                                    </view>
                                </view>
                            </view>
                        </view>
                    </view>
                    <view class="fliter-item" v-if="brand_list.length > 0">
                        <view class='cell-item right-img'>
                            <view class='cell-item-hd'>
                                <view class='cell-hd-title'>品牌</view>
                            </view>
                        </view>
                        <view class="fliter-i-c">
                            <view v-for="item in brand_list" :key="item.brand_id" v-if="item.brand_id && item.name" @click="selectKey('brand_list', item.brand_id)">
                                <view class="fic-item" v-if="!item.isSelect">
                                    <view class="fic-item-text two-line">
                                        {{item.name}}
                                    </view>
                                </view>
                                <view class="fic-item fic-item-active" v-else-if="item.isSelect">
                                    <view class="fic-item-text two-line">
                                        {{item.name}}
                                    </view>
                                </view>
                            </view>
                        </view>
                    </view>
                    <view class="fliter-item" v-if="label_list.length > 0">
                        <view class='cell-item right-img'>
                            <view class='cell-item-hd'>
                                <view class='cell-hd-title'>标签</view>
                            </view>
                        </view>
                        <view class="fliter-i-c">
                            <view v-for="item in label_list" :key="item.id" v-if="item.id && item.name" @click="selectKey('label_list', item.id)">
                                <view class="fic-item" v-if="!item.isSelect">
                                    <view class="fic-item-text two-line">
                                        {{item.name}}
                                    </view>
                                </view>
                                <view class="fic-item fic-item-active" v-else-if="item.isSelect">
                                    <view class="fic-item-text two-line">
                                        {{item.name}}
                                    </view>
                                </view>
                            </view>
                        </view>
                    </view>
                </scroll-view>
                <view class="button-bottom">
                    <!-- <button class="btn btn-square" @click="filterNo()">重置</button> -->
                    <button class="btn btn-square" @click="toclose()">关闭</button>
                    <button class="btn btn-b btn-square" @click="filterOk()">确定</button>
                </view>
            </view>
        </lvv-popup>

        <!-- 商品列表 -->
        <scroll-view scroll-y="true" :scroll-into-view="toView" class="scroll-Y" @scrolltolower="lower" enable-back-to-top="true" lower-threshold="45">
            <!-- 表格图片 -->
            <view class="img-grids" v-show="current === 0">
                <view v-if="goodsList.length>0">
                    <view class="img-grids-item" v-for="(item, index) in goodsList" :key="index" @click="goodsDetail(item.id)">
                        <image class="img-grids-item-t have-none" :src="item.image_url" mode='aspectFill'></image>
                        <view class="img-grids-item-b">
                            <view class="goods-name grids-goods-name">
                                {{item.name}}
                            </view>
                            <view class="goods-item-c">
                                <view class="goods-price red-price">¥{{item.price}}</view>
                                <image class="goods-cart" src="/static/image/ic-car.png"></image>
                            </view>
                        </view>
                    </view>
                </view>
                <!-- 无数据时默认显示 -->
                <view class="order-none" v-else>
                    <image class="order-none-img" src="/static/image/order.png" mode=""></image>
                </view>
            </view>
        
            <!-- 列表图片 -->
            <view class="img-list" v-show="current === 1">
                <view v-if="goodsList.length>0">
                    <view class="img-list-item" v-for="(item, index) in goodsList" :key="index" @click="goodsDetail(item.id)">
                        <image class="img-list-item-l" :src="item.image_url" mode='aspectFill'></image>
                        <view class="img-list-item-r">
                            <view class="goods-name list-goods-name">
                                {{item.name}}
                            </view>
                            <view class="goods-item-c">
                                <view class="goods-price red-price">¥{{item.price}}</view>
                                <view class="goods-buy">
                                    <view class="goods-salesvolume" v-if="item.comments_count > 0">{{item.comments_count}}条评论</view>
                                    <view class="goods-salesvolume" v-else-if="item.comments_count <= 0">暂无评论</view>
                                    <image class="goods-cart" src="/static/image/ic-car.png"></image>
                                </view>
                            </view>
                        </view>
                    </view>
                </view>
                <view class="order-none" v-else>
                    <image class="order-none-img" src="/static/image/order.png" mode=""></image>
                </view>
            </view>
        </scroll-view>
    </view>
</template>

<script>
import lvvPopup from '@/components/lvv-popup/lvv-popup.vue'
export default {
    data() {
        return {
            current: 0,
            id: '',
            showView: false,
            goodsList: [],
            minPrice: '',
            maxPrice: '',
            ajaxStatus: false,
            loading: true,
            loadingComplete: false,
            nodata: false,
            toView: '',
            searchData: {
                where: {},
                limit: 10,
                page: 1,
                order: {
                    key: 'sort',
                    sort: 'asc'
                }
            },
            searchKey: '请输入关键字搜索', //关键词
            alllist: true,
            allgrid: false,
            screents: true,
            screentc: false,
            sPrice: '',
            ePrice: '',
            brand_list: [],
            cat_list: [],
            label_list: []
        };
    },
    //加载执行
    onLoad: function(options) {
        var where = {};
        if (options.id) {
            where = {
                cat_id: options.id
            };
            //this.getGoodsClass(options.id);
        }
        if (options.key) {
            where = {
                search_name: options.key
            };
            this.searchKey = options.key;
        }
        if (options.type) {
            if (options.type == 'hot') {
                where = {
                    hot: true
                };
            }
            if (options.type == 'recommend') {
                where = {
                    recommend: true
                }
            }
        }
        if(options.cat_id){
            where.cat_id = options.cat_id
        }
        if(options.brand_id){
            where.brand_id =options.brand_id
        }
        if(options.hot){
            where.hot =options.hot
        }
        if(options.recommend){
            where.recommend =options.recommend
        }
        if(options.label_id){
            where.label_id =options.label_id
        }
        this.setSearchData({
            where: where
        });
        
        this.getGoods();
    },

    components: {lvvPopup},
    methods: {
        listGrid() {
            if (this.current == 0) {
                this.current = 1;
            } else {
                this.current = 0;
            }
        },
        //设置查询条件
        setSearchData: function(searchData, clear = false) {
            var sd = this.searchData;
            this.searchData = this.$common.deepCopy(sd, searchData)
            if (clear) {
                this.goodsList = [];
            }
        },
        //获取分类名称
//         getGoodsClass: function(id) {
//             let data = {
//                 id: id
//             };
//             this.$api.getGoodsClass(data, function(res) {
//                 wx.setNavigationBarTitle({
//                     title: res.data
//                 });
//             });
//         },
        onChangeShowState: function() {
            var _this = this;
            _this.showView = !_this.showView;
        },
        //点击综合排序
        comprehensive: function() {
            this.setSearchData(
                {
                    order: {
                        key: 'sort',
                        sort: 'asc'
                    },
                    page: 1
                },
                true
            );
            this.getGoods();
        },
        //销量
        salesVolume: function() {
            if (this.searchData.order.key == 'buy_count') {
                if (this.searchData.order.sort == 'desc') {
                    this.searchData.order.sort = 'asc';
                } else {
                    this.searchData.order.sort = 'desc';
                }
            } else {
                this.searchData.order = {
                    key: 'buy_count',
                    sort: 'desc'
                };
            }
            this.searchData.page = 1; //从第一页重新显示
            this.setSearchData(this.searchData, true);
            this.getGoods();
        },
        //价格排序
        priceSort: function() {
            if (this.searchData.order.key == 'price') {
                if (this.searchData.order.sort == 'desc') {
                    this.searchData.order.sort = 'asc';
                } else {
                    this.searchData.order.sort = 'desc';
                }
            } else {
                this.searchData.order = {
                    key: 'price',
                    sort: 'asc'
                };
            }
            this.searchData.page = 1; //从第一页重新显示
            this.setSearchData(this.searchData, true);
            this.getGoods();
        },
        //设置查询价格区间
//         orderPrice: function(e) {
//             var reg = /^[0-9]+(.[0-9]{2})?$/;
//             if (!reg.test(e.detail.value)) {
//                 this.$common.errorToShow('请输入正确金额');
//                 this.maxPrice = '';
//             } else {
//                 this.maxPrice = e.detail.value;
//             }
//         },
        //查询价格区间
//         searchPrice: function(event) {
//             if (
//                 this.minPrice > 0 &&
//                 this.maxPrice > 0 &&
//                 this.minPrice > this.maxPrice
//             ) {
//                 app.common.errorToShow('价格区间有误');
//                 return false;
//             }
// 
//             this.setSearchData(
//                 {
//                     page: 1,
//                     where: {
//                         price_f: this.minPrice,
//                         price_t: this.maxPrice
//                     }
//                 },
//                 true
//             );
//             this.getGoods();
//         },
        //页面相关事件处理函数--监听用户下拉动作
        onPullDownRefresh: function() {},
        //跳转到商品详情页面
        goodsDetail: function(id) {
            let url = '/pages/goods/index/index?id=' + id;
            this.$common.navigateTo(url);
        },
        //取得商品数据
        getGoods: function() {
            var _this = this;
            if (_this.ajaxStatus) {
                return false;
            }
            _this.ajaxStatus = true;
            _this.loading = true;
            _this.loadingComplete = false;
            _this.nodata = true;
            //如果已经没有数据了,就不取数据了,直接提示已经没有数据
            if (_this.loadingComplete) {
                _this.$common.errorToShow("暂时没有数据了")
                return false;
            }
            
            
            _this.$api.goodsList(_this.conditions(), function(res) {
                if (res.status) {
                    //判是否没有数据了,只要返回的记录条数小于总记录条数,那就说明到底了,因为后面没有数据了
                    var isEnd = false;
                    if (res.data.list.length < _this.searchData.limit) {
                        isEnd = true;
                    }
                    //判断是否为空
                    var isEmpty = false;
                    if (_this.searchData.page == 1 && res.data.list.length == 0) {
                        isEmpty = true;
                    }
                    
                    if(res.data.class_name != ''){
                        uni.setNavigationBarTitle({
                            title: res.data.class_name
                        });
                    }else{
                        if(res.data.where && res.data.where.search_name && res.data.where.search_name != ''){
                            uni.setNavigationBarTitle({
                                title: '商品搜索'
                            });
                        }
                    }
                    
                    _this.goodsList = _this.goodsList.concat(res.data.list);
                    _this.ajaxStatus = false;
                    _this.loading = !isEnd && !isEmpty;
                    _this.toView = '';
                    _this.loadingComplete =  isEnd && !isEmpty;
                    _this.nodata = isEmpty;
                    if(res.data.filter){
                        let filter = res.data.filter;
                        if(filter.brand_ids){
                            for(let i = 0; i < filter.brand_ids.length; i++){
                                filter.brand_ids[i].isSelect = false;
                            }
                            _this.brand_list = filter.brand_ids;
                        }
                        if(filter.goods_cat){
                            for(let i = 0; i < filter.goods_cat.length; i++){
                                filter.goods_cat[i].isSelect = false;
                            }
                            _this.cat_list = filter.goods_cat;
                        }
                        if(filter.label_ids){
                            for(let i = 0; i < filter.label_ids.length; i++){
                                filter.label_ids[i].isSelect = false;
                            }
                            _this.label_list = filter.label_ids;
                        }
                    }
                }
            });
        },
        //上拉加载
        lower: function() {
            var _this = this;
            _this.toView = 'loading';

            if (!_this.loadingComplete) {
                _this.setSearchData({
                    page: _this.searchData.page + 1
                });
                _this.getGoods();
            }
        },
        listgrid: function() {
            let _this = this;
            if (_this.alllist) {
                _this.allgrid = true;
                _this.listgrid = true;
                _this.alllist = false;
            } else {
                _this.allgrid = false;
                _this.listgrid = false;
                _this.alllist = true;
            }
        },
        // 统一返回筛选条件 查询条件 分页
        conditions () {
            let data = this.searchData;
            var newData = {};
            newData = this.$common.deepCopy(newData,data);
            //把data里的where换成json
            if(data.where){
                newData.where = JSON.stringify(data.where);
            }
            //把排序换成字符串
            if(data.order){
                var sort = data.order.key + ' ' + data.order.sort;
                if(data.order.key != 'sort'){
                    sort = sort + ',sort asc'   //如果不是综合排序,增加上第二个排序优先级排序
                }
                newData.order = sort;
            }else{
                newData.order = 'sort asc';
            }
            return newData;
        },
        //老搜索
        search(){
            this.setSearchData(
                {
                    page: 1,
                    where: {
                        search_name: this.keyword
                    }
                },
                true
            );
            this.getGoods();
        },
        //去搜索
        goSearch() {
            let pages = getCurrentPages();
            let prevPage = pages[pages.length - 2];
            // #ifdef H5 || MP-WEIXIN
            if(prevPage && prevPage.route){
                let search_flag = prevPage.route;
                if (search_flag == 'pages/index/search') {
                    uni.navigateBack({
                        delta: 1
                    });
                }else{
                    this.$common.navigateTo('/pages/index/search');
                }
            }else{
                this.$common.navigateTo('/pages/index/search');
            }
            // #endif
            
            // #ifdef MP-ALIPAY
            if(prevPage && prevPage.__proto__.route){
                let search_flag = prevPage.__proto__.route;
                if (search_flag == 'pages/index/search') {
                    uni.navigateBack({
                        delta: 1
                    });
                }else{
                    this.$common.navigateTo('/pages/index/search');
                }
            }else{
                this.$common.navigateTo('/pages/index/search');
            }
            // #endif
        },
        //筛选条件弹出窗口
        toshow(){
            this.$refs.lvvpopref.show();
            this.screents = false;
            this.screentc = true;
        },
        //关闭筛选
        toclose(){
            this.$refs.lvvpopref.close();
            this.screentc = false;
            this.screents = true;
        },
        //取消筛选
        filterNo(){
            this.ePrice = '';
            this.sPrice = '';
            for(let i = 0; i < this.cat_list.length; i++){
                this.cat_list[i].isSelect = false;
            }
            for(let i = 0; i < this.brand_list.length; i++){
                this.brand_list[i].isSelect = false;
            }
            for(let i = 0; i < this.label_list.length; i++){
                this.label_list[i].isSelect = false;
            }
            this.filterOk();
            this.toclose();
        },
        //确认筛选
        filterOk(){
            let data = this.searchData;
            
            //获取分类
            // data.where.cat_id = '';
            for(let i = 0; i < this.cat_list.length; i++){
                if(this.cat_list[i].isSelect){
                    data.where.cat_id = this.cat_list[i].goods_cat_id;
                }
            }
            
            //获取多个品牌
            let brand_ids = '';
            for(let i = 0; i < this.brand_list.length; i++){
                if(this.brand_list[i].isSelect){
                    brand_ids += this.brand_list[i].brand_id+',';
                }
            }
            if(brand_ids){
                brand_ids = brand_ids.substr(0, brand_ids.length-1);
            }
            data.where.brand_id = brand_ids;
            
            //获取标签
            data.where.label_id = '';
            for(let i = 0; i < this.label_list.length; i++){
                if(this.label_list[i].isSelect){
                    data.where.label_id = this.label_list[i].id;
                }
            }
            
            //价格区间
            data.where.price_f = '';
            data.where.price_t = '';
            if(this.sPrice*1 < 0 || (this.ePrice != '' && this.ePrice <= 0) || this.ePrice*1 < 0 || (this.sPrice*1 > this.ePrice*1 && this.sPrice != '' && this.ePrice != '')){
                this.$common.errorToShow('价格区间有误');
                return false;
            }else{
                data.where.price_f = this.sPrice;
                data.where.price_t = this.ePrice;
            }

            this.setSearchData(data, true);
            this.getGoods();
            this.toclose();
        },
        //选择
        selectKey(type, id){
            //分类一次只能选择一个
            if(type == 'cat_list'){
                for(let i = 0; i < this.cat_list.length; i++){
                    if(this.cat_list[i].goods_cat_id == id){
                        this.cat_list[i].isSelect = this.cat_list[i].isSelect?false:true;
                    }else{
                        this.cat_list[i].isSelect = false;
                    }
                }
            }
            
            if(type == 'brand_list'){
                for(let i = 0; i < this.brand_list.length; i++){
                    if(this.brand_list[i].brand_id == id){
                        this.brand_list[i].isSelect = this.brand_list[i].isSelect?false:true;
                    }
                }
            }
            
            if(type == 'label_list'){
                for(let i = 0; i < this.label_list.length; i++){
                    if(this.label_list[i].id == id){
                        this.label_list[i].isSelect = this.label_list[i].isSelect?false:true;
                    }else{
                        this.label_list[i].isSelect = false;
                    }
                }
            }
        }
    },
    // #ifdef MP-ALIPAY
    onChangeShowState_show: function () {
        var that = this;
        that.setData({
        showView: that.showView =true
        })
        },
        onChangeShowState_hid: function () {
        var that = this;
        that.setData({
        showView: that.showView =false
        })
    },
    // #endif
};
</script>

<style>
page{
    background-color: #fff;
}
.search{
    position: fixed;
    z-index: 997;
    /*  #ifdef  H5  */
    top: 44px;
    /*  #endif  */
}
.screen {
    width: 100%;
    padding: 10upx 26upx 20upx;
    overflow: hidden;
    margin-bottom: 2upx;
    background-color: #fff;
    position: fixed;
    /*  #ifdef  H5  */
    top: calc(44px + 104upx);
    /*  #endif  */
    /*  #ifndef H5 */
    top: 104upx;
    /*  #endif  */
    
    z-index: 997;
}
.screen-item {
    width: 20%;
    height: 50upx;
    line-height: 42upx;
    float: left;
    text-align: center;
    position: relative;
}
.screents {
    border-left: 2upx solid #eee;
}
.screen-item-text {
    font-size: 24upx;
    color: #333;
    margin-right: 8upx;
}
.screen-item-icon {
    display: inline-block;
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    overflow: hidden;
}
.screen-item-icon-img {
    width: 16upx;
    height: 8upx;
    display: block;
}
.screen-item-icon .screen-item-icon-img:first-child {
    margin-bottom: 4upx;
}
.list-grid {
    width: 44upx;
    height: 44upx;
    float: left;
}
.filter-img {
    width: 18upx;
    height: 8upx;
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
}
.img-grids{
    padding-bottom: 26upx;
}
.img-grids-item {
    margin-bottom: 0;
}
.img-grids>view,.img-list>view{
    overflow: hidden;
}
.scroll-Y{
    /*  #ifdef  H5  */
    height:calc(100vh - 44px - 186upx);
    /*  #endif  */
    /*  #ifndef H5 */
    height:calc(100vh - 186upx);
    /*  #endif  */
    position: fixed;
    bottom: 0;
}
.search-input-p{
    color: #888;
}
.order-none{
    text-align: center;
    padding: 200upx 0;
}
.order-none-img{
    width: 274upx;
    height: 274upx;
}
.fliter-c{
    width: 100%;
    /*  #ifdef  H5  */
    height: calc(100% - 44px - 184upx);
    top: calc(44px + 182upx);
    /*  #endif  */
    /*  #ifndef H5 */
    height: calc(100% - 184upx);
    top: 182upx;
    /*  #endif  */
    background: #FFFFFF;
    position: absolute;
    left:0;
    
    padding-bottom: 90upx;
}
.fliter-item{}
.fliter-item .cell-item{
    border-bottom: none;
}
.fliter-i-c{
    padding: 0 26upx;
    overflow: hidden;
}
.fic-item{
    display: inline-block;
    float: left;
    width: 160upx;
    margin-right: 14upx;
    height: 70upx;
    background-color: #f1f1f1;
    text-align: center;
    font-size: 24upx;
    margin-bottom: 14upx;
    color: #333;
    padding: 0 10upx;
}
.fic-item-active{
    background-color: #FF7159;
    color: #fff;
}
.fic-item-text{
    position: relative;
    top:50%;
    transform: translateY(-50%);
}
.fic-item:nth-child(4n){
    margin-right: 0;
}
.fic-item-line{
    float: left;
    margin: 34upx 18upx 0 0;
    width: 50upx;
    height: 2upx;
    border-bottom: 2upx solid #ccc;
}
.fic-item-input{
    position: relative;
    top: 50%;
    transform: translateY(-50%);
}

/* #ifdef MP-ALIPAY */
.hide{
 display: none;
}
.show{ 
 display: block;

}
/* #endif */
.square{
    border-radius: 0;
}
.radius{
    border-radius: 12upx;
}
</style>
pintuan_list.vue
<template>
    <view class="content">
        <!-- 列表图片 -->
        <view class="img-list" >
            <view v-if="goodsList.length>0">
                <view class="img-list-item" v-for="(item, index) in goodsList" :key="index" @click="goodsDetail(item.id)">
                    <image class="img-list-item-l" :src="item.image_url" mode='aspectFill'></image>
                    <view class="img-list-item-r">
                        <view class="goods-name list-goods-name">
                            {{item.name}}
                        </view>
                        <view class="goods-item-c">
                            <view class="pintuan_time">
                                <text class="fsz24 color-9">剩余:</text><uni-countdown textColor="#999" color="#999" :day="item.lasttime.day" :hour="item.lasttime.hour" :minute="item.lasttime.minute" :second="item.lasttime.second"></uni-countdown>
                            </view>
                            <view class="goods-price red-price">
                                ¥{{item.pintuanPrice}} <text class="people-num color-9 fsz24">{{item.pintuan_rule.people_number}}人成团</text>
                                <!-- <image class="goods-cart" src="/static/image/more.png"></image> -->
                            </view>
                            <view class="goods-buy">
                                <view class="goods-salesvolume" v-if="item.comments_count > 0">{{item.comments_count}}条评论</view>
                                <view class="goods-salesvolume" v-else-if="item.comments_count <= 0">暂无评论</view>
                                <image class="goods-cart" src="/static/image/more.png"></image>
                            </view>
                        </view>
                    </view>
                </view>
            </view>
            <view class="order-none" v-else>
                <image class="order-none-img" src="/static/image/order.png" mode=""></image>
            </view>
        </view>
    </view>
</template>

<script>
import uniCountdown from "@/components/uni-countdown/uni-countdown.vue"
export default {
    components:{uniCountdown},
    data() {
        return {
            goodsList: {},
            pintuanPrice: 0,
            lasttime: {
                day: 0,
                hour: false,
                minute: 0,
                second: 0
            }, //购买倒计时
        };
    },
    //加载执行
    onLoad: function() {
        this.getGoods();
    },
    methods: {
        //跳转到商品详情页面
        goodsDetail: function(id) {
            let url = '/pages/goods/index/pintuan?id=' + id;
            this.$common.navigateTo(url);
        },
        //取得商品数据
        getGoods: function() {
            var _this = this;
            let data = {}
            _this.$api.pintuanList(data, res => {
                if (res.status) {
                    _this.goodsList = res.data;
                    _this.goodsList.forEach(item=>{
                        
                        if (item.pintuan_price<=0) {
                            item.pintuan_price = '0.00'
                        } else {
                            item.pintuanPrice =  this.$common.moneySub(item.price,item.pintuan_rule.discount_amount);
                        }
                        let timestamp = Date.parse(new Date())/1000;
                        let lasttime = item.pintuan_rule.etime - timestamp;
                        item.lasttime = _this.$common.timeToDateObj(lasttime);
                        
                    })
                }
            });
        },
    },
    
};
</script>

<style>

.list-grid {
    width: 44upx;
    height: 44upx;
    float: left;
}

.img-grids{
    padding-bottom: 26upx;
}
.img-grids-item {
    margin-bottom: 0;
}
.img-grids>view,.img-list>view{
    overflow: hidden;
}

.order-none{
    text-align: center;
    padding: 200upx 0;
}
.order-none-img{
    width: 274upx;
    height: 274upx;
}
.goods-price{
    margin-bottom: 10upx;
    width: 100%;
    overflow: hidden;
}
.people-num{
    
    margin-left: 16upx;
}
.img-list-item .goods-item-c{
    bottom: 0;
}
</style>

form

detail
form.vue
<template>
    <view v-show="showPage">
        <form @submit="formSubmit" bindreset="formReset">
            <view class="content">
                <view v-if="form.head_type==1">
                    <view class="banner">
                        <image :src='form.head_type_value_url[0]' mode='widthFix'></image>
                    </view>
                </view>
                <!-- 轮播图 -->
                <view v-else-if="form.head_type == 2">
                    <view>
                        <view class='sw'>
                            <swiper>
                                <swiper-item v-for="(item,item_index) in form.head_type_value_url" :key="item_index">
                                    <image :src="item" class="slide-image" mode='widthFix' />
                                </swiper-item>
                            </swiper>
                        </view>
                    </view>
                </view>
                <view v-else-if="form.head_type==3">
                    <view class='video'>
                        <video :src='form.head_type_video_url[0]' :poster="form.head_type_value_url[0]"></video>
                    </view>
                </view>
                <!-- 纯文字 -->
                <view v-if="form.desc !=''">
                    <view class='plaintext'>
                        <text>{{form.desc}}</text>
                    </view>
                </view>
                <view class="input-box">
                    <view v-for="(item,index) in form.items" :key="index">
                        <view class='goods-box-item' v-if="item.type=='goods'">
                            <image class='goods-img' :src='item.goods.image_url' mode='aspectFit'></image>
                            <view class='goods-right'>
                                <view class='goods-name'>{{item.name}}</view>
                                <view class='goods-mid'>
                                    <text>已售{{item.goods.buy_count}}</text>
                                </view>
                                <view class='goods-buttom'>
                                    <view class="goods-price">¥{{item.goods.price}}</view>
                                    <view class='choose-specs' @click="specifications($event,item)" data-type='1' :data-goods="item.goods.id"
                                     :data-id="item.id" data-statu="openspecs">
                                        选规格
                                    </view>
                                    <text class='order-num' v-if="item.cart_count> 0">{{item.cart_count}}</text>
                                </view>
                            </view>
                        </view>
                        <view class='form-input-box-item' v-if="item.type=='text'">
                            <view class='ib-item-left'>
                                <text>{{item.name}}:</text>
                            </view>
                            <view class='ib-item-right'>
                                <input class='ib-item-input' type="text" :name="''+item.id" :data-id="item.id" v-model="item.default_value"
                                 placeholder-class='ib-item-input-c' :placeholder="'请输入'+item.name"></input>
                            </view>
                        </view>
                        <!-- 日期 -->
                        <view class='form-input-box-item' v-if="item.type=='date'">
                            <view class='ib-item-left'>
                                <text>{{item.name}}:</text>
                            </view>
                            <view class='ib-item-right'>
                                <view class="ib-item-mid">
                                    <picker mode="date" :name="''+item.id" :value="item.default_value" start="1949-10-01" end="2019-10-01" @change="bindDateChange($event,item)"
                                     :data-id='item.id'>
                                        <view>{{item.default_value}}</view>
                                    </picker>
                                    <image class='icon-img-right' src='/static/image/ic-unfold.png'></image>
                                </view>
                            </view>
                        </view>
                        <!-- 时间 -->
                        <view class='form-input-box-item' v-if="item.type=='time'">
                            <view class='ib-item-left'>
                                <text>{{item.name}}:</text>
                            </view>
                            <view class='ib-item-right'>
                                <view class="ib-item-mid">
                                    <picker class="weui-btn" :name="''+item.id" mode="time" :value="item.default_value" start="09:01" end="21:01"
                                     @change="bindTimeChange($event,item)" :data-id='item.id'>
                                        <view>{{item.default_value}}</view>
                                    </picker>
                                    <image class='icon-img-right' src='/static/image/ic-unfold.png'></image>
                                </view>
                            </view>
                        </view>
                        <!-- 范围选择 -->
                        <!-- 多选 -->
                        <view class='form-input-box-item' v-if="item.type=='checbox'">
                            <view class='ib-item-left'>
                                <text>{{item.name}}:</text>
                            </view>
                            <view class='ib-item-right'>
                                <view class='checkout-list'>
                                    <checkbox-group @change="checkboxChange($event,item)" :data-value="item.id" :name="''+item.id">
                                        <label class="checkout-item" v-for="(checkbox_item,item_index) in item.checbox_value" :key="item_index">
                                            <view class="checkout-item-c" :class="checkbox_item.checked?'black':''">
                                                <checkbox class="" :value="checkbox_item.value" :checked="checkbox_item.checked" /> {{checkbox_item.value}}
                                            </view>
                                        </label>
                                    </checkbox-group>
                                </view>
                            </view>
                        </view>
                        <!-- radio时处理 -->
                        <view class='form-input-box-item' v-if="item.type=='radio'">
                            <view class='ib-item-left'>
                                <text>{{item.name}}:</text>
                            </view>
                            <view class='ib-item-right'>
                                <radio-group class="uni-list" @change="radioChange($event,item)" :data-value="item.id" :name="''+item.id">
                                    <label class=" uni-list-cell uni-list-cell-pd " v-for="(radio_item, item_index) in  item.radio_value" :key="item_index">
                                        <view class="invoice-type-icon">
                                            <radio class="a-radio" :id="radio_item" :value="radio_item" checked=true v-if="radio_item==item.default_value"></radio>
                                            <radio class="a-radio" :id="radio_item" :value="radio_item" v-if="radio_item!=item.default_value"></radio>
                                        </view>
                                        <view class="invoice-type-c">
                                            <label class="label-2-text" :for="radio_item">
                                                <text>{{radio_item}}</text>
                                            </label>
                                        </view>
                                    </label>
                                </radio-group>
                            </view>
                        </view>
                        <!-- 省市区选择 -->
                        <view class='form-input-box-item' v-if="item.type=='area'">
                            <view class='ib-item-left'>
                                <text>{{item.name}}:</text>
                            </view>
                            <view class='ib-item-right'>
                                <view class="ib-item-mid">
                                    <input class="fsz26" :value="pickerValue" @focus="showThreePicker" :name="''+item.id" />
                                    <area-picker class="fsz26" ref="areaPicker" :areaId="areaId" :defaultIndex="defaultIndex" @onConfirm="onConfirm"></area-picker>
                                </view>
                            </view>
                        </view>
                        <!-- 金额 -->
                        <view class='form-input-box-item' v-if="item.type=='money'">
                            <view class='ib-item-left'>
                                <text>{{item.name}}:</text>
                            </view>
                            <view class='ib-item-right'>
                                <view class="ib-item-mid">
                                    <input class='ib-item-input' type="digit" :name="''+item.id" v-model="item.default_value" placeholder-class='ib-item-input-c'
                                     :placeholder="'请输入'+item.name"></input>
                                </view>
                            </view>
                        </view>
                        <!-- 密码 -->
                        <view class='form-input-box-item' v-if="item.type=='password'">
                            <view class='ib-item-left'>
                                <text>{{item.name}}:</text>
                            </view>
                            <view class='ib-item-right'>
                                <view class="ib-item-mid">
                                    <input class='ib-item-input' type='password' :name="''+item.id" v-model="item.default_value" placeholder-class='ib-item-input-c'
                                     :placeholder="'请输入'+item.name"></input>
                                </view>
                            </view>
                        </view>
                        <!-- 图片 -->
                        <view class='form-input-box-item' v-if="item.type=='image'">
                            <view class='form-input-box-title'>上传{{item.name}}</view>
                            <view class='form-multiple-rows'>
                                <view class='f-m-r-item'>
                                    <view class='upload-img-list'>
                                        <view class='upload-img-bd'>
                                            <view class='upload-img' v-for="(pic_item, i) in item.pics" :key="i">
                                                <image @click='pic_del(item,index,i)' :data-index="i" class='del-img' src='/static/image/del.png'></image>
                                                <image class='upload-camera' :src="pic_item.src" mode='aspectFit'></image>
                                                <input type='text' hidden='hidden' :name="item.id+'_'+i" v-model="pic_item.image_id"></input>
                                            </view>
                                        </view>
                                        <view class='upload-img-hd'>
                                            <image class='upload-camera' src="/static/image/camera.png" @click="pic_choose($event,item,index)"
                                             :data-id="item.id"></image>
                                        </view>
                                    </view>
                                </view>
                            </view>
                        </view>
                        <!-- 文本域 -->
                        <view class='form-input-box-item' v-if="item.type=='textarea'">
                            <view class='form-input-box-title'>{{item.name}}</view>
                            <view class='form-multiple-rows'>
                                <view class='f-m-r-item form-input-box-item'>
                                    <textarea :name="''+item.id" class='ib-item-textarea' :placeholder="'请输入'+item.name" placeholder-class="ib-item-input-c"></textarea>
                                </view>
                            </view>
                        </view>
                        <!-- 定位 -->
                        <view class='form-input-box-item' v-if="item.type=='coordinate'">
                            <view class='ib-item-left'>
                                <text>{{item.name}}:</text>
                            </view>
                            <view class='ib-item-right'>
                                <view class="ib-item-mid">
                                    <image class='icon-img' src='/static/image/ic-location.png'></image>
                                    <input class='ib-item-input margin-r' placeholder-class='ib-item-input-c' :name="''+item.id" :value="item.default_value"
                                     disabled='disabled' placeholder="点击获取位置信息" @click="chooseLocation($event,item)" :data-id='item.id' />
                                </view>
                            </view>
                        </view>
                    </view>
                </view>
                <view class='goods-bottom' v-if="form.type==1">
                    <text class='goods-total'>合计
                        <text class='goods-total-r'>¥{{goodsTotalMoney}}</text>
                    </text>
                </view>
            </view>
            <!-- 底部按钮 -->
            <view class='bottom-btn'>
                <button :style='{backgroundColor:form.button_color}' data-statu="open" form-type="submit" :disabled='submitStatus'
                 :loading='submitStatus'>{{form.button_name}}</button>
            </view>
        </form>
        <lvv-popup position="bottom" ref="lvvpopref" class="lvvpopref">
            <!-- 多规格商品弹出 -->
            <block v-if="showSpecs">
                <view class="modal-body" data-statu="closespecs" catchtouchmove="move">
                    <view class='specs-goods-t'>
                        <view class='specs-goods-information'>
                            <text class='specs-goods-name'>{{goodsInfoName}}</text>
                            <text class='specs-goods-price'>¥{{goodsInfoPrint}}</text>
                        </view>
                        <view class='close-btn' @click="closeModal" :data-goods="select_goods_id" :data-id="select_id" data-type="100"
                         data-statu="closespecs">
                            <image src='/static/image/close.png'></image>
                        </view>
                    </view>
                    <scroll-view class='specs-goods-c' scroll-y="true">

                        <view class="color" v-for="(value,key) in goodsSpesDesc" :key="key">
                            <text class='salespromotion-service-name'>{{key}}</text>
                            <view class='salespromotion-service-b'>
                                <block v-for="(i,item_index) in value" :key="item_index">
                                    <view v-if="i.is_default" class='pitch-on'>{{i.name}}</view>
                                    <view v-else-if="i.product_id != 0" :class='i.is_default ? "pitch-on" : ""' :data-key="i.product_id" :data-id="i.name"
                                     @click="selectSku">{{i.name}}</view>
                                    <view v-else class='nothing'>{{i.name}}</view>
                                </block>
                            </view>
                        </view>

                        <!-- 库存 -->
                        <view class='number'>
                            <text class='salespromotion-service-name'>数量</text>
                            <view class="stepper">
                                <text :class="goodsNums==0?'disabled':'normal'" @click="bindMinus">-</text>
                                <input type="number" @change="bindManual" v-model="goodsNums" />
                                <text :class="goodsNums==goodsInfoNumber?'disabled':'normal'" @click="bindPlus">+</text>
                            </view>
                        </view>
                    </scroll-view>
                    <view class='detail-footer'>
                        <!-- 点击加购物车/购买 -->
                        <view class='detail-footer-right determine-next' v-if="status">
                            <!-- <view @click='goodsAddCart' class='determine'>确定</view> -->
                            <view @click='goodsAddCart' class='next'>下一步</view>
                        </view>
                        <view class='detail-footer-right' v-else>
                            <view class='stockno'>该商品已售罄</view>
                        </view>
                    </view>
                </view>
            </block>
        </lvv-popup>
    </view>
</template>
<script>
    import areaPicker from '@/components/area-picker/areaPicker.vue'
    import lvvPopup from '@/components/lvv-popup/lvv-popup.vue'
    export default {
        name: '',
        components: {
            areaPicker,
            lvvPopup
        },
        props: {},
        data() {
            return {
                formId: '',
                form: {
                    head_type: 1,
                    head_type_value_url: '',
                },
                showPage: true,
                hiddenForm: true,
                indicatorDots: true, //商品轮播图底部圆点
                autoplay: true, //商品轮播图自动播放
                interval: 3000, //商品轮播图切换间隔
                duration: 500, //商品轮播图切换动画时间
                slideImg: [], //幻灯片广告数据
                minusStatus: 'disabled', // 使用data数据对象设置样式名
                animationData: {},
                opacityData: {},
                hide: 'animathide',
                formMoney: 0.0, //表单金额
                region: ['河南省', '郑州市', '中原区'],
                areaId: 410102,
                pickerValue: '',
                defaultIndex: [0, 0, 0],
                pics: [], //图片
                goodsNums: 0,
                cart: [],
                currentKey: 0, //当前下单的商品的Key
                currentGoodsId: 0, //当前选中的商品ID
                goodsTotalMoney: '0.00', //商品总额
                originForm: [], //原始表单
                paymentType: '', //支付类型
                payment_type: '', //表单付款码||表单订单
                /** 商品信息*/
                goodsSpesDesc: '',
                productId: '',
                status: '',
                goodsInfoName: '',
                goodsInfoPrint: '',
                goodsInfoNumber: '',
                select_goods_id: '',
                select_id: '',
                showSpecs: false,
                submitStatus: false, //按钮状态

            }
        },
        onLoad(options) {
            var id = options.id
            if (!id) {
                this.$common.errorToShow('路径错误')
                return false
            }
            this.formId = id
            this.$db.set('formId', id)
        },
        onShow() {
            this.getFormDetail()
        },
        methods: {
            // 省市区联动初始化
            showThreePicker() {
                this.pickerValue =
                    this.region[0] + ' ' + this.region[1] + ' ' + this.region[2]
                this.$refs.areaPicker[0].showPicker()
            },
            onConfirm(e) {
                let province_name = e[0].name
                let city_name = e[1].name
                let county_name = e[2].name
                this.pickerValue = e[0].name + ' ' + e[1].name + ' ' + e[2].name
                let data = {
                    province_name: province_name,
                    city_name: city_name,
                    county_name: county_name
                }
                let regionName = [province_name, city_name, county_name]
                this.$api.getAreaId(data, res => {
                    if (res.status) {
                        this.areaId = res.data
                    } else {
                        uni.showModal({
                            title: '提示',
                            content: '地区选择出现问题,请重新选择地区',
                            showCancel: false
                        })
                    }
                })
            },
            getFormDetail() {
                var data = {
                    id: this.formId,
                    token: this.$db.get('userToken')
                }
                var that = this
                this.$api.getFormDetial(data, res => {
                    if (res.status) {
                        this.form = res.data
                        this.originForm = res.data
                        if (res.data.type == '1' || res.data.type == '2') {
                            if (res.data.type == '1') {
                                //订单
                                that.payment_type = this.$config.paymentType.form_order
                            } else if (res.data.type == '2') {
                                //付款码
                                that.payment_type = this.$config.paymentType.form_pay
                            }
                        }
                        //设置title名称
                        uni.setNavigationBarTitle({
                            title: res.data.name
                        })

                    } else {
                        this.showPage = false;
                        if (typeof res.data.need_login == 'undefined') {
                            uni.showModal({
                                title: '提示',
                                content: '表单已过期,请扫描新的二维码',
                                showCancel: false,
                                success: function(res) {
                                    if (res.confirm) {
                                        uni.switchTab({
                                            url: '../../index/index'
                                        })
                                    }
                                }
                            })
                        } else {
                            //去登录    
                            this.$store.commit({
                                type: 'redirect',
                                page: '/pages/form/detail/form?id=' + this.formId
                            })
                            this.$common.jumpToLogin();
                        }
                    }
                })
            },
            // 选择日期
            bindDateChange(e, item) {
                item.default_value = e.target.value
            },
            // 选择时间
            bindTimeChange(e, item) {
                item.default_value = e.target.value
            },
            // 单选
            radioChange(e, item) {
                item.default_value = e.detail.value
            },
            // 多选
            checkboxChange(e, item) {
                var values = e.detail.value
                for (var i = 0; i < item.checbox_value.length; ++i) {
                    const checkbox_item = item.checbox_value[i]
                    if (values.includes(checkbox_item.value)) {
                        this.$set(checkbox_item, 'checked', true)
                    } else {
                        this.$set(checkbox_item, 'checked', false)
                    }
                }
            },

            //商品减一
            bindMinus() {
                if (this.goodsNums > 1) {
                    this.goodsNums--
                } else {
                    this.goodsNums = 0
                }
            },
            //商品加一
            bindPlus() {
                if (this.goodsNums >= this.goodsInfoNumber) {
                    this.goodsNums = this.goodsInfoNumber
                } else {
                    this.goodsNums++
                }
            },
            /* 输入框事件 */
            bindManual(e) {
                this.num = e.detail.value
            },
            //选择位置
            chooseLocation(e, item) {
                wx.chooseLocation({
                    success(e) {
                        item.default_value = e.latitude + ',' + e.longitude
                    },
                    fail(e) {
                        wx.getSetting({
                            success(res) {
                                if (!res.authSetting['scope.userLocation']) {
                                    wx.openSetting()
                                }
                            }
                        })
                    }
                })
            },
            pic_choose(e, item, index) {
                var that = this
                this.$api.uploadImage(5, res => {
                    if (res.status) {
                        if (!item.pics) {
                            item.pics = []
                        }
                        item.pics.push({
                            src: res.data.url.replace(/\\/g, '/'),
                            image_id: res.data.image_id
                        })
                        this.$set(this.form.items, index, item)
                        that.$common.successToShow(res.msg)
                    } else {
                        that.$common.errorToShow(res.msg)
                    }
                })
            },
            //删除图片
            pic_del(item, index, i) {
                item.pics.splice(i, 1)
                this.$set(this.form.items, index, item)
            },
            //表单提交
            formSubmit(e) {
                var that = this
                var data = e.detail.value
                //订单时需要合并购物车信息
                if (this.form.type == 1) {
                    if (this.cart.length < 1) {
                        this.$common.errorToShow('请先选择商品')
                        return true
                    }
                    var tempArray = []
                    this.cart.forEach(function(item, index, input) {
                        tempArray[item.key + '_' + index] = item
                    })
                    data = Object.assign(data, tempArray)
                }
                let userToken = this.$db.get('userToken')
                let obj = {
                    data,
                    id: this.form.id,
                    token: userToken
                }
                this.submitStatus = true;
                this.$api.addSubmitForm(obj, res => {
                    this.submitStatus = false;
                    if (res.status) {
                        //表单类型判断是否需要支付,支付金额多少
                        if (that.form.type == '1' || that.form.type == '2') {
                            that.$common.successToShow(res.msg);
                            //跳转首页
                            setTimeout(function() {
                                //出来支付按钮
                                that.$common.redirectTo('/pages/goods/payment/index?form_id=' + res.data.id + '&type=' + that.payment_type +
                                    '&recharge=' + res.data.money)
                            }, 1000)
                        } else {
                            that.formReset()
                            that.$common.successToShow(res.msg)
                            //跳转首页
                            setTimeout(function() {
                                wx.switchTab({
                                    url: '../../index/index'
                                })
                            }, 1500)
                        }
                    } else {
                        this.$common.errorToShow(res.msg);
                    }
                })
            },
            //表单清空
            formReset(e) {
                this.$db.set('formId', '')
                this.cart = [] //初始化,刷新当前页面
                this.form = this.originForm
            },
            closeModal() {
                this.$refs.lvvpopref.close()
            },
            //选择规格弹出
            specifications(e, item) {
                this.$refs.lvvpopref.show()
                this.showSpecs = true
                this.select_id = e.target.dataset.id
                this.select_goods_id = e.target.dataset.goods
                this.currentKey = e.target.dataset.id //当前选中的key
                this.currentGoodsId = e.target.dataset.goods //当前选中的商品ID
                this.getGoodsInfo(item)
            },
            //获取商品详情
            getGoodsInfo(item) {
                let goods = item.goods
                this.goodsSpesDesc = this.getSpes(goods.product)
                this.productId = goods.product.id
                this.goodsInfoName = goods.product.name
                this.goodsInfoPrint = goods.product.price
                this.goodsInfoNumber = goods.product.stock
                this.goodsNums = this.getNumsByKey(this.currentKey, goods.product.id)
                this.status = goods.product.stock < 1 ? false : true
            },
            /*获取key的数量 */
            getNumsByKey(key, productId) {
                var that = this
                if (that.cart.length < 1) {
                    return 0
                } else {
                    for (var i = 0; i < that.cart.length; i++) {
                        if (that.cart[i].key == key && that.cart[i].productId == productId) {
                            return that.cart[i].nums
                        }
                    }
                    return 0
                }
            },
            //加入购物车
            goodsAddCart: function() {
                var productId = this.productId
                var currentKey = this.currentKey
                if (this.cart.length < 1) {
                    this.cart.push({
                        key: currentKey,
                        productId: productId,
                        goodsId: this.select_goods_id,
                        nums: this.goodsNums,
                        price: this.goodsInfoPrint
                    })
                } else {
                    var isIn = false
                    for (var i = 0; i < this.cart.length; i++) {
                        if (
                            this.cart[i].key == currentKey &&
                            this.cart[i].productId == productId
                        ) {
                            this.cart[i] = {
                                key: currentKey,
                                productId: productId,
                                goodsId: this.select_goods_id,
                                nums: this.goodsNums,
                                price: this.goodsInfoPrint
                            }
                            isIn = true
                        }
                    }
                    if (!isIn) {
                        this.cart.push({
                            key: currentKey,
                            productId: productId,
                            goodsId: this.select_goods_id,
                            nums: this.goodsNums,
                            price: this.goodsInfoPrint
                        })
                    }
                }
                this.showSpecs = false
                this.$refs.lvvpopref.close()
                this.getCartNums()
            },
            getCartNums() {
                var items = this.form.items
                var itemKey = ''
                for (var i = 0, len = items.length; i < len; ++i) {
                    if (items[i].id == this.currentKey) {
                        itemKey = i
                    }
                }
                var that = this
                if (this.form.items[itemKey].goods.id == this.currentGoodsId) {
                    if (this.form.items[itemKey].cart_count > 0) {
                        var cart_count = 0
                        var currentKey = this.currentKey
                        this.cart.forEach(function(item, index, input) {
                            if (item.key == currentKey) {
                                cart_count += item.nums
                            }
                            that.form.items[itemKey].cart_count = cart_count
                        })
                    } else {
                        this.form.items[itemKey].cart_count = this.goodsNums
                    }
                } else {
                    this.form.items[itemKey].cart_count = this.goodsNums
                }
                this.getGoodsTotalMoney()
            },
            //获取商品总额
            getGoodsTotalMoney() {
                var that = this
                var goodsTotalMoney = 0
                this.cart.forEach(function(item, index, input) {
                    goodsTotalMoney += item.price * item.nums
                })
                this.goodsTotalMoney = this.$common.formatMoney(goodsTotalMoney, 2, '')
            },
            getSpes: function(product) {
                if (!product.default_spes_desc) {
                    return []
                }
                return product.default_spes_desc
            },
            //获取规格信息
            selectSku(e) {
                var id = e.target.dataset.key
                this.$api.getProductInfo({
                    id
                }, res => {
                    if (res.status) {
                        this.goodsSpesDesc = this.getSpes(res.data)
                        this.productId = res.data.id
                        this.goodsInfoName = res.data.name
                        this.goodsInfoPrint = res.data.price
                        this.goodsInfoNumber = res.data.stock
                        this.goodsNums = this.getNumsByKey(this.currentKey, res.data.id)
                        this.status = res.data.stock < 1 ? false : true
                    }
                })
            }
        },
        //分享
        onShareAppMessage() {
            let myInviteCode = this.$db.get("userToken");
            let ins = this.$common.shareParameterDecode('type=10&id=' + this.formId + '&invite=' + myInviteCode);
            let path = '/pages/share/jump?scene=' + ins;
            return {
                title: this.form.name,
                path: path
            }
        }
    }
</script>
<style>
    .content {
        margin-bottom: 200rpx;
        background-color: #eeeeee;
    }

    .sw,
    .video {
        height: 350rpx;
    }

    .banner,
    .sw,
    .video {
        width: 100%;
        /* height: 350rpx; */
        background-color: #fff;
    }

    .banner image,
    .sw swiper,
    .sw swiper image,
    .video video {
        width: 100%;
        height: 100%;
    }

    .plaintext {
        padding: 20rpx 30rpx;
        font-size: 30rpx;
        color: #333;
        background-color: #fff;
    }

    .goods {
        /* margin: 20rpx 0; */
        background-color: #fff;
    }

    .form-input-box-title {
        /* padding: 20rpx 30rpx 0; */
        font-size: 28rpx;
    }

    .goods-box-item {
        overflow: hidden;
        padding: 20rpx 30rpx 20rpx 0;
        margin-left: 30rpx;
        border-bottom: 2rpx solid #eeeeee;
    }

    .goods-box-item:nth-last-child(2) {
        border: none;
    }

    .goods-img {
        width: 150rpx;
        height: 150rpx;
        display: inline-block;
        float: left;
    }

    .goods-right {
        width: 520rpx;
        display: inline-block;
        float: left;
        margin-left: 20rpx;
    }

    .goods-name {
        font-size: 30rpx;
        color: #333;
        overflow: hidden;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
    }

    .goods-mid {
        font-size: 24rpx;
        color: #999;
    }

    .goods-buttom {
        overflow: hidden;
        position: relative;
        height: 60rpx;
    }

    .goods-price {
        font-size: 28rpx;
        color: #eb0000;
        display: inline-block;
    }

    .stepper {
        width: 156rpx;
        height: 48rpx;
        border-radius: 6rpx;
        margin: 0 auto;
        display: inline-block;
        overflow: hidden;
        box-sizing: border-box;
        float: right;
    }

    .stepper text {
        width: 44rpx;
        line-height: 42rpx;
        text-align: center;
        float: left;
        box-sizing: border-box;
        border: 2rpx solid #ccc;
    }

    .stepper input {
        width: 64rpx;
        height: 38rpx;
        float: left;
        text-align: center;
        font-size: 28rpx;
        display: inline-block;
        box-sizing: border-box;
    }

    .stepper .normal {
        color: black;
    }

    .stepper .disabled {
        color: #ccc;
    }

    .choose-specs {
        width: 136rpx;
        height: 48rpx;
        line-height: 46rpx;
        border-radius: 50rpx;
        margin: 0 auto;
        text-align: center;
        display: inline-block;
        overflow: hidden;
        box-sizing: border-box;
        float: right;
        font-size: 24rpx;
        border: 2rpx solid #ccc;
        position: relative;
        top: 12rpx;
    }

    .goods-bottom {
        border-top: 2rpx solid #eeeeee;
        overflow: hidden;
        padding: 20rpx 30rpx;
        background-color: #fff;
    }

    .goods-total {
        float: right;
        color: #999;
        font-size: 28rpx;
    }

    .goods-total-r {
        color: #eb0000;
        font-size: 30rpx;
    }

    .input-box {
        margin: 20rpx 0;
        background-color: #fff;
    }

    .form-input-box-item {
        overflow: hidden;
        padding: 20rpx 30rpx 20rpx 0;
        margin-left: 30rpx;
        border-bottom: 2rpx solid #eeeeee;
    }

    .ib-item-left {
        display: inline-block;
        min-width: 150rpx;
        max-width: 600rpx;
        font-size: 28rpx;
        color: #333;

        float: left;
        padding: 10rpx 0;
    }

    .ib-item-right {
        min-width: 600rpx;
        max-width: 690rpx;
        display: inline-block;
        color: #666;
        font-size: 28rpx;
        float: left;
        padding: 6rpx 0;
    }

    .ib-item-input {
        color: #666;
        font-size: 28rpx;
    }

    .margin-r {
        margin-left: 40rpx;
    }

    .ib-item-input-c {
        color: #999;
        font-size: 28rpx;
    }

    .ib-item-label {
        display: inline-block;
        position: relative;
        min-width: 150rpx;
        margin-right: 20rpx;
    }

    .ib-item-label radio {
        position: absolute;
        opacity: 0;
        width: 40rpx;
        height: 40rpx;
    }

    .ib-item-label-text {
        display: inline-block;
        margin-left: 60rpx;
        position: relative;
        top: 2rpx;
    }

    .label-icon {
        position: absolute;
        top: 0;
    }

    .label-icon icon {
        margin: 0;
    }

    .ib-item-mid {
        padding-top: 4rpx;
        margin: 0;
        position: relative;
    }

    .ib-item-mid picker {
        height: 40rpx;
    }

    .ib-item-mid .weui-select {
        border: none;
        height: 100%;
        line-height: 48rpx;
        min-height: 40rpx;
    }

    .ib-item-mid-text {
        margin-left: 40rpx;
        color: #999;
    }

    .icon-img {
        position: absolute;
        top: 50%;
        transform: translateY(-50%);
        width: 32rpx;
        height: 32rpx;
    }

    .icon-img-right {
        position: absolute;
        top: 50%;
        transform: translateY(-50%);
        width: 32rpx;
        height: 32rpx;
        right: 0;
    }

    .form-multiple-rows .form-input-box-item {
        border: none;
    }

    .f-m-r-item {
        color: #666;
        font-size: 28rpx;
        margin-top: 16upx;
    }

    .f-m-r-item .ib-item-label {
        display: block;
        margin-bottom: 20rpx;
    }

    .f-m-r-item .ib-item-label:last-child {
        margin-bottom: 0;
    }

    .various-spec-list {
        overflow: hidden;
    }

    .various-spec-item {
        padding: 10rpx 20rpx;
        display: inline-block;
        border: 2rpx solid #e2e2e2;
        margin-right: 20rpx;
        margin-bottom: 20rpx;
        border-radius: 6rpx;
        color: #666;
        background-color: #f7f7f7;
        min-width: 130rpx;
        text-align: center;
    }

    .vAactive {
        border: 2rpx solid #333;
        color: #333;
    }

    .various-spec-list:last-child .various-spec-item {
        margin-bottom: 0rpx;
    }

    .upload-img-list {
        overflow: hidden;
    }

    .upload-img-hd {
        position: relative;
        width: 150rpx;
        height: 150rpx;
        border: 2rpx solid #e2e2e2;
        background-color: #f7f7f7;
        border-radius: 6rpx;
        box-sizing: border-box;
        float: left;
        margin-left: 30rpx;
    }

    .upload-img-hd input {
        position: absolute;
        width: 100%;
        height: 100%;
        opacity: 0;
    }

    .upload-img-hd image {
        width: 48rpx;
        height: 48rpx;
        position: relative;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
    }

    .upload-img-bd {
        /* width: 150rpx; */
        /* height: 150rpx; */
        float: left;

        overflow: hidden;
    }

    .upload-img .upload-camera {
        width: 100%;
        height: 100%;
    }

    .upload-img {
        width: 150rpx;
        height: 150rpx;
        position: relative;
        float: left;
        margin-right: 30rpx;
    }

    .upload-img:last-child {
        margin-right: 0;
    }

    .del-img {
        width: 36rpx !important;
        height: 36rpx !important;
        position: absolute;
        right: 0;
        top: 0;
        z-index: 99;
    }

    .ib-item-textarea {
        width: 100%;
        height: 200rpx;
        box-sizing: border-box;
        border: 2rpx solid #e2e2e2;
        background-color: #f7f7f7;
        border-radius: 6rpx;
        padding: 20rpx 30rpx;
    }

    .bottom-btn {
        position: fixed;
        bottom: 0;
        width: 100%;
        z-index: 95;
    }

    .bottom-btn button {
        width: 100%;
        height: 90rpx;
        line-height: 90rpx;
        margin: 0 auto;
        background-color: #333;
        color: #fff;
        font-size: 32rpx;
        border-radius: 0;
    }

    .bottom-btn button::after {
        border-radius: 0;
    }

    .hidden {
        display: none;
    }

    .checkout-list {
        overflow: hidden;
    }

    .checkout-item {
        display: inline-block;
        float: left;
    }

    .checkout-item-c {
        padding: 4rpx 14rpx;
        border: 2rpx solid #ccc;
        margin-right: 10rpx;
        border-radius: 6rpx;
        color: #888;
    }

    .checkout-item-c checkbox {
        display: none;
    }

    .black {
        background-color: rgb(55, 55, 55);
        color: #fff;
        border: 2rpx solid rgb(55, 55, 55);
    }

    /*支付按钮样式*/

    .content-bot {
        margin-top: 18rpx;
    }

    .content-bot>view {
        padding: 16rpx 0;
        margin-bottom: 2rpx;
        position: relative;
        background-color: #fff;
        height: 75rpx;
    }

    .content-bot>view button {
        background-color: #fff;
        width: 100%;
        height: 100%;
        padding: 0;
        position: static;
        text-align: left;
    }

    .content-bot>view button::after {
        border: none;
    }

    .content-bot .left-img {
        display: inline-block;
        height: 82rpx;
        width: 94rpx;
        border-right: 2rpx solid #f4f4f4;
        position: absolute;
        left: 30rpx;
        top: 50%;
        transform: translateY(-50%);
    }

    .content-bot .left-img image {
        width: 64rpx;
        height: 64rpx;
        position: relative;
        top: 8rpx;
    }

    .content-bot-right {
        display: inline-block;
        margin-left: 150rpx;
        position: relative;
        top: 16rpx;
    }

    .modal-box {
        position: fixed;
        width: 100%;
        height: 100%;
        top: 0px;
        background: rgba(0, 0, 0, 0.4);
        overflow: hidden;
        z-index: 1000;
    }

    .modal-body {
        position: fixed;
        bottom: 0;
        background-color: #fff;
        width: 100%;
        z-index: 1001;
        font-size: 28rpx;
    }

    .modal-payment .item {
        height: 80rpx;
        width: 100%;
        line-height: 80rpx;
        text-align: center;
    }

    .modal-payment .immediate-pay {
        height: 80rpx;
        line-height: 80rpx;
        width: 100%;
        text-align: center;
        border: none;
        border-radius: 0;
        border-bottom: 2rpx solid #eee;
        box-sizing: border-box;
        background-color: #fff;
    }

    .modal-payment .immediate-pay::after {
        border: none;
    }

    .specs-goods-t {
        position: relative;
        padding: 30rpx;
        border-bottom: 2rpx solid #f3f3f3;
    }

    .specs-goods-information {
        width: 520rpx;
        display: inline-block;
    }

    .specs-goods-information .specs-goods-name {
        width: 100%;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
        display: block;
        font-size: 24rpx;
        margin-bottom: 20rpx;
    }

    .specs-goods-information .specs-goods-price {
        display: block;
        color: #ff3b44;
        font-size: 30rpx;
    }

    .close-btn {
        width: 40rpx;
        height: 40rpx;
        border-radius: 50%;
        display: inline-block;
        position: absolute;
        right: 30rpx;
    }

    .close-btn image {
        width: 100%;
        height: 100%;
    }

    .modal-body .detail-footer-right {
        width: 100%;
    }

    .gray-text {
        color: #a5a5a5;
        font-size: 28rpx;
    }

    .salespromotion-service-name {
        color: #a5a5a5;
        margin-right: 26rpx;
    }

    .color .salespromotion-service-name {
        float: left;
    }

    .salespromotion-service-body,
    .salespromotion-service-body view {
        display: inline-block;
    }

    .sales-promotion .salespromotion-service-body {
        margin: auto;
    }

    .sales-promotion text.salespromotion-service-body {
        background-color: #ff3b44;
        color: #fff;
        font-size: 18rpx;
        margin-left: 0rpx;
        border-radius: 10rpx;
        height: 28rpx;
        line-height: 28rpx;
        padding: 0 10rpx;
    }

    .salespromotion-service-body view {
        width: 170rpx;
        height: 40rpx;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
        position: relative;
        left: -6rpx;
    }

    .salespromotion-service-body view:first-child {
        margin-right: 8rpx;
    }

    .color-number {
        font-size: 28rpx;
        border-bottom: 14rpx solid #f3f3f3;
    }

    .color,
    .specifications,
    .number {
        padding: 22rpx 25rpx;
        border-bottom: 2rpx solid #f3f3f3;
        overflow: hidden;
    }

    .color {
        padding-bottom: 8rpx;
    }

    .color .salespromotion-service-b,
    .specifications .salespromotion-service-b {
        width: 600rpx;
        display: inline-block;
        float: left;
    }

    .color .salespromotion-service-b>view,
    .specifications .salespromotion-service-b>view {
        padding: 2rpx 20rpx;
        display: inline-block;
        text-align: center;
        border: 2rpx solid #e0e0e0;
        border-radius: 8rpx;
        color: #666;
        margin-right: 22rpx;
        margin-bottom: 12rpx;
    }

    .pitch-on {
        border: 2rpx solid #ff3b44;
        background-color: #ff3b44;
        color: #fff !important;
    }

    .nothing {
        border: 2rpx dashed #e0e0e0 !important;
        color: #c9c9c9 !important;
    }

    .specs-goods-c {
        margin-bottom: 100rpx;
        max-height: 432rpx;
    }

    .number {
        padding: 22rpx 25rpx;
    }

    .number>text {
        color: #999;
        position: relative;
        font-size: 28rpx;
    }

    .detail-footer {
        overflow: hidden;
        height: 100rpx;
        position: fixed;
        bottom: 0;
        width: 750rpx;
        text-align: center;
        z-index: 1000;
    }

    .detail-footer-left {
        width: 30%;
        height: 100rpx;
        font-size: 24rpx;
        color: #666;
        background-color: #f7f7f7;
        padding-top: 10rpx;
        box-sizing: border-box;
        display: inline-block;
    }

    .detail-footer-left>view {
        width: 50%;
        box-sizing: border-box;
        float: left;
        display: inline-block;
    }

    .detail-footer-left>view image {
        height: 36rpx;
        width: 36rpx;
    }

    .detail-footer-left>view text {
        display: block;
    }

    .detail-footer-right {
        width: 70%;
        display: inline-block;
        height: 100rpx;
        line-height: 100rpx;
        float: right;
        font-size: 28rpx;
        color: #fff;
        box-sizing: border-box;
    }

    .detail-footer-right>view {
        width: 100%;
        display: inline-block;
    }

    .modal-body .detail-footer-right {
        width: 100%;
    }

    .detail-footer-right>view {
        background-color: #333;
    }

    .order-num {
        display: block;
        min-width: 16rpx;
        height: 28rpx;
        line-height: 28rpx;
        background-color: #ff3b44;
        color: #fff;
        font-size: 16rpx;
        border-radius: 50rpx;
        position: absolute;
        right: 0rpx;
        top: 0rpx;
        padding: 0 6rpx;
        text-align: center;
    }

    .uni-list-cell-pd {
        /* width: 200upx; */
        margin-right: 40upx;
    }

    .invoice-type-icon,
    .invoice-type-c {
        display: inline-block;
    }

    .lvvpopref {
        z-index: 100;
    }
</style>

goods

index
group.vue
<template>
    <view class="content">
        <view class="nav-back">
            <view class="back-btn" @click="backBtn()">
                <image class="icon" src="/static/image/back-black.png" mode=""></image>
            </view>
        </view>
        
        <view class="content-top">
            <!-- 轮播图 -->
            <view class='swiper'>
                <swiper class="swiper-c" :indicator-dots="swiper.indicatorDots" :autoplay="swiper.autoplay" :interval="swiper.interval"
                 :duration="swiper.duration">
                    <swiper-item class="have-none" v-for="(item, index) in goodsInfo.album" :key="index" @click="clickImg(item)">
                        <image class='' :src='item' mode="aspectFill"></image>
                    </swiper-item>
                </swiper>
            </view>
            <!-- 轮播图end -->

            <view class='cell-group'>
                <!-- 倒计时 -->
                <view class='price-salesvolume' v-if="lasttime.hour!==false">
                    <view class='commodity-price'>
                        <text class='current-price'>¥{{product.price}}</text>
                        <text class='cost-price' v-if="parseFloat(product.mktprice)>0">¥{{product.mktprice}}</text>
                    </view>
                    <view class='commodity-salesvolume'>
                        <text>已售{{goodsInfo.buy_count}}件/剩余{{product.stock}}件</text>
                        <text>累计销售{{goodsInfo.buy_count}}件</text>
                    </view>
                    <view class='commodity-time-img'></view>
                    <view class='commodity-time'>
                        <text>距结束仅剩</text>
                        <view class='commodity-day'>
                            <uni-countdown :show-day="false" :hour="lasttime.hour" :minute="lasttime.minute" :second="lasttime.second"></uni-countdown>
                        </view>
                    </view>
                    <!-- <view class='commodity-time'>
                        已结束
                    </view> -->
                </view>
                <!-- 倒计时end -->

                <!-- 分享 -->
                <view class='cell-item goods-details'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>
                            <view class="color-3 fsz28 cell-hd-title-view">
                                {{ product.name }}
                            </view>
                            <view v-if="goodsInfo.brief" class="color-9 fsz24 cell-hd-title-view">
                                {{ goodsInfo.brief }}
                            </view>
                        </view>
                    </view>
                    <view class='cell-item-ft'>
                        <image class='cell-ft-next icon' @click="goShare()" src='/static/image/share.png'></image>
                    </view>
                </view>
                <!-- 分享end -->

                <!-- 促销 -->
                <view class='cell-item goods-title-item' v-if="promotion.length">
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>促销</view>
                    </view>
                    <view class='cell-item-bd'>
                        <view class="romotion-tip">
                            <view class="romotion-tip-item" :class="item.type !== 2 ? 'bg-gray' : ''" v-for="(item, index) in promotion"
                             :key="index">
                                {{ item.name }}
                            </view>
                        </view>
                    </view>
                </view>
                <!-- 促销end -->

                <!-- 规格 -->
                <view class='cell-item goods-title-item' v-if="isSpes">
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>规格</view>
                    </view>
                    <view class='cell-item-bd' @click="toshow()">
                        <text class='cell-bd-text'>{{ product.spes_desc }}</text>
                    </view>
                </view>
                <!-- 规格end -->

                <!-- 说明 -->
                <view class='cell-item goods-title-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>说明</view>
                    </view>
                    <view class='cell-item-bd'>
                        <view class="cell-bd-view">
                            <image class="goods-title-item-ic" src="/static/image/ic-dui.png" mode=""></image>
                            <text class="cell-bd-text">24小时内发货</text>
                        </view>
                        <view class="cell-bd-view">
                            <image class="goods-title-item-ic" src="/static/image/ic-dui.png" mode=""></image>
                            <text class="cell-bd-text">7天拆封无条件退货</text>
                        </view>
                    </view>
                </view>
                <!-- 说明end -->
            </view>

            <view class="goods-content">
                <uni-segmented-control :current="current" :values="items" @clickItem="onClickItem" style-type="text" active-color="#333"></uni-segmented-control>
                <view class="goods-content-c">
                    <view class="goods-detail" v-if="current === 0">
                        <jshopContent :content="goodsInfo.intro" v-if="goodsInfo.intro"></jshopContent>
                    </view>
                    <view class="goods-parameter" v-else-if="current === 1">
                        <view class='cell-group' v-if="goodsParams.length">
                            <view class='cell-item' v-for="(item, index) in goodsParams" :key="index">
                                <view class='cell-item-hd'>
                                    <view class='cell-hd-title'>{{ item.name }}</view>
                                </view>
                                <view class='cell-item-bd'>
                                    <text class='cell-bd-text'>{{ item.value }}</text>
                                </view>
                            </view>
                            <!--                             <view class='cell-item'>
                                <view class='cell-item-hd'>
                                    <view class='cell-hd-title'>保修政策</view>
                                </view>
                                <view class='cell-item-bd'>
                                    <view class="cell-bd-view">
                                        <text class="cell-bd-text">二十日内包修理或换货</text>
                                    </view>
                                    <view class="cell-bd-view">
                                        <text class="cell-bd-text">一年内包修理</text>
                                    </view>
                                </view>
                            </view> -->
                        </view>
                    </view>
                    <view class="goods-assess" v-else-if="current === 2">
                        <view v-if="goodsComments.list.length">
                            <view class="goods-assess-item" v-for="(item, index) in goodsComments.list" :key="index">
                                <view class='cell-group'>
                                    <view class='cell-item goods-title-item'>
                                        <view class='cell-item-hd'>
                                            <image class='user-head-img' :src='item.user.avatar' mode="aspectFill"></image>
                                        </view>
                                        <view class='cell-item-bd'>
                                            <view class="cell-bd-view">
                                                <text class="cell-bd-text">{{ item.user.nickname }}</text>
                                                <view class="cell-bd-text-right">
                                                    <uni-rate size="16" disabled="true" :value="item.score"></uni-rate>
                                                </view>
                                            </view>
                                            <view class="cell-bd-view">
                                                <text class="cell-bd-text color-9" style="margin-right: 16upx;">{{ item.ctime }}</text>
                                                <text class="cell-bd-text color-9">{{ item.addon }}</text>
                                            </view>
                                        </view>
                                    </view>
                                </view>
                                <view class="gai-body">
                                    <view class="gai-body-text">
                                        {{ item.content }}
                                    </view>
                                    <view class="gai-body-img" v-if="item.images_url.length">
                                        <image :src="img" mode="aspectFill" v-for="(img, key) in item.images_url" :key="key" @click="clickImg(img)"></image>
                                    </view>
                                </view>
                            </view>
                            <uni-load-more :status="goodsComments.loadStatus"></uni-load-more>
                        </view>
                        <view class="comment-none" v-else>
                            <image class="comment-none-img" src="/static/image/order.png" mode=""></image>
                        </view>
                    </view>
                </view>
            </view>
        </view>

        <lvv-popup position="bottom" ref="share">

            <!-- #ifdef H5 -->
            <shareByH5 :goodsId="goodsInfo.id" :shareImg="goodsInfo.image_url" :shareTitle="goodsInfo.name" :shareContent="goodsInfo.brief"
             :shareHref="shareHref" @close="closeShare()"></shareByH5>
            <!-- #endif -->

            <!-- #ifdef MP-WEIXIN -->
            <shareByWx :goodsId="goodsInfo.id" :shareImg="goodsInfo.image_url" :shareTitle="goodsInfo.name" :shareContent="goodsInfo.brief"
             :shareHref="shareHref" @close="closeShare()"></shareByWx>
            <!-- #endif -->

            <!-- #ifdef MP-ALIPAY -->
            <shareByAli :goodsId="goodsInfo.id" :shareImg="goodsInfo.image_url" :shareTitle="goodsInfo.name" :shareContent="goodsInfo.brief"
             :shareHref="shareHref" @close="closeShare()"></shareByAli>
            <!-- #endif -->

            <!-- #ifdef APP-PLUS -->
            <shareByApp :goodsId="goodsInfo.id" :shareImg="goodsInfo.image_url" :shareTitle="goodsInfo.name" :shareContent="goodsInfo.brief"
             :shareHref="shareHref" @close="closeShare()"></shareByApp>
            <!-- #endif -->

        </lvv-popup>

        <!-- 弹出层 -->
        <lvv-popup position="bottom" ref="lvvpopref">
            <view style="width: 100%;max-height: 804upx;background: #FFFFFF;position: absolute;left:0;bottom: 0;">
                <view class="pop-c">
                    <view class="pop-t">
                        <view class='goods-img'>
                            <image :src='product.image_path' mode='aspectFill'></image>
                        </view>
                        <view class='goods-information'>
                            <view class='pop-goods-name'>{{ product.name }}</view>
                            <view class='pop-goods-price red-price'>¥ {{ product.price }}</view>
                        </view>
                        <view class='close-btn' @click="toclose()">
                            <image src='/static/image/close.png'></image>
                        </view>
                    </view>
                    <scroll-view class="pop-m" scroll-y="true" style="max-height: 560upx;">
                        <spec :spesData="product.default_spes_desc" ref="spec" @changeSpes="changeSpes"></spec>

                        <view class="goods-number">
                            <text class="pop-m-title">数量</text>
                            <view class="pop-m-bd-in">
                                <uni-number-box :min="minNums" :max="product.stock" :value="buyNum" @change="bindChange"></uni-number-box>
                            </view>
                        </view>
                    </scroll-view>
                    <view class="pop-b">
                        <!-- <button class='btn btn-square btn-g btn-half' @click="addToCart">加入购物车</button>
                        <button class='btn btn-square btn-b btn-half' @click="buyNow">立即购买</button> -->
                        <button class='btn btn-square btn-b btn-all' hover-class="btn-hover2" @click="buyNow()" v-if="product.stock">确定</button>
                        <button class='btn btn-square btn-g btn-all' v-else>已售罄</button>
                    </view>
                </view>
            </view>
        </lvv-popup>
        <!-- 弹出层end -->

        <div id="qrCode" ref="qrCodeDiv"></div>
        <!-- 底部按钮 -->
        <view class="goods-bottom">
            <view class="goods-bottom-ic" @click="collection">
                <image class="icon" :src="isfav ? favLogo[1] : favLogo[0]" mode=""></image>
                <view v-if="!isfav">收藏</view>
                <view v-if="isfav">已收藏</view>
            </view>

            <view class="goods-bottom-ic" @click="redirectCart">
                <view class="badge color-f" v-if="cartNums">{{ cartNums }}</view>
                <image class="icon" src="/static/image/ic-me-car.png" mode=""></image>
                <view>购物车</view>
            </view>
            <button class='btn btn-square btn-b tl' @click="toshow(2)" hover-class="btn-hover2">立即{{typeName}}</button>
        </view>
        <!-- 底部按钮end -->

        <!-- 右边浮动球 -->
        <!-- <view class="right-ball">
            <view class="" @click="goIndex()">
                <image class="icon" src="/static/image/tab-ic-hom-selected.png" mode=""></image>
            </view>
        </view> -->
        <uni-fab :pattern="pattern" :content="content" :horizontal="horizontal" :vertical="vertical" :direction="direction"
         @trigger="trigger"></uni-fab>
    </view>
</template>

<script>
    import uniSegmentedControl from "@/components/uni-segmented-control/uni-segmented-control.vue";
    import lvvPopup from '@/components/lvv-popup/lvv-popup.vue';
    import uniNumberBox from "@/components/uni-number-box/uni-number-box.vue";
    import uniRate from "@/components/uni-rate/uni-rate.vue";
    import uniLoadMore from '@/components/uni-load-more/uni-load-more.vue';
    import uniFab from '@/components/uni-fab/uni-fab.vue';
    import {
        get
    } from '@/config/db.js';
    import {
        apiBaseUrl
    } from '@/config/config.js'
    import uniCountdown from "@/components/uni-countdown/uni-countdown.vue"
    import spec from '@/components/spec/spec.vue'
    // #ifdef H5
    import shareByH5 from '@/components/share/shareByh5.vue'
    // #endif
    // #ifdef MP-WEIXIN
    import shareByWx from '@/components/share/shareByWx.vue'
    // #endif
    // #ifdef MP-ALIPAY
    import shareByAli from '@/components/share/shareByAli.vue'
    // #endif
    // #ifdef APP-PLUS
    import shareByApp from '@/components/share/shareByApp.vue'
    // #endif

    import jshopContent from '@/components/jshop/jshop-content.vue'//视频和文本解析组件
    
    export default {
        components: {
            uniSegmentedControl,
            lvvPopup,
            uniNumberBox,
            uniRate,
            uniLoadMore,
            uniFab,
            uniCountdown,
            spec,
            jshopContent,
            // #ifdef H5
            shareByH5,
            // #endif

            // #ifdef MP-WEIXIN
            shareByWx,
            // #endif

            // #ifdef MP-ALIPAY
            shareByAli,
            // #endif

            // #ifdef APP-PLUS
            shareByApp,
            // #endif
        },
        data() {
            return {
                myShareCode: '', //分享Code
                swiper: {
                    indicatorDots: true,
                    autoplay: true,
                    interval: 3000,
                    duration: 800,
                }, // 轮播图属性设置
                items: ['图文详情', '商品参数', '买家评论'],
                current: 0, // init tab位
                goodsId: 0, // 商品id
                groupId: 0, // 团购ID
                goodsInfo: {}, // 商品详情
                cartNums: 0, // 购物车数量
                product: {}, // 规格详情
                goodsParams: [], // 商品参数信息
                goodsComments: {
                    loadStatus: 'more',
                    page: 1,
                    limit: 5,
                    list: []
                }, // 商品评论信息
                buyNum: 1, // 选定的购买数量
                minBuyNum: 1, // 最小可购买数量
                type: 1,
                isfav: false, // 商品是否收藏
                favLogo: [
                    '/static/image/ic-me-collect.png',
                    '/static/image/ic-me-collect2.png'
                ],
                horizontal: 'right', //右下角弹出按钮
                vertical: 'bottom',
                direction: 'vertical',
                pattern: {
                    color: '#7A7E83',
                    backgroundColor: '#fff',
                    selectedColor: '#007AFF',
                    buttonColor: "#FF7159"
                },
                content: [{
                        iconPath: '/static/image/tab-ic-hom-selected.png',
                        selectedIconPath: '/static/image/tab-ic-hom-unselected.png',
                        // text: '首页',
                        active: false,
                        url: '/pages/index/index'
                    },

                    {
                        iconPath: '/static/image/tab-ic-me-selected.png',
                        selectedIconPath: '/static/image/tab-ic-me-unselected.png',
                        // text: '个人中心',
                        active: false,
                        url: '/pages/member/index/index'
                    },
                ],
                indicatorDots: false,
                autoplay: false,
                interval: 2000,
                duration: 500,
                lasttime: {
                    hour: false,
                    minute: 0,
                    second: 0
                },
            }
        },
        onLoad(e) {
            this.goodsId = e.id;
            this.groupId = e.group_id;

            if (this.goodsId && this.groupId) {
                this.getGoodsInfo();
                this.getGoodsParams();
                this.getGoodsComments();
            } else {
                this.$common.errorToShow('获取失败', () => {
                    uni.navigateBack({
                        delta: 1
                    });
                });
            }

            // 获取购物车数量
            this.getCartNums();
            this.getMyShareCode();
        },
        computed: {
            // 规格切换计算规格商品的 可购买数量
            minNums() {
                return this.product.stock > this.minBuyNum ? this.minBuyNum : this.product.stock;
            },
            // 判断商品是否是多规格商品  (为了兼容小程序 只能写在计算属性里面了)
            isSpes() {
                if (this.product.hasOwnProperty('default_spes_desc') && Object.keys(this.product.default_spes_desc).length) {
                    return true;
                } else {
                    return false;
                }
            },
            // 优惠信息重新组装
            promotion() {
                let arr = [];
                if (this.product.promotion_list) {
                    for (let k in this.product.promotion_list) {
                        arr.push(this.product.promotion_list[k]);
                    }
                }
                return arr;
            },
            typeName() {
                return this.goodsInfo.group_type == 3 ? '团购' : '秒杀';
            },
            shareHref() {
                let pages = getCurrentPages()
                let page = pages[pages.length - 1]
                // #ifdef H5 || MP-WEIXIN || APP-PLUS || APP-PLUS-NVUE
                return apiBaseUrl + 'wap/' + page.route + '?id=' + this.goodsId + '&group_id=' + this.groupId;
                // #endif

                // #ifdef MP-ALIPAY
                return apiBaseUrl + 'wap/' + page.__proto__.route + '?id=' + this.goodsId + '&group_id=' + this.groupId;
                // #endif
            }
        },
        onReachBottom() {
            if (this.current === 2 && this.goodsComments.loadStatus === 'more') {
                this.getGoodsComments();
            }
        },
        methods: {
            // 返回上一页
            backBtn() {
                uni.navigateBack({
                    delta: 1
                });
            },
            getGoodsInfo() {
                let data = {
                    id: this.goodsId,
                    group_id: this.groupId,
                }
                // 如果用户已经登录 要传用户token
                let userToken = get('userToken');
                if (userToken) {
                    data['token'] = userToken;
                }
                let _this = this;
                this.$api.groupInfo(data, res => {
                    if (res.status) {
                        if (res.data.length < 1) {
                            this.$common.errorToShow('该商品不存在,请返回重新选择商品。', () => {
                                uni.navigateBack({
                                    delta: 1
                                });
                            });
                        } else if (res.data.marketable != 1) {
                            this.$common.errorToShow('该商品已下架,请返回重新选择商品。', () => {
                                uni.navigateBack({
                                    delta: 1
                                });
                            });
                        } else {
                            let info = res.data;
                            let products = res.data.product;
                            this.goodsInfo = info;
                            this.isfav = this.goodsInfo.isfav === 'true' ? true : false;
                            this.product = this.spesClassHandle(products);
                            let lasttime = res.data.lasttime;
                            _this.lasttime = lasttime;

                            // 判断如果登录用户添加商品浏览足迹
                            if (userToken) {
                                this.goodsBrowsing();
                            }
                        }
                    }
                });
            },
            // 获取购物车数量
            getCartNums() {
                let userToken = this.$db.get("userToken");
                if (userToken && userToken != '') {
                    // 获取购物车数量
                    this.$api.getCartNum({}, res => {
                        if (res.status) {
                            this.cartNums = res.data;
                        }
                    });
                }
            },
            // 显示modal弹出框
            toshow(type) {
                this.type = type;
                this.$refs.lvvpopref.show();
            },
            // 关闭modal弹出框
            toclose() {
                this.$refs.lvvpopref.close();
            },
            // 切换商品规格
            changeSpes(obj) {
                let index = obj.v;
                let key = obj.k;
                if (this.product.default_spes_desc[index][key].hasOwnProperty('product_id') && this.product.default_spes_desc[index]
                    [key].product_id) {
                    let data = {
                        'id': this.product.default_spes_desc[index][key].product_id
                    };
                    let userToken = this.$db.get("userToken");
                    if (userToken) {
                        data['token'] = userToken;
                    }
                    this.$api.getProductInfo(data, res => {
                        if (res.status == true) {
                            // 切换规格判断可购买数量
                            this.buyNum = res.data.stock > this.minBuyNum ? this.minBuyNum : res.data.stock;
                            this.product = this.spesClassHandle(res.data);
                        }
                    });
                    uni.showLoading({
                        title: '加载中'
                    });
                    setTimeout(function() {
                        uni.hideLoading();
                    }, 1000);
                }
            },
            // 多规格样式统一处理
            spesClassHandle(products) {
                // 判断是否是多规格 (是否有默认规格)
                if (products.hasOwnProperty('default_spes_desc')) {
                    let spes = products.default_spes_desc;
                    for (let key in spes) {
                        for (let i in spes[key]) {
                            if (spes[key][i].hasOwnProperty('is_default') && spes[key][i].is_default === true) {
                                this.$set(spes[key][i], 'cla', 'pop-m-item selected');
                            } else if (spes[key][i].hasOwnProperty('product_id') && spes[key][i].product_id) {
                                this.$set(spes[key][i], 'cla', 'pop-m-item not-selected');
                            } else {
                                this.$set(spes[key][i], 'cla', 'pop-m-item none');
                            }
                        }
                    }
                    products.default_spes_desc = spes;
                }
                return products;
            },
            // 购买数量加减操作
            bindChange(val) {
                this.buyNum = val;
            },
            // 商品收藏/取消
            collection() {
                let data = {
                    goods_id: this.goodsInfo.id
                }
                this.$api.goodsCollection(data, res => {
                    if (res.status) {
                        this.isfav = !this.isfav;
                        this.$common.successToShow(res.msg);
                    } else {
                        this.$common.errorToShow(res.msg);
                    }
                })
            },
            // tab点击切换
            onClickItem(index) {
                if (this.current !== index) {
                    this.current = index;
                }
            },
            // 获取商品参数信息
            getGoodsParams() {
                this.$api.goodsParams({
                    id: this.goodsId
                }, res => {
                    if (res.status == true) {
                        this.goodsParams = res.data;
                    }
                })
            },
            // 获取商品评论信息
            getGoodsComments() {
                let data = {
                    page: this.goodsComments.page,
                    limit: this.goodsComments.limit,
                    goods_id: this.goodsId
                }

                this.goodsComments.loadStatus = 'loading';

                this.$api.goodsComment(data, res => {
                    if (res.status == true) {
                        let _list = res.data.list;

                        // 如果评论没有图片 在这块作处理否则控制台报错
                        _list.forEach(item => {
                            item.ctime = this.$common.timeToDate(item.ctime)
                            if (!item.hasOwnProperty('images_url')) {
                                this.$set(item, 'images_url', [])
                            }
                        });

                        this.goodsComments.list = [...this.goodsComments.list, ..._list];
                        // 根据count数量判断是否还有数据
                        if (res.data.count > this.goodsComments.list.length) {
                            this.goodsComments.loadStatus = 'more';
                            this.goodsComments.page++;
                        } else {
                            this.goodsComments.loadStatus = 'noMore';
                        }
                    } else {
                        this.$common.errorToShow(res.msg);
                    }
                })
            },
            // 添加商品浏览足迹
            goodsBrowsing() {
                let data = {
                    goods_id: this.goodsInfo.id
                }

                this.$api.addGoodsBrowsing(data, res => {});
            },

            // 立即购买
            buyNow() {
                if (this.buyNum > 0) {
                    let data = {
                        product_id: this.product.id,
                        nums: this.buyNum,
                        order_type: 1,

                    }
                    this.$api.addCart(data, res => {
                        if (res.status) {
                            this.toclose();
                            let cartIds = res.data;
                            this.$common.navigateTo('/pages/goods/place-order/index?cart_ids=' + JSON.stringify(cartIds));
                        } else {
                            this.$common.errorToShow(res.msg);
                        }
                    })
                }
            },
            // 拼团
            Group() {
                if (this.buyNum > 0) {
                    let data = {
                        product_id: this.product.id,
                        nums: this.buyNum,
                        order_type: this.type, // 区分购买和拼团

                    }
                    this.$api.addCart(data, res => {
                        if (res.status) {
                            this.toclose();
                            let cartIds = res.data;
                            this.$common.navigateTo('/pages/goods/place-order/index?cart_ids=' + JSON.stringify(cartIds));
                        }
                    })
                }
            },

            // 购物车页面跳转
            redirectCart() {
                uni.switchTab({
                    url: '/pages/cart/index/index'
                });
            },

            trigger(e) {
                this.content[e.index].active = !e.item.active;
                uni.switchTab({
                    url: e.item.url
                })
            },
            // 跳转到h5分享页面
            goShare() {
                this.$refs.share.show();
            },
            closeShare() {
                this.$refs.share.close();
            },
            // 图片点击放大
            clickImg(imgs) {
                // 预览图片
                uni.previewImage({
                    urls: imgs.split()
                });
            },
            getMyShareCode() {
                let userToken = this.$db.get("userToken");
                if (userToken && userToken != '') {
                    // 获取我的分享码
                    this.$api.shareCode({}, res => {
                        if (res.status) {
                            this.myShareCode = res.data ? res.data : '';
                        }
                    });
                }
            }
        },
        //分享
        onShareAppMessage() {
            let myInviteCode = this.myShareCode ? this.myShareCode : '';
            let ins = this.$common.shareParameterDecode('type=6&id=' + this.goodsId + '&group_id=' + this.groupId + '&invite=' +
                myInviteCode);
            let path = '/pages/share/jump?scene=' + ins;
            return {
                title: this.goodsInfo.name,
                // #ifdef MP-ALIPAY
                desc: this.goodsInfo.brief,
                // #endif
                imageUrl: this.goodsInfo.album[0],
                path: path
            }
        }
    }
</script>

<style>
    .swiper {
        height: 750upx;
    }

    .goods-top {
        border-bottom: 0;
    }

    .goods-top .goods-price {
        font-size: 38upx;
    }

    .cost-price {
        font-size: 28upx !important;
        bottom: -10upx;
        color: #999;
        text-decoration: line-through;
    }

    .goods-top .cell-item-ft {
        font-size: 20upx;
        color: #666;
    }

    .goods-details {
        padding-top: 16upx;
    }

    .goods-details .cell-hd-title {
        width: 620upx;
    }

    .goods-details .cell-hd-title .cell-hd-title-view {
        width: 100%;
        display: -webkit-box;
        -webkit-box-orient: vertical;
        -webkit-line-clamp: 2;
        overflow: hidden;
    }

    .goods-details .cell-hd-title .cell-hd-title-view:last-child {
        margin-top: 10upx;
    }

    .goods-details .cell-item-ft {
        top: 24upx;
    }

    .goods-title-item .cell-item-hd {
        min-width: 60upx;
        color: #666;
        font-size: 24upx;
    }

    .goods-title-item .cell-item-bd {
        color: #333;
        font-size: 24upx;
    }

    .goods-title-item .cell-bd-text {
        bottom: 0;
    }

    .cell-bd-view {
        position: relative;
        overflow: hidden;
    }

    .cell-bd-view:first-child {
        margin-bottom: 8upx;
    }

    .goods-title-item-ic {
        width: 22upx;
        height: 22upx;
        position: absolute;
        top: 50%;
        transform: translateY(-50%);
        /* #ifdef MP-ALIPAY */
        background-size: 100% 100%;
        /* #endif */
    }

    .cell-bd-view .cell-bd-text {
        margin-left: 30upx;
    }

    .goods-content {
        margin-top: 26upx;
        background-color: #fff;
        padding: 26upx 0;
    }

    .goods-content-c {}

    .goods-parameter {
        padding: 10upx 26upx;
    }

    .goods-bottom,
    .pop-b {
        background-color: #fff;
        position: fixed;
        bottom: 0;
        height: 90upx;
        width: 100%;
        overflow: hidden;
        box-shadow: 0 0 20upx #ccc;
    }

    .goods-bottom button {
        height: 100%;
        width: 35%;
    }

    .goods-bottom-ic {
        display: inline-block;
        position: relative;
        text-align: center;
        height: 100%;
        width: 15%;
        float: left;
        font-size: 22upx;
        color: #666;
    }

    .goods-bottom-ic .icon {
        position: relative;
        top: 6upx;
        /* left: -6upx; */
        /* #ifdef MP-ALIPAY */
        background-size: 100% 100%;
        /* #endif */
    }

    .goods-bottom .btn-g {
        color: #333;
        background-color: #D9D9D9;
    }

    .goods-parameter .cell-item {
        border-bottom: none;
        margin-left: 0;
    }

    .goods-parameter .cell-item-hd {
        color: #333;
        font-size: 24upx;
    }

    .goods-parameter .cell-item-bd {
        color: #999;
    }

    .goods-parameter .cell-item-bd .cell-bd-text {
        bottom: 0;
    }

    .goods-parameter .cell-bd-text {
        margin-left: 0;
    }

    .pop-t {
        position: relative;
        padding: 30upx 26upx;
        border-bottom: 2upx solid #f3f3f3;
        /* box-shadow: 0 0 20upx #ccc; */
    }

    .goods-img {
        width: 160upx;
        height: 160upx;
        position: absolute;
        top: -20upx;
        background-color: #fff;
        border-radius: 6upx;
        border: 2upx solid #fff;
    }

    .goods-img image {
        height: 100%;
        width: 100%;
    }

    .goods-information {
        width: 420upx;
        display: inline-block;
        margin-left: 180upx;
    }

    .pop-goods-name {
        width: 100%;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
        display: block;
        font-size: 24upx;
        margin-bottom: 20upx;
    }

    .pop-goods-price {
        font-size: 30upx;
    }

    .close-btn {
        width: 40upx;
        height: 40upx;
        border-radius: 50%;
        display: inline-block;
        position: absolute;
        right: 30upx;
    }

    .close-btn image {
        width: 100%;
        height: 100%;
    }

    .pop-m {
        font-size: 28upx;
        margin-bottom: 90upx;
    }

    .goods-specs,
    .goods-number {
        padding: 26upx;
        border-top: 1px solid #f3f3f3;
    }

    .goods-specs:first-child {
        border: none;
    }

    .pop-m-title {
        margin-right: 10upx;
        color: #666;
    }

    .pop-m-bd {
        overflow: hidden;
        margin-top: 10upx;
    }

    .pop-m-item {
        display: inline-block;
        float: left;
        padding: 6upx 16upx;
        background-color: #fff;
        color: #333;
        margin-right: 16upx;
        margin-bottom: 10upx;
    }

    .selected {
        border: 2upx solid #333;
        background-color: #333;
        color: #fff;
    }

    .not-selected {
        border: 2upx solid #ccc;
    }

    .none {
        border: 2upx dashed #ccc;
        color: #888;
    }

    .pop-m-bd-in {
        display: inline-block;
    }

    .badge {
        top: 2upx;
        left: 62upx;
    }

    .goods-assess .user-head-img {
        width: 80upx;
        height: 80upx;
        border-radius: 50%;
    }

    .goods-assess .cell-item-bd {
        padding-right: 0;
    }

    .goods-assess .cell-bd-text {
        margin: 0;
    }

    .goods-assess .cell-bd-text.color-9 {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        max-width: 440upx;
    }

    .gai-body {}

    .gai-body-text {
        font-size: 26upx;
        color: #333;
        padding: 0 26upx;
        word-wrap: break-word;
    }

    .gai-body-img {
        overflow: hidden;
        padding: 20upx 26upx;
    }

    .gai-body-img image {
        width: 220upx;
        height: 220upx;
        float: left;
        margin-right: 19upx;
        margin-bottom: 18upx;
    }

    .gai-body-img image:nth-child(3n) {
        margin-right: 0;
    }

    .redstar {
        width: 24rpx;
        height: 24rpx;
        padding: 2rpx;
    }

    .mask-share-wechat {
        display: inline-block;
        background-color: #fff;
        padding: 0;
    }

    .mask-share-wechat:after {
        border: none;
    }

    .right-ball {
        position: fixed;
        right: 30upx;
        bottom: 300upx;
        z-index: 999;
        text-align: center;
        padding: 14upx 0;
        /* line-height: 80upx; */
        width: 80upx;
        height: 80upx;
        font-size: 24upx;
        color: #fff;
        background-color: rgba(0, 0, 0, .5);
        border-radius: 50%;
    }

    .share-pop {
        height: 300upx;
        width: 100%;
        display: flex;
    }

    .share-item {
        flex: 1;
        text-align: center;
        font-size: 26upx;
        color: #333;
        padding: 20upx 0;
    }

    /* .share-item image{
    width: 120upx;
    height: 120upx;
} */
    .comment-none {
        text-align: center;
        padding: 200upx 0;
    }

    .comment-none-img {
        width: 274upx;
        height: 274upx;
    }

    .price-salesvolume {
        width: 100%;
        padding: 0 0 0 26upx;
        overflow: hidden;
        color: #A5A5A5;
        background-color: rgb(252, 226, 80);
        position: relative;
    }

    .commodity-price {
        width: 224upx;
        display: inline-block;
        float: left;
    }

    .current-price {
        font-size: 40upx;
        color: #FF7159;
        display: block;
        line-height: 1.5;
    }

    .cost-price {
        font-size: 26upx;
        text-decoration: line-through;
        /* margin-left: 8rpx; */
        display: block;
    }

    .commodity-salesvolume {
        width: 240upx;
        display: inline-block;
        font-size: 22upx;
        float: left;
        padding: 16upx 0;
    }

    .commodity-salesvolume>text {
        display: block;
    }

    .commodity-time-img {
        display: block;
        width: 0;
        height: 0;
        border-width: 56upx 28upx 56upx 0;
        border-style: solid;
        border-color: transparent #FF7159 transparent transparent;
        /*透明 黄 透明 透明 */
        position: absolute;
        top: 0px;
        left: 462upx;
    }

    .commodity-time {
        display: inline-block;
        width: 260upx;
        text-align: center;
        font-size: 24upx;
        background-color: #FF7159;
        padding: 16upx 0 18upx;
        color: #FF7159;
    }

    .commodity-time>text {
        color: rgb(252, 226, 80);
    }


    .nav-back {
        width: 100%;
        height: 44px;
        /* #ifndef MP-WEIXIN */
        padding: 12px 12px 0;
        /* #endif */
        /* #ifdef MP-WEIXIN */
        padding: 26px 12px 0;
        /* #endif */
        
        position: fixed;
        top: 0;
        background-color: rgba(255, 255, 255, 0);
        z-index: 98;
    }

    .back-btn {
        height: 32px;
        width: 32px;
        border-radius: 50%;
        background-color: rgba(255, 255, 255, 0.8);
    }

    .back-btn .icon {
        height: 20px;
        width: 20px;
        position: relative;
        top: 50%;
        left: 46%;
        transform: translate(-50%, -50%);
    }
    .commodity-day>text {
        display: inline-block;
        background-color: rgb(255, 212, 176);
        color: rgb(255, 115, 0);
        padding: 0 6upx;
        border-radius: 6upx;
    }

    .tl {
        width: 70% !important;
    }

    .group-swiper {
        /* padding: 20upx 26upx; */
    }

    .group-swiper-c {
        height: 242upx;
    }

    .group-swiper-c .swiper-item .cell-item {
        height: 50%;
    }

    .group-swiper-c .swiper-item .cell-item .user-head-img {
        width: 80upx;
        height: 80upx;
        border-radius: 50%;
    }

    .group-swiper-c .swiper-item .cell-item .cell-hd-title {
        position: absolute;
        top: 50%;
        left: 100upx;
        transform: translateY(-50%);
        max-width: 260upx;
        width: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .group-swiper-c .swiper-item .cell-item .cell-item-bd {
        min-width: 150upx;
        max-width: 150upx
    }

    .group-swiper-c .swiper-item .cell-item .cell-item-ft .btn {
        font-size: 26upx;
        color: #fff;
        background-color: #FF7159;
        /* padding: 0; */
        text-align: center;
    }
</style>
index.vue
<template>
    <view class="content">
        
        <view class="nav-back">
            <view class="back-btn" @click="backBtn()">
                <image class="icon" src="/static/image/back-black.png" mode=""></image>
            </view>
        </view>
        

        <view class="content-top">

            <!-- 轮播图 -->
            <view class='swiper'>
                <swiper class="swiper-c" :indicator-dots="swiper.indicatorDots" :autoplay="swiper.autoplay" :interval="swiper.interval"
                 :duration="swiper.duration">
                    <swiper-item class="have-none" v-for="(item, index) in goodsInfo.album" :key="index" @click="clickImg(item)">
                        <image class='' :src='item' mode="aspectFill"></image>
                    </swiper-item>
                </swiper>
            </view>
            <!-- 轮播图end -->

            <view class='cell-group'>
                <view class='cell-item goods-top'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title goods-price red-price'>¥{{ product.price }}</view>
                        <view class='cell-hd-title goods-price cost-price' v-if="parseFloat(product.mktprice)>0">¥{{ product.mktprice }}</view>
                    </view>
                    <view class='cell-item-ft'>
                        <text>{{ goodsInfo.buy_count }} 人已购买</text>
                    </view>
                </view>

                <view class='cell-item goods-details'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>
                            <view class="color-3 fsz28 cell-hd-title-view">
                                {{ product.name }}
                            </view>
                            <text v-if="goodsInfo.brief" class="color-9 fsz24 ">
                                {{ goodsInfo.brief }}
                            </text>
                        </view>
                    </view>
                    <view class='cell-item-ft'>
                        <image class='cell-ft-next icon' @click="goShare()" src='/static/image/share.png'></image>
                    </view>
                </view>

                <!-- 促销 -->
                <view class='cell-item goods-title-item' v-if="promotion.length">
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>促销</view>
                    </view>
                    <view class='cell-item-bd'>
                        <view class="romotion-tip">
                            <view class="romotion-tip-item" :class="item.type !== 2 ? 'bg-gray' : ''" v-for="(item, index) in promotion"
                             :key="index">
                                {{ item.name }}
                            </view>
                        </view>
                    </view>
                </view>
                <!-- 促销end -->

                <!-- 规格 -->
                <view class='cell-item goods-title-item' v-if="isSpes">
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>规格</view>
                    </view>
                    <view class='cell-item-bd' @click="toshow()">
                        <text class='cell-bd-text'>{{ product.spes_desc }}</text>
                    </view>
                </view>
                <!-- 规格end -->

                <view class='cell-item goods-title-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>说明</view>
                    </view>
                    <view class='cell-item-bd'>
                        <view class="cell-bd-view">
                            <image class="goods-title-item-ic" src="/static/image/ic-dui.png" mode=""></image>
                            <text class="cell-bd-text">24小时内发货</text>
                        </view>
                        <view class="cell-bd-view">
                            <image class="goods-title-item-ic" src="/static/image/ic-dui.png" mode=""></image>
                            <text class="cell-bd-text">7天拆封无条件退货</text>
                        </view>
                    </view>
                </view>
            </view>

            <view class="goods-content">
                <uni-segmented-control :current="current" :values="items" @clickItem="onClickItem" style-type="text" active-color="#333"></uni-segmented-control>
                <view class="goods-content-c">
                    <view class="goods-detail" v-show="current === 0">
                        <jshopContent :content="goodsInfo.intro" v-if="goodsInfo.intro"></jshopContent>
                    </view>
                    <view class="goods-parameter" v-show="current === 1">
                        <view class='cell-group' v-if="goodsParams.length">
                            <view class='cell-item' v-for="(item, index) in goodsParams" :key="index">
                                <view class='cell-item-hd'>
                                    <view class='cell-hd-title'>{{ item.name }}</view>
                                </view>
                                <view class='cell-item-bd'>
                                    <text class='cell-bd-text'>{{ item.value }}</text>
                                </view>
                            </view>
                            <!--                             <view class='cell-item'>
                                <view class='cell-item-hd'>
                                    <view class='cell-hd-title'>保修政策</view>
                                </view>
                                <view class='cell-item-bd'>
                                    <view class="cell-bd-view">
                                        <text class="cell-bd-text">二十日内包修理或换货</text>
                                    </view>
                                    <view class="cell-bd-view">
                                        <text class="cell-bd-text">一年内包修理</text>
                                    </view>
                                </view>
                            </view> -->
                        </view>
                    </view>
                    <view class="goods-assess" v-show="current === 2">
                        <view v-if="goodsComments.list.length">
                            <view class="goods-assess-item" v-for="(item, index) in goodsComments.list" :key="index">
                                <view class='cell-group'>
                                    <view class='cell-item goods-title-item'>
                                        <view class='cell-item-hd'>
                                            <image class='user-head-img' :src='item.user.avatar' mode="aspectFill"></image>
                                        </view>
                                        <view class='cell-item-bd'>
                                            <view class="cell-bd-view">
                                                <text class="cell-bd-text">{{ (item.user.nickname && item.user.nickname != '')?item.user.nickname:item.user.mobile }}</text>
                                                <view class="cell-bd-text-right">
                                                    <uni-rate size="16" disabled="true" :value="item.score"></uni-rate>
                                                </view>
                                            </view>
                                            <view class="cell-bd-view">
                                                <text class="cell-bd-text color-9" style="margin-right: 16upx;">{{ item.ctime }}</text>
                                                <text class="cell-bd-text color-9">{{ item.addon }}</text>
                                            </view>
                                        </view>
                                    </view>
                                </view>
                                <view class="gai-body">
                                    <view class="gai-body-text">
                                        {{ item.content }}
                                    </view>
                                    <view class="gai-body-img" v-if="item.images_url.length">
                                        <image :src="img" mode="aspectFill" v-for="(img, key) in item.images_url" :key="key" @click="clickImg(img)"></image>
                                    </view>
                                    <view class="seller-content" v-if="item.seller_content">
                                        <view class="seller-content-top">
                                            <image class="seller-content-img" src="/static/image/seller-content.png"></image>掌柜回复
                                        </view>
                                        {{item.seller_content}}
                                    </view>
                                </view>
                            </view>
                            <uni-load-more :status="goodsComments.loadStatus"></uni-load-more>
                        </view>
                        <view class="comment-none" v-else>
                            <image class="comment-none-img" src="/static/image/order.png" mode=""></image>
                        </view>
                    </view>
                </view>
            </view>
        </view>

        <lvv-popup position="bottom" ref="share">

            <!-- #ifdef H5 -->
            <shareByH5 :goodsId="goodsInfo.id" :shareImg="goodsInfo.image_url" :shareTitle="goodsInfo.name" :shareContent="goodsInfo.brief"
             :shareHref="shareHref" @close="closeShare()"></shareByH5>
            <!-- #endif -->

            <!-- #ifdef MP-WEIXIN -->
            <shareByWx :goodsId="goodsInfo.id" :shareImg="goodsInfo.image_url" :shareTitle="goodsInfo.name" :shareContent="goodsInfo.brief"
             :shareHref="shareHref" @close="closeShare()"></shareByWx>
            <!-- #endif -->

            <!-- #ifdef MP-ALIPAY -->
            <shareByAli :goodsId="goodsInfo.id" :shareImg="goodsInfo.image_url" :shareTitle="goodsInfo.name" :shareContent="goodsInfo.brief"
             :shareHref="shareHref" @close="closeShare()"></shareByAli>
            <!-- #endif -->

            <!-- #ifdef APP-PLUS -->
            <shareByApp :goodsId="goodsInfo.id" :shareImg="goodsInfo.image_url" :shareTitle="goodsInfo.name" :shareContent="goodsInfo.brief"
             :shareHref="shareHref" @close="closeShare()"></shareByApp>
            <!-- #endif -->

        </lvv-popup>

        <!-- 弹出层 -->
        <lvv-popup position="bottom" ref="lvvpopref">
            <view style="width: 100%;max-height: 804upx;background: #FFFFFF;position: absolute;left:0;bottom: 0;">
                <view class="pop-c">
                    <view class="pop-t">
                        <view class='goods-img'>
                            <image :src='product.image_path' mode='aspectFill'></image>
                        </view>
                        <view class='goods-information'>
                            <view class='pop-goods-name'>{{ product.name }}</view>
                            <view class='pop-goods-price red-price'>¥ {{ product.price }}</view>
                        </view>
                        <view class='close-btn' @click="toclose()">
                            <image src='/static/image/close.png'></image>
                        </view>
                    </view>
                    <scroll-view class="pop-m" scroll-y="true" style="max-height: 560upx;">
                        <spec :spesData="product.default_spes_desc" ref="spec" @changeSpes="changeSpes"></spec>
                        <view class="goods-number">
                            <text class="pop-m-title">数量</text>
                            <view class="pop-m-bd-in">
                                <uni-number-box :min="minNums" :max="product.stock" :value="buyNum" @change="bindChange"></uni-number-box>
                            </view>
                        </view>
                    </scroll-view>
                    <view class="pop-b">
                        <!-- <button class='btn btn-square btn-g btn-half' @click="addToCart">加入购物车</button>
                        <button class='btn btn-square btn-b btn-half' @click="buyNow">立即购买</button> -->
                        <button class='btn btn-square btn-b btn-all' hover-class="btn-hover2" @click="clickHandle()" :disabled='submitStatus'
                         :loading='submitStatus' v-if="product.stock">确定</button>
                        <button class='btn btn-square btn-g btn-all' v-else>已售罄</button>
                    </view>
                </view>
            </view>
        </lvv-popup>
        <!-- 弹出层end -->

        <div id="qrCode" ref="qrCodeDiv"></div>
        <!-- 底部按钮 -->
        <view class="goods-bottom">
            <view class="goods-bottom-ic" @click="collection">
                <image class="icon" :src="isfav ? favLogo[1] : favLogo[0]" mode=""></image>
                <view v-if="!isfav">收藏</view>
                <view v-if="isfav">已收藏</view>
            </view>

            <view class="goods-bottom-ic" @click="redirectCart">
                <view class="badge color-f" v-if="cartNums">{{ cartNums }}</view>
                <image class="icon" src="/static/image/ic-me-car.png" mode=""></image>
                <view>购物车</view>
            </view>
            <button class='btn btn-square btn-g' @click="toshow(1)" hover-class="btn-hover2">加入购物车</button>
            <button class='btn btn-square btn-b' @click="toshow(2)" hover-class="btn-hover2">立即购买</button>
        </view>
        <!-- 底部按钮end -->

        <!-- 右边浮动球 -->
        <!-- <view class="right-ball">
            <view class="" @click="goIndex()">
                <image class="icon" src="/static/image/tab-ic-hom-selected.png" mode=""></image>
            </view>
        </view> -->
        <uni-fab :pattern="pattern" :content="content" :horizontal="horizontal" :vertical="vertical" :direction="direction"
         @trigger="trigger"></uni-fab>
    </view>
</template>

<script>
    import uniSegmentedControl from "@/components/uni-segmented-control/uni-segmented-control.vue";
    import lvvPopup from '@/components/lvv-popup/lvv-popup.vue';
    import uniNumberBox from "@/components/uni-number-box/uni-number-box.vue";
    import uniRate from "@/components/uni-rate/uni-rate.vue";
    import uniLoadMore from '@/components/uni-load-more/uni-load-more.vue';
    import uniFab from '@/components/uni-fab/uni-fab.vue';
    import {
        get
    } from '@/config/db.js';
    import {
        apiBaseUrl
    } from '@/config/config.js'
    import spec from '@/components/spec/spec.vue'
    // #ifdef H5
    import shareByH5 from '@/components/share/shareByh5.vue'
    // #endif
    // #ifdef MP-WEIXIN
    import shareByWx from '@/components/share/shareByWx.vue'
    // #endif
    // #ifdef MP-ALIPAY
    import shareByAli from '@/components/share/shareByAli.vue'
    // #endif
    // #ifdef APP-PLUS
    import shareByApp from '@/components/share/shareByApp.vue'
    // #endif
    import jshopContent from '@/components/jshop/jshop-content.vue'//视频和文本解析组件
    
    export default {
        components: {
            uniSegmentedControl,
            lvvPopup,
            uniNumberBox,
            uniRate,
            uniLoadMore,
            uniFab,
            spec,
            jshopContent,
            // #ifdef H5
            shareByH5,
            // #endif
            // #ifdef MP-WEIXIN
            shareByWx,
            // #endif
            // #ifdef MP-ALIPAY
            shareByAli,
            // #endif
            // #ifdef APP-PLUS
            shareByApp,
            // #endif
        },
        data() {
            return {
                myShareCode: '', //分享Code
                swiper: {
                    indicatorDots: true,
                    autoplay: true,
                    interval: 3000,
                    duration: 800,
                }, // 轮播图属性设置
                items: ['图文详情', '商品参数', '买家评论'],
                current: 0, // init tab位
                goodsId: 0, // 商品id
                goodsInfo: {}, // 商品详情
                cartNums: 0, // 购物车数量
                product: {}, // 规格详情
                goodsParams: [], // 商品参数信息
                goodsComments: {
                    loadStatus: 'more',
                    page: 1,
                    limit: 5,
                    list: []
                }, // 商品评论信息
                buyNum: 1, // 选定的购买数量
                minBuyNum: 1, // 最小可购买数量
                type: 2, // 1加入购物车 2购买
                isfav: false, // 商品是否收藏
                favLogo: [
                    '/static/image/ic-me-collect.png',
                    '/static/image/ic-me-collect2.png'
                ],
                horizontal: 'right', //右下角弹出按钮
                vertical: 'bottom',
                direction: 'vertical',
                pattern: {
                    color: '#7A7E83',
                    backgroundColor: '#fff',
                    selectedColor: '#007AFF',
                    buttonColor: "#FF7159"
                },
                content: [{
                        iconPath: '/static/image/tab-ic-hom-selected.png',
                        selectedIconPath: '/static/image/tab-ic-hom-unselected.png',
                        // text: '首页',
                        active: false,
                        url: '/pages/index/index'
                    },
                    {
                        iconPath: '/static/image/tab-ic-me-selected.png',
                        selectedIconPath: '/static/image/tab-ic-me-unselected.png',
                        // text: '个人中心',
                        active: false,
                        url: '/pages/member/index/index'
                    }
                ],
                submitStatus: false
            }
        },
        onLoad(options) {
            //获取商品ID
            if (options.id != '') {
                this.goodsId = options.id;
            }

            if (this.goodsId) {
                this.getGoodsDetail();
                this.getGoodsParams();
                this.getGoodsComments();
            } else {
                this.$common.errorToShow('获取失败', () => {
                    uni.navigateBack({
                        delta: 1
                    });
                });
            }

            // 获取购物车数量
            this.getCartNums();
            this.getMyShareCode();
        },
        onShow(){
            this.submitStatus = false;
        },
        computed: {
            // 规格切换计算规格商品的 可购买数量
            minNums() {
                return this.product.stock > this.minBuyNum ? this.minBuyNum : this.product.stock;
            },
            // 判断商品是否是多规格商品  (为了兼容小程序 只能写在计算属性里面了)
            isSpes() {
                if (this.product.hasOwnProperty('default_spes_desc') && Object.keys(this.product.default_spes_desc).length) {
                    return true;
                } else {
                    return false;
                }
            },
            // 优惠信息重新组装
            promotion() {
                let arr = [];
                if (this.product.promotion_list) {
                    for (let k in this.product.promotion_list) {
                        arr.push(this.product.promotion_list[k]);
                    }
                }
                return arr;
            },
            shareHref() {
                let pages = getCurrentPages()
                let page = pages[pages.length - 1]
                // #ifdef H5 || MP-WEIXIN || APP-PLUS || APP-PLUS-NVUE
                return apiBaseUrl + 'wap/' + page.route + '?id=' + this.goodsId;
                // #endif

                // #ifdef MP-ALIPAY
                return apiBaseUrl + 'wap/' + page.__proto__.route + '?id=' + this.goodsId;
                // #endif
            }
        },
        onReachBottom() {
            if (this.current === 2 && this.goodsComments.loadStatus === 'more') {
                this.getGoodsComments();
            }
        },
        methods: {
            // 返回上一页
            backBtn() {
                uni.navigateBack({
                    delta: 1
                });
            },
            // 获取商品详情
            getGoodsDetail() {
                let data = {
                    id: this.goodsId
                }

                // 如果用户已经登录 要传用户token
                let userToken = this.$db.get("userToken");

                if (userToken) {
                    data['token'] = userToken;
                }

                this.$api.goodsDetail(data, res => {
                    if (res.status == true) {
                        let info = res.data;
                        let products = res.data.product;

                        //var htmlString = info.intro; //replace(/\\/g, "").replace(/<img/g, "<img style=\"display:none;\"")
                        //info.intro = htmlParser(htmlString);
                        this.goodsInfo = info;
                        this.isfav = this.goodsInfo.isfav === 'true' ? true : false;
                        this.product = this.spesClassHandle(products);



                        // 判断如果登录用户添加商品浏览足迹
                        if (userToken) {
                            this.goodsBrowsing();
                        }
                    } else {
                        this.$common.errorToShow(res.msg, () => {
                            uni.navigateBack({
                                delta: 1
                            });
                        })
                    }
                })
            },
            // 获取购物车数量    
            getCartNums() {
                let userToken = this.$db.get("userToken");
                if (userToken && userToken != '') {
                    // 获取购物车数量
                    this.$api.getCartNum({}, res => {
                        if (res.status) {
                            this.cartNums = res.data;
                        }
                    })
                }
            },
            // 显示modal弹出框
            toshow(type) {
                this.type = type;
                this.$refs.lvvpopref.show();
            },
            // 关闭modal弹出框
            toclose() {
                this.$refs.lvvpopref.close();
            },
            // 切换商品规格
            changeSpes(obj) {
                let index = obj.v;
                let key = obj.k;

                if (this.product.default_spes_desc[index][key].hasOwnProperty('product_id') && this.product.default_spes_desc[index]
                    [key].product_id) {
                    let data = {
                        'id': this.product.default_spes_desc[index][key].product_id
                    };
                    let userToken = this.$db.get("userToken");
                    if (userToken) {
                        data['token'] = userToken;
                    }
                    this.$api.getProductInfo(data, res => {
                        if (res.status == true) {
                            // 切换规格判断可购买数量
                            this.buyNum = res.data.stock > this.minBuyNum ? this.minBuyNum : res.data.stock;
                            this.product = this.spesClassHandle(res.data);
                        }
                    });
                    uni.showLoading({
                        title: '加载中'
                    });
                    setTimeout(function() {
                        uni.hideLoading();
                    }, 1000);
                }
            },
            // 多规格样式统一处理
            spesClassHandle(products) {
                // 判断是否是多规格 (是否有默认规格)
                if (products.hasOwnProperty('default_spes_desc')) {
                    let spes = products.default_spes_desc;
                    for (let key in spes) {
                        for (let i in spes[key]) {
                            if (spes[key][i].hasOwnProperty('is_default') && spes[key][i].is_default === true) {
                                this.$set(spes[key][i], 'cla', 'pop-m-item selected');
                            } else if (spes[key][i].hasOwnProperty('product_id') && spes[key][i].product_id) {
                                this.$set(spes[key][i], 'cla', 'pop-m-item not-selected');
                            } else {
                                this.$set(spes[key][i], 'cla', 'pop-m-item none');
                            }
                        }
                    }
                    products.default_spes_desc = spes;
                }
                return products;
            },
            // 购买数量加减操作
            bindChange(val) {
                this.buyNum = val;
            },
            // 商品收藏/取消
            collection() {
                let data = {
                    goods_id: this.goodsInfo.id
                }
                this.$api.goodsCollection(data, res => {
                    if (res.status) {
                        this.isfav = !this.isfav;
                        this.$common.successToShow(res.msg);
                    } else {
                        this.$common.errorToShow(res.msg);
                    }
                })
            },
            // tab点击切换
            onClickItem(index) {
                if (this.current !== index) {
                    this.current = index;
                }
            },
            // 获取商品参数信息
            getGoodsParams() {
                this.$api.goodsParams({
                    id: this.goodsId
                }, res => {
                    if (res.status == true) {
                        this.goodsParams = res.data;
                    }
                })
            },
            // 获取商品评论信息
            getGoodsComments() {
                let data = {
                    page: this.goodsComments.page,
                    limit: this.goodsComments.limit,
                    goods_id: this.goodsId
                }

                this.goodsComments.loadStatus = 'loading';

                this.$api.goodsComment(data, res => {
                    if (res.status == true) {
                        let _list = res.data.list;
                        let count = res.data.count;
                        this.items = ['图文详情', '商品参数', '买家评论(' + count + ')']
                        // 如果评论没有图片 在这块作处理否则控制台报错
                        _list.forEach(item => {
                            item.ctime = this.$common.timeToDate(item.ctime, true);
                            if (!item.hasOwnProperty('images_url')) {
                                this.$set(item, 'images_url', [])
                            }
                        });

                        this.goodsComments.list = [...this.goodsComments.list, ..._list];
                        // 根据count数量判断是否还有数据
                        if (res.data.count > this.goodsComments.list.length) {
                            this.goodsComments.loadStatus = 'more';
                            this.goodsComments.page++;
                        } else {
                            this.goodsComments.loadStatus = 'noMore';
                        }
                    } else {
                        this.$common.errorToShow(res.msg);
                    }
                })
            },
            // 添加商品浏览足迹
            goodsBrowsing() {
                let data = {
                    goods_id: this.goodsInfo.id
                }

                this.$api.addGoodsBrowsing(data, res => {});
            },
            // 加入购物车
            addToCart() {
                if (this.buyNum > 0) {
                    let data = {
                        product_id: this.product.id,
                        nums: this.buyNum
                    }
                    this.$api.addCart(data, res => {
                        if (res.status) {
                            this.toclose(); // 关闭弹出层
                            this.getCartNums(); // 获取购物车数量
                            this.$common.successToShow(res.msg);
                        } else {
                            this.$common.errorToShow(res.msg);
                        }
                        this.submitStatus = false;
                    })
                } else {
                    this.submitStatus = false;
                }
            },
            // 立即购买
            buyNow() {
                if (this.buyNum > 0) {
                    let data = {
                        product_id: this.product.id,
                        nums: this.buyNum,
                        type: 2 // 区分加入购物车和购买
                    }

                    this.$api.addCart(data, res => {
                        if (res.status) {
                            this.toclose();
                            let cartIds = res.data;
                            this.$common.navigateTo('/pages/goods/place-order/index?cart_ids=' + JSON.stringify(cartIds));
                        }
                        this.submitStatus = false;
                    })
                } else {
                    this.submitStatus = false;
                }
            },
            // 购物车页面跳转
            redirectCart() {
                uni.switchTab({
                    url: '/pages/cart/index/index'
                });
            },
            // 点击弹出框确定按钮事件处理
            clickHandle() {
                this.submitStatus = true;
                this.type === 1 ? this.addToCart() : this.buyNow();
            },
            // 右下角按钮
            //         goIndex(){
            //             uni.switchTab({
            //                 url:'../../index/index'
            //             });
            //         },
            trigger(e) {
                // console.log(e);
                this.content[e.index].active = !e.item.active;
                //             uni.showModal({
                //                 title: '提示',
                //                 content: `您${this.content[e.index].active?'选中了':'取消了'}${e.item.text}`,
                //                 success: function(res) {
                //                     if (res.confirm) {
                //                         console.log('用户点击确定');
                //                     } else if (res.cancel) {
                //                         console.log('用户点击取消');
                //                     }
                //                 }
                //             });
                uni.switchTab({
                    url: e.item.url
                })
            },
            // 跳转到h5分享页面
            goShare() {
                this.$refs.share.show();
            },
            closeShare() {
                this.$refs.share.close();
            },
            // 图片点击放大
            clickImg(imgs) {
                // 预览图片
                uni.previewImage({
                    urls: imgs.split()
                });
            },
            getMyShareCode() {
                let userToken = this.$db.get("userToken");
                if (userToken && userToken != '') {
                    // 获取我的分享码
                    this.$api.shareCode({}, res => {
                        if (res.status) {
                            this.myShareCode = res.data ? res.data : '';
                        }
                    });
                }
            }
        },
        //分享
        onShareAppMessage() {
            let myInviteCode = this.myShareCode ? this.myShareCode : '';
            let ins = this.$common.shareParameterDecode('type=2&id=' + this.goodsInfo.id + '&invite=' + myInviteCode);
            let path = '/pages/share/jump?scene=' + ins;
            return {
                title: this.goodsInfo.name,
                // #ifdef MP-ALIPAY
                desc: this.goodsInfo.brief,
                // #endif
                imageUrl: this.goodsInfo.album[0],
                path: path
            }
        }
    }
</script>

<style>
    .swiper {
        height: 750upx;
    }

    .goods-top {
        border-bottom: 0;
    }

    .goods-top .goods-price {
        font-size: 38upx;
    }

    .cost-price {
        font-size: 28upx !important;
        bottom: -10upx;
        color: #999;
        text-decoration: line-through;
    }

    .goods-top .cell-item-ft {
        font-size: 20upx;
        color: #666;
    }

    .goods-details {
        padding-top: 0;
    }

    .goods-details .cell-hd-title {
        width: 620upx;
    }

    .goods-details .cell-hd-title .cell-hd-title-view {
        width: 100%;
        display: -webkit-box;
        -webkit-box-orient: vertical;
        -webkit-line-clamp: 2;
        overflow: hidden;
    }

    .goods-details .cell-hd-title .cell-hd-title-view:last-child {
        margin-top: 10upx;
    }

    .goods-details .cell-item-ft {
        top: 24upx;
    }

    .goods-title-item .cell-item-hd {
        min-width: 60upx;
        color: #666;
        font-size: 24upx;
    }

    .goods-title-item .cell-item-bd {
        color: #333;
        font-size: 24upx;
    }

    .goods-title-item .cell-bd-text {
        bottom: 0;
    }

    .cell-bd-view {
        position: relative;
        overflow: hidden;
    }

    .cell-bd-view:first-child {
        margin-bottom: 8upx;
    }

    .goods-title-item-ic {
        width: 22upx;
        height: 22upx;
        position: absolute;
        top: 50%;
        transform: translateY(-50%);
        /* #ifdef MP-ALIPAY */
        background-size: 100% 100%;
        /* #endif */
    }

    .cell-bd-view .cell-bd-text {
        margin-left: 30upx;
    }

    .goods-content {
        margin-top: 26upx;
        background-color: #fff;
        padding: 26upx 0;
    }

    .goods-content-c {
        margin-top: 20upx;
    }

    .goods-parameter {
        padding: 10upx 26upx;
    }

    .goods-bottom,
    .pop-b {
        background-color: #fff;
        position: fixed;
        bottom: 0;
        height: 90upx;
        width: 100%;
        overflow: hidden;
        box-shadow: 0 0 20upx #ccc;

    }

    .goods-bottom button {
        height: 100%;
        width: 35%;
    }

    .goods-bottom-ic {
        display: inline-block;
        position: relative;
        text-align: center;
        height: 100%;
        width: 15%;
        float: left;
        font-size: 22upx;
        color: #666;
    }

    .goods-bottom-ic .icon {
        position: relative;
        top: 6upx;
        /* left: -6upx; */
        /* #ifdef MP-ALIPAY */
        background-size: 100% 100%;
        /* #endif */
    }

    .goods-bottom .btn-g {
        color: #333;
        background-color: #D9D9D9;
    }

    .goods-parameter .cell-item {
        border-bottom: none;
        margin-left: 0;
    }

    .goods-parameter .cell-item-hd {
        color: #333;
        font-size: 24upx;
    }

    .goods-parameter .cell-item-bd {
        color: #999;
    }

    .goods-parameter .cell-item-bd .cell-bd-text {
        bottom: 0;
    }

    .goods-parameter .cell-bd-text {
        margin-left: 0;
    }

    .pop-t {
        position: relative;
        padding: 30upx 26upx;
        border-bottom: 2upx solid #f3f3f3;
        /* box-shadow: 0 0 20upx #ccc; */
    }

    .goods-img {
        width: 160upx;
        height: 160upx;
        position: absolute;
        top: -20upx;
        background-color: #fff;
        border-radius: 6upx;
        border: 2upx solid #fff;

    }

    .goods-img image {
        height: 100%;
        width: 100%;
    }

    .goods-information {
        width: 420upx;
        display: inline-block;
        margin-left: 180upx;
    }

    .pop-goods-name {
        width: 100%;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
        display: block;
        font-size: 24upx;
        margin-bottom: 20upx;
    }

    .pop-goods-price {
        font-size: 30upx;
    }

    .close-btn {
        width: 40upx;
        height: 40upx;
        border-radius: 50%;
        display: inline-block;
        position: absolute;
        right: 30upx;
    }

    .close-btn image {
        width: 100%;
        height: 100%;
    }

    .pop-m {
        font-size: 28upx;
        margin-bottom: 90upx;
    }

    .goods-specs,
    .goods-number {
        padding: 26upx;
        border-top: 1px solid #f3f3f3;
    }

    .goods-specs:first-child {
        border: none;
    }

    .pop-m-title {
        margin-right: 10upx;
        color: #666;
    }

    .pop-m-bd {
        overflow: hidden;
        margin-top: 10upx;
    }

    .pop-m-item {
        display: inline-block;
        float: left;
        padding: 6upx 16upx;
        background-color: #fff;
        color: #333;
        margin-right: 16upx;
        margin-bottom: 10upx;
    }

    .selected {
        border: 2upx solid #333;
        background-color: #333;
        color: #fff;
    }

    .not-selected {
        border: 2upx solid #ccc;
    }

    .none {
        border: 2upx dashed #ccc;
        color: #888;
    }

    .pop-m-bd-in {
        display: inline-block;
    }

    .badge {
        top: 2upx;
        left: 62upx;
    }

    .goods-assess .user-head-img {
        width: 80upx;
        height: 80upx;
        border-radius: 50%;
    }

    .goods-assess .cell-item-bd {
        padding-right: 0;
    }

    .goods-assess .cell-bd-text {
        margin: 0;
    }

    .goods-assess .cell-bd-text.color-9 {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        max-width: 440upx;
    }

    .gai-body {}

    .gai-body-text {
        font-size: 26upx;
        color: #333;
        padding: 0 26upx;
        word-wrap: break-word;
    }

    .gai-body-img {
        overflow: hidden;
        padding: 20upx 26upx;
    }

    .gai-body-img image {
        width: 220upx;
        height: 220upx;
        float: left;
        margin-right: 19upx;
        margin-bottom: 18upx;
    }

    .gai-body-img image:nth-child(3n) {
        margin-right: 0;
    }

    .redstar {
        width: 24rpx;
        height: 24rpx;
        padding: 2rpx;
    }

    .mask-share-wechat {
        display: inline-block;
        background-color: #fff;
        padding: 0;
    }

    .mask-share-wechat:after {
        border: none;
    }

    .right-ball {
        position: fixed;
        right: 30upx;
        bottom: 300upx;
        z-index: 999;
        text-align: center;
        padding: 14upx 0;
        /* line-height: 80upx; */
        width: 80upx;
        height: 80upx;
        font-size: 24upx;
        color: #fff;
        background-color: rgba(0, 0, 0, .5);
        border-radius: 50%;
    }

    .comment-none {
        text-align: center;
        padding: 200upx 0;
    }

    .comment-none-img {
        width: 274upx;
        height: 274upx;
    }


    .price-salesvolume {
        width: 100%;
        padding: 0 0 0 26upx;
        overflow: hidden;
        color: #A5A5A5;
        background-color: rgb(252, 226, 80);
        position: relative;
    }

    .commodity-price {
        width: 224upx;
        display: inline-block;
        float: left;
    }

    .current-price {
        font-size: 40upx;
        color: #FF7159;
        display: block;
        line-height: 1.5;
    }

    .cost-price {
        font-size: 26upx;
        text-decoration: line-through;
        /* margin-left: 8rpx; */
        display: block;
    }

    .commodity-salesvolume {
        width: 240upx;
        display: inline-block;
        font-size: 22upx;
        float: left;
        padding: 16upx 0;
    }

    .commodity-salesvolume>text {
        display: block;
    }

    .commodity-time-img {
        display: block;
        width: 0;
        height: 0;
        border-width: 48upx 28upx 50upx 0;
        border-style: solid;
        border-color: transparent #FF7159 transparent transparent;
        /*透明 黄 透明 透明 */
        position: absolute;
        top: 0px;
        left: 462upx;
    }

    .commodity-time {
        display: inline-block;
        width: 260upx;
        text-align: center;
        font-size: 24upx;
        background-color: #FF7159;
        padding: 16upx 0 18upx;
        color: rgb(250, 233, 0);
    }

    .commodity-time>text {
        display: block;
    }

    .commodity-day {
        font-size: 22upx;
    }

    .commodity-day>text {
        display: inline-block;
        background-color: rgb(255, 212, 176);
        color: rgb(255, 115, 0);
        padding: 0 6upx;
        border-radius: 6upx;
    }

    .nav-back {
        width: 100%;
        height: 44px;
        /* #ifndef MP-WEIXIN */
        padding: 12px 12px 0;
        /* #endif */
        /* #ifdef MP-WEIXIN */
        padding: 26px 12px 0;
        /* #endif */
        
        position: fixed;
        top: 0;
        background-color: rgba(255, 255, 255, 0);
        z-index: 98;
    }

    .back-btn {
        height: 32px;
        width: 32px;
        border-radius: 50%;
        background-color: rgba(255, 255, 255, 0.8);
    }

    .back-btn .icon {
        height: 20px;
        width: 20px;
        position: relative;
        top: 50%;
        left: 46%;
        transform: translate(-50%, -50%);
    }

    .seller-content {
        background-color: #f8f8f8;
        margin: 0 13px 15px;
        padding: 10px;
        color: #6e6e6e;
        border-radius: 4px;
    }

    .seller-content-top {
        font-weight: bold;
        margin-bottom: 6px;
    }

    .seller-content-img {
        width: 20px;
        height: 20px;
        vertical-align: middle;
        margin-right: 4px;
    }
</style>
pintuan.vue
<template>
    <view class="content">
        <view class="nav-back">
            <view class="back-btn" @click="backBtn()">
                <image class="icon" src="/static/image/back-black.png" mode=""></image>
            </view>
        </view>
        
        <view class="content-top">
            <!-- 轮播图 -->
            <view class='swiper'>
                <swiper class="swiper-c" :indicator-dots="swiper.indicatorDots" :autoplay="swiper.autoplay" :interval="swiper.interval"
                 :duration="swiper.duration">
                    <swiper-item class="have-none" v-for="(item, index) in goodsInfo.album" :key="index" @click="clickImg(item)">
                        <!-- {{goodsInfo.album}} -->
                        <image class='' :src='item' mode="aspectFill"></image>
                    </swiper-item>
                </swiper>
            </view>
            <!-- 轮播图end -->

            <view class='cell-group'>
                <!-- 倒计时 -->
                <view class='price-salesvolume' v-if="lasttime.hour!==false">
                    <view class='commodity-price'>
                        <text class='current-price'>¥{{pintuanPrice}}</text>
                        <text class='cost-price' v-if="parseFloat(product.mktprice)>0">¥{{product.mktprice}}</text>
                    </view>
                    <view class='commodity-salesvolume'>
                        <text>已售{{goodsInfo.buy_count}}件/剩余{{product.stock}}件</text>
                        <text>累计销售{{goodsInfo.buy_count}}件</text>
                    </view>

                    <view class='commodity-time' v-if="goodsInfo.pintuan_rule.pintuan_start_status == 1">
                        <text>距结束仅剩</text>
                        <view class='commodity-day'>
                            <uni-countdown textColor="#fce250" :day="lasttime.day" :hour="lasttime.hour" :minute="lasttime.minute" :second="lasttime.second"></uni-countdown>
                        </view>
                    </view>

                    <view class='commodity-time' v-if="goodsInfo.pintuan_rule.pintuan_start_status == 2">
                        <text>即将开团</text>
                        <view class='commodity-day'>
                            <uni-countdown textColor="#fce250" :day="goodsInfo.pintuan_rule.lasttime.day" :hour="goodsInfo.pintuan_rule.lasttime.hour"
                             :minute="goodsInfo.pintuan_rule.lasttime.minute" :second="goodsInfo.pintuan_rule.lasttime.second"></uni-countdown>
                        </view>
                    </view>
                    <view class='commodity-time-img'></view>
                    <!-- <view class='commodity-time'>
                        已结束
                    </view> -->
                </view>
                <!-- 倒计时end -->

                <!-- 分享 -->
                <view class='cell-item goods-details'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>
                            <view class="color-3 fsz28 cell-hd-title-view">
                                {{ product.name }}
                            </view>
                            <view v-if="goodsInfo.brief" class="color-9 fsz24 cell-hd-title-view">
                                {{ goodsInfo.brief }}
                            </view>
                        </view>
                    </view>
                    <view class='cell-item-ft'>
                        <image class='cell-ft-next icon' @click="goShare()" src='/static/image/share.png'></image>
                    </view>
                </view>
                <!-- 分享end -->

                <!-- 促销 -->
                <view class='cell-item goods-title-item' v-if="promotion.length">
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>促销</view>
                    </view>
                    <view class='cell-item-bd'>
                        <view class="romotion-tip">
                            <view class="romotion-tip-item" :class="item.type !== 2 ? 'bg-gray' : ''" v-for="(item, index) in promotion"
                             :key="index">
                                {{ item.name }}
                            </view>
                        </view>
                    </view>
                </view>
                <!-- 促销end -->

                <!-- 规格 -->
                <view class='cell-item goods-title-item' v-if="isSpes">
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>规格</view>
                    </view>
                    <view class='cell-item-bd' @click="toshow()">
                        <text class='cell-bd-text'>{{ product.spes_desc }}</text>
                    </view>
                </view>
                <!-- 规格end -->

                <!-- 说明 -->
                <view class='cell-item goods-title-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>说明</view>
                    </view>
                    <view class='cell-item-bd'>
                        <view class="cell-bd-view">
                            <image class="goods-title-item-ic" src="/static/image/ic-dui.png" mode=""></image>
                            <text class="cell-bd-text">24小时内发货</text>
                        </view>
                        <view class="cell-bd-view">
                            <image class="goods-title-item-ic" src="/static/image/ic-dui.png" mode=""></image>
                            <text class="cell-bd-text">7天拆封无条件退货</text>
                        </view>
                    </view>
                </view>
                <!-- 说明end -->
            </view>

            <!-- 团购拼单 -->
            <view class="cell-group margin-cell-group" v-if="pintuanRecord.length>0">

                <view class='cell-item right-img'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>{{teamCount}}人在拼单,可直接参与</view>
                    </view>
                    <!-- <view class='cell-item-ft' >
                        <image class='cell-ft-next icon' src='/static/image/right.png'></image>
                        <text class='cell-ft-text'>查看更多</text>
                    </view> -->
                </view>
                <view class="group-swiper">
                    <swiper class="group-swiper-c" :class="groupHeight" :indicator-dots="indicatorDots" :autoplay="autoplay" vertical="true"
                     circular="true" :interval="interval" :duration="duration">
                        <swiper-item v-for="(item, index) in pintuanRecord" :key="index">
                            <view class="swiper-item">
                                <view class='cell-item'>
                                    <view class='cell-item-hd'>
                                        <image class="user-head-img cell-hd-icon have-none" :src='item[0].user_avatar' mode=""></image>
                                        <view class="cell-hd-title">
                                            {{item[0].nickname}}
                                        </view>
                                    </view>
                                    <view class='cell-item-bd'>
                                        <view class="cell-bd-view">
                                            <text class="cell-bd-text">还差<text class="red-price">{{item[0].team_nums}}人</text>拼成</text>
                                        </view>
                                        <view class="cell-bd-view">
                                            <view class='commodity-day'>
                                                <text class="fsz24 color-6">剩余:</text>
                                                <uni-countdown color="#666" :day="item[0].remainder_time.day" :hour="item[0].remainder_time.hour" :minute="item[0].remainder_time.minute"
                                                 :second="item[0].remainder_time.second"></uni-countdown>
                                            </view>

                                        </view>
                                    </view>
                                    <view class="cell-item-ft">
                                        <button class="btn" @click="toshow(2,item[0].team_id)">去拼单</button>
                                    </view>
                                    <!-- <view class="cell-item-ft" v-else>
                                        <button class="btn btn-b">拼团中</button>
                                    </view> -->
                                </view>
                                <view class='cell-item' v-if="item[1]">
                                    <view class='cell-item-hd'>
                                        <image class="user-head-img cell-hd-icon have-none" :src='item[1].user_avatar' mode=""></image>
                                        <view class="cell-hd-title">
                                            {{item[1].nickname}}
                                        </view>
                                    </view>
                                    <view class='cell-item-bd'>
                                        <view class="cell-bd-view">
                                            <text class="cell-bd-text">还差<text class="red-price">{{item[1].team_nums}}人</text>拼成</text>
                                        </view>
                                        <view class="cell-bd-view">
                                            <view class='commodity-day'>
                                                <text class="fsz24 color-6">剩余:</text>
                                                <uni-countdown color="#666" :day="item[1].remainder_time.day" :hour="item[1].remainder_time.hour" :minute="item[1].remainder_time.minute"
                                                 :second="item[1].remainder_time.second"></uni-countdown>
                                            </view>

                                        </view>
                                    </view>
                                    <view class="cell-item-ft">
                                        <button class="btn" @click="toshow(2,item[1].id)">去拼单</button>
                                    </view>
                                </view>
                            </view>
                        </swiper-item>
                    </swiper>
                </view>
            </view>
            <view class="cell-group margin-cell-group" v-else="">
                <view class='cell-item right-img'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>暂无开团信息</view>
                    </view>
                </view>
            </view>

            <view class="goods-content">
                <uni-segmented-control :current="current" :values="items" @clickItem="onClickItem" style-type="text" active-color="#333"></uni-segmented-control>
                <view class="goods-content-c">
                    <view class="goods-detail" v-if="current === 0">
                        <jshopContent :content="goodsInfo.intro" v-if="goodsInfo.intro"></jshopContent>
                    </view>
                    <view class="goods-parameter" v-else-if="current === 1">
                        <view class='cell-group' v-if="goodsParams.length">
                            <view class='cell-item' v-for="(item, index) in goodsParams" :key="index">
                                <view class='cell-item-hd'>
                                    <view class='cell-hd-title'>{{ item.name }}</view>
                                </view>
                                <view class='cell-item-bd'>
                                    <text class='cell-bd-text'>{{ item.value }}</text>
                                </view>
                            </view>
                        </view>
                    </view>
                    <view class="goods-assess" v-else-if="current === 2">
                        <view v-if="goodsComments.list.length">
                            <view class="goods-assess-item" v-for="(item, index) in goodsComments.list" :key="index">
                                <view class='cell-group'>
                                    <view class='cell-item goods-title-item'>
                                        <view class='cell-item-hd'>
                                            <image class='user-head-img' :src='item.user.avatar' mode="aspectFill"></image>
                                        </view>
                                        <view class='cell-item-bd'>
                                            <view class="cell-bd-view">
                                                <text class="cell-bd-text">{{ item.user.nickname }}</text>
                                                <view class="cell-bd-text-right">
                                                    <uni-rate size="16" disabled="true" :value="item.score"></uni-rate>
                                                </view>
                                            </view>
                                            <view class="cell-bd-view">
                                                <text class="cell-bd-text color-9" style="margin-right: 16upx;">{{ item.ctime }}</text>
                                                <text class="cell-bd-text color-9">{{ item.addon }}</text>
                                            </view>
                                        </view>
                                    </view>
                                </view>
                                <view class="gai-body">
                                    <view class="gai-body-text">
                                        {{ item.content }}
                                    </view>
                                    <view class="gai-body-img" v-if="item.images_url.length">
                                        <image :src="img" mode="aspectFill" v-for="(img, key) in item.images_url" :key="key" @click="clickImg(img)"></image>
                                    </view>
                                </view>
                            </view>
                            <uni-load-more :status="goodsComments.loadStatus"></uni-load-more>
                        </view>
                        <view class="comment-none" v-else>
                            <image class="comment-none-img" src="/static/image/order.png" mode=""></image>
                        </view>
                    </view>
                </view>
            </view>
        </view>

        <lvv-popup position="bottom" ref="pintuanpop">
            <view class="ig-top" v-if="teamInfo.list.length>0">
                <view class="ig-top-t">
                    <view class="">
                        剩余时间:<uni-countdown :day="teamInfo.team_time.day" :hour="teamInfo.team_time.hour" :minute="teamInfo.team_time.minute"
                         :second="teamInfo.team_time.second"></uni-countdown>
                    </view>
                </view>
                <view class="ig-top-m">
                    <view class="user-head-img-c" v-for="(item, index) in teamInfo.list" :key="index">
                        <view class="user-head-img-tip" v-if="item.id == item.team_id">拼主</view>
                        <image class="user-head-img cell-hd-icon have-none" :src='item.user_avatar' mode=""></image>
                    </view>
                    <view class="user-head-img-c uhihn" v-if="teamInfo.team_nums" v-for="n in teamInfo.team_nums" :key="n"><text>?</text></view>
                </view>
                <view class="ig-top-b">
                    <view class="igtb-top">
                        还差<text class="red-price">{{ teamInfo.team_nums }}</text>人,赶快拼单吧
                    </view>
                    <view class="igtb-mid">
                        <button class="btn" @click="toshow(2,teamInfo.id)">参与拼团</button>
                    </view>
                </view>
            </view>
        </lvv-popup>

        <lvv-popup position="bottom" ref="share">

            <!-- #ifdef H5 -->
            <shareByH5 :shareType='3' :goodsId="goodsInfo.id" :shareImg="goodsInfo.image_url" :shareTitle="goodsInfo.name"
             :shareContent="goodsInfo.brief" :shareHref="shareHref" @close="closeShare()"></shareByH5>
            <!-- #endif -->

            <!-- #ifdef MP-WEIXIN -->
            <shareByWx :shareType='3' :goodsId="goodsInfo.id" :shareImg="goodsInfo.image_url" :shareTitle="goodsInfo.name"
             :shareContent="goodsInfo.brief" :shareHref="shareHref" @close="closeShare()"></shareByWx>
            <!-- #endif -->

            <!-- #ifdef MP-ALIPAY -->
            <shareByAli :shareType='3' :goodsId="goodsInfo.id" :shareImg="goodsInfo.image_url" :shareTitle="goodsInfo.name"
             :shareContent="goodsInfo.brief" :shareHref="shareHref" @close="closeShare()"></shareByAli>
            <!-- #endif -->

            <!-- #ifdef APP-PLUS -->
            <shareByApp :shareType='3' :goodsId="goodsInfo.id" :shareImg="goodsInfo.image_url" :shareTitle="goodsInfo.name"
             :shareContent="goodsInfo.brief" :shareHref="shareHref" @close="closeShare()"></shareByApp>
            <!-- #endif -->

        </lvv-popup>

        <!-- 弹出层 -->
        <lvv-popup position="bottom" ref="lvvpopref">
            <view style="width: 100%;max-height: 804upx;background: #FFFFFF;position: absolute;left:0;bottom: 0;">
                <view class="pop-c">
                    <view class="pop-t">
                        <view class='goods-img'>
                            <image :src='product.image_path' mode='aspectFill'></image>
                        </view>
                        <view class='goods-information'>
                            <view class='pop-goods-name'>{{ product.name }}</view>
                            <view class='pop-goods-price red-price'>¥ {{ price }}</view>
                        </view>
                        <view class='close-btn' @click="toclose()">
                            <image src='/static/image/close.png'></image>
                        </view>
                    </view>
                    <scroll-view class="pop-m" scroll-y="true" style="max-height: 560upx;">
                        <spec :spesData="product.default_spes_desc" ref="spec" @changeSpes="changeSpes"></spec>

                        <view class="goods-number">
                            <text class="pop-m-title">数量</text>
                            <view class="pop-m-bd-in">
                                <uni-number-box :min="minNums" :max="product.stock" :value="buyNum" @change="bindChange"></uni-number-box>
                            </view>
                        </view>
                    </scroll-view>
                    <view class="pop-b">
                        <!-- <button class='btn btn-square btn-g btn-half' @click="addToCart">加入购物车</button>
                        <button class='btn btn-square btn-b btn-half' @click="buyNow">立即购买</button> -->
                        <button class='btn btn-square btn-b btn-all' hover-class="btn-hover2" @click="buyNow()" v-if="product.stock">确定</button>
                        <button class='btn btn-square btn-g btn-all' v-else>已售罄</button>
                    </view>
                </view>
            </view>
        </lvv-popup>
        <!-- 弹出层end -->

        <div id="qrCode" ref="qrCodeDiv"></div>
        <!-- 底部按钮 -->
        <view class="goods-bottom">
            <view class="goods-bottom-ic" @click="collection">
                <image class="icon" :src="isfav ? favLogo[1] : favLogo[0]" mode=""></image>
                <view v-if="!isfav">收藏</view>
                <view v-if="isfav">已收藏</view>
            </view>

            <view class="goods-bottom-ic" @click="redirectCart">
                <view class="badge color-f" v-if="cartNums">{{ cartNums }}</view>
                <image class="icon" src="/static/image/ic-me-car.png" mode=""></image>
                <view>购物车</view>
            </view>
            <button class='btn btn-square btn-g' @click="toshow(1)" hover-class="btn-hover2">
                <view class="btn-content">
                    <view class="color-6">¥{{product.price}}</view>
                    <view class="color-6 fsz24">单独购买</view>
                </view>
            </button>
            <button class='btn btn-square btn-b' @click="toshow(2)" hover-class="btn-hover2" v-if="goodsInfo.pintuan_rule.pintuan_start_status == 1 ">
                <view class="btn-content">
                    <view class="">¥{{pintuanPrice}}</view>
                    <view class="fsz24">发起拼团</view>
                </view>
            </button>
            <button class='btn btn-square btn-b' hover-class="btn-hover2" v-if="goodsInfo.pintuan_rule.pintuan_start_status == 2 ">
                <view class="btn-content">
                    <view class="">¥{{pintuanPrice}}</view>
                    <view class="fsz24">即将开团</view>
                </view>
            </button>
            <button class='btn btn-square btn-b' hover-class="btn-hover2" v-if="goodsInfo.pintuan_rule.pintuan_start_status == 3 ">
                <view class="btn-content">
                    <view class="">¥{{pintuanPrice}}</view>
                    <view class="fsz24">拼团已结束</view>
                </view>
            </button>
        </view>
        <!-- 底部按钮end -->

        <!-- 右边浮动球 -->
        <!-- <view class="right-ball">
            <view class="" @click="goIndex()">
                <image class="icon" src="/static/image/tab-ic-hom-selected.png" mode=""></image>
            </view>
        </view> -->
        <uni-fab :pattern="pattern" :content="content" :horizontal="horizontal" :vertical="vertical" :direction="direction"
         @trigger="trigger"></uni-fab>
    </view>
</template>

<script>
    import uniSegmentedControl from "@/components/uni-segmented-control/uni-segmented-control.vue";
    import lvvPopup from '@/components/lvv-popup/lvv-popup.vue';
    import uniNumberBox from "@/components/uni-number-box/uni-number-box.vue";
    import uniRate from "@/components/uni-rate/uni-rate.vue";
    import uniLoadMore from '@/components/uni-load-more/uni-load-more.vue';
    import uniFab from '@/components/uni-fab/uni-fab.vue';
    import {
        get
    } from '@/config/db.js';
    import {
        apiBaseUrl
    } from '@/config/config.js'
    import uniCountdown from "@/components/uni-countdown/uni-countdown.vue"
    import spec from '@/components/spec/spec.vue'
    // #ifdef H5
    import shareByH5 from '@/components/share/shareByh5.vue'
    // #endif
    // #ifdef MP-WEIXIN
    import shareByWx from '@/components/share/shareByWx.vue'
    // #endif
    // #ifdef MP-ALIPAY
    import shareByAli from '@/components/share/shareByAli.vue'
    // #endif
    // #ifdef APP-PLUS
    import shareByApp from '@/components/share/shareByApp.vue'
    // #endif
    import jshopContent from '@/components/jshop/jshop-content.vue'//视频和文本解析组件
    export default {
        components: {
            uniSegmentedControl,
            lvvPopup,
            uniNumberBox,
            uniRate,
            uniLoadMore,
            uniFab,
            uniCountdown,
            spec,
            jshopContent,
            // #ifdef H5
            shareByH5,
            // #endif

            // #ifdef MP-WEIXIN
            shareByWx,
            // #endif

            // #ifdef MP-ALIPAY
            shareByAli,
            // #endif

            // #ifdef APP-PLUS
            shareByApp,
            // #endif
        },
        data() {
            return {
                myShareCode: '', //分享Code
                swiper: {
                    indicatorDots: true,
                    autoplay: true,
                    interval: 3000,
                    duration: 800,
                }, // 轮播图属性设置
                items: ['图文详情', '商品参数', '买家评论'],
                current: 0, // init tab位
                goodsId: 0, // 商品id
                groupId: 0, // 团购ID
                goodsInfo: {
                    pintuan_rule: {
                        pintuan_start_status: 1
                    }
                }, // 商品详情
                cartNums: 0, // 购物车数量
                product: {}, // 规格详情
                goodsParams: [], // 商品参数信息
                goodsComments: {
                    loadStatus: 'more',
                    page: 1,
                    limit: 5,
                    list: []
                }, // 商品评论信息
                buyNum: 1, // 选定的购买数量
                minBuyNum: 1, // 最小可购买数量
                type: 2, // 1单独购买 2拼团
                isfav: false, // 商品是否收藏
                favLogo: [
                    '/static/image/ic-me-collect.png',
                    '/static/image/ic-me-collect2.png'
                ],
                horizontal: 'right', //右下角弹出按钮
                vertical: 'bottom',
                direction: 'vertical',
                pattern: {
                    color: '#7A7E83',
                    backgroundColor: '#fff',
                    selectedColor: '#007AFF',
                    buttonColor: "#FF7159"
                },
                content: [{
                        iconPath: '/static/image/tab-ic-hom-selected.png',
                        selectedIconPath: '/static/image/tab-ic-hom-unselected.png',
                        // text: '首页',
                        active: false,
                        url: '/pages/index/index'
                    },

                    {
                        iconPath: '/static/image/tab-ic-me-selected.png',
                        selectedIconPath: '/static/image/tab-ic-me-unselected.png',
                        // text: '个人中心',
                        active: false,
                        url: '/pages/member/index/index'
                    },
                ],
                indicatorDots: false,
                autoplay: false,
                interval: 2000,
                duration: 500,
                lasttime: {
                    day: 0,
                    hour: false,
                    minute: 0,
                    second: 0
                }, //购买倒计时
                pintuanPrice: 0,
                discount_amount: 0, //拼团优惠金额
                price: 0,
                teamCount: 0, //已经有多少人拼团
                pintuanRecord: [], //拼团列表
                remainder_time: {
                    day: 0,
                    hour: false,
                    minute: 0,
                    second: 0
                }, //拼团倒计时
                groupHeight: 'groupHeight',
                teamId: 0, //去参团的teamid
                teamInfo: {
                    list: [],
                    team_time: {
                        day: 0,
                        hour: 0,
                        minute: 0,
                        second: 0
                    }, //被邀请拼团倒计时
                },

            }
        },
        onLoad(e) {
            this.goodsId = e.id;
            if (e.team_id) {
                this.teamId = e.team_id;
                this.getTeam(this.teamId)
            }
            if (this.goodsId) {
                this.getGoodsInfo();
                this.getGoodsParams();
                this.getGoodsComments();

            } else {
                this.$common.errorToShow('获取失败', () => {
                    uni.navigateBack({
                        delta: 1
                    });
                });
            }

            // 获取购物车数量
            this.getCartNums();
            this.getMyShareCode();
        },
        onReady() {

        },
        computed: {

            // 规格切换计算规格商品的 可购买数量
            minNums() {
                return this.product.stock > this.minBuyNum ? this.minBuyNum : this.product.stock;
            },
            // 判断商品是否是多规格商品  (为了兼容小程序 只能写在计算属性里面了)
            isSpes() {
                if (this.product.hasOwnProperty('default_spes_desc') && Object.keys(this.product.default_spes_desc).length) {
                    return true;
                } else {
                    return false;
                }
            },
            // 优惠信息重新组装
            promotion() {
                let arr = [];
                if (this.product.promotion_list) {
                    for (let k in this.product.promotion_list) {
                        arr.push(this.product.promotion_list[k]);
                    }
                }
                return arr;
            },
            typeName() {
                return this.goodsInfo.group_type == 3 ? '团购' : '秒杀';
            },
            shareHref() {
                let pages = getCurrentPages()
                let page = pages[pages.length - 1]
                // #ifdef H5 || MP-WEIXIN || APP-PLUS || APP-PLUS-NVUE
                return apiBaseUrl + 'wap/' + page.route + '?id=' + this.goodsId + '&group_id=' + this.groupId;
                // #endif

                // #ifdef MP-ALIPAY
                return apiBaseUrl + 'wap/' + page.__proto__.route + '?id=' + this.goodsId + '&group_id=' + this.groupId;
                // #endif
            }
        },
        onReachBottom() {
            if (this.current === 2 && this.goodsComments.loadStatus === 'more') {
                this.getGoodsComments();
            }
        },
        methods: {
            // 返回上一页
            backBtn() {
                uni.navigateBack({
                    delta: 1
                });
            },
            // 获取商品详情
            getGoodsInfo() {
                let data = {
                    id: this.goodsId
                }
                // 如果用户已经登录 要传用户token
                let userToken = get('userToken');
                if (userToken) {
                    data['token'] = userToken;
                }
                let _this = this;
                _this.$api.pintuanGoodsInfo(data, res => {
                    console.log(res);
                    if (res.status) {
                        if (res.data.length < 1) {
                            _this.$common.errorToShow('该商品不存在,请返回重新选择商品。', () => {
                                uni.navigateBack({
                                    delta: 1
                                });
                            });
                        } else if (res.data.marketable != 1) {
                            _this.$common.errorToShow('该商品已下架,请返回重新选择商品。', () => {
                                uni.navigateBack({
                                    delta: 1
                                });
                            });
                        } else {
                            let info = res.data;
                            _this.goodsInfo = info;
                            let products = res.data.product;
                            _this.discount_amount = parseFloat(info.pintuan_rule.discount_amount).toFixed(2);

                            //products.price = _this.$common.moneySub(products.price,_this.discount_amount);
                            _this.product = _this.spesClassHandle(products);
                            _this.isfav = _this.goodsInfo.isfav === 'true' ? true : false;
                            // _this.pintuanPrice = info.pintuan_price.toFixed(2)
                            _this.pintuanPrice = this.$common.moneySub(this.product.price, this.discount_amount);
                            let timestamp = Date.parse(new Date()) / 1000;

                            let lasttime = res.data.pintuan_rule.etime - timestamp;
                            _this.lasttime = _this.$common.timeToDateObj(lasttime);
                            // 获取拼团记录
                            let pintuan_data = info.pintuan_record;
                            let new_data = new Array();
                            for (var k = 0; k < pintuan_data.length; k++) {
                                pintuan_data[k].remainder_time = _this.$common.timeToDateObj(pintuan_data[k].close_time - timestamp)
                                if (k == 0 || k % 2 == 0) {
                                    if (k + 1 < pintuan_data.length) {
                                        var a = [
                                            pintuan_data[k],
                                            pintuan_data[k + 1]
                                        ];
                                    } else {
                                        var a = [pintuan_data[k]];
                                    }
                                    new_data.push(a);
                                }
                            }
                            pintuan_data.length < 2 ? _this.groupHeight = 'groupHeight' : _this.groupHeight = '';
                            _this.pintuanRecord = new_data;
                            // console.log(new_data);
                            _this.teamCount = info.pintuan_record_nums;
                            // 判断如果登录用户添加商品浏览足迹
                            if (userToken) {
                                _this.goodsBrowsing();
                            }
                        }
                    }
                });
            },

            // 获取通过分享进来的拼团数据
            getTeam(id) {
                this.$api.getOrderPintuanTeamInfo({
                    team_id: id
                }, res => {
                    if (res.status) {
                        this.teamInfo = {
                            list: res.data.teams,
                            current_count: res.data.teams.length,
                            people_number: res.data.people_number,
                            team_nums: res.data.team_nums, //剩余
                            close_time: res.data.close_time, //关闭时间
                            id: res.data.id, //拼团id
                            team_id: res.data.team_id, //拼团团队id
                            rule_id: res.data.rule_id,
                            status: res.data.status
                        };
                        let timestamp = Date.parse(new Date()) / 1000;
                        this.teamInfo.team_time = this.$common.timeToDateObj(res.data.close_time - timestamp);
                        if (res.data.status == 1) {
                            this.pintuanShow();
                        } else {
                            this.teamId = 0;
                        }
                    } else {
                        this.$common.errorToShow(res.msg)
                    }

                });
            },

            // 获取购物车数量    
            getCartNums() {
                let userToken = this.$db.get("userToken");
                if (userToken && userToken != '') {
                    // 获取购物车数量
                    this.$api.getCartNum({}, res => {
                        if (res.status) {
                            this.cartNums = res.data;
                        }
                    });
                }
            },
            // 显示modal弹出框
            toshow(type, team_id) {
                this.type = type;
                if (team_id) {
                    this.teamId = team_id
                }
                if (this.type == 2) {
                    this.price = this.pintuanPrice;
                } else {
                    this.price = this.product.price;
                }
                this.$refs.lvvpopref.show();
            },
            // 关闭modal弹出框
            toclose() {
                this.$refs.lvvpopref.close();
            },
            // 切换商品规格
            changeSpes(obj) {
                let index = obj.v;
                let key = obj.k;
                //type = 1是立即购买,2是拼团购买
                if (this.product.default_spes_desc[index][key].hasOwnProperty('product_id') && this.product.default_spes_desc[index]
                    [key].product_id) {

                    let data = {
                        'id': this.product.default_spes_desc[index][key].product_id
                    };
                    let userToken = this.$db.get("userToken");
                    if (userToken) {
                        data['token'] = userToken;
                    }
                    this.$api.getProductInfo(data, res => {
                        if (res.status == true) {
                            // 切换规格判断可购买数量
                            this.buyNum = res.data.stock > this.minBuyNum ? this.minBuyNum : res.data.stock;
                            this.product = this.spesClassHandle(res.data);
                            //products.price = _this.$common.moneySub(products.price,_this.discount_amount);
                            if (this.type == 2) { //拼团
                                this.price = this.$common.moneySub(this.product.price, this.discount_amount);
                            } else {
                                this.price = this.product.price;
                            }
                        }
                    });
                    uni.showLoading({
                        title: '加载中'
                    });
                    setTimeout(function() {
                        uni.hideLoading();
                    }, 1000);
                }
            },
            // 多规格样式统一处理
            spesClassHandle(products) {
                // 判断是否是多规格 (是否有默认规格)
                if (products.hasOwnProperty('default_spes_desc')) {
                    let spes = products.default_spes_desc;
                    for (let key in spes) {
                        for (let i in spes[key]) {
                            if (spes[key][i].hasOwnProperty('is_default') && spes[key][i].is_default === true) {
                                this.$set(spes[key][i], 'cla', 'pop-m-item selected');
                            } else if (spes[key][i].hasOwnProperty('product_id') && spes[key][i].product_id) {
                                this.$set(spes[key][i], 'cla', 'pop-m-item not-selected');
                            } else {
                                this.$set(spes[key][i], 'cla', 'pop-m-item none');
                            }
                        }
                    }
                    products.default_spes_desc = spes;
                }
                return products;
            },
            // 购买数量加减操作
            bindChange(val) {
                this.buyNum = val;
            },
            // 商品收藏/取消
            collection() {
                let data = {
                    goods_id: this.goodsInfo.id
                }
                this.$api.goodsCollection(data, res => {
                    if (res.status) {
                        this.isfav = !this.isfav;
                        this.$common.successToShow(res.msg);
                    } else {
                        this.$common.errorToShow(res.msg);
                    }
                })
            },
            // tab点击切换
            onClickItem(index) {
                if (this.current !== index) {
                    this.current = index;
                }
            },
            // 获取商品参数信息
            getGoodsParams() {
                this.$api.goodsParams({
                    id: this.goodsId
                }, res => {
                    if (res.status == true) {
                        this.goodsParams = res.data;
                    }
                })
            },
            // 获取商品评论信息
            getGoodsComments() {
                let data = {
                    page: this.goodsComments.page,
                    limit: this.goodsComments.limit,
                    goods_id: this.goodsId
                }

                this.goodsComments.loadStatus = 'loading';

                this.$api.goodsComment(data, res => {
                    if (res.status == true) {
                        let _list = res.data.list;

                        // 如果评论没有图片 在这块作处理否则控制台报错
                        _list.forEach(item => {
                            item.ctime = this.$common.timeToDate(item.ctime)
                            if (!item.hasOwnProperty('images_url')) {
                                this.$set(item, 'images_url', [])
                            }
                        });

                        this.goodsComments.list = [...this.goodsComments.list, ..._list];
                        // 根据count数量判断是否还有数据
                        if (res.data.count > this.goodsComments.list.length) {
                            this.goodsComments.loadStatus = 'more';
                            this.goodsComments.page++;
                        } else {
                            this.goodsComments.loadStatus = 'noMore';
                        }
                    } else {
                        this.$common.errorToShow(res.msg);
                    }
                })
            },
            // 添加商品浏览足迹
            goodsBrowsing() {
                let data = {
                    goods_id: this.goodsInfo.id
                }

                this.$api.addGoodsBrowsing(data, res => {});
            },

            // 立即购买
            buyNow() {
                if (this.buyNum > 0) {
                    let data = {
                        product_id: this.product.id,
                        nums: this.buyNum,
                        order_type: this.type
                    }
                    this.$api.addCart(data, res => {
                        if (res.status) {
                            this.toclose();
                            let cartIds = res.data;
                            if (this.teamId == 0) {
                                this.$common.navigateTo('/pages/goods/place-order/index?cart_ids=' + JSON.stringify(cartIds) + '&order_type=' +
                                    this.type);
                            } else {
                                this.$common.navigateTo('/pages/goods/place-order/index?cart_ids=' + JSON.stringify(cartIds) + '&order_type=' +
                                    this.type + '&team_id=' + this.teamId);
                            }

                        } else {
                            this.toclose();
                            this.$common.errorToShow(res.msg);
                        }
                    })
                }
            },
            // 购物车页面跳转
            redirectCart() {
                uni.switchTab({
                    url: '/pages/cart/index/index'
                });
            },

            trigger(e) {
                this.content[e.index].active = !e.item.active;
                uni.switchTab({
                    url: e.item.url
                })
            },
            // 跳转到h5分享页面
            goShare() {
                this.$refs.share.show();
            },
            closeShare() {
                this.$refs.share.close();
            },
            // 拼团弹出层
            pintuanShow() {
                this.$refs.pintuanpop.show();
                // this.$refs.lvvpopref.close();
            },
            pintuanClose() {
                //this.$refs.pintuanpop.close();
                // this.$refs.pintuanpop.close();
                // this.$refs.share.close();
                //this.$refs.lvvpopref.close();
            },
            // 图片点击放大
            clickImg(imgs) {
                // 预览图片
                uni.previewImage({
                    urls: imgs.split()
                });
            },
            getMyShareCode() {
                let userToken = this.$db.get("userToken");
                if (userToken && userToken != '') {
                    // 获取我的分享码
                    this.$api.shareCode({}, res => {
                        if (res.status) {
                            this.myShareCode = res.data ? res.data : '';
                        }
                    });
                }
            }
        },
        //分享
        onShareAppMessage() {
            let myInviteCode = this.myShareCode ? this.myShareCode : '';
            let ins = this.$common.shareParameterDecode('type=5&id=' + this.goodsId + '&invite=' + myInviteCode);
            let path = '/pages/share/jump?scene=' + ins;
            console.log(path);
            return {
                title: this.goodsInfo.name,
                // #ifdef MP-ALIPAY
                desc: this.goodsInfo.brief,
                // #endif
                imageUrl: this.goodsInfo.album[0],
                path: path
            }
        }
    }
</script>

<style>
    .swiper {
        height: 750upx;
    }

    .goods-top {
        border-bottom: 0;
    }

    .goods-top .goods-price {
        font-size: 38upx;
    }

    .cost-price {
        font-size: 28upx !important;
        bottom: -10upx;
        color: #999;
        text-decoration: line-through;
    }

    .goods-top .cell-item-ft {
        font-size: 20upx;
        color: #666;
    }

    .goods-details {
        padding-top: 16upx;
    }

    .goods-details .cell-hd-title {
        width: 620upx;
    }

    .goods-details .cell-hd-title .cell-hd-title-view {
        width: 100%;
        display: -webkit-box;
        -webkit-box-orient: vertical;
        -webkit-line-clamp: 2;
        overflow: hidden;
    }

    .goods-details .cell-hd-title .cell-hd-title-view:last-child {
        margin-top: 10upx;
    }

    .goods-details .cell-item-ft {
        top: 42upx;
    }

    .goods-title-item .cell-item-hd {
        min-width: 60upx;
        color: #666;
        font-size: 24upx;
    }

    .goods-title-item .cell-item-bd {
        color: #333;
        font-size: 24upx;
    }

    .goods-title-item .cell-bd-text {
        bottom: 0;
    }

    .cell-bd-view {
        position: relative;
        overflow: hidden;
    }

    .cell-bd-view:first-child {
        margin-bottom: 8upx;
    }

    .goods-title-item-ic {
        width: 22upx;
        height: 22upx;
        position: absolute;
        top: 50%;
        transform: translateY(-50%);
        /* #ifdef MP-ALIPAY */
        background-size: 100% 100%;
        /* #endif */
    }

    .cell-bd-view .cell-bd-text {
        margin-left: 30upx;
    }

    .goods-content {
        margin-top: 26upx;
        background-color: #fff;
        padding: 26upx 0;
    }

    .goods-content-c {}

    .goods-parameter {
        padding: 10upx 26upx;
    }

    .goods-bottom,
    .pop-b {
        background-color: #fff;
        position: fixed;
        bottom: 0;
        height: 90upx;
        width: 100%;
        overflow: hidden;
        box-shadow: 0 0 20upx #ccc;
    }

    .goods-bottom button {
        height: 100%;
        width: 35%;
    }

    .goods-bottom-ic {
        display: inline-block;
        position: relative;
        text-align: center;
        height: 100%;
        width: 15%;
        float: left;
        font-size: 22upx;
        color: #666;
    }

    .goods-bottom-ic .icon {
        position: relative;
        top: 6upx;
        /* left: -6upx; */
        /* #ifdef MP-ALIPAY */
        background-size: 100% 100%;
        /* #endif */
    }

    .goods-bottom .btn-g {
        color: #333;
        background-color: #D9D9D9;
    }

    .goods-parameter .cell-item {
        border-bottom: none;
        margin-left: 0;
    }

    .goods-parameter .cell-item-hd {
        color: #333;
        font-size: 24upx;
    }

    .goods-parameter .cell-item-bd {
        color: #999;
    }

    .goods-parameter .cell-item-bd .cell-bd-text {
        bottom: 0;
    }

    .goods-parameter .cell-bd-text {
        margin-left: 0;
    }

    .pop-t {
        position: relative;
        padding: 30upx 26upx;
        border-bottom: 2upx solid #f3f3f3;
        /* box-shadow: 0 0 20upx #ccc; */
    }

    .goods-img {
        width: 160upx;
        height: 160upx;
        position: absolute;
        top: -20upx;
        background-color: #fff;
        border-radius: 6upx;
        border: 2upx solid #fff;
    }

    .goods-img image {
        height: 100%;
        width: 100%;
    }

    .goods-information {
        width: 420upx;
        display: inline-block;
        margin-left: 180upx;
    }

    .pop-goods-name {
        width: 100%;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
        display: block;
        font-size: 24upx;
        margin-bottom: 20upx;
    }

    .pop-goods-price {
        font-size: 30upx;
    }

    .close-btn {
        width: 40upx;
        height: 40upx;
        border-radius: 50%;
        display: inline-block;
        position: absolute;
        right: 30upx;
    }

    .close-btn image {
        width: 100%;
        height: 100%;
    }

    .pop-m {
        font-size: 28upx;
        margin-bottom: 90upx;
    }

    .goods-specs,
    .goods-number {
        padding: 26upx;
        border-top: 1px solid #f3f3f3;
    }

    .goods-specs:first-child {
        border: none;
    }

    .pop-m-title {
        margin-right: 10upx;
        color: #666;
    }

    .pop-m-bd {
        overflow: hidden;
        margin-top: 10upx;
    }

    .pop-m-item {
        display: inline-block;
        float: left;
        padding: 6upx 16upx;
        background-color: #fff;
        color: #333;
        margin-right: 16upx;
        margin-bottom: 10upx;
    }

    .selected {
        border: 2upx solid #333;
        background-color: #333;
        color: #fff;
    }

    .not-selected {
        border: 2upx solid #ccc;
    }

    .none {
        border: 2upx dashed #ccc;
        color: #888;
    }

    .pop-m-bd-in {
        display: inline-block;
    }

    .badge {
        top: 2upx;
        left: 62upx;
    }

    .goods-assess .user-head-img {
        width: 80upx;
        height: 80upx;
        border-radius: 50%;
    }

    .goods-assess .cell-item-bd {
        padding-right: 0;
    }

    .goods-assess .cell-bd-text {
        margin: 0;
    }

    .goods-assess .cell-bd-text.color-9 {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        max-width: 440upx;
    }

    .gai-body {}

    .gai-body-text {
        font-size: 26upx;
        color: #333;
        padding: 0 26upx;
        word-wrap: break-word;
    }

    .gai-body-img {
        overflow: hidden;
        padding: 20upx 26upx;
    }

    .gai-body-img image {
        width: 220upx;
        height: 220upx;
        float: left;
        margin-right: 19upx;
        margin-bottom: 18upx;
    }

    .gai-body-img image:nth-child(3n) {
        margin-right: 0;
    }

    .redstar {
        width: 24rpx;
        height: 24rpx;
        padding: 2rpx;
    }

    .mask-share-wechat {
        display: inline-block;
        background-color: #fff;
        padding: 0;
    }

    .mask-share-wechat:after {
        border: none;
    }

    .right-ball {
        position: fixed;
        right: 30upx;
        bottom: 300upx;
        z-index: 999;
        text-align: center;
        padding: 14upx 0;
        /* line-height: 80upx; */
        width: 80upx;
        height: 80upx;
        font-size: 24upx;
        color: #fff;
        background-color: rgba(0, 0, 0, .5);
        border-radius: 50%;
    }

    .share-pop {
        height: 300upx;
        width: 100%;
        display: flex;
    }

    .share-item {
        flex: 1;
        text-align: center;
        font-size: 26upx;
        color: #333;
        padding: 20upx 0;
    }

    /* .share-item image{
    width: 120upx;
    height: 120upx;
} */
    .comment-none {
        text-align: center;
        padding: 200upx 0;
    }

    .comment-none-img {
        width: 274upx;
        height: 274upx;
    }

    .price-salesvolume {
        width: 100%;
        height: 112upx;
        padding: 0 0 0 26upx;
        overflow: hidden;
        color: #A5A5A5;
        background-color: rgb(252, 226, 80);
        position: relative;
    }

    .commodity-price {
        width: 224upx;
        display: inline-block;
        float: left;
    }

    .current-price {
        font-size: 40upx;
        color: #FF7159;
        display: block;
        line-height: 1.5;
    }

    .cost-price {
        font-size: 26upx;
        text-decoration: line-through;
        /* margin-left: 8rpx; */
        display: block;
    }

    .commodity-salesvolume {
        width: 240upx;
        display: inline-block;
        font-size: 22upx;
        float: left;
        padding: 16upx 0;
    }

    .commodity-salesvolume>text {
        display: block;
    }

    .commodity-time-img {
        display: block;
        width: 0;
        height: 0;
        border-width: 56upx 28upx 56upx 0;
        border-style: solid;
        border-color: transparent #FF7159 transparent transparent;
        /*透明 黄 透明 透明 */
        /* position: absolute; */
        /* top: 0px; */
        /* right: 260upx; */
        float: right;
    }

    .commodity-time {
        display: inline-block;
        width: 220upx;
        height: 100%;
        text-align: center;
        font-size: 24upx;
        background-color: #FF7159;
        padding: 16upx 0 18upx;
        color: #FF7159;
        float: right;
    }

    .commodity-time>text {
        color: rgb(252, 226, 80);
    }

    .commodity-day>text {
        display: inline-block;
        background-color: rgb(255, 212, 176);
        color: rgb(255, 115, 0);
        padding: 0 6upx;
        border-radius: 6upx;
    }


    .nav-back {
        width: 100%;
        height: 44px;
        /* #ifndef MP-WEIXIN */
        padding: 12px 12px 0;
        /* #endif */
        /* #ifdef MP-WEIXIN */
        padding: 26px 12px 0;
        /* #endif */
        
        position: fixed;
        top: 0;
        background-color: rgba(255, 255, 255, 0);
        z-index: 98;
    }

    .back-btn {
        height: 32px;
        width: 32px;
        border-radius: 50%;
        background-color: rgba(255, 255, 255, 0.8);
    }

    .back-btn .icon {
        height: 20px;
        width: 20px;
        position: relative;
        top: 50%;
        left: 46%;
        transform: translate(-50%, -50%);
    }
    .tl {
        width: 70% !important;
    }

    .group-swiper {
        /* padding: 20upx 26upx; */
    }

    .groupHeight {
        height: 122upx !important;
    }

    .group-swiper-c {
        height: 242upx;
    }

    .group-swiper-c .swiper-item .cell-item {
        height: 50%;
    }

    .group-swiper-c .swiper-item .cell-item .user-head-img {
        width: 80upx;
        height: 80upx;
        border-radius: 50%;
    }

    .group-swiper-c .swiper-item .cell-item .cell-hd-title {
        position: absolute;
        top: 50%;
        left: 100upx;
        transform: translateY(-50%);
        max-width: 220upx;
        width: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .group-swiper-c .swiper-item .cell-item .cell-item-bd {
        min-width: 150upx;
        max-width: 200upx;
        padding-right: 134upx;
        text-align: center;
    }

    .group-swiper-c .swiper-item .cell-item .cell-item-bd .cell-bd-view {
        margin-bottom: 0;
    }

    .group-swiper-c .swiper-item .cell-item .cell-item-bd .cell-bd-text {
        float: none;
    }

    .group-swiper-c .commodity-day>text {
        background: none !important;
        padding: 0;
    }

    .group-swiper-c .swiper-item .cell-item .cell-item-ft .btn {
        font-size: 26upx;
        color: #fff;
        background-color: #FF7159;
        /* padding: 0; */
        text-align: center;
    }

    .btn-content {
        line-height: 1.2;
        position: relative;
        top: 49%;
        transform: translateY(-50%);
    }

    .ig-top {
        text-align: center;
        background-color: #fff;
        padding: 20upx 26upx;
        width: 690upx;
        min-height: 90upx;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
    }

    .ig-top-t,
    .ig-top-m {
        margin-bottom: 20upx;
    }

    .ig-top-t>view {
        display: inline-block;
        padding: 0 10upx;
        color: #999;
    }

    .user-head-img-c {
        position: relative;
        width: 80upx;
        height: 80upx;
        border-radius: 50%;
        margin-right: 20upx;
        box-sizing: border-box;
        display: inline-block;
        /* float: left; */
        border: 1px solid #f3f3f3;
    }

    .user-head-img-tip {
        position: absolute;
        top: -6upx;
        left: -10upx;
        display: inline-block;
        background-color: #FF7159;
        color: #fff;
        font-size: 22upx;
        z-index: 98;
        padding: 0 10upx;
        border-radius: 10upx;
        transform: scale(.8);
    }

    .user-head-img-c .user-head-img {
        width: 100%;
        height: 100%;
        border-radius: 50%;
    }

    .user-head-img-c:first-child {
        border: 1px solid #FF7159;
    }

    .uhihn {
        width: 80upx;
        height: 80upx;
        border-radius: 50%;
        display: inline-block;
        border: 2upx dashed #e1e1e1;
        text-align: center;
        color: #d1d1d1;
        font-size: 40upx;
        box-sizing: border-box;
        position: relative;
    }

    .uhihn>text {
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
    }

    .igtb-top {
        font-size: 32upx;
        color: #333;
        margin-bottom: 16upx;
    }

    .igtb-mid {
        margin-bottom: 16upx;
    }

    .igtb-mid .btn {
        width: 100%;
        background-color: #FF7159;
        color: #fff;
    }

    .igtb-bot {
        font-size: 24upx;
        color: #666;
    }
</style>
pintuan2.vue
<template>
    <view class="content">
        <view class="content-top">
            <!-- 轮播图 -->
            <view class='swiper'>
                <swiper class="swiper-c" :indicator-dots="swiper.indicatorDots" :autoplay="swiper.autoplay" :interval="swiper.interval"
                 :duration="swiper.duration">
                    <swiper-item class="have-none" v-for="(item, index) in goodsInfo.album" :key="index" @click="clickImg(item)">
                        <image class='' :src='item' mode="aspectFill"></image>
                    </swiper-item>
                </swiper>
            </view>
            <!-- 轮播图end -->

            <view class='cell-group'>
                <!-- 倒计时 -->
                <view class='price-salesvolume' v-if="lasttime.hour!==false">
                    <view class='commodity-price'>
                        <text class='current-price'>¥{{ product.pintuan_price }}</text>
                        <text class='cost-price'>¥{{product.mktprice}}</text>
                    </view>
                    <view class='commodity-salesvolume'>
                        <text>已售{{goodsInfo.buy_count}}件/剩余{{product.stock}}件</text>
                        <text>累计销售{{goodsInfo.buy_count}}件</text>
                    </view>
                    <view class='commodity-time-img'></view>
                    <view class='commodity-time'>
                        <text>距结束仅剩</text>
                        <view class='commodity-day'>
                            <uni-countdown :day="lasttime.day" :hour="lasttime.hour" :minute="lasttime.minute" :second="lasttime.second"></uni-countdown>
                        </view>
                    </view>
                    <!-- <view class='commodity-time'>
                        已结束
                    </view> -->
                </view>
                <!-- 倒计时end -->

                <!-- 分享 -->
                <view class='cell-item goods-details'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>{{ product.name }}</view>
                    </view>
                    <view class='cell-item-ft'>
                        <image class='cell-ft-next icon' @click="goShare()" src='../../../static/image/share.png'></image>
                    </view>
                </view>
                <!-- 分享end -->



                <!-- 规格 -->
                <view class='cell-item goods-title-item' v-if="isSpes">
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>规格</view>
                    </view>
                    <view class='cell-item-bd' @click="toshow(2)">
                        <text class='cell-bd-text'>{{ product.spes_desc }}</text>
                    </view>
                </view>
                <!-- 规格end -->

                <!-- 说明 -->
                <view class='cell-item goods-title-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>说明</view>
                    </view>
                    <view class='cell-item-bd'>
                        <view class="cell-bd-view">
                            <image class="goods-title-item-ic" src="../../../static/image/ic-dui.png" mode=""></image>
                            <text class="cell-bd-text">24小时内发货</text>
                        </view>
                        <view class="cell-bd-view">
                            <image class="goods-title-item-ic" src="../../../static/image/ic-dui.png" mode=""></image>
                            <text class="cell-bd-text">7天拆封无条件退货</text>
                        </view>
                    </view>
                </view>
                <!-- 说明end -->
            </view>

            <!-- 团购拼单 -->
            <view class="cell-group margin-cell-group" v-if="teamCount">
                <view class='cell-item right-img'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>{{teamCount}}人在拼单,可直接参与</view>
                    </view>
                    <!-- <view class='cell-item-ft' >
                        <image class='cell-ft-next icon' src='../../../static/image/right.png'></image>
                        <text class='cell-ft-text'>查看更多</text>
                    </view> -->
                </view>
                <view class="group-swiper">
                    <swiper class="group-swiper-c" :indicator-dots="indicatorDots" :autoplay="autoplay" vertical="true" circular="true"
                     :interval="interval" :duration="duration">
                        <swiper-item v-for="(item, index) in teamList" :key="index">
                            <view class="swiper-item">
                                <view class='cell-item'>
                                    <view class='cell-item-hd'>
                                        <image class="user-head-img cell-hd-icon have-none" :src='item[0].avatar' mode=""></image>
                                        <view class="cell-hd-title">
                                            {{item[0].user_name}}
                                        </view>
                                    </view>
                                    <view class='cell-item-bd'>
                                        <view class="cell-bd-view">
                                            <text class="cell-bd-text">还差<text class="red-price">{{item[0].peopleNums}}人</text>拼成</text>
                                        </view>
                                        <view class="cell-bd-view">
                                            <view class='commodity-day'>
                                                <uni-countdown :day="item[0].remainder_time.day" :hour="item[0].remainder_time.hour" :minute="item[0].remainder_time.minute"
                                                 :second="item[0].remainder_time.second"></uni-countdown>
                                            </view>

                                        </view>
                                    </view>
                                    <view class="cell-item-ft" v-if="!item[0].is_own">
                                        <button class="btn" @click="toshow(1,item[0].id)">去拼单</button>
                                    </view>
                                    <view class="cell-item-ft" v-else>
                                        <button class="btn btn-b">拼团中</button>
                                    </view>
                                </view>
                                <view class='cell-item' v-if="item[1]">
                                    <view class='cell-item-hd'>
                                        <image class="user-head-img cell-hd-icon have-none" :src='item[1].avatar' mode=""></image>
                                        <view class="cell-hd-title">
                                            {{item[1].user_name}}
                                        </view>
                                    </view>
                                    <view class='cell-item-bd'>
                                        <view class="cell-bd-view">
                                            <text class="cell-bd-text">还差<text class="red-price">{{item[1].peopleNums}}人</text>拼成</text>
                                        </view>
                                        <view class="cell-bd-view">
                                            <view class='commodity-day'>
                                                <uni-countdown :day="item[1].remainder_time.day" :hour="item[1].remainder_time.hour" :minute="item[1].remainder_time.minute"
                                                 :second="item[1].remainder_time.second"></uni-countdown>
                                            </view>

                                        </view>
                                    </view>
                                    <view class="cell-item-ft" v-if="!item[1].is_own">
                                        <button class="btn" @click="toshow(1,item[1].id)">去拼单</button>
                                    </view>
                                    <view class="cell-item-ft" v-else>
                                        <button class="btn btn-b">拼团中</button>
                                    </view>
                                </view>
                            </view>
                        </swiper-item>
                    </swiper>
                </view>
            </view>
            <view class="cell-group margin-cell-group" v-else>
                <view class='cell-item right-img'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>暂无开团信息</view>
                    </view>

                </view>
            </view>
            <view class="goods-content">
                <uni-segmented-control :current="current" :values="items" @clickItem="onClickItem" style-type="text" active-color="#333"></uni-segmented-control>
                <view class="goods-content-c">
                    <view class="goods-detail" v-if="current === 0">
                        <u-parse :content="goodsInfo.intro" />
                    </view>
                    <view class="goods-parameter" v-else-if="current === 1">
                        <view class='cell-group' v-if="goodsParams.length">
                            <view class='cell-item' v-for="(item, index) in goodsParams" :key="index">
                                <view class='cell-item-hd'>
                                    <view class='cell-hd-title'>{{ item.name }}</view>
                                </view>
                                <view class='cell-item-bd'>
                                    <text class='cell-bd-text'>{{ item.value }}</text>
                                </view>
                            </view>
                        </view>
                    </view>
                    <view class="goods-assess" v-else-if="current === 2">
                        <view v-if="goodsComments.list.length">
                            <view class="goods-assess-item" v-for="(item, index) in goodsComments.list" :key="index">
                                <view class='cell-group'>
                                    <view class='cell-item goods-title-item'>
                                        <view class='cell-item-hd'>
                                            <image class='user-head-img' :src='item.user.avatar' mode="aspectFill"></image>
                                        </view>
                                        <view class='cell-item-bd'>
                                            <view class="cell-bd-view">
                                                <text class="cell-bd-text">{{ item.user.nickname }}</text>
                                                <view class="cell-bd-text-right">
                                                    <uni-rate size="16" disabled="true" :value="item.score"></uni-rate>
                                                </view>
                                            </view>
                                            <view class="cell-bd-view">
                                                <text class="cell-bd-text color-9" style="margin-right: 16upx;">{{ item.ctime }}</text>
                                                <text class="cell-bd-text color-9">{{ item.addon }}</text>
                                            </view>
                                        </view>
                                    </view>
                                </view>
                                <view class="gai-body">
                                    <view class="gai-body-text">
                                        {{ item.content }}
                                    </view>
                                    <view class="gai-body-img" v-if="item.images_url.length">
                                        <image :src="img" mode="aspectFill" v-for="(img, key) in item.images_url" :key="key" @click="clickImg(img)"></image>
                                    </view>
                                </view>
                            </view>
                            <uni-load-more :status="goodsComments.loadStatus"></uni-load-more>
                        </view>
                        <view class="comment-none" v-else>
                            <image class="comment-none-img" src="../../../static/image/order.png" mode=""></image>
                        </view>
                    </view>
                </view>
            </view>
        </view>

        <!-- 弹出层 -->
        <lvv-popup position="bottom" ref="share">

            <!-- #ifdef H5 -->
            <shareByH5 :shareType='3' :goodsId="goodsInfo.id" :groupId="groupInfo.id" :shareImg="goodsInfo.image_url"
             :shareTitle="goodsInfo.name" :shareContent="goodsInfo.brief" :shareHref="shareHref" @close="closeShare()"></shareByH5>
            <!-- #endif -->

            <!-- #ifdef MP-WEIXIN -->
            <shareByWx :shareType='3' :goodsId="goodsInfo.id" :groupId="groupInfo.id" :shareImg="goodsInfo.image_url"
             :shareTitle="goodsInfo.name" :shareContent="goodsInfo.brief" :shareHref="shareHref" @close="closeShare()"></shareByWx>
            <!-- #endif -->

            <!-- #ifdef MP-ALIPAY -->
            <shareByAli :shareType='3' :goodsId="goodsInfo.id" :groupId="groupInfo.id" :shareImg="goodsInfo.image_url"
             :shareTitle="goodsInfo.name" :shareContent="goodsInfo.brief" :shareHref="shareHref" @close="closeShare()"></shareByAli>
            <!-- #endif -->

            <!-- #ifdef APP-PLUS -->
            <shareByApp :shareType='3' :goodsId="goodsInfo.id" :groupId="groupInfo.id" :shareImg="goodsInfo.image_url"
             :shareTitle="goodsInfo.name" :shareContent="goodsInfo.brief" :shareHref="shareHref" @close="closeShare()"></shareByApp>
            <!-- #endif -->

        </lvv-popup>

        <!-- 弹出层 -->

        <lvv-popup position="bottom" ref="lvvpopref">
            <view style="width: 100%;max-height: 804upx;background: #FFFFFF;position: absolute;left:0;bottom: 0;">
                <view class="pop-c">
                    <view class="pop-t">
                        <view class='goods-img'>
                            <image :src='product.image_path' mode='aspectFill'></image>
                        </view>
                        <view class='goods-information'>
                            <view class='pop-goods-name'>{{ product.name }}</view>
                            <view class='pop-goods-price red-price'>¥ {{ product.price }}</view>
                        </view>
                        <view class='close-btn' @click="toclose()">
                            <image src='../../../static/image/close.png'></image>
                        </view>
                    </view>
                    <scroll-view class="pop-m" scroll-y="true" style="max-height: 560upx;">
                        <spec :spesData="product.default_spes_desc" ref="spec" @changeSpes="changeSpes"></spec>

                        <view class="goods-number">
                            <text class="pop-m-title">数量</text>
                            <view class="pop-m-bd-in">
                                <uni-number-box :min="minNums" :max="product.stock" :value="buyNum" @change="bindChange"></uni-number-box>
                            </view>
                        </view>
                    </scroll-view>
                    <view class="pop-b" v-if="lvvpopref_type == 2">
                        <button class='btn btn-square btn-g btn-half' @click="buyNow(1)">单独购买¥ {{ product.price }}</button>
                        <button class='btn btn-square btn-b btn-half' @click="buyNow(2)">立即拼单¥ {{ product.pintuan_price }}</button>
                    </view>
                    <view class="pop-b" v-else>
                        <button class='btn btn-square btn-b' @click="buyNow1(2)">确定¥ {{ product.pintuan_price }}</button>
                    </view>
                </view>
            </view>
        </lvv-popup>
        <!-- 弹出层end -->
        <!-- 底部按钮 -->
        <view class="goods-bottom">
            <view class="goods-bottom-ic" @click="collection">
                <image class="icon" :src="isfav ? favLogo[1] : favLogo[0]" mode=""></image>
                <view v-if="!isfav">收藏</view>
                <view v-if="isfav">已收藏</view>
            </view>

            <view class="goods-bottom-ic" @click="redirectCart">
                <view class="badge color-f" v-if="cartNums">{{ cartNums }}</view>
                <image class="icon" src="../../../static/image/ic-me-car.png" mode=""></image>
                <view>购物车</view>
            </view>
            <button class='btn btn-square btn-b tl' @click="toshow(2)" hover-class="btn-hover2">立即拼单</button>
        </view>
        <!-- 底部按钮end -->

        <!-- 右边浮动球 -->
        <uni-fab :pattern="pattern" :content="content" :horizontal="horizontal" :vertical="vertical" :direction="direction"
         @trigger="trigger"></uni-fab>
    </view>
</template>

<script>
    import uniSegmentedControl from "@/components/uni-segmented-control/uni-segmented-control.vue";
    import lvvPopup from '@/components/lvv-popup/lvv-popup.vue';
    import uniNumberBox from "@/components/uni-number-box/uni-number-box.vue";
    import uniRate from "@/components/uni-rate/uni-rate.vue";
    import uniLoadMore from '@/components/uni-load-more/uni-load-more.vue';
    import uniFab from '@/components/uni-fab/uni-fab.vue';
    import {
        get
    } from '@/config/db.js';
    import {
        apiBaseUrl
    } from '@/config/config.js';
    import {
        pintuanUrl
    } from '@/config/config.js';
    import uniCountdown from "@/components/uni-countdown/uni-countdown.vue";
    import uParse from '@/components/u-parse/u-parse.vue';
    import spec from '@/components/spec/spec.vue';
    import share from '@/components/share/share.vue';
    // #ifdef H5
    import shareByH5 from '@/components/share/shareByh5.vue'
    // #endif
    // #ifdef MP-WEIXIN
    import shareByWx from '@/components/share/shareByWx.vue'
    // #endif
    // #ifdef MP-ALIPAY
    import shareByAli from '@/components/share/shareByAli.vue'
    // #endif
    // #ifdef APP-PLUS
    import shareByApp from '@/components/share/shareByApp.vue'
    // #endif

    import htmlParser from '@/common/html-parser'
    export default {

        components: {
            uniSegmentedControl,
            lvvPopup,
            uniNumberBox,
            uniRate,
            uniLoadMore,
            uniFab,
            uniCountdown,
            uParse,
            share,
            spec,
            // #ifdef H5
            shareByH5,
            // #endif

            // #ifdef MP-WEIXIN
            shareByWx,
            // #endif

            // #ifdef MP-ALIPAY
            shareByAli,
            // #endif

            // #ifdef APP-PLUS
            shareByApp,
            // #endif
        },
        data() {
            return {
                myShareCode: '', //分享Code
                shareType: 0,
                providerList: [], // 分享通道 包含生成海报
                swiper: {
                    indicatorDots: true,
                    autoplay: true,
                    interval: 3000,
                    duration: 800,
                }, // 轮播图属性设置
                items: ['图文详情', '商品参数', '买家评论'],
                current: 0, // init tab位
                goodsId: 0, // 商品id
                groupId: 0, // 拼团ID
                cartNums: 0, // 购物车数量
                groupInfo: {}, // 拼团详情
                goodsInfo: {}, //商品详情
                teamList: [], //团队列表
                teamCount: 0, //开团团数
                product: {}, // 规格详情
                goodsParams: [], // 商品参数信息
                goodsComments: {
                    loadStatus: 'more',
                    page: 1,
                    limit: 5,
                    list: []
                }, // 商品评论信息
                buyNum: 1, // 选定的购买数量
                minBuyNum: 1, // 最小可购买数量
                type: 2, // 1加入购物车 2购买
                isfav: false, // 商品是否收藏
                favLogo: [
                    '../../../static/image/ic-me-collect.png',
                    '../../../static/image/ic-me-collect2.png'
                ],
                horizontal: 'right', //右下角弹出按钮
                vertical: 'bottom',
                direction: 'vertical',
                pattern: {
                    color: '#7A7E83',
                    backgroundColor: '#fff',
                    selectedColor: '#007AFF',
                    buttonColor: "#FF7159"
                },
                content: [{
                        iconPath: '../../../static/image/tab-ic-hom-selected.png',
                        selectedIconPath: '../../../static/image/tab-ic-hom-unselected.png',
                        // text: '首页',
                        active: false,
                        url: '/pages/index/index'
                    },

                    {
                        iconPath: '../../../static/image/tab-ic-me-selected.png',
                        selectedIconPath: '../../../static/image/tab-ic-me-unselected.png',
                        // text: '个人中心',
                        active: false,
                        url: '/pages/member/index/index'
                    },
                ],
                indicatorDots: false,
                autoplay: false,
                interval: 2000,
                duration: 500,
                lasttime: {
                    hour: false,
                    minute: 0,
                    second: 0
                },
                lvvpopref_type: 2,
                team_id: 0, //团id
                userToken: 0,
                invite: 0 //邀请人的团Id
            }
        },
        onLoad(e) {
            this.goodsId = e.id;
            this.groupId = e.group_id;
            
            //获取拼团id,商品ID
            if (this.goodsId && this.groupId) {
                this.getPintuanInfo(groupId);
                this.getTeam(groupId);
                this.getGoodsParams();
                this.getGoodsComments();
            } else {
                this.$common.errorToShow('获取失败', () => {
                    uni.navigateBack({
                        delta: 1
                    });
                });
            }
            
            // 获取购物车数量
            this.getCartNums();
            this.getMyShareCode();
        },
        computed: {

            // 规格切换计算规格商品的 可购买数量
            minNums() {
                return this.product.stock > this.minBuyNum ? this.minBuyNum : this.product.stock;
            },
            // 判断商品是否是多规格商品  (为了兼容小程序 只能写在计算属性里面了)
            isSpes() {
                if (this.product.hasOwnProperty('default_spes_desc') && Object.keys(this.product.default_spes_desc).length) {
                    return true;
                } else {
                    return false;
                }
            },
            // 优惠信息重新组装
            promotion() {
                let arr = [];
                if (this.product.promotion_list) {
                    for (let k in this.product.promotion_list) {
                        arr.push(this.product.promotion_list[k]);
                    }
                }
                return arr;
            },
            shareHref() {
                let pages = getCurrentPages()
                let page = pages[pages.length - 1]
                // #ifdef H5 || MP-WEIXIN || APP-PLUS || APP-PLUS-NVUE
                return apiBaseUrl + 'wap/#/' + page.route + '?id=' + this.goodsId + '&group_id=' + this.groupId;
                // #endif

                // #ifdef MP-ALIPAY
                return apiBaseUrl + 'wap/#/' + page.__proto__.route + '?id=' + this.goodsId + '&group_id=' + this.groupId;
                // #endif
            }

        },
        onReachBottom() {
            if (this.current === 2 && this.goodsComments.loadStatus === 'more') {
                this.getGoodsComments();
            }
        },
        methods: {
            // 关闭弹出层
            close() {
                this.$emit('close')
            },
            // 点击操作
            clickHandler(e) {
                if (e.cate === 'poster') {
                    this.createPoster()
                } else {
                    // 去分享
                    this.share(e)
                }
            },
            // 购物车页面跳转
            redirectCart() {
                uni.switchTab({
                    url: '/pages/cart/index/index'
                });
            },
            //开团列表
            getTeam(id) {
                uni.showLoading({
                    title: '加载中'
                });
                let userToken = this.$db.get("userToken");
                if (userToken && userToken != '') {
                    this.userToken = userToken;
                }
                uni.request({
                    url: this.$config.pintuanUrl + 'getTeam',
                    header: {
                        'Accept': 'application/json',
                        'Content-Type': 'application/json',
                    },
                    method: 'POST',
                    data: {
                        rule_id: id,
                        token: this.userToken
                    },
                    success: (res) => {
                        uni.hideLoading();
                        if (res.data.status) {
                            let data = res.data.data;
                            let new_data = new Array();
                            for (var k = 0; k < data.length; k++) {
                                if (k == 0 || k % 2 == 0) {
                                    if (k + 1 < data.length) {
                                        var a = [
                                            data[k],
                                            data[k + 1]
                                        ];
                                    } else {
                                        var a = [data[k]];

                                    }
                                    new_data.push(a);
                                }
                            }
                            //console.log(new_data);
                            this.teamList = new_data;
                            this.teamCount = res.data.count;
                        }
                    },
                    fail: (error) => {
                        uni.hideLoading();
                        if (error && error.response) {
                            this.$common.showError(error.response);
                        }
                    },
                });
            },

            //拼团信息
            getPintuanInfo(id) {
                uni.showLoading({
                    title: '加载中'
                });
                uni.request({
                    url: this.$config.pintuanUrl + 'getPintuanInfo',
                    header: {
                        'Accept': 'application/json',
                        'Content-Type': 'application/json',
                    },
                    method: 'POST',
                    data: {
                        id: id
                    },
                    success: (res) => {
                        uni.hideLoading();
                        if (res.data.status) {
                            if (res.data.data.length < 1) {
                                this.$common.errorToShow('该拼团活动不存在,请返回重新选择。', () => {
                                    uni.navigateBack({
                                        delta: 1
                                    });
                                });
                            }
                            // else if (res.data.data.goods_info.goodmarketable != 1){
                            //     this.$common.errorToShow('该商品已下架,请返回重新选择商品。', () => {
                            //         uni.navigateBack({
                            //             delta: 1
                            //         });
                            //     });
                            // }
                            else {
                                this.groupInfo = res.data.data;
                                this.product = res.data.data.goods_info.product;
                                this.goodsInfo = this.groupInfo.goods_info;
                                let price = this.product.price;
                                if (price > 0) {
                                    this.product.price = price;
                                } else {
                                    this.product.price = 0.00;
                                }
                                this.product = this.spesClassHandle(this.product);
                                this.lasttime = res.data.data.lasttime;
                            }

                        }
                    },
                    fail: (error) => {
                        uni.hideLoading();
                        if (error && error.response) {
                            this.$common.showError(error.response);
                        }
                    },
                });
            },
            // 获取购物车数量    
            getCartNums() {
                let userToken = this.$db.get("userToken");
                if (userToken && userToken != '') {
                    // 获取购物车数量
                    this.$api.getCartNum({}, res => {
                        if (res.status) {
                            this.cartNums = res.data;
                        }
                    });
                }
            },
            // 显示modal弹出框
            toshow(type, team_id = 0) {
                if (type == 1) {
                    this.lvvpopref_type = 1;
                }
                if (type == 2) {
                    this.lvvpopref_type = 2;
                }
                if (team_id !== 0) {
                    this.team_id = team_id;
                }
                this.$refs.lvvpopref.show();
            },
            // 关闭modal弹出框
            toclose() {
                this.$refs.lvvpopref.close();
            },
            // 切换商品规格
            changeSpes(obj) {
                //console.log(obj);
                let index = obj.v;
                let key = obj.k;
                if (this.product.default_spes_desc[index][key].hasOwnProperty('product_id') && this.product.default_spes_desc[index]
                    [key].product_id) {
                    uni.showLoading({
                        title: '加载中'
                    });
                    uni.request({
                        url: this.$config.pintuanUrl + 'getProductInfo',
                        header: {
                            'Accept': 'application/json',
                            'Content-Type': 'application/json',
                        },
                        method: 'POST',
                        data: {
                            id: this.product.default_spes_desc[index][key].product_id,
                            discount_amount: this.groupInfo.discount_amount
                        },
                        success: (res) => {
                            uni.hideLoading();
                            if (res.data.status) {
                                // 切换规格判断可购买数量
                                this.buyNum = res.data.data.stock > this.minBuyNum ? this.minBuyNum : res.data.data.stock;
                                this.product = this.spesClassHandle(res.data.data);
                            }
                        },
                        fail: (error) => {
                            uni.hideLoading();
                            if (error && error.response) {
                                this.$common.showError(error.response);
                            }
                        },
                    });
                    setTimeout(function() {
                        uni.hideLoading();
                    }, 1000);
                }
            },
            // 多规格样式统一处理
            spesClassHandle(products) {
                // 判断是否是多规格 (是否有默认规格)
                if (products.hasOwnProperty('default_spes_desc')) {
                    let spes = products.default_spes_desc;
                    for (let key in spes) {
                        for (let i in spes[key]) {
                            if (spes[key][i].hasOwnProperty('is_default') && spes[key][i].is_default === true) {
                                this.$set(spes[key][i], 'cla', 'pop-m-item selected');
                            } else if (spes[key][i].hasOwnProperty('product_id') && spes[key][i].product_id) {
                                this.$set(spes[key][i], 'cla', 'pop-m-item not-selected');
                            } else {
                                this.$set(spes[key][i], 'cla', 'pop-m-item none');
                            }
                        }
                    }
                    products.default_spes_desc = spes;
                }
                return products;
            },
            // 购买数量加减操作
            bindChange(val) {
                this.buyNum = val;
            },
            // 商品收藏/取消
            collection() {
                let data = {
                    goods_id: this.goodsId
                }
                this.$api.goodsCollection(data, res => {
                    if (res.status) {
                        this.isfav = !this.isfav;
                        this.$common.successToShow(res.msg);
                    } else {
                        this.$common.errorToShow(res.msg);
                    }
                })
            },

            // tab点击切换
            onClickItem(index) {
                if (this.current !== index) {
                    this.current = index;
                }
            },
            // 获取商品参数信息
            getGoodsParams() {
                this.$api.goodsParams({
                    id: this.goodsId
                }, res => {
                    if (res.status == true) {
                        this.goodsParams = res.data;
                    }
                })
            },
            // 获取商品评论信息
            getGoodsComments() {
                let data = {
                    page: this.goodsComments.page,
                    limit: this.goodsComments.limit,
                    goods_id: this.goodsId
                }

                this.goodsComments.loadStatus = 'loading';

                this.$api.goodsComment(data, res => {
                    if (res.status == true) {
                        let _list = res.data.list;

                        // 如果评论没有图片 在这块作处理否则控制台报错
                        _list.forEach(item => {
                            item.ctime = this.$common.timeToDate(item.ctime)
                            if (!item.hasOwnProperty('images_url')) {
                                this.$set(item, 'images_url', [])
                            }
                        });

                        this.goodsComments.list = [...this.goodsComments.list, ..._list];
                        // 根据count数量判断是否还有数据
                        if (res.data.count > this.goodsComments.list.length) {
                            this.goodsComments.loadStatus = 'more';
                            this.goodsComments.page++;
                        } else {
                            this.goodsComments.loadStatus = 'noMore';
                        }
                    } else {
                        this.$common.errorToShow(res.msg);
                    }
                })
            },
            // 添加商品浏览足迹
            goodsBrowsing() {
                let data = {
                    goods_id: this.goodsInfo.id
                }

                this.$api.addGoodsBrowsing(data, res => {});
            },

            // 立即购买
            buyNow(card_type) {
                if (this.buyNum > 0) {
                    let data = {
                        product_id: this.product.id,
                        nums: this.buyNum,
                        type: 2, // 区分加入购物车和购买,
                    }
                    if (card_type == 2) {
                        data['cart_type'] = 2;

                    }
                    this.$api.addCart(data, res => {
                        if (res.status) {
                            this.toclose();
                            let cartIds = res.data;
                            if (card_type == 1) {
                                this.$common.navigateTo('/pages/goods/place-order/index?cart_ids=' + JSON.stringify(cartIds));
                            } else {
                                if (this.invite != 0) {
                                    this.$common.navigateTo('/pages/goods/place-order/index?cart_ids=' + JSON.stringify(cartIds) +
                                        '&cart_type=2&team_id=' + this.invite);
                                } else {
                                    this.$common.navigateTo('/pages/goods/place-order/index?cart_ids=' + JSON.stringify(cartIds) +
                                        '&cart_type=2');
                                }

                            }

                        }
                    })
                }
            },
            // 立即购买
            buyNow1(card_type) {
                if (this.buyNum > 0) {
                    let data = {
                        product_id: this.product.id,
                        nums: this.buyNum,
                        type: 2, // 区分加入购物车和购买,
                    }
                    if (card_type == 2) {
                        data['cart_type'] = 2;

                    }
                    this.$api.addCart(data, res => {
                        if (res.status) {
                            this.toclose();
                            let cartIds = res.data;
                            if (this.team_id != 0) {
                                this.$common.navigateTo('/pages/goods/place-order/index?cart_ids=' + JSON.stringify(cartIds) +
                                    '&cart_type=2&team_id=' + this.team_id);
                            } else {
                                this.$common.navigateTo('/pages/goods/place-order/index?cart_ids=' + JSON.stringify(cartIds) + '&cart_type=2');
                            }

                        }
                    })
                }
            },
            trigger(e) {
                this.content[e.index].active = !e.item.active;
                uni.switchTab({
                    url: e.item.url
                })
            },
            // 跳转到h5分享页面
            goShare() {
                this.$refs.share.show();
            },
            closeShare() {
                this.$refs.share.close();
            },

            // 图片点击放大
            clickImg(imgs) {
                // 预览图片
                uni.previewImage({
                    urls: imgs.split()
                });
            },
            getMyShareCode() {
                let userToken = this.$db.get("userToken");
                if (userToken && userToken != '') {
                    // 获取我的分享码
                    this.$api.shareCode({}, res => {
                        if (res.status) {
                            this.myShareCode = res.data ? res.data : '';
                        }
                    });
                }
            }
        },
        //分享
        onShareAppMessage() {
            let myInviteCode = this.myShareCode ? this.myShareCode : '';
            let ins = encodeURIComponent('type=5&id=' + this.goodsId + '&group_id=' + this.groupId + '&invite=' + myInviteCode);
            let path = '/pages/share/jump?scene=' + ins;
            return {
                title: this.goodsInfo.name,
                // #ifdef MP-ALIPAY
                desc: this.goodsInfo.brief,
                // #endif
                imageUrl: this.goodsInfo.album[0],
                path: path
            }
        }
    }
</script>

<style>
    .swiper {
        height: 750upx;
    }

    .goods-top {
        border-bottom: 0;
    }

    .goods-top .goods-price {
        font-size: 38upx;
    }

    .cost-price {
        font-size: 28upx !important;
        bottom: -10upx;
        color: #999;
        text-decoration: line-through;
    }

    .goods-top .cell-item-ft {
        font-size: 20upx;
        color: #666;
    }

    .goods-details {
        padding-top: 16upx;
    }

    .goods-details .cell-hd-title {
        width: 620upx;
        color: #333;
        font-size: 26upx;
        display: -webkit-box;
        -webkit-box-orient: vertical;
        -webkit-line-clamp: 2;
        overflow: hidden;
    }

    .goods-details .cell-item-ft {
        top: 40%;
    }

    .goods-title-item .cell-item-hd {
        min-width: 60upx;
        color: #666;
        font-size: 24upx;
    }

    .goods-title-item .cell-item-bd {
        color: #333;
        font-size: 24upx;
    }

    .goods-title-item .cell-bd-text {
        bottom: 0;
    }

    .cell-bd-view {
        position: relative;
        overflow: hidden;
    }

    .cell-bd-view:first-child {
        margin-bottom: 8upx;
    }

    .goods-title-item-ic {
        width: 22upx;
        height: 22upx;
        position: absolute;
        top: 50%;
        transform: translateY(-50%);
        /* #ifdef MP-ALIPAY */
        background-size: 100% 100%;
        /* #endif */
    }

    .cell-bd-view .cell-bd-text {
        margin-left: 30upx;
    }

    .goods-content {
        margin-top: 26upx;
        background-color: #fff;
        padding: 26upx 0;
    }

    .goods-content-c {}

    .goods-parameter {
        padding: 10upx 26upx;
    }

    .goods-bottom,
    .pop-b {
        background-color: #fff;
        position: fixed;
        bottom: 0;
        height: 90upx;
        width: 100%;
        overflow: hidden;
        display: flex;
        box-shadow: 0 0 20upx #ccc;
    }

    .pop-b button {
        flex: 1;
    }

    .goods-bottom button {
        height: 100%;
        width: 35%;
    }

    .goods-bottom-ic {
        display: inline-block;
        position: relative;
        text-align: center;
        height: 100%;
        width: 15%;
        float: left;
        font-size: 22upx;
        color: #666;
    }

    .goods-bottom-ic .icon {
        position: relative;
        top: 6upx;
        /* left: -6upx; */
        /* #ifdef MP-ALIPAY */
        background-size: 100% 100%;
        /* #endif */
    }

    .goods-bottom .btn-g {
        color: #333;
        background-color: #D9D9D9;
    }

    .goods-parameter .cell-item {
        border-bottom: none;
        margin-left: 0;
    }

    .goods-parameter .cell-item-hd {
        color: #333;
        font-size: 24upx;
    }

    .goods-parameter .cell-item-bd {
        color: #999;
    }

    .goods-parameter .cell-item-bd .cell-bd-text {
        bottom: 0;
    }

    .goods-parameter .cell-bd-text {
        margin-left: 0;
    }

    .pop-t {
        position: relative;
        padding: 30upx 26upx;
        border-bottom: 2upx solid #f3f3f3;
        /* box-shadow: 0 0 20upx #ccc; */
    }

    .goods-img {
        width: 160upx;
        height: 160upx;
        position: absolute;
        top: -20upx;
        background-color: #fff;
        border-radius: 6upx;
        border: 2upx solid #fff;
    }

    .goods-img image {
        height: 100%;
        width: 100%;
    }

    .goods-information {
        width: 420upx;
        display: inline-block;
        margin-left: 180upx;
    }

    .pop-goods-name {
        width: 100%;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
        display: block;
        font-size: 24upx;
        margin-bottom: 20upx;
    }

    .pop-goods-price {
        font-size: 30upx;
    }

    .close-btn {
        width: 40upx;
        height: 40upx;
        border-radius: 50%;
        display: inline-block;
        position: absolute;
        right: 30upx;
    }

    .close-btn image {
        width: 100%;
        height: 100%;
    }

    .pop-m {
        font-size: 28upx;
        margin-bottom: 90upx;
    }

    .goods-specs,
    .goods-number {
        padding: 26upx;
        border-top: 1px solid #f3f3f3;
    }

    .goods-specs:first-child {
        border: none;
    }

    .pop-m-title {
        margin-right: 10upx;
        color: #666;
    }

    .pop-m-bd {
        overflow: hidden;
        margin-top: 10upx;
    }

    .pop-m-item {
        display: inline-block;
        float: left;
        padding: 6upx 16upx;
        background-color: #fff;
        color: #333;
        margin-right: 16upx;
        margin-bottom: 10upx;
    }

    .selected {
        border: 2upx solid #333;
        background-color: #333;
        color: #fff;
    }

    .not-selected {
        border: 2upx solid #ccc;
    }

    .none {
        border: 2upx dashed #ccc;
        color: #888;
    }

    .pop-m-bd-in {
        display: inline-block;
    }

    .badge {
        top: 2upx;
        left: 62upx;
    }

    .goods-assess .user-head-img {
        width: 80upx;
        height: 80upx;
        border-radius: 50%;
    }

    .goods-assess .cell-item-bd {
        padding-right: 0;
    }

    .goods-assess .cell-bd-text {
        margin: 0;
    }

    .goods-assess .cell-bd-text.color-9 {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        max-width: 440upx;
    }

    .gai-body {}

    .gai-body-text {
        font-size: 26upx;
        color: #333;
        padding: 0 26upx;
    }

    .gai-body-img {
        overflow: hidden;
        padding: 20upx 26upx;
    }

    .gai-body-img image {
        width: 220upx;
        height: 220upx;
        float: left;
        margin-right: 19upx;
        margin-bottom: 18upx;
    }

    .gai-body-img image:nth-child(3n) {
        margin-right: 0;
    }

    .redstar {
        width: 24rpx;
        height: 24rpx;
        padding: 2rpx;
    }

    .mask-share-wechat {
        display: inline-block;
        background-color: #fff;
        padding: 0;
    }

    .mask-share-wechat:after {
        border: none;
    }

    .right-ball {
        position: fixed;
        right: 30upx;
        bottom: 300upx;
        z-index: 999;
        text-align: center;
        padding: 14upx 0;
        /* line-height: 80upx; */
        width: 80upx;
        height: 80upx;
        font-size: 24upx;
        color: #fff;
        background-color: rgba(0, 0, 0, .5);
        border-radius: 50%;
    }

    .share-pop {
        height: 300upx;
        width: 100%;
        display: flex;
    }

    .share-item {
        flex: 1;
        text-align: center;
        font-size: 26upx;
        color: #333;
        padding: 20upx 0;
    }

    .share-item image {
        width: 120upx;
        height: 120upx;
    }

    .share-item .btn {
        line-height: 1;
        display: block;
        font-size: 26upx;
        background-color: #fff;
    }

    .comment-none {
        text-align: center;
        padding: 200upx 0;
    }

    .comment-none-img {
        width: 274upx;
        height: 274upx;
    }

    .price-salesvolume {
        width: 100%;
        padding: 0 0 0 26upx;
        overflow: hidden;
        color: #A5A5A5;
        background-color: rgb(252, 226, 80);
        position: relative;
    }

    .commodity-price {
        width: 224upx;
        display: inline-block;
        float: left;
    }

    .current-price {
        font-size: 40upx;
        color: #FF7159;
        display: block;
        line-height: 1.5;
    }

    .cost-price {
        font-size: 26upx;
        text-decoration: line-through;
        /* margin-left: 8rpx; */
        display: block;
    }

    .commodity-salesvolume {
        width: 240upx;
        display: inline-block;
        font-size: 22upx;
        float: left;
        padding: 16upx 0;
    }

    .commodity-salesvolume>text {
        display: block;
    }

    .commodity-time-img {
        display: block;
        width: 0;
        height: 0;
        border-width: 56upx 28upx 56upx 0;
        border-style: solid;
        border-color: transparent #FF7159 transparent transparent;
        /*透明 黄 透明 透明 */
        position: absolute;
        top: 0px;
        left: 462upx;
    }

    .commodity-time {
        display: inline-block;
        width: 260upx;
        text-align: center;
        font-size: 24upx;
        background-color: #FF7159;
        padding: 16upx 0 18upx;
        color: #FF7159;
    }

    .commodity-time>text {
        color: rgb(252, 226, 80);
    }

    .commodity-day>text {
        display: inline-block;
        background-color: rgb(255, 212, 176);
        color: rgb(255, 115, 0);
        padding: 0 6upx;
        border-radius: 6upx;
    }

    .tl {
        width: 70% !important;
    }

    .group-swiper {
        /* padding: 20upx 26upx; */
    }

    .group-swiper-c {
        height: 242upx;
    }

    .group-swiper-c .swiper-item .cell-item {
        height: 50%;
    }

    .group-swiper-c .swiper-item .cell-item .user-head-img {
        width: 80upx;
        height: 80upx;
        border-radius: 50%;
    }

    .group-swiper-c .swiper-item .cell-item .cell-hd-title {
        position: absolute;
        top: 50%;
        left: 100upx;
        transform: translateY(-50%);
        max-width: 260upx;
        width: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .group-swiper-c .swiper-item .cell-item .cell-item-bd {
        min-width: 150upx;
        max-width: 150upx
    }

    .group-swiper-c .swiper-item .cell-item .cell-item-ft .btn {
        font-size: 26upx;
        color: #fff;
        background-color: #FF7159;
        /* padding: 0; */
        text-align: center;
    }

    .price-salesvolume .commodity-day .uni-countdown__splitor {
        color: rgb(252, 226, 80);
    }

    .group-swiper .commodity-day .uni-countdown__splitor {
        color: #666;
    }

    @import url('@/components/u-parse/u-parse.css')
</style>
payment
auth.vue
<template>
  <view class="content">
    <view class="content-c">
      <image class="load-img" src="/static/image/loading.gif" mode=""></image>
      <view class="load-text color-9">信息加载中.....</view>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      type: '',
      openid: '',
      orderId: '',
      state: ''
    }
  },
  onLoad(options) {
    this.orderId = options.order_id
    this.money = Number(options.money)
    this.type = Number(options.type)
    this.uid = Number(options.uid)
    this.state = this.$common.getQueryString('state')
    this.getCode()
  },
  methods: {
    getCode() {
      var code = this.$common.getQueryString('code')
      code && this.getOpenId(code)
    },
    getOpenId(code) {
      let data = {
        code: code,
        scope: 2,
        state: this.state
      }
      //模拟接口
      this.$api.getOpenId(data, res => {
        if (res.status) {
          this.openid = res.data.openid
          this.toPayHandler('wechatpay')
        } else {
          this.$common.errorToShow(res.msg)
        }
      })
    },
    checkWXJSBridge(data) {
      let that = this
      let interval = setInterval(() => {
        if (typeof window.WeixinJSBridge != 'undefined') {
          clearTimeout(interval)
          that.onBridgeReady(data)
        }
      }, 200)
    },
    onBridgeReady(data) {
      var _this = this
      window.WeixinJSBridge.invoke(
        'getBrandWCPayRequest',
        {
          appId: data.appid, // 公众号名称,由商户传入
          timeStamp: data.timeStamp, // 时间戳,自1970年以来的秒数
          nonceStr: data.nonceStr, // 随机串
          package: data.package,
          signType: data.signType, // 微信签名方式:
          paySign: data.paySign // 微信签名
        },
        function(res) {
          if (res.err_msg === 'get_brand_wcpay_request:ok') {
            _this.$common.successToShow('支付成功')
          } else if (res.err_msg === 'get_brand_wcpay_request:cancel') {
            _this.$common.errorToShow('取消支付')
          } else {
            _this.$common.errorToShow('支付失败')
          }
          setTimeout(() => {
            _this.$common.redirectTo(
              '/pages/goods/payment/result?id=' + data.payment_id
            )
          },1000)
        }
      )
    },
    toPayHandler(code) {
      let data = {
        payment_code: code,
        payment_type: this.type
      }
      data['ids'] = (this.type == 1 || this.type == 5 || this.type == 6) ? this.orderId : this.uid
      //data['ids'] = this.type == 1 ? this.orderId : this.uid
      
      if (this.type == 1 && this.orderId) {
        // 微信jsapi支付
        if (this.openid) {
          data['params'] = {
            trade_type: 'JSAPI_OFFICIAL',
            openid: this.openid
          }
        }
      } else if (this.type == 2 && this.money) {
        if (this.openid) {
          data['params'] = {
            trade_type: 'JSAPI_OFFICIAL',
            money: this.money,
            openid: this.openid
          }
        }
      }else if ((this.type == 5 || this.type == 6) && this.recharge) {
        data['params'] = {
            trade_type: 'JSAPI_OFFICIAL',
            openid: this.openid,
            formid: this.orderId
        }
      }
      this.$api.pay(data, res => {
        if (res.status) {
          const data = res.data
          this.checkWXJSBridge(data)
        } else {
          this.$common.errorToShow(res.msg)
        }
      })
    }
  }
}
</script>

<style>
.content {
  position: relative;
  height: 80vh;
}
.content-c {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
}
.load-img {
  width: 100upx;
  height: 100upx;
}
.load-text {
  font-size: 26upx;
}
</style>
index.vue
<template>
    <view class="content">
        <view class='cell-group margin-cell-group'>
            <view class='cell-item'>
                <view class='cell-item-hd'>
                    <view class='cell-hd-title'>订单类型</view>
                </view>
                <view class='cell-item-ft'>
                    <text class="cell-ft-p" v-if="type == 1" @click="orderDetail(orderId)">商品订单</text>
                    <text class="cell-ft-p" v-if="type == 2" @click="toRecharge()">充值订单</text>
                    <text class="cell-ft-p" v-if="type == 5" >快捷下单</text>
                    <text class="cell-ft-p" v-if="type == 6" >付款码</text>
                </view>
            </view>
            <view v-if="type == 1">
                <view class='cell-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>订单编号</view>
                    </view>
                    <view class='cell-item-ft'>
                        <text class="cell-ft-p" @click="orderDetail(orderId)">{{ orderId }}</text>
                    </view>
                </view>
                <view class='cell-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>订单金额</view>
                    </view>
                    <view class='cell-item-ft'>
                        <text class="cell-ft-p red-price">¥{{ orderInfo.order_amount }}</text>
                    </view>
                </view>
            </view>
            <view v-else-if="type == 2">
                <view class='cell-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>充值金额</view>
                    </view>
                    <view class='cell-item-ft'>
                        <text class="cell-ft-p red-price">¥ {{ recharge }}</text>
                    </view>
                </view>
            </view>
        </view>

        <!-- #ifdef H5 -->
        <payments-by-h5
                :orderId="orderId"
                :recharge="recharge"
                :type="type"
                :uid="userInfo.id"
        ></payments-by-h5>
        <!-- #endif -->

        <!-- #ifdef MP-WEIXIN -->
        <payments-by-wx
                :orderId="orderId"
                :recharge="recharge"
                :type="type"
                :uid="userInfo.id"
        ></payments-by-wx>
        <!-- #endif -->

        <!-- #ifdef MP-ALIPAY -->
        <payments-by-ali
                :orderId="orderId"
                :recharge="recharge"
                :type="type"
                :uid="userInfo.id"
        ></payments-by-ali>
        <!-- #endif -->

        <!-- #ifdef APP-PLUS||APP-PLUS-NVUE -->
        <payments-by-app
                :orderId="orderId"
                :recharge="recharge"
                :type="type"
                :uid="userInfo.id"
        ></payments-by-app>
        <!-- #endif -->
        
        
    </view>
</template>

<script>
    // #ifdef H5
    import paymentsByH5 from '@/components/payments/paymentsByH5.vue'
    // #endif

    // #ifdef MP-WEIXIN
    import paymentsByWx from '@/components/payments/paymentsByWx.vue'
    // #endif

    // #ifdef MP-ALIPAY
    import paymentsByAli from '@/components/payments/paymentsByAli.vue'
    // #endif

    // #ifdef APP-PLUS||APP-PLUS-NVUE
    import paymentsByApp from '@/components/payments/paymentsByApp.vue'
    // #endif

    import { orders } from '@/config/mixins.js'
    export default {
        mixins: [orders],
        data () {
            return {
                orderId: 0,
                recharge: 0,
                type: 1,    // 订单类型 1商品订单 2充值订单
                orderInfo: {}, // 订单详情
                userInfo: {},    // 用户信息
                form_id:0
            }
        },

        components: {
            // #ifdef H5
            paymentsByH5,
            // #endif
            // #ifdef MP-WEIXIN
            paymentsByWx,
            // #endif
            // #ifdef MP-ALIPAY
            paymentsByAli,
            // #endif
            // #ifdef APP-PLUS||APP-PLUS-NVUE
            paymentsByApp,
            // #endif
        },

        onLoad (options) {
            this.orderId = options.order_id
            this.recharge = Number(options.recharge)
            this.type = Number(options.type)
            this.form_id =  Number(options.form_id)
            
            if (this.orderId && this.type == 1) {
                // 商品订单
                this.getOrderInfo()
            } else if (this.recharge && this.type == 2) {
                // 充值订单 获取用户id
                this.getUserInfo()
            } else if (this.form_id && (this.type == 5 || this.type == 6)) {
                // 表单订单 id传到订单上
                this.orderId = ''+this.form_id;
            } else {
                this.$common.errorToShow('订单支付参数错误', () => {
                    uni.navigateBack({
                        delta: 1
                    })
                })
            }
        },
        methods: {
            // 获取订单详情
            getOrderInfo () {
                let data = {
                    order_id: this.orderId
                }
                this.$api.orderDetail(data, res => {
                    if (res.status) {
                        this.orderInfo = res.data
                        if(this.orderInfo.pay_status == 2){
                            this.$common.redirectTo(
                                '/pages/goods/payment/result?order_id=' + this.orderInfo.order_id
                            )
                        }
                    }
                })
            },
            // 获取用户信息
            getUserInfo () {
                this.$api.userInfo({}, res => {
                    if (res.status) {
                        this.userInfo = res.data
                        
                    } else {
                        this.$common.errorToShow(res.msg)
                    }
                })
            },
            // 跳转我的余额页面
            toRecharge () {
                this.$common.navigateTo('/pages/member/balance/index')
            }
        }
    }
</script>

<style>
    .margin-cell-group{
        margin-bottom: 20upx;
    }
    .cell-hd-title{
        color: #999;
    }
    .payment-method .cell-item-hd{
        min-width: 70upx;
    }
    .payment-method .cell-hd-icon{
        width: 70upx;
        height: 70upx;
    }
    .payment-method .cell-item-bd{
        border-left: 2upx solid #F0F0F0;
        padding-left: 30upx;
    }
    .payment-method .cell-bd-text{
        font-size: 28upx;
        color: #666;
    }
    .payment-method .address{
        font-size: 24upx;
        color: #999;
    }
</style>
result.vue
<template>
    <view class="content">
        <view class="result succsee" v-if="status && paymentInfo.status === 2">
            <image class="result-img" src="/static/image/win.png" mode=""></image>
            <view class="result-top">
                支付成功
            </view>
            <view class="result-mid red-price">
                {{ paymentInfo.money }}
            </view>
            <view class="result-bot">
                <button class="btn btn-g" @click="orderDetail()">查看详情</button>
            </view>
        </view>
        <view class="result fail" v-else-if="status && paymentInfo.status === 1">
            <image class="result-img" src="/static/image/pastdue.png" mode=""></image>
            <view class="result-top">
                支付失败
            </view>
            <view class="result-mid red-price">
                {{ paymentInfo.money }}
            </view>
            <view class="result-bot">
                <button class="btn btn-g" @click="orderDetail()">查看详情</button>
            </view>
        </view>
    </view>
</template>

<script>
    export default {
        data() {
            return {
                paymentId: 0,
                paymentInfo: {}, // 支付单详情
                orderId: 0,
                status: false
            }
        },
        onLoad(options) {
            if (options.id) {
                this.paymentId = options.id
            }
            if (options.order_id) {
                this.orderId = options.order_id
            }
        },
        mounted() {
            this.getPaymentInfo()
        },
        methods: {

            getPaymentInfo() {
                if (!this.paymentId) {
                    this.status = true;
                    this.paymentInfo.money = '0.00'
                    this.paymentInfo.status = 2;
                    this.paymentInfo.type = 1;

                    return
                }
                let data = {
                    payment_id: this.paymentId
                }

                this.$api.paymentInfo(data, res => {
                    if (res.status) {
                        let info = res.data
                        if (info.payment_code === 'alipay') {
                            info.payment_name = '支付宝支付'
                        } else if (info.payment_code === 'wechatpay') {
                            info.payment_name = '微信支付'
                        } else if (info.payment_code === 'balancepay') {
                            info.payment_name = '余额支付'
                        }

                        // 获取订单号
                        if (info.rel.length) {
                            for (let i = 0; i < info.rel.length; i++) {
                                if (info.rel[i].source_id) {
                                    this.orderId = info.rel[i].source_id
                                    break;
                                }
                            }
                        }
                        this.status = true;
                        this.paymentInfo = info
                    } else {
                        this.$common.errorToShow(res.msg)
                    }
                })
            },
            orderDetail() {
                if (this.orderId && this.paymentInfo.type === 1) {
                    this.$common.redirectTo('/pages/member/order/orderdetail?order_id=' + this.orderId)
                } else if (this.paymentInfo.type === 2) {
                    this.$common.redirectTo('/pages/member/balance/details')
                } else if (this.paymentInfo.type === 5 || this.paymentInfo.type === 6) {
                    uni.switchTab({
                        url: '/pages/index/index'
                    });
                }
            }
        }
    }
</script>

<style>
    .result {
        text-align: center;
        padding-top: 200upx;
    }

    .result-img {
        width: 140upx;
        height: 140upx;
        margin-bottom: 20upx;
    }

    .result-num {
        color: #666;
        font-size: 30upx;
        margin-bottom: 20upx;
    }

    .result-top {
        color: #666;
        font-size: 30upx;
        margin-bottom: 20upx;
    }

    .result-mid {
        margin-bottom: 60upx;
    }

    .result-bot .btn {
        margin-top: 40upx;
        font-size: 26upx;
        padding: 0 50upx;
    }
</style>
place-order
index.vue
<template>
    <form class="content" @submit="toPay" report-submit="true">
        <view class="content-top">
            <uni-segmented-control :current="type_current" :values="type_items" @clickItem="onTypeItem" style-type="text" active-color="#333" v-if="storeSwitch == 1"></uni-segmented-control>
            <view class="content">
                <view v-show="type_current === 0">
                    <!-- 收货地址信息 -->
                    <view class='cell-group margin-cell-group' v-if="userShip.id"  @click="showAddressList">
                        <view class='cell-item add-title-item right-img'>
                            <view class='cell-item-hd'>
                                <image class='cell-hd-icon' src='/static/image/location.png'></image>
                            </view>
                            <view class='cell-item-bd'>
                                <view class="cell-bd-view">
                                    <text class="cell-bd-text">收货人:{{ userShip.name }}</text>
                                    <text class="cell-bd-text-right">{{ userShip.mobile }}</text>
                                </view>
                                <view class="cell-bd-view">
                                    <text class="cell-bd-text address">{{ userShip.area_name }}</text>
                                </view>
                            </view>
                            <view class='cell-item-ft'>
                                <image class='cell-ft-next icon' src='/static/image/right.png'></image>
                            </view>
                        </view>
                    </view>
                    <view class="cell-group margin-cell-group" v-else>
                        <view class='cell-item add-title-items'>
                            <button class="btn btn-b" @click="goAddress()" hover-class="btn-hover2">添加收货地址</button>
                        </view>
                    </view>
                </view>
                <view v-show="type_current === 1">
                    <!-- 门店信息 -->
                    <view v-if="store.id != 0" class='cell-group margin-cell-group' @click="goStorelist()">
                        <view class='cell-item add-title-item right-img'>
                            <view class='cell-item-hd'>
                                <image class='cell-hd-icon' src='/static/image/homepage.png'></image>
                            </view>
                            <view class='cell-item-bd'>
                                <view class="cell-bd-view">
                                    <text class="cell-bd-text">{{store.name}}</text>
                                    <text class="cell-bd-text-right">{{store.mobile}}</text>
                                </view>
                                <view class="cell-bd-view">
                                    <text class="cell-bd-text address">{{store.address}}</text>
                                </view>
                            </view>
                            <view class='cell-item-ft'>
                                <image class='cell-ft-next icon' src='/static/image/right.png'></image>
                            </view>
                        </view>
                    </view>
                    <view v-else class='cell-group margin-cell-group'>
                        <view class='cell-item add-title-item right-img no-store'>暂无门店</view>
                    </view>
                </view>
            </view>

            <view class='cell-group margin-cell-group' v-if="storeSwitch == 1 && type_current === 1">
                <view class='cell-item user-head'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>姓名</view>
                    </view>
                    <view class='cell-item-bd'>
                        <input class='cell-bd-input' placeholder='请输入提货人姓名' v-model="store_pick.name"></input>
                    </view>
                </view>
                <view class='cell-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>电话</view>
                    </view>
                    <view class='cell-item-bd'>
                        <input class='cell-bd-input' placeholder='请输入提货人电话' v-model="store_pick.mobile"></input>
                    </view>
                </view>
            </view>

            <!-- 商品列表信息 -->
            <view class='img-list'>
                <view class='img-list-item' v-if="item.is_select == true" v-for="(item, index) in products" :key="index">
                    <image class='img-list-item-l little-img have-none' :src='item.products.image_path' mode='aspectFill'></image>
                    <view class='img-list-item-r little-right'>
                        <view class='little-right-t'>
                            <view class='goods-name list-goods-name' @click="goodsDetail(item.products.goods_id)">{{ item.products.name }}</view>
                            <view class='goods-price'>¥{{ item.products.price }}</view>
                        </view>
                        <view class="romotion-tip" v-if="item.products.promotion_list">
                            <view class="romotion-tip-item" :class="v.type !== 2 ? 'bg-gray' : ''" v-for="(v, k) in item.products.promotion_list" :key="k">
                                {{ v.name }}
                            </view>
                        </view>
                        <view class='goods-item-c'>
                            <view class='goods-buy'>
                                <view class='goods-salesvolume' v-if="item.products.spes_desc !== null">{{ item.products.spes_desc }}</view>
                                <view class='goods-num'>× {{ item.nums }}</view>
                            </view>
                        </view>
                    </view>
                </view>
            </view>

            <view class='cell-group'>
                <view class='cell-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>优惠券</view>
                    </view>
                    <view class='cell-item-ft'>
                        <text class="cell-ft-p" @click="toshow()">{{ usedCouponsCompute }}</text>
                    </view>
                </view>

                <!-- 商户开启积分 并且用户有积分情况下 -->
                <view class='cell-item add-title-item right-img' v-if="isOpenPoint === 1 && userPointNums > 0">
                    <view class='cell-item-bd'>
                        <view class="cell-bd-view">
                            积分抵扣
                        </view>
                        <view class="cell-bd-view">
                            <text class="cell-bd-text address color-9">可用 {{ canUsePoint }} 积分,可抵扣 {{ pointMoney }} 元,共有 {{ userPointNums }} 积分。</text>
                        </view>
                    </view>
                    <view class='cell-item-ft' @click="changePointHandle">
                        <label class="radio">
                            <radio value="1" :checked="isUsePoint" color="#FF7159"/>
                            <!-- <radio class="radioNo" disabled="true"/> -->
                        </label>
                    </view>
                </view>

                <view class='cell-item invoice right-img' v-if="invoiceSwitch == 1">
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>发票</view>
                    </view>
                    <view class='cell-item-ft' @click="goInvoice()">
                        <image class='cell-ft-next icon' src='/static/image/right.png'></image>
                        <text class='cell-ft-text'>{{invoice.name}}</text>
                    </view>
                </view>

                <view class='cell-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-bd-view'>商品价格</view>
                        <view class='cell-bd-view' v-if="cartData.goods_pmt_old > 0">商品优惠</view>
                        <view class='cell-hd-view' v-if="cartData.order_pmt_old > 0">订单优惠</view>
                        <view class='cell-hd-view' v-if="!couponIsUsed">优惠券抵扣</view>
                        <view class='cell-hd-view' v-if="cartData.point > 0">积分抵扣</view>
                        <view class='cell-hd-view'>运费</view>
                    </view>
                    <view class='cell-item-ft'>
                        <view class="cell-ft-view red-price">{{ cartData.goods_amount }}</view>
                        <view class="cell-ft-view" v-if="cartData.goods_pmt_old > 0">-{{ cartData.goods_pmt }}</view>
                        <view class="cell-ft-view" v-if="cartData.order_pmt_old > 0">-{{ cartData.order_pmt }}</view>
                        <view class="cell-ft-view" v-if="!couponIsUsed">-{{ cartData.coupon_pmt }}</view>
                        <view class="cell-ft-view" v-if="cartData.point > 0">-{{ cartData.point_money }}</view>
                        <view class="cell-ft-view">{{ cartData.cost_freight }}</view>
                    </view>
                </view>
            </view>

            <view class='cell-group leave-message'>
                <view class='cell-item right-img'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>买家留言</view>
                    </view>
                </view>
                <view class="cell-textarea ">
                    <!-- #ifndef MP-WEIXIN -->
                    <textarea v-model="memo" placeholder="50字以内(选填)" maxlength="50"/>
                    <!-- #endif -->
                    <!-- #ifdef MP-WEIXIN -->
                    <input v-model="memo" placeholder="50字以内(选填)"/>
                    <!-- #endif -->
                </view>
            </view>
        </view>

        <!-- 优惠券信息 -->
        <lvv-popup position="bottom" ref="lvvpopref">
            <view style="width: 100%;height: 700upx;background: #F8F8F8;;position: absolute;left:0;bottom: 0;">
                <view class="pop-c">
                    <!-- <view class="pop-t">
                        <view class='cell-item invoice'>
                            <view class='cell-item-hd'>
                                <view class='cell-hd-title'>优惠券</view>
                            </view>
                            <view class='cell-item-ft'
                            @click="toclose()">
                                <image class='cell-ft-next icon' src='/static/image/close.png'></image>
                            </view>
                        </view>
                    </view> -->

                    <view class="pop-b">
                        <view class="pop-b-t">
                            <uni-segmented-control
                                    :current="current"
                                    :values="items"
                                    @clickItem="onClickItem"
                                    style-type="text"
                                    active-color="#333"
                            ></uni-segmented-control>
                        </view>
                        <view class="" v-show="current === 0">
                            <scroll-view class="coupon-c" scroll-y="true" style="" v-if="userCoupons.length">
                                <view class="coupon-c-item" v-for="(item, index) in userCoupons" :key="index">
                                    <view :class="item.cla">
                                        <view class="cci-l-c color-f">
                                            coupon
                                        </view>
                                    </view>

                                    <view class="cci-r">
                                        <!-- <image class="cci-r-img" src="" mode=""></image> -->
                                        <view class="cci-r-c">
                                            <view class="ccirc-t color-9">
                                                {{ item.name }}
                                            </view>
                                            <view class="ccirc-b">
                                                <view class="ccirc-b-l">
                                                    <view class="ccirc-b-tip">
                                                        {{ item.expression1 + item.expression2 }}
                                                    </view>
                                                    <view class="ccirc-b-time color-9">
                                                        有效期:{{ item.stime + ' - ' + item.etime }}
                                                    </view>
                                                </view>
                                                <view class="ccirc-b-r color-f"
                                                      @click="couponHandle(index)"
                                                      v-if="!item.checked && !item.disabled"
                                                >
                                                    立即使用
                                                </view>
                                                <view class="ccirc-b-r color-f"
                                                      @click="couponHandle(index)"
                                                      v-else-if="item.checked && !item.disabled"
                                                >
                                                    取消使用
                                                </view>
                                                <!-- <view class="ccirc-b-r color-f bg-c">
                                                    不可用
                                                </view> -->
                                            </view>
                                        </view>
                                    </view>
                                </view>
                            </scroll-view>
                            <view class="coupon-none" v-else>
                                <image class="coupon-none-img" src="/static/image/order.png" mode=""></image>
                            </view>
                        </view>

                        <view class="coupon-c" v-show="current === 1">
                            <view class="coupon-enter">
                                <view class="coupon-input">
                                    <input type="text" v-model="inputCouponCode" placeholder="请输入优惠券码"/>
                                </view>
                                <!-- #ifdef MP-WEIXIN -->
                                <!-- <view class="coupon-code">
                                    <image src="/static/image/ewm.png" class="icon" mode="" @click="scanCode"></image>
                                </view> -->
                                <!-- #endif -->
                                <view class="coupon-enter-btn"
                                      @click="useInputCouponCode"
                                >
                                    <button class="btn btn-b">确认</button>
                                </view>
                            </view>
                        </view>
                    </view>
                    <view class="button-bottom">
                        <button class="btn btn-square"
                                @click="notUseCoupon()"
                        >不使用优惠卷</button>
                        <button class="btn btn-square btn-b"
                                @click="toclose()"
                        >确定</button>
                    </view>

                </view>
            </view>
        </lvv-popup>

        <view class="button-bottom">
            <view class="button-bottom-c">
                <view class="button-bottom-c-t">共 {{ productNums }} 件商品</view>
                <view class="button-bottom-c-b">合计<text class="red-price"> {{ cartData.amount }}</text></view>
            </view>
            <button class='btn btn-square btn-b' hover-class="btn-hover2" form-type="submit" :disabled='submitStatus' :loading='submitStatus'>立即支付</button>
        </view>
    </form>
</template>

<script>
    import lvvPopup from '@/components/lvv-popup/lvv-popup.vue'
    import uniSegmentedControl from "@/components/uni-segmented-control/uni-segmented-control.vue"
    import { goods } from '@/config/mixins.js'
    export default {
        mixins: [ goods ],
        data () {
            return {
                type_items: ['快递配送','门店自提'],//门店自提切换
                type_current: 0,
                cartData: {}, // 购物车商品详情
                products: [], // 货品信息
                promotions: [], // 促销信息
                userShip: {}, // 用户收货地址
                receiptType: 1, // 订单类型 1是发货订单 2是门店自提订单
                params: {
                    ids: 0, // 传递过来的购物车id
                    area_id: 0, // 收货地址id
                    coupon_code: '', // 优惠券码列表(string)多张逗号分隔
                    point: 0 ,// 抵扣积分额
                    type :1 ,//购物车类型
                }, // 监听params参数信息 以重新请求接口
                // 发票信息
                invoice: {
                    type: '1',    // 类型 1不开发票 2个人发票 3公司发票
                    name: '不开发票',    // 发票抬头
                    code: ''    // 发票税号
                },
                memo: '', // 买家留言
                items: [
                    '选择优惠券',
                    '输入券码',
                ],
                orderType: 1, // 商品订单类型 1
                current: 0,
                isUsePoint: false,    // 是否勾选使用积分
                userPointNums: 0, // 用户的总积分
                canUsePoint: 0,    // 可以使用的积分
                pointMoney: '', // 积分抵扣的金额
                userCoupons: [], // 用户的可用优惠券列表
                usedCoupons: {}, // 已经选择使用的优惠券
                inputCouponCode: '', // 输入的优惠券码
                optCoupon: '' ,// 当前选择使用的优惠券(暂存使用 如果接口返回不可用则剔除优惠券状态)
                store : {
                    id: 0,
                    name: '',
                    mobile: '',
                    address: ''
                },
                store_pick: {
                    name: '',
                    mobile: ''
                },
                team_id: 0, //拼团id
                submitStatus: false
            }
        },
        components: {lvvPopup,uniSegmentedControl},
        onLoad (options) {
            let cartIds = options.cart_ids;
            if(options.order_type){
                this.params.order_type = options.order_type;
            }
            if(options.team_id){
                this.team_id = options.team_id;
            }
            

            this.params.ids = JSON.parse(cartIds)
            if (!this.params.ids) {
                this.$common.successToShow('获取失败', function(){
                    uni.navigateBack({
                        delta: 1
                    })
                })
            }
            // 获取用户的默认收货地址信息
            this.userDefaultShip()

            // 获取用户的可用优惠券信息
            this.getUserCounpons()

            //获取默认门店信息
            this.getDefaultStore();
        },
        methods: {
            // 切换门店
            onTypeItem(index) {
                if (this.type_current !== index) {
                    this.type_current = index;
                }
                let receiptType = 1;
                if(this.type_current != 0){
                    receiptType = 2;
                }
                this.receiptType = receiptType;

                this.getCartList();
            },
            // 跳转到门店列表
            goStorelist(){
                uni.navigateTo({
                    url: './storelist'
                })
            },
            // 没有收货地址时跳转
            goAddress(){
                uni.navigateTo({
                    url: '/pages/member/address/list?type=order'
                })
            },
            // 获取用户的默认收货地址
            userDefaultShip () {
                this.$api.userDefaultShip({}, res => {
                    if (res.status && Object.keys(res.data).length) {
                        this.userShip = res.data
                        this.params.area_id = this.userShip.area_id
                    }
                })
            },
            // 获取购物车商品详情
            getCartList () {
                let data = this.params
                data['receipt_type'] = this.receiptType    // 区分订单类型  1快递订单 2门店自提订单

                this.$api.cartList(data, res => {
                    if (res.status) {
                        let data = res.data

                        // 判断是否开启积分抵扣 并且 没有勾选积分使用
                        if (this.isOpenPoint === 1 && !this.isUsePoint) {
                            let money = {
                                order_money: data.amount
                            }
                            this.$api.usablePoint(money, res => {
                                if (res.status) {
                                    this.userPointNums = res.data    // 用户总积分
                                    this.canUsePoint = res.available_point    // 可以使用的积分
                                    this.pointMoney = res.point_rmb    // 积分抵扣的总金额
                                }
                            })
                        }

                        // 所有价格转换
                        data.amount = this.$common.formatMoney(data.amount);
                        data.goods_amount = this.$common.formatMoney(data.goods_amount);
                        data.goods_pmt_old = data.goods_pmt;
                        data.goods_pmt = this.$common.formatMoney(data.goods_pmt);
                        data.coupon_pmt = this.$common.formatMoney(data.coupon_pmt);
                        data.order_pmt_old = data.order_pmt;
                        data.order_pmt = this.$common.formatMoney(data.order_pmt);
                        data.point_money = this.$common.formatMoney(data.point_money);
                        data.cost_freight = this.$common.formatMoney(data.cost_freight);

                        // 购物车详情
                        this.cartData = data
                        // 商品详情
                        this.products = data.list
                        // 优惠信息
                        this.promotions = data.promotion_list
                        // 使用的优惠券信息
                        this.usedCoupons = data.coupon

                        // 手动输入的优惠券使用成功后关闭弹窗并清除输入的优惠券码
                        this.current === 1 && this.$refs.lvvpopref.popshow && this.inputCouponCode ? this.toclose() : ''
                        this.inputCouponCode = ''

                        this.optCoupon = ''
                    } else {
                        this.$common.errorToShow(res.msg, () => {
                            // 优惠券不可用状态判断
                            // 优惠券号码不存在             15009
                            // 优惠券未开始                15010
                            // 优惠券已使用                15013
                            // 优惠券不符合使用规则        15014
                            // 优惠券不可使用多张            15015
                            let errStatus = [15009, 15010, 15013, 15014, 15015]

                            if (errStatus.indexOf(res.data) !== -1) {
                                // 删除使用的优惠券号码
                                if (this.current === 1) {
                                    this.removeCouponCode(this.inputCouponCode, this.current)
                                } else {
                                    // 取消选择使用的状态
                                    if (this.optCoupon) {
                                        this.userCoupons.forEach(item => {
                                            if (item.coupon_code === this.optCoupon) {
                                                item.checked = false
                                            }
                                        })
                                    }
                                    this.removeCouponCode(this.optCoupon, this.current)
                                }
                            }
                        })
                    }
                })
            },
            // 获取用户可用的优惠券信息
            getUserCounpons () {
                let data = {
                    display: 'no_used'
                }
                this.$api.userCoupon(data, res => {
                    if (res.status) {
                        let _list = res.data.list
                        let nowTime = Math.round(new Date().getTime() / 1000).toString()
                        _list.forEach(item => {
                            this.$set(item, 'checked', false)
                            // 判断优惠券是否有效(开始时间)
                            this.$set(item, 'disabled', item.start_time > nowTime ? true : false)
                            this.$set(item, 'cla', item.disabled ? 'cci-l bg-c' : 'cci-l')    // 绑定相应的class样式
                        })
                        this.userCoupons = _list
                    }
                })
            },
            // 点击使用/取消优惠券操作
            couponHandle (index) {
                // 更改使用/取消状态
                this.userCoupons[index].checked = !this.userCoupons[index].checked

                // 暂存当次选中使用的优惠券key
                this.optCoupon = this.userCoupons[index].coupon_code

                let arr = []
                this.userCoupons.forEach(item => {
                    if (item.checked) {
                        arr.push(item.coupon_code)
                    }
                })
                if (this.userCoupons[index].checked) {
                    // 使用
                    this.params.coupon_code = arr.join()
                } else {
                    // 取消使用
                    let paramsCodes = this.params.coupon_code.split(',')
                    let usedIndex = paramsCodes.indexOf(this.userCoupons[index].coupon_code)
                    if (usedIndex !== -1) {
                        paramsCodes.splice(usedIndex, 1)
                        this.params.coupon_code = paramsCodes.join()
                    }
                }
            },
            // 手输的优惠券码使用
            useInputCouponCode () {
                if (!this.inputCouponCode) {
                    this.$common.errorToShow('请输入优惠券码')
                } else {
                    // 判断是否有使用的优惠券
                    if (this.params.coupon_code.length > 0) {
                        this.params.coupon_code += ',' + this.inputCouponCode
                    } else {
                        this.params.coupon_code = this.inputCouponCode
                    }
                }
            },
            // 不使用优惠券
            notUseCoupon () {
                this.toclose()
                this.inputCouponCode = ''    // 清空手输的优惠券码
                this.userCoupons.forEach(item => {
                    item.checked = false
                }) // 取消所有选中的使用状态
                this.params.coupon_code = ''    // 清空params优惠券码
            },
            // 移除/取消使用中的指定优惠券
            removeCouponCode (code, current) {
                let arr = this.params.coupon_code.split(',')
                arr.splice(arr.indexOf(code), 1)
                current === 0 ? this.optCoupon = '' : this.inputCouponCode = ''
                this.params.coupon_code = arr.join()
            },
            // 是否使用积分
            changePointHandle(){
                if(this.userPointNums > 0){
                    this.isUsePoint = !this.isUsePoint;
                    this.params.point = this.isUsePoint ? this.canUsePoint : 0;
                }
            },
            // 显示modal弹出框
            toshow(){
                this.$refs.lvvpopref.show();
            },
            // 关闭modal弹出框
            toclose(){
                this.$refs.lvvpopref.close();
            },
            // 去支付
            toPay (e) {
                this.submitStatus = true;
                let receiptType = 1;
                if(this.type_current != 0){
                    receiptType = 2;
                }
                this.receiptType = receiptType;

                let data = {
                    cart_ids: this.params.ids,
                    memo: this.memo,
                    coupon_code: this.params.coupon_code,
                    point: this.params.point,
                    receipt_type: this.receiptType
                }
                data['order_type'] = this.params.order_type; //订单类型
                if(this.team_id != 0){
                    data['params'] = JSON.stringify({team_id:this.team_id})  //团id
                }
                let delivery = {}
                // 判断是快递配送还是门店自提
                if(this.receiptType == 1){
                    if(!this.userShip.id || !this.params.area_id){
                        this.$common.errorToShow('请选择收货地址');
                        this.submitStatus = false;
                        return false;
                    }
                    // 快递配送
                    delivery = {
                        uship_id: this.userShip.id,
                        area_id: this.params.area_id
                    }
                }
                if(this.receiptType == 2){
                    if(!this.store.id){
                        this.$common.errorToShow('请选择自提门店');
                        this.submitStatus = false;
                        return false;
                    }
                    if(!this.store_pick.name){
                        this.$common.errorToShow('请输入提货人姓名');
                        this.submitStatus = false;
                        return false;
                    }
                    if(!this.store_pick.mobile){
                        this.$common.errorToShow('请输入提货人电话');
                        this.submitStatus = false;
                        return false;
                    }
                    // 门店自提
                    delivery = {
                        store_id: this.store.id,
                        lading_name: this.store_pick.name,
                        lading_mobile: this.store_pick.mobile
                    }
                }

                // 发票信息
                data['tax_type'] = this.invoice.type
                data['tax_name'] = this.invoice.name
                data['tax_code'] = this.invoice.code

                // #ifdef H5
                data['source'] = 2;
                // #endif
                // #ifdef MP-WEIXIN
                data['source'] = 3;
                data['formId'] = e.detail.formId;
                // #endif
                // #ifdef MP-ALIPAY
                data['source'] = 4;
                // #endif
                // #ifdef APP-PLUS|| APP-PLUS-NVUE
                data['source'] = 5;
                // #endif

                data = Object.assign(data, delivery)

                this.$api.createOrder(data, res => {
                    if (res.status) {
                        // 创建订单成功 去支付
                        this.submitStatus = false;
                        this.$common.redirectTo('/pages/goods/payment/index?order_id=' + res.data.order_id + '&type=' + this.orderType)
                    }else{
                        this.$common.errorToShow(res.msg);
                        this.submitStatus = false;
                    }
                })
            },
            // 跳转发票页面
            goInvoice () {
                this.$common.navigateTo('./invoice')
            },
            // 跳转我的收货地址列表
            showAddressList () {
                this.$common.navigateTo('/pages/member/address/list?type=order')
            },
            // tab点击切换
            onClickItem(index) {
                if (this.current !== index) {
                    this.current = index;
                }
            },
            // 获取默认店铺
            getDefaultStore(){
                this.$api.defaultStore({}, res => {
                    if(res.status){
                        let store = {
                            id: res.data.id,
                            name: res.data.store_name,
                            mobile: res.data.store_mobile,
                            address: res.data.all_address
                        }
                        this.store = store;
                    }
                });
            }
            //扫码
//         scanCode() {
//             console.log(1);
//             uni.scanCode({
//                 success(res) {
//                     console.log(2);
//                     console.log(res)
//                 },
//                 complete(res){
//                     console.log(3);
//                     console.log(res)
//                 },
//                 fail(res) {
//                     console.log(4);
//                     console.log(res)
//                 }
//             })
//         }
        },
        computed: {
            // 计算购物车商品数量
            productNums () {
                let nums = 0
                for (let i in this.cartData.list) {
                    if(this.cartData.list[i].is_select){
                        nums += this.cartData.list[i].nums;
                    }
                }
                return nums
            },
            // 判断商户是否开启积分抵扣 1开启 2未开启
            isOpenPoint () {
                return this.$store.state.config.point_switch
            },
            // 获取使用的优惠券名称
            usedCouponsCompute () {
                let name = '未使用'
                if (Object.keys(this.usedCoupons).length) {
                    let coupons = []
                    for (let i in this.usedCoupons) {
                        coupons.push(this.usedCoupons[i])
                    }
                    name = coupons.join()
                }
                return name
            },
            // 判断是否开启发票功能
            invoiceSwitch () {
                return this.$store.state.config.invoice_switch || 2;
            },
            // 判断店铺开关
            storeSwitch() {
                return this.$store.state.config.store_switch || 2;
            },
            // 根据接口返回数据判断是否使用优惠券
            couponIsUsed () {
                return this.cartData.coupon instanceof Array
            }
        },
        watch: {
            // 监听数据状态(切换收货地址, 是否使用优惠券, 是否使用积分) 重新请求订单数据
            params: {
                handler () {
                    this.getCartList()
                },
                deep: true
            }
        }
    }
</script>

<style>
    .margin-cell-group {
        margin: 0 0 2upx 0;
    }

    .add-title-items{
        text-align: center;
    }
    .add-title-items .btn{
        height: ;
        font-size: 24upx;
        /* margin: 0 auto; */
    }
    .add-title-item .cell-item-hd {
        min-width: 40upx;
        color: #666;
        font-size: 28upx;
    }
    .add-title-item .cell-item-bd {
        color: #333;
        font-size: 28upx;
    }
    .add-title-item .cell-bd-text {
        bottom: 0;
    }
    .cell-bd-view:first-child {
        margin-bottom: 8upx;
    }
    .cell-ft-view:first-child {
        margin-bottom: 8upx;
    }
    .address {
        display: -webkit-box;
        -webkit-box-orient: vertical;
        -webkit-line-clamp: 2;
        overflow: hidden;
        width: 100%;
    }
    .img-list {
        margin-bottom: 20upx;
    }
    .button-bottom button{
        height: 100%;
        width: 280upx;
    }
    .button-bottom-c{
        display: inline-block;
        position: relative;
        padding: 10upx 26upx;
        height: 100%;
        width: 470upx;
        float: left;
        font-size: 22upx;
        color: #666;
        overflow: hidden;
    }
    .button-bottom-c-t{
        font-size: 22upx;
        color: #999;
        display: inline-block;
        float: left;
        height: 100%;
        line-height: 70upx;
    }
    .button-bottom-c-b{
        font-size: 26upx;
        color: #333;
        display: inline-block;
        float: right;
        height: 100%;
        line-height: 70upx;
    }
    .invoice .cell-ft-text{
        /* top: 4upx; */
        color: #666;
        font-size: 24upx;
    }
    .pop-t{
        border-bottom: 2upx solid #f4f4f4;
        background-color: #fff;
    }
    .pop-b{
        margin-bottom: 90upx;
    }
    .pop-b-t{
        background-color: #fff;
        width: 100%;
        padding-top: 10upx;
    }
    .coupon-c{
        /* padding: 50upx; */
        height: 546upx;
        box-sizing: border-box;
    }
    .coupon-c-item{
        margin: 30upx 50upx;
        /* width: 100%; */
        height: 150upx;
        margin-bottom: 20upx;
    }
    .cci-l{
        width: 60upx;
        height: 100%;
        background-color: #FF7159;
        font-size: 32upx;
        display: inline-block;
        box-sizing: border-box;
        float: left;
        border-top-left-radius: 16upx;
        border-bottom-left-radius: 16upx;
    }
    .cci-l-c{
        height: 60upx;
        line-height: 44upx;
        width: 150upx;
        text-align: center;
        transform-origin: 30upx 30upx;
        transform: rotate(90deg);
    }
    .cci-r{
        position: relative;
        height: 150upx;
        width: calc(100% - 70upx);
        margin-left: 10upx;
        display: inline-block;
        background-color: #fff;
    }
    .cci-r-img{
        position: absolute;
        width: 100%;
        height: 100%;
        background-color: #fff;
    }
    .cci-r-c{
        position: relative;
        z-index: 99;
    }
    .ccirc-t{
        font-size: 24upx;
        padding: 10upx 20upx;
        min-height: 56upx;
    }
    .ccirc-b{
        padding: 10upx;
        position: relative;
    }
    .ccirc-b-l{
        display: inline-block;
        max-width: 400upx;
    }
    .ccirc-b-tip{
        font-size: 28upx;
        width: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        min-height: 38upx;
    }
    .ccirc-b-tip text{
        font-size: 34upx;
    }
    .ccirc-b-time{
        font-size: 24upx;
    }
    .ccirc-b-r{
        display: inline-block;
        background-color: #FF7159;
        font-size: 26upx;
        padding: 4upx 10upx;
        border-radius: 4upx;
        position: absolute;
        right: 20upx;
        bottom: 12upx;
    }
    .pop-c .btn{
        width: 100%;
    }
    .leave-message{
        margin: 20upx 0;
    }
    .leave-message .cell-item{
        border-bottom: 0;
    }
    .cell-textarea{
        padding: 0 26upx 20upx;
    }

    /* #ifndef MP-WEIXIN */
    .cell-textarea textarea{
        width: 100%;
        height: 100upx;
        font-size: 26upx;
        color: #333;
    }
    /* #endif */
    /* #ifdef MP-WEIXIN */
    .cell-textarea input{
        width: 100%;
        font-size: 26upx;
        color: #333;
    }
    /* #endif */
    .coupon-enter{
        display: flex;
        height: 60upx;
        margin: 40upx;
    }
    .coupon-enter>view{
        display: inline-block;
    }
    .coupon-input{
        /* width: 450upx; */
        flex: 1;
        border: 2upx solid #e8e8e8;
        background-color: #fff;
        height: 100%;
    }
    .coupon-input input{
        height: 100%;
        font-size: 26upx;
        padding: 2upx 10upx;
    }
    .coupon-code{
        margin: 4upx 30upx;
    }
    .coupon-enter-btn{
        height: 100%;
        margin-left: 20upx;
    }
    .coupon-enter-btn .btn{
        font-size: 24upx;
        height: 100%;
        width: 108upx;
        line-height: 58upx;
    }
    .bg-c{
        background-color: #ccc;
    }
    .no-store{
        text-align: center;
        padding: 30upx 0;
        font-size: 26upx;
        color: #666;
        /* min-height: 60upx; */
    }
    .coupon-none{
        text-align: center;
        padding: 120upx 0;
    }
    .coupon-none-img{
        width: 274upx;
        height: 274upx;
    }
</style>
invoice.vue
<template>
    <view class="content">
        <view class="content-top">
            <view class='cell-group margin-cell-group'>
                <view class='cell-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>发票类型</view>
                    </view>
                    <view class='cell-item-ft'>
                        <view class="uni-form-item uni-column invoice-type">
                            <radio-group class="uni-list" @change="radioChange">
                                <label class="uni-list-cell uni-list-cell-pd" v-for="(item,index) in radioItems" :key="index">
                                    <view class="invoice-type-icon">
                                        <radio :id="item.name" :value="item.value" :checked="item.value == type"></radio>
                                    </view>
                                    <view class="invoice-type-c">
                                        <label class="label-2-text" :for="item.name">
                                            <text>{{item.name}}</text>
                                        </label>
                                    </view>
                                </label>
                            </radio-group>
                        </view>
                    </view>
                </view>
                <view class='cell-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>发票抬头</view>
                    </view>
                    <view class='cell-item-ft'>
                        <input class='cell-bd-input' v-model="name" placeholder='抬头名称'></input>
                    </view>
                </view>
                <view class='cell-item' v-show="type === '3'">
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>税号</view>
                    </view>
                    <view class='cell-item-ft'>
                        <input class='cell-bd-input' v-model="code" placeholder='纳税人识别号'></input>
                    </view>
                </view>
                
            </view>
            <view class='cell-group margin-cell-group'>
                <view class='cell-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>发票内容</view>
                    </view>
                    <view class='cell-item-ft'>
                        <view class="cell-ft-view">明细</view>
                    </view>
                </view>
            </view>
            <view class='cell-group margin-cell-group'>
                <view class='cell-item right-img'  @click="notNeedInvoice">
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>本次不开具发票</view>
                    </view>
                    <view class='cell-item-ft'>
                        <image class='cell-ft-next icon' src='/static/image/right.png'></image>
                    </view>
                </view>
            </view>
        </view>
        <view class="button-bottom">
            <button class="btn btn-square btn-b" @click="saveInvoice" hover-class="btn-hover2">保存</button>
        </view>
    </view>
</template>

<script>
export default {
    data() {
        return {
            radioItems: [
                {
                    name: '个人或事业单位',
                    value: '2'
                },
                {
                    name: '企业',
                    value: '3'
                }
            ],
            type: '3', // 发票类型 2个人 3企业
            name: '', // 抬头名称
            code: '' // 税号
        }
    },
    onLoad () {
        let invoice
        let pages = getCurrentPages()
        let pre = pages[pages.length - 2]
        
        // #ifdef H5
        invoice = pre.invoice
        // #endif
        
        // #ifdef MP-WEIXIN || APP-PLUS || APP-PLUS-NVUE
        invoice = pre.$vm.invoice
        // #endif
        
        // #ifdef MP-ALIPAY
        invoice = pre.rootVM.invoice;
        // #endif

        if (invoice && invoice.hasOwnProperty('type') && invoice.type !== '1') {
            // 发票不是未使用, 展示发票信息
            this.name = invoice.name
            this.code = invoice.code
            this.type = invoice.type
        }
        
    },
    methods: {
        // 单选框点击切换
        radioChange (evt) {
            this.radioItems.forEach(item => {
                if (item.value === evt.target.value) {
                    this.type = item.value
                }
            })
        },
        // 不需要发票信息
        notNeedInvoice () {
            let data = {
                type: '1',
                name: '不开发票',
                code: ''
            }
            
            this.setPageData(data)
        },
        // 保存发票信息
        saveInvoice () {
            if (!this.name) {
                this.$common.errorToShow('请输入发票抬头')
                return false
            }
            
            // 企业类型需要输入税号
            if (this.type === '3' && !this.code) {
                this.$common.errorToShow('请输入发票税号信息')
                return false
            }
            
            let data = {
                type: this.type,
                name: this.name
            }
            
            // 不是企业类型不需要税号
            data['code'] = this.type === '3' ? this.code : ''
            
            this.setPageData(data)
        },
        // 向上个页面赋值并返回
        setPageData (data) {
            let pages = getCurrentPages();//当前页
            let beforePage = pages[pages.length - 2];//上个页面
            
            // #ifdef MP-ALIPAY
            beforePage.rootVM.invoice = data;
            // #endif
            
            // #ifdef MP-WEIXIN || APP-PLUS || APP-PLUS-NVUE
            beforePage.$vm.invoice = data;
            // #endif
            
            // #ifdef H5 
            beforePage.invoice = data;
            // #endif
            
            uni.navigateBack({
                delta: 1
            })
        }
    }
}
</script>

<style>
/* .margin-cell-group{
    margin-bottom: 20upx;
} */
.invoice-type .uni-list-cell{
    display: inline-block;
    font-size: 26upx;
    color: #333;
    position: relative;
    margin-left: 50upx;
}
.invoice-type .uni-list-cell>view{
    display: inline-block;
}
.invoice-type-icon{
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
}
.invoice-type-c{
    margin-left: 50upx;
    line-height: 2;
}
.cell-item-ft .cell-bd-input{
    text-align: right;
    width: 500upx;
}
.button-bottom .btn {
    width: 100%;
}
</style>
storelist.vue
<template>
    <view class="content">
        <view class='search'>
            <view class='search-c'>
                <image class='icon search-icon' src='/static/image/zoom.png'></image>
                <input class='search-input' placeholder-class='search-input-p' placeholder='请输入门店名' v-model="key"></input>
            </view>
            <button class="btn btn-g" hover-class="btn-hover2" @click="storeSearch">搜索</button>
        </view>
        <view class='cell-group margin-cell-group'>
            <view class='cell-item add-title-item right-img' v-for="(item, key) in storeList" :key="key" @click="selectStore(item.id, item.store_name, item.mobile, item.all_address)">
                <view class="cell-item-hd">
                    <image class='cell-hd-icon' src='/static/image/homepage.png'></image>
                </view>
                <view class='cell-item-bd'>
                    <view class="cell-bd-view black-text">
                        <text class="cell-bd-text">{{item.store_name}}</text>
                    </view>
                    <view class="cell-bd-view">
                        <text class="cell-bd-text">电话:{{item.mobile}}</text>
                    </view>
                    <view class="cell-bd-view">
                        <text class="cell-bd-text">地址:{{item.all_address}}</text>
                    </view>
                </view>
                <view class='cell-item-ft'>
                    <image class='cell-ft-next icon' src='/static/image/location.png'></image>
                    <text class="cell-ft-text color-9">{{item.distance}}</text>
                </view>
            </view>
        </view>
    </view>
</template>

<script>
    export default {
        data () {
            return {
                storeList: [],
                key: '',
                longitude: '',
                latitude: '',
            }
        },
        onShow () {
            this.getStoreList();
        },
        methods: {
            //门店搜索
            storeSearch(){
                this.getStoreList();
            },
            //获取门店列表
            getStoreList(){
                let _this = this;
                uni.getLocation({
                    type: 'gcj02',
                    success: function (res) {
                        _this.longitude = res.longitude;
                        _this.latitude = res.latitude;
                    },
                    complete: function (res) {
                        let data = {
                            'key': _this.key,
                            'longitude': _this.longitude,
                            'latitude': _this.latitude
                        }
                        _this.$api.storeList(data, e => {
                            _this.storeList = e.data;
                        });
                    }
                });
            },
            //门店选择
            selectStore(id, name, mobile, address){
                let pages = getCurrentPages()
                let pre = pages[pages.length - 2]
                let store = {};
                store['id'] = id;
                store['name'] = name;
                store['mobile'] = mobile;
                store['address'] = address;
                
                // #ifdef MP-ALIPAY
                pre.rootVM.store = store;
                // #endif

                // #ifdef MP-WEIXIN || APP-PLUS || APP-PLUS-NVUE
                pre.$vm.store = store
                // #endif
                
                // #ifdef H5 
                pre.store = store
                // #endif
                
                uni.navigateBack({
                    delta: 1
                });
            }
        }
    }
</script>

<style>
.search{
    display: flex;
}
.search-c{
    width: 80%;
    margin-right: 2%;
}
.search-icon{
    left: 30upx;    
}
.search-input {
    padding: 10upx 30upx 10upx 90upx;
}
.search-input-p{
    padding: 0 !important;
}
.search .btn{
    width: 18%;
    border: none;
    background-color: #f1f1f1;
    font-size: 28upx;
    color: #333;
    border-radius: 6upx;
    line-height: 72upx;
}
.add-title-item .cell-item-hd {
    min-width: 50upx;
    color: #666;
    font-size: 28upx;
}
.cell-bd-view {
    margin-bottom: 6upx;
}
.cell-bd-view .cell-bd-text{
    font-size: 22upx;
    color: #999;
}
.black-text .cell-bd-text{
    font-size: 28upx;
    color: #333;    
}
</style>

index

custom.vue
<template>
    <view class="content" style="padding-top: 0upx;">
        <jshop :data="pageData"></jshop>
        <jihaiCopyright></jihaiCopyright>
    </view>
</template>
<script>
    import jshop from "@/components/jshop/jshop.vue"
    import jihaiCopyright from "@/components/jihai-copyright/jihaiCopyright.vue"
    import {
        goods
    } from '@/config/mixins.js'
    export default {
        mixins: [goods],
        components: {
            jihaiCopyright,
            jshop
        },
        data() {
            return {
                myShareCode: '', //分享Code
                imageUrl: '/static/image/share_image.png', //店铺分享图片
                pageData: [],
                pageCode: 'mobile_home', //页面布局编码
                statusBarHeight: '0',
                customBarOpacity: false,
                scrollTop: 0,
                showLoad: false, //是否显示loading
                share_name: ''
            }
        },
        computed: {
            appTitle() {
                return this.$store.state.config.shop_name;
            }
        },
        onLoad(e) {
            //增加页面编码,可自定义编码
            if (e.page_code) {
                this.pageCode = e.page_code
            }
            this.initData()
        },
        // 小程序沉浸式状态栏变色
        onPageScroll(e) {
            // console.log(e);
            e.scrollTop > 50 ? this.customBarOpacity = true : this.customBarOpacity = false
        },
        mounted() {
            // #ifdef H5 
            window.addEventListener('scroll', this.handleScroll)
            // #endif
        },
        methods: {
            // 搜索框滑动变色
            handleScroll() {
                var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
                scrollTop > 50 ? this.searchBarOpacity = true : this.searchBarOpacity = false
            },
            destroyed() {
                window.removeEventListener('scroll', this.handleScroll)
            },
            goSearch() {
                uni.navigateTo({
                    url: './search'
                });
            },
            // 首页初始化获取数据
            initData() {
                this.showLoad = true;
                //获取首页配置
                this.$api.getPageConfig({
                    code: this.pageCode,
                }, res => {
                    if (res.status == true) {
                        this.pageData = res.data.items;
                        this.share_name = res.data.name;
                        uni.setNavigationBarTitle({
                            title: res.data.name
                        });
                        //隐藏loading
                        setTimeout(() => {
                            this.showLoad = false;
                        }, 600);
                    }
                });
                
                this.getMyShareCode();
            },
            getMyShareCode() {
                let userToken = this.$db.get("userToken");
                if (userToken && userToken != '') {
                    // 获取我的分享码
                    this.$api.shareCode({}, res => {
                        if (res.status) {
                            this.myShareCode = res.data ? res.data : '';
                        }
                    });
                }
            }
        },
        onPullDownRefresh() {
            this.initData();
            uni.stopPullDownRefresh();
        },
        //分享
        onShareAppMessage() {
            let myInviteCode = this.myShareCode ? this.myShareCode : '';
            let ins = this.$common.shareParameterDecode('type=8&page_code=' + this.pageCode + '&invite=' + myInviteCode);
            let path = '/pages/share/jump?scene=' + ins;
            return {
                title: this.share_name,
                // #ifdef MP-ALIPAY
                //desc: this.$store.state.config.share_desc,
                // #endif
                //imageUrl: this.$store.state.config.share_image,
                path: path
            }
        }
    }
</script>

<style>
    .search {
        /* position: fixed; */
        /*  #ifdef  H5  */
        /* top: 44px; */
        /*  #endif  */
        /*  #ifndef  H5  */
        /* top: 0; */
        /*  #endif  */
    }

    .cell-item {
        border: none;
    }

    .cell-ft-text {
        font-size: 22upx;
        color: #999;
    }

    .status_bar {
        height: var(--status-bar-height);
        width: 100%;
        position: fixed;
        top: 0;
        z-index: 999;
        background: rgba(0, 0, 0, 0);
        transition: all .5s;
    }

    .custom-navbar {
        height: 40px;
        line-height: 34px;
        position: fixed;
        width: 100%;
        padding-left: 26upx;
        top: var(--status-bar-height);
        z-index: 999;
        background: rgba(0, 0, 0, 0);
        transition: all .5s;
    }

    .index-logo {
        width: 140upx;
        height: 70upx;
        /* margin: 0 auto; */
    }

    .index-logo-img {
        width: 100%;
        height: 100%;
    }

    .isOpacity {
        background: rgba(255, 255, 255, 1);
        transition: all .5s;
    }

    /* iPhone X in portrait & landscape */
    @media only screen and (min-device-width : 375px) and (max-device-width : 812px) and (-webkit-device-pixel-ratio : 3) {
        .status_bar {
            height: 50px;
        }

        .custom-navbar {
            top: 50px;
        }
    }

    /* iPhone X in landscape */
    @media only screen and (min-device-width : 375px) and (max-device-width : 812px) and (-webkit-device-pixel-ratio : 3) and (orientation : landscape) {
        .status_bar {
            height: 50px;
        }

        .custom-navbar {
            top: 50px;
        }
    }

    /* iPhone X in portrait */
    @media only screen and (min-device-width : 375px) and (max-device-width : 812px) and (-webkit-device-pixel-ratio : 3) and (orientation : portrait) {
        .status_bar {
            height: 50px;
        }

        .custom-navbar {
            top: 50px;
        }
    }
</style>
index.vue
<template>
    <view class="content" style="padding-top: 0upx;">
        <jshop :data="pageData"></jshop>
        <jihaiCopyright></jihaiCopyright>
        <red-bag v-if="redBagShow" @click="handleGet"></red-bag>
    </view>
</template>
<script>
    import jshop from '@/components/jshop/jshop.vue'
    import jihaiCopyright from '@/components/jihai-copyright/jihaiCopyright.vue'
    import uniCountdown from '@/components/uni-countdown/uni-countdown.vue'
    import redBag from '@/components/red-bag/index'
    import {
        goods
    } from '@/config/mixins.js'
    import {
        goBack
    } from '@/config/mixins.js'
    export default {
        mixins: [goods],
        components: {
            jihaiCopyright,
            jshop,
            uniCountdown,
            redBag
        },
        data() {
            return {
                myShareCode: '', //分享Code
                imageUrl: '/static/image/share_image.png', //店铺分享图片
                pageData: [],
                pageCode: 'mobile_home', //页面布局编码
                pintuan: [], //拼团列表,
                redBagShow: false, //红包
            }
        },
        computed: {
            appTitle() {
                return this.$store.state.config.shop_name
            }
        },
        onLoad(e) {
            this.initData()
            if(this.$store.state.config.shop_name){
                uni.setNavigationBarTitle({
                    title: this.$store.state.config.shop_name||''
                });
            }
        },
        methods: {
            //领取红包
            handleGet() {},
            destroyed() {
                window.removeEventListener('scroll', this.handleScroll)
            },
            goSearch() {
                uni.navigateTo({
                    url: './search'
                })
            },
            // 首页初始化获取数据
            initData() {
                //获取首页配置
                this.$api.getPageConfig({
                        code: this.pageCode
                    },
                    res => {
                        if (res.status == true) {
                            this.pageData = res.data.items;
                            //隐藏loading
                            setTimeout(() => {
                                this.showLoad = false;
                            }, 600);
                        }
                    }
                );
                
                this.getMyShareCode();
            },
            getMyShareCode() {
                let userToken = this.$db.get("userToken");
                if (userToken && userToken != '') {
                    // 获取我的分享码
                    this.$api.shareCode({}, res => {
                        if (res.status) {
                            this.myShareCode = res.data ? res.data : '';
                        }
                    });
                }
            }
        },
        onPullDownRefresh() {
            this.initData()
            //this.$db.del('all_cat');
            uni.stopPullDownRefresh()
        },
        //分享
        onShareAppMessage() {
            let myInviteCode = this.myShareCode ? this.myShareCode : '';
            let ins = this.$common.shareParameterDecode('type=1&invite=' + myInviteCode);
            let path = '/pages/share/jump?scene=' + ins;
            return {
                title: this.$store.state.config.share_title,
                // #ifdef MP-ALIPAY
                desc: this.$store.state.config.share_desc,
                // #endif
                imageUrl: this.$store.state.config.share_image,
                path: path
            }
        }
    }
</script>

<style>
    .search {
        /* position: fixed; */
        /*  #ifdef  H5  */
        /* top: 44px; */
        /*  #endif  */
        /*  #ifndef  H5  */
        /* top: 0; */
        /*  #endif  */
    }

    .cell-item {
        border: none;
    }

    .cell-ft-text {
        font-size: 22upx;
        color: #999;
    }

    /* .new-goods {
        min-height: 300upx;
        white-space: nowrap;
        width: 100%;
    }

    .new-goods-item {
        width: 200upx;
        display: inline-block;
        margin-right: 20upx;
    }

    .new-goods-item:last-child {
        margin-right: 0;
    }

    .news-goods-img {
        width: 200upx;
        height: 200upx;
    }

    .news-goods-img image {
        width: 100%;
        height: 100%;
    }

    .news-goods-bot {
        margin-top: 6upx;
    }

    .new-goods-name {
        display: block;
        font-size: 26upx;
    }

    .new-goods-price {
        display: block;
        font-size: 26upx;
        color: #e14d4d;
    } */
</style>
search.vue
<template>
    <view class="content">
        <view class='search'>
            <view class='search-c'>
                <image class='icon search-icon' src='/static/image/zoom.png'></image>
                <input v-bind:class="$store.state.searchStyle" class='search-input' placeholder-class='search-input-p' placeholder='请输入关键字搜索' v-model="key" focus :auto-focus="focus" :fixed="focus"></input>
            </view>
            <button class="btn btn-g" @click="search" hover-class="btn-hover2">搜索</button>
        </view>
        <view class="history-c" v-show="keys.length > 0">
            <view class="history-title">
                <view class='ht-left'>历史记录</view>
                <view class='ht-right' @click="deleteKey">清除</view>
            </view>
            <view class="history-body">
                <view class="hb-item" v-for="(item, key) in keys" :key="key" @click="toNav(item)">
                    {{item}}
                </view>
            </view>
        </view>
        <view class="history-c" v-show="recommend && recommend.length > 0">
            <view class="history-title">
                <view class='ht-left'>搜索发现</view>
            </view>
            <view class="history-body">
                <view class="hb-item" v-for="(item, key) in recommend" :key="key" @click="toNav(item)">
                    {{item}}
                </view>
            </view>
        </view>
    </view>
</template>

<script>
export default {
    data() {
        return {
            keys: [],
            key: '',
            navType: 'toNav',
            focus: true,
        }
    },
    computed: {
        recommend() {
            return this.$store.state.config.recommend_keys
        }
    },
    methods: {
        //搜索
        search: function () {
            let keys = this.key;
            if(keys != '') {
                let search_key = this.$db.get('search_key');
                if (!search_key) {
                    search_key = [];
                }
                let flag = true;
                for (var key in search_key) {
                    if (search_key[key] == keys) {
                        flag = false;
                    }
                }
                if (flag) {
                    search_key.unshift(keys);
                }
                this.$db.set('search_key', search_key);
                this.$db.set('search_term', keys);
                this.$common.navigateTo('/pages/classify/index?key=' + keys);
            }
        },

        //清除
        deleteKey: function () {
            //删除显示
            this.keys = [];
            //删除存储
            this.$db.del('search_key');
        },

        //跳转操作
        toNav: function (keys) {
            this.$db.set('search_term', keys);
            let search_key = this.$db.get('search_key');
            if (!search_key) {
                search_key = [];
            }
            var flag = true;
            for (var key in search_key) {
                if (search_key[key] == keys) {
                    flag = false;
                }
            }
            if (flag) {
                search_key.unshift(keys);
            }
            this.$db.set('search_key', search_key);
            this.$common.navigateTo('/pages/classify/index?key=' + keys);
        },
    },
    //加载触发
    onShow(e) {
        this.keys = this.$db.get('search_key');
        this.key = this.$db.get('search_term');
        this.focus = true;
    },
    //页面卸载触发
    onUnload() {
        this.$db.set('search_term', '');
    }
}
</script>

<style>
.search{
    display: flex;
}
.search-c{
    width: 80%;
    margin-right: 2%;
}
.search-icon{
    left: 30upx;    
}
.search-input {
    padding: 10upx 30upx 10upx 90upx;
}
.search-input-p{
    padding: 0 !important;
}
.search .btn{
    width: 18%;
    border: none;
    background-color: #f1f1f1;
    font-size: 28upx;
    color: #333;
    border-radius: 6upx;
    line-height: 72upx;
}
.history-c{
    /* background-color: #fff; */
    padding: 20upx 26upx;
}
.history-title{
    overflow: hidden;    
}
.ht-left{
    float: left;
    font-size: 28upx;
    color: #333;
}
.ht-right{
    float: right;
    color: #999;
    font-size: 26upx;
}
.history-body{
    overflow: hidden;
    margin-top: 20upx;
    min-height: 200upx;
}
.hb-item{
    display: inline-block;
    float: left;
    background-color: #fff;
    color: #888;
    margin-right: 20upx;
    margin-bottom: 14upx;
    font-size: 26upx;
    padding: 10upx 20upx;
}
.square{
    border-radius: 0;
}
.radius{
    border-radius: 12upx;
}
</style>

login

choose
index.vue
<template>
    <view class="content">
        <view class="login-m">
            <view class="login-item">
                <view class="logo">
                    <open-data type="userAvatarUrl"></open-data>
                </view>
            </view>
            <view class="login-tip">
                <view class="login-tip-big">
                    申请获取以下权限
                </view>
                <view class="login-tip-small">
                    获得你的公开信息 (昵称、头像等)
                </view>
            </view>
        </view>
        <view class="login-b flc">
            <!-- #ifdef MP-WEIXIN -->
            <button class="auth-btn refuse" @click="handleRefuse">拒绝</button>
            <button class="auth-btn " open-type="getUserInfo" @getuserinfo="getUserInfo" hover-class="btn-hover">允许</button>
            <!-- #endif -->
            <!-- #ifdef MP-ALIPAY -->
            <button class="auth-btn " @click="getALICode" hover-class="btn-hover">授权登录</button>
            <!-- #endif -->
        </view>
    </view>
</template>

<script>
export default {
  data() {
    return {
      open_id: ''
    }
  },
  computed: {
    logoImage() {
      return this.$store.state.config.shop_logo
    }
  },
  onLoad() {
    const _this = this
    // #ifdef MP-WEIXIN
    this.getCode(function(code) {
      var data = {
        code: code
      }
      _this.$api.login1(data, (res)=>{
        if (!res.status) {
          _this.$common.successToShow(res.msg, function() {
            uni.navigateBack({
              delta: 1
            })
          })
        } else {
          _this.open_id = res.data
        }
      })
    })
    // #endif
  },
  // #ifdef MP-WEIXIN
  // onUnload: function() {
  //   wx.reLaunch({
  //     url: '/pages/index/index'
  //   })
  // },
  // #endif
  methods: {
    getCode: function(callback) {
      uni.login({
        // #ifdef MP-ALIPAY
        scopes: 'auth_user',
        // #endif
        success: function(res) {
          if (res.code) {
            return callback(res.code)
          } else {
            //login成功,但是没有取到code
            this.$common.errorToShow('未取得code')
          }
        },
        fail: function(res) {
          this.$common.errorToShow('用户授权失败wx.login')
        }
      })
    },
    handleRefuse(){
      uni.showToast({
        title: '未授权',
        icon: 'none',
        duration: 1000,
      })
      setTimeout(() => {
        uni.hideToast();
        uni.navigateBack(-1);
      }, 1000);
    },
    getUserInfo: function(e) {
      //console.log(e);
      let _this = this
      //return false;
      if (e.detail.errMsg == 'getUserInfo:fail auth deny') {
        _this.$common.errorToShow('未授权')
      } else {
        var data = {
          open_id: _this.open_id,
          iv: e.detail.iv,
          edata: e.detail.encryptedData,
          signature: e.detail.signature
        }
        //有推荐码的话,带上
        var invitecode = _this.$db.get('invitecode')
        if (invitecode) {
          data.invitecode = invitecode
        }
        _this.toLogin(data)
      }
    },
    //实际的去登陆
    toLogin: function(data) {
      let _this = this
      _this.$api.login2(data, function(res) {
        if (res.status) {
          //判断是否返回了token,如果没有,就说明没有绑定账号,跳转到绑定页面
          if (typeof res.data.token == 'undefined') {
            uni.redirectTo({
              url: '/pages/login/login/index?user_wx_id=' + res.data.user_wx_id
            })
          } else {
            //登陆成功,设置token,并返回上一页
            _this.$db.set('userToken', res.data.token)
            uni.navigateBack({
              delta: 1
            })
            return false
          }
        } else {
          _this.$common.errorToShow('登录失败,请重试')
        }
      })
    },
    getALICode() {
        let that = this
        uni.login({
            scopes: 'auth_user',
            success: (res) => {
                if(res.authCode){
                    uni.getUserInfo({
                        provider: 'alipay',
                        success: function (infoRes) {
                            if(infoRes.errMsg == "getUserInfo:ok"){
                                let user_info = {
                                    'nickname': infoRes.nickName,
                                    'avatar': infoRes.avatar
                                }
                                that.aLiLoginStep1(res.authCode, user_info);
                            }
                        },
                        fail: function (errorRes) {
                            this.$common.errorToShow('未取得用户昵称头像信息');
                        }
                    });
                }else{
                    this.$common.errorToShow('未取得code');
                }
            },
            fail: function(res) {
                this.$common.errorToShow('用户授权失败my.login');
            }
        });
    },
    aLiLoginStep1(code, user_info) {
        let data = {
            'code': code,
            'user_info': user_info
        }
        this.$api.alilogin1(data, res => {
            this.alipayNoLogin = false;
            if (res.status) {
                this.open_id = res.data.user_wx_id
                //判断是否返回了token,如果没有,就说明没有绑定账号,跳转到绑定页面
                if (!res.data.hasOwnProperty('token')) {
                    this.$common.redirectTo('/pages/login/login/index?user_wx_id=' + res.data.user_wx_id);
                } else {
                    this.$db.set('userToken', res.data.token)
                    uni.navigateBack({
                      delta: 1
                    });
                }
            } else {
                this.$common.errorToShow(res.msg)
            }
        })
    },
  }
}
</script>

<style lang="scss">
.content {
  background-color: #fff;
  height: 100vh;
  padding: 100upx 60upx 0;
}
.login-item {
  display: flex;
  justify-content: center;
  padding-bottom: 40upx;
  border-bottom: 1upx solid #dddddd;
}
.logo {
  display: block;
  width: 180upx;
  height: 180upx;
  border-radius: 50%;
  overflow: hidden;
  border: 2px solid #fff;
  box-shadow: 3px 3px 10px rgba(0, 0, 0, 0.2);
}
.login-tip{
    padding:60upx 0;
    &-big{
        font-size: 28upx;
        line-height: 80upx;
    }
    &-small{
        font-size: 12px;
        color:#9e9e9e;
    }
}
.app-name {
  font-size: 28upx;
  color: #999;
}
.login-b .btn-g {
  margin-top: 40upx;
}
.auth-btn{
  flex:1;
    display: block;
    height: 80upx;
    line-height: 80upx;
    text-align: center;
    font-size: 12px;
    color:#FFF;
    background:#1aad19;
    border-radius: 40upx;
  &.refuse{
    background:#999;
    margin-right:40upx;
  }
}
</style>
login
index.vue
<template>
  <view class="content">
    <view class="login-t">
      <image class="login-logo" :src="logoImage" mode="aspectFill"></image>
    </view>
    <view class="login-m">
      <view class="login-item">
        <input type="number" v-model="mobile" :maxlength="maxMobile" placeholder="请输入手机号码" focus placeholder-class="login-item-i-p" />
      </view>
      <view class="login-item flc">
        <input class="login-item-input" placeholder-class="login-item-i-p" type="text" v-model="code" placeholder="请输入验证码" />
        <view :class="sendCodeBtn" @click="sendCode" v-if="verification">发送验证码</view>
        <view class="btn btn-g" v-if="!verification">{{ timer }} 秒后重新获取</view>
      </view>

    </view>
    <view class="login-b">
      <!-- #ifdef H5|APP-PLUS|APP-PLUS-NVUE -->
      <view v-if="user_wx_id">
        <button :class="regButtonClass" @click="toBind()" hover-class="btn-hover">登录</button>
      </view>
      <view v-else>
        <button :class="regButtonClass" @click="login()" hover-class="btn-hover">登录</button>
        <view class="login-other flc">
          <view class="fz12 item" @click="selectLoginType">
            密码登录
          </view>
          <view class="fz12 item" @click="toReg">
            注册
          </view>
        </view>
      </view>
      <!-- #endif -->
      <!-- #ifdef MP -->
      <button :class="regButtonClass" @click="showTopTips()" hover-class="btn-hover">登录</button>
      <!-- #endif -->
    </view>
  </view>
</template>

<script>
import { goBack, jumpBackPage } from '@/config/mixins.js'
export default {
  mixins: [goBack,jumpBackPage],
  data() {
    return {
      maxMobile: 11,
      mobile: '', // 用户手机号
      code: '', // 短信验证码
      user_wx_id: '', //授权id
      verification: true, // 通过v-show控制显示获取还是倒计时
      timer: 60, // 定义初始时间为60s
      btnb: 'btn btn-square btn-c btn-all', //按钮背景
      type: '', // 有值是第三方登录账号绑定
      isWeixinBrowser: this.$common.isWeiXinBrowser()
    }
  },
  onLoad(option) {
    if (option.user_wx_id) {
      this.user_wx_id = option.user_wx_id
      uni.setNavigationBarTitle({
        title: '绑定手机号'
      })
    }


    // H5第三方授权登录绑定
    // if (option.type && option.type === 'bind') {
    //     this.type = option.type
    //     uni.setNavigationBarTitle({
    //         title: '绑定手机号'
    //     })
    // }
  },
  computed: {
    // 验证手机号
    rightMobile() {
      let res = {}
      if (!this.mobile) {
        res.status = false
        res.msg = '请输入手机号'
      } else if (!/^1[3456789]{1}\d{9}$/gi.test(this.mobile)) {
        res.status = false
        res.msg = '手机号格式不正确'
      } else {
        res.status = true
      }
      return res
    },
    // 动态计算发送验证码按钮样式
    sendCodeBtn() {
      let btn = 'btn btn-g'
      if (this.mobile.length === this.maxMobile && this.rightMobile.status) {
        return btn + ' btn-b'
      } else {
        return btn
      }
    },
    // 动态更改登录按钮bg
    regButtonClass() {
      return this.mobile && this.mobile.length === this.maxMobile && this.code
        ? this.btnb + ' btn-b'
        : this.btnb
    },
    logoImage() {
      return this.$store.state.config.shop_logo
    }
  },
  onShow() {
    let _this = this
    let userToken = _this.$db.get('userToken')
    if (userToken) {
      uni.switchTab({
        url: '/pages/member/index/index'
      })
      return true
    }
    _this.timer = parseInt(_this.$db.get('timer'))
    if (_this.timer != null && _this.timer > 0) {
      _this.countDown()
      _this.verification = false
    }
  },
  methods: {
    // 发送短信验证码
    sendCode() {
      if (!this.rightMobile.status) {
        this.$common.errorToShow(this.rightMobile.msg)
      } else {
        this.$common.loadToShow('发送中...')
        setTimeout(() => {
          this.$common.loadToHide()
          this.$api.sms({ mobile: this.mobile, code: 'login' }, res => {
            if (res.status) {
              this.timer = 60
              this.verification = false
              this.$common.successToShow(res.msg)
              this.countDown() // 执行验证码计时
              // this.btnb = 'btn btn-square btn-all btn-b';
            } else {
              this.$common.errorToShow(res.msg)
            }
          })
        }, 1000)
      }
    },
    // 去注册
    toReg() {
      this.$common.navigateTo('/pages/login/register/index')
    },
    // 验证码倒计时
    countDown() {
      let auth_timer = setInterval(() => {
        // 定时器设置每秒递减
        this.timer-- // 递减时间
        uni.setStorage({
          key: 'timer',
          data: this.timer,
          success: function() {}
        })
        if (this.timer <= 0) {
          this.verification = true // 60s时间结束还原v-show状态并清除定时器
          clearInterval(auth_timer)
        }
      }, 1000)
    },
    // 登录
    login() {
      var _this = this
      if (!_this.rightMobile.status) {
        _this.$common.errorToShow(_this.rightMobile.msg)
      } else {
        // 短信验证码登录
        if (!_this.code) {
          _this.$common.errorToShow('请输入短信验证码!')
        } else {
          let data = {
            mobile: _this.mobile,
            code: _this.code
          }

          let invicode = _this.$db.get('invitecode')
          if (invicode) {
            data.invitecode = invicode
          }

          _this.$api.smsLogin(data, res => {
            if (res.status) {
              this.$db.set('userToken', res.data)
              _this.redirectHandler()
            } else {
              _this.$common.errorToShow(res.msg)
            }
          })
        }
      }
    },
    // 重定向跳转 或者返回上一个页面
    redirectHandler() {
      this.$common.successToShow('登录成功!', () => {
        this.$db.set('timer', 0)
        this.$db.del('invitecode')
        this.handleBack()
      })
    },
    // 跳转到普通登录
    toLogin() {
      uni.navigateTo({
        url: '../../login/login/index'
      })
    },
    //提交按钮
    showTopTips: function() {
      let _this = this
      if (_this.mobile == '') {
        _this.$common.errorToShow('请输入手机号码')
        return false
      }
      if (this.code == '') {
        _this.$common.errorToShow('请输入验证码')
        return false
      }
      if (_this.user_wx_id == 0) {
        _this.$common.errorToShow('登录失败,请稍后再试', function() {
          uni.navigateBack({
            delta: 1
          })
        })
        return false
      }
      var platform = 2
      //1就是h5登陆(h5端和微信公众号端),2就是微信小程序登陆,3是支付宝小程序,4是app,5是pc
      // #ifdef MP-ALIPAY
      platform = 3
      // #endif
      // #ifdef APP-PLUS||APP-PLUS-NVUE
      platform = 4
      // #endif
      var data = {
        mobile: _this.mobile,
        code: _this.code,
        platform: platform, //平台id,标识是小程序登陆的
        user_wx_id: _this.user_wx_id //微信小程序接口存不了session,所以要绑定的id只能传到前台
      }
      //有推荐码的话,带上
      var invitecode = _this.$db.get('invitecode')
      if (invitecode) {
        data.invitecode = invitecode
      }
      _this.$api.smsLogin(data, function(res) {
        if (res.status) {
          _this.$db.set('userToken', res.data)
          _this.redirectHandler()
        } else {
          //报错了
          _this.$common.errorToShow(res.msg)
        }
      })
    },
    // 公众号第三方登录账号绑定
    toBind() {
      if (this.mobile == '') {
        this.$common.errorToShow('请输入手机号码')
        return false
      }
      if (this.code == '') {
        this.$common.errorToShow('请输入验证码')
        return false
      }

      let data = {
        mobile: this.mobile,
        code: this.code,
        user_wx_id:this.user_wx_id
      }

      // 获取邀请码
      let invicode = this.$db.get('invitecode')
      if (invicode) {
        data.invitecode = invicode
      }

      this.$api.smsLogin(data, res => {
        if (res.status) {
          this.$db.set('userToken', res.data)
          this.redirectHandler()
        } else {
          this.$common.errorToShow(res.msg)
        }
      })
    },
    // 切换登录方式
    selectLoginType() {
      this.$common.redirectTo('./index1')
    }
  }
}
</script>

<style lang="scss">
.content {
  /*  #ifdef  H5  */
  height: calc(100vh - 90upx);
  /*  #endif  */
  /*  #ifndef  H5  */
  height: 100vh;
  /*  #endif  */
  background-color: #fff;

  padding: 0upx 100upx;
}
.login-t {
  text-align: center;
  padding: 50upx 0;
}
.login-logo {
  width: 180upx;
  height: 180upx;
  border-radius: 20upx;
  background-color: #f8f8f8;
  /* margin: 0 auto; */
}
.login-m {
  margin-bottom: 100upx;
}
.login-item {
  border-bottom: 2upx solid #d0d0d0;
  overflow: hidden;
  padding: 10upx;
  color: #333;
  margin-bottom: 30upx;
}
.login-item-input {
  display: inline-block;
  flex: 1;
  box-sizing: border-box;
}
.login-item .btn {
  border: none;
  width: 40%;
  text-align: right;
  padding: 0;
  &.btn-b {
    background: none;
    color: #333 !important;
  }
}
.login-b .btn {
  color: #999;
}
.btn-b {
  color: #fff !important;
}
.login-other {
  margin-bottom: 40upx;
  .item {
    padding: 20upx 0;
  }
}
.btn-square {
  color: #333;
}
</style>
index1.vue
<template>
  <view class="content">
    <view class="login-t">
      <image class="login-logo" :src="logoImage" mode="aspectFill"></image>
    </view>
    <view>
      <view class="login-m">
        <view class="login-item">
          <input type="number" v-model="mobile" :maxlength="maxMobile" placeholder="请输入手机号码"  placeholder-class="login-item-i-p" />
        </view>
        <view class="login-item flc">
          <input class="login-item-input" :password="true" placeholder-class="login-item-i-p" type="text" v-model="pwd" placeholder="请输入密码" />
        </view>
        <view class="login-item" v-if="isCaptcha">
          <input class="login-item-input" placeholder-class="login-item-i-p" type="text" v-model="captcha" placeholder="输入验证码" />
          <img class='codeimg' :src="captchaUrl" alt="">
        </view>
      </view>
      <view class="login-b">
        <button :class="loginButtonClass" @click="loginHandler" hover-class="btn-hover">登录</button>
        <view class="login-other flc">
          <view class="fz12 item" @click="selectLoginType">
            验证码登录
          </view>
          <view class="fz12 item" @click="toReg">
            注册
          </view>
        </view>
      </view>
    </view>
    <!--  微信浏览器里 -->
    <!-- #ifdef H5 -->
    <template v-if="weixinBrowser">
      <view class="fz12 g5">
        第三方账号登录:
      </view>
      <view class="flc third-block">
        <view class="third-item" v-for="(item, key,index) in thirdPartyLogins" :key="index" @click="handleThirdLogin(item)">
          <image class="third-item-img" :src="getThirdLoginImg(key)" mode="aspectFill"></image>
        </view>
      </view>
    </template>
        <!-- #endif -->
    <!-- #ifdef APP-PLUS||APP-PLUS-NVUE -->
      <view class="fz12 g5">
        第三方账号登录:
      </view>
      <view class="flc third-block" v-if="thirdPartyLogins.length>0">
        <view class="third-item" v-for="(item, key,index) in thirdPartyLogins" :key="key" @click="handleThirdLoginApp(item)">
        <image class="third-item-img" src="/static/image/ic-wechat.png" mode="aspectFill" v-if="item=='weixin'"></image>
        </view>
      </view>
    <!-- #endif -->
    
    
  </view>
</template>

<script>
import { baseUrl } from '@/config/config.js'
import { goBack,jumpBackPage} from '@/config/mixins.js'
export default {
  mixins: [goBack,jumpBackPage],
  data() {
    return {
      maxMobile: 11,
      mobile: '', // 手机号
      pwd: '', // 密码
      isCaptcha: false, // 是否需要验证码
      captcha: '', // 输入的验证码
      captchaUrl: '', // 验证码图片地址
      btnb: 'btn btn-square btn-c btn-all', // 按钮bg
      weixinBrowser: false, // 是否是微信浏览器
      thirdPartyLogins: [], // 第三方登录列表      
    }
  },
  onLoad(options) {
    if (options.invitecode) {
      this.$db.set('invitecode', options.invitecode)
    }
    // 判断浏览器环境
    this.weixinBrowser = this.$common.isWeiXinBrowser()
    
    if (this.weixinBrowser) {
      this.getAuths()
    }
    // #ifdef APP-PLUS||APP-PLUS-NVUE
    this.getAppAuths();
    // #endif
    
  },
  onShow() {
    if (this.$db.get('userToken')) {
      uni.switchTab({
        url:'/pages/index/index'
      })
    }
  },
  computed: {
    // 动态更改登录按钮bg
    loginButtonClass() {
      return this.mobile && this.mobile.length === 11 && this.pwd
        ? this.btnb + ' btn-b'
        : this.btnb
    },
    logoImage() {
      return this.$store.state.config.shop_logo
    },
    getThirdLoginImg(key) {
        
      return key => {
        if (key == 'Wxofficial') {
          return '/static/image/ic-wechat.png'
        }else if(key == 'weixin'){
          return '/static/image/ic-wechat.png'
        }
      }
    }
  },
  methods: {
    // 验证手机号
    rightMobile() {
      let res = {}
      if (!this.mobile) {
        res.status = false
        res.msg = '请输入手机号'
      } else if (!/^1[3456789]{1}\d{9}$/gi.test(this.mobile)) {
        res.status = false
        res.msg = '手机号格式不正确'
      } else if (!this.pwd) {
        res.status = false
        res.msg = '请输入密码'
      } else {
        res.status = true
      }
      return res
    },
    // 登录处理
    loginHandler() {
      if (this.mobile && this.mobile.length === 11 && this.pwd) {
        if (!this.rightMobile().status) {
          this.$common.errorToShow(this.rightMobile().msg)
        } else {
          this.toLogin()
        }
      }
    },
    // 获取验证码图片地址
    getCaptchaUrl() {
      this.captchaUrl = this.$config.apiBaseUrl + 'captcha.html'
    },
    // 去注册
    toReg() {
      this.$common.navigateTo('/pages/login/register/index')
    },
    // 去登录
    toLogin() {
      let data = {
        mobile: this.mobile,
        password: this.pwd
      }

      if (this.isCaptcha) {
        data.captcha = this.captcha
      }

      // 获取邀请码
      let invicode = this.$db.get('invitecode')
      if (invicode) {
        data.invitecode = invicode
      }

      this.$api.login(data, res => {
        if (res.status) {
          this.$db.set('userToken', res.data)
          this.redirectHandler()
        } else {
          this.$common.errorToShow(res.msg, () => {
            // 需要输入验证码 或者 验证码错误刷新
            if (res.data === 10013 || res.data === 10012) {
              this.isCaptcha = true
            }

            // 登录需要验证码
            if (this.isCaptcha) {
              this.getCaptchaUrl()
            }
          })
        }
      })
    },
    // 重定向跳转 或者返回上一个页面
    redirectHandler() {
      this.$db.del('invitecode')
      this.handleBack()
    },
    // 登录方式切换
    selectLoginType() {
      this.$common.redirectTo('/pages/login/login/index')
    },
    // 获取第三方登录列表
    getAuths() {
      let data = {
        url: baseUrl + 'wap/pages/author'
      }
      this.$api.getTrustLogin(data, res => {
        if (res.status) {
          this.thirdPartyLogins = res.data
        }
      })
    },
    // 第三方登录授权
    handleThirdLogin(url) {
      this.$common.redirectTo('')
      let redirect = this.$store.state.redirectPage
      this.$db.set('redirectPage', redirect)
      window.location.href = url
    },
    //获取APP信任登录
    getAppAuths(){
        let _this = this;
        _this.thirdPartyLogins = [];
        uni.getProvider({
            service: 'oauth',
            success: function (res) {
                if(res.errMsg == 'getProvider:ok'){
                    _this.thirdPartyLogins = res.provider;
                    
                }
            }
        });
    },
    //app第三方登录
    handleThirdLoginApp(type){
        uni.showLoading({
            title: '加载中'
        });
        let _this = this;
        uni.login({
          provider: type,
          success: function (loginRes) {
            // 获取用户信息
            uni.getUserInfo({
              provider: type,
              success: function (infoRes) {
                  if(infoRes.errMsg == 'getUserInfo:ok'){
                      var data = {
                          user:infoRes.userInfo,
                          type:type
                      };
                      var invitecode = _this.$db.get('invitecode')
                      if (invitecode) {
                        data.invitecode = invitecode
                      }
                      _this.$api.appTrustLogin(data,res=>{
                          uni.hideLoading();
                          if (res.status) {
                            //判断是否返回了token,如果没有,就说明没有绑定账号,跳转到绑定页面
                            if (typeof res.data.token == 'undefined') {
                              uni.redirectTo({
                                url: '/pages/login/login/index?user_wx_id=' + res.data.user_wx_id
                              })
                            } else {
                              //登陆成功,设置token,并返回上一页
                              _this.$db.set('userToken', res.data.token)
                              uni.navigateBack({
                                delta: 1
                              })
                              return false
                            }
                          } else {
                            _this.$common.errorToShow('登录失败,请重试')
                          }
                      });
                  }else{
                        uni.hideLoading();
                       _this.$common.errorToShow('登录失败,请重试')
                  }
              }
            });
          }
        });
    }
  }
}
</script>

<style lang="scss">
.content {
  /*  #ifdef  H5  */
  height: calc(100vh - 90upx);
  /*  #endif  */
  /*  #ifndef  H5  */
  height: 100vh;
  /*  #endif  */
  background-color: #fff;

  padding: 0upx 100upx;
}
.login-t {
  text-align: center;
  padding: 50upx 0;
}
.login-logo {
  width: 180upx;
  height: 180upx;
  border-radius: 20upx;
  background-color: #f8f8f8;
  /* margin: 0 auto; */
}
.login-m {
  margin-bottom: 100upx;
}
.login-item {
  border-bottom: 2upx solid #d0d0d0;
  overflow: hidden;
  padding: 10upx;
  font-size: 28upx;
  color: #333;
  margin-bottom: 30upx;
  display: flex;
  align-items: center;
}
.login-item-input {
  display: inline-block;
  // width: 60%;
  flex: 1;
  box-sizing: border-box;
}
.codeimg{
    width: 210rpx;
}
.login-item .btn {
  display: inline-block;
  font-size: 28upx;
  border: none;
  width: 40%;
  padding: 0;
  line-height: 1.7;
  float: right;
}
.login-b .btn {
  color: #999;
}
.btn-b {
  color: #fff !important;
}
.registered-item {
  overflow: hidden;
  width: 100%;
}
.registered {
  float: right;
}
.registered-item .btn-square {
  color: #333;
}
.third-block {
  justify-content: center;
  padding-top: 40upx;
  .third-item {
    width: 80upx;
    height: 80upx;
    background: $g2;
    border-radius: 50%;
    padding: 16upx;
    &-img {
      display: block;
      width: 100%;
      height: 100%;
    }
  }
}
.login-other {
  margin-bottom: 40upx;
  .item {
    padding: 20upx 0;
  }
}
</style>
register
index.vue
<template>
    <view class="content">
        <view class="reg-t">
            <image class="reg-logo" :src="logoImage" mode="aspectFill"></image>
        </view>
        <view class="reg-m">
            <view class="reg-item">
                <input type="number" v-model="mobile" :maxlength="maxMobile" placeholder="请输入手机号码" focus placeholder-class="reg-item-i-p" />
            </view>
            <view class="reg-item flc">
                <input class="reg-item-input" placeholder-class="reg-item-i-p" type="text" v-model="code" placeholder="请输入验证码" />
                <view :class="sendCodeBtn" @click="sendCode" v-if="verification">发送验证码</view>
                <view class="btn btn-g" v-if="!verification">{{ timer }} 秒后重新获取</view>
            </view>
            <view class="reg-item">
                <input class="login-item-input" :password="true" placeholder-class="login-item-i-p" type="text" v-model="pwd" placeholder="请输入密码" />
            </view>
        </view>
        <view class="reg-b">
            <button :class="regButtonClass" @click="toReg()" hover-class="btn-hover">注册</button>
        </view>
        <view class="registered-item">
            <view class="btn btn-g btn-square registered" @click="toLogin">已有账号,立即登录</view>
        </view>
    </view>
</template>

<script>
import { goBack } from '@/config/mixins.js'
export default {
  mixins: [goBack],
  data() {
    return {
      maxMobile: 11,
      mobile: '', // 用户手机号
      code: '', // 短信验证码
      pwd: '', // 用户密码
      verification: true, // 通过v-show控制显示获取还是倒计时
      timer: 60, // 定义初始时间为60s
      btnb: 'btn btn-c btn-square btn-all' //按钮背景
    }
  },
  onLoad(options) {
    let _this = this
    _this.timer = parseInt(_this.$db.get('timer'))
    if (_this.timer != null && _this.timer > 0) {
      _this.countDown()
      _this.verification = false
    }

    if (options.invitecode) {
      this.$db.set('invitecode', options.invitecode)
    }
  },
  computed: {
    // 验证手机号
    rightMobile() {
      let res = {}
      if (!this.mobile) {
        res.status = false
        res.msg = '请输入手机号'
      } else if (!/^1[3456789]{1}\d{9}$/gi.test(this.mobile)) {
        res.status = false
        res.msg = '手机号格式不正确'
      } else {
        res.status = true
      }
      return res
    },
    // 动态更改登录按钮bg
    regButtonClass() {
      return this.mobile && this.mobile.length === 11 && this.pwd && this.code
        ? this.btnb + ' btn-b'
        : this.btnb
    },
    // 动态修改发送验证码按钮
    sendCodeBtn() {
      let btn = 'btn btn-g'
      if (this.mobile.length === this.maxMobile && this.rightMobile.status) {
        return btn + ' btn-b'
      } else {
        return btn
      }
    },
    logoImage() {
      return this.$store.state.config.shop_logo
    }
  },
  onShow() {
    let _this = this
    let userToken = _this.$db.get('userToken')
    if (userToken && userToken != '') {
      uni.switchTab({
        url: '/pages/member/index/index'
      })
      return true
    }
    _this.timer = parseInt(_this.$db.get('timer'))
    if (_this.timer != null && _this.timer > 0) {
      _this.countDown()
      _this.verification = false
    }
  },
  methods: {
    // 发送短信验证码
    sendCode() {
      if (!this.rightMobile.status) {
        this.$common.errorToShow(this.rightMobile.msg)
      } else {
        this.$common.loadToShow('发送中...')
        setTimeout(() => {
          this.$common.loadToHide()
          this.$api.sms({ mobile: this.mobile, code: 'reg' }, res => {
            if (res.status) {
              this.timer = 60
              this.verification = false
              this.$common.successToShow(res.msg)
              this.countDown() // 执行验证码计时
              this.btnb = 'btn btn-square btn-all btn-b'
            } else {
              this.$common.errorToShow(res.msg)
            }
          })
        }, 1000)
      }
    },
    // 验证码倒计时
    countDown() {
      let auth_timer = setInterval(() => {
        // 定时器设置每秒递减
        this.timer-- // 递减时间
        uni.setStorage({
          key: 'timer',
          data: this.timer,
          success: function() {}
        })
        if (this.timer <= 0) {
          this.verification = true // 60s时间结束还原v-show状态并清除定时器
          clearInterval(auth_timer)
        }
      }, 1000)
    },
    toReg() {
      if (!this.rightMobile.status) {
        this.$common.errorToShow(this.rightMobile.msg)
      } else if (!this.code) {
        this.$common.errorToShow('请输入短信验证码')
      } else if (!this.pwd) {
        this.$common.errorToShow('请输入登录密码')
      } else {
        let data = {
          mobile: this.mobile,
          code: this.code,
          password: this.pwd
        }

        // 获取邀请码
        let invicode = this.$db.get('invitecode')
        if (invicode) {
          data.invitecode = invicode
                }
        this.$api.smsLogin(data, res => {
          if (res.status) {
            this.$db.set('userToken', res.data)
            this.$common.successToShow('注册成功', () => {
              // 清除随机uid 和 邀请码
              this.$db.del('uuid')
              this.$db.del('invitecode')
              let redirect = this.$store.state.redirectPage
                ? this.$store.state.redirectPage
                : '/pages/member/index/index'
              this.$store.commit({
                type: 'redirect',
                page: ''
              })
              uni.reLaunch({
                url: redirect
              })
            })
          } else {
            this.$common.errorToShow(res.msg)
          }
        })
      }
    },
    toLogin() {
      this.$common.navigateTo('/pages/login/login/index1')
    }
  }
}
</script>

<style lang="scss">
.content {
  /*  #ifdef  H5  */
  height: calc(100vh - 90upx);
  /*  #endif  */
  /*  #ifndef  H5  */
  height: 100vh;
  /*  #endif  */
  background-color: #fff;

  padding: 0upx 100upx;
}
.reg-t {
  text-align: center;
  padding: 50upx 0;
}
.reg-logo {
  width: 180upx;
  height: 180upx;
  border-radius: 20upx;
  background-color: #f8f8f8;
  /* margin: 0 auto; */
}
.reg-m {
  margin-bottom: 100upx;
}
.reg-item {
  border-bottom: 2upx solid #d0d0d0;
  overflow: hidden;
  padding: 10upx;
  color: #333;
  margin-bottom: 30upx;
  .btn{
    border: none;
    width: 40%;
    text-align:right;
    &.btn-b {
      background: none;
      color: #333 !important;
    }
  }
}
.reg-item-input {
  flex:1;
}

.reg-b .btn {
  color: #999;
}

.registered-item {
  overflow: hidden;
  width: 100%;
}
.registered {
  float: right;
}
.btn-square {
  color: #333;
  height: 80upx;
    line-height: 80upx;
  padding:0;
  font-size:$fz12;
}
</style>

member

address
index.vue
<template>
    <view class="content">
        <view class="content-top">
            <view class='cell-group'>
                <view class='cell-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>收货人</view>
                    </view>
                    <view class='cell-item-bd'>
                        <input type="text" class='cell-bd-input' placeholder='请填写收货人姓名' v-model="name"></input>
                    </view>
                </view>
                <view class='cell-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>手机号</view>
                    </view>
                    <view class='cell-item-bd'>
                        <input type="text" class='cell-bd-input' placeholder='请填写收货人手机号' v-model="mobile"></input>
                    </view>
                </view>
                
                <view class='cell-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>省市区</view>
                    </view>

                    <view class='cell-item-bd'>
                        <input :value="pickerValue" @focus="showThreePicker"></input>
                        <area-picker ref="areaPicker" :areaId="areaId" :defaultIndex="defaultIndex" @onConfirm="onConfirm"></area-picker>
                    </view>
                    
                    <view class='cell-item-ft'>
                        <image class='cell-ft-next icon' src='/static/image/ic-pull-down.png' @click="showThreePicker"></image>
                    </view>
                </view>
                
                <view class='cell-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>详细地址</view>
                    </view>
                    <view class='cell-item-bd'>
                        <input type="text" class='cell-bd-input' placeholder='请填写收货详细地址' v-model="address"></input>
                    </view>
                </view>
                <view class='cell-item' @click="defaultChange">
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>设为默认</view>
                    </view>
                    <view class='cell-item-ft' >
                        <label class="radio" ><radio value="1" :checked="checked" color="#FF7159"/></label>
                    </view>
                </view>
            </view>
        </view>
        <view class="button-bottom">
            
            <button class="btn btn-square btn-w" @click="delShip" v-if="id && id != 0" hover-class="btn-hover2" :disabled='submitStatus' :loading='submitStatus'>删除</button>
            
            <button class="btn btn-square btn-b" @click="saveShip" hover-class="btn-hover2" :disabled='submitStatus' :loading='submitStatus'>保存</button>
        </view>
    </view>

</template>

<script>
import areaPicker from "@/components/area-picker/areaPicker.vue";
export default {
    components: {
        areaPicker
    },
    data() {
        return {
            id: 0,
            name: '',
            mobile: '',
            region: ['北京市', '北京市', '东城区'],
            areaId: 110101,
            address: '',
            is_def: 2,
            multiArray: [
                [],
                [],
                []
            ],
            multiIndex: [110000, 110100, 110101],
            checked: false,
            pickerValue: '',
            defaultIndex: [0, 0, 0],
            submitStatus: false
        }
    },
    computed: {},
    methods: {
        // 省市区联动初始化
        showThreePicker() {
            this.$refs.areaPicker.showPicker();
        },
        onConfirm(e) {
            let province_name = e[0].name;
            let city_name = e[1].name;
            let county_name = e[2].name;
            this.pickerValue = e[0].name+ " "+ e[1].name+" "+e[2].name
            let data = {
                province_name: province_name,
                city_name: city_name,
                county_name: county_name
            }
            let regionName = [province_name, city_name, county_name];
            this.$api.getAreaId(data, res => {
                if (res.status) {
                    this.areaId = res.data
                } else {
                    uni.showModal({
                        title: '提示',
                        content: '地区选择出现问题,请重新选择地区',
                        showCancel: false
                    });
                }
            });
        },
        // 信息验证
        checkData (data) {
            this.submitStatus = false;
            if (!data.name) {
                this.$common.errorToShow('请输入收货人姓名')
                return false
            } else if (!data.mobile) {
                this.$common.errorToShow('请输入收货人手机号')
                return false
            } else if (data.mobile.length !== 11) {
                this.$common.errorToShow('收货人手机号格式不正确')
                return false
            } else if (!data.area_id) {
                this.$common.errorToShow('请选择地区信息')
                return false
            } else if (!data.address) {
                this.$common.errorToShow('请输入收货地址详细信息')
                return false
            } else {
                return true
            }
        },
        //默认
        defaultChange(){
            if(this.checked){
                this.checked = false;
                this.is_def = 2;
            }else{
                this.checked = true;
                this.is_def = 1;
            }
        },
        //编辑获取收货地址信息
        getShipInfo() {
            let data = {
                'id': this.id
            }
            this.$api.shipDetail(data, res => {
                if(res.status){
                    let region = res.data.area_name.split(" ");
                    this.name = res.data.name;
                    this.mobile = res.data.mobile;
                    this.region = region;
                    this.areaId = res.data.area_id;
                    
                    this.pickerValue = this.region[0]+ " "+ this.region[1]+" "+this.region[2]
                    this.$refs.areaPicker.init();//初始化插件
                    
                    this.address = res.data.address;
                    this.is_def = res.data.is_def;
                    if(res.data.is_def == 1){
                        this.checked = true;
                    }else{
                        this.checked = false;
                    }
                }else{
                    this.$common.errorToShow('获取收货地址信息出现问题');
                    this.submitStatus = false;
                }
            });
        },
        //删除地址
        delShip() {
            this.submitStatus = true;
            this.$api.removeShip({'id': this.id}, res => {
                if(res.status){
                    this.$common.successToShow(res.msg, ress => {
                        this.submitStatus = false;
                        uni.navigateBack({
                            delta: 1
                        });
                    });
                }else{
                    this.$common.errorToShow(res.msg);
                    this.submitStatus = false;
                }
            });
        },
        //存储收货地址
        saveShip() {
            this.submitStatus = true;
            let data = {
                name: this.name,
                address: this.address,
                mobile: this.mobile,
                is_def: this.is_def,
                area_id: this.areaId
            }
            
            if(this.id && this.id != 0){
                //编辑存储
                data.id = this.id
                
                if (this.checkData(data)) {
                    this.$api.editShip(data, res => {
                        if(res.status){
                            this.$common.successToShow(res.msg, ress => {
                                this.submitStatus = false;
                                uni.navigateBack({
                                    delta: 1
                                });
                            });
                        }else{
                            this.$common.errorToShow(res.msg);
                            this.submitStatus = false;
                        }
                    });
                }
            }else{
                //添加
                if (this.checkData(data)) {
                    this.$api.saveUserShip(data, res => {
                        if(res.status){
                            this.$common.successToShow(res.msg, ress => {
                                this.submitStatus = false;
                                uni.navigateBack({
                                    delta: 1
                                });
                            });
                        }else{
                            this.$common.errorToShow(res.msg);
                            this.submitStatus = false;
                        }
                    });
                }
            }
        }
    },
    onLoad(e) {
        if(e.ship_id){
            //编辑
            this.id = e.ship_id;
            this.getShipInfo();
        }else{
            //添加
            this.pickerValue = this.region[0]+ " "+ this.region[1]+" "+this.region[2];
            uni.setNavigationBarTitle({
                title: '添加地址'
            });
        }
    },
    onBackPress() {
        if (this.$refs.areaPicker.pickerShow) {
            this.$refs.areaPicker.closePicker();
            return true;
        }
    },

}
</script>

<style>
.user-head{
    height: 100upx;
}
.user-head-img{
    height: 90upx;
    width: 90upx;
    border-radius: 50%;
}
.cell-hd-title{
    color: #333;
}
.cell-item-bd{
    color: #666;
    font-size: 26upx;
}
.button-bottom .btn {
    width: 50%;
}
.cell-bd-input{
    width: 100%;
}
/* #ifdef MP-ALIPAY */
input{
    font-size: 24upx;
}
/* #endif */
</style>
list.vue
<template>
    <view class="content">
        <view class="content-top" v-if="list.length">
            <view class="uni-list-cell uni-list-cell-pd" v-for="(item, key) in list" :key="key">
                <view class='cell-group min-cell-group'>
                    <view class='cell-item'>
                        <view class='cell-item-hd' @click="isSelect(item)">
                            <view class='cell-hd-title'>{{item.name}} <text class="phone-num">{{item.mobile}}</text></view>
                        </view>
                        <view class='cell-item-ft' v-show="type != 'order'">
                            <image class='cell-ft-next icon' src='/static/image/compile.png' @click="toEdit(item.id)"></image>
                            <text class="cell-ft-text"></text>
                        </view>
                    </view>
                    <view class='cell-item' @click="isSelect(item)">
                        <view class='cell-item-bd'>
                            <view class="cell-bd-view">
                                <view class="cell-tip" v-show="item.is_def === 1">默认</view>
                                <text class="cell-bd-text">{{item.area_name + item.address}}</text>
                            </view>
                        </view>
                    </view>
                </view>
            </view>
        </view>
        <view class="address-none" v-else>
            <image class="address-none-img" src="/static/image/order.png" mode=""></image>
        </view>
        <view class="button-bottom">
            <!-- #ifdef MP-WEIXIN -->
            <button class="btn btn-square btn-b" @click="wechatAddress" hover-class="btn-hover2">从微信获取</button>
            <!-- #endif -->
            <button class="btn btn-square btn-w" @click="toAdd()" hover-class="btn-hover2">新增收货地址</button>
        </view>
    </view>
</template>

<script>
export default {
    data() {
        return {
            list: [] ,// 用户收货地址列表
            type: ''
        }
    },
    onLoad (e) {
        if(e.type){
            this.type = e.type;
        }
    },
    onShow () {
        this.userShipList();
    },
    methods: {
        // 获取收货地址列表
        userShipList () {
            this.$api.userShip({}, res => {
                if (res.status) {
                    this.list = res.data
                }
            })
        },
        // 收货地址删除
        delShip (id) {
            this.$common.modelShow('提示', '确认删除此收货地址?', () => {
                let data = {
                    id: id
                }
                this.$api.removeShip(data, res => {
                    if (res.status) {
                        this.$common.successToShow(res.msg, () => {
                            this.userShipList();
                        });
                    } else {
                        this.$common.errorToShow(res.msg);
                    }
                })
            })
        },
        //编辑
        toEdit (id) {
            this.$common.navigateTo('./index?ship_id=' + id);
        },
        //添加
        toAdd() {
            this.$common.navigateTo('./index');
        },
        //选择
        isSelect(data) {
            if(this.type == 'order'){
                let pages = getCurrentPages();//当前页
                let beforePage = pages[pages.length - 2];//上个页面
                
                // #ifdef MP-ALIPAY
                beforePage.rootVM.userShip = data;
                beforePage.rootVM.params.area_id = data.area_id;
                // #endif
                
                // #ifdef H5
                beforePage.userShip = data;
                beforePage.params.area_id = data.area_id;
                // #endif

                // #ifdef MP-WEIXIN || APP-PLUS || APP-PLUS-NVUE
                beforePage.$vm.userShip = data;
                beforePage.$vm.params.area_id = data.area_id;
                // #endif 
                
                uni.navigateBack({
                    delta: 1
                });
            }
        },
        // #ifdef MP-WEIXIN
        wechatAddress: function () {
            wx.chooseAddress({
                success: res => {
                    if (res.errMsg == "chooseAddress:ok") {
                        //获取成功
                        //存储这个收获地区信息到数据库
                        let data = {
                            province_name: res.provinceName,
                            city_name: res.cityName,
                            county_name: res.countyName,
                            postal_code: res.postalCode
                        };
                        let areaId = 0;
                        this.$api.getAreaId(data, res1 => {
                            if (res1.status) {
                                //存储用户收货信息
                                let userShipId = 0;
                                let userShipData = {
                                    area_id: res1.data,
                                    user_name: res.userName,
                                    detail_info: res.detailInfo,
                                    tel_number: res.telNumber,
                                    is_def: 2
                                }
                                this.$api.saveUserShipWx(userShipData, res2 => {
                                    if (res2.status) {
                                        this.$common.errorToShow('存储微信地址成功', r => {
                                            setTimeout(rp => {
                                                this.userShipList();
                                            }, 1000);
                                        });
                                    }else{
                                        uni.showModal({
                                            title: '提示',
                                            content: '存储微信地址失败',
                                            showCancel: false
                                        });
                                    }
                                });
                            }else{
                                uni.showModal({
                                    title: '提示',
                                    content: '获取微信地址失败',
                                    showCancel: false
                                });
                            }
                        });
                    } else {
                        uni.showModal({
                            title: '提示',
                            content: '获取微信地址失败',
                            showCancel: false
                        });
                    }
                }
            });
        },
        // #endif
    }
}
</script>

<style>
.cell-tip{
    background-color: #FF7159;
    color: #fff;
    font-size: 24upx;
    display: inline-block;
    float: left;
    /* border-radius: 10upx; */
    padding: 4upx 10upx;
    margin-right: 10upx;
    transform: scale(.9);
}
.min-cell-group .cell-ft-text{
    font-size: 24upx;
    margin-right: 10upx;
}
.min-cell-group .cell-item-bd{
    color: #666;
    padding-right: 0;
}
.min-cell-group .default{
    color: #666;
}
.min-cell-group uni-radio .uni-radio-input{
    width: 36upx;
    height: 36upx;
}
.min-cell-group .default .checked-radio{
    display: inline-block;
    float: left;
    position: relative;
    bottom: 2upx;
}
.green{
    background-color: #999;
}
.cell-hd-title{
    font-size: 28upx;
}
.phone-num{
    margin-left: 20upx;
    color: #999;
    font-size: 24upx;
}
.address-none{
    text-align: center;
    padding: 200upx 0;
}
.address-none-img{
    width: 274upx;
    height: 274upx;
}
</style>
after_sale
detail.vue
<template>
    <view class="content">
        <view class="content-top">
            <!-- <view class="back-img">
                <view class="back-img-c">
                    <view class="back-img-t">退款单状态</view>
                    <view class="back-img-b">{{status_name}} {{refund_name}} {{reship_name}}...</view>
                </view>
            </view> -->
            <view class='cell-group margin-cell-group'>
                <view class='cell-item add-title-item'>
                    <view class='cell-item-bd'>
                        <view class="cell-bd-view black-text">
                            <text class="cell-bd-text color-3">退款单状态</text>
                        </view>
                        <view class="cell-bd-view">
                            <text class="cell-bd-text color-9">{{status_name}} {{refund_name}} {{reship_name}}...</text>
                        </view>
                        <view class="cell-bd-view">
                            <!-- <text class="cell-bd-text">下单时间:{{ orderInfo.ctime }}</text> -->
                        </view>
                    </view>
                </view>
            </view>
            <view class='cell-group margin-cell-group'>
                <view class='cell-item'>
                    <view class='cell-item-hd'><view class='cell-hd-title'>售后类型</view></view>
                    <view class='cell-item-ft'><view class="cell-ft-p">{{type_name}}</view></view>
                </view>
                <view class='cell-item'>
                    <view class='cell-item-hd'><view class='cell-hd-title'>退款金额</view></view>
                    <view class='cell-item-ft'><view class="cell-ft-p red-price">{{refund}}元</view></view>
                </view>
            </view>
            <view class='cell-group margin-cell-group' v-if="images.length > 0">
                <view class='cell-item right-img'><view class='cell-item-hd'><view class='cell-hd-title'>图片凭证</view></view></view>
                <view class="">
                    <view class="evaluate-c-b">
                        <view class="goods-img-item" v-for="(item, key) in images" :key="key">
                            <image :src="item.url" mode="aspectFit" @click="clickImg(item.url)"></image>
                        </view>
                    </view>
                </view>
            </view>
            <view class='cell-group margin-cell-group'>
                <view class='cell-item right-img'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>问题描述</view>
                    </view>
                </view>
                <view class="cell-textarea">
                    <text v-if="reason">{{reason}}</text>
                    <text v-else>暂无描述</text>
                </view>
            </view>
            <view class='cell-group margin-cell-group' v-show="status == 2 && reship_status == 1">
                <view class='cell-item right-img'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>退货邮寄信息</view>
                    </view>
                </view>
                <view class='cell-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>收件人</view>
                    </view>
                    <view class='cell-item-bd'>
                        <input class='cell-bd-input' type="text" disabled="false" :value="reship_info.reship_name" />
                    </view>
                </view>
                <view class='cell-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>联系方式</view>
                    </view>
                    <view class='cell-item-bd'>
                        <input class='cell-bd-input' type="text" disabled="false" :value="reship_info.reship_mobile" />
                    </view>
                </view>
                <view class='cell-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>邮寄地址</view>
                    </view>
                    <view class='cell-item-bd'>
                        <input class='cell-bd-input' type="text" disabled="false" :value="reship_info.reship_area + reship_info.reship_address" />
                    </view>
                </view>
            </view>
            <view class='cell-group margin-cell-group' v-show="status == 2 && reship_status == 1">
                <view class='cell-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>快递公司</view>
                    </view>
                    <view class='cell-item-bd'>
                        <input class='cell-bd-input' type="text" v-model="logi_code" placeholder="请填写快递公司名称"/>
                    </view>
                </view>
                <view class='cell-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>物流单号</view>
                    </view>
                    <view class='cell-item-bd'>
                        <input class='cell-bd-input' type="text" v-model="logi_no" placeholder="请填写物流单号" />
                    </view>
                </view>
            </view>
            <view class='cell-group margin-cell-group' v-show="status == 2 && reship_status > 1">
                <view class='cell-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>快递公司</view>
                    </view>
                    <view class='cell-item-bd'>
                        <input class='cell-bd-input' type="text" disabled="false" :value="logi_code"/>
                    </view>
                </view>
                <view class='cell-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>物流单号</view>
                    </view>
                    <view class='cell-item-bd'>
                        <input class='cell-bd-input' type="text" disabled="false" :value="logi_no"/>
                    </view>
                </view>
            </view>
        </view>
        <view class="button-bottom" v-show="status == 2 && reship_status == 1">
            <button class="btn btn-b" @click="submitBtn" :disabled='submitStatus' :loading='submitStatus'>提交</button>
        </view>
        <view class="button-bottom" v-show="(order_status == 1 && status == 3) || (order_status == 1 && status == 2 && refund_status != 1 && refund_status != 0) || (order_status == 1 && status == 2 && reship_status == 3)">
            <button class="btn btn-b" @click="repeat">再次申请售后</button>
        </view>
    </view>
</template>

<script>
export default {
    data() {
        return {
            delivers: ["请选择物流公司","顺丰", "中通", "圆通","韵达"],
            deliverIndex: 0,
            type_name:'',     //售后类型显示
            refund:0,         //退款金额
            images:[],        //图片
            reason: '暂无',       //问题描述
            ttype:1,          //售后类型
            status:1,         //售后单状态
            status_name: '审核中',   //售后单状态文字描述
            reship_status:0,        //退货单状态
            reship_name:'',
            refund_status:0,        //退款单状态
            refund_name:'',
            reship_info:[],         //退货单明细,如果售后单未审核呢,那么显示的是售后单明细,如果售后单审核通过了,显示退款单明细
            items:[],             //退货明细
            mark:"暂无",            //拒绝原因
            logi_no:'',            //回填物流信息
            logi_code:'',          //物流公司
            reship_id:'',
            mode: 'aspectFill',
            order_id: '', //订单号
            order_status: '', //订单状态
            submitStatus: false
        }
    },
    methods: {
        //提交按钮
        submitBtn() {
            this.submitStatus = true;
            if (this.logino == '') {
                this.$common.errorToShow('请输入退货快递信息');
                this.submitStatus = false;
                return false;
            }
            let data = {
                logi_no: this.logi_no,
                logi_code:this.logi_code,
                reship_id: this.reship_id,
            };
            this.$api.sendShip(data, res => {
                if (res.status) {
                    this.$common.successToShow('提交成功', ress => {
                        this.submitStatus = false;
                        uni.navigateBack({
                            delta: 1
                        });
                    });
                } else {
                    this.$common.errorToShow(res.msg);
                    this.submitStatus = false;
                }
            });
        },
        repeat() {
            this.$common.navigateTo('../after_sale/index?order_id='+this.order_id);
        },
        // 图片点击放大
        clickImg (img) {
            // 预览图片
            uni.previewImage({
                urls: img.split()
            });
        }
    },
    //页面加载
    onLoad(options) {
        let data = {
            aftersales_id: options.aftersales_id
        }
        this.$api.afterSalesInfo(data, res => {
            if(res.status){
                let info = res.data.info;
                if (info.type == 1){
                    this.ttype = 1;
                    this.type_name = '仅退款';
                }else{
                    this.ttype = 2;
                    this.type_name = '退款退货';
                }
                this.refund = info.refund;
                this.images = info.images;
                this.reason = info.reason;
                this.reship_info = res.data.reship;
                this.order_id = info.order_id;
                this.order_status = info.order_status;
                if(info.mark){
                    this.mark = info.mark;
                }
                if(info.status == 1){
                    this.status = 1;
                    this.status_name = '审核中';
                }else if(info.status == 2){
                    this.status = 2;
                    this.status_name = '申请通过';
                    //退款单状态
                    if (info.bill_refund) {
                        if (info.bill_refund.status == 1) {
                            this.refund_status = 1;
                            this.refund_name = '退款中';
                        } else if (info.bill_refund.status == 2) {
                            this.refund_status = 2;
                            this.refund_name = '退款成功';
                        }
                    }
        
                    //退货单状态
                    if(info.bill_reship){
                        this.reship_id = info.bill_reship.reship_id
                        if(info.bill_reship.status == 1) {
                            this.reship_status = 1;
                            this.reship_name = '待发退货';
                        } else if (info.bill_reship.status == 2) {
                            this.reship_status = 2;
                            this.reship_name = '待收退货';
                            this.logi_no = info.bill_reship.logi_no;
                            this.logi_code = info.bill_reship.logi_code;
                        } else {
                            this.reship_status = 3;
                            this.reship_name = '已收退货';
                            this.logi_no = info.bill_reship.logi_no;
                            this.logi_code = info.bill_reship.logi_code;
                        }
                    }
                }else{
                    this.status = 3;
                    this.status_name = '申请驳回';
                }
                //售后单明细,如果有退货单明细,就用退货单明细,否则就用售后单明细
                // if(info.bill_reship.items){
                //   page.data.items = info.bill_reship.items;
                // }else{
                //   page.data.items = info.items;
                // }
            } else {
                this.$common.errorToShow(res.msg);
            }
        });
    }
}
</script>

<style>
.back-img{
    width: 100%;
    height: 200upx;
    position: relative;
    background-color: #FF7159;
}
.back-img image{
    width: 100%;
    height: 100%;
    position: absolute;
}
.back-img-c{
    width: 100%;
    height: 100%;
    color: #fff;
    position: relative;
    z-index: 99;
    padding: 50upx;
}
.back-img-t{
    font-size: 32upx;
}
.back-img-b{
    font-size: 24upx;
}
.list-goods-name{
    width: 100% !important;
}
.invoice-type .uni-list-cell{
    display: inline-block;
    font-size: 26upx;
    color: #333;
    position: relative;
    margin-left: 50upx;
}
.invoice-type .uni-list-cell>view{
    display: inline-block;
}
.invoice-type-icon{
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
}
.invoice-type-c{
    margin-left: 50upx;
    line-height: 2;
}
.cell-item-ft .cell-bd-input{
    text-align: right;
    width: 500upx;
    font-size: 28upx;
}
.cell-item-bd .cell-bd-input{
    width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.right-img{
    border-bottom: 0;
}
.cell-textarea{
    padding: 0 26upx 20upx;
    font-size: 26upx;
    color: #333;
    word-wrap: break-word;
}
.evaluate-c-b{
    overflow: hidden;
    padding: 0 20upx;
}
.upload-img{
    width: 146upx;
    height: 146upx;
    margin: 14upx;
    text-align: center;
    color: #999999;
    font-size: 22upx;
    border: 2upx solid #E1E1E1;
    border-radius: 4upx;
    display: inline-block;
    float: left;
    padding: 24upx 0;
}
.goods-img-item{
    width: 174upx;
    height: 174upx;
    padding: 14upx;
    float: left;
    position: relative;
}
.goods-img-item:nth-child(4n){
    margin-right: 0;
}
.goods-img-item image{
    width: 100%;
    height: 100%;
}
.del{
    width: 30upx !important;
    height: 30upx !important;
    position: absolute;
    right: 0;
    top: 0;
    z-index: 999;
}
.black-text .cell-bd-text{
    font-size: 28upx;
}
</style>
index.vue
<template>
    <view class="content">
        <form @submit="submit" report-submit='true'>
            <view class="content-top">
                <view class="img-list cart-list">
                    <checkbox-group class="cart-checkbox" @change="checkboxChange">
                        <view class="cart-checkbox-item" v-for="(item, key) in items" :key="key">
                            <label class="uni-list-cell uni-list-cell-pd">
                                <view class="cart-checkbox-c"><checkbox :value='item.id' :checked="item.checked" color="#FF7159"/></view>
                                <view class="img-list-item">
                                    <image class="img-list-item-l little-img have-none" :src="item.image_url" mode="aspectFill"></image>
                                    <view class="img-list-item-r little-right">
                                        <view class="little-right-t">
                                            <view class="goods-name list-goods-name">{{item.name}}</view>
                                        </view>
                                        <view class="goods-item-c">
                                            <view class="goods-buy">
                                                <!-- 商品规格 -->
                                                <view class="goods-salesvolume">
                                                    {{item.addon}} x{{item.nums}}
                                                </view>
                                            </view>
                                        </view>
                                    </view>
                                </view>
                            </label>
                        </view>
                    </checkbox-group>
                </view>
                <view class='cell-group margin-cell-group'>
                    <view class='cell-item'>
                        <view class='cell-item-hd'>
                            <view class='cell-hd-title'>服务类型</view>
                        </view>
                        <view class='cell-item-ft'>
                            <view class="uni-form-item uni-column invoice-type">
                                <!-- <radio-group class="uni-list" @change="radioChange">
                                    <label class="uni-list-cell uni-list-cell-pd" v-for="(item,index) in type_list" :key="index">
                                        <view>
                                            <radio :id="item.name" :value="item.name" :checked="item.checked"></radio>
                                        </view>
                                        <view>
                                            <label class="label-2-text" :for="item.name">
                                                <text>{{item.value}}</text>
                                            </label>
                                        </view>
                                    </label>
                                </radio-group> -->
                                <!-- #ifndef MP-ALIPAY -->
                                <radio-group class="uni-list" @change="radioChange">
                                    <label class="uni-list-cell uni-list-cell-pd" v-for="(item, index) in type_list" :key="index">
                                        <view class="invoice-type-icon">
                                            <radio class="a-radio" :id="item.name" :value="item.value" :checked="item.checked" :disabled="item.disabled"></radio>
                                        </view>
                                        <view class="invoice-type-c">
                                            <label class="label-2-text" :for="item.name">
                                                <text>{{item.name}}</text>
                                            </label>
                                        </view>
                                    </label>
                                </radio-group>
                                <!-- #endif -->
                                <!-- #ifdef MP-ALIPAY -->
                                <jhlable></jhlable>
                                <!-- #endif -->
                            </view>
                        </view>
                    </view>
                    <view class='cell-item'>
                        <view class='cell-item-hd'>
                            <view class='cell-hd-title'>退款金额</view>
                        </view>
                        <view class='cell-item-ft'>
                            <input class='cell-bd-input red-price' v-model="refund" :disabled="refund_input_noedit"></input>
                        </view>
                    </view>
                </view>
                <view class='cell-group margin-cell-group'>
                    <view class='cell-item right-img'>
                        <view class='cell-item-hd'>
                            <view class='cell-hd-title'>上传凭证</view>
                        </view>
                    </view>
                    <view class="">
                        <view class="evaluate-c-b">
                            <view class="goods-img-item" v-for="(item, key) in images" :key="key">
                                <image class="del" src="/static/image/del.png" mode="" @click="delImage(item)"></image>
                                <image class="" :src="item.url" mode="" @click="clickImg(item.url)"></image>
                            </view>
                            <view class="upload-img" v-show="isImage" @click="upImage">
                                <image class="icon" src="/static/image/camera.png" mode=""></image>
                                <view class="">上传照片</view>
                            </view>
                        </view>
                    </view>
                </view>
                <view class='cell-group margin-cell-group'>
                    <view class='cell-item right-img'>
                        <view class='cell-item-hd'>
                            <view class='cell-hd-title'>问题描述</view>
                        </view>
                    </view>
                    <view class="cell-textarea ">
                        <textarea v-model="reason" placeholder="请您在此描述问题(最多200字)" maxlength="200"/>
                    </view>
                </view>
            </view>
            <view class="button-bottom">
                <button class="btn btn-b btn-square" formType="submit" :disabled='submitStatus' :loading='submitStatus'>提交</button>
            </view>
        </form>
    </view>
</template>

<script>
import jhlable from '@/components/jihai-lable.vue'
export default {
    data() {
        return {
            type_list: [
                { value: '1', name: '仅退款', checked: true, disabled: false },
                { value: '2', name: '退货退款', checked: false, disabled:false },
            ],
            order_id:'',
            items:[],   //退货明细
            item_ids:[],  //选择的退货
            aftersale_type:1,     //售后类型1退款,2退款退货
            refund:0,   //退款金额,等于已支付的金额减去已退款的金额
            refund_show:0,
            images:[],      //图片
            reason:'',      //原因
            image_max: 5,    //用于前台判断上传图片按钮是否显示
            refund_input_noedit: true,
            mode: 'aspectFill',
            submitStatus: false
        }
    },
    components: { jhlable },
    computed: {
        isImage() {
            let num = this.image_max - this.images.length;
            if(num > 0) {
                return true;
            }else{
                return false;
            }
        }
    },
    methods: {
        // 单选框点击切换
        radioChange: function(evt) {
            this.type_list.forEach(item => {
                if (item.value === evt.target.value) {
                    item.checked = true;
                    this.aftersale_type = evt.target.value;
                }else{
                    item.checked = false;
                }
            });
            if(this.type_list[0].checked){
                this.refund_input_noedit = true;
            }else{
                this.refund_input_noedit = false;
            }
        },
        
        //订单商品信息
        getOrderInfo() {
            let data = {
                order_id: this.order_id
            }
            this.$api.afterSalesStatus(data, res => {
                if (res.status) {
                    //如果不是未支付的,已取消的,已完成的状态,就都可以售后
                    if (res.data.text_status != 1 && res.data.text_status != 6 && res.data.text_status != 7){
                        //判断是已付款未发货,如果是,就禁用退货
                        let type_list = this.type_list;
                        if (res.data.text_status == 2){
                            type_list[1].disabled = true; 
                        }
                        
                        //设置已选中的商品
                        let nums = 0;
                        for(var i=0;i<res.data.items.length;i++){
                            //  if(res.data.items[i].sendnums > res.data.items[i].reship_nums){
                            //    nums = res.data.items[i].sendnums - res.data.items[i].reship_nums;
                            //  }
                            res.data.items[i].id = res.data.items[i].id.toString();
                            nums = res.data.items[i].nums;
                            res.data.items[i].checked = true;
                            this.item_ids = this.item_ids.concat({ id: res.data.items[i].id, nums: nums });
                        }
                        this.items = res.data.items;
                        this.refund = res.data.payed - res.data.refunded;
                        this.refund_show = res.data.payed - res.data.refunded;
                        this.type_list = type_list;
                    }else{
                        this.$common.errorToBack('订单不可以进行售后');
                    }
                } else {
                    this.$common.errorToBack('没有找到此订单');
                }
            });
        },
        
        //退货商品选择
        checkboxChange (e) {
            let nums = 0;
            this.item_ids = [];
            for (var i = 0; i < e.detail.value.length; i++) {
                let k = e.detail.value[i];
                for(var j = 0; j < this.items.length; j++){
                    if(this.items[j].id == k) {
                        if(this.items[j].sendnums > this.items[j].reship_nums) {
                            nums = this.items[j].sendnums - this.items[j].reship_nums;
                            this.item_ids = this.item_ids.concat({ id: k, nums: nums });
                        }
                    }
                }
            }
        },

        //提交
        submit(e) {
            this.submitStatus = true;
            let images = [];
            for(var i = 0; i<this.images.length; i++) {
                images = images.concat(this.images[i].image_id);
            }

            //判断退款金额
            let reg = /^[0-9]+(.[0-9]{1,2})?$/;
            if (!reg.test(this.refund)) {
                this.$common.errorToShow('请输入正确金额');
                this.submitStatus = false;
                return false;
            } else {
                if (this.refund > this.refund_show) {
                    this.$common.errorToShow('退款金额过大');
                    this.submitStatus = false;
                    return false;
                } 
            }

            //组装数据,提交数据
            let data = {
                order_id:this.order_id,
                type: this.aftersale_type,
                items:this.item_ids,
                images:images,
                refund: this.refund,
                reason:this.reason
            };
            // #ifdef MP-WEIXIN
            data['formId'] = e.detail.formId;
            // #endif
            this.$api.addAfterSales(data, res => {
                if(res.status){
                    this.$common.successToShow('提交成功', ress => {
                        this.submitStatus = false;
                        uni.navigateBack({
                            delta: 1
                        });
                    });
                }else{
                    this.$common.errorToShow(res.msg);
                    this.submitStatus = false;
                }
            });
        },
        
        //上传图片
        upImage() {
            let num = this.image_max - this.images.length;
            if(num > 0){
                this.$api.uploadImage(num, res => {
                    if(res.status){
                        this.images.push(res.data);
                        this.$common.successToShow(res.msg);
                    }else{
                        this.$common.errorToShow(res.msg);
                    }
                });
            }
        },

        //删除图片
        delImage(e) {
            let newImages = [];
            for(var i = 0; i < this.images.length; i++) {
                if(this.images[i].image_id != e.image_id){
                    newImages.push(this.images[i]);
                }
            }
            this.images = newImages;
        },
        // 图片点击放大
        clickImg (img) {
            // 预览图片
            uni.previewImage({
                urls: img.split()
            });
        }
    },
    onLoad(e) {
        this.order_id = e.order_id;
        this.getOrderInfo();
    }
}
</script>

<style>
.list-goods-name{
    width: 100% !important;
}
.cart-checkbox-item{
    position: relative;
}
.invoice-type .uni-list-cell{
    display: inline-block;
    font-size: 26upx;
    color: #333;
    position: relative;
    margin-left: 50upx;
}
.invoice-type .uni-list-cell>view{
    display: inline-block;
}
.invoice-type-icon{
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
}
.invoice-type-c{
    margin-left: 50upx;
    line-height: 2;
}
.cell-item-ft .cell-bd-input{
    text-align: right;
    width: 500upx;
    font-size: 28upx;
}
.right-img{
    border-bottom: 0;
}
.cell-textarea{
    padding: 0 26upx 20upx;
}
.cell-textarea textarea{
    width: 100%;
    height: 200upx;
    font-size: 26upx;
    color: #333;
}
.evaluate-c-b{
    overflow: hidden;
    padding: 0 20upx;
}
.upload-img{
    width: 146upx;
    height: 146upx;
    margin: 14upx;
    text-align: center;
    color: #999999;
    font-size: 22upx;
    border: 2upx solid #E1E1E1;
    border-radius: 4upx;
    display: inline-block;
    float: left;
    padding: 24upx 0;
}
.goods-img-item{
    width: 174upx;
    height: 174upx;
    padding: 14upx;
    float: left;
    position: relative;
}
.goods-img-item:nth-child(4n){
    margin-right: 0;
}
.goods-img-item image{
    width: 100%;
    height: 100%;
}
.del{
    width: 30upx !important;
    height: 30upx !important;
    position: absolute;
    right: 0;
    top: 0;
    z-index: 999;
}

/* #ifdef MP-ALIPAY */

/* #endif */
</style>
list.vue
<template>
    <view class="content">
        <view class="order-list">
            <view class="goods-detail" v-for="(item, key) in order" :key="key" v-if="item.order && item.order.items">
                <view class="order-item">
                    <view class='cell-group'>
                        <view class='cell-item'>
                            <view class='cell-item-hd'>
                                <view class='cell-hd-title'>售后单号:{{item.aftersales_id}}</view>
                                <button class='btn btn-g btn-small' hover-class="btn-hover" @click="copyData(item.aftersales_id)">复制</button>
                            </view>
                            <view class='cell-item-ft'>
                                <text class='cell-ft-text' v-if="item.status == 1">待审核</text>
                                <text class='cell-ft-text' v-else-if="item.status == 2">审核通过</text>
                                <text class='cell-ft-text' v-else-if="item.status == 3">审核拒绝</text>
                            </view>
                        </view>
                    </view>
                    <view class='img-list' v-if="item.order && item.order.items">
                        <view class='img-list-item' v-for="(v, k) in item.order.items" :key="k" @click="showOrder(item.aftersales_id)">
                            <image class='img-list-item-l little-img' :src='v.image_url' mode='aspectFill'></image>
                            <view class='img-list-item-r little-right'>
                                <view class='little-right-t'>
                                    <view class='goods-name list-goods-name'>{{v.name}}</view>
                                    <view class='goods-price'>¥{{v.price}}</view>
                                </view>
                                <view class='goods-item-c'>
                                    <view class='goods-buy'>
                                        <view class='goods-salesvolume' v-if="v.addon">{{v.addon}}</view>
                                        <view class='goods-num'>× {{v.nums}}</view>
                                    </view>
                                </view>
                            </view>
                        </view>
                    </view>
                    <!-- <view class='cell-group'>
                        <view class='cell-item'>
                            <view class='cell-item-ft goods-num'>
                                <text class='cell-ft-text'>合计<text class="red-price">¥{{item.order.order_amount}}(含运费¥{{item.order.cost_freight}})</text></text>
                                <text class='cell-ft-text'>共计{{item.countnum}}件商品</text>
                            </view>
                        </view>
                    </view> -->
                    <view class='order-list-button'>
                        <button class='btn btn-circle btn-b' @click="showOrder(item.aftersales_id)">查看详情</button>
                    </view>
                </view>
            </view>
            <uni-load-more :status="loadStatus"></uni-load-more>
        </view>
    </view>
</template>

<script>
import {
    tools
} from '@/config/mixins.js'
import uniLoadMore from '@/components/uni-load-more/uni-load-more.vue'
export default {
    mixins: [tools],
    components: {
        uniLoadMore
    },
    data() {
        return {
            order: [], //订单列表
            page: 1, //当前页
            limit: 5, //每页显示几条
            loadStatus: 'more'
        }
    },
    onShow() {
        this.getOrderList();
    },
    onReachBottom () {
        if (this.loadStatus === 'more') {
            this.getOrderList()
        }
    },
    methods: {
        //获取订单数据
        getOrderList() {
            let data = {};
            this.loadStatus = 'loading'
            data['page'] = this.page;
            data['limit'] = this.limit;
            this.$api.afterSalesList(data, res => {
                let orderList = this.dataFormat(res.data.list);
                this.order = this.order.concat(orderList);
                this.page = res.data.page*1+1;
                let allpage = res.data.total_page;
                if(allpage < this.page){
                    this.loadStatus = 'noMore'
                }else{
                    this.loadStatus = 'more'
                }
            });
        },

        //数据格式处理
        dataFormat(data) {
            for (var i = 0; i < data.length; i++) {
                let countnum = 0
                if(data[i].order && data[i].order.items){
                    for (var j = 0; j < data[i].order.items.length; j++) {
                        countnum += data[i].order.items[j].nums;
                    }
                    data[i].countnum = countnum;
                }
            }
            return data;
        },

        //查看详情
        showOrder(aftersales_id) {
            this.$common.navigateTo('detail?aftersales_id=' + aftersales_id);
        }
    },
}
</script>

<style>
.segmented-control {
    width: 100%;
    background-color: #fff;
    position: fixed;
    top: 88upx;
    z-index: 999;
}
.segmented-control-item{
    line-height: 70upx;
}
.order-list{
    /* margin-top: 64upx; */
}
.order-item{
    margin-bottom: 20upx;
}
.img-list{
    margin-top: 2upx;
}
.cell-group,.img-list-item {
    background-color: #fff;
}
.cell-hd-title{
    font-size: 22upx;
    color: #666;
}
.cell-ft-text{
    top: 0;
    font-size: 22upx;
    color: #333;
}
.order-list-button{
    width: 100%;
    background-color: #fff;
    text-align: right;
    padding: 10upx 26upx;
}
.order-list-button .btn{
    height: 50upx;
    line-height: 50upx;
}
.order-list-button .btn-w{
    margin-left: 20upx;
}
.goods-num .cell-ft-text{
    color: #999;
}
.goods-num .cell-ft-text:first-child{
    margin-left: 10upx;
}
.order-none{
    text-align: center;
    padding: 200upx 0;
}
.order-none-img{
    width: 274upx;
    height: 274upx;
}
</style>
balance
add_bankcard.vue
<template>
    <view class="content">
        <view class="content-top">
            <view class='cell-group'>
                <view class='cell-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>银行卡号</view>
                    </view>
                    <view class='cell-item-bd'>
                        <input type="number" class='cell-bd-input' v-model="cardNumber" focus @blur="checkCard()" placeholder='请输入银行卡号'></input>
                    </view>
                </view>
                <view class='cell-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>持卡人</view>
                    </view>
                    <view class='cell-item-bd'>
                        <input type="text" class='cell-bd-input' v-model="name" placeholder='请输入持卡人姓名'></input>
                    </view>
                </view>
                <view class='cell-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>银行名称</view>
                    </view>
                    <view class='cell-item-bd'>
                        <input type="text" class='cell-bd-input' :disabled="true" v-model="bankName"></input>
                    </view>
                </view>
                <view class='cell-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>银行卡类型</view>
                    </view>
                    <view class='cell-item-bd'>
                        <input type="text" class='cell-bd-input' :disabled="true" v-model='cardTypeName'></input>
                    </view>
                </view>
                <view class='cell-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>开户行名</view>
                    </view>
                    <view class='cell-item-bd'>
                        <input type="text" class='cell-bd-input' v-model="accountBank" placeholder='请输入开户银行名'></input>
                    </view>
                </view>
                
                <view class='cell-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>开户行地址</view>
                    </view>
                    <view class='cell-item-bd'>
                        <input :value="pickerValue" @focus="showThreePicker"></input>
                        <area-picker ref="areaPicker" :areaId="areaId" :defaultIndex="defaultIndex" @onConfirm="onConfirm"></area-picker>
                    </view>
                    <view class='cell-item-ft'>
                        <image class='cell-ft-next icon' src='/static/image/ic-pull-down.png' @click="showThreePicker"></image>
                    </view>
                </view>
                
                <view class='cell-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>设为默认</view>
                    </view>
                    <view @click="defaultChange">
                        <view class='cell-item-ft'>
                            <label class="radio"><radio value="1" :checked="checked" color="#333"/></label>
                        </view>
                    </view>
                </view>
            </view>
        </view>
        <view class="button-bottom">
            <!-- <button class="btn btn-square btn-w" @click="delShip" v-show="id && id != 0" hover-class="btn-hover2">删除</button> -->
            <button class="btn btn-square btn-b" @click="addCard" hover-class="btn-hover2" :disabled='submitStatus' :loading='submitStatus'>保存</button>
        </view>
    </view>

</template>

<script>
import areaPicker from "@/components/area-picker/areaPicker.vue";
export default {
    components: {
        areaPicker
    },
    data() {
        return {
            bankName: '',    // 银行名称
            cardType: 1, // 卡类型
            cardTypeName: '', // 卡片类型
            bankCode: '', // 银行缩写码
            accountBank: '', // 开户行
            cardNumber: '', // 银行卡号
            name: '',    // 开户人姓名
            mobile: '',    // 
            region: ['北京市', '北京市', '东城区'],
            areaId: 110101,
            address: '',
            is_def: 2,
            checked: false,
            pickerValue: '',
            defaultIndex: [0, 0, 0],
            submitStatus: false
        }
    },
    computed: {},
    methods: {
        // 省市区联动初始化
        showThreePicker() {
            this.$refs.areaPicker.showPicker();
        },
        // 选择收货地址
        onConfirm(e) {
            let province_name = e[0].name;
            let city_name = e[1].name;
            let county_name = e[2].name;
            this.pickerValue = e[0].name+ " "+ e[1].name+" "+e[2].name
            let data = {
                province_name: province_name,
                city_name: city_name,
                county_name: county_name
            }
            let regionName = [province_name, city_name, county_name];
            this.$api.getAreaId(data, res => {
                if (res.status) {
                    this.areaId = res.data
                } else {
                    uni.showModal({
                        title: '提示',
                        content: '地区选择出现问题,请重新选择地区',
                        showCancel: false
                    });
                }
            });
        },
        // 选择/取消默认
        defaultChange () {
            this.checked = !this.checked
            this.is_def = this.is_def === 1 ? 2 : 1
        },
        //存储收货地址
        saveShip() {
            if(this.id && this.id != 0){
                //编辑存储
                let data = {
                    'id': this.id,
                    'name': this.name,
                    'address': this.address,
                    'mobile': this.mobile,
                    'is_def': this.is_def
                }
                
                data['area_id'] = this.areaId,
                this.$api.editShip(data, res => {
                    if(res.status){
                        this.$common.successToShow('编辑成功', function(){
                            uni.navigateBack({
                                delta: 1
                            });
                        });
                    }else{
                        this.$common.errorToShow(res.msg);
                    }
                });
            }else{
                //添加
                let data = {
                    'area_id': this.areaId,
                    'name': this.name,
                    'address': this.address,
                    'mobile': this.mobile,
                    'is_def': this.is_def
                }
                this.$api.saveUserShip(data, res => {
                    if(res.status){
                        this.$common.successToShow('添加成功', function(){
                            uni.navigateBack({
                                delta: 1
                            });
                        });
                    }else{
                        this.$common.errorToShow(res.msg);
                    }
                });
            }
        },
        // 判断获取银行卡类型
        checkCard () {
            if (this.cardNumber) {
                let data = {
                    card_code: this.cardNumber
                }
                this.$api.getBankCardOrganization(data, res => {
                    if (res.status) {
                        let data = res.data
                        this.bankName = data.name
                        this.cardType = data.type
                        this.bankCode = data.bank_code
                        this.cardTypeName = data.type_name
                    } else {
                        this.$common.errorToShow(res.msg, () => {
                            this.bankCode = this.bankName = this.cardType = this.cardTypeName = ''
                        })
                    }
                })
            } else {
                this.bankCode = this.bankName = this.cardType = this.cardTypeName = ''
            }
        },
        // 添加银行卡
        addCard () {
            if (!this.cardNumber) {
                this.$common.errorToShow('请输入银行卡号')
            } else if (!this.bankName || !this.cardType || !this.bankCode) {
                this.$common.errorToShow('请输入正确的银行卡号')
            } else if (!/^[\u4E00-\u9FA5]{2,4}$/.test(this.name)) {
                this.$common.errorToShow('请输入正确的持卡人名称')
            } else if (!this.areaId) {
                this.$common.errorToShow('请选择开户行所在地区')
            } else if (!this.accountBank) {
                this.$common.errorToShow('请输入开户银行信息')
            } else {
                this.submitStatus = true;
                let data = {
                    bankName: this.bankName,
                    areaId: this.areaId,
                    accountBank: this.accountBank,
                    accountName: this.name,
                    bankCode: this.bankCode,
                    cardNumber: this.cardNumber,
                    cardType: this.cardType,
                    isDefault: this.is_def
                }
                
                this.$api.addBankCard(data, res => {
                    if (res.status) {
                        this.$common.successToShow(res.msg, ress => {
                            this.submitStatus = false;
                            uni.navigateBack({
                                delta: 1
                            });
                        })
                    } else {
                        this.$common.errorToShow(res.msg);
                        this.submitStatus = false;
                    }
                })
            }
        },
        // #ifdef MP-ALIPAY
        // alipay bank
        aliPayBank() {
            if(this.cardNumber.length >= 16 && this.cardNumber.length <= 19){
                let data = {
                    card_code: this.cardNumber
                }
                this.$api.getBankCardOrganization(data, res => {
                    if (res.status) {
                        let data = res.data
                        this.bankName = data.name
                        this.cardType = data.type
                        this.bankCode = data.bank_code
                        this.cardTypeName = data.type_name
                    } else {
                        this.$common.errorToShow(res.msg, () => {
                            this.bankCode = this.bankName = this.cardType = this.cardTypeName = ''
                        });
                    }
                })
            } else {
                this.bankCode = this.bankName = this.cardType = this.cardTypeName = ''
            }
        }
        // #endif
    },
    onLoad(e) {
        if(e.ship_id){
            //编辑
            this.id = e.ship_id;
            this.getShipInfo();
        }else{
            //添加
            this.pickerValue = this.region[0]+ " "+ this.region[1]+" "+this.region[2];
        }
    },
    onBackPress() {
        if (this.$refs.areaPicker.pickerShow) {
            this.$refs.areaPicker.closePicker();
            return true;
        }
    },
    // #ifdef MP-ALIPAY
    watch: {
        cardNumber () {
            this.$common.throttle(this.aliPayBank, this, 450);
        }
    },
    // #endif
}
</script>

<style>
.user-head{
    height: 100upx;
}
.user-head-img{
    height: 90upx;
    width: 90upx;
    border-radius: 50%;
}
.cell-hd-title{
    color: #333;
}
.cell-item-bd{
    color: #666;
    font-size: 26upx;
}
.button-bottom .btn {
    width: 50%;
}
/* #ifdef MP-ALIPAY */
input{
    font-size: 24upx;
}
/* #endif */
</style>
bankcard.vue
<template>
    <view class="content">
        <view class="content-top" v-if="cards.length">
            <view class="card-item"
            v-for="(item, index) in cards"
            :key="index"
            >
                <view class="card-item-tip" v-if="item.is_default === 1">
                    <view class="cit-bg"></view>
                    <view class="cit-text">默</view>
                </view>
                <view class="card-item-body">
                    <view class="cib-left">
                        <image class="bank-logo" :src="item.bank_logo" mode=""></image>
                    </view>
                    <view class="cib-right">
                        <view class="cibr-t color-3">
                            {{ item.bank_name }} - {{ item.card_type }}
                        </view>
                        <view class="cibr-b color-9">
                            {{ item.card_number }}
                        </view>
                    </view>
                </view>
                <view class="mr-card" 
                v-if="item.is_default === 2"
                @click="setDefault(item.id)"
                >
                    <button class="btn btn-w" :disabled='submitStatus' :loading='submitStatus'>设为默认</button>
                </view>
                <view class="del-card" 
                v-if="mold"
                @click="selected(index)"
                >
                    <button class="btn btn-b">选择</button>
                </view>
                <view class="del-card" 
                v-else
                @click="removeCard(item.id)"
                >
                    <button class="btn btn-b" :disabled='delSubmitStatus' :loading='delSubmitStatus'>删除</button>
                </view>
            </view>
        </view>
        <view class="cards-none" v-else>
            <image class="cards-none-img" src="/static/image/order.png" mode=""></image>
        </view>
        <view class="button-bottom">
            <button class="btn btn-b" @click="goAddcard()">添加银行卡</button>
        </view>
    </view>
</template>

<script>
export default {
    data () {
        return {
            mold: '',
            cards: [] ,// 我的银行卡列表
            submitStatus: false,
            delSubmitStatus: false
        }
    },
    onLoad (options) {
        if (options.mold && options.mold == 'select') {
            this.mold = options.mold
        }
    },
    onShow () {
        this.getBankCards()
    },
    methods:{
        // 获取我的银行卡列表
        getBankCards() {
            this.$api.getBankCardList({}, res => {
                if (res.status) {
                    this.cards = res.data
                }
            })
        },
        // 删除银行卡
        removeCard (cardId) {
            this.$common.modelShow('提示', '确定删除该银行卡?', res => {
                this.delSubmitStatus = true;
                let data = {
                    id: cardId
                }
                this.$api.removeBankCard(data, res => {
                    if (res.status) {
                        this.$common.successToShow(res.msg, ress => {
                            this.delSubmitStatus = false;
                            this.getBankCards();
                        })
                    } else {
                        this.$common.errorToShow(res.msg);
                        this.delSubmitStatus = false;
                    }
                })
            })
        },
        // 设置默认卡
        setDefault (id) {
            this.submitStatus = true;
            let data = {
                id: id
            }
            this.$api.setDefaultBankCard(data, res => {
                if (res.status) {
                    this.$common.successToShow(res.msg, ress => {
                        this.submitStatus = false;
                        this.getBankCards();
                    })
                } else {
                    this.$common.errorToShow(res.msg);
                    this.submitStatus = false;
                }
            })
        },
        // 添加新的银行卡
        goAddcard(){
            this.$common.navigateTo('./add_bankcard')
        },
        selected (index) {
            let pages = getCurrentPages();//当前页
            let beforePage = pages[pages.length - 2];//上个页面
            
            // #ifdef H5
            beforePage.cardInfo = this.cards[index]
            // #endif
            
            // #ifdef MP-WEIXIN
            beforePage.$vm.cardInfo = this.cards[index]
            // #endif
            
            // #ifdef MP-ALIPAY
            beforePage.rootVM.cardInfo = this.cards[index]
            // #endif
            
            uni.navigateBack({
                delta: 1
            })
        }
    }
}
</script>

<style>
.card-item{
    position: relative;
    background-color: #fff;
    margin: 26upx;
    border-radius: 10upx;
    box-shadow: 0 0 20upx #ccc;
    padding: 60upx 30upx 80upx;
}
.card-item-tip{
    position:absolute;
    top:0upx;
    left:0upx;
    z-index:10;
    border-top-left-radius:10upx;
    overflow:hidden;
    width:100upx;
    height:100upx;
}
.cit-bg{
    position:absolute;
    top:0;
    left:0;
    z-index:11;
    color:#ffffff;
    width:0upx;
    height:0upx;
    border-bottom:solid 100upx transparent;
    border-right:solid 100upx transparent;
    border-top:solid 100upx #FF7159;
}
.cit-text{
    position:absolute;
    top:0;
    left:0;
    z-index:12;
    color:#ffffff;
    margin-top:4upx;
    margin-left:14upx;
    font-size:30upx;

}
.card-item-body{
    position: relative;
}
.cib-left{
    position: absolute;
    top: 60%;
    transform: translateY(-50%);
    width: 250upx;
}
.bank-logo{
    width: 240upx;
    height: 70upx;
}
.cib-right{
    margin-left: 250upx;
}
.cibr-t{
    font-size: 30upx;
    margin-bottom: 10upx;
    text-align: center;
}
.cibr-b{
    font-size: 26upx;
    text-align: center;
}
.mr-card{
    position: absolute;
    right: 140upx;
    bottom: 0upx;
}
.del-card{
    position: absolute;
    right: 30upx;
    bottom: 0upx;
}
.del-card .btn,.mr-card .btn{
    font-size: 24upx;
    height: 48upx;
    line-height: 46upx;
    padding: 0 16upx;
}
.cards-none{
    text-align: center;
    padding: 200upx 0;
}
.cards-none-img{
    width: 274upx;
    height: 274upx;
}
</style>
cashlist.vue
<template>
    <view class="content">
        <view class='cell-group'>
            <view class='cell-item right-img'>
                <view class='cell-item-hd'>
                    <view class='cell-hd-title color-6'>类型筛选</view>
                </view>
                <view class='cell-item-bd'>
                    <view class="uni-list">
                        <view class="uni-list-cell-db color-6">
                            <picker @change="changeState" :value="index" :range="objectType">
                                <view class="uni-input">{{objectType[index]}}</view>
                            </picker>
                        </view>
                        <image class='right-img icon' src='/static/image/ic-pull-down.png'></image>
                    </view>
                </view>
            </view>
        </view>
        <view class="type-c"
        v-if="list.length"
        >
            <view class="cell-group margin-cell-group"
            v-for="(item, index) in list"
            :key="index"
            >
                <view class="cell-item">
                    <view class="cell-item-hd">
                        <view class='cell-hd-title'>{{ item.type }}</view>
                    </view>
                    <view class="cell-item-ft">
                        <view class="cell-ft-p color-9">
                            {{ item.ctime }}
                        </view>
                    </view>
                </view>
                <view class="cell-item">
                    <view class="cell-item-hd">
                        <view class='cell-hd-title color-9'>提现卡号:{{ item.card_number }}</view>
                    </view>
                    <view class="cell-item-ft red-price">
                        {{ item.money }}
                    </view>
                </view>
            </view>
            <uni-load-more
            :status="loadStatus"
            ></uni-load-more>
        </view>
        <view class="order-none" v-else>
            <image class="cash-none-img" src="/static/image/order.png" mode=""></image>
        </view>
    </view>
</template>

<script>
import uniLoadMore from '@/components/uni-load-more/uni-load-more.vue'    
export default {
    components: {
        uniLoadMore
    },
    data() {
        return {
            objectType: ['全部', '待审核', '提现成功', '提现失败'],
            index: 0,    // 默认选中的类型    索引
            page: 1,
            limit: 10,
            list: [],
            states: [0, 1, 2, 3], // 不同类型的状态
            loadStatus: 'more'
        }
    },
    onLoad () {
        this.getCash()
    },
    onReachBottom () {
        if (this.loadStatus === 'more') {
            this.getCash()
        }
    },
    methods: {
        // 切换类型
        changeState (e) {
            if (this.index !== e.target.value) {
                this.index = e.target.value;
                this.page = 1
                this.list = []
            }
        },
        // 获取余额明细
        getCash () {
            let data = {
                page: this.page,
                limit: this.limit
            }
            
            if (this.states[this.index]) {
                data.type = this.states[this.index]
            }
            
            this.loadStatus = 'loading'
            
            this.$api.cashList(data, res => {
                if (res.status) {
                    if (this.page >= res.total) {
                        // 没有数据了
                        this.loadStatus = 'noMore'
                    } else {
                        // 未加载完毕
                        this.loadStatus = 'more'
                        this.page ++
                    }
                    this.list = [...this.list, ...res.data]
                } else {
                    this.$common.errorToShow(res.msg)
                }
            })
        }
    },
    watch: {
        index () {
            this.getCash()
        }
    }
}
</script>

<style>
.uni-list{
    overflow: hidden;
}
.uni-list-cell-db{
    float: left;
    padding-top: 8upx;
    margin-right: 6upx;
    display: inline-block;
}
.uni-list .right-img{
    float: left;
}
.cell-item-bd{
    font-size: 26upx;
}
.type-c .cell-group{
    padding: 10upx 0;
}
.type-c .cell-item{
    border: none;
    min-height: 70upx;
    padding: 0 26upx 0 0;
}
.type-c .cell-item .red-price{
    font-size: 50upx;
}
.type-c .cell-item .color-9{
    font-size: 24upx;
}
.order-none{
    text-align: center;
    padding: 200upx 0;
}
.cash-none-img{
    width: 274upx;
    height: 274upx;
}
</style>
details.vue
<template>
    <view class="content">
        <view class='cell-group'>
            <view class='cell-item right-img'>
                <view class='cell-item-hd'>
                    <view class='cell-hd-title color-6' style="top: 0;">类型筛选</view>
                </view>
                <view class='cell-item-bd down-pull'>
                    <view class="uni-list">
                        <view class="uni-list-cell-db color-6">
                            <picker @change="changeState" :value="index" :range="objectType">
                                <view class="uni-input">{{objectType[index]}}</view>
                            </picker>
                        </view>
                        <image class='right-img icon' src='/static/image/ic-pull-down.png'></image>
                    </view>
                </view>
            </view>
        </view>
        <view class="type-c"
        v-if="list.length"
        >
            <view class="cell-group margin-cell-group"
            v-for="(item, index) in list"
            :key="index"
            >
                <view class="cell-item">
                    <view class="cell-item-hd">
                        <view class='cell-hd-title'>{{ item.type }}</view>
                    </view>
                    <view class="cell-item-ft">
                        <view class="cell-ft-p color-9">
                            {{ item.ctime }}
                        </view>
                    </view>
                </view>
                <view class="cell-item">
                    <view class="cell-item-hd">
                        <view class='cell-hd-title color-9'>余额:{{ item.balance }}</view>
                    </view>
                    <view class="cell-item-ft red-price">
                        {{ item.money }}
                    </view>
                </view>
            </view>
            <uni-load-more
            :status="loadStatus"
            ></uni-load-more>
        </view>
        <view class="order-none" v-else>
            <image class="balance-none-img" src="/static/image/order.png" mode=""></image>
        </view>
    </view>
</template>

<script>
import uniLoadMore from '@/components/uni-load-more/uni-load-more.vue'    
export default {
    components: {
        uniLoadMore
    },
    data() {
        return {
            objectType: ['全部', '消费', '退款', '充值', '提现', '佣金', '平台调整'],
            index: 0,    // 默认选中的类型    索引
            page: 1,
            limit: 10,
            list: [],
            states: [0, 1, 2, 3, 4, 5, 7], // 不同类型的状态
            loadStatus: 'more'
        }
    },
    onLoad (e) {
        if(e.status){
            this.index = this.states.indexOf(parseInt(e.status));
        }else{
            this.balances()//修复多次加载问题
        }
    },
    onReachBottom () {
        if (this.loadStatus === 'more') {
            this.balances()
        }
    },
    methods: {
        // 切换类型
        changeState (e) {
            if (this.index !== e.target.value) {
                this.index = e.target.value;
                this.page = 1
                this.list = []
            }
        },
        // 获取余额明细
        balances () {
            let data = {
                type: this.states[this.index],
                page: this.page,
                limit: this.limit
            }
            
            this.loadStatus = 'loading'
            
            this.$api.getBalanceList(data, res => {
                if (res.status) {
                    if (this.page >= res.total) {
                        // 没有数据了
                        this.loadStatus = 'noMore'
                    } else {
                        // 未加载完毕
                        this.loadStatus = 'more'
                        this.page ++
                    }
                    this.list = [...this.list, ...res.data]
                } else {
                    this.$common.errorToShow(res.msg)
                }
            })
        }
    },
    watch: {
        index () {
            this.balances();
        }
    }
}
</script>

<style>
.uni-list{
    overflow: hidden;
}
.uni-list-cell-db{
    float: left;
    /* padding-top: 8upx; */
    margin-right: 6upx;
    display: inline-block;
    height: 50upx;
    line-height: 50upx;
}
.uni-list .right-img{
    float: left;
}
.cell-item-bd{
    font-size: 26upx;
}
.type-c .cell-group{
    padding: 10upx 0;
}
.type-c .cell-item{
    border: none;
    min-height: 70upx;
    padding: 0 26upx 0 0;
}
.type-c .cell-item .red-price{
    font-size: 50upx;
}
.type-c .cell-item .color-9{
    font-size: 24upx;
}
.order-none{
    text-align: center;
    padding: 200upx 0;
}
.balance-none-img{
    width: 274upx;
    height: 274upx;
}
.down-pull{
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    left: 120upx;
}
</style>
index.vue
<template>
    <view class="content">
        <view class='withdrawcash-top'>
            <text class='withdrawcash-title'>账户余额(元)</text>
            <text class='withdrawcash-num'>{{ userInfo.balance }}</text>
        </view>
        <view class='cell-group margin-cell-group right-img'>
            <view class='cell-item'>
                <view class='cell-item-hd' @click="navigateToHandle('./recharge')">
                    <image class='cell-hd-icon' src='/static/image/topup.png'></image>
                    <view class='cell-hd-title'>账户充值</view>
                </view>
                <view class='cell-item-ft'>
                    <image class='cell-ft-next icon' src='/static/image/right.png'></image>
                </view>
            </view>
            <view class='cell-item'>
                <view class='cell-item-hd' @click="navigateToHandle('./withdraw_cash')">
                    <image class='cell-hd-icon' src='/static/image/withdraw.png'></image>
                    <view class='cell-hd-title'>余额提现</view>
                </view>
                <view class='cell-item-ft'>
                    <image class='cell-ft-next icon' src='/static/image/right.png'></image>
                </view>
            </view>
            <view class='cell-item'>
                <view class='cell-item-hd' @click="navigateToHandle('./details')">
                    <image class='cell-hd-icon' src='/static/image/detail.png'></image>
                    <view class='cell-hd-title'>余额明细</view>
                </view>
                <view class='cell-item-ft'>
                    <image class='cell-ft-next icon' src='/static/image/right.png'></image>
                </view>
            </view>
            <view class='cell-item'>
                <view class='cell-item-hd' @click="navigateToHandle('./cashlist')">
                    <image class='cell-hd-icon' src='/static/image/record.png'></image>
                    <view class='cell-hd-title'>提现记录</view>
                </view>
                <view class='cell-item-ft'>
                    <image class='cell-ft-next icon' src='/static/image/right.png'></image>
                </view>
            </view>
            <view class='cell-item'>
                <view class='cell-item-hd' @click="navigateToHandle('./bankcard')">
                    <image class='cell-hd-icon' src='/static/image/card.png'></image>
                    <view class='cell-hd-title'>我的银行卡</view>
                </view>
                <view class='cell-item-ft'>
                    <image class='cell-ft-next icon' src='/static/image/right.png'></image>
                </view>
            </view>
        </view>
    </view>
</template>

<script>
export default {
    data () {
        return {
            userInfo: {}
        }
    },
    onShow () {
        this.getUserInfo()
    },
    methods: {
        // 获取用户信息
        getUserInfo () {
            this.$api.userInfo({}, res => {
                if (res.status) {
                    this.userInfo = res.data
                } else {
                    this.$common.errorToShow(res.msg)
                }
            })
        },
        // 页面跳转
        navigateToHandle (pageUrl) {
            this.$common.navigateTo(pageUrl)
        }
    }
}    
</script>

<style>
.withdrawcash-top{
  padding: 40upx 26upx;
  background-color: #FF7159;
  color: #fff;
}
.withdrawcash-title{
  font-size: 28upx;
  display: block
}
.withdrawcash-num{
  font-size: 70upx;
  display: block;
  margin-top: 20upx;
  margin-left: 50upx;
}
.margin-cell-group {
    margin: 20upx 0;
    color: #666666;
}
</style>
recharge.vue
<template>
    <view class="content">
        <view class="content-top">
            <view class='cell-group margin-cell-group'>
                <view class='cell-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>当前金额</view>
                    </view>
                    <view class='cell-item-bd'>
                        <text class="cell-bd-view">¥{{ user.balance }}</text>
                    </view>
                </view>
                <view class='cell-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>充值金额</view>
                    </view>
                    <view class='cell-item-bd'>
                        <input class='cell-bd-input' placeholder='请输入要充值的金额' v-model="money" focus type="digit"></input>
                    </view>
                </view>
            </view>
        </view>
        <view class="button-bottom">
            <button class="btn btn-square btn-b" hover-class="btn-hover2" @click="navigateToHandle">去支付</button>
        </view>
    </view>
</template>

<script>
export default {
    data () {
        return {
            user: {}, // 用户信息
            payments: [], // 可用充值方式列表
            money: '', // 充值的金额
            orderType: 2    // 充值类型
        }
    },
    onLoad () {
        this.userInfo()
    },
    methods: {
        // 获取用户信息
        userInfo () {
            this.$api.userInfo({}, res => {
                if (res.status) {
                    this.user = res.data
                }
            })
        },
        // 去充值
        navigateToHandle () {
            if (!Number(this.money)) {
                this.$common.errorToShow('请输入要充值的金额')
            } else {
                this.$common.navigateTo('/pages/goods/payment/index?recharge=' + Number(this.money) + '&type=' + this.orderType)
            }
        }
    }
}
</script>

<style>
.user-head{
    height: 100upx;
}
.user-head-img{
    height: 90upx;
    width: 90upx;
    border-radius: 50%;
}
.cell-hd-title{
    color: #333;
}
.cell-item-bd{
    color: #666;
    font-size: 26upx;
}
.button-bottom .btn {
    width: 100%;
}
</style>
withdraw_cash.vue
<template>
    <view class="content">
        <view class="content-top">
            
            <!-- 我的银行卡信息 -->
            <view class='cell-group margin-cell-group' 
            v-if="userbankCard"
            @click="toBankCardList"
            >
                <view class='cell-item right-img'>
                    <view class='cell-item-hd'>
                        <image class="yl-logo" :src="cardInfo.bank_logo" mode=""></image>
                    </view>
                    <view class='cell-item-bd'>
                        <text class="cell-bd-view">{{ cardInfo.card_number }}</text>
                    </view>
                    <view class="cell-item-ft">
                        <image class='cell-ft-next icon' src='/static/image/right.png'></image>
                    </view>
                </view>
            </view>
            <view class='cell-group margin-cell-group' 
            v-else
            @click="toBankCardList"
            >
                <view class='cell-item right-img'>
                    <view class='cell-item-hd'>
                        <image class="yl-logo" src="/static/image/yl.png" mode=""></image>
                    </view>
                    <view class='cell-item-bd'>
                        <text class="cell-bd-view">请添加银行卡</text>
                    </view>
                    <view class="cell-item-ft">
                        <image class='cell-ft-next icon' src='/static/image/right.png'></image>
                    </view>
                </view>
            </view>
            
            <!-- 提现金额手续费 提现金额input -->
            <view class='cell-group margin-cell-group'>
                <view class='cell-item'>
                    <view class='cell-item-bd' v-if="tocashExplain">
                        <view class='cell-hd-title' style="color: #666;">{{ tocashExplain }}</view>
                    </view>
                </view>
                <view class='cell-item'>
                    <view class='cell-item-bd withdrawcash-input'>
                        <view class='cell-hd-title'><text>¥</text><input type="number" focus v-model="money"/></view>
                    </view>
                </view>
                <view class='cell-item'>
                    <view class='cell-item-bd'>
                        <view class='cell-hd-title' style="color: #666;" v-show="!isError">可用余额 {{ user.balance }} 元</view>
                        <view class='cell-hd-title' style="color: #f00;" v-show="isError">提现金额超过可用余额</view>
                    </view>
                </view>
            </view>
            
        </view>
        <view class="button-bottom">
            <button class="btn btn-square btn-b" hover-class="btn-hover2" v-if="isSubmit" @click="toCash" :disabled='submitStatus' :loading='submitStatus'>确认提现</button>
            <button class="btn btn-square btn-b" hover-class="btn-hover2" v-else-if="!isSubmit" disabled>确认提现</button>
        </view>
    </view>
</template>

<script>
export default {
    data () {
        return {
            cardInfo: {}, // 我的银行卡信息
            user: {}, // 用户信息
            isError: false, // 当提现金额大于可用余额 显示错误提示
            isSubmit: false, // 提现点击
            money: '', // 用户输入的提现金额
            submitStatus: false
        }
    },
    onLoad () {
        this.userBankCard()
        this.userInfo()
    },
    computed: {
        userbankCard () {
            if (Object.keys(this.cardInfo).length) {
                return true
            } else {
                return false
            }
        },
        // 店铺提现手续费
        tocashMoneyRate () {
            return this.$store.state.config.tocash_money_rate
        },
        // 店铺提现最低金额
        tocashMoneyLow () {
            return this.$store.state.config.tocash_money_low
        },
        // 提现文字说明
        tocashExplain () {
            if (this.tocashMoneyRate && this.tocashMoneyLow) {
                return '最低提现金额 ' + this.tocashMoneyLow + ' 元(收取 ' + this.tocashMoneyRate + ' %服务费)'
            } else if (this.tocashMoneyLow) {
                return '最低提现金额 ' + this.tocashMoneyLow + ' 元'
            } else if (this.tocashMoneyRate) {
                return '收取 ' + this.tocashMoneyRate + ' %服务费'
            } else {
                return ''
            }
        }
    },
    methods: {
        // 获取我的默认银行卡信息
        userBankCard () {
            this.$api.getDefaultBankCard({}, res => {
                if (res.status) {
                    this.cardInfo = res.data
                }
            })
        },
        // 获取用户信息
        userInfo () {
            // 获取我的余额信息
            // 获取用户的可用余额
            this.$api.userInfo({}, res => {
                this.user = res.data
            })
        },
        // 去提现
        toCash () {
            if (!Object.keys(this.cardInfo).length) {
                this.$common.errorToShow('请选择要提现的银行卡')
                return false
            } else if (!this.money) {
                this.$common.errorToShow('请输入要提现的金额')
                return false
            } else if (Number(this.money) === 0) {
                this.$common.errorToShow('提现金额不能为0')
            } else {
                this.submitStatus = true;
                this.$api.userToCash({
                    money: this.money,
                    cardId: this.cardInfo.id
                }, res => {
                    if (res.status) {
                        this.$common.successToShow(res.msg, () => {
                            this.submitStatus = false;
                            uni.navigateBack({
                                delta: 1
                            });
                        })
                    } else {
                        this.$common.errorToShow(res.msg);
                        this.submitStatus = false;
                    }
                })
            }
        },
        // 跳转我的银行卡列表
        toBankCardList () {
            this.$common.navigateTo('./bankcard?mold=select')
        }
    },
    watch: {
        money () {
            // 比较用户的输入金额 如果大于可用金额
            if (this.money === '' || Number(this.money) <= 0) {
                this.isSubmit = false
            } else if (Number(this.money) > Number(this.user.balance)) {
                this.isError = true
                this.isSubmit = false
            } else if (Number(this.money) < Number(this.tocashMoneyLow)) {
                this.isError = false
                this.isSubmit = false
            } else {
                this.isError = false
                this.isSubmit = true
            }
        }
    }
}
</script>

<style>
.user-head{
    height: 100upx;
}
.user-head-img{
    height: 90upx;
    width: 90upx;
    border-radius: 50%;
}
.cell-hd-title{
    color: #333;
}
.cell-item{
    border: none;
}
.cell-item-bd{
    color: #666;
    font-size: 26upx;
}
.button-bottom .btn {
    width: 100%;
}
.yl-logo{
    width: 188upx;
    height: 54upx;
    float: left;
}
.withdrawcash-input{
    font-size: 50upx;
    border-bottom: 2upx solid #e8e8e8;
    padding-bottom: 20upx;
}
.withdrawcash-input text{
    font-size: 40upx;
}
.withdrawcash-input input{
    display: inline-block;
    min-width: 500upx;
    padding-left: 20upx;
}
/* #ifdef MP-ALIPAY */
.cell-hd-title input {
    font-size: 24px;
    height: 18px;
}
/* #endif */
</style>
collection
index.vue
<template>
    <view class="content">
        <view class="collection" v-if="list.length">
            <view class="container_of_slide" 
            v-for="(item, index) in list" 
            :key="index"
            >
                <view class="slide_list" 
                @touchstart="touchStart($event,index)" 
                @touchend="touchEnd($event,index)" 
                @touchmove="touchMove($event,index)"
                @tap="recover(index)" 
                :style="{transform:'translate3d('+item.slide_x+'px, 0, 0)'}"
                v-if="item.goods"
                >
                    <view class="now-message-info" hover-class="uni-list-cell-hover" :style="{width:Screen_width+'px'}" 
                    @click="goodsDetail(item.goods_id)">
                        <view class="icon-circle">
                            <image class='goods-img' :src="item.goods.image_url" mode="aspectFill"></image>
                        </view>
                        
                        <view class="list-right">
                            <view class="list-title">{{ item.goods.name }}</view>
                            <view class="red-price">¥{{ item.goods.price }}</view>
                            <view class="list-detail">{{ item.ctime }}</view>
                        </view>
                        <view class="list-right-1">
                            <image class='cell-ft-next icon' src='/static/image/right.png'></image>
                        </view>
                    </view>
                    <view class="group-btn">
                        <view class="removeM btn-div" @tap="collect(index)">
                            取消
                        </view>
                    </view>
                    <view style="clear:both"></view>
                </view>
            </view>
            <uni-load-more
            :status="loadStatus"
            ></uni-load-more>
        </view>
        <view class="collection-none" v-else>
            <image class="collection-none-img" src="/static/image/order.png" mode=""></image>
        </view>
    </view>
</template>

<script>
import uniLoadMore from '@/components/uni-load-more/uni-load-more.vue'
import { goods } from '@/config/mixins.js'
    export default {
        mixins: [ goods ],
        components: {
            uniLoadMore
        },
        computed: {
            Screen_width() {
                return uni.getSystemInfoSync().windowWidth;
            }
        },
        data() {
            return {
                visible: false,
                start_slide_x: 0,
                btnWidth: 0,
                startX: 0,
                LastX: 0,
                startTime: 0,
                screenName: '',
                page: 1,
                limit: 10,
                list: [], // 商品浏览足迹
                loadStatus: 'more'
            };
        },
        onLoad () {
            this.goodsCollectionList()
        },
        onShow() {
            const res = uni.getSystemInfoSync();
        },
        onReachBottom () {
            if (this.loadStatus === 'more') {
                this.goodsCollectionList()
            }
        },
        methods: {
            goodsCollectionList () {
                let data = {
                    page: this.page,
                    limit: this.limit
                }

                this.loadStatus = 'loading'
                
                this.$api.goodsCollectionList(data, res => {
                    if (res.status) {
                        let _list = res.data.list
                        _list.forEach (item => {
                            this.$set(item, 'slide_x', 0)
                            item.ctime = this.$common.timeToDate(item.ctime)
                        })
                        this.list = [...this.list, ..._list]
                        
                        if (res.data.count > this.list.length) {
                            this.page ++
                            this.loadStatus = 'more'
                        } else {
                            this.loadStatus = 'noMore'
                        }
                    } else {
                        this.$common.errorToShow(res.msg)
                    }
                })
            },
            cancelEvent(){
                this.visible = false
            },
            // 滑动开始
            touchStart(e, index) {
                this.startCilentY = e.touches[0].clientY;
                //记录手指放上去的时间
                this.startTime = e.timeStamp;
                //记录滑块的初始位置
                this.start_slide_x = this.list[index].slide_x;
                // 按钮宽度
                uni.createSelectorQuery()
                    .selectAll('.group-btn')
                    .boundingClientRect()
                    .exec(res => {
                        if (res[0] != null) {
                            this.btnWidth = res[0][index].width * -1;
                        }
                    });
                // 记录上一次开始时手指所处位置
                this.startX = e.touches[0].pageX;
                // 记录上一次手指位置
                this.lastX = this.startX;
                //初始化非当前滑动消息列的位置
                this.list.forEach((item, eq) => {
                    if (eq !== index) {
                        item.slide_x = 0;
                    }
                });
            },
            // 滑动中
            touchMove(e, index) {
                var endCilentY = e.touches[0].clientY; 
                var moveClientY = endCilentY - this.startCilentY;
                if (this.direction === 'Y' || Math.abs(moveClientY ) > 20 || e.currentTarget.dataset.disabled === true) { this.direction = ''; return; }
                const endX = e.touches[0].pageX;
                const distance = endX - this.lastX;
                // 预测滑块所处位置
                const duang = this.list[index].slide_x + distance;
                // 如果在可行区域内
                if (duang <= 0 && duang >= this.btnWidth) {
                    this.list[index].slide_x = duang;
                }
                // 此处手指所处位置将成为下次手指移动时的上一次位置
                this.lastX = endX;
            },
            // 滑动结束
            touchEnd(e, index) {
                let distance = 10;
                const endTime = e.timeStamp;
                const x_end_distance = this.startX - this.lastX;
                if (Math.abs(endTime - this.startTime) > 200) {
                    distance = this.btnWidth / -2;
                }
                // 判断手指最终位置与手指开始位置的位置差距
                if (x_end_distance > distance) {
                    this.list[index].slide_x = this.btnWidth;
                } else if (x_end_distance < distance * -1) {
                    this.list[index].slide_x = 0;
                } else {
                    this.list[index].slide_x = this.start_slide_x;
                }
            },
            // 点击回复原状
            recover(index) {
                this.list[index].slide_x = 0;
            },
            // 取消收藏
            collect (index) {
                let data = {
                    goods_id: this.list[index].goods_id
                }
                
                this.$api.goodsCollection(data, res => {
                    if (res.status) {
                        this.$common.successToShow(res.msg, () => {
                            this.$nextTick(() => {
                                this.list.splice(index, 1)
                            })
                        })
                    } else {
                        this.$common.errorToShow(res.msg)
                    }
                })
            }
        }
    };
</script>

<style scoped>
.collection .goods-img{
    width: 150upx;
    height: 150upx;    
}
.container_of_slide {
    width: 100%;
    overflow: hidden;
}
.slide_list {
    transition: all 100ms;
    transition-timing-function: ease-out;
    min-width: 200%;
}
.now-message-info {
    box-sizing:border-box;
    display: flex;
    align-items: center;
    font-size: 16px;
    clear:both;
    padding: 20upx 26upx;
    margin-bottom: 2upx;
    background: #FFFFFF;
}
.now-message-info,
.group-btn {
    float: left;
}
.group-btn {
    display: flex;
    flex-direction: row;
    height: 190upx;
    min-width: 100upx;
    align-items: center;

}
.group-btn .btn-div {
    height: 190upx;
    color: #fff;
    text-align: center;
    padding: 0 50upx;
    font-size: 34upx;
    line-height: 190upx;
}
.group-btn .top {
    background-color: #FFAA33;
}
.group-btn .removeM {
    background-color: #ff3b44;
}
.icon-circle{
    width:150upx;
    height: 150upx;
    float: left;
}
.list-right{
    float: left;
    margin-left: 25upx;
    height: 150upx;
}
.list-right-1{
    float: right;
    color: #A9A9A9;
}
.list-title{
    width: 490upx;
    line-height:1.5;
    overflow:hidden;
    color:#333;
    display:-webkit-box;
    -webkit-box-orient:vertical;
    -webkit-line-clamp:2;
    overflow:hidden;
    font-size: 26upx;
    color: #333;
    min-height: 80upx;
}
.list-detail{
    width: 460upx;
    font-size: 24upx;
    color: #a9a9a9;
    display:-webkit-box;
    -webkit-box-orient:vertical;
    -webkit-line-clamp:1;
    overflow:hidden;
}
.collection-none{
    text-align: center;
    padding: 200upx 0;
}
.collection-none-img{
    width: 274upx;
    height: 274upx;
}
</style>
coupon
index.vue
<template>
    <view class="content">
        <uni-segmented-control :current="current" :values="items" @clickItem="onClickItem" style-type="text" active-color="#333"></uni-segmented-control>
        <view class="">
            <view class="coupon-c-item" v-for="(item, key) in listData" :key="key">
                <view class="cci-l">
                    <view class="cci-l-c color-f" v-if="current == 0">
                        coupon
                    </view>
                    <view class="cci-l-c color-f color-b" v-if="current != 0">
                        coupon
                    </view>
                </view>
                <view class="cci-r">
                    <view class="cci-r-c">
                        <view class="ccirc-t color-9">
                            {{item.name}}
                        </view>
                        <view class="ccirc-b">
                            <view class="ccirc-b-l">
                                <view class="ccirc-b-tip">
                                    {{ item.expression1 + item.expression2 }}
                                </view>
                                <view class="ccirc-b-time color-9">
                                    有效期:{{item.stime}} - {{item.etime}}
                                </view>
                            </view>
                            <view class="ccirc-b-r color-f" @click="goIndex" v-if="current == 0">
                                立即使用
                            </view>
                        </view>
                    </view>
                </view>
            </view>
            <uni-load-more :status="loadStatus"></uni-load-more>
        </view>
    </view>
</template>

<script>
    import uniLoadMore from '@/components/uni-load-more/uni-load-more.vue'
    import uniSegmentedControl from "@/components/uni-segmented-control/uni-segmented-control.vue";
    export default {
        components: {
            uniSegmentedControl,uniLoadMore
        },
        data() {
            return {
                items: ['未使用','已使用','已失效'],
                current: 0,
                page: 1,
                limit: 10,
                listData: [],
                loadStatus: 'more'
            }
        },
        onLoad() {
            this.getData();
        },
        onReachBottom () {
            if (this.loadStatus === 'more') {
                this.getData();
            }
        },
        methods: {
            // tab点击切换
            onClickItem(index) {
                if (this.current !== index) {
                    this.current = index;
                    this.page = 1;
                    this.listData = [];
                    this.getData();
                }
            },
            //获取优惠券列表
            getData() {
                this.loadStatus = 'loading'
                let data = {
                    page: this.page,
                    limit: this.limit
                }
                if (this.current == 0) {
                    data['display'] = 'no_used';
                }
                if (this.current == 1) {
                    data['display'] = 'yes_used';
                }
                if (this.current == 2) {
                    data['display'] = 'invalid';
                }
                this.$api.userCoupon(data, res => {
                    if (res.status) {
                        let now_type = 'no_used';
                        if (this.current == 1) {
                            now_type = 'yes_used';
                        }
                        if (this.current == 2) {
                            now_type = 'invalid';
                        }
                        if (now_type == res.data.q_type) {
                            if (res.data.page >= this.page) {
                                let newList = this.listData.concat(res.data.list);
                                this.listData = newList;
                                if (res.data.count > this.listData.length) {
                                    this.page ++
                                    this.loadStatus = 'more'
                                } else {
                                    this.loadStatus = 'noMore'
                                }
                            }
                        }
                    }else{
                        this.$common.errorToShow(res.msg);
                    }
                });
            },
            //跳转首页
            goIndex() {
                uni.switchTab({
                    url: '/pages/index/index'
                });
            }
        }
    }
</script>

<style>
.coupon-c-item{
    margin: 30upx 50upx;
    /* width: 100%; */
    height: 150upx;
    margin-bottom: 20upx;
}
.cci-l{
    width: 60upx;
    height: 100%;
    background-color: #FF7159;
    font-size: 32upx;
    display: inline-block;
    box-sizing: border-box;
    float: left;
    border-top-left-radius: 16upx;
    border-bottom-left-radius: 16upx;
}
.cci-l-c{
    height: 60upx;
    line-height: 44upx;
    width: 150upx;
    text-align: center;
    transform-origin: 30upx 30upx;
    transform: rotate(90deg);
}
.cci-r{
    position: relative;
    height: 150upx;
    width: calc(100% - 70upx);
    margin-left: 10upx;
    display: inline-block;
    background-color: #fff;
}
.cci-r-img{
    position: absolute;
    width: 100%;
    height: 100%;
    background-color: #fff;
}
.cci-r-c{
    position: relative;
    z-index: 99;
}
.ccirc-t{
    font-size: 24upx;
    padding: 10upx 20upx;
}
.ccirc-b{
    padding: 10upx;
    position: relative;
}
.ccirc-b-l{
    display: inline-block;
    max-width: 400upx;
}
.ccirc-b-tip{
    font-size: 28upx;
    width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.ccirc-b-tip text{
    font-size: 34upx;
}
.ccirc-b-time{
    font-size: 24upx;
}
.ccirc-b-r{
    display: inline-block;
    background-color: #FF7159;
    font-size: 26upx;
    padding: 4upx 10upx;
    border-radius: 4upx;
    position: absolute;
    right: 20upx;
    bottom: 16upx;
}
.color-b{
    background-color: #e5e5e5;
    border-bottom-right-radius: 12upx;
    border-bottom-left-radius: 12upx;
    color: #fff;
}
</style>
distribution
agreement.vue
<template>
    <view class="content">
        <view class="article">
            <view class="article-content">
                <rich-text :nodes="content"></rich-text>
            </view>
        </view>
    </view>
</template>

<script>
    import htmlParser from '@/common/html-parser'
    export default {
        data() {
            return {
                content:this.$store.state.config.distribution_agreement,
            }
        },
        onLoad(e) {
        },
        computed: {
        },
        methods: {
        }
    }
</script>

<style>
    .content {
        /*  #ifdef  H5  */
        height: calc(100vh - 90upx);
        /*  #endif  */
        /*  #ifndef  H5  */
        height: 100vh;
        /*  #endif  */
        background-color: #fff;
    }

    .article {
        padding: 20upx;
    }

    .article-title {
        font-size: 32upx;
        color: #333;
        margin-bottom: 20upx;
        /* text-align: center; */
        position: relative;
        height: 100upx;
    }

    .article-time {
        /* text-align: right; */
        margin-left: 20upx;
    }

    .article-content {
        font-size: 28upx !important;
        color: #666;
        line-height: 1.6;
        margin-top: 20upx;
    }

    .article-content p img {
        width: 100% !important;
    }

    .shop-logo {
        width: 60upx;
        height: 60upx;
        border-radius: 50%;
        position: absolute;
        top: 50%;
        transform: translateY(-50%);
    }

    .shop-name {
        line-height: 100upx;
        margin-left: 80upx;
    }
</style>
apply.vue
<template>
    <view class="content">
        <view class="apply-c">
            <view class="apply-top">
                <view class='cell-group'>
                    <view class='cell-item'>
                        <view class='cell-item-hd'>
                            <view class='cell-hd-title'>姓名</view>
                        </view>
                        <view class='cell-item-bd'>
                            <input type="text" class='cell-bd-input' placeholder='请填您的姓名' v-model="name"></input>
                        </view>
                    </view>
                    <view class='cell-item'>
                        <view class='cell-item-hd'>
                            <view class='cell-hd-title'>微信</view>
                        </view>
                        <view class='cell-item-bd'>
                            <input type="text" class='cell-bd-input' placeholder='请填您的微信' v-model="weixin"></input>
                        </view>
                    </view>
                    <view class='cell-item'>
                        <view class='cell-item-hd'>
                            <view class='cell-hd-title'>QQ</view>
                        </view>
                        <view class='cell-item-bd'>
                            <input type="number" class='cell-bd-input' placeholder='请填您的QQ' v-model="qq"></input>
                        </view>
                    </view>
                    <view class='cell-item'>
                        <view class='cell-item-hd'>
                            <view class='cell-hd-title'>手机</view>
                        </view>
                        <view class='cell-item-bd'>
                            <input type="number" class='cell-bd-input' placeholder='请填写您的手机号码' v-model="mobile"></input>
                        </view>
                    </view>
                    
                </view>
                <view class="apply-tip color-6 fsz26">
                    <label class="radio" @click="agreeAgreement"><radio value="1" :checked="checked" color="#FF7159"/>我已经阅读并接受</label><text class="" @click="goAgreement()">"分销协议"</text>
                </view>
            </view>
            
            <view class="apply-bot">
                <button class="btn btn-square btn-o btn-all" hover-class="btn-hover" @click="goApplyState()">申请成为分销</button>
            </view>
        </view>
    </view>
</template>

<script>
export default {
    data() {
        return {
            name: '',
            weixin: '',
            qq: '',
            mobile: '',
            checked: false,
            is_agree: 'off'
        }
    },
    methods: {
        // 是否同意协议
        agreeAgreement(){
            
            if(this.checked){
                this.checked = false;
                this.is_agree = 'off';
            }else{
                this.checked = true;
                this.is_agree = 'on';
            }
            // console.log(this.checked)
        },
        // 信息验证
        checkData (data) {
            if (!data.name) {
                this.$common.errorToShow('请输入您的姓名')
                return false
            } else if (!data.weixin) {
                this.$common.errorToShow('请输入您的微信')
                return false
            } else if (!data.qq) {
                // console.log(this.is_agree)
                this.$common.errorToShow('请输入您的QQ')
                return false
            } else if (!data.mobile) {
                this.$common.errorToShow('请输入您的手机号')
                return false
            } else if (data.mobile.length !== 11) {
                this.$common.errorToShow('手机号格式不正确')
                return false
            } else if (data.agreement != 'on') {
                //console.log(data)
                this.$common.errorToShow('请钩选分销协议')
                return false
            } else {
                return true
            }
        },
        // 提交审核
        goApplyState() {
            let data = {
                name: this.name,
                weixin: this.weixin,
                qq: this.qq,
                mobile: this.mobile,
                agreement: this.is_agree,
            }
            
            if (this.checkData(data)) {
                this.$api.applyDistribution(data, res => {
                    if(res.status){
                        this.$common.successToShow(res.msg, function(){
                            uni.navigateTo({
                                url:'./apply_state'
                            });
                        });
                    }else{
                        this.$common.errorToShow(res.msg);
                    }
                });
            }
        },
        goAgreement(){
            uni.navigateTo({
                url: './agreement'
            })
        }
        
    }
}
</script>

<style>
.content{
    background-color: #FF7159;
    height: calc(100vh - 44px);
    padding-top: 50upx;
}
.apply-c{
    margin: 40upx auto;
    padding: 26upx 0;
    border-radius: 30upx;
    box-shadow: 0 0 10px #aaa;
    width: 670upx;
    min-height: 400upx;
    background-color: #fff;
}
.apply-top .cell-item{
    width: 610upx;
}
.apply-top .cell-item:last-child{
    border-bottom: 1px solid #f3f3f3;
}
.apply-top .cell-item .cell-item-hd{
    min-width: 120upx;
}
.apply-top .cell-item .cell-bd-input{
    width: 100%;
}
.apply-tip{
    padding: 26upx;
}
.apply-bot{
    width: 100%;
    text-align: center;
}
.apply-bot .btn{
    border-radius: 50upx;
    width: 90%;
    margin: 40upx auto 0;
}
</style>
apply_state.vue
<template>
    <view class="content">
        <view class="apply-c">
            <view class="apply-top fsz36 color-o"  v-if="info.verify==2">
                恭喜,您的申请已提交!
            </view>
            <view class="apply-top-refuse fsz36 color-o"  v-if="info.verify==3">
                抱歉,您的申请被驳回!
            </view>
            <view class="apply-top fsz36 color-o"  v-if="info.verify==1">
                恭喜,您的申请已通过!
            </view>
            <view class="apply-bot"  v-if="info.verify==2">
                <view class="apply-bot-sop">
                    <view class="abs-img">
                        <image class="icon" src="/static/image/del.png" mode=""></image>
                    </view>
                    <view class="color-9 abs-mid"  >
                        <image class="dot" src="/static/image/dot-o.png" mode=""></image>
                        <image class="dot" src="/static/image/dot-o.png" mode=""></image>
                        <image class="dot" src="/static/image/dot-o.png" mode=""></image>
                        <image class="dot" src="/static/image/dot-o.png" mode=""></image>
                        <image class="dot" src="/static/image/dot-o.png" mode=""></image>
                        <image class="dot" src="/static/image/dot-o.png" mode=""></image>

                        <image class="dot" src="/static/image/dot-g.png" mode=""></image>
                        <image class="dot" src="/static/image/dot-g.png" mode="" ></image>
                        <image class="dot" src="/static/image/dot-g.png" mode="" ></image>
                        <image class="dot" src="/static/image/dot-g.png" mode="" ></image>
                        <image class="dot" src="/static/image/dot-g.png" mode="" ></image>
                        <image class="dot" src="/static/image/dot-g.png" mode="" ></image>
                    </view>
                    <view class="abs-img">
                        <image class="icon" src="/static/image/close.png" mode=""></image>
                    </view>
                </view>
                <view class="apply-bot-text">
                    <view class="abt-c">
                        <view class="color-6 fsz30">
                            申请提交成功
                        </view>
                        <view class="color-9 fsz24">
                            {{info.ctime}}
                        </view>
                    </view>
                    <view class="abt-c">
                        <view class="color-6 fsz30" v-if="info.verify==2">
                            等待审核
                        </view>
                        <view class="color-6 fsz30" v-if="info.verify==3">
                            审核驳回
                        </view>
                        <view class="color-6 fsz30" v-if="info.verify==1">
                            审核通过
                        </view>
                    </view>
                </view>
            </view>
        </view>
    </view>
</template>

<script>
export default {
    data() {
        return {
            info: {}
        }
    },
    onLoad:function() {
        var _this = this;
        _this.$api.getDistributioninfo({check_condition:true}, function(res) {
            if (res.status) {
                if(res.data.need_apply && res.data.condition_status ==false){
                    _this.$common.redirectTo('/pages/member/distribution/index');
                }
                if(res.data.verify == 1){//审核通过
                    _this.$common.redirectTo('/pages/member/distribution/user');
                }
                _this.info = res.data;
            } else {
                //报错了
                _this.$common.errorToShow(res.msg);
            }
        });
    },
    methods: {
       
        
    }
}
</script>

<style>
.content{
    height: calc(100vh - 44px);
    padding-top: 50upx;
}

.apply-c{
    margin: 40upx auto;
    text-align: center;
    padding: 26upx;
    border-radius: 30upx;
    box-shadow: 0 0 10px #aaa;
    width: 670upx;
    min-height: 400upx;
    background-color: #fff;
}
.apply-top{
    margin-top: 40upx;
}
.apply-top-refuse{
    margin-top: 140upx;
}
.apply-bot{
    width: 100%;
    text-align: center;
}
.apply-bot-sop{
    position: relative;
    height: 60upx;
    width: 65%;
    margin: 40upx auto 20upx;
    display: flex;
    line-height: 1.7555;
    /* vertical-align: middle; */
}
.apply-bot-sop>view{
    display: inline-block;
}
.abs-img{
    flex: 1;
}
.abs-img image{
    position: relative;
    top: 50%;
    transform: translateY(-50%);
}
.abs-mid{
    /* font-size: 70upx; */
    flex: 2;
    display: flex;
}
.apply-bot-text{
    display: flex;
}
.abt-c{
    flex: 1;
}
.dot{
    width: 8upx;
    height: 8upx;
    margin: 0 4upx;
}
</style>
index.vue
<template>
    <view class="content">
        <view class="content-top">
            <view class="dist-head">
                <view class="dist-head-top">
                    <view class="dht-margin color-f fsz34" v-if="condition.condition_status">已达标</view>
                    <view class="dht-margin color-f fsz34" v-if="!condition.condition_status">未达标</view>
                    
                    <cmd-progress class="dht-margin" :percent="condition.condition_progress" :stroke-width="23" stroke-color="linear-gradient(to right, #ef32d9, #89fffd)"></cmd-progress>

                    <view class="dht-margin color-d fsz28">{{condition.condition_msg}}</view>
                </view>
                <view class="dist-head-tip color-f fsz24">
                    注:消费金额只算实付金额部分,储值抵扣/退款退货金额不算在内。
                </view>
            </view>
            <view class="dist-body">
                <view class="db-title color-3 fsz34">
                    分销商须知
                </view>
                <view class="db-body color-6 fsz30">
                    <text class="db-item">{{distributionNotes}}</text>
                </view>
            </view>
        </view>
        <view class="button-bottom">
            <button class="btn btn-square btn-o" hover-class="btn-hover" v-if="condition.condition_status" @click="goApply()">申请</button>
            <button class="btn btn-square btn-g" v-else >您的条件暂不满足</button>
        </view>
    </view>
</template>

<script>
import cmdProgress  from '@/components/cmd-progress/cmd-progress.vue'
export default {
    components: { cmdProgress },
    data() {
        return {
            condition: {}
        }
    },
    methods: {
        goApply() {
            this.$common.navigateTo('./apply');
        }
    },
    computed: {
        distributionNotes () {
            return this.$store.state.config.distribution_notes
        }
        
    },
    onLoad: function() {
        var _this = this;
        _this.$api.getDistributioninfo({}, function(res) {
            if (res.status) {
                _this.condition = res.data;
                if(_this.condition.hasOwnProperty('verify')){
                    if(_this.condition.verify == 1 || (!_this.condition.need_apply && _this.condition_status)){
                        _this.$common.redirectTo('/pages/member/distribution/user');
                    }else if(_this.condition.condition_status){
                        _this.$common.redirectTo('/pages/member/distribution/apply_state');//待审核
                    }
                }
            } else {
                //报错了
                _this.$common.errorToShow(res.msg);
            }
        });
    }
}
</script>

<style>
.content{
    background-color: #fff;
    height: calc(100vh - 44px);
}
.dist-head{
    padding: 50upx 26upx 20upx;
    text-align: center;
    background: linear-gradient( #FF7159, #ff9785);
}
.dist-head-top{
    padding: 0upx 50upx 30upx;
}
.dht-margin{
    margin-bottom: 26upx;
}
.dht-margin.color-d{
    padding: 0 40upx;
}
.dht-mid{
    margin-bottom: 12upx;
}
.dist-head-tip{
    text-align: left;
    
}
.dist-body{
    padding: 26upx;
}
.db-title{
    border-bottom: 2upx solid #ccc;
    padding-bottom: 26upx;
}
.db-body{
    padding: 26upx 10upx;
}
.db-item{
    /* padding: ; */
    margin-bottom: 14upx;
}
pre {
    white-space: pre-wrap;       /* css-3 */
    white-space: -moz-pre-wrap;  /* Mozilla, since 1999 */
    white-space: -pre-wrap;      /* Opera 4-6 */
    white-space: -o-pre-wrap;    /* Opera 7 */
    word-wrap: break-word;       /* Internet Explorer 5.5+ */
} 
</style>
my_store.vue
<template>
    <view class="content my-store">
        <view class="" ref="myStore">
            <view class="my-store-t">
                <view class="mst-top">
                    <image :src="store_banner_src" mode="widthFix"></image>
                </view>
                <view class="mst-bot">
                    <view class='member-grid'>
                        <view class='member-item'>
                            <image class='member-item-img' :src='store_logo_src'></image>
                        </view>
                        <view class='member-item'>
                            <view class="color-o fsz36">{{total_goods}}</view>
                            <text class='member-item-text'>全部宝贝</text>
                        </view>
                        <view class='member-item' @click="openPopup()">
                            <image class='member-item-icon' src='/static/image/ic-me-collect.png'></image>
                            <text class='member-item-text'>收藏本店</text>
                        </view>
                        <view class='member-item'>
                            <!-- #ifdef MP-WEIXIN -->
                            <button class='share btn' open-type="share">
                                <image class='member-item-icon' src='/static/image/qr_code.png'></image>
                                <text class='member-item-text'>二维码</text>
                            </button>
                            <!-- #endif -->
                            <!-- #ifndef MP-WEIXIN -->
                            <button class='share btn' @click="createPoster()">
                                <image class='member-item-icon' src='/static/image/qr_code.png'></image>
                                <text class='member-item-text'>二维码</text>
                            </button>
                            <!-- #endif -->

                        </view>
                    </view>
                </view>
            </view>
            <view class="my-store-m">
                <view class="search">
                    <view class="search-c" @click="goSearch">
                        <view class="search-input search-input-p">
                            <view class="search-input-p-c">
                                {{ searchKey }}
                            </view>
                        </view>
                        <image class="icon search-icon" src="/static/image/zoom.png"></image>
                    </view>
                </view>
            </view>
            <!-- 收藏弹出窗 -->
            <lvv-popup position="bottom" ref="lvvpopref" @click="closePopup()">
                <view class="collect-pop" @click="closePopup()">
                    <image v-if="isWeixinBrowser" src="/static/image/wxh5.png" mode="widthFix"></image>
                    <!-- #ifdef MP-WEIXIN -->
                    <image src="/static/image/wxxcx.png" mode="widthFix"></image>
                    <!-- #endif -->
                    <!-- #ifdef H5 -->
                    <view class="h5-tip color-f fsz38">
                        <view>请将此页面添加浏览器书签</view>
                        <view>方便下次浏览</view>
                    </view>
                    <!-- #endif -->
                </view>
            </lvv-popup>
        </view>
        <!-- 商品列表 -->
        <view class="img-grids">
            <view v-if="goodsList.length>0">
                <view class="img-grids-item" v-for="(item, index) in goodsList" :key="index" @click="goodsDetail(item.id)">
                    <image class="img-grids-item-t have-none" :src="item.image_url" mode='aspectFill'></image>
                    <view class="img-grids-item-b">
                        <view class="goods-name grids-goods-name">
                            {{item.name}}
                        </view>
                        <view class="goods-item-c">
                            <view class="goods-price red-price">¥{{item.price}}</view>
                            <image class="goods-cart" src="../../static/image/ic-car.png"></image>
                        </view>
                    </view>
                </view>

            </view>
            <!-- 无数据时默认显示 -->
            <view class="order-none" v-else>
                <image class="order-none-img" src="../../static/image/order.png" mode=""></image>
            </view>

        </view>
        <uni-load-more :status="loadStatus"></uni-load-more>

    </view>
</template>

<script>
    import uniLoadMore from '@/components/uni-load-more/uni-load-more.vue'

    import lvvPopup from '@/components/lvv-popup/lvv-popup.vue';
    import {
        apiBaseUrl
    } from '@/config/config.js'
    export default {
        components: {
            lvvPopup,
            uniLoadMore
        },
        data() {
            return {
                goodsList: [],
                loadStatus: 'more',
                orderItems: [{
                        name: '全部宝贝',
                        nums: '115'
                    },
                    {
                        name: '收藏本店',
                        icon: '/static/image/ic-me-collect.png',
                    },
                    {
                        name: '二维码',
                        icon: '/static/image/qr_code.png',
                    }
                ],
                storeCode: '',
                store_name: '', //店铺名称
                store_logo: '',
                store_logo_src: '',
                store_banner: '',
                store_desc: '', //店铺介绍
                store_banner_src: '',
                isWeixinBrowser: this.$common.isWeiXinBrowser(), //判断是否是微信浏览器
                total_goods: 0,
                myShareCode: '', //邀请码
                page: 1, //默认页码
                searchKey: '请输入关键字搜索'
            }
        },
        onShow: function() {
            if (this.$store.state.config.distribution_store == '2') {
                //跳转到首页
                uni.switchTab({
                    url: '/pages/index/index'
                });
            }
        },
        //加载执行
        onLoad: function(options) {
            let store = options.store;
            this.storeCode = store;
            this.getDistribution(store);
            this.getGoods();
            this.getMyShareCode()
        },
        mounted() {
            // #ifdef H5 || APP-PLUS
            window.addEventListener('scroll', this.handleScroll)
            // #endif
        },
        updated() {
            // #ifndef MP-WEIXIN
            // 获取上半部分的整体高度
            this.$nextTick(() => {
                let h = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; //浏览器高度
                this.top_height = this.$refs.myStore.$el.clientHeight;
            })
            // #endif
        },
        methods: {
            // 显示modal弹出框
            openPopup() {
                this.$refs.lvvpopref.show();
            },
            // 关闭modal弹出框
            closePopup() {
                this.$refs.lvvpopref.close();
            },
            //去搜索
            goSearch() {
                let pages = getCurrentPages();
                let prevPage = pages[pages.length - 2];
                // #ifdef H5 || MP-WEIXIN
                if (prevPage && prevPage.route) {
                    let search_flag = prevPage.route;
                    if (search_flag == 'pages/index/search') {
                        uni.navigateBack({
                            delta: 1
                        });
                    } else {
                        this.$common.navigateTo('/pages/index/search');
                    }
                } else {
                    this.$common.navigateTo('/pages/index/search');
                }
                // #endif

                // #ifdef MP-ALIPAY
                if (prevPage && prevPage.__proto__.route) {
                    let search_flag = prevPage.__proto__.route;
                    if (search_flag == 'pages/index/search') {
                        uni.navigateBack({
                            delta: 1
                        });
                    } else {
                        this.$common.navigateTo('/pages/index/search');
                    }
                } else {
                    this.$common.navigateTo('/pages/index/search');
                }
                // #endif
            },
            //跳转到商品详情页面
            goodsDetail: function(id) {
                let url = '/pages/goods/index/index?id=' + id;
                this.$common.navigateTo(url);
            },
            //取得商品数据
            getGoods: function() {
                let data = {
                    page: this.page,
                    limit: 10
                }
                this.loadStatus = 'loading'
                this.$api.goodsList(data, res => {
                    if (res.status) {
                        if (this.page >= res.data.total_page) {
                            // 没有数据了
                            this.loadStatus = 'noMore'
                        } else {
                            // 未加载完毕
                            this.loadStatus = 'more'
                            this.page++
                        }
                        this.goodsList = [...this.goodsList, ...res.data.list]
                    } else {
                        this.$common.errorToShow(res.msg)
                    }
                });
            },
            //获取分销商信息
            getDistribution: function(store) {
                let _this = this;
                _this.$api.getStoreInfo({
                    store: store
                }, function(res) {
                    if (res.status) {
                        _this.store_name = res.data.store_name;
                        _this.store_desc = res.data.store_desc;
                        _this.store_logo_src = res.data.store_logo_src;
                        _this.store_logo = res.data.store_logo;
                        _this.store_banner_src = res.data.store_banner_src;
                        _this.total_goods = res.data.total_goods;
                        uni.setNavigationBarTitle({
                            title: _this.store_name
                        });
                    } else {
                        //报错了
                        _this.$common.errorToShow(res.msg);
                    }
                });
            },
            // 生成邀请海报
            createPoster() {
                let data = {
                    type: 4,
                    id: this.storeCode
                }

                let pages = getCurrentPages()
                let page = pages[pages.length - 1]
                let page_path = '/pages/share/jump';
                // #ifdef H5
                data.source = 1;
                data.return_url = apiBaseUrl + 'wap/' + page_path;
                // #endif

                // #ifdef MP-WEIXIN
                data.source = 2;
                data.return_url = page_path;
                // #endif

                // #ifdef MP-ALIPAY
                data.source = 3;
                data.return_url = page_path;
                // #endif

                let userToken = this.$db.get('userToken')

                if (userToken) {
                    data.token = userToken
                }
                this.$api.createPoster(data, res => {
                    if (res.status) {
                        this.$common.navigateTo('/pages/share?poster=' + res.data)
                    } else {
                        this.$common.errorToShow(res.msg)
                    }
                })
            },
            getMyShareCode() {
                let userToken = this.$db.get("userToken");
                if (userToken && userToken != '') {
                    // 获取我的分享码
                    this.$api.shareCode({}, res => {
                        if (res.status) {
                            this.myShareCode = res.data ? res.data : '';
                        }
                    });
                }
            }
        },
        //上拉加载
        onReachBottom() {
            if (this.loadStatus === 'more') {
                this.getGoods();
            }
        },
        //分享
        onShareAppMessage() {
            let myInviteCode = this.myShareCode ? this.myShareCode : '';
            let ins = this.$common.shareParameterDecode('type=9&invite=' + myInviteCode + "&id=" + this.storeCode);
            let path = '/pages/share/jump?scene=' + ins;
            return {
                title: this.$store.state.config.share_title,
                // #ifdef MP-ALIPAY
                desc: this.$store.state.config.share_desc,
                // #endif
                imageUrl: this.$store.state.config.share_image,
                path: path
            }
        }

    }
</script>

<style>
    .mst-top {
        width: 100%;
    }

    .mst-top image {
        width: 100%;
    }

    .member-grid {
        border-top: 2upx solid #ddd;
        background-color: #fff;
        margin-bottom: 20upx;
    }

    .member-item {
        border-right: 2upx solid #eee;
        height: 90upx;
    }

    .member-item:last-child {
        border-right: none;
    }

    .member-item-img {
        width: 150upx;
        height: 150upx;
        top: -70upx;
        position: absolute;
        left: 42%;
        transform: translateX(-50%);
        border-radius: 10upx;
        background-color: #fff;
        border-radius: 6upx;
        box-shadow: 0 0 10upx #ccc;
    }

    .img-grids {
        padding-bottom: 26upx;
    }

    .img-grids-item {
        margin-bottom: 0;
    }

    .scroll-Y {
        /*  #ifdef  H5  */
        height: calc(100vh - 44px - 0upx);
        /*  #endif  */
        /*  #ifndef H5 */
        height: calc(100vh - 0upx);
        /*  #endif  */
        position: position;
        /* bottom: 0; */
        /*     padding-bottom:200upx */

    }

    .collect-pop {
        width: 100%;
        height: 100%;
        /* background: #FFFFFF; */
        position: absolute;
        left: 0;
        bottom: 0;
        /* transform: ; */
    }

    .collect-pop image {
        width: 100%;
    }

    .h5-tip {
        text-align: center;
        margin-top: 300upx;
    }

    .member-item .share {
        background: none !important;
        line-height: normal;
    }
</style>
order.vue
<template>
    <view class="content">
        <view class="type-c" v-if="list.length">
            <view class="cell-group margin-cell-group" v-for="(item, index) in list" :key="index">
                <view class="cell-item">
                    <view class="cell-item-hd">
                        <view class='cell-hd-title'>下单人:{{ item.buy_user }}</view>
                    </view>
                    <view class="cell-item-ft">
                        <view class="cell-ft-p color-9">
                            {{ item.ctime }}
                        </view>
                    </view>
                </view>
                <view class="cell-item">
                    <view class="cell-item-hd">
                        <view class='cell-hd-title color-9'>订单号:{{ item.order_id }}</view>
                    </view>
                    <view class="cell-item-ft red-price">
                        {{ item.amount }}
                    </view>
                </view>
            </view>
            <uni-load-more
            :status="loadStatus"
            ></uni-load-more>
        </view>
        <view class="order-none" v-else>
            <image class="balance-none-img" src="/static/image/order.png" mode=""></image>
        </view>
    </view>
</template>

<script>
import uniLoadMore from '@/components/uni-load-more/uni-load-more.vue'
import { goods } from '@/config/mixins.js'
    export default {
        mixins: [ goods ],
        components: {
            uniLoadMore
        },
        data() {
            return {
                startTime: 0,
                screenName: '',
                page: 1,
                limit: 10,
                list: [], // 商品浏览足迹
                loadStatus: 'more'
            };
        },
        onLoad () {
            this.getDistributionOrder()
        },
        onShow() {
            const res = uni.getSystemInfoSync();
        },
        onReachBottom () {
            if (this.loadStatus === 'more') {
                this.getDistributionOrder()
            }
        },
        methods: {
            getDistributionOrder () {
                let data = {
                    page: this.page,
                    limit: this.limit
                }

                this.loadStatus = 'loading'
                
                this.$api.getDistributionOrder(data, res => {
                    //console.log(res);
                    if (res.status) {
                        let _list = res.data.list
                        _list.forEach (item => {
                            this.$set(item, 'slide_x', 0)
                        })
                        this.list = [...this.list, ..._list]
                        
                        if (res.data.count > this.list.length) {
                            this.page ++
                            this.loadStatus = 'more'
                        } else {
                            this.loadStatus = 'noMore'
                        }
                    } else {
                        this.$common.errorToShow(res.msg)
                    }
                })
            },
        }
    };
</script>

<style scoped>
.type-c .cell-group{
    padding: 10upx 0;
    margin-top: 0;
}
.type-c .cell-item{
    border: none;
    min-height: 70upx;
    padding: 0 26upx 0 0;
}
.type-c .cell-item .red-price{
    font-size: 50upx;
}
.type-c .cell-item .color-9{
    font-size: 24upx;
}
.order-none{
    text-align: center;
    padding: 200upx 0;
}
.balance-none-img{
    width: 274upx;
    height: 274upx;
}
</style>
popularize.vue
<template>
    <view class="content">
        <view class="content-c">
            <view class="content-c-top color-6 fsz28">
                将网站分享给您的好友,您的好友通过您的分享购买网站商品,你将会获得佣金。
            </view>
            <image class="qrcode-img" src="/static/demo-img/qcode.png" mode="widthFix"></image>
            <view class="color-3 fsz26">
                长按保存二维码图片
            </view>
        </view>
    </view>
</template>

<script>
</script>

<style>
.content-c{
    text-align: center;
    padding: 50upx 0;
    width: 80%;
    margin: 0 auto;
}
.content-c-top{
    text-align: left;
}
.qrcode-img{
    width: 400upx;
    height: 400upx;
    /* margin-top: 50upx; */
    margin: 50upx auto;
}
</style>
store_setting.vue
<template>
    <view class="content">
        <view class="content-top">
            <view class='cell-group'>
                <view class='cell-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>名称</view>
                    </view>
                    <view class='cell-item-bd'>
                        <input class='cell-bd-input' placeholder='请输入店铺名称' v-model="store_name"></input>
                    </view>
                </view>
                <view class='cell-item user-head'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>图标</view>
                    </view>
                    <view class='cell-item-ft'>
                        <image class='cell-ft-next user-head-img have-none' mode="aspectFill" :src="logo" @click="uploadLogo"></image>
                    </view>
                </view>
            </view>
            <view class='cell-group'>
                <view class='cell-item right-img'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>店招</view>
                    </view>
                </view>
                <view class="">
                    <view class="evaluate-c-b">
                        <view class="goods-img-item" v-for="(item, key) in images" :key="key">
                            <image class="del" src="/static/image/del.png" mode="" @click="delImage(item)"></image>
                            <image class="" :src="item.url" mode="" @click="clickImg(item.url)"></image>
                        </view>
                        <view class="upload-img" v-show="isImage" @click="upImage">
                            <image class="icon" src="/static/image/camera.png" mode=""></image>
                            <view class="">上传照片</view>
                        </view>
                    </view>
                </view>
            </view>
            <view class='cell-group'>
                <view class='cell-item right-img'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>简介</view>
                    </view>

                </view>
                <view class="cell-textarea ">
                    <textarea v-model="store_desc" placeholder="请您在此描述问题(最多200字)" maxlength="200" />
                    </view>
            </view>
        </view>
        <view class="button-bottom">
            <button class="btn btn-square btn-b"  hover-class="btn-hover2" @click="submitHandler()">保存</button>
        </view>
    </view>
</template>

<script>
export default {
    data() {
        return {
            title: 'picker',
            logo: '',
            index: 2,
            images:[],
            image_max: 1,
            store_name:'',//店铺名称
            store_logo:'',
            store_banner:'',
            store_desc:'',//店铺介绍
            store_logo_src:'',
            store_banner_src:'',
        }
    },
    computed: {
        isImage() {
            let num = this.image_max - this.images.length;
            if(num > 0) {
                return true;
            }else{
                return false;
            }
        }
    },
    methods: {
        // 用户上传头像
        uploadLogo () {
            this.$api.uploadFiles(res => {
                if (res.status) {
                    this.store_logo = res.data.image_id;
                    this.logo = res.data.url;
                } else {
                    this.$common.errorToShow(res.msg)
                }
            })
        },
        // 保存资料
        submitHandler() {
            if(!this.store_name||this.store_name==''){
                this.$common.errorToShow('请填写店铺名称');
                return;
            }
            if(this.images.length <= 0){
                this.$common.errorToShow('请上传店招');
                return;
            }
            if(!this.store_logo){
                this.$common.errorToShow('请上传图标');
                return;
            }
            this.store_banner = this.images[0].image_id;
            
            this.$api.setStore({
                    store_name: this.store_name,
                    store_logo: this.store_logo,
                    store_banner: this.store_banner,
                    store_desc: this.store_desc
                }, res => {
                    if(res.status){
                        this.$common.successToShow(res.msg, result => {
                            uni.navigateBack({
                                delta: 1
                            });
                        });
                    }else{
                        this.$common.errorToShow(res.msg);
                    }
                }
            );
        },
                //上传图片
        upImage() {
            let num = this.image_max - this.images.length;
            if(num > 0){
                this.$api.uploadImage(num, res => {
                    if(res.status){
                        this.images.push(res.data);
                        this.$common.successToShow(res.msg);
                    }else{
                        this.$common.errorToShow(res.msg);
                    }
                });
            }
        },
        //删除图片
        delImage(e) {
            let newImages = [];
            for(var i = 0; i < this.images.length; i++) {
                if(this.images[i].image_id != e.image_id){
                    newImages.push(this.images[i]);
                }
            }
            this.images = newImages;
        },
        // 图片点击放大
        clickImg (img) {
            // 预览图片
            uni.previewImage({
                urls: img.split()
            });
        }
    },
    onLoad: function() {
        var _this = this;
        _this.$api.getDistributioninfo({check_condition:false}, function(res) {
            if (res.status) {
                _this.store_name = res.data.store_name;
                _this.store_desc = res.data.store_desc;
                _this.store_logo = res.data.store_logo;
                if( res.data.store_logo){
                    _this.logo = res.data.store_logo_src;
                }
                _this.store_banner = res.data.store_banner;
                if(_this.store_banner){
                    _this.images.push({
                        image_id:res.data.store_banner,
                        url:res.data.store_banner_src
                        });
                }
            } else {
                //报错了
                _this.$common.errorToShow(res.msg);
            }
        });
    }
}
</script>

<style>
.user-head{
    height: 100upx;
}
.user-head-img{
    height: 90upx;
    width: 90upx;
    border-radius: 50%;
}
.cell-hd-title{
    color: #333;
}
.cell-item-bd{
    color: #666;
    font-size: 26upx;
}
.list-goods-name{
    width: 100% !important;
}
.cart-checkbox-item{
    position: relative;
}
.invoice-type .uni-list-cell{
    display: inline-block;
    font-size: 26upx;
    color: #333;
    position: relative;
    margin-left: 50upx;
}
.invoice-type .uni-list-cell>view{
    display: inline-block;
}
.invoice-type-icon{
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
}
.invoice-type-c{
    margin-left: 50upx;
    line-height: 2;
}
.cell-item-ft .cell-bd-input{
    text-align: right;
    width: 500upx;
    font-size: 28upx;
}
.right-img{
    border-bottom: 0;
}
.cell-textarea{
    padding: 0 26upx 20upx;
}
.cell-textarea textarea{
    width: 100%;
    height: 200upx;
    font-size: 26upx;
    color: #333;
}
.evaluate-c-b{
    overflow: hidden;
    padding: 0 20upx;
}
.upload-img{
    width: 146upx;
    height: 146upx;
    margin: 14upx;
    text-align: center;
    color: #999999;
    font-size: 22upx;
    border: 2upx solid #E1E1E1;
    border-radius: 4upx;
    display: inline-block;
    float: left;
    padding: 24upx 0;
}
.goods-img-item{
    width: 174upx;
    height: 174upx;
    padding: 14upx;
    float: left;
    position: relative;
}
.goods-img-item:nth-child(4n){
    margin-right: 0;
}
.goods-img-item image{
    width: 100%;
    height: 100%;
}
.del{
    width: 30upx !important;
    height: 30upx !important;
    position: absolute;
    right: 0;
    top: 0;
    z-index: 999;
}
.cell-textarea textarea{
    background-color: #f8f8f8;
    padding: 12upx 20upx;
    box-sizing: border-box;
}
</style>
user.vue
<template>
    <view class="content">

        <!-- 用户头像header -->
        <view class='member-top'>
            <!-- <image class='bg-img' src='/static/image/member-bg.png'></image> -->
            <view class='member-top-c'>
                <view class="fsz50 color-f">{{info.total_settlement_amount}}</view>
                <view class='fsz26 color-d'>累计收入</view>
            </view>
        </view>
        <!-- 用户头像header end -->

        <!-- 其他功能菜单 -->
        <view class='member-grid'>
            <view class='member-item' v-for="(item, index) in orderItems" :key="index">
                <text class='member-item-text'>{{ item.name }}</text>
                <view class="color-o fsz38">{{ item.nums }}</view>
            </view>
        </view>
        <view class='cell-group margin-cell-group right-img'>
            <view class='cell-item' v-for="(item, index) in utilityMenus" :key="index">
                <view class='cell-item-hd' @click="navigateToHandle(item.router)">
                    <image class='cell-hd-icon' :src='item.icon'></image>
                    <view class='cell-hd-title'>{{ item.name }}</view>
                </view>
                <view class='cell-item-ft'>
                    <image class='cell-ft-next icon' src='/static/image/right.png'></image>
                </view>
            </view>
            <view class='cell-item'>
                <view class='cell-item-hd' @click="createPoster()">
                    <image class='cell-hd-icon' src='/static/image/extension.png'></image>
                    <view class='cell-hd-title'>我要推广</view>
                </view>
                <view class='cell-item-ft'>
                    <image class='cell-ft-next icon' src='/static/image/right.png'></image>
                </view>
            </view>
        </view>
        <!-- 其他功能菜单end -->
        <jihaiCopyright></jihaiCopyright>
    </view>
</template>


<script>
    import jihaiCopyright from '@/components/jihai-copyright/jihaiCopyright.vue'
    import {
        checkLogin
    } from '@/config/mixins.js'
    import {
        apiBaseUrl
    } from '@/config/config.js'
    export default {
        components: {
            jihaiCopyright
        },
        mixins: [checkLogin],
        data() {
            return {
                // isClerk: false,
                orderItems: {
                    freeze: {
                        name: '冻结金额',
                        nums: "0"
                    },
                    settlement: {
                        name: '已结算金额',
                        nums: '0'
                    },
                    current_month_order: {
                        name: '本月订单数',
                        nums: '0'
                    }
                },
                utilityMenus: {
                    invite: {
                        name: '我的邀请',
                        icon: '/static/image/ic-me-invite.png',
                        router: '../invite/list'
                    },
                    order: {
                        name: '推广订单',
                        icon: '/static/image/extension_order.png',
                        router: './order'
                    },
                    balance: {
                        name: '我的佣金',
                        icon: '/static/image/ic-me-balance.png',
                        router: '../balance/details?status=5'
                    },
                    my_store: {
                        name: '我的店铺',
                        icon: '/static/image/my_store.png',
                        router: './my_store'
                    },
                    store_setting: {
                        name: '店铺设置',
                        icon: '/static/image/me-ic-set.png',
                        router: './store_setting'
                    }
                },
                info: {}, //分销商信息

            }
        },
        onShow() {
            var _this = this;
            if (_this.$store.state.config.distribution_store != '1') {
                delete this.utilityMenus.my_store;
                delete this.utilityMenus.store_setting;
            }
            _this.$api.getDistributioninfo({}, function(res) {
                if (res.status) {
                    _this.info = res.data;
                    if (res.data.verify != 1) { //审核通过
                        _this.$common.redirectTo('/pages/member/distribution/index');
                    }
                    _this.orderItems.freeze.nums = _this.info.freeze_amount;
                    _this.orderItems.settlement.nums = _this.info.settlement_amount;
                    _this.orderItems.current_month_order.nums = _this.info.current_month_order;
                    if (_this.$store.state.config.distribution_store == '1') {
                        _this.utilityMenus.my_store.router = './my_store?store=' + _this.info.store;
                    }
                    
                } else {
                    //报错了
                    _this.$common.errorToShow(res.msg);
                }
            });
        },
        methods: {

            navigateToHandle(pageUrl) {
                this.$common.navigateTo(pageUrl)
            },
            orderNavigateHandle(url, tab = 0) {
                if (!this.hasLogin) {
                    return this.checkIsLogin()
                }
                this.$store.commit('orderTab', tab)
                this.$common.navigateTo(url)
            },
            goAfterSaleList() {
                if (!this.hasLogin) {
                    return this.checkIsLogin()
                }
                this.$common.navigateTo('../after_sale/list')
            },
            // 生成邀请海报
            createPoster() {
                let data = {
                    type: 4,
                    id: this.info.store,

                }
                //console.log(this.info.store)
                let pages = getCurrentPages()
                let page = pages[pages.length - 1]
                let page_path = '/pages/share/jump';
                // #ifdef H5
                data.source = 1;
                data.return_url = apiBaseUrl + 'wap/' + page_path;
                // #endif

                // #ifdef MP-WEIXIN
                data.source = 2;
                data.return_url = page_path;
                // #endif

                // #ifdef MP-ALIPAY
                data.source = 3;
                data.return_url = page_path;
                // #endif

                let userToken = this.$db.get('userToken')

                if (userToken) {
                    data.token = userToken
                }
                this.$api.createPoster(data, res => {
                    if (res.status) {
                        this.$common.navigateTo('/pages/share?poster=' + res.data)
                    } else {
                        this.$common.errorToShow(res.msg)
                    }
                })
            },
        },
        //分享
        onShareAppMessage() {
            let myInviteCode = this.myShareCode ? this.myShareCode : '';
            let ins = this.$common.shareParameterDecode('type=3&invite=' + myInviteCode);
            let path = '/pages/share/jump?scene=' + ins;
            return {
                title: this.$store.state.config.share_title,
                // #ifdef MP-ALIPAY
                desc: this.$store.state.config.share_desc,
                // #endif
                imageUrl: this.$store.state.config.share_image,
                path: path
            }
        }
    }
</script>

<style>
    .member-top {
        position: relative;
        width: 100%;
        height: 340upx;
        background-color: #FF7159;
    }

    .bg-img {
        position: absolute;
        width: 100%;
        height: 100%;
    }

    .member-top-c {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        text-align: center;
    }

    .user-head-img {
        display: block;
        width: 160upx;
        height: 160upx;
        border-radius: 50%;
        overflow: hidden;
        background-color: rgba(255, 255, 255, 0.7);
    }

    .user-name {
        font-size: 30upx;
        color: #fff;
    }

    .member-grid {
        background-color: #fff;
        border-top: 2upx solid #eee;
        padding: 20upx 0;
    }

    .margin-cell-group {
        margin: 20upx 0;
        color: #666666;
    }

    .badge {
        left: 80upx;
        top: -6upx;
    }

    button.cell-item-hd {
        background-color: #fff;
        padding: 0;
        line-height: 1.4;
        color: #333;
    }

    button.cell-item-hd:after {
        border: none;
    }

    .login-btn {
        color: #fff;
        width: 160upx;
        height: 50upx;
        line-height: 50upx;
        border-radius: 25upx;
        background: #ff7159;
        font-size: 12px;
        margin-top: 16upx;
    }
</style>
history
index.vue
<template>
    <view class="content">
        <view class="collection" v-if="list.length">
            <view class="container_of_slide" 
            v-for="(item, index) in list" 
            :key="index"
            >
                <view class="slide_list" 
                @touchstart="touchStart($event,index)" 
                @touchend="touchEnd($event,index)" 
                @touchmove="touchMove($event,index)"
                @tap="recover(index)" 
                :style="{transform:'translate3d('+item.slide_x+'px, 0, 0)'}"
                v-if="item.goods"
                >
                    <view class="now-message-info" hover-class="uni-list-cell-hover" :style="{width:Screen_width+'px'}" 
                    @click="goodsDetail(item.goods_id)">
                        <view class="icon-circle">
                            <image class='goods-img' :src="item.goods.image_url" mode="aspectFill"></image>
                        </view>
                        
                        <view class="list-right">
                            <view class="list-title">{{ item.goods.name }}</view>
                            <view class="red-price">¥{{ item.goods.price }}</view>
                            <view class="list-detail">{{ item.ctime }}</view>
                        </view>
                        <view class="list-right-1">
                            <image class='cell-ft-next icon' src='/static/image/right.png'></image>
                        </view>
                    </view>
                    <view class="group-btn">
                        <view class="top btn-div" @tap="collect(index)" v-if="item.isCollection">
                            取消
                        </view>
                        <view class="top btn-div" @tap="collect(index)" v-if="!item.isCollection">
                            收藏
                        </view>
                        <view class="removeM btn-div" @tap="remove(index)">
                            删除
                        </view>
                    </view>
                    <view style="clear:both"></view>
                </view>
            </view>
            <uni-load-more
            :status="loadStatus"
            ></uni-load-more>
        </view>
        <view class="history-none" v-else>
            <image class="history-none-img" src="/static/image/order.png" mode=""></image>
        </view>
    </view>
</template>

<script>
import uniLoadMore from '@/components/uni-load-more/uni-load-more.vue'
import { goods } from '@/config/mixins.js'
    export default {
        mixins: [ goods ],
        components: {
            uniLoadMore
        },
        computed: {
            Screen_width() {
                return uni.getSystemInfoSync().windowWidth;
            }
        },
        data() {
            return {
                visible: false,
                start_slide_x: 0,
                btnWidth: 0,
                startX: 0,
                LastX: 0,
                startTime: 0,
                screenName: '',
                page: 1,
                limit: 10,
                list: [], // 商品浏览足迹
                loadStatus: 'more'
            };
        },
        onLoad () {
            this.goodsBrowsing()
        },
        onShow() {
            const res = uni.getSystemInfoSync();
        },
        onReachBottom () {
            if (this.loadStatus === 'more') {
                this.goodsBrowsing()
            }
        },
        methods: {
            goodsBrowsing () {
                let data = {
                    page: this.page,
                    limit: this.limit
                }

                this.loadStatus = 'loading'
                
                this.$api.goodsBrowsing(data, res => {
                    if (res.status) {
                        let _list = res.data.list
                        _list.forEach (item => {
                            this.$set(item, 'slide_x', 0)
                            item.ctime = this.$common.timeToDate(item.ctime)
                        })
                        this.list = [...this.list, ..._list]
                        
                        if (res.data.count > this.list.length) {
                            this.page ++
                            this.loadStatus = 'more'
                        } else {
                            this.loadStatus = 'noMore'
                        }
                    } else {
                        this.$common.errorToShow(res.msg)
                    }
                })
            },
            cancelEvent(){
                this.visible = false
            },
            // 滑动开始
            touchStart(e, index) {
                this.startCilentY = e.touches[0].clientY;
                //记录手指放上去的时间
                this.startTime = e.timeStamp;
                //记录滑块的初始位置
                this.start_slide_x = this.list[index].slide_x;
                // 按钮宽度
                uni.createSelectorQuery()
                    .selectAll('.group-btn')
                    .boundingClientRect()
                    .exec(res => {
                        if (res[0] != null) {
                            this.btnWidth = res[0][index].width * -1;
                        }
                    });
                // 记录上一次开始时手指所处位置
                this.startX = e.touches[0].pageX;
                // 记录上一次手指位置
                this.lastX = this.startX;
                //初始化非当前滑动消息列的位置
                this.list.forEach((item, eq) => {
                    if (eq !== index) {
                        item.slide_x = 0;
                    }
                });
            },
            // 滑动中
            touchMove(e, index) {
                var endCilentY = e.touches[0].clientY; 
                var moveClientY = endCilentY - this.startCilentY;
                if (this.direction === 'Y' || Math.abs(moveClientY ) > 20 || e.currentTarget.dataset.disabled === true) { this.direction = ''; return; }
                const endX = e.touches[0].pageX;
                const distance = endX - this.lastX;
                // 预测滑块所处位置
                const duang = this.list[index].slide_x + distance;
                // 如果在可行区域内
                if (duang <= 0 && duang >= this.btnWidth) {
                    this.list[index].slide_x = duang;
                }
                // 此处手指所处位置将成为下次手指移动时的上一次位置
                this.lastX = endX;
            },
            // 滑动结束
            touchEnd(e, index) {
                let distance = 10;
                const endTime = e.timeStamp;
                const x_end_distance = this.startX - this.lastX;
                if (Math.abs(endTime - this.startTime) > 200) {
                    distance = this.btnWidth / -2;
                }
                // 判断手指最终位置与手指开始位置的位置差距
                if (x_end_distance > distance) {
                    this.list[index].slide_x = this.btnWidth;
                } else if (x_end_distance < distance * -1) {
                    this.list[index].slide_x = 0;
                } else {
                    this.list[index].slide_x = this.start_slide_x;
                }
            },
            // 点击回复原状
            recover(index) {
                this.list[index].slide_x = 0;
            },
            // 收藏/取消
            collect (index) {
                let data = {
                    goods_id: this.list[index].goods_id
                }
                
                this.$api.goodsCollection(data, res => {
                    if (res.status) {
                        this.$common.successToShow(res.msg, () => {
                            this.$nextTick(() => {
                                this.list[index].isCollection = !this.list[index].isCollection
                            })
                        })
                    } else {
                        this.$common.errorToShow(res.msg)
                    }
                })
            },
            // 删除
            remove(index) {
                
                let data = {
                    goods_ids: this.list[index].goods_id
                }
                
                this.$api.delGoodsBrowsing(data, res => {
                    if (res.status) {
                        this.$common.successToShow(res.msg, () => {
                            this.list.splice(index, 1)
                        })
                    } else {
                        this.$common.errorToShow(res.msg)
                    }
                })
            }
        }
    };
</script>

<style scoped>
.collection .goods-img{
    width: 150upx;
    height: 150upx;    
}
.container_of_slide {
    width: 100%;
    overflow: hidden;
}
.slide_list {
    transition: all 100ms;
    transition-timing-function: ease-out;
    min-width: 200%;
}
.now-message-info {
    box-sizing:border-box;
    display: flex;
    align-items: center;
    font-size: 16px;
    clear:both;
    padding: 20upx 26upx;
    margin-bottom: 2upx;
    background: #FFFFFF;
}
.now-message-info,
.group-btn {
    float: left;
}
.group-btn {
    display: flex;
    flex-direction: row;
    height: 190upx;
    min-width: 100upx;
    align-items: center;

}
.group-btn .btn-div {
    height: 190upx;
    color: #fff;
    text-align: center;
    padding: 0 50upx;
    font-size: 34upx;
    line-height: 190upx;
}
.group-btn .top {
    background-color: #FF7159;
}
.group-btn .removeM {
    background-color: #999;
}
.icon-circle{
    width:150upx;
    height: 150upx;
    float: left;
}
.list-right{
    float: left;
    margin-left: 25upx;
    height: 150upx;
}
.list-right-1{
    float: right;
    color: #A9A9A9;
}
.list-title{
    width: 490upx;
    line-height:1.5;
    overflow:hidden;
    color:#333;
    display:-webkit-box;
    -webkit-box-orient:vertical;
    -webkit-line-clamp:2;
    overflow:hidden;
    font-size: 26upx;
    color: #333;
    min-height: 80upx;
}
.list-detail{
    width: 460upx;
    font-size: 24upx;
    color: #a9a9a9;
    display:-webkit-box;
    -webkit-box-orient:vertical;
    -webkit-line-clamp:1;
    overflow:hidden;
}
.history-none{
    text-align: center;
    padding: 200upx 0;
}
.history-none-img{
    width: 274upx;
    height: 274upx;
}
</style>
index
index.vue
<template>
    <view class="content">

        <!-- 用户头像header -->
        <view class='member-top'>
            <image class='bg-img' src='/static/image/member-bg.png'></image>
            <view class='member-top-c'>
                <template v-if="hasLogin">
                    <image class='user-head-img' mode="aspectFill" :src='userInfo.avatar'></image>
                    <view class='user-name'>{{ userInfo.nickname }}</view>
                    <view class="fz12 grade" v-if="userInfo.grade_name">
                        {{userInfo.grade_name}}
                    </view>
                </template>
                <template v-else>
                    <!-- #ifdef H5 || APP-PLUS -->
                    <image class='user-head-img' mode="aspectFill" :src='$store.state.config.shop_logo'></image>
                    <view class="login-btn" @click="toLogin">
                        登录/注册
                    </view>
                    <!-- #endif -->
                    <!-- #ifdef MP-WEIXIN -->
                    <view class="user-head-img">
                        <open-data type="userAvatarUrl"></open-data>
                    </view>
                    <view>
                        <!-- open-type="getUserInfo" @getuserinfo="getUserInfo" -->
                        <button class="login-btn" hover-class="btn-hover" @click="goLogin()">授权登录</button>
                    </view>
                    <!-- #endif -->
                    <!-- #ifdef MP-ALIPAY -->
                    <view class="user-head-img"></view>
                    <view>
                        <button class="login-btn" open-type="getAuthorize" @click="getALICode" hover-class="btn-hover">授权登录</button>
                    </view>
                    <!-- #endif -->
                </template>

            </view>
        </view>
        <!-- 用户头像header end -->

        <!-- 订单列表信息 -->
        <view class='cell-group'>
            <view class='cell-item right-img' @click="orderNavigateHandle('../order/orderlist')">
                <view class='cell-item-hd'>
                    <view class='cell-hd-title'>我的订单</view>
                </view>
                <view class='cell-item-ft'>
                    <image class='cell-ft-next icon' src='/static/image/right.png'></image>
                </view>
            </view>
        </view>

        <view class='member-grid'>
            <view class='member-item' v-for="(item, index) in orderItems" :key="index" @click="orderNavigateHandle('../order/orderlist', index + 1)">
                <view class="badge color-f" v-if="item.nums">{{ item.nums }}</view>
                <image class='member-item-icon' :src='item.icon'></image>
                <text class='member-item-text'>{{ item.name }}</text>
            </view>
            <view class='member-item' @click="goAfterSaleList">
                <view class="badge color-f" v-if="afterSaleNums != 0">{{afterSaleNums}}</view>
                <image class='member-item-icon' src='/static/image/me-ic-evaluate.png'></image>
                <text class='member-item-text'>退换货</text>
            </view>
        </view>
        <!-- 订单列表end -->

        <!-- 其他功能菜单 -->
        <view class='cell-group margin-cell-group right-img'>

            <view class='cell-item' v-for="(item, index) in utilityMenus" :key="index" v-if="!item.unshowItem">
                <view class='cell-item-hd' @click="navigateToHandle(item.router)">
                    <image class='cell-hd-icon' :src='item.icon'></image>
                    <view class='cell-hd-title'>{{ item.name }}</view>
                </view>
                <view class='cell-item-ft'>
                    <image class='cell-ft-next icon' src='/static/image/right.png'></image>
                </view>
            </view>
            <!-- #ifdef H5 || APP-PLUS -->
            <view class='cell-item'>
                <view class='cell-item-hd' @click="showChat()">
                    <image class='cell-hd-icon' src='/static/image/me-ic-phone.png'></image>
                    <view class='cell-hd-title'>联系客服</view>
                </view>
                <view class='cell-item-ft'>
                    <image class='cell-ft-next icon' src='/static/image/right.png'></image>
                </view>
            </view>
            <!-- #endif -->
            <!-- #ifdef MP-WEIXIN -->
            <view class='cell-item'>
                <button class="cell-item-hd " hover-class="none" open-type="contact" bindcontact="showChat" :session-from="kefupara">
                    <image src='/static/image/me-ic-phone.png' class='cell-hd-icon'></image>
                    <view class='cell-hd-title'>联系客服</view>
                </button>
                <view class='cell-item-ft'>
                    <image class='cell-ft-next icon' src='/static/image/right.png'></image>
                </view>
            </view>
            <!-- #endif -->
            <!-- #ifdef MP-ALIPAY -->
            <view class='cell-item'>
                <contact-button icon="/static/image/kefu2.png" size="170rpx*76rpx" tnt-inst-id="WKPKUZXG" scene="SCE00040186"
                 class="cell-item-hd " hover-class="none" />
                <view class='cell-item-ft'>
                    <image class='cell-ft-next icon' src='/static/image/right.png'></image>
                </view>
            </view>
            <!-- #endif -->
        </view>

        <view class='cell-group margin-cell-group right-img' v-if="isClerk">
            <view class='cell-item' v-for="(item, index) in clerk" :key="index">
                <view class='cell-item-hd' @click="navigateToHandle(item.router)">
                    <image class='cell-hd-icon' :src='item.icon'></image>
                    <view class='cell-hd-title'>{{ item.name }}</view>
                </view>
                <view class='cell-item-ft'>
                    <image class='cell-ft-next icon' src='/static/image/right.png'></image>
                </view>
            </view>
        </view>
        <!-- 其他功能菜单end -->
        <jihaiCopyright></jihaiCopyright>
    </view>
</template>


<script>
    import jihaiCopyright from '@/components/jihai-copyright/jihaiCopyright.vue'
    import {
        checkLogin
    } from '@/config/mixins.js'
    export default {
        components: {
            jihaiCopyright
        },
        mixins: [checkLogin],
        data() {
            return {
                open_id: '',
                hasLogin: false,
                userInfo: {}, // 用户信息
                kefupara: '', //客服传递资料
                afterSaleNums: 0,
                isClerk: false,
                alipayNoLogin: true,
                alipayName: '',
                alipayAvatar: '',
                config:'',//配置信息
                orderItems: [{
                        name: '待付款',
                        icon: '/static/image/me-ic-obligation.png',
                        nums: 0
                    },
                    {
                        name: '待发货',
                        icon: '/static/image/me-ic-sendout.png',
                        nums: 0
                    },
                    {
                        name: '待收货',
                        icon: '/static/image/me-ic-receiving.png',
                        nums: 0
                    },
                    {
                        name: '待评价',
                        icon: '/static/image/me-ic-evaluate.png',
                        nums: 0
                    }
                ],
                utilityMenus: {
                    distribution: {
                        name: '分销中心',
                        icon: '/static/image/distribution.png',
                        router: '../distribution/user',
                        unshowItem: false
                    },
                    coupon: {
                        name: '我的优惠券',
                        icon: '/static/image/ic-me-coupon.png',
                        router: '../coupon/index',
                        unshowItem: false
                    },
                    balance: {
                        name: '我的余额',
                        icon: '/static/image/ic-me-balance.png',
                        router: '../balance/index',
                        unshowItem: false
                    },
                    integral: {
                        name: '我的积分',
                        icon: '/static/image/integral.png',
                        router: '../integral/index',
                        unshowItem: false
                    },
                    address: {
                        name: '地址管理',
                        icon: '/static/image/me-ic-site.png',
                        router: '../address/list',
                        unshowItem: false
                    },
                    collection: {
                        name: '我的收藏',
                        icon: '/static/image/ic-me-collect.png',
                        router: '../collection/index',
                        unshowItem: false
                    },
                    history: {
                        name: '我的足迹',
                        icon: '/static/image/ic-me-track.png',
                        router: '../history/index',
                        unshowItem: false
                    },
                    invite: {
                        name: '邀请好友',
                        icon: '/static/image/ic-me-invite.png',
                        router: '../invite/index',
                        unshowItem: true
                    },
                    setting: {
                        name: '系统设置',
                        icon: '/static/image/me-ic-set.png',
                        router: '../setting/index',
                        unshowItem: false
                    }
                },
                clerk: [{
                        name: '提货单列表',
                        icon: '/static/image/me-ic-phone.png',
                        router: '../take_delivery/list'

                    },
                    {
                        name: '提货单核销',
                        icon: '/static/image/me-ic-about.png',
                        router: '../take_delivery/index'
                    }
                ]
            }
        },
        onShow() {
            this.initData()
        },
        methods: {
            goLogin(){
                uni.navigateTo({
                    url:'/pages/login/choose/index'
                })
            },
            getUserInfo(e) {
                let _this = this
                //return false;
                if (e.detail.errMsg == 'getUserInfo:fail auth deny') {
                    _this.$common.errorToShow('未授权')
                } else {
                    var data = {
                        open_id: _this.open_id,
                        iv: e.detail.iv,
                        edata: e.detail.encryptedData,
                        signature: e.detail.signature
                    }
                    //有推荐码的话,带上
                    var invitecode = _this.$db.get('invitecode')
                    if (invitecode) {
                        data.invitecode = invitecode
                    }
                    _this.toWxLogin(data)
                }
            },
            getALICode() {
                let that = this
                uni.login({
                    scopes: 'auth_user',
                    success: (res) => {
                        if (res.authCode) {
                            uni.getUserInfo({
                                provider: 'alipay',
                                success: function(infoRes) {
                                    if (infoRes.errMsg == "getUserInfo:ok") {
                                        let user_info = {
                                            'nickname': infoRes.nickName,
                                            'avatar': infoRes.avatar
                                        }
                                        that.aLiLoginStep1(res.authCode, user_info);
                                    }
                                },
                                fail: function(errorRes) {
                                    this.$common.errorToShow('未取得用户昵称头像信息');
                                }
                            });
                        } else {
                            this.$common.errorToShow('未取得code');
                        }
                    },
                    fail: function(res) {
                        this.$common.errorToShow('用户授权失败my.login');
                    }
                });
            },
            getWxCode() {
                let that = this
                uni.login({
                    scopes: 'auth_user',
                    success: function(res) {
                        if (res.code) {
                            that.wxLoginStep1(res.code)
                        } else {
                            this.$common.errorToShow('未取得code')
                        }
                    },
                    fail: function(res) {
                        this.$common.errorToShow('用户授权失败wx.login')
                    }
                })
            },
            wxLoginStep1(code) {
                this.$api.login1({
                    code
                }, res => {
                    if (res.status) {
                        this.open_id = res.data
                    } else {
                        this.$common.errorToShow(res.msg, function() {
                            uni.navigateBack({
                                delta: 1
                            })
                        })
                    }
                })
            },
            aLiLoginStep1(code, user_info) {
                let data = {
                    'code': code,
                    'user_info': user_info
                }
                this.$api.alilogin1(data, res => {
                    this.alipayNoLogin = false;
                    if (res.status) {
                        this.open_id = res.data.user_wx_id
                        //判断是否返回了token,如果没有,就说明没有绑定账号,跳转到绑定页面
                        if (!res.data.hasOwnProperty('token')) {
                            this.$common.redirectTo('/pages/login/login/index?user_wx_id=' + res.data.user_wx_id);
                        } else {
                            this.$db.set('userToken', res.data.token)
                            this.initData()
                        }
                    } else {
                        this.$common.errorToShow(res.msg)
                    }
                })
            },
            toWxLogin(data) {
                let _this = this
                _this.$api.login2(data, function(res) {
                    if (res.status) {
                        //判断是否返回了token,如果没有,就说明没有绑定账号,跳转到绑定页面
                        if (typeof res.data.token == 'undefined') {
                            uni.redirectTo({
                                url: '/pages/login/login/index?user_wx_id=' + res.data.user_wx_id
                            })
                        } else {
                            _this.$db.set('userToken', res.data.token)
                            _this.initData()
                        }
                    } else {
                        _this.$common.errorToShow('登录失败,请重试')
                    }
                })
            },
            toLogin() {
                this.$common.navigateTo('../../login/login/index1')
            },
            initData() {
                // 获取用户信息
                var _this = this
                //判断是开启分销还是原始推广
                this.$api.shopConfig(res => {
                    this.config = res;
                    if (res.open_distribution) {
                        this.utilityMenus.invite.unshowItem = true
                    } else {
                        this.utilityMenus.distribution.unshowItem = true
                        this.utilityMenus.invite.unshowItem = false
                    }
                })
                if (this.$db.get('userToken')) {
                    this.hasLogin = true
                    this.$api.userInfo({}, res => {
                        if (res.status) {
                            _this.userInfo = res.data
                            // #ifdef MP-WEIXIN
                            //微信小程序打开客服时,传递用户信息
                            var kefupara = {}
                            kefupara.nickName = res.data.nickname
                            kefupara.tel = res.data.mobile
                            _this.kefupara = JSON.stringify(kefupara)
                            // #endif
                            // 获取订单不同状态的数量
                            let data = {
                                ids: '1,2,3,4',
                                isAfterSale: true
                            }
                            _this.$api.getOrderStatusSum(data, res => {
                                if (res.status) {
                                    _this.orderItems.forEach((item, key) => {
                                        item.nums = res.data[key + 1]
                                    })
                                    _this.afterSaleNums = res.data.isAfterSale ?
                                        res.data.isAfterSale :
                                        0
                                }
                            })
                            //判断是否是店员
                            this.$api.isStoreUser({}, res => {
                                this.isClerk = res.flag
                            })
                        }
                    })
                } else {
                    this.hasLogin = false
                    // #ifdef MP-WEIXIN
                    this.getWxCode()
                    // #endif
                }
            },
            navigateToHandle(pageUrl) {
                if (!this.hasLogin) {
                    return this.checkIsLogin()
                }
                this.$common.navigateTo(pageUrl)
            },
            orderNavigateHandle(url, tab = 0) {
                if (!this.hasLogin) {
                    return this.checkIsLogin()
                }
                this.$store.commit('orderTab', tab)
                this.$common.navigateTo(url)
            },
            goAfterSaleList() {
                if (!this.hasLogin) {
                    return this.checkIsLogin()
                }
                this.$common.navigateTo('../after_sale/list')
            },
            //在线客服,只有手机号的,请自己替换为手机号
            showChat() {
                // #ifdef H5
                let _this = this
                window._AIHECONG('ini', {
                    entId: this.config.ent_id,
                    button: false,
                    appearance: {
                        panelMobile: {
                            tone: '#FF7159',
                            sideMargin: 30,
                            ratio: 'part',
                            headHeight: 50
                        }
                    }
                })
                //传递客户信息
                window._AIHECONG('customer', {
                    head: _this.userInfo.avatar,
                    '名称': _this.userInfo.nickname,
                    '手机': _this.userInfo.mobile
                })
                window._AIHECONG('showChat')
                // #endif

                // 拨打电话
                // #ifdef APP-PLUS
                if (this.kfmobile) {
                    uni.makePhoneCall({
                        phoneNumber: '' + this.kfmobile,
                        success: () => {
                            // console.log("成功拨打电话")
                        }
                    })
                } else {
                    this.$common.errorToShow('商户未设置客服手机号')
                }
                // #endif
            }
        },
        computed: {
            // 获取店铺联系人手机号
            kfmobile() {
                return this.$store.state.config.shop_mobile || 0
            }
        },
        watch: {}
    }
</script>


<style>
    .member-top {
        position: relative;
        width: 100%;
        height: 340upx;
    }

    .bg-img {
        position: absolute;
        width: 100%;
        height: 100%;
    }

    .member-top-c {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        text-align: center;
    }

    .user-head-img {
        display: block;
        width: 160upx;
        height: 160upx;
        border-radius: 50%;
        overflow: hidden;
        background-color: rgba(255, 255, 255, 0.7);
        margin: 0 auto 16upx;
    }

    .user-name {
        font-size: 30upx;
        color: #fff;
        margin-bottom: 16upx;
    }

    .grade {
        color: #FFF;
    }

    .member-grid {
        background-color: #fff;
        border-top: 2upx solid #eee;
        padding: 20upx 0;
    }

    .margin-cell-group {
        margin: 20upx 0;
        color: #666666;
    }

    .badge {
        left: 80upx;
        top: -6upx;
    }

    button.cell-item-hd {
        background-color: #fff;
        padding: 0;
        line-height: 1.4;
        color: #333;
    }

    button.cell-item-hd:after {
        border: none;
    }

    .login-btn {
        color: #fff;
        width: 180upx;
        height: 50upx;
        line-height: 50upx;
        border-radius: 25upx;
        background: #ff7159;
        font-size: 12px;
    }
</style>
integral
index.vue
<template>
    <view class="content">
        <view class="integral-top">
            <view class="integral-top-t">
                可用积分
            </view>
            <view class="integral-top-n">
                {{ pointList.length ? pointList[0].balance : 0}}
            </view>
            <view class="integral-top-d">
                {{ nowDate }}
            </view>
        </view>
        <view class="integral-bottom">
            <view class='cell-group margin-cell-group'>
                <view class='cell-item add-title-item cell-title'>
                    <view class='cell-item-bd'>
                        <view class="cell-bd-view black-text">
                            <text class="cell-bd-text">积分记录</text>
                        </view>
                    </view>
                </view>
                <view 
                class='cell-item add-title-item'
                v-for="item in pointList"
                :key="item.id"
                >
                    <view class='cell-item-bd'>
                        <view class="cell-bd-view black-text">
                            <text class="cell-bd-text">{{ item.remarks }}</text>
                        </view>
                        <view class="cell-bd-view">
                            <text class="cell-bd-text">{{ item.ctime }}</text>
                        </view>
                    </view>
                    <view class="cell-item-ft">
                        <text class="cell-ft-p">{{ item.num > 0 ? '+' + item.num : item.num }}</text>
                    </view>
                </view>
                <uni-load-more
                :status="loadStatus"
                :show-icon="true"
                ></uni-load-more>
            </view>
        </view>
    </view>
</template>

<script>
import uniLoadMore from '@/components/uni-load-more/uni-load-more.vue'    
export default {
    data () {
        return {
            page: 1,
            limit: 10,
            pointList: [], // 积分记录
            loadStatus: 'more'
        }
    },
    components: { uniLoadMore },
    onLoad () {
        this.userPointLog()
    },
    computed: {
        nowDate () {
            return this.$common.timeToDate(Math.round(new Date().getTime()/1000))
        }
    },
    methods: {
        userPointLog () {
            let _this = this
            let data = {
                page: _this.page,
                limit: _this.limit
            }
            
            _this.loadStatus = 'loading'
            
            _this.$api.pointLog(data, function (res) {
                if (res.status) {
                    _this.pointList = [..._this.pointList, ...res.data]
                    // 判断数据是否加载完毕
                    if (res.count > _this.pointList.length) {
                        _this.page ++
                        _this.loadStatus = 'more'
                    } else {
                        _this.loadStatus = 'noMore'
                    }
                } else {
                    // 接口請求出錯
                    _this.$common.errorToShow(res.msg)
                    _this.loadStatus = 'more'
                }
            })
        }
    },
    // 页面滚动到底部触发事件
    onReachBottom () {
        let _this = this
        if (_this.loadStatus === 'more') {
            _this.userPointLog()
        }
    }
}    
</script>

<style>
.content{
    background-color: #fff;
    padding-top: 20upx;
}
.integral-top{
    background-color: #F7F7F7;
    text-align: center;
    width: 698upx;
    margin: 0 auto 10upx;
    border-radius: 12upx;
    padding: 40upx 0;
    border: 2upx solid #E9E9E9;
    box-shadow: 0 0 10upx #ddd;
}
.integral-top-t{
    font-size: 28upx;
    color: #666;
    margin-bottom: 16upx;
}
.integral-top-n{
    font-size: 58upx;
    color: #333;
    margin-bottom: 16upx;
}
.integral-top-d{
    font-size: 22upx;
    color: #999;
}
.cell-title .cell-bd-text{
    font-size: 34upx !important;
}
.cell-bd-view{
    font-size: 22upx;
    color: #999;
}
.cell-item .black-text .cell-bd-text{
    font-size: 28upx;
    color: #333;
}
</style>
invite
index.vue
<template>
    <view class="content">
        <image class="invite-bg" src="/static/image/invite-bg.png" mode=""></image>
        <view class="invite-c">
            <view class="invite-w">
                <view class='invite-w-t'>我的专属邀请码</view>
                <text class='invite-w-num'>{{code}}</text>
                <view class='invite-w-detail'>快去分享您的邀请码吧,让更多的好友加入到【{{appTitle}}】,您也可以获得丰厚的奖励!</view>
                <view class='invite-w-bot'>
                    <view bindtap='commission' @click="toMoney">
                        <image class='invite-w-bot-ic' src='/static/image/ic-earnings.png'></image>
                        <text class='invite-w-bot-red'>¥{{money}}元</text>
                        <text class='invite-w-bot-gray'>邀请收益</text>
                    </view>
                    <view bindtap='recommendlist' @click="toList">
                        <image class='invite-w-bot-ic' src='/static/image/ic-number.png'></image>
                        <text class='invite-w-bot-red'>{{number}}人</text>
                        <text class='invite-w-bot-gray'>邀请人数</text>
                    </view>
                </view>
            </view>
            <view class="invite-w" v-if="!is_superior">
                <text class='invite-w-t-blue'>谁推荐你的?</text>
                <input class='invite-w-input' placeholder='请输入推荐人邀请码' v-model="inviteKey"></input>
                <view class='invite-w-btn' @click="setMyInvite">提交</view>
            </view>
            <view class='invite-btn'>
                <!-- #ifdef MP-WEIXIN -->
                <button class='share btn' open-type="share">
                    <image src='/static/image/ic-wechat.png'></image>
                </button>
                <!-- #endif -->
                <!-- #ifdef H5 -->
                <button class='share btn' @click="copyUrl()">
                    <image src='/static/image/ic-link.png'></image>
                </button>
                <!-- #endif -->
                <button class='share btn' @click="createPoster()">
                    <image src='/static/image/ic-img.png'></image>
                </button>
            </view>
        </view>
    </view>
</template>

<script>
    import {
        apiBaseUrl
    } from '@/config/config.js'
    export default {
        data() {
            return {
                myShareCode: '', //分享Code
                code: '',
                money: 0,
                number: 0,
                is_superior: false,
                inviteKey: '',
                imageUrl: '/static/image/share_image.png'
            }
        },
        computed: {
            appTitle() {
                return this.$store.state.config.shop_name;
            }
        },
        onShow() {
            this.getInviteData();
            this.getMyShareCode();
        },
        methods: {
            //获取数据
            getInviteData() {
                this.$api.myInvite(res => {
                    this.code = res.data.code;
                    this.money = res.data.money;
                    this.number = res.data.number;
                    this.is_superior = res.data.is_superior;
                });
            },
            //去佣金明细
            toMoney() {
                this.$common.navigateTo('../balance/details?status=5');
            },
            //去邀请列表
            toList() {
                this.$common.navigateTo('./list');
            },
            //填写设置要求
            setMyInvite() {
                let data = {
                    code: this.inviteKey
                }
                this.$api.setMyInvite(data, res => {
                    if (res.status) {
                        this.$common.successToShow('邀请码填写成功');
                        this.is_superior = true;
                    } else {
                        this.$common.errorToShow(res.msg);
                    }
                });
            },
            // 生成邀请海报
            createPoster() {
                let data = {
                    type: 2
                }

                let page_path = '/pages/share/jump';
                // #ifdef H5
                data.source = 1;
                data.return_url = apiBaseUrl + 'wap/' + page_path;
                // #endif

                // #ifdef MP-WEIXIN
                data.source = 2;
                data.return_url = page_path;
                // #endif

                // #ifdef MP-ALIPAY
                data.source = 3;
                data.return_url = page_path;
                // #endif

                let userToken = this.$db.get('userToken')

                if (userToken) {
                    data.token = userToken
                }
                this.$api.createPoster(data, res => {
                    if (res.status) {
                        this.$common.navigateTo('/pages/share?poster=' + res.data)
                    } else {
                        this.$common.errorToShow(res.msg)
                    }
                })
            },
            //复制URL链接
            copyUrl() {
                let data = {
                    type: 2
                }
                let page_path = '/pages/share/jump';
                data.return_url = apiBaseUrl + 'wap' + page_path;
                let userToken = this.$db.get('userToken')
                if (userToken) {
                    data.token = userToken
                }
                let _this = this;
                _this.$api.createShareUrl(data, res => {
                    if(res.status) {
                        //todo::要复制的内容是 res.data
                        uni.setClipboardData({
                            data:res.data,
                            success:function(data){
                                _this.$common.successToShow('复制成功');
                            }, 
                            fail:function(err){
                                _this.$common.errorToShow('复制分享URL失败');
                            }
                        })
                        
                    } else {
                        _this.$common.errorToShow('复制分享URL失败');
                    }
                });
            },
            getMyShareCode() {
                let userToken = this.$db.get("userToken");
                if (userToken && userToken != '') {
                    // 获取我的分享码
                    this.$api.shareCode({}, res => {
                        if (res.status) {
                            this.myShareCode = res.data ? res.data : '';
                        }
                    });
                }
            }
        },
        //分享
        onShareAppMessage() {
            let myInviteCode = this.myShareCode ? this.myShareCode : '';
            let ins = this.$common.shareParameterDecode('type=3&invite=' + myInviteCode);
            let path = '/pages/share/jump?scene=' + ins;
            return {
                title: this.$store.state.config.share_title,
                // #ifdef MP-ALIPAY
                desc: this.$store.state.config.share_desc,
                // #endif
                imageUrl: this.$store.state.config.share_image,
                path: path
            }
        }
    }
</script>

<style>
    .invite {
        width: 100%;
        height: 100%;
        background: linear-gradient(to right, #4c21d2, #4864f8);
    }

    .invite-bg {
        position: absolute;
        width: 750upx;
        height: 683upx;
        z-index: 66;
    }

    .invite-c {
        position: relative;
        z-index: 67;
        width: 750upx;
        padding: 0 30upx;
        top: 488upx;
        background: linear-gradient(to right, #4c21d2, #4864f8);
    }

    .invite-w {
        background-color: #fff;
        width: 690upx;
        text-align: center;
        padding: 40upx 100upx;
        box-sizing: border-box;
        border-radius: 30upx;
        margin-bottom: 70upx;
        position: relative;
        top: -148upx;
    }

    .invite-w-t {
        width: 70%;
        margin: 0 auto;
        color: #fff;
        border-radius: 50upx;
        font-size: 30upx;
        box-sizing: border-box;
        padding: 10upx;
        display: block;
        background: linear-gradient(to right, #5f2ef6, #b945dd);
    }

    .invite-w-num {
        color: #5f2ef6;
        display: block;
        font-size: 36upx;
        margin-top: 20upx;
    }

    .invite-w-detail {
        color: #666;
        font-size: 24upx;
        line-height: 1.5;
        margin-top: 20upx;
    }

    .invite-w-bot {
        margin: 20upx 0 50upx;
    }

    .invite-w-bot>view {
        width: 49%;
        display: inline-block;
    }

    .invite-w-bot-ic {
        width: 48upx;
        height: 48upx;
    }

    .invite-w-bot-red {
        font-size: 24upx;
        color: #ca0400;
        display: block;
    }

    .invite-w-bot-gray {
        font-size: 24upx;
        color: #acacac;
        display: block;
    }

    .invite-w-t-blue {
        color: #348dfc;
        font-size: 30upx;
        margin-bottom: 50upx;
        display: block;
    }

    .invite-w-input {
        font-size: 30upx;
        border-bottom: 1px solid #dadada;
        margin-bottom: 50upx;
        color: #999;
    }

    .invite-w-btn {
        background: linear-gradient(to right, #4a6af9, #28c4ff);
        color: #fff;
        width: 50%;
        margin: 0 auto;
        border-radius: 50upx;
        font-size: 30upx;
        padding: 10upx 0;
    }

    .invite-btn {
        position: relative;
        top: -150upx;
        text-align: center;
        width: 690upx;
    }

    .share {
        background-color: none;
        position: relative;
        width: 98upx;
        height: 98upx;
        display: inline-block;
        border-radius: 50%;
        padding: 0;
        margin: 0 40rpx 40rpx;
    }

    .invite-btn image {
        width: 98upx;
        height: 98upx;
    }
</style>
list.vue
<template>
    <view class="content">
        <view class="collection">
            <view class="container_of_slide" v-for="(item, index) in lists" :key="index">
                <view class="slide_list">
                    <view class="now-message-info" hover-class="uni-list-cell-hover">
                        <view class="icon-circle">
                            <image class='goods-img' :src="item.avatar" mode="aspectFill"></image>
                        </view>
                        <view class="list-right">
                            <view class="list-title">昵称: {{ item.nickname }}</view>
                            <view class="list-detail color-6">手机号: {{ item.mobile }}</view>
                            <view class="list-detail">推荐时间: {{ item.ctime }}</view>
                        </view>
                    </view>
                    <view style="clear:both"></view>
                </view>
            </view>
            <uni-load-more :status="loadStatus"></uni-load-more>
        </view>
    </view>
</template>

<script>
import uniLoadMore from '@/components/uni-load-more/uni-load-more.vue'
export default {
    components: {
        uniLoadMore
    },
    data() {
        return {
            lists: [],
            page: 1, //当前页
            limit: 10, //每页显示几条
            loadStatus: 'more'
        };
    },
    onLoad () {
        this.getShareCode();
        this.getDataList();
    },
    onReachBottom () {
        if (this.loadStatus === 'more') {
            this.getDataList()
        }
    },
    methods: {
        getDataList() {
            this.loadStatus = 'loading'
            let data = {
                page: this.page,
                limit: this.limit
            }
            this.$api.recommendList(data, res => {
                if (res.status) {
                    for (let i = 0; i < res.data.length; i++) {
                        if (res.data[i].avatar == null) {
                            res.data[i].avatar = this.$store.state.config.shop_default_image;
                        }
                        if (res.data[i].nickname == null) {
                            res.data[i].nickname = '暂无昵称'
                        }
                    }
                    let lists = this.lists.concat(res.data);
                    this.lists = lists;
                    if (res.total > this.page) {
                        this.page++
                        this.loadStatus = 'more'
                    } else {
                        this.loadStatus = 'noMore'
                    }
                }else{
                    this.$common.errorToShow(res.msg)
                }
            });
        },
        //获取邀请码
        getShareCode(){
            let userToken = this.$db.get("userToken");
            if (userToken && userToken != '') {
                // 获取我的分享码
                this.$api.shareCode({}, res => {
                    if (res.status) {
                        this.myShareCode = res.data;
                    }
                });
            }
        }
    },
};
</script>

<style scoped>
.collection .goods-img{
    width: 150upx;
    height: 150upx;    
}
.container_of_slide {
    width: 100%;
    overflow: hidden;
}
.slide_list {
    transition: all 100ms;
    transition-timing-function: ease-out;
    min-width: 100%;
}
.now-message-info {
    box-sizing:border-box;
    display: flex;
    align-items: center;
    font-size: 16px;
    clear:both;
    padding: 20upx 26upx;
    margin-bottom: 2upx;
    background: #FFFFFF;
    width: 100%;
}
.now-message-info,
.group-btn {
    float: left;
}
.group-btn {
    display: flex;
    flex-direction: row;
    height: 190upx;
    min-width: 100upx;
    align-items: center;

}
.group-btn .btn-div {
    height: 190upx;
    color: #fff;
    text-align: center;
    padding: 0 50upx;
    font-size: 34upx;
    line-height: 190upx;
}
.group-btn .top {
    background-color: #FF7159;
}
.group-btn .removeM {
    background-color: #999;
}
.icon-circle{
    width:150upx;
    height: 150upx;
    float: left;
}
.list-right{
    float: left;
    margin-left: 25upx;
    height: 150upx;
}
.list-right-1{
    float: right;
    color: #A9A9A9;
}
.list-title{
    width: 490upx;
    line-height:1.5;
    overflow:hidden;
    color:#333;
    font-size: 26upx;
    min-height: 60upx;
}
.list-detail{
    width: 460upx;
    font-size: 24upx;
    color: #a9a9a9;
    display:-webkit-box;
    -webkit-box-orient:vertical;
    -webkit-line-clamp:1;
    overflow:hidden;
    height: 50upx;
}
</style>
order
evaluate.vue
<template>
    <view class="content">
        <view class="content-top">
            <view class='img-list'>
                <view class='img-list-item'
                v-for="item in info.items"
                :key="item.id"
                >
                    <view class="img-list-item-gray">
                        <image class='img-list-item-l small-img' :src='item.image_url' mode='aspectFill'></image>
                        <view class='img-list-item-r small-right'
                        @click="goodsDetail(item.goods_id)"
                        >
                            <view class='little-right-t'>
                                <view class='goods-name list-goods-name'>{{ item.name }}</view>
                            </view>
                        </view>
                    </view>
                    
                    <view class="evaluate-num">
                        <view class="evaluate-num-t">商品评分</view>
                        <view class="evaluate-num-b">
                            <uni-rate 
                            size="18" 
                            :id="item.id"
                            :value="score[item.id]"
                            @change="changeScore"
                            ></uni-rate>
                        </view>
                    </view>
                    
                    <view class="evaluate-content">
                        <view class="evaluate-c-t">
                            <textarea v-model="textarea[item.id]" placeholder="宝贝满足你的期待吗? 说说你的使用心得" />
                        </view>
                        <view class="evaluate-c-b">
                            <view class="goods-img-item"
                            v-if="images[item.id].length"
                            v-for="(img, key) in images[item.id]"
                            :key="key"
                            >
                                <image class="del" src="/static/image/del.png" mode="" @click="removeImg(item.id, key)"></image>
                                <image class="" :src="img.url" mode="" @click="clickImg(img.url)"></image>
                            </view>
                            <view class="upload-img" v-show="isupload[item.id]">
                                <image class="icon" src="/static/image/camera.png" mode="" @click="uploadImg(item.id)"></image>
                                <view class="">上传照片</view>
                            </view>
                        </view>
                    </view>
                    
                </view>
            </view>
            
        </view>

        <view class="button-bottom">
            <button class="btn btn-square btn-b" hover-class="btn-hover" @click="toEvaluate" :disabled='submitStatus' :loading='submitStatus'>提交评论</button>
        </view>
        
    </view>
</template>

<script>
import uniRate from "@/components/uni-rate/uni-rate.vue"
import { goods } from '@/config/mixins.js'
export default {
    mixins: [goods],
    components: {uniRate},
    data () {
        return {
            orderId: 0,
            info: {}, // 订单详情
            images: [],
            score: [], // 商品评价
            textarea: [], // 商品评价信息
            isupload: [], // 启/禁用 图片上传按钮
            rate: 5,
            submitStatus: false
        }
    },
    onLoad (options) {
        this.orderId = options.order_id
        this.orderId 
        ? this.orderInfo() 
        : this.$common.errorToShow('获取失败', () => {
            uni.navigateBack({
                delta: 1
            })
        })
    },
    computed: {
        // 获取vuex中状态
        maxUploadImg () {
            return this.$store.state.config.image_max
        }
    },
    methods: {
        // 获取订单详情
        orderInfo () {
            let data = {
                order_id: this.orderId
            }
            this.$api.orderDetail(data, res => {
                if (res.status && res.data.text_status === 4) {
                    const _info = res.data
                    
                    let images = []
                    let textarea = []
                    let upload = []
                    let score = []
                    
                    _info.items.forEach (item => {
                        images[item.id] = []
                        textarea[item.id] = ''
                        upload[item.id] = true
                        score[item.id] = 5
                    })
                    
                    this.info = _info
                    
                    this.images = images
                    this.textarea = textarea
                    this.score = score
                    this.isupload = upload
                } else {
                    this.$common.errorToShow('订单不存在或状态不可评价!')
                }
            })
        },
        // 上传图片
        uploadImg (key) {
            this.$api.uploadFiles(res => {
                if (res.status) {
                    let img = {
                        url: res.data.url,
                        id: res.data.image_id
                    }
                    this.images[key].push(img)
                    
                    this.$common.successToShow(res.msg)
                } else {
                    this.$common.errorToShow(res.msg)
                }
            })
        },
        // 删除图片
        removeImg (id, key) {
            this.images[id].splice(key, 1)
        },
        // 图片点击放大
        clickImg (img) {
            // 预览图片
            uni.previewImage({
                urls: img.split()
            });
        },
        // 改变评分
        changeScore (e) {
            this.score[e.id] = e.value
        },
        // 提交评价
        toEvaluate () {
            this.submitStatus = true;
            let items = {}
            
            this.images.forEach((item, key) => {
                items[key] = {
                    images: item,
                    score: this.score[key],
                    textarea: this.textarea[key]
                }
            })

            let data = {
                order_id: this.orderId,
                items: items
            }

            this.$api.orderEvaluate(data, res => {
                if (res.status) {
                    this.$common.successToShow(res.msg, ress => {
                        // 更改订单列表页的订单状态
                        let pages = getCurrentPages(); // 当前页
                        let beforePage = pages[pages.length - 2]; // 上个页面
                        
                        if (beforePage !== undefined && beforePage.route === 'pages/member/order/orderlist') {
                            // #ifdef MP-WEIXIN
                            beforePage.$vm.isReload = true
                            // #endif
                            
                            // #ifdef H5
                            beforePage.isReload = true
                            // #endif
                            
                            // #ifdef MP-ALIPAY
                            beforePage.rootVM.isReload = true
                            // #endif
                        }
                        this.submitStatus = false;
                        uni.navigateBack({
                            delta: 1
                        })
                    })
                } else {
                    this.$common.errorToShow(res.msg)
                    this.submitStatus = false;
                }
            })
        }
    },
    watch: {
        images: {
            handler () {
                this.images.forEach((item, key) => {
                    this.isupload[key] = item.length > this.maxUploadImg ? false : true
                })
            },
            deep: true
        }
    }
}
</script>

<style>
.img-list-item{
    padding: 30upx 20upx;
}
.img-list-item-gray{
    background-color: #F7F7F7;
    overflow: hidden;
    padding: 18upx 20upx;
}
.small-right{
    width: 520upx;
}
.evaluate-content{
    background-color: #fff;
    padding: 20upx 0upx;
}
.evaluate-c-t{
    width: 100%;
    height: 240upx;
}
.evaluate-c-t textarea{
    width: 100%;
    height: 100%;
    font-size: 26upx;
    padding: 10upx;
}
.evaluate-c-b{
    overflow: hidden;
}
.upload-img{
    width: 146upx;
    height: 146upx;
    margin: 14upx;
    text-align: center;
    color: #999999;
    font-size: 22upx;
    border: 2upx solid #E1E1E1;
    /* #ifdef MP-ALIPAY */
    border-top: 8upx solid #E1E1E1;
    /* #endif */
    border-radius: 4upx;
    display: inline-block;
    float: left;
    padding: 24upx 0;
}
.goods-img-item{
    width: 174upx;
    height: 174upx;
    padding: 14upx;
    float: left;
    position: relative;
}
.goods-img-item:nth-child(4n){
    margin-right: 0;
}
.goods-img-item image{
    width: 100%;
    height: 100%;
}
.del{
    width: 30upx !important;
    height: 30upx !important;
    position: absolute;
    right: 0;
    top: 0;
    z-index: 999;
}
.evaluate-num{
    padding: 20upx 26upx;
    background-color: #fff;
    margin-top: 20upx;
}
.evaluate-num-t{
    color: #333;
    font-size: 28upx;
    margin-bottom: 20upx;
}
.button-bottom .btn{
    width: 100%;
}
</style>
express_delivery.vue
<template>
    <view class="content">
        <view class="ed-head color-6"
        v-if="add.length"
        >
            收货地址:{{ add }}
        </view>
        <view class="ed-body">
            <view v-if="isExpress">
                <view class="ed-body-item"
                v-for="(item, index) in express.data"
                :key="index"
                >
                    <view class="edbi-left">
                        <view class="edbi-date color-6">
                            {{ item.date }}
                        </view>
                        <view class="edbi-time color-9">
                            {{ item.utime }}
                        </view>
                    </view>
                    <view class="edbi-circle last-circle" v-if="item.end">
                        <view>收</view>
                    </view>
                    <view class="edbi-circle"v-else>
                        <view></view>
                    </view>
                    <view class="edbi-right">
                        <view class="edbi-title color-3">
                            {{ item.title }}
                        </view>
                        <view class="edbi-content color-9">
                            {{ item.content }}
                        </view>
                    </view>
                </view>
            </view>
            <view class="ed-none" v-else>
                暂无物流信息
            </view>
        </view>
    </view>
</template>

<script>
export default {
    data () {
        return {
            add: '', // 收货地址
            express: {}, // 快递物流信息
//             no:"70433978952894",
//             data:[
//                 {"time":"2019-03-25 11:19:15","context":"郑州市【郑州二七区七部】,已送达 已签收"},
//                 {"time":"2019-03-25 08:42:02","context":"郑州市【郑州二七区七部】,【左颜璞\/15837175131】正在派件"},
//                 {"time":"2019-03-25 07:43:35","context":"到郑州市【郑州二七区七部】"},
//                 {"time":"2019-03-24 16:59:41","context":"郑州市【郑州转运中心】,正发往【郑州二七区七部】"},
//                 {"time":"2019-03-24 16:25:55","context":"到郑州市【郑州转运中心】"},
//                 {"time":"2019-03-23 22:43:27","context":"漯河市【漯河转运中心】,正发往【郑州转运中心】"},
//                 {"time":"2019-03-23 22:41:13","context":"到漯河市【漯河转运中心】"},
//                 {"time":"2019-03-23 01:35:51","context":"杭州市【杭州转运中心】,正发往【漯河转运中心】"},
//                 {"time":"2019-03-23 01:34:46","context":"到杭州市【杭州转运中心】"},
//                 {"time":"2019-03-22 22:27:29","context":"杭州市【杭州萧山区十部】,正发往【杭州转运中心】"},
//                 {"time":"2019-03-22 20:10:58","context":"到杭州市【杭州萧山区十部集货点】"},
//                 {"time":"2019-03-22 18:49:57","context":"杭州市【杭州萧山区十部】,【吴永海\/15885770819】已揽收"},
//             ],
//             state:"3",
//             state_name:"已签收"
        }
    },
    onLoad (options) {
        let params = options.params
        let arr = decodeURIComponent(params).split('&')
        let code, no
        for (var i = 0; i < arr.length; i++) {
            let key = arr[i].split("=")[0]
            if (key == 'code') {
                code = arr[i].split("=")[1]
            }
            if (key == 'no') {
                no = arr[i].split("=")[1]
            }
            if (key == 'add') {
                this.add = arr[i].split('=')[1]
            }
        }
        
        if (!code || !no) {
            this.$common.errorToShow('缺少物流查询参数', () => {
                uni.navigateBack({
                    delta: 1
                })
            })
        } 
        
        this.expressInfo(code, no)
    },
    computed: {
        isExpress () {
            return Object.keys(this.express).length ? true : false
        }
    },
    methods: {
        expressInfo (code, no) {
            let data = {
                code: code,
                no: no
            }
            this.$api.logistics(data, res => {
                if (res.status) {
                    let _info = res.data.info
                    _info.data.forEach((item, key) => {
                        // 日期时间重新格式化处理
                        let times = item.time.split(' ')
                        this.$set(item, 'date', times[0].substring(5, times[0].length))
                        this.$set(item, 'utime', times[1].substring(0, 5))
                        
                        // 快递信息格式化处理
                        let contents = item.context.split(',')
                        this.$set(item, 'title', contents[0])
                        this.$set(item, 'content', contents[1] ? contents[1] : '')
                        
                        // 签收状态logo处理
                        this.$set(item, 'end', _info.state === 3 && key === 0 ? true : false)
                    })
                    
                    this.express = _info
                } else {
                    this.$common.errorToShow(res.msg)
                }
            })
        }
    }
}    
</script>

<style>
.ed-head{
    font-size: 30upx;
    padding: 20upx 26upx;
}
.ed-body{
    margin: 0 26upx;
    background-color: #fff;
    box-shadow: 0 0 20upx #ccc;
    padding: 26upx;
}
.ed-body-item{
    /* display: flex; */
    overflow: hidden;
    position: relative;    
}
.edbi-left{
    display: inline-block;
    width: 96upx;
    float: left;
    padding: 4upx 0;
}
.edbi-date{
    font-size: 26upx;
}
.edbi-time{
    font-size: 24upx;
}
.edbi-circle{
    display: inline-block;
    width: 18upx;
    height: 18upx;
    border: 2upx solid #ccc;
    border-radius: 50%;
    position: absolute;
    left: 88upx;
    top: 12upx;
    background-color: #fff;
    z-index: 99;
}
.last-circle{
    width: 40upx;
    height: 40upx;
    font-size: 24upx;
    left: 78upx;
    text-align: center;
    line-height: 40upx;
    color: #fff;
    background-color: #FF7159;
    border: none;
    top: 0;
}
.edbi-right{
    display: inline-block;
    width: 550upx;
    float: right;
    border-left: 2upx solid #e8e8e8;
    padding-left: 30upx;
    position: relative;
    padding-bottom: 30upx;
}
.edbi-title{
    font-size: 30upx;
}
.edbi-content{
    font-size: 26upx;
    margin-top: 4upx;
}
.ed-none{
    text-align: center;
    font-size: 26upx;
    color: #666;
    padding: 100upx;
}
</style>
invitation_group.vue
<template>
    <view class="content">
        <view class="ig-top">
            <view class="ig-top-t">
                <view class="">
                    剩余时间:<uni-countdown :day="lasttime.day" :hour="lasttime.hour" :minute="lasttime.minute" :second="lasttime.second"></uni-countdown>
                </view>
            </view>
            <view class="ig-top-m">
                <view class="user-head-img-c" v-for="(item, index) in teamInfo.list" :key="index">
                    <view class="user-head-img-tip" v-if="item.id == item.team_id">拼主</view>
                    <image class="user-head-img cell-hd-icon have-none" :src='item.user_avatar' mode=""></image>
                </view>
                <view class="user-head-img-c uhihn" v-if="teamInfo.team_nums" v-for="n in teamInfo.team_nums" :key="n"><text>?</text></view>
            </view>
            <view class="ig-top-b">
                <view class="igtb-top">
                    还差<text class="red-price">{{ teamInfo.team_nums }}</text>人,赶快邀请好友来拼单吧
                </view>
                <view class="igtb-mid">
                    <button class="btn" @click="goShare()">邀请好友拼单</button>
                </view>
                <view class="igtb-bot">
                    分享好友越多,成团越快
                </view>
            </view>
        </view>
        <!-- 弹出层 -->
        <lvv-popup position="bottom" ref="share">

            <!-- #ifdef H5 -->
            <shareByH5 :shareType='3' :goodsId="goodsInfo.goods_id" :teamId="teamInfo.team_id" :groupId="teamInfo.rule_id"
             :shareImg="goodsInfo.image_url" :shareTitle="goodsInfo.name" :shareContent="goodsInfo.brief" :shareHref="shareHref"
             @close="closeShare()"></shareByH5>
            <!-- #endif -->

            <!-- #ifdef MP-WEIXIN -->
            <shareByWx :shareType='3' :goodsId="goodsInfo.goods_id" :teamId="teamInfo.team_id" :groupId="teamInfo.rule_id"
             :shareImg="goodsInfo.image_url" :shareTitle="goodsInfo.name" :shareContent="goodsInfo.brief" :shareHref="shareHref"
             @close="closeShare()"></shareByWx>
            <!-- #endif -->

            <!-- #ifdef MP-ALIPAY -->
            <shareByAli :shareType='3' :goodsId="goodsInfo.goods_id" :teamId="teamInfo.team_id" :groupId="teamInfo.rule_id"
             :shareImg="goodsInfo.image_url" :shareTitle="goodsInfo.name" :shareContent="goodsInfo.brief" :shareHref="shareHref"
             @close="closeShare()"></shareByAli>
            <!-- #endif -->

            <!-- #ifdef APP-PLUS -->
            <shareByApp :shareType='3' :goodsId="goodsInfo.goods_id" :teamId="teamInfo.team_id" :groupId="teamInfo.rule_id"
             :shareImg="goodsInfo.image_url" :shareTitle="goodsInfo.name" :shareContent="goodsInfo.brief" :shareHref="shareHref"
             @close="closeShare()"></shareByApp>
            <!-- #endif -->

        </lvv-popup>
        <view class="cell-group margin-cell-group">
            <view class='cell-item'>
                <view class='cell-item-hd'>
                    <view class='cell-hd-title'>商品名称</view>
                </view>
                <view class='cell-item-ft'>
                    <text class="cell-ft-text">{{ goodsInfo.name }}</text>
                </view>
            </view>
            <view class='cell-item'>
                <view class='cell-item-hd'>
                    <view class='cell-hd-title'>拼单时间</view>
                </view>
                <view class='cell-item-ft'>
                    <text class="cell-ft-text">{{ orderInfo.ctime }}</text>
                </view>
            </view>
            <view class='cell-item'>
                <view class='cell-item-hd'>
                    <view class='cell-hd-title'>拼单须知</view>
                </view>
                <view class='cell-item-ft group-notice'>
                    <text class="cell-ft-text">* 好友拼单 </text>
                    <text class="cell-ft-text">* 人满发货 </text>
                    <text class="cell-ft-text">* 人不满退款 </text>
                </view>
            </view>
        </view>
    </view>
</template>

<script>
    import lvvPopup from '@/components/lvv-popup/lvv-popup.vue';
    import uniCountdown from "@/components/uni-countdown/uni-countdown.vue"
    import {
        get
    } from '@/config/db.js';
    import {
        apiBaseUrl
    } from '@/config/config.js';
    import share from '@/components/share/share.vue';
    // #ifdef H5
    import shareByH5 from '@/components/share/shareByh5.vue'
    // #endif
    // #ifdef MP-WEIXIN
    import shareByWx from '@/components/share/shareByWx.vue'
    // #endif
    // #ifdef MP-ALIPAY
    import shareByAli from '@/components/share/shareByAli.vue'
    // #endif
    // #ifdef APP-PLUS
    import shareByApp from '@/components/share/shareByApp.vue'
    // #endif

    import htmlParser from '@/common/html-parser'
    export default {
        components: {
            lvvPopup,
            uniCountdown,
            share,
            // #ifdef H5
            shareByH5,
            // #endif

            // #ifdef MP-WEIXIN
            shareByWx,
            // #endif

            // #ifdef MP-ALIPAY
            shareByAli,
            // #endif

            // #ifdef APP-PLUS
            shareByApp,
            // #endif
            // spec
        },
        data() {
            return {
                myShareCode: '', //分享Code
                shareType: 3,
                providerList: [], // 分享通道 包含生成海报
                swiper: {
                    indicatorDots: true,
                    autoplay: true,
                    interval: 3000,
                    duration: 800,
                }, // 轮播图属性设置
                goodsInfo: [],
                teamInfo: [],
                favLogo: [
                    '/static/image/ic-me-collect.png',
                    '/static/image/ic-me-collect2.png'
                ],
                horizontal: 'right', //右下角弹出按钮
                vertical: 'bottom',
                direction: 'vertical',
                pattern: {
                    color: '#7A7E83',
                    backgroundColor: '#fff',
                    selectedColor: '#007AFF',
                    buttonColor: "#FF7159"
                },

                query: '', // query参数登录跳转回来使用
                indicatorDots: false,
                autoplay: false,
                interval: 2000,
                duration: 500,
                lasttime: {
                    day: 0,
                    hour: 0,
                    minute: 0,
                    second: 0
                }, //购买倒计时
                userToken: 0,
                time: 0,
                order_id:'',//订单号
                orderInfo:{}
            }
        },
        onLoad(options) {
            if(options.order_id){
                this.order_id = options.order_id;
            }else{
                this.$common.errorToShow('参数错误');
            }
            let teamInfo,orderInfo,goodsInfo
    
            let pages = getCurrentPages()
            let pre = pages[pages.length - 2]
            if(typeof pre!='undefined'){
                // #ifdef H5
                teamInfo = pre.teamInfo
                orderInfo = pre.orderInfo
                // #endif
                
                // #ifdef MP-WEIXIN || APP-PLUS || APP-PLUS-NVUE
                teamInfo = pre.$vm.teamInfo
                orderInfo = pre.$vm.orderInfo
                // #endif
                
                // #ifdef MP-ALIPAY
                teamInfo = pre.rootVM.teamInfo;
                orderInfo = pre.rootVM.orderInfo
                // #endif
            }
            if(teamInfo && orderInfo){
                this.teamInfo = teamInfo;
                this.orderInfo = orderInfo;
                this.goodsInfo = orderInfo.items[0];
                
            }else{
                this.orderDetail();
                this.getTeam();
            }
            let timestamp = Date.parse(new Date())/1000;
            this.lasttime = this.$common.timeToDateObj(options.close_time-timestamp);
            this.getMyShareCode();
        },
        computed: {
            shareHref() {
                let pages = getCurrentPages()
                let page = pages[pages.length - 1]
                // #ifdef H5 || MP-WEIXIN || APP-PLUS || APP-PLUS-NVUE
                return apiBaseUrl + 'wap/' + page.route + '?scene=' + this.query;
                // #endif

                // #ifdef MP-ALIPAY
                return apiBaseUrl + 'wap/' + page.__proto__.route + '?scene=' + this.query;
                // #endif
            }

        },
        onReachBottom() {
            if (this.current === 2 && this.goodsComments.loadStatus === 'more') {
                this.getGoodsComments();
            }
        },
        methods: {
            //拼团信息
            getTeam(){
                this.$api.getOrderPintuanTeamInfo({order_id:this.order_id},res=>{
                    if (res.status) {
                        
                        this.teamInfo = {
                            list:res.data.teams,
                            current_count:res.data.teams.length,
                            people_number:res.data.people_number,
                            team_nums:res.data.team_nums,//剩余
                            close_time:res.data.close_time,//关闭时间
                            id:res.data.id,//拼团id
                            team_id:res.data.team_id,//拼团团队id
                            rule_id:res.data.rule_id,
                        };
                        console.log(this.lasttime);
                    }else{
                        this.$common.errorToShow(res.msg)
                    }
                    
                });
            },
            //获取订单详情
            orderDetail () {
                let _this = this
                let data = {
                    order_id: _this.order_id
                }
                _this.$api.orderDetail(data, function(res) {
                    if (res.status) {
                        let data = res.data
                        // 支付时间转换
                        if (data.ctime !== null) {
                            data.ctime = _this.$common.timeToDate(data.ctime)
                        }
                        
                        _this.orderInfo = data
                        _this.goodsInfo = data.items[0];
                    
                    } else {
                        _this.$common.errorToShow(res.msg)
                    }
                })
            },
            // 关闭弹出层
            close() {
                this.$emit('close')
            },
            // 点击操作
            clickHandler(e) {
                if (e.cate === 'poster') {
                    this.createPoster()
                } else {
                    // 去分享
                    this.share(e)
                }
            },
            // 显示modal弹出框
            toshow(type, team_id = 0) {
                if (type == 1) {
                    this.lvvpopref_type = 1;
                }
                if (team_id !== 0) {
                    this.team_id = team_id;
                }
                this.$refs.lvvpopref.show();
            },
            // 关闭modal弹出框
            toclose() {
                this.$refs.lvvpopref.close();
            },

            // 跳转到h5分享页面
            goShare() {
                this.$refs.share.show();
            },
            closeShare() {
                this.$refs.share.close();
            },
            getMyShareCode() {
                let userToken = this.$db.get("userToken");
                if (userToken && userToken != '') {
                    // 获取我的分享码
                    this.$api.shareCode({}, res => {
                        if (res.status) {
                            this.myShareCode = res.data ? res.data : '';
                        }
                    });
                }
            }
        },
        //分享
        onShareAppMessage() {
             let myInviteCode = this.myShareCode ? this.myShareCode : '';
             let teamId = this.teamInfo.list[0].team_id;
             let ins = this.$common.shareParameterDecode('type=5&invite=' + myInviteCode+'&id='+ this.goodsInfo.goods_id +'&team_id=' + teamId );
            
             let path = '/pages/share/jump?scene=' + ins;
              console.log(path);
             return {
                 title: this.goodsInfo.name,
                 // #ifdef MP-ALIPAY
                 desc: this.goodsInfo.brief,
                 // #endif
                 imageUrl: this.goodsInfo.image_url,
                 path: path
             }
         }
    }
</script>

<style>
    .ig-top {
        text-align: center;
        background-color: #fff;
        padding: 20upx 26upx;
    }

    .ig-top-t,
    .ig-top-m {
        margin-bottom: 20upx;
    }

    .ig-top-t>view {
        display: inline-block;
        padding: 0 10upx;
        color: #999;
    }

    .user-head-img-c {
        position: relative;
        width: 80upx;
        height: 80upx;
        border-radius: 50%;
        margin-right: 20upx;
        box-sizing: border-box;
        display: inline-block;
        /* float: left; */
        border: 1px solid #f3f3f3;
    }

    .user-head-img-tip {
        position: absolute;
        top: -6upx;
        left: -10upx;
        display: inline-block;
        background-color: #FF7159;
        color: #fff;
        font-size: 22upx;
        z-index: 98;
        padding: 0 10upx;
        border-radius: 10upx;
        transform: scale(.8);
    }

    .user-head-img-c .user-head-img {
        width: 100%;
        height: 100%;
        border-radius: 50%;
    }

    .user-head-img-c:first-child {
        border: 1px solid #FF7159;
    }

    .uhihn {
        width: 80upx;
        height: 80upx;
        border-radius: 50%;
        display: inline-block;
        border: 2upx dashed #e1e1e1;
        text-align: center;
        color: #d1d1d1;
        font-size: 40upx;
        box-sizing: border-box;
        position: relative;
    }

    .uhihn>text {
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
    }

    .igtb-top {
        font-size: 32upx;
        color: #333;
        margin-bottom: 16upx;
    }

    .igtb-mid {
        margin-bottom: 16upx;
    }

    .igtb-mid .btn {
        width: 100%;
        background-color: #FF7159;
        color: #fff;
    }

    .igtb-bot {
        font-size: 24upx;
        color: #666;
    }

    .cell-ft-text {
        max-width: 520upx;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .group-notice .cell-ft-text {
        color: #999;
        margin-left: 20upx;
        font-size: 26upx;
    }
</style>
orderdetail.vue
<template>
    <view class="content">
        <view class="content-top">
            <view class='cell-group margin-cell-group'>
                <view class='cell-item add-title-item'>
                    <view class='cell-item-bd'>
                        <view class="cell-bd-view black-text" v-if="orderInfo.order_type != 2">
                            <text class="cell-bd-text">{{ orderInfo.status_name }}</text>
                        </view>
                        <view class="cell-bd-view">
                            <text class="cell-bd-text">订单号:{{ orderInfo.order_id }}</text>
                            <button class='btn btn-g btn-small' hover-class="btn-hover" @click="copyData(orderInfo.order_id)">复制</button>
                        </view>
                        <view class="cell-bd-view">
                            <text class="cell-bd-text">下单时间:{{ orderInfo.ctime }}</text>
                        </view>
                    </view>
                </view>
            </view>

            <view class='cell-group margin-cell-group'>
                <view class='cell-item add-title-item' v-if="isDelivery" @click="logistics">
                    <view class='cell-item-bd'>
                        <view class="cell-bd-view black-text">
                            <text class="cell-bd-text">{{ orderInfo.express_delivery.context }}</text>
                        </view>
                        <view class="cell-bd-view">
                            <text class="cell-bd-text">{{ orderInfo.express_delivery.time }}</text>
                        </view>
                    </view>
                    <view class="cell-item-ft">
                        <image class='cell-ft-next icon' src='/static/image/right.png'></image>
                    </view>
                </view>
                <view class='cell-item add-title-item' v-if="!orderInfo.store">
                    <view class='cell-item-bd'>
                        <view class="cell-bd-view black-text">
                            <text class="cell-bd-text">收件人:{{ orderInfo.ship_name }}</text>
                        </view>
                        <view class="cell-bd-view">
                            <text class="cell-bd-text">{{ orderInfo.ship_area_name + orderInfo.ship_address }}</text>
                        </view>
                    </view>
                </view>
            </view>
            
            <view class='cell-group margin-cell-group' v-if="orderInfo.store">
                <view class='cell-item add-title-item'>
                    <view class="cell-item-hd">
                        <image class='cell-hd-icon' src='/static/image/homepage.png'></image>
                    </view>
                    <view class='cell-item-bd'>
                        <view class="cell-bd-view black-text">
                            <text class="cell-bd-text">{{orderInfo.store.store_name}}</text>
                        </view>
                        <view class="cell-bd-view">
                            <text class="cell-bd-text">门店电话:{{orderInfo.store.mobile}}</text>
                        </view>
                        <view class="cell-bd-view">
                            <text class="cell-bd-text">门店地址:{{orderInfo.store.all_address}}</text>
                        </view>
                        <view class="cell-bd-view">
                            <text class="cell-bd-text">提货人信息:{{orderInfo.ship_name}}</text><text class="cell-bd-text" style="margin-left: 10rpx;">{{orderInfo.ship_mobile}}</text>
                        </view>
                        <view class="cell-bd-view" v-if="lading.status">
                            <text class="cell-bd-text">提货码:<text class="red-price">{{lading.code}}</text></text>
                        </view>
                    </view>
                </view>
            </view>
            

            <!-- 团购分享拼单 -->
            <view class="cell-group margin-cell-group" v-if="(orderInfo.text_status == 1 || orderInfo.text_status == 2 ) && orderInfo.order_type==2">
                <view class='cell-item right-img'>
                    <view class='cell-item-hd'>
                        <view v-if="teamInfo.status==1" class='cell-hd-title'>待拼团,还差{{ teamInfo.team_nums }}人</view>
                        <view v-else-if="teamInfo.status==2" class='cell-hd-title'>拼团成功,待发货</view>
                        <view v-else-if="teamInfo.status==3" class='cell-hd-title'>拼团失败</view>
                    </view>
                </view>
                <view class="group-swiper">
                    <view class='cell-item' v-if="teamInfo.current_count">
                        <view class='cell-item-hd'>
                            <view class="user-head-img-c" v-for="(item, index) in teamInfo.list" :key="index">
                                <view class="user-head-img-tip" v-if="item.id == item.team_id">拼主</view>
                                <image class="user-head-img cell-hd-icon have-none" :src='item.user_avatar' mode=""></image>
                            </view>
                            <view v-if="teamInfo.team_nums > 3">
                                <view class="uhihn" v-for="n in 3" :key="n">?</view>
                                <view class="uhihn">···</view>
                            </view>
                            <view v-else>
                                <view class="uhihn" v-for="n in teamInfo.team_nums" :key="n">?</view>
                            </view>
                        </view>
                        <view class="cell-item-ft" v-if="teamInfo.status==1">
                            <button class="btn" @click="goInvition()">邀请拼单</button>
                        </view>
                    </view>
                </view>
            </view>

            <view class='img-list'>
                <view class='img-list-item' v-for="item in orderInfo.items" :key="item.id">
                    <image class='img-list-item-l little-img have-none' :src='item.image_url' mode='aspectFill'></image>
                    <view class='img-list-item-r little-right'>
                        <view class='little-right-t'>
                            <view class='goods-name list-goods-name' @click="goodsDetail(item.goods_id)" v-if="orderInfo.order_type == 1">{{ item.name }}</view>
                            <view class='goods-name list-goods-name' @click="pintuanDetail(item.goods_id)" v-else-if="orderInfo.order_type == 2">{{ item.name }}</view>
                            <view class='goods-price'>¥{{ item.price }}</view>
                        </view>
                        <view class="romotion-tip">
                            <view class="romotion-tip-item" v-for="(promotion, key) in formatPormotions(item.promotion_list)" :key="key">
                                {{ promotion }}
                            </view>
                        </view>
                        <view class='goods-item-c'>
                            <view class='goods-buy'>
                                <view class='goods-salesvolume' v-if="item.addon !== null">{{ item.addon }}</view>
                                <view class='goods-num'>× {{ item.nums }}</view>
                            </view>
                        </view>
                    </view>
                </view>
            </view>

            <view class='cell-group margin-cell-group' v-if="orderInfo.tax_type != 1">
                <view class='cell-item add-title-item'>
                    <view class='cell-item-bd'>
                        <view class="cell-bd-view black-text">
                            <text class="cell-bd-text">发票信息</text>
                        </view>
                        <view class="cell-bd-view" v-if="orderInfo.tax_type != 1">
                            <text class="cell-bd-text">发票抬头:{{orderInfo.tax_title}}</text>
                        </view>
                        <view class="cell-bd-view" v-if="orderInfo.tax_type == 3">
                            <text class="cell-bd-text">发票税号:{{orderInfo.tax_code}}</text>
                        </view>
                    </view>
                </view>
            </view>

            <view class='cell-group margin-cell-group order-offer' v-if="orderInfo.promotion_list && orderInfo.promotion_list.length > 0">
                <view class='cell-item add-title-item'>
                    <view class='cell-item-hd'>
                        <view class="cell-bd-view promotion-title">
                            <text class="cell-bd-text promotion-title-text">订单优惠</text>
                        </view>
                    </view>
                    <view class='cell-item-bd'>
                        <view v-for="(item, key) in orderInfo.promotion_list" :key="key" v-show="item.type == 2" class="order-promotion">{{item.name}}</view>
                    </view>
                </view>
            </view>

            <view class='cell-group margin-cell-group order-price'>
                <view class='cell-item add-title-item'>
                    <view class='cell-item-bd'>
                        <view class="cell-bd-view">
                            <text class="cell-bd-text">商品总价</text>
                        </view>
                    </view>
                    <view class='cell-item-ft'>
                        <text class="cell-ft-p">¥{{ orderInfo.goods_amount }}</text>
                    </view>
                </view>
                <view class='cell-item add-title-item'>
                    <view class='cell-item-bd'>
                        <view class="cell-bd-view">
                            <text class="cell-bd-text">运费</text>
                        </view>
                    </view>
                    <view class='cell-item-ft'>
                        <text class="cell-ft-p">¥{{ orderInfo.cost_freight }}</text>
                    </view>
                </view>
                <view class='cell-item add-title-item' v-if="orderInfo.goods_pmt > 0">
                    <view class='cell-item-bd'>
                        <view class="cell-bd-view">
                            <text class="cell-bd-text">商品优惠</text>
                        </view>
                    </view>
                    <view class='cell-item-ft'>
                        <text class="cell-ft-p">-¥{{ orderInfo.goods_pmt }}</text>
                    </view>
                </view>
                <view class='cell-item add-title-item' v-if="orderInfo.point_money > 0">
                    <view class='cell-item-bd'>
                        <view class="cell-bd-view">
                            <text class="cell-bd-text">积分优惠</text>
                        </view>
                    </view>
                    <view class='cell-item-ft'>
                        <text class="cell-ft-p">-¥{{ orderInfo.point_money }}</text>
                    </view>
                </view>
                <view class='cell-item add-title-item' v-if="orderInfo.order_pmt > 0">
                    <view class='cell-item-bd'>
                        <view class="cell-bd-view">
                            <text class="cell-bd-text">订单优惠</text>
                        </view>
                    </view>
                    <view class='cell-item-ft'>
                        <text class="cell-ft-p">-¥{{ orderInfo.order_pmt }}</text>
                    </view>
                </view>
                <view class='cell-item add-title-item' v-if="orderInfo.coupon_pmt > 0">
                    <view class='cell-item-bd'>
                        <view class="cell-bd-view">
                            <text class="cell-bd-text">其他优惠</text>
                        </view>
                    </view>
                    <view class='cell-item-ft'>
                        <text class="cell-ft-p">-¥{{ orderInfo.coupon_pmt }}</text>
                    </view>
                </view>
                <view class='cell-item add-title-item'>
                    <view class='cell-item-bd'>
                        <view class="cell-bd-view">
                            <text class="cell-bd-text">订单总价</text>
                        </view>
                    </view>
                    <view class='cell-item-ft'>
                        <text class="cell-ft-p red-price">¥{{ orderInfo.order_amount }}</text>
                    </view>
                </view>
                <view class='cell-item add-title-item' v-if="orderInfo.pay_status > 1">
                    <view class='cell-item-bd'>
                        <view class="cell-bd-view">
                            <text class="cell-bd-text">支付方式</text>
                        </view>
                    </view>
                    <view class='cell-item-ft'>
                        <text class="cell-ft-p">{{ orderInfo.payment_name }}</text>
                    </view>
                </view>
                <view class='cell-item add-title-item' v-if="orderInfo.pay_status > 1">
                    <view class='cell-item-bd'>
                        <view class="cell-bd-view">
                            <text class="cell-bd-text">支付时间</text>
                        </view>
                    </view>
                    <view class='cell-item-ft'>
                        <text class="cell-ft-p">{{ orderInfo.payment_time }}</text>
                    </view>
                </view>
            </view>
        </view>
        <view class="button-bottom" v-if="orderInfo.text_status === 1">
            <button class='btn btn-circle btn-g' hover-class="btn-hover" @click="cancelOrder(orderInfo.order_id)">取消订单</button>
            <button class='btn btn-circle btn-w' hover-class="btn-hover" @click="toPay(orderInfo.order_id)">立即支付</button>
        </view>
        <view class="button-bottom" v-if="orderInfo.text_status === 2">
            <button class='btn btn-circle btn-w' hover-class="btn-hover" @click="customerService(orderInfo.order_id)" v-if="orderInfo.bill_aftersales_id == false">申请售后</button>
            <button class='btn btn-circle btn-w' hover-class="btn-hover" @click="showCustomerService(orderInfo.bill_aftersales_id)"
             v-else-if="orderInfo.bill_aftersales_id && orderInfo.bill_aftersales_id != false">查看售后</button>
        </view>
        <view class="button-bottom" v-if="orderInfo.text_status === 3">
            <button class='btn btn-circle btn-g' hover-class="btn-hover" @click="customerService(orderInfo.order_id)" v-if="orderInfo.bill_aftersales_id == false">申请售后</button>
            <button class='btn btn-circle btn-g' hover-class="btn-hover" @click="showCustomerService(orderInfo.bill_aftersales_id)"
             v-else-if="orderInfo.bill_aftersales_id && orderInfo.bill_aftersales_id != false">查看售后</button>
            <button class='btn btn-circle btn-g' hover-class="btn-hover" @click="logistics">查看物流</button>
            <button class='btn btn-circle btn-w' hover-class="btn-hover" @click="tackDeliery(orderInfo.order_id)">确认收货</button>
        </view>
        <view class="button-bottom" v-if="orderInfo.text_status === 4">
            <button class='btn btn-circle btn-g' hover-class="btn-hover" @click="customerService(orderInfo.order_id)" v-if="orderInfo.bill_aftersales_id == false">申请售后</button>
            <button class='btn btn-circle btn-g' hover-class="btn-hover" @click="showCustomerService(orderInfo.bill_aftersales_id)"
             v-else-if="orderInfo.bill_aftersales_id && orderInfo.bill_aftersales_id != false">查看售后</button>
            <button class='btn btn-circle btn-w' hover-class="btn-hover" @click="toEvaluate(orderInfo.order_id)">立即评价</button>
        </view>
        <view class="button-bottom" v-if="orderInfo.text_status === 5">
            <button class='btn btn-circle btn-w' hover-class="btn-hover" @click="customerService(orderInfo.order_id)" v-if="orderInfo.bill_aftersales_id == false">申请售后</button>
            <button class='btn btn-circle btn-w' hover-class="btn-hover" @click="showCustomerService(orderInfo.bill_aftersales_id)"
             v-else-if="orderInfo.bill_aftersales_id && orderInfo.bill_aftersales_id != false">查看售后</button>
        </view>
    </view>
</template>

<script>
    import {
        orders,
        goods,
        tools
    } from '@/config/mixins.js'
    export default {
        mixins: [orders, goods,tools],
        data() {
            return {
                orderId: 0,
                orderInfo: {}, // 订单详情
                teamInfo: [], //拼团团信息
                lading: {
                    status: false,
                    code: ''
                }, //提货信息
            }
        },
        onLoad(options) {
            this.orderId = options.order_id
            if (this.orderId) {
                //this.orderDetail()
            } else {
                this.$common.errorToShow('', () => {
                    uni.navigateBack({
                        delta: 1,
                    })
                })
            }
        },
        onShow() {
            this.orderDetail();
        },
        computed: {
            // 判断是否发货
            isDelivery() {
                if (this.orderInfo.text_status > 2 &&
                    this.orderInfo.express_delivery != null &&
                    this.orderInfo.hasOwnProperty('express_delivery') &&
                    Object.keys(this.orderInfo.express_delivery).length
                ) {
                    return true
                } else {
                    return false
                }
            }
        },
        methods: {
            // 获取订单详情
            orderDetail() {
                let _this = this
                let data = {
                    order_id: _this.orderId
                }
                _this.$api.orderDetail(data, function(res) {
                    if (res.status) {
                        let data = res.data
                        // 订单状态文字转化
                        switch (data.text_status) {
                            case 1:
                                _this.$set(data, 'status_name', '待付款')
                                break
                            case 2:
                                _this.$set(data, 'status_name', '待发货')
                                break
                            case 3:
                                _this.$set(data, 'status_name', '待收货')
                                break
                            case 4:
                                _this.$set(data, 'status_name', '待评价')
                                break
                            case 6:
                                _this.$set(data, 'status_name', '交易完成')
                                break
                            case 7:
                                _this.$set(data, 'status_name', '交易取消')
                                break
                            case 8:
                                _this.$set(data, 'status_name', '待分享')
                                break
                            default:
                                _this.$set(data, 'status_name', '交易成功')
                                break
                        }
                        // 订单时间转换
                        data.ctime = _this.$common.timeToDate(data.ctime)

                        // 支付时间转换
                        if (data.payment_time !== null) {
                            data.payment_time = _this.$common.timeToDate(data.payment_time)
                        }

                        _this.orderInfo = data
                        if (data.order_type == 2 && (data.text_status == 2 || data.text_status == 1)) {
                            _this.getTeam(data.order_id);
                        }
                        
                        if(data.ladingItem[0]){
                            _this.lading = {
                                status: true,
                                code: data.ladingItem[0].id
                            }
                        }
                    } else {
                        _this.$common.errorToShow(res.msg)
                    }
                })
            },
            // 取消订单
            cancelOrder(orderId) {
                this.$common.modelShow('提示', '确认要取消订单吗?', () => {
                    let data = {
                        order_ids: orderId
                    }

                    this.$api.cancelOrder(data, res => {
                        if (res.status) {
                            this.$common.successToShow(res.msg, () => {
                                this.orderDetail()
                            })
                        } else {
                            this.$common.errorToShow(res.msg)
                        }
                    })
                })
            },
            // 确认收货
            tackDeliery(orderId) {
                this.$common.modelShow('提示', '确认收货操作吗?', () => {
                    let data = {
                        order_id: orderId
                    }
                    this.$api.confirmOrder(data, res => {
                        if (res.status) {
                            this.$common.successToShow('确认收货成功', () => {
                                // 更改订单列表页的订单状态
                                let pages = getCurrentPages(); // 当前页
                                let beforePage = pages[pages.length - 2]; // 上个页面

                                if (beforePage !== undefined && beforePage.route === 'pages/member/order/orderlist') {
                                    // #ifdef MP-WEIXIN
                                    beforePage.$vm.isReload = true
                                    // #endif

                                    // #ifdef H5
                                    beforePage.isReload = true
                                    // #endif

                                    // #ifdef MP-ALIPAY
                                    beforePage.rootVM.isReload = true
                                    // #endif
                                }

                                this.orderDetail()
                            })
                        } else {
                            this.$common.errorToShow(res.msg)
                        }
                    })
                })
            },
            formatPormotions(promotion) {
                let obj = {}
                obj = JSON.parse(promotion)
                return obj
            },
            //申请售后
            customerService(id) {
                this.$common.navigateTo('../after_sale/index?order_id=' + id);
            },
            //快递信息
            logistics() {
                let address1 = this.orderInfo.ship_area_name ? this.orderInfo.ship_area_name : ''
                let address2 = this.orderInfo.ship_address ? this.orderInfo.ship_address : ''
                let address = address1 + address2
                this.showExpress(this.orderInfo.delivery[0].logi_code, this.orderInfo.delivery[0].logi_no, address)
            },
            //查看售后
            showCustomerService(id) {
                this.$common.navigateTo('../after_sale/detail?aftersales_id=' + id);
            },
            goInvition() {
                uni.navigateTo({
                    url: './invitation_group?order_id=' + this.orderInfo.order_id + '&close_time=' + this.teamInfo.close_time
                })
            },
            //拼团信息
            getTeam(id) {
                this.$api.getOrderPintuanTeamInfo({
                    order_id: id
                }, res => {
                    if (res.status) {
                        this.teamInfo = {
                            list: res.data.teams,
                            current_count: res.data.teams.length,
                            people_number: res.data.people_number,
                            team_nums: res.data.team_nums, //剩余
                            close_time: res.data.close_time, //关闭时间
                            id: res.data.id, //拼团id
                            team_id: res.data.team_id, //拼团团队id
                            rule_id: res.data.rule_id,
                            status: res.data.status
                        };
                    } else {
                        this.$common.errorToShow(res.msg)
                    }

                });
            }
        }
    }
</script>

<style>
    .cell-group {
        margin-bottom: 20upx;
    }

    .cell-bd-view {
        margin-bottom: 8upx;
    }

    .cell-bd-view .cell-bd-text {
        font-size: 22upx;
        color: #999;
    }

    .black-text .cell-bd-text {
        font-size: 28upx;
        color: #333;
    }

    .button-bottom {
        padding: 15upx 26upx;
        text-align: right;
        display: block;
    }

    .button-bottom .btn {
        margin-left: 20upx;
    }

    .order-price {
        padding: 10upx 0 20upx;
    }

    .order-price .cell-item {
        border-bottom: none;
        padding-bottom: 0;
        padding-top: 0;
        min-height: 40upx;
    }

    .order-price .cell-bd-view {
        margin-bottom: 0;
    }

    .order-offer .cell-item-hd {
        vertical-align: top;
        padding-top: 8upx;
    }

    .order-offer .cell-item-bd {
        padding: 0;
    }

    .order-promotion {
        font-size: 24upx;
        color: #fff;
        background-color: #ff7159;
        margin: 0 0 4upx 6upx;
        padding: 2upx 10upx;
        display: inline-block;
        float: right;
    }

    .tax_name {}

    .tax_code {}

    .user-head-img-c {
        position: relative;
        width: 80upx;
        height: 80upx;
        border-radius: 50%;
        margin-right: 20upx;
        box-sizing: border-box;
        display: inline-block;
        float: left;
        border: 1px solid #f3f3f3;
    }

    .user-head-img-tip {
        position: absolute;
        top: -6upx;
        left: -10upx;
        display: inline-block;
        background-color: #FF7159;
        color: #fff;
        font-size: 22upx;
        z-index: 99;
        padding: 0 10upx;
        border-radius: 10upx;
        transform: scale(.8);
    }

    .group-swiper .cell-item .user-head-img {
        width: 100%;
        height: 100%;
        border-radius: 50%;
    }

    .group-swiper .cell-item .user-head-img-c:first-child {
        border: 1px solid #FF7159;
    }

    .uhihn {
        width: 80upx;
        height: 80upx;
        border-radius: 50%;
        margin-right: 20upx;
        display: inline-block;
        border: 2upx dashed #e1e1e1;
        text-align: center;
        line-height: 80upx;
        color: #d1d1d1;
        font-size: 40upx;
        box-sizing: border-box;
    }

    .group-swiper .cell-item .cell-item-ft .btn {
        font-size: 26upx;
        color: #fff;
        background-color: #FF7159;
        /* padding: 0; */
        text-align: center;
    }
    
    .add-title-item .cell-item-hd {
        min-width: 20px;
        color: #666;
        font-size: 14px;
    }
</style>
orderlist.vue
<template>
    <view class="content">
        <uni-segmented-control 
        :current="tab" 
        :values="items" 
        @clickItem="onClickItem" 
        style-type="text" 
        active-color="#333"
        ></uni-segmented-control>
        <view class="order-list">
            
            <view class="goods-detail" 
            v-if="list.length">
                <view class="order-item"
                v-for="(item, index) in list"
                :key="index"
                >
                    <view class='cell-group'>
                        <view class='cell-item'
                        @click="orderDetail(item.order_id)"
                        >
                            <view class='cell-item-hd'>
                                <view class='cell-hd-title'>订单编号:{{ item.order_id }}</view>
                            </view>
                            <view class='cell-item-ft'>
                                <text class='cell-ft-text'>{{ item.order_status_name }}</text>
                            </view>
                        </view>
                    </view>
                    <view class='img-list'>
                        <view class='img-list-item'
                        v-for="(goods, key) in item.items"
                        :key="key"
                        >
                            <image class='img-list-item-l little-img have-none' :src='goods.image_url' mode='aspectFill'></image>
                            <view class='img-list-item-r little-right'>
                                <view class='little-right-t'>
                                    <view class='goods-name list-goods-name'
                                    @click="orderDetail(item.order_id)"
                                    >{{ goods.name }}</view>
                                    <view class='goods-price'>¥{{ goods.price }}</view>
                                </view>
                                <view class="romotion-tip">
                                    <view class="romotion-tip-item"
                                    v-for="(promotion, k) in formatPromotions(goods.promotion_list)"
                                    :key="k"
                                    >
                                        {{ promotion }}
                                    </view>
                                </view>
                                <view class='goods-item-c'>
                                    <view class='goods-buy'>
                                        <view class='goods-salesvolume'
                                        v-if="goods.addon !== null"
                                        >{{ goods.addon }}</view>
                                        <view class='goods-num'>× {{ goods.nums }}</view>
                                    </view>
                                </view>
                            </view>
                        </view>
                    </view>
                    <view class='cell-group'>
                        <view class='cell-item'>
                            <view class='cell-item-ft goods-num'>
                                <text class='cell-ft-text'>合计<text class="red-price">¥ {{ item.order_amount }}</text></text>
                                <text class='cell-ft-text'>共 {{ item.items.length }} 件</text>
                            </view>
                        </view>
                    </view>
                    <view class='order-list-button'>
                        
                        <button class='btn btn-circle btn-g' hover-class="btn-hover" @click="orderDetail(item.order_id)">查看详情</button>
                        
                        <button class='btn btn-circle btn-w'
                        hover-class="btn-hover"
                        v-if="item.status === 1 && item.pay_status === 1" 
                        @click="toPay(item.order_id)"
                        >立即支付</button>
                        
                        <button class='btn btn-circle btn-w' 
                        hover-class="btn-hover"
                        v-if="item.status === 1 && item.pay_status === 2 && item.ship_status === 3 && item.confirm === 1" 
                        @click="tackDelivery(index)"
                        >确认收货</button>
                        
                        <button class='btn btn-circle btn-w' 
                        hover-class="btn-hover"
                        v-if="item.status === 1 && item.pay_status === 2 && item.ship_status === 3 && item.confirm === 2 && item.is_comment === 1" 
                        @click="toEvaluate(item.order_id)"
                        >立即评价</button>
                        
                    </view>
                </view>
                <uni-load-more
                :status="loadStatus"
                ></uni-load-more>
            </view>
            <view class="order-none" v-else>
                <image class="order-none-img" src="/static/image/order.png" mode=""></image>
            </view>
<!--             <view class="goods-detail" v-show="current === 1">
                <view class="order-none">
                    <image class="order-none-img" src="/static/image/order.png" mode=""></image>
                </view>
            </view>
            <view class="goods-detail" v-show="current === 2">
                3
            </view>
            <view class="goods-detail" v-show="current === 3">
                4
            </view>
            <view class="goods-detail" v-show="current === 4">
                5
            </view> -->
        </view>
    </view>
</template>

<script>
import uniSegmentedControl from "@/components/uni-segmented-control/uni-segmented-control.vue"
import uniLoadMore from '@/components/uni-load-more/uni-load-more.vue'
import { orders, goods } from '@/config/mixins.js'
export default {
    mixins: [orders, goods],
    components: {
        uniSegmentedControl, uniLoadMore
    },
    data() {
        return {
            items: [
                '全部',
                '待付款',
                '待发货',
                '待收货',
                '待评价',
            ],
            list: [],
            page: 1,
            limit: 5, // 每页订单显示数量
            loadStatus: 'more',
            status: [0, 1, 2, 3, 4]    ,// 订单状态 0全部 1待付款 2待发货 3待收货 4待评价
            isReload: false, // 页面是否刷新?重载
        }
    },
    onLoad () {
        this.initData()
    },
    onShow () {
        if (this.isReload) {
            this.initData()
        }
    },
    computed: {
        // 获取订单列表tab
        tab () {
            return this.$store.state.orderTab
        }
    },
    methods: {
        // 初始化数据并获取订单列表
        initData (page = 1) {
            this.page = page
            this.list = []
            this.orderList()
        },
        // 订单状态切换
        onClickItem(index) {
            if (this.tab !== index) {
                this.$store.commit('orderTab', index)
                this.initData()
            }
        },
        // 获取订单列表
        orderList () {
            let data = {
                page: this.page,
                limit: this.limit,
                status: this.status[this.tab]
            }
            
            this.loadStatus = 'loading'

            this.$api.orderList(data, res => {
                if (res.status) {
                    let _list = res.data.list
                    if (res.data.status == this.status[this.tab]) {
                        this.list = [...this.list, ...this.formatOrderStatus(_list)]
                        // 判断所有数据是否请求完毕
                        if (res.data.count > this.list.length) {
                            this.page ++
                            this.loadStatus = 'more'
                        } else {
                            this.loadStatus = 'noMore'
                        }
                    }
                } else {
                    this.$common.errorToShow(res.msg)
                }
            })
            
            if (this.isReload) {
                this.isReload = false
            }
        },
        // 确认收货
        tackDelivery (index) {
            this.$common.modelShow('提示', '确认执行收货操作吗?', () => {
                let data = {
                    order_id: this.list[index].order_id
                }
                this.$api.confirmOrder(data, res => {
                    if (res.status) {
                        this.$common.successToShow('确认收货成功', () => {
                            if (this.tab !== 0) {
                                this.list.splice(index, 1)
                            } else {
                                this.initData()
                            }
                        })
                    } else {
                        this.$common.errorToShow(res.msg)
                    }
                })
            })
        },
        // 订单状态统一在这处理
        formatOrderStatus (orderList) {
            orderList.forEach (item => {
                switch (item.status) {
                    case 1:
                        if (item.pay_status === 1) {
                            this.$set(item, 'order_status_name', '待付款')
                        }
                        if (item.pay_status === 2 && item.ship_status === 1){
                            this.$set(item, 'order_status_name', '待发货')
                        }
                        if (item.pay_status === 2 && item.ship_status === 3 && item.confirm === 1) {
                            this.$set(item, 'order_status_name', '待收货')
                        }
                        if (item.pay_status === 2 && item.ship_status === 3 && item.confirm === 2 && item.is_comment === 1) {
                            this.$set(item, 'order_status_name', '待评价')
                        }
                        if (item.pay_status === 2 && item.ship_status === 3 && item.confirm === 2 && item.is_comment === 2) {
                            this.$set(item, 'order_status_name', '已评价')
                        }
                        if (item.pay_status === 4) {
                            this.$set(item, 'order_status_name', '售后单')
                        }
                        break
                    case 2:
                        this.$set(item, 'order_status_name', '已完成')
                        break
                    case 3:
                        this.$set(item, 'order_status_name', '已取消')
                        break
                }
            })
            return orderList
        },
        formatPromotions (promotions) {
            let obj = {}
            obj = JSON.parse(promotions)
            return obj
        }
    },
    // 页面下拉到底部触发
    onReachBottom () {
        if (this.loadStatus == 'more') {
            this.orderList()
        }
    }
}
</script>

<style>
.segmented-control {
    /*  #ifdef  H5  */
    top: 44px;
    /*  #endif  */
    /*  #ifndef  H5  */
    top: 0;
    /*  #endif  */
    width: 100%;
    background-color: #fff;
    position: fixed;
    
    z-index: 999;
}
.segmented-control-item{
    line-height: 70upx;
}
.order-list{
    margin-top: 64upx;
}
.order-item{
    margin-bottom: 20upx;
}
.img-list{
    margin-top: 2upx;
}
.cell-group,.img-list-item {
    background-color: #fff;
}
.cell-hd-title{
    font-size: 22upx;
    color: #666;
}
.cell-ft-text{
    top: 0;
    font-size: 22upx;
    color: #333;
}
.order-list-button{
    width: 100%;
    background-color: #fff;
    text-align: right;
    padding: 10upx 26upx;
    /* border-top: 2upx solid #f8f8f8; */
}
.order-list-button .btn{
    height: 50upx;
    line-height: 50upx;
}
.order-list-button .btn-w{
    margin-left: 20upx;
}
.goods-num .cell-ft-text{
    color: #999;
    line-height: 32upx;
}
.goods-num .cell-ft-text:first-child{
    margin-left: 10upx;
}
.order-none{
    text-align: center;
    padding: 200upx 0;
}
.order-none-img{
    width: 274upx;
    height: 274upx;
}
.goods-name{
    min-height: 74upx;
}
</style>
setting
index.vue
<template>
    <view class="content">
        <view class="content-top">
            <view class='cell-group right-img'>
                <view class='cell-item'>
                    <view class='cell-item-hd' @click="navigateToHandle('./user_info/index')">
                        <!-- <image class='cell-hd-icon' src=''></image> -->
                        <view class='cell-hd-title'>个人信息</view>
                    </view>
                    <view class='cell-item-ft'>
                        <image class='cell-ft-next icon' src='/static/image/right.png'></image>
                    </view>
                </view>
                <view class='cell-item'>
                    <view class='cell-item-hd' @click="navigateToHandle('./user_info/password')">
                        <view class='cell-hd-title'>修改密码</view>
                    </view>
                    <view class='cell-item-ft'>
                        <image class='cell-ft-next icon' src='../../../static/image/right.png'></image>
                    </view>
                </view>
                <view class='cell-item'>
                    <view class='cell-item-hd' @click="clearCache">
                        <!-- <image class='cell-hd-icon' src=''></image> -->
                        <view class='cell-hd-title'>清除缓存</view>
                    </view>
                    <view class='cell-item-ft'>
                        <image class='cell-ft-next icon' src='/static/image/right.png'></image>
                    </view>
                </view>
                <view class='cell-item'>
                    <view class='cell-item-hd' @click="aboutUs">
                        <!-- <image class='cell-hd-icon' src='/static/image/me-ic-about.png'></image> -->
                        <view class='cell-hd-title'>关于我们</view>
                    </view>
                    <view class='cell-item-ft'>
                        <image class='cell-ft-next icon' src='/static/image/right.png'></image>
                    </view>
                </view>
                <view class='cell-item'>
                    <view class='cell-item-hd' @click="logOff">
                        <!-- <image class='cell-hd-icon' src='/static/image/me-ic-about.png'></image> -->
                        <view class='cell-hd-title'>退出</view>
                    </view>
                    <view class='cell-item-ft'>
                        <image class='cell-ft-next icon' src='/static/image/right.png'></image>
                    </view>
                </view>
            </view>
        </view>
        <!--         <view class="button-bottom">
            <button class="btn btn-b">退出登录</button>
        </view> -->
    </view>
</template>

<script>
export default {
  methods: {
    navigateToHandle(pageUrl) {
      this.$common.navigateTo(pageUrl)
    },
    // 清除缓存
    clearCache() {
      // 重新获取统一配置信息
      this.$api.shopConfig(res => {
        this.$store.commit('config', res)
      })
      // 删除地区缓存信息
      this.$db.del('areaList')
      setTimeout(() => {
        this.$common.successToShow('清除成功')
      }, 500)
    },
    // 关于我们
    aboutUs() {
      let articleId = this.$store.state.config.about_article_id;
      this.$common.navigateTo('/pages/article/index?id_type=1&id=' + articleId);
    },
    // 退出登录
    logOff() {
      this.$common.modelShow('退出', '确认退出登录吗?', () => {
        this.$db.del('userToken')
        uni.reLaunch({
          url: '/pages/index/index'
        })
      })
    }
  }
}
</script>

<style>
</style>
user_info
index.vue
<template>
    <view class="content">
        <view class="content-top">
            <view class='cell-group'>
                <view class='cell-item user-head'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>头像</view>
                    </view>
                    <view class='cell-item-ft'>
                        <image class='cell-ft-next user-head-img have-none' mode="aspectFill" :src="avatar" @click="uploadAvatar"></image>
                    </view>
                </view>
                <view class='cell-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>昵称</view>
                    </view>
                    <view class='cell-item-bd'>
                        <input class='cell-bd-input' placeholder='' v-model="nickname" ></input>
                    </view>
                </view>
                <view class='cell-item right-img'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>性别</view>
                    </view>
                    <view class='cell-item-bd'>
                        <view class="uni-list">
                            <view class="uni-list-cell-db">
                                <picker @change="bindPickerChange" :value="index" :range="objectSex">
                                    <view class="uni-input">{{objectSex[sex]}}</view>
                                </picker>
                            </view>
                        </view>
                    </view>
                    <view class='cell-item-ft'>
                        <image class='cell-ft-next icon' src='/static/image/ic-pull-down.png'></image>
                    </view>
                </view>
                <view class='cell-item right-img'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>生日</view>
                    </view>
                    <view class='cell-item-bd'>
                        <view class="uni-list">
                            <view class="uni-list-cell-db">
                                <picker mode="date" :value="date" :start="startDate" :end="endDate" @change="bindDateChange">
                                    <view class="uni-input">{{birthday}}</view>
                                </picker>
                            </view>
                        </view>
                    </view>
                    <view class='cell-item-ft'>
                        <image class='cell-ft-next icon' src='/static/image/ic-pull-down.png'></image>
                    </view>
                </view>
            </view>
        </view>
        <view class="button-bottom">
            <button class="btn btn-square btn-b"  hover-class="btn-hover2" @click="submitHandler()" :disabled='submitStatus' :loading='submitStatus'>保存</button>
        </view>
    </view>
</template>

<script>
export default {
    data() {
        return {
            title: 'picker',
            avatar: '',
            objectSex: ['男', '女', '未知'],
            index: 2,
            nickname: '',
            mobile: '',
            date: '1990-01-01',
            birthday: '请选择',
            sex: 0,
            submitStatus: false
        }
    },
    computed: {
        startDate() {
            return this.getDate('start');
        },
        endDate() {
            return this.getDate('end');
        }
    },
    methods: {
        //性别
        bindPickerChange: function(e) {
            this.sex = e.target.value;
        },
        //生日
        bindDateChange: function(e) {
            this.birthday = e.target.value;
        },
        getDate(type) {
            const date = new Date();
            let year = date.getFullYear();
            let month = date.getMonth() + 1;
            let day = date.getDate();

            if (type === 'start') {
                year = year - 60;
            } else if (type === 'end') {
                year = year + 2;
            }
            month = month > 9 ? month : '0' + month;;
            day = day > 9 ? day : '0' + day;
            return `${year}-${month}-${day}`;
        },
        // 用户上传头像
        uploadAvatar () {
            this.$api.uploadFiles(res => {
                if (res.status) {
                    let avatar = res.data.url // 上传成功的图片地址
                    // 执行头像修改
                    this.$api.changeAvatar({
                        avatar: avatar
                    }, res => {
                        if (res.status) {
                            this.$common.successToShow('上传成功', () => {
                                this.avatar = res.data.avatar
                            })
                        } else {
                            this.$common.errorToShow(res.msg)
                        }
                    })
                } else {
                    this.$common.errorToShow(res.msg)
                }
            })
        },
        // 保存资料
        submitHandler() {
            this.submitStatus = true;
            let sex = this.sex +1;
            if(this.birthday == '请选择'){
                this.$common.successToShow('请选择出生日期');
                this.submitStatus = false;
                return false;
            }else{
                this.$api.editInfo({
                        sex: sex,
                        birthday: this.birthday,
                        nickname: this.nickname
                    }, res => {
                        this.$common.successToShow(res.msg, result => {
                            this.submitStatus = false;
                            uni.navigateBack({
                                delta: 1
                            });
                        });
                    }
                );
            }
        }
    },
    onLoad: function() {
        var _this = this;
        _this.$api.userInfo({}, function(res) {
            if (res.status) {
                var the_sex = res.data.sex - 1;
                if (res.data.birthday == null) {
                    res.data.birthday = '请选择';
                }
                _this.nickname = res.data.nickname;
                _this.mobile = res.data.mobile;
                _this.sex = the_sex;
                _this.index = the_sex;
                _this.birthday = res.data.birthday;
                _this.avatar = res.data.avatar;
                if(_this.birthday!='请选择'){
                    _this.date = _this.birthday;
                }
            } else {
                //报错了
                _this.$common.errorToShow(res.msg);
            }
        });
    }
}
</script>

<style>
.user-head{
    height: 100upx;
}
.user-head-img{
    height: 90upx;
    width: 90upx;
    border-radius: 50%;
}
.cell-hd-title{
    color: #333;
}
.cell-item-bd{
    color: #666;
    font-size: 26upx;
}
</style>
password.vue
<template>
    <view class="content">
        <view class="content-top">
            <view class='cell-group'>
                <view class='cell-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>旧密码</view>
                    </view>
                    <view class='cell-item-bd'>
                        <input class='cell-bd-input' placeholder='' v-model="pwd"></input>
                    </view>
                </view>
            </view>
            <view class='cell-group'>
                <view class='cell-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>新密码</view>
                    </view>
                    <view class='cell-item-bd'>
                        <input class='cell-bd-input' placeholder='' v-model="newPwd"></input>
                    </view>
                </view>
            </view>
            <view class='cell-group'>
                <view class='cell-item'>
                    <view class='cell-item-hd'>
                        <view class='cell-hd-title'>确认密码</view>
                    </view>
                    <view class='cell-item-bd'>
                        <input class='cell-bd-input' placeholder='' v-model="rePwd"></input>
                    </view>
                </view>
            </view>
        </view>
        <view class="button-bottom">
            <button class="btn btn-square btn-b" hover-class="btn-hover2" @click="submitHandler()" :disabled='submitStatus'
             :loading='submitStatus'>保存</button>
        </view>
    </view>
</template>

<script>
    export default {
        data() {
            return {
                pwd: '',
                newPwd: '',
                rePwd: '',
                sex: 0,
                submitStatus: false
            }
        },
        computed: {},
        methods: {
            // 保存资料
            submitHandler() {
                this.submitStatus = true;
                if (this.pwd === '') {
                    this.$common.errorToShow('请输入旧密码')
                    this.submitStatus = false;
                } else if (this.newPwd === '') {
                    this.$common.errorToShow('请输入新密码')
                    this.submitStatus = false;
                } else if (this.rePwd === '') {
                    this.$common.errorToShow('请输入重复密码')
                    this.submitStatus = false;
                } else {
                    this.$api.editPwd({
                        pwd: this.pwd,
                        newpwd: this.newPwd,
                        repwd: this.rePwd
                    }, res => {
                        this.submitStatus = false;
                        this.$common.successToShow(res.msg)
                        this.pwd = this.newPwd = this.rePwd = '';
                    })
                }
            }
        },
        onLoad: function() {
            var _this = this;
            _this.$api.userInfo({}, function(res) {
                if (res.status) {
                    var the_sex = res.data.sex - 1;
                    if (res.data.birthday == null) {
                        res.data.birthday = '请选择';
                    }
                    _this.nickname = res.data.nickname;
                    _this.mobile = res.data.mobile;
                    _this.sex = the_sex;
                    _this.index = the_sex;
                    _this.birthday = res.data.birthday;
                    _this.avatar = res.data.avatar;
                    if (_this.birthday != '请选择') {
                        _this.date = _this.birthday;
                    }
                } else {
                    //报错了
                    _this.$common.errorToShow(res.msg);
                }
            });
        }
    }
</script>

<style>
    .user-head {
        height: 100upx;
    }

    .user-head-img {
        height: 90upx;
        width: 90upx;
        border-radius: 50%;
    }

    .cell-hd-title {
        color: #333;
    }

    .cell-item-bd {
        color: #666;
        font-size: 26upx;
    }
</style>
take_delivery
index.vue
<template>
    <view class="content">
        <view class="content-top">
            <view class="ad" >
                <image class="ad-img" src="/static/demo-img/banner.png" mode="widthFix" ></image>
            </view>
            <view class='search'>
                <view class='search-c'>
                    <image class='icon search-icon' src='/static/image/zoom.png'></image>
                    <input class='search-input' placeholder-class='search-input-p' placeholder='请输入完整提货单号、订单号、提货手机号' v-model="key"></input>
                </view>
                <button class="btn btn-g" hover-class="btn-hover2" @click="search">查询</button>
            </view>
            <view v-if="allData.length">
                <checkbox-group @change="checkboxChange">
                    <view class="img-list">
                        
                        <view class="img-list-c" v-for="(item, index) in allData" :key="index">
                            <view class="img-list-title">
                                <view class="ilt-left">
                                    <text class="color-6">订单号:</text><text class="color-9">{{ item.order_id }}</text>
                                </view>
                                <view class="ilt-right  color-9">
                                    {{ item.status_name }}
                                </view>
                            </view>
                            <view class="img-list-bot">
                                <label class="uni-list-cell uni-list-cell-pd">
                                    <view v-if="!item.disabled" class="img-list-checkbox">
                                        <checkbox color="#FF7159" :value="item.id" :checked="item.checked" :disabled="item.disabled" v-if="item.disabled" class="checkboxNo"/>
                                        <checkbox color="#FF7159" :value="item.id" :checked="item.checked" :disabled="item.disabled" v-else/>
                                    </view>
                                </label>
                                <view class="img-list-right">
                                    <view class="img-list-content" v-for="(i, key) in item.goods" :key="key">
                                        <view class="img-list-item">
                                            <image class="img-list-item-l" :src="i.image_url" mode='aspectFill'></image>
                                            <view class="img-list-item-r">
                                                <view class="goods-name list-goods-name">{{i.name}}</view>
                                                <view class="goods-item-c">
                                                    <view class="goods-buy">
                                                        <view class="goods-salesvolume">规格:{{i.addon}}</view>
                                                        <view class="goods-salesvolume">数量:{{i.nums}}</view>
                                                        <view class="goods-salesvolume">SN码:{{i.sn}}</view>
                                                        <view class="goods-salesvolume">BN码:{{i.bn}}</view>
                                                    </view>
                                                </view>
                                            </view>
                                        </view>
                                    </view>
                                </view>
                            </view>
                        </view>
                        
                    </view>
                </checkbox-group>
            </view>
        </view>
        
        <view class="button-bottom" v-if="allData.length">
            <button class="btn btn-b btn-square" @click="write" v-if="checkedIds.length">确认核销</button>
            <button class="btn btn-b btn-square completed" v-else>请选择待核销订单</button>
        </view>
    </view>
</template>

<script>
    export default {
        data(){
            return {
                key: '', // 筛选条件
                isgo: false,
                isgotext: '确认核销',
                allData: [] // 提货单列表
            }
        },
        onLoad(e){
            if(e.id){
                this.key = e.id;
            }
            this.getLadingInfo();
        },
        computed: {
            // 获取选中的提货单id
            checkedIds () {
                let ids = []
                this.allData.forEach(item => {
                    // 判断不是禁用状态 并且是选中状态 并且是未核销状态
                    if (!item.disabled && item.checked && item.status === 1) {
                        ids.push(item.id)
                    }
                })
                return ids
            },
        },
        methods: {
            // 多选框点击事件处理
            checkboxChange (e) {
                var values = e.detail.value;
                this.allData.forEach(item => {
                    if (values.includes(item.id)) {
                        item.checked = true
                    } else {
                        item.checked = false
                    }
                })
            },
            //获取提货单详情
            getLadingInfo() {
                if(this.key){
                    let data = {
                        'key': this.key
                    }
                    this.$api.ladingInfo(data, e => {
                        if (e.status) {
                            this.allData = this.formatData(e.data);
                        } else {
                            this.allData = []; // 清空数据
                            this.$common.modelShow('提示', e.msg, function(){});
                        }
                    });
                }
            },

            //搜索
            search() {
                if(this.key != ''){
                    this.getLadingInfo();
                }else{
                    this.$common.errorToShow('请输入查询关键字');
                    return false;
                }
            },
    
            //查询判断是否可以核销
            isGoWrite(data) {
                let isgo = false;
                if (data.order_info.pay_status == 2 && data.order_info.ship_status == 3){
                    isgo = true;
                    this.lading_id = data.id;
                    this.goodsList = data.goods;
                    this.allData = data;
                } else {
                    this.$common.modelShow('无法核销', '订单必须支付并已发货才可以核销', function(){});
                }
                this.isgo = isgo;
            },
            // 数据转化
            formatData (data){
                data.forEach (item => {
                    if (item.status === 2) {
                        // 已提货
                        this.$set(item, 'checked', false)
                        this.$set(item, 'disabled', true)
                    } else {
                        // 未提货
                        this.$set(item, 'checked', true)
                        this.$set(item, 'disabled', false)
                    }
                })
                return data
            },
            //去核销
            write() {
                let _this = this;
                this.$common.modelShow('提示', '您确认核销吗?', function(res){
                    //去核销
                    let data = {
                        lading_ids: _this.checkedIds.join()
                    }
                    _this.$api.ladingExec(data, res => {
                        if(res.status) {
                            _this.$common.successToShow(res.msg, _this.afterChangeDataStatus())
                        }
                    });
                });
            },
            // 核销完成后更改数据状态
            afterChangeDataStatus () {
                this.allData.forEach(item => {
                    if (this.checkedIds.indexOf(item.id) > -1) {
                        item.status = 2
                        item.checked = false
                        item.disabled = true
                    }
                })
            }
        }
    }
</script>

<style>
.ad {
    width: 100%;
    /* margin: 20upx 0; */
    overflow: hidden;
}
.ad-img{
    width: 100%;
    float: left;
    margin-bottom: 20upx;
}
.ad-img:last-child{
    margin-bottom: 0;
}
.search{
    display: flex;
}
.search-c{
    width: 85%;
    margin-right: 2%;
}
.search-icon{
    left: 20upx;    
}
.search-input {
    padding: 10upx 30upx 10upx 70upx;
}
.search-input-p{
    padding: 0 !important;
}
.search .btn{
    width: 15%;
    border: none;
    background-color: #f1f1f1;
    font-size: 26upx;
    color: #333;
    border-radius: 6upx;
    line-height: 72upx;
    padding-left: 18upx;
    padding-right: 18upx;
}
.list-goods-name{
    margin-bottom: 8upx;
}
.goods-salesvolume{
    display: block;
    margin-bottom: 6upx;
}
.completed{
    background-color: #d9d9d9;
    color: #4e4e4e;
}
.img-list-bot{
    background-color: #fff;
    display: flex;
    padding: 30upx 26upx;
}
.img-list-title{
    padding: 26upx 26upx 0;
    background-color: #fff;
    font-size: 28upx;
    overflow: hidden;
}
.ilt-left{
    float: left;
}
.ilt-right{
    float: right;
}
.img-list-checkbox{
    /* display: inline-block; */
    position: relative;
    height: 100%;
}
.img-list-checkbox uni-checkbox{
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
}
.img-list-right{
    /* display: inline-block; */
    margin-left: 60upx;
}
.img-list-item{
    padding: 0;
}
.img-list-item-r{
    width: 360upx;
}
</style>
list.vue
<template>
    <view class="content">
        <view class="order-list">
            <view class="goods-detail">
                <view class="order-item" v-for="(item, key) in ladingList" :key="key">
                    <view class='cell-group'>
                        <view class='cell-item' style="padding: 10upx 26upx 0 0;">
                            <view class='cell-item-hd'>
                                <view class='cell-hd-title'>提货码:{{item.id}}</view>
                            </view>
                            <view class='cell-item-ft'>
                                <text class='cell-ft-text'>{{item.status_name}}</text>
                            </view>
                        </view>
                    </view>
                    <view class='cell-group'>
                        <view class='cell-item'>
                            <view class='cell-item-hd'>
                                <view class='cell-hd-title'>订单编号:{{item.order_id}}</view>
                            </view>
                            <view class='cell-item-ft'>
<!--                                 <text class='cell-ft-text' v-if="item.status == 1">待提货</text>
                                <text class='cell-ft-text' v-else-if="item.status === 2">已提货</text>
                                <text class='cell-ft-text' v-else>未知状态</text> -->
                            </view>
                        </view>
                    </view>
                    <view class='img-list'>
                        <view class='img-list-item' v-for="(v, k) in item.order_items" :key="k">
                            <image class='img-list-item-l little-img have-none' :src='v.image_url' mode='aspectFill'></image>
                            <view class='img-list-item-r little-right'>
                                <view class='little-right-t'>
                                    <view class='goods-name list-goods-name'>{{v.name}}</view>
                                    <view class='goods-price'>¥{{v.price}}</view>
                                </view>
                                <view class='goods-item-c'>
                                    <view class='goods-buy'>
                                        <view class='goods-salesvolume' v-show="v.addon">{{v.addon}}</view>
                                        <view class='goods-num'>×{{v.nums}}</view>
                                    </view>
                                </view>
                            </view>
                        </view>
                    </view>
                    <view class='order-list-button'>
                        <button class='btn btn-circle btn-g' hover-class="btn-hover" v-if="item.status == 2" @click="ladingDel(item.id)">删除</button>
                        <button class='btn btn-circle btn-w' hover-class="btn-hover" v-if="item.status == 1" @click="ladingWrite(item.id)">提货单核销</button>
                    </view>
                </view>
            </view>
        </view>
    </view>
</template>

<script>
export default {
    data(){
        return {
            ladingList: [],
        }
    },
    onShow(){
        this.getLadingList();
    },
    methods: {
        //获取提货单列表
        getLadingList() {
            this.$api.storeLadingList({}, res => {
                this.ladingList = res.data;
            });
        },
        
        //提货单核销
        ladingWrite(id) {
            this.$common.navigateTo('./index?id=' + id);
        },

        //删除
        ladingDel(id) {
            this.$common.modelShow('提示', '删除提货单后将无法找回!', res => {
                let data = {
                    'lading_id': id
                }
                this.$api.ladingDel(data, res => {
                    this.$common.successToShow(res.msg, res => {
                        this.getLadingList();
                    });
                });
            });
        }
    }
}
</script>

<style>
.segmented-control {
    /*  #ifdef  H5  */
    top: 44px;
    /*  #endif  */
    /*  #ifndef  H5  */
    top: 0;
    /*  #endif  */
    width: 100%;
    background-color: #fff;
    position: fixed;
    
    z-index: 999;
}
.segmented-control-item{
    line-height: 70upx;
}
.order-list{
    /* margin-top: 64upx; */
}
.order-item{
    margin-bottom: 20upx;
}
.img-list{
    margin-top: 2upx;
}
.cell-group,.img-list-item {
    background-color: #fff;
}
.cell-hd-title{
    font-size: 22upx;
    color: #666;
}
.cell-ft-text{
    top: 0;
    font-size: 22upx;
    color: #333;
}
.order-list-button{
    width: 100%;
    background-color: #fff;
    text-align: right;
    padding: 10upx 26upx;
    /* border-top: 2upx solid #f8f8f8; */
}
.order-list-button .btn{
    height: 50upx;
    line-height: 50upx;
}
.order-list-button .btn-w{
    margin-left: 20upx;
}
.goods-num .cell-ft-text{
    color: #999;
    line-height: 32upx;
}
.goods-num .cell-ft-text:first-child{
    margin-left: 10upx;
}
.order-none{
    text-align: center;
    padding: 200upx 0;
}
.order-none-img{
    width: 274upx;
    height: 274upx;
}
</style>

model

index.vue

share

jump.vue
<template>
    <view></view>
</template>
<script>
    export default {
        data() {
            return {};
        },
        onLoad(e) {
            let url = this.$common.shareParameterEncode(e.scene);
            let arr1 = url.split('&');
            
            let type = '',
                invite = '',
                page_code = '',
                id = '',
                id_type = '',
                group_id = '',
                team_id = '';

            for (var i = 0; i < arr1.length; i++) {
                let key = arr1[i].split('=')[0]
                if (key == 'type') {
                    type = arr1[i].split('=')[1]
                }
                if (key == 'invite') {
                    invite = arr1[i].split('=')[1]
                }
                if (key == 'page_code') {
                    page_code = arr1[i].split('=')[1]
                }
                if (key == 'id') {
                    id = arr1[i].split('=')[1]
                }
                if (key == 'id_type') {
                    id_type = arr1[i].split('=')[1]
                }
                if (key == 'group_id') {
                    group_id = arr1[i].split('=')[1]
                }
                if (key == 'team_id') {//拼团参团id
                    team_id = arr1[i].split('=')[1]
                }
            }
            
            this.saveInviteCode(invite); //存储邀请码
            switch (type) {
                case '1': //首页
                    this.gotoIndex();
                    break;
                case '2': //商品详情页面
                    this.gotoGoods(id);
                    break;
                case '3': //首页
                    this.gotoIndex();
                    break;
                case '4': //文章页面
                    this.gotoArticle(id, id_type);
                    break;
                case '5': //拼团页面
                    this.gotoPinTuan(id, team_id);
                    break;
                case '6': //团购页面
                    this.gotoGroup(id, group_id);
                    break;
                case '7': //参团页面
                    // todo:: 功能暂无后续开发
                    // this.gotoInvitationGroup(id, group_id, team_id);
                    break;
                case '8': //自定义页面
                    this.gotoCustom(page_code);
                    break;
                case '9': //店铺邀请
                    this.gotoStore(id);
                    break;
                case '10': //智能表单
                    this.gotoForm(id);
                    break;
                default:
                    this.gotoIndex();
                    break;
            }
        },
        methods: {
            //存储邀请码
            saveInviteCode(invite) {
                if (invite && invite != '') {
                    this.$db.set('invitecode', invite);
                }
            },
            //跳转到首页
            gotoIndex() {
                uni.switchTab({
                    url: '/pages/index/index'
                });
            },
            //跳转到商品
            gotoGoods(id) {
                if(id && id != ''){
                    let url = '/pages/goods/index/index?id=' + id;
                    this.$common.redirectTo(url);
                }else{
                    this.gotoIndex();
                }
            },
            //跳转到文章
            gotoArticle(id, id_type) {
                if(id && id != ''){
                    let url = '/pages/article/index?id=' + id + '&id_type=' + id_type;
                    this.$common.redirectTo(url);
                }else{
                    this.gotoIndex();
                }
            },
            //跳转到拼团
            gotoPinTuan(id, team_id) {
                if(id && id != ''){
                    let url = '/pages/goods/index/pintuan?id=' + id + '&team_id=' + team_id;
                    this.$common.redirectTo(url);
                }else{
                    this.gotoIndex();
                }
            },
            //跳转到团购
            gotoGroup(id, group_id) {
                if(id && id != ''){
                    let url = '/pages/goods/index/group?id=' + id + '&group_id=' + group_id;
                    this.$common.redirectTo(url);
                }else{
                    this.gotoIndex();
                }
            },
            //跳转到参团
            //todo:: 功能暂无后续开发
            // gotoInvitationGroup(id, group_id, team_id) {
            //     if(id && id != '' && group_id && group_id != '' && team_id && team_id != ''){
            //         let url = '/pages/member/order/invitation_group?id=' + id + '&group_id=' + group_id + '&team_id=' + team_id;
            //         this.$common.redirectTo(url);
            //     }else{
            //         this.gotoIndex();
            //     }
            // },
            //跳转到自定义页
            gotoCustom(page_code) {
                if(page_code && page_code != ''){
                    let url = '/pages/index/custom?page_code=' + page_code;
                    this.$common.redirectTo(url);
                }else{
                    this.gotoIndex();
                }
            },
            gotoStore(id) {
                if(id && id != ''){
                    let url = '/pages/member/distribution/my_store?store=' + id;
                    this.$common.redirectTo(url);
                }else{
                    this.gotoIndex();
                }
            },
            //跳转表单
            gotoForm(id){
                if(id && id != ''){
                    let url = '/pages/form/detail/form?id=' + id;
                    this.$common.redirectTo(url);
                }else{
                    this.gotoIndex();
                }
            }
        }
    };
</script>

share.vue

<template>
    <view class="content">
        <view class="share-top"><img class="share-img" :src="poster" mode="widthFix"/></view>
        <view class="share-bot">
            <button class="btn btn-b" v-if="weiXinBrowser">长按图片保存到手机</button>
            <button class="btn btn-b" @click="savePoster()" v-else>保存到本地</button>
            <button class="btn btn-w" @click="goBack()">返回</button>
        </view>
    </view>
</template>
<script>
export default {
    data() {
        return {
            poster: ''
        };
    },
    onLoad(options) {
        this.poster = options.poster;
    },
    computed: {
        weiXinBrowser () {
            return this.$common.isWeiXinBrowser()
        }
    },
    methods: {
        goBack() {
            uni.navigateBack({
                delta: 1
            });
        },
        // 保存海报到本地
        savePoster() {
            let _this = this;
            // #ifdef H5 
            _this.downloadIamge(_this.poster, 'image');
            // #endif

            // #ifdef MP || MP-ALIPAY || APP-PLUS || APP-PLUS-NVUE
            _this.downloadImageOfMp(_this.poster)
            // #endif
        },
        //下载图片地址和图片名
        downloadIamge(imgsrc, name) {
            var image = new Image();
            // 解决跨域 Canvas 污染问题
            image.setAttribute('crossorigin', 'anonymous');
            image.onload = () => {
                var canvas = document.createElement('canvas');
                canvas.width = image.width;
                canvas.height = image.height;
                var context = canvas.getContext('2d');
                context.drawImage(image, 0, 0, image.width, image.height);
                var url = canvas.toDataURL('image/png'); //得到图片的base64编码数据
                var a = document.createElement('a'); // 生成一个a元素
                var event = new MouseEvent('click'); // 创建一个单击事件
                a.download = name || 'photo'; // 设置图片名称
                a.href = url; // 将生成的URL设置为a.href属性
                a.dispatchEvent(event); // 触发a的单击事件
            };
            image.src = imgsrc;
        },
        downloadImageOfMp (image) {
            let _this = this
            
            // #ifdef APP-PLUS
            uni.downloadFile({
                url: image,
                success (res) {
                    uni.saveImageToPhotosAlbum({
                        filePath: res.tempFilePath,
                        success() {
                            _this.$common.successToShow('保存成功')
                        },
                        fail() {
                            _this.$common.errorToShow('图片保存失败')
                        }
                    });
                },
                fail () {
                    _this.$common.errorToShow('下载失败')
                }
            })
            // #endif
            
            // #ifdef MP
            uni.authorize({
                scope: 'scope.writePhotosAlbum',
                success() {
                    // 先下载到本地
                    uni.downloadFile({
                        url: image,
                        success (res) {
                            uni.saveImageToPhotosAlbum({
                                filePath: res.tempFilePath,
                                success() {
                                    _this.$common.successToShow('保存成功')
                                },
                                fail() {
                                    _this.$common.errorToShow('图片保存失败')
                                }
                            });
                        },
                        fail () {
                            _this.$common.errorToShow('下载失败')
                        }
                    })
                },
                fail() {
                    //console.log('授权失败')
                }
            })
            // #endif
        }
    }
};
</script>
<style>
.share-top {
    margin-bottom: 50upx;
    padding-top: 50upx;
    text-align: center;
}
.share-img {
    box-shadow: 0 0 20upx #ccc;
    width: 80%;
}
.share-bot {
    width: 80%;
    margin: 0 auto;
}
.share-bot .btn {
    width: 100%;
    margin: 20upx 0;
}
</style>

store_map

index.vue
<template>
    <view class="content">
        <view class="map-body">
            <cover-view></cover-view>
            <map id="storeMap" :latitude="latitude" :longitude="longitude" :markers="covers"  style="width: 100%;height: 100%;"></map>
        </view>
        <scroll-view class="store-list" scroll-y>
            <view class="cell-item add-title-item" v-for="(item, index) in storeList" :key="index" @click="goMarkers(item.id)">
                <view class="cell-item-hd"><image class="store-img" :src="item.logo"></image></view>
                <view class="cell-item-bd">
                    <view class="cell-bd-view">
                        <text class="cell-bd-text fsz30">{{ item.store_name }}</text>
                    </view>
                    <view class="cell-bd-view">
                        <text class="cell-bd-text color-6 fsz24">电话:{{ item.mobile }}</text>
                    </view>
                    <view class="cell-bd-view">
                        <text class="cell-bd-text color-6 fsz24">地址:{{ item.all_address }}</text>
                    </view>
                </view>
                <view class="cell-item-ft"><image class="cell-ft-next icon" src="/static/image/right.png"></image></view>
            </view>
        </scroll-view>
    </view>
</template>

<script>
export default {
    data() {
        return {
            storeList: [],
            longitude: 0,
            latitude: 0,
            covers: [{
                'longitude': 0,
                'latitude': 0
            }]
        };
    },
    onLoad() {
        this.getMyLocation();
        this.getStoreList();
    },
    methods: {
        // 获取自己的位置信息
        getMyLocation() {
            let _this = this;
            uni.getLocation({
                type: 'wgs84',
                success: function (res) {
                    _this.longitude = res.longitude;
                    _this.latitude = res.latitude;
                },
                fail: function () {
                    _this.$common.errorToShow("获取位置信息失败")
                }
            });

        },
        // 获取店铺列表信息
        getStoreList() {
            let _this = this;
            _this.$api.storeList({}, res => {
                if (res.status) {
                    _this.storeList = res.data;
                    let storeList = res.data;
                    let covers = [];
                    for (let i=0; i < storeList.length; i++) {
                        let newArr = {}
                        newArr.latitude = storeList[i].latitude;
                        newArr.longitude = storeList[i].longitude;
                        newArr.width = '50rpx';
                        newArr.height = '50rpx';
                        newArr.iconPath = '/static/image/gps-blue.png'
                        covers.push(newArr)
                        
                    }
                    console.log(covers)
                    _this.covers = covers;
                } else {
                }
                // console.log(res)
            });
        }
    }
};
</script>

<style scoped>
.content {
    width: 100%;
    /* #ifdef H5 */
    height: calc(100vh - 44px);
    /* #endif */
    /* height: 100vh; */
}
.map-body {
    width: 100%;
    height: 700rpx;
    position: relative;
}
.store-list {
    background-color: #fff;
    height: calc(100vh - 44px - 700rpx);
}
.store-item {
    display: flex;
}
.store-img {
    width: 140rpx;
    height: 140rpx;
}
.store-right {
    flex: 1;
}
</style>

pages.json

{
  "pages": [
    {
      "path": "pages/index/index",
      "style": {
        "navigationBarTitleText": "首页",
        // #ifdef H5
        "titleNView": false,
        // #endif
        "enablePullDownRefresh": true
      }
    },
    {
      "path": "pages/index/custom",
      "style": {
        "navigationBarTitleText": "页面",
        // #ifdef H5
        "titleNView": false,
        // #endif
        "enablePullDownRefresh": true
      }
    },
    {
      "path": "pages/index/search",
      "style": {
        "navigationBarTitleText": "搜索"
      }
    },
    {
      "path": "pages/classify/classify",
      "style": {
        "navigationBarTitleText": "分类"
      }
    },
    {
      "path": "pages/classify/index",
      "style": {
        "navigationBarTitleText": "商品列表"
      }
    },
    {
      "path": "pages/cart/index/index",
      "style": {
        "navigationBarTitleText": "购物车"
      }
    },
    {
      "path": "pages/member/index/index",
      "style": {
        // #ifdef H5
        "titleNView": false,
        // #endif
        "navigationBarTitleText": "个人中心"
      }
    },
    {
      "path": "pages/member/coupon/index",
      "style": {
        "navigationBarTitleText": "我的优惠券"
      }
    },
    {
      "path": "pages/member/balance/index",
      "style": {
        "navigationBarTitleText": "我的余额"
      }
    },
    {
      "path": "pages/member/balance/recharge",
      "style": {
        "navigationBarTitleText": "充值"
      }
    },
    {
      "path": "pages/member/balance/withdraw_cash",
      "style": {
        "navigationBarTitleText": "提现"
      }
    },
    {
      "path": "pages/member/balance/details",
      "style": {
        "navigationBarTitleText": "余额明细"
      }
    },
    {
      "path": "pages/member/balance/cashlist",
      "style": {
        "navigationBarTitleText": "提现记录"
      }
    },
    {
      "path": "pages/member/balance/bankcard",
      "style": {
        "navigationBarTitleText": "我的银行卡"
      }
    },
    {
      "path": "pages/member/balance/add_bankcard",
      "style": {
        "navigationBarTitleText": "添加银行卡"
      }
    },
    {
      "path": "pages/member/collection/index",
      "style": {
        "navigationBarTitleText": "我的收藏"
      }
    },
    {
      "path": "pages/member/history/index",
      "style": {
        "navigationBarTitleText": "我的足迹"
      }
    },
    {
      "path": "pages/member/address/list",
      "style": {
        "navigationBarTitleText": "地址管理"
      }
    },
    {
      "path": "pages/member/address/index",
      "style": {
        "navigationBarTitleText": "修改地址"
      }
    },
    {
      "path": "pages/member/setting/index",
      "style": {
        "navigationBarTitleText": "设置"
      }
    },
    {
      "path": "pages/member/setting/user_info/index",
      "style": {
        "navigationBarTitleText": "个人信息"
      }
    },
    {
      "path": "pages/member/setting/user_info/password",
      "style": {
        "navigationBarTitleText": "修改密码"
      }
    },
    {
      "path": "pages/member/integral/index",
      "style": {
        "navigationBarTitleText": "我的积分"
      }
    },
    {
      "path": "pages/member/invite/index",
      "style": {
        "navigationBarTitleText": "邀请好友"
      }
    },
    {
      "path": "pages/member/invite/list",
      "style": {
        "navigationBarTitleText": "邀请列表"
      }
    },
    {
      "path": "pages/member/take_delivery/index",
      "style": {
        "navigationBarTitleText": "提货单核销"
      }
    },
    {
      "path": "pages/member/take_delivery/list",
      "style": {
        "navigationBarTitleText": "提货单列表"
      }
    },
    {
      "path": "pages/goods/index/index",
      "style": {
        // #ifdef H5
        "titleNView": false,
        // #endif
        "navigationBarTitleText": "商品详情",
        "navigationStyle": "custom"
      }
    },
    {
      "path": "pages/goods/index/group",
      "style": {
        "navigationBarTitleText": "促销详情",
        "navigationStyle": "custom"
      }
    },
    {
      "path": "pages/goods/place-order/index",
      "style": {
        "navigationBarTitleText": "提交订单"
      }
    },
    {
      "path": "pages/goods/place-order/invoice",
      "style": {
        "navigationBarTitleText": "发票"
      }
    },
    {
      "path": "pages/goods/place-order/storelist",
      "style": {
        "navigationBarTitleText": "门店列表"
      }
    },
    {
      "path": "pages/goods/payment/index",
      "style": {
        "navigationBarTitleText": "支付"
      }
    },
    {
      "path": "pages/goods/payment/auth",
      "style": {
        "navigationBarTitleText": "等待支付"
      }
    },
    {
      "path": "pages/goods/payment/result",
      "style": {
        "navigationBarTitleText": "支付结果"
      }
    },
    {
      "path": "pages/member/order/orderlist",
      "style": {
        "navigationBarTitleText": "订单列表"
      }
    },
    {
      "path": "pages/member/order/orderdetail",
      "style": {
        "navigationBarTitleText": "订单详情"
      }
    },
    {
      "path": "pages/member/order/invitation_group",
      "style": {
        "navigationBarTitleText": "邀请拼单"
      }
    },
    {
      "path": "pages/member/after_sale/index",
      "style": {
        "navigationBarTitleText": "申请售后"
      }
    },
    {
      "path": "pages/member/after_sale/list",
      "style": {
        "navigationBarTitleText": "售后列表"
      }
    },
    {
      "path": "pages/member/after_sale/detail",
      "style": {
        "navigationBarTitleText": "售后详情"
      }
    },
    {
      "path": "pages/member/order/evaluate",
      "style": {
        "navigationBarTitleText": "订单评价"
      }
    },
    {
      "path": "pages/member/order/express_delivery",
      "style": {
        "navigationBarTitleText": "物流信息"
      }
    },
    {
      "path": "pages/article/index",
      "style": {
        "navigationBarTitleText": "文章详情"
      }
    },
    {
      "path": "pages/article/list",
      "style": {
        "navigationBarTitleText": "文章列表"
      }
    },
    {
      "path": "pages/login/choose/index",
      "style": {
        "navigationBarTitleText": "授权登录"
      }
    },
    {
      "path": "pages/login/login/index",
      "style": {
        "navigationBarTitleText": "登录"
      }
    },
    {
      "path": "pages/login/login/index1",
      "style": {
        "navigationBarTitleText": "登录"
      }
    },
    {
      "path": "pages/share",
      "style": {
        "navigationBarTitleText": "分享"
      }
    },
    {
      "path": "pages/author",
      "style": {
        // #ifdef H5
        "titleNView": false,
        // #endif
        "navigationBarTitleText": "获取授权中"
      }
    },
    {
      "path": "pages/login/register/index",
      "style": {
        "navigationBarTitleText": "注册"
      }
    },
    {
      "path": "pages/classify/pintuan_list",
      "style": {
        "navigationBarTitleText": "拼团列表"
      }
    },
    {
      "path": "pages/goods/index/pintuan",
      "style": {
        "navigationBarTitleText": "拼团详情",
        "navigationStyle": "custom"
      }
    },
    {
      "path": "pages/form/detail/form",
      "style": {
        "navigationBarTitleText": "万能表单"
      }
    },
    {
      "path": "pages/member/distribution/index",
      "style": {
        "navigationBarTitleText": "分销中心"
      }
    },
    {
      "path": "pages/member/distribution/apply",
      "style": {
        "navigationBarTitleText": "申请成为分销"
      }
    },
    {
      "path": "pages/member/distribution/apply_state",
      "style": {
        "navigationBarTitleText": "审核状态"
      }
    },
    {
      "path": "pages/member/distribution/user",
      "style": {
        "navigationBarTitleText": "分销中心"
      }
    },
    {
      "path": "pages/member/distribution/agreement",
      "style": {
        "navigationBarTitleText": "分销协议"
      }
    },
    {
      "path": "pages/member/distribution/order",
      "style": {
        "navigationBarTitleText": "推广订单"
      }
    },
    {
      "path": "pages/member/distribution/popularize",
      "style": {
        "navigationBarTitleText": "我要推广"
      }
    },
    {
      "path": "pages/member/distribution/my_store",
      "style": {
        "navigationBarTitleText": "我的店铺"
      }
    },
    {
      "path": "pages/member/distribution/store_setting",
      "style": {
        "navigationBarTitleText": "店铺设置"
      }
    },
    {
      "path": "pages/activity/index",
      "style": {
        "navigationBarTitleText": "转盘抽奖"
      }
    },
    {
      "path": "pages/share/jump",
      "style": {
        // #ifdef H5
        "titleNView": false,
        // #endif
        "navigationBarTitleText": "加载中..."
      }
    },
    {
      "path": "pages/store_map/index",
      "style": {
        "navigationBarTitleText": "门店列表"
      }
    }
  ],
  "globalStyle": {
    "navigationBarTextStyle": "black",
    "navigationBarTitleText": "新模板",
    "navigationBarBackgroundColor": "#fff",
    "backgroundColor": "#F8F8F8"
  },
  "tabBar": {
    "color": "#999",
    "selectedColor": "#333",
    "backgroundColor": "#fff",
    "list": [
      {
        "pagePath": "pages/index/index",
        "text": "首页",
        "iconPath": "static/image/index_gray.png",
        "selectedIconPath": "static/image/index_black.png"
      },
      {
        "pagePath": "pages/classify/classify",
        "text": "分类",
        "iconPath": "static/image/classify_gray.png",
        "selectedIconPath": "static/image/classify_black.png"
      },
      {
        "pagePath": "pages/cart/index/index",
        "text": "购物车",
        "iconPath": "static/image/cart_gray.png",
        "selectedIconPath": "static/image/cart_black.png"
      },
      {
        "pagePath": "pages/member/index/index",
        "text": "我的",
        "iconPath": "static/image/user_gray.png",
        "selectedIconPath": "static/image/user_black.png"
      }
    ]
  },
  "condition": {
    //模式配置,仅开发期间生效
    "current": 0, //当前激活的模式(list 的索引项)
    "list": [
      {
        "name": "", //模式名称
        "path": "", //启动页面,必选
        "query": "" //启动参数,在页面的onLoad函数里面得到
      }
    ]
  }
}

README.md

# Jshop小程序uniapp前台简约模板

#### 介绍

当前版本已支持可视化操作首页

uni-app简约前台H5+小程序模板,全新UI设计,更多交互细节,我们倾尽全力为您提供更加流畅舒爽的体验。

增加对支付宝小程序、APP的支持,实现一个后台,管理5个前端。

同时又实现了一套前端代码,发布多个平台,为您的业务可以提供更加强有力的支撑!



#### Jshop小程序商城介绍
Jshop小程序商城,是一款开源的电商系统,包含微信小程序和H5端,为大中小企业提供移动电子商务优秀的解决方案。

后台采用Thinkphp5.1框架开发,执行效率、扩展性、稳定性值得信赖。并且Jshop小程序商城上手难度低,可大量节省定制化开发周期。

前台H5使用Vue开发,在页面的打开和渲染效率上更快,下单流程流畅自然,可大大增加用户体验,提升订单量。

强大的促销引擎,多种促销方式自由搭配,满足各种场景的促销方式需求,做活动更灵活简单,并且在促销的扩展上也非常方便。



#### 关于开源

这不是一款免费的系统,商用记得授权哦。

之所以不彻底免费,一方面是可以让我们有持续维护下去的动力和资源,另外一方面也是不想让您有后顾之忧,避免后期尴尬。

我们的团队水平有限,也是在探索中学习,在改进。之所以开源,就是为了方便大家,也是为了提升下该项目的质量,我们相信有您的参与,可以使我们的系统更加完善和健壮。



#### 功能介绍

 + 商品管理,单规格、多规格商品管理,品牌、分类管理、商品评价
 + 订单管理,订单支付、发货、取消、售后等
 + 会员管理,会员列表,消息管理等
 + 运营管理,广告管理、文章管理
 + 微信管理,小程序管理、微信公众号管理、模板列表、公众号菜单管理
 + 促销管理,商品促销、订单促销、优惠券、团购秒杀
 + 财务管理,支付单、退款单管理、提现管理、账户资金管理
 + 控制面板,计划任务、插件、图片、地区、消息、店铺配置、支付方式、配送方式、物流公司管理。信任登录插件、阿里云OSS插件、阿里云短信插件、微信消息模板插件、分销功能
 + 门店管理,门店列表。门店核销、店员管理、提货单管理。
 + 智能表单,表单列表、表单统计、表单提交管理、表单小程序码等
 + 统计报表,商品销量统计、财务收款统计、订单销量统计
 + 页面管理,布局管理,页面可视化操作

#### 项目演示
- H5体验地址:https://demo.jihainet.com/wap/
- 后台项目地址:https://gitee.com/hnjihai/jshop_mall
- QQ交流群:823732583(开发手册、接口文档、操作手册请进群查看哦~)
- 交流社区:[https://bbs.jihainet.com/](https://bbs.jihainet.com/)
- H5体验二维码

![输入图片说明](https://gitee.com/uploads/images/2019/0426/090608_1a1f0073_8503.png "H5.png")

- APP体验二维码

![输入图片说明](https://gitee.com/uploads/images/2019/0426/090622_d1d4b372_8503.png "app.png")

- 微信小程序体验码

![输入图片说明](https://gitee.com/uploads/images/2019/0426/082533_e2f315f9_8503.jpeg "gh_f9fafa5a7066_344.jpg")


#### 项目截图
![输入图片说明](https://gitee.com/uploads/images/2019/0404/180847_9615f414_8503.png "未标题-1.png")

#### 目录结构


初始的目录结构如下:

wap WEB部署目录(或者子目录)
├─components uniapp组件目录
├─pages 应用页面
│ ├─article 文章相关页面
│ ├─cart 购物车相关页面
│ ├─classify 分类以及商品列表页面
│ ├─goods 商品详情页等相关页面
│ ├─index 首页以及搜索页
│ ├─login 登录相关页面
│ ├─member 会员中心相关页面

├─config 配置文件目录
├─static 静态文件目录
├─unpackage 编译后目录
├─index.html 入口文件模板

#### 更新说明
2019-07-31 v1.0.6
更新日志
1. 可视化图片分组添加最小高度
2. 禁止可视化垃圾桶拖拽
3. 1086短信接口改为curl
4. 增加是否绑定手机号码选项,优化后台生成用户方法
5. 修复购物车数量加减的问题
6. 生成订单的时候,有几个值没有保存成功的bug,感谢@打酱油网友提供的bug
7. 修复运费包邮bug
8. 开启规格处增加提示
9. 新增拼团功能
10. 微信登陆免手机号码校验
11. 第三方登录的时候,免手机号码验证登陆的时候,保存推荐人信息
12. 如果是第三方微信登陆,增加直接登陆
13. 用户列表显示编号
14. 修复团购秒杀删除商品后依然显示问题
15. 门店表距离获取 表前缀bug修复
16. 修复商品商品详情页品牌为空的时候,显示null的问题
17. 门店列表表前缀sql修复
18. 小程序可视化单图组件添加按钮功能
19. 订单列表加类型筛选
20. 商品详情显示优化
21. 修复库存问题
22. 可视化编辑添加文字按钮颜色
23. 小程序价格区间问题修复
24. 微信公众号无感登陆支付
25. 公众号自动登陆调整
26. 修复售后单详情查询的时候必填user_id的问题
27. 商品分类排序问题修复
28. 文章详情接口修改(文章发布时间修改为相对时间)
29. 手机号验证规则修复
30. 修复后台用户信息保存推荐人信息错误的bug
31. 修复多规格商品添加时,第一次无法保存库存问题
32. 修改可视化商品组件手动选择数据绑定
33. 修复团购秒杀问题
34. 微信和支付宝同步回调地址增加上支付单号
35. 修复门店订单有运费问题
36. 后台提货单操作,提货单详情接口修改
37. 订单售后状态简单修改
38. 修复首页多个商品组件时问题
39. 商品列表问题修复
40. 商品列表筛选调整
41. 商品分类优化
42. 页面布局修改
43. 修改商品和货品库存显示
44. 优化权限问题,修复订单支付无权限bug
45. 优化角色权限选择,可以单独选择父节点
46. 商品添加扩展分类
47. 后台商品列表动态计算库存
48. 修复公众号菜单问题
49. 修复关键词菜单
50. 图文编辑原文地址必填项问题修复,增加系统图文地址
51. 商品增加批量出库库存,改价
52. 修复商品评论,评论优化
53. 分类增加是否显示
54. 页面增加添加功能
55. 会员增加批量删除
56. 新增分销插件
57. 增加每日提现上限
58. 接口增加全局安全过滤
59. 后台登录添加背景动画,优化后台登录
60. 后台管理弹框显示修改
61. 余额变动优化,增加余额当前页统计,余额筛选类型修复
62. 修复收货地址前端输入换行问题
63. 修复后台修改管理员密码问题
64. 优化后台优化输出结构,避免节点无权限时乱码
65. 优化公众号配置地址
66. 修复原生小程序商品列表翻页问题
67. 海报生成提出来,统一处理
68. 订单发货问题优化
69. 修复vue,H5底部遮挡问题
70. 优化添加商品按钮
71. 增加加解密函数
72. 增加图片缓存,路由缓存
73. 优化分享设置,后台可设置分享
74. 后台商品列表修复高级筛选
75. 商品评价列表优化
76. 表单功能修复
77. uniapp增加智能表单
78. 表单增加提交次数限制
79. uniapp增加微信模板消息
80. 增加关于我们后台可直接配置
81. 添加批量购物车接口
82. 修复商品规格编辑问题
83. 购物车和促销价格使用精确计算
84. 微信图文增加创建和更新时间
85. 最低提现金额不能小于0.01
86. 自定义页面增加操作说明
87. 配置统一获取方法优化确保只查询一次数据库
88. 修复广告位
89. 修复编辑文章时分类问题
90. 可视化单图组件增加按钮以及颜色
2019-05-23 v1.0.5
1.修复图片组件跳转问题

2019-05-22 v1.0.4
1.增加可视化支持

2019-04-25 v1.0.3
1. 修复海报生成
2. 修复支付宝支付问题
3. 微信授权登录修复
4. 修复app登录返回问题
5. 修复支付宝绑定账户时短信验证码ip问题


#### 安装教程

1. 小程序发布教程
具体配置稍后提供
开发相关介绍:https://uniapp.dcloud.io/

2. H5发布教程
具体配置稍后提供
开发相关开发介绍:https://uniapp.dcloud.io/

## 配置
### 服务器地址
config/config.js中

export const baseUrl = 'http://www.b2c.com/';//注意最后斜杠,填写你的域名地址
export const entId = '';//客服ID 在https://www.jihainet.com中找客服开通


### 海报H5中保存图片跨域
nginx中添加以下配置
location ~ .*\.(gif|jpg|jpeg|png)$ {
  add_header Access-Control-Allow-Origin *;
  add_header Access-Control-Allow-Headers X-Requested-With;
  add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
}


#### 安全&缺陷
如果你发现了一个安全漏洞或缺陷,请发送邮件到 jima@jihainet.com。所有的安全漏洞都将及时得到解决。


#### License

Jshop小程序商城遵循JPPL(吉海科技Jshop系列付费产品许可)协议。

本项目包含的第三方源码和二进制文件之版权信息另行标注。

版权所有Copyright © 2019 by 吉海科技 (https://www.jihainet.com)

All rights reserved。

吉海科技Jshop系列付费产品许可协议详情请参阅 [LICENSE.txt](LICENSE.txt)

static

css

style.css
body{
  background-color: #f8f8f8;
  font-size: 28upx;
}
view{
  box-sizing: border-box;
}
/* #ifdef MP-ALIPAY */
image{
    background-size: 100% 100%;
}
button{
    height: auto;
    border: none;
    line-height: 2.55555556;
    padding: 0 28upx;
}
input{
    background: none;
    padding: 0;
}
shared-checkbox{
    border-radius: 50%;
}
shared-checkbox{
    border-radius: 50%;
    height: 36rpx;
    width: 36rpx;
    margin-top: -4rpx;
    border: 1rpx solid #d1d1d1;
    color: #FF7159;
}
shared-checkbox:checked {
  /* width: 36rpx;
  height: 36rpx;
  line-height: 36rpx;
  border-radius: 50%;
  text-align: center;
  font-size: 28rpx;
  color: #fff;
  background: transparent;
  transform: translate(-50%, -50%) scale(1);
  -webkit-transform: translate(-50%, -50%) scale(1);
  background-color: #FF7159;
  border: 1rpx solid #FF7159; */
  background-color: #000;
  color: #000;
}
._radio{
   border-radius: 50%;/* 圆角 */
   width: 36rpx;
   height: 36rpx;
   margin-top: -4rpx;
   border: 1rpx solid #d1d1d1;
}
/* 选中后的 背景样式 (红色背景 无边框 可根据UI需求自己修改) */
._radio:checked{
   border: 1rpx solid #FF7159;
   background: #FF7159;
}
/* 选中后的 对勾样式 (白色对勾 可根据UI需求自己修改) */
._radio:checked::before{
   border-radius: 50%;/* 圆角 */
   width: 36rpx; /* 选中后对勾大小,不要超过背景的尺寸 */
   height: 36rpx; /* 选中后对勾大小,不要超过背景的尺寸 */
   line-height: 36rpx;
   text-align: center;
   font-size:28rpx; /* 对勾大小 30rpx */
   color:#fff; /* 对勾颜色 白色 */
   background: transparent;
   transform:translate(-50%, -50%) scale(1);
   -webkit-transform:translate(-50%, -50%) scale(1);
}
/* #endif */
uni-toast .uni-toast{
    /* width: 6em; */
    font-size: 24upx;
    border-radius: 10px;
    background: rgba(17,17,17,.5);
}
uni-input div, uni-input div div,uni-input, uni-input input{
    /* min-height: 1rem !important; */
}
uni-input{
    /* height: 1rem; */
}
uni-input div div.input-placeholder{
    /* padding: 8upx 0; */
}
.content-top{
    margin-bottom: 116upx;
}
.have-none{
  background-color: #f3f3f3;
}
.color-o{
    color: #FF7159 !important;
}
.color-f{
    color: #fff !important;
}
.color-d{
    color: #ddd !important;
}
.color-3{
    color: #333 !important;
}
.color-6{
    color: #666 !important;
}
.color-9{
    color: #999 !important;
}
.fsz24{
    font-size: 24upx !important;
}
.fsz26{
    font-size: 26upx !important;
}
.fsz28{
    font-size: 28upx !important;
}
.fsz30{
    font-size: 30upx !important;
}
.fsz32{
    font-size: 32upx !important;
}
.fsz34{
    font-size: 34upx !important;
}
.fsz36{
    font-size: 36upx !important;
}
.fsz38{
    font-size: 38upx !important;
}
.fsz50{
    font-size: 50upx !important;
}
.search{
  width: 100%;
  height: 104upx;
  padding: 16upx 26upx;
  background-color: rgba(255,255,255,1);
    z-index: 999;
    transition: all .5s;
}
.search-c{
  width: 100%;
  height: 100%;
  position: relative;
}
.search-input{
  background-color: #E9E9E9;
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  line-height: 52upx;
  padding: 10upx 90upx 10upx 40upx;
  border-radius: 50upx;
  font-size: 24upx;
    transition: all .5s;  
}
.search-input-p{
  color: #999;
  width: 100%;
  height: 100%;
}
.search-input-p-c{
    position: relative;
    top: 50%;
    transform: translateY(-50%);
}
.search-icon{
  position: absolute;
  top: 50%;
  right: 30upx;
  transform: translateY(-50%);
    z-index: 99;
}
.swiper-c{
  height: 100%;
}
.swiper-c image{
  height: 100%;
  width: 100%;
}
.btn{
  display: inline-block;
  box-sizing: border-box;
  border-radius: 0;
  font-size: 28upx;
    transform: scale(1);
    transition: all .5s;
}
/*按钮按下缩小变色*/
.btn-hover{
    transform: scale(.90);
    transition: all .5s;
    opacity: .8;
}
/*按钮按下只变色*/
.btn-hover2{
/*     transform: scale(.95); */
    transition: all .1s;
    opacity: .6;
}
.btn::after{
  border: none;
}
.btn-circle{
  padding: 0upx 20upx;
  height: 60upx;
  line-height: 60upx;
  min-width: 140upx;
/*  border-radius: 6upx; */
  font-size: 22upx;
}
.btn-square{
  padding: 0upx 40upx;
  height: 90upx;
  line-height: 90upx;
  min-width: 150upx;
  border: none !important;
}
.btn-fillet{
    border-radius: 50upx;
}
.btn-c{
    background-color: #f7f7f7;
}
.btn-w{
  border: 2upx solid #333;
  color: #333;
    background-color: #fff;
}
.btn-g{
  border: 2upx solid #E0E0E0;
  color: #999;
    background-color: #fff;
}
.btn-b{
  border: 2upx solid #333;
  background-color: #333;
  color: #fff;
}
.btn-o{
  border: 2upx solid #FF7159;
  background-color: #FF7159;
  color: #fff;
}
.btn-half{
    width: 50%;
}
.btn-all{
    width: 100%;
}
.img-grids{
  overflow: hidden;
    /* padding-bottom: 26upx; */
}
.img-grids .goods-name{
    height: 72upx;
}
.column3.img-grids .goods-name{
    height: 68upx;
}
.img-grids-item{
  width: 336upx;
  margin: 26upx;
  display: inline-block;
  background-color: #fff;
  float: left;
  min-height: 130upx;
  /* #ifdef MP-ALIPAY */
  width: 330rpx;
  margin: 25rpx;
  min-height: 130rpx;
  /* #endif */
}
.img-grids-item:nth-child(2n-1){
  margin-right: 0;
}
.img-grids-item-t{
  width: 336upx;
  height: 336upx;
   /* #ifdef MP-ALIPAY */
  width: 330rpx;
  height: 330rpx;
  /* #endif */
}
.img-grids-item-b{
  padding: 0 10upx 10upx;
}
.goods-name{
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  color: #333;  
  width: 100%; 
  /* height: 72upx; */
  /* #ifdef MP-ALIPAY */
  min-height: 20px;
  /* #endif */
}
.grids-goods-name{
  font-size: 26upx;
}
.goods-item-c{
  overflow: hidden;
  margin-top: 10upx;
}
.goods-price{
  min-width: 120upx;
  min-height: 40upx;
  color: #333;
  font-size: 28upx;
  display: inline-block;
  float: left;
}
.red-price{
  color: #FF7159 !important;
}
.img-list{

}
.img-list .goods-name{
    min-height: 74upx;
}
.img-list-item{
  padding: 30upx 26upx;
  background-color: #fff;
  margin-bottom: 2upx;
  overflow: hidden;
}
.img-list-item-l{
  width: 250upx;
  height: 250upx;
  display: inline-block;
  float: left;
}
.img-list-item-r{
  width: 410upx;
  min-height: 250upx;
  display: inline-block;
  margin-left: 26upx;
  float: left;
  padding: 10upx 0;
  position: relative;
}
.list-goods-name{
  font-size: 28upx;
}
.img-list-item .goods-item-c{
  /* position: absolute; */
  /* bottom: 0; */
  width: 100%;
    margin-top: 0;
}
.img-list-item .goods-price{
  min-width: 150upx;
  min-height: 50upx;
  font-size: 38upx;
  float: none;
}
.goods-buy{
  overflow: hidden;
}
.goods-salesvolume{
  min-width: 100upx;
  height: 30upx;
  font-size: 20upx;
  color: #999;
  display: inline-block;
}
.goods-cart{
  width: 40upx;
  height: 40upx;
  float: right;
}
.medium-img{
    width: 196upx;
    height: 196upx;
}
.little-img{
  width: 140upx;
  height: 140upx;
}
.small-img{
  width: 120upx;
  height: 120upx;
}
.medium-right{
    width: 340upx;
    min-height: 140upx;
}
.little-right{
  width: 520upx;
  min-height: 140upx;
  padding: 0;
}
.small-right{
  width: 540upx;
  height: 120upx;
  padding: 0;
    min-height: 60upx;
}
.little-right-t{
  overflow: hidden;
}
.little-right .list-goods-name{
  float: left;
  width: 360upx;
    margin-bottom: 6upx;
}
.small-right .list-goods-name{
  width: 100%;
}
.little-right .goods-price{
  float: right;
  font-size: 28upx;
  text-align: right;
  min-width: 120upx;
    max-width: 150upx;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
  min-height: 40upx;
}
.goods-num{
  float: right;
  color: #999;
  font-size: 24upx;
  height: 30upx;
  min-width: 50upx;
}
.goods-numbox{
    float: right;
}
.little-right .goods-salesvolume{
  font-size: 24upx;
  /* float: left; */
}
.cell-group{
  background-color: #fff;
}
.cell-item{
  padding: 20upx 26upx 20upx 0;
  width: 724upx;
  margin-left: 26upx;
  border-bottom: 2upx solid #f3f3f3;
  position: relative;
  overflow: hidden;
  background-color: #fff;
    color: #333;
  display: table;
    min-height: 90upx;
}
.cell-item:last-child{
  border: none;
}
.cell-item-hd{
  display: table-cell;
  vertical-align: middle;
  min-width: 160upx;
  max-width: 180upx;
  font-size: 28upx;
    position: relative;
}
.cell-hd-icon{
  width: 40upx;
  height: 40upx;
  display: inline-block;
  float: left;
    margin-right: 8upx;
}
.cell-hd-title{
  float: left;
  display: inline-block;
  position: relative;
  /* #ifdef MP-ALIPAY */
  top: 4upx;
  /* #endif */
  /* word-wrap: break-word; */
}
.cell-item-bd{
  display: table-cell;
  vertical-align: middle;
  margin-left: 20upx;
  min-height: 30upx;
  overflow: hidden;
  min-width: 440upx;
  max-width: 480upx;
    padding-right: 50upx;
}
.cell-bd-view {
    position: relative;
    overflow: hidden;
}
.cell-bd-text{
  float: left;
  position: relative;
  font-size: 24upx;
}
.cell-bd-text-right{
    float: right;
}
.cell-bd-input{
  display: inline-block;
  float: left;
    font-size: 26upx;
}
.cell-item-ft{
  display: inline-block;
  position: absolute;
  top: 50%;
  right: 26upx;
  transform: translateY(-50%);
  overflow: hidden;
}
.right-img .cell-item-ft{
    right: 8upx;
    height: 50upx;
}
.cell-ft-view{
    position: relative;
    overflow: hidden;
    color: #666;
    font-size: 28upx;
    text-align: right;
}
.cell-ft-p{
    font-size: 24upx;
    color: #666;
}
.cell-ft-text{
  font-size: 28upx;
  float: right;
  position: relative;
  /* top: 8upx; */
  line-height: 50upx;
}
.cell-ft-next{
  float: right;  
}
.margin-cell-group{
    margin: 20upx 0;
}
.bottom-cell-group{
    margin-bottom: 20upx;
}
.min-cell-group{
    margin-bottom: 1px;
    padding: 20upx 0;
}
.min-cell-group .cell-item{
    border-bottom: none;
    min-height: 50upx;
    padding: 0 26upx 0 0;
}
.icon{
  width: 50upx;
  height: 50upx;
  /* #ifdef MP-ALIPAY */
  background-size: 100% 100%;
  /* #endif */
}
.swiper-grids .swiper-list{
  white-space:nowrap;
  width:100%;
  min-height: 200upx;
}
.swiper-grids .img-grids-item{
  float: none;
  margin-right: 0;
  width: 255upx;
  margin-top: 0;
}
.swiper-grids .img-grids-item:last-child{
  margin-right: 26upx;
}
.swiper-grids .img-grids-item-t{
  width: 255upx;
  height: 255upx;
}
.swiper-grids .goods-name{
  white-space: normal;
}
.member-grid{
  padding: 20upx 26upx;
  /* overflow: hidden; */
  width: 100%;
  display: flex;
}
.member-item{
  /* width: 20%; */
  flex: 1;
  /* float: left; */
  /* display: inline-block; */
  text-align: center;
  position: relative;
}
/*会员中心图标按下事件*/
.member-item:active{
    transform: scale(.90);
    transition: all .5s;
    opacity: .8;
}
.member-item-icon{
  width: 50upx;
  height: 50upx;
  display: block;
  margin: 0 auto;
}
.member-item-text{
  font-size: 24upx;
  color: #666;
  display: block;
}
.cart-list{
    
}
.cart-checkbox{
    position: relative;
    height: 100%;
}
.cart-checkbox-c{
    display: inline-block;
    position: absolute;
    top: 50%;
    left: 26upx;
    transform: translateY(-50%);
    z-index: 99;
}
.cart-list .img-list-item{
    padding-left: 90upx;
}
.cart-list .little-right{
    width: 468upx;
}
.cart-list .little-right .list-goods-name{
    width: 300upx;
}
.uni-checkbox-input{
    border-radius: 50% !important;
    color: #fff !important;
}
uni-radio .uni-radio-input,uni-checkbox .uni-checkbox-input{
    width: 36upx;
    height: 36upx;
}
uni-checkbox .uni-checkbox-input.uni-checkbox-input-checked,.uni-radio-input.uni-radio-input-checked{
    background-color: #FF7159 !important;
    border-color: #FF7159 !important;
    width: 36upx;
    height: 36upx;
}
uni-checkbox.checkboxNo .uni-checkbox-input{
    background-color: #e1e1e1 !important;
    border-color: #e1e1e1 !important;
}
uni-radio.radioNo .uni-radio-input{
    background-color: #e1e1e1 !important;
    border-color: #e1e1e1 !important;
}
uni-checkbox .uni-checkbox-input.uni-checkbox-input-checked:before{
    font-size: 36rpx;
}
.login-item-i-p{
    color: #999;
}
.two-line{
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
}
.badge{
    display: inline-block;
    position: absolute;
    min-width:13px;
    height:13px;
    line-height:13px;
    background-color:#FF7159;
    color:#fff;
    font-size:12px;
    border-radius:50upx;
    padding:0 3px;
    z-index: 99;
}
.button-bottom{
    background-color: #fff;
    position: fixed;
    bottom: 0;
    height: 90upx;
    width: 100%;
    display: flex;
    z-index: 66;
    box-shadow: 0 0 10px #ccc;
}
.button-bottom .btn{
    flex: 1;
}
.romotion-tip{
    /* display: inline-block; */
    overflow: hidden;
}
.romotion-tip-item{
    display: inline-block;
    float: left;
    margin-right: 10upx;
    margin-bottom: 4upx;
    background-color: #FF7159;
    color: #fff;
    height: 34upx;
    font-size: 24upx;
    line-height: 34upx;
    padding: 0 10upx;
}
.bg-gray{
    background-color: #D0D0D0;
}



/*  #ifdef MP */
checkbox .wx-checkbox-input{
    border-radius: 50%;
    height: 36rpx;
    width: 36rpx;
    margin-top: -4rpx;
    border: 1rpx solid #d1d1d1;
    
}
checkbox .wx-checkbox-input.wx-checkbox-input-checked::before {
  width: 36rpx;
  height: 36rpx;
  line-height: 36rpx;
  border-radius: 50%;
  text-align: center;
  font-size: 28rpx;
  color: #fff;
  background: transparent;
  transform: translate(-50%, -50%) scale(1);
  -webkit-transform: translate(-50%, -50%) scale(1);
  background-color: #FF7159;
  border: 1rpx solid #FF7159;
}
radio .wx-radio-input{
   border-radius: 50%;/* 圆角 */
   width: 36rpx;
   height: 36rpx;
   margin-top: -4rpx;
   border: 1rpx solid #d1d1d1;
}
/* 选中后的 背景样式 (红色背景 无边框 可根据UI需求自己修改) */
radio .wx-radio-input.wx-radio-input-checked{
   border: 1rpx solid #FF7159;
   background: #FF7159;
}
/* 选中后的 对勾样式 (白色对勾 可根据UI需求自己修改) */
radio .wx-radio-input.wx-radio-input-checked::before{
   border-radius: 50%;/* 圆角 */
   width: 36rpx; /* 选中后对勾大小,不要超过背景的尺寸 */
   height: 36rpx; /* 选中后对勾大小,不要超过背景的尺寸 */
   line-height: 36rpx;
   text-align: center;
   font-size:28rpx; /* 对勾大小 30rpx */
   color:#fff; /* 对勾颜色 白色 */
   background: transparent;
   transform:translate(-50%, -50%) scale(1);
   -webkit-transform:translate(-50%, -50%) scale(1);
}

/*  #endif  */

.goods-bottom{
    z-index: 97;
}

.btn-small{
 padding: 0 10rpx;
  height: 36rpx;
  line-height: 32rpx;
  font-size: 24rpx;
  margin: 0 10rpx;
}

image

img

store

index.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const store = new Vuex.Store({
    state: {
        config: {}, // 店铺配置信息
        orderTab: 0, // 选中的订单tab页
        redirectPage: '',
        uuid:'',//当前客户端
        searchStyle: ''
    },
    mutations: {
        config (state, payload) {
            state.config = payload
        },
        orderTab (state, tab) {
            state.orderTab = tab
        },
        redirect (state, payload) {
            state.redirectPage = payload.page
        },
        searchStyle (state, style) {
            state.searchStyle = style
        }
    },
    actions: {

    },
    getters: {
        shopConfig: state => state.config,
        uuid: state    =>    state.uuid,
    }
})

export default store

uni.scss

/**
 * 这里是uni-app内置的常用样式变量
 *
 * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
 * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
 *
 */

/**
 * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
 *
 * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
 */

/* 颜色变量 */

/* 行为相关颜色 */
$uni-color-primary: #007aff;
$uni-color-success: #4cd964;
$uni-color-warning: #f0ad4e;
$uni-color-error: #dd524d;

/* 文字基本颜色 */
$uni-text-color:#333;//基本色
$uni-text-color-inverse:#fff;//反色
$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
$uni-text-color-placeholder: #808080;
$uni-text-color-disable:#c0c0c0;

/* 背景颜色 */
$uni-bg-color:#ffffff;
$uni-bg-color-grey:#f8f8f8;
$uni-bg-color-hover:#f1f1f1;//点击状态颜色
$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色

/* 边框颜色 */
$uni-border-color:#c8c7cc;

/* 尺寸变量 */

/* 文字尺寸 */
$uni-font-size-sm:24upx;
$uni-font-size-base:28upx;
$uni-font-size-lg:32upx;

/* 图片尺寸 */
$uni-img-size-sm:40upx;
$uni-img-size-base:52upx;
$uni-img-size-lg:80upx;

/* Border Radius */
$uni-border-radius-sm: 4upx;
$uni-border-radius-base: 6upx;
$uni-border-radius-lg: 12upx;
$uni-border-radius-circle: 50%;

/* 水平间距 */
$uni-spacing-row-sm: 10px;
$uni-spacing-row-base: 20upx;
$uni-spacing-row-lg: 30upx;

/* 垂直间距 */
$uni-spacing-col-sm: 8upx;
$uni-spacing-col-base: 16upx;
$uni-spacing-col-lg: 24upx;

/* 透明度 */
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度

/* 文章场景相关 */
$uni-color-title: #2C405A; // 文章标题颜色
$uni-font-size-title:40upx;
$uni-color-subtitle: #555555; // 二级标题颜色
$uni-font-size-subtitle:36upx;
$uni-color-paragraph: #3F536E; // 文章段落颜色
$uni-font-size-paragraph:30upx;

//自定义变量
$theme-color: #28b8a1;
$bg-grey: #f4f4f4;
$bd-color: #f0f0f0;
$color-light: #5e5e5e;
$g2: #eeeeee;
$g5: #9e9e9e;
$fz12: 24upx;
$fz16: 32upx;
$fz18: 36upx;
$fz20: 40upx;