连续复制
一键复制
一键打包
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(/∀/g, '∀');
str = str.replace(/∂/g, '∂');
str = str.replace(/∃/g, '∃');
str = str.replace(/∅/g, '∅');
str = str.replace(/∇/g, '∇');
str = str.replace(/∈/g, '∈');
str = str.replace(/∉/g, '∉');
str = str.replace(/∋/g, '∋');
str = str.replace(/∏/g, '∏');
str = str.replace(/∑/g, '∑');
str = str.replace(/−/g, '−');
str = str.replace(/∗/g, '∗');
str = str.replace(/√/g, '√');
str = str.replace(/∝/g, '∝');
str = str.replace(/∞/g, '∞');
str = str.replace(/∠/g, '∠');
str = str.replace(/∧/g, '∧');
str = str.replace(/∨/g, '∨');
str = str.replace(/∩/g, '∩');
str = str.replace(/∪/g, '∪');
str = str.replace(/∫/g, '∫');
str = str.replace(/∴/g, '∴');
str = str.replace(/∼/g, '∼');
str = str.replace(/≅/g, '≅');
str = str.replace(/≈/g, '≈');
str = str.replace(/≠/g, '≠');
str = str.replace(/≤/g, '≤');
str = str.replace(/≥/g, '≥');
str = str.replace(/⊂/g, '⊂');
str = str.replace(/⊃/g, '⊃');
str = str.replace(/⊄/g, '⊄');
str = str.replace(/⊆/g, '⊆');
str = str.replace(/⊇/g, '⊇');
str = str.replace(/⊕/g, '⊕');
str = str.replace(/⊗/g, '⊗');
str = str.replace(/⊥/g, '⊥');
str = str.replace(/⋅/g, '⋅');
return str;
}
// HTML 支持的希腊字母
function strGreeceDiscode(str) {
str = str.replace(/Α/g, 'Α');
str = str.replace(/Β/g, 'Β');
str = str.replace(/Γ/g, 'Γ');
str = str.replace(/Δ/g, 'Δ');
str = str.replace(/Ε/g, 'Ε');
str = str.replace(/Ζ/g, 'Ζ');
str = str.replace(/Η/g, 'Η');
str = str.replace(/Θ/g, 'Θ');
str = str.replace(/Ι/g, 'Ι');
str = str.replace(/Κ/g, 'Κ');
str = str.replace(/Λ/g, 'Λ');
str = str.replace(/Μ/g, 'Μ');
str = str.replace(/Ν/g, 'Ν');
str = str.replace(/Ξ/g, 'Ν');
str = str.replace(/Ο/g, 'Ο');
str = str.replace(/Π/g, 'Π');
str = str.replace(/Ρ/g, 'Ρ');
str = str.replace(/Σ/g, 'Σ');
str = str.replace(/Τ/g, 'Τ');
str = str.replace(/Υ/g, 'Υ');
str = str.replace(/Φ/g, 'Φ');
str = str.replace(/Χ/g, 'Χ');
str = str.replace(/Ψ/g, 'Ψ');
str = str.replace(/Ω/g, 'Ω');
str = str.replace(/α/g, 'α');
str = str.replace(/β/g, 'β');
str = str.replace(/γ/g, 'γ');
str = str.replace(/δ/g, 'δ');
str = str.replace(/ε/g, 'ε');
str = str.replace(/ζ/g, 'ζ');
str = str.replace(/η/g, 'η');
str = str.replace(/θ/g, 'θ');
str = str.replace(/ι/g, 'ι');
str = str.replace(/κ/g, 'κ');
str = str.replace(/λ/g, 'λ');
str = str.replace(/μ/g, 'μ');
str = str.replace(/ν/g, 'ν');
str = str.replace(/ξ/g, 'ξ');
str = str.replace(/ο/g, 'ο');
str = str.replace(/π/g, 'π');
str = str.replace(/ρ/g, 'ρ');
str = str.replace(/ς/g, 'ς');
str = str.replace(/σ/g, 'σ');
str = str.replace(/τ/g, 'τ');
str = str.replace(/υ/g, 'υ');
str = str.replace(/φ/g, 'φ');
str = str.replace(/χ/g, 'χ');
str = str.replace(/ψ/g, 'ψ');
str = str.replace(/ω/g, 'ω');
str = str.replace(/ϑ/g, 'ϑ');
str = str.replace(/ϒ/g, 'ϒ');
str = str.replace(/ϖ/g, 'ϖ');
str = str.replace(/·/g, '·');
return str;
}
function strcharacterDiscode(str) {
// 加入常用解析
str = str.replace(/ /g, ' ');
str = str.replace(/ /g, ' ');
str = str.replace(/ /g, ' ');
str = str.replace(/"/g, "'");
str = str.replace(/&/g, '&');
str = str.replace(/</g, '<');
str = str.replace(/>/g, '>');
str = str.replace(/•/g, '•');
return str;
}
// HTML 支持的其他实体
function strOtherDiscode(str) {
str = str.replace(/Œ/g, 'Œ');
str = str.replace(/œ/g, 'œ');
str = str.replace(/Š/g, 'Š');
str = str.replace(/š/g, 'š');
str = str.replace(/Ÿ/g, 'Ÿ');
str = str.replace(/ƒ/g, 'ƒ');
str = str.replace(/ˆ/g, 'ˆ');
str = str.replace(/˜/g, '˜');
str = str.replace(/ /g, '');
str = str.replace(/ /g, '');
str = str.replace(/ /g, '');
str = str.replace(/‌/g, '');
str = str.replace(/‍/g, '');
str = str.replace(/‎/g, '');
str = str.replace(/‏/g, '');
str = str.replace(/–/g, '–');
str = str.replace(/—/g, '—');
str = str.replace(/‘/g, '‘');
str = str.replace(/’/g, '’');
str = str.replace(/‚/g, '‚');
str = str.replace(/“/g, '“');
str = str.replace(/”/g, '”');
str = str.replace(/„/g, '„');
str = str.replace(/†/g, '†');
str = str.replace(/‡/g, '‡');
str = str.replace(/•/g, '•');
str = str.replace(/…/g, '…');
str = str.replace(/‰/g, '‰');
str = str.replace(/′/g, '′');
str = str.replace(/″/g, '″');
str = str.replace(/‹/g, '‹');
str = str.replace(/›/g, '›');
str = str.replace(/‾/g, '‾');
str = str.replace(/€/g, '€');
str = str.replace(/™/g, '™');
str = str.replace(/←/g, '←');
str = str.replace(/↑/g, '↑');
str = str.replace(/→/g, '→');
str = str.replace(/↓/g, '↓');
str = str.replace(/↔/g, '↔');
str = str.replace(/↵/g, '↵');
str = str.replace(/⌈/g, '⌈');
str = str.replace(/⌉/g, '⌉');
str = str.replace(/⌊/g, '⌊');
str = str.replace(/⌋/g, '⌋');
str = str.replace(/◊/g, '◊');
str = str.replace(/♠/g, '♠');
str = str.replace(/♣/g, '♣');
str = str.replace(/♥/g, '♥');
str = str.replace(/♦/g, '♦');
str = str.replace(/'/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.pix