init project
0 parents
Showing
107 changed files
with
6842 additions
and
0 deletions
.env.development
0 → 100644
| 1 | # just a flag | ||
| 2 | ENV = 'development' | ||
| 3 | |||
| 4 | # base api | ||
| 5 | # VUE_APP_BASE_API = 'http://192.168.11.94:8081' | ||
| 6 | # VUE_APP_BASE_API = 'http://192.168.252.25:8081' | ||
| 7 | VUE_APP_BASE_API = 'https://pre-web-chery.situdata.com' | ||
| 8 | |||
| 9 | VUE_APP_WEBRTC_URL = 'pre-jitsi-chery.situdata.com' | ||
| 10 | # VUE_APP_WEBRTC_URL = 'srtc.situdata.com' | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
.env.production
0 → 100644
.gitignore
0 → 100644
package-lock.json
0 → 100644
This diff could not be displayed because it is too large.
package.json
0 → 100644
| 1 | { | ||
| 2 | "name": "yunxiao-admin-fe", | ||
| 3 | "version": "0.1.0", | ||
| 4 | "private": true, | ||
| 5 | "scripts": { | ||
| 6 | "serve": "vue-cli-service serve --mode development", | ||
| 7 | "build": "vue-cli-service build", | ||
| 8 | "lint": "vue-cli-service lint", | ||
| 9 | "test:unit": "vue-cli-service test:unit", | ||
| 10 | "commit": "cz" | ||
| 11 | }, | ||
| 12 | "dependencies": { | ||
| 13 | "animate.css": "^4.1.0", | ||
| 14 | "axios": "^0.18.1", | ||
| 15 | "captcha-mini": "^1.1.0", | ||
| 16 | "core-js": "^2.6.11", | ||
| 17 | "echarts": "^4.8.0", | ||
| 18 | "element-ui": "^2.13.2", | ||
| 19 | "js-cookie": "^2.2.1", | ||
| 20 | "nprogress": "^0.2.0", | ||
| 21 | "pug": "^2.0.4", | ||
| 22 | "pug-plain-loader": "^1.0.0", | ||
| 23 | "uuid": "^8.3.0", | ||
| 24 | "v-charts": "^1.19.0", | ||
| 25 | "video.js": "^7.8.4", | ||
| 26 | "vue": "^2.6.10", | ||
| 27 | "vue-router": "^3.1.3", | ||
| 28 | "vue-simple-uploader": "^0.7.4", | ||
| 29 | "vuex": "^3.1.2" | ||
| 30 | }, | ||
| 31 | "devDependencies": { | ||
| 32 | "@vue/cli-plugin-babel": "^3.12.1", | ||
| 33 | "@vue/cli-plugin-eslint": "^3.12.1", | ||
| 34 | "@vue/cli-plugin-unit-mocha": "^3.12.1", | ||
| 35 | "@vue/cli-service": "^3.12.1", | ||
| 36 | "@vue/eslint-config-standard": "^4.0.0", | ||
| 37 | "@vue/test-utils": "1.0.0-beta.29", | ||
| 38 | "babel-eslint": "^10.0.3", | ||
| 39 | "chai": "^4.1.2", | ||
| 40 | "commitizen": "^4.2.0", | ||
| 41 | "cz-conventional-changelog": "^3.2.1", | ||
| 42 | "cz-emoji": "^1.2.2", | ||
| 43 | "eslint": "^5.16.0", | ||
| 44 | "eslint-plugin-vue": "^5.2.3", | ||
| 45 | "filemanager-webpack-plugin": "^2.0.5", | ||
| 46 | "node-sass": "^4.13.0", | ||
| 47 | "qr-image": "^3.2.0", | ||
| 48 | "sass-loader": "^7.3.1", | ||
| 49 | "svg-sprite-loader": "^4.3.0", | ||
| 50 | "vue-particles": "^1.0.9", | ||
| 51 | "vue-template-compiler": "^2.5.21" | ||
| 52 | }, | ||
| 53 | "eslintConfig": { | ||
| 54 | "root": true, | ||
| 55 | "env": { | ||
| 56 | "node": true | ||
| 57 | }, | ||
| 58 | "extends": [ | ||
| 59 | "plugin:vue/essential", | ||
| 60 | "@vue/standard" | ||
| 61 | ], | ||
| 62 | "parserOptions": { | ||
| 63 | "parser": "babel-eslint" | ||
| 64 | }, | ||
| 65 | "rules": { | ||
| 66 | "no-tabs": "off", | ||
| 67 | "space-before-function-paren": "off" | ||
| 68 | } | ||
| 69 | }, | ||
| 70 | "postcss": { | ||
| 71 | "plugins": { | ||
| 72 | "autoprefixer": {} | ||
| 73 | } | ||
| 74 | }, | ||
| 75 | "browserslist": [ | ||
| 76 | "> 1%", | ||
| 77 | "last 2 versions" | ||
| 78 | ], | ||
| 79 | "config": { | ||
| 80 | "cz-emoji": { | ||
| 81 | "types": [ | ||
| 82 | { | ||
| 83 | "emoji": "🌟", | ||
| 84 | "code": "🌟feat:", | ||
| 85 | "description": "A new feature", | ||
| 86 | "name": "feature" | ||
| 87 | }, | ||
| 88 | { | ||
| 89 | "emoji": "🐞", | ||
| 90 | "code": "🐞fix:", | ||
| 91 | "description": "A bug fix", | ||
| 92 | "name": "fix" | ||
| 93 | }, | ||
| 94 | { | ||
| 95 | "emoji": "📝", | ||
| 96 | "code": "📝docs:", | ||
| 97 | "description": "update docs", | ||
| 98 | "name": "docs" | ||
| 99 | }, | ||
| 100 | { | ||
| 101 | "emoji": "💰", | ||
| 102 | "code": "💰perf:", | ||
| 103 | "description": "Improves performance with this change", | ||
| 104 | "name": "perf" | ||
| 105 | }, | ||
| 106 | { | ||
| 107 | "emoji": "🎨", | ||
| 108 | "code": "🎨style:", | ||
| 109 | "description": "Doesn't affect the meaning of the code (white-space, semi-colons, etc)", | ||
| 110 | "name": "style" | ||
| 111 | }, | ||
| 112 | { | ||
| 113 | "emoji": "🚓", | ||
| 114 | "code": "🚓test:", | ||
| 115 | "description": "Testing improved with new or fixed tests", | ||
| 116 | "name": "test" | ||
| 117 | }, | ||
| 118 | { | ||
| 119 | "emoji": "🔨", | ||
| 120 | "code": "🔨build-conf:", | ||
| 121 | "description": "更新一些配置文件", | ||
| 122 | "name": "build-conf" | ||
| 123 | }, | ||
| 124 | { | ||
| 125 | "emoji": "💊", | ||
| 126 | "code": "💊revert:", | ||
| 127 | "description": "Reverts a previous commit", | ||
| 128 | "name": "revert" | ||
| 129 | } | ||
| 130 | ] | ||
| 131 | }, | ||
| 132 | "commitizen": { | ||
| 133 | "path": "./node_modules/cz-emoji" | ||
| 134 | } | ||
| 135 | } | ||
| 136 | } |
prettier.config.js
0 → 100644
| 1 | module.exports = { | ||
| 2 | // tab缩进大小,默认为2 | ||
| 3 | tabWidth: 2, | ||
| 4 | // 使用tab缩进,默认false | ||
| 5 | useTabs: false, | ||
| 6 | // 使用分号, 默认true | ||
| 7 | semi: false, | ||
| 8 | // 使用单引号, 默认false(在jsx中配置无效, 默认都是双引号) | ||
| 9 | singleQuote: true, | ||
| 10 | // 行尾逗号,默认none,可选 none|es5|all | ||
| 11 | // es5 包括es5中的数组、对象 | ||
| 12 | // all 包括函数对象等所有可选 | ||
| 13 | TrailingCooma: 'none', | ||
| 14 | // 对象中的空格 默认true | ||
| 15 | // true: { foo: bar } | ||
| 16 | // false: {foo: bar} | ||
| 17 | bracketSpacing: true, | ||
| 18 | // JSX标签闭合位置 默认false | ||
| 19 | // false: <div | ||
| 20 | // className="" | ||
| 21 | // style={{}} | ||
| 22 | // > | ||
| 23 | // true: <div | ||
| 24 | // className="" | ||
| 25 | // style={{}} > | ||
| 26 | jsxBracketSameLine: false, | ||
| 27 | // 箭头函数参数括号 默认avoid 可选 avoid| always | ||
| 28 | // avoid 能省略括号的时候就省略 例如x => x | ||
| 29 | // always 总是有括号 | ||
| 30 | arrowParens: 'avoid' | ||
| 31 | } |
public/favicon.ico
0 → 100644
No preview for this file type
public/index.html
0 → 100644
| 1 | <!DOCTYPE html> | ||
| 2 | <html lang="en"> | ||
| 3 | <head> | ||
| 4 | <meta charset="utf-8" /> | ||
| 5 | <meta http-equiv="X-UA-Compatible" content="IE=edge" /> | ||
| 6 | <meta name="viewport" content="width=device-width,initial-scale=1.0" /> | ||
| 7 | <link rel="icon" href="<%= BASE_URL %>favicon.ico" /> | ||
| 8 | <title>云销</title> | ||
| 9 | <!-- strophe删除待定 --> | ||
| 10 | <!-- <script src="./libs/strophe/strophe.js"></script> | ||
| 11 | <script src="./libs/strophe/strophe.disco.min.js?v=1"></script> | ||
| 12 | |||
| 13 | <script src="./libs/jquery-2.1.1.min.js"></script> | ||
| 14 | <script src="./libs/lib-jitsi-meet.min.js"></script> --> | ||
| 15 | </head> | ||
| 16 | <body> | ||
| 17 | <noscript> | ||
| 18 | <strong | ||
| 19 | >We're sorry but smartimageplatform doesn't work properly without | ||
| 20 | JavaScript enabled. Please enable it to continue.</strong | ||
| 21 | > | ||
| 22 | </noscript> | ||
| 23 | <div id="app"></div> | ||
| 24 | <!-- built files will be auto injected --> | ||
| 25 | </body> | ||
| 26 | </html> |
public/libs/jquery-2.1.1.js
0 → 100644
This diff could not be displayed because it is too large.
public/libs/jquery-2.1.1.min.js
0 → 100644
| 1 | /*! jQuery v2.1.1 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ | ||
| 2 | !function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l=a.document,m="2.1.1",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!n.isArray(a)&&a-parseFloat(a)>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=l.createElement("script"),b.text=a,l.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:k}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+-new Date,v=a.document,w=0,x=0,y=gb(),z=gb(),A=gb(),B=function(a,b){return a===b&&(l=!0),0},C="undefined",D=1<<31,E={}.hasOwnProperty,F=[],G=F.pop,H=F.push,I=F.push,J=F.slice,K=F.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},L="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",N="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=N.replace("w","w#"),P="\\["+M+"*("+N+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+O+"))|)"+M+"*\\]",Q=":("+N+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+P+")*)|.*)\\)|)",R=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),S=new RegExp("^"+M+"*,"+M+"*"),T=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),V=new RegExp(Q),W=new RegExp("^"+O+"$"),X={ID:new RegExp("^#("+N+")"),CLASS:new RegExp("^\\.("+N+")"),TAG:new RegExp("^("+N.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+Q),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+L+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),db=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{I.apply(F=J.call(v.childNodes),v.childNodes),F[v.childNodes.length].nodeType}catch(eb){I={apply:F.length?function(a,b){H.apply(a,J.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],!a||"string"!=typeof a)return d;if(1!==(k=b.nodeType)&&9!==k)return[];if(p&&!e){if(f=_.exec(a))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return I.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return I.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=9===k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+qb(o[l]);w=ab.test(a)&&ob(b.parentNode)||b,x=o.join(",")}if(x)try{return I.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function gb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function hb(a){return a[u]=!0,a}function ib(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function jb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function kb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||D)-(~a.sourceIndex||D);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function lb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function nb(a){return hb(function(b){return b=+b,hb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function ob(a){return a&&typeof a.getElementsByTagName!==C&&a}c=fb.support={},f=fb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fb.setDocument=function(a){var b,e=a?a.ownerDocument||a:v,g=e.defaultView;return e!==n&&9===e.nodeType&&e.documentElement?(n=e,o=e.documentElement,p=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){m()},!1):g.attachEvent&&g.attachEvent("onunload",function(){m()})),c.attributes=ib(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ib(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(e.getElementsByClassName)&&ib(function(a){return a.innerHTML="<div class='a'></div><div class='a i'></div>",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=ib(function(a){return o.appendChild(a).id=u,!e.getElementsByName||!e.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==C&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c=typeof a.getAttributeNode!==C&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==C?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==C&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(e.querySelectorAll))&&(ib(function(a){a.innerHTML="<select msallowclip=''><option selected=''></option></select>",a.querySelectorAll("[msallowclip^='']").length&&q.push("[*^$]="+M+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+M+"*(?:value|"+L+")"),a.querySelectorAll(":checked").length||q.push(":checked")}),ib(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+M+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ib(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",Q)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===v&&t(v,a)?-1:b===e||b.ownerDocument===v&&t(v,b)?1:k?K.call(k,a)-K.call(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],i=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:k?K.call(k,a)-K.call(k,b):0;if(f===g)return kb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?kb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},e):n},fb.matches=function(a,b){return fb(a,null,null,b)},fb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fb(b,n,null,[a]).length>0},fb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&E.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fb.selectors={cacheLength:50,createPseudo:hb,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+M+")"+a+"("+M+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==C&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?hb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=K.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:hb(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?hb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:hb(function(a){return function(b){return fb(a,b).length>0}}),contains:hb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:hb(function(a){return W.test(a||"")||fb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:nb(function(){return[0]}),last:nb(function(a,b){return[b-1]}),eq:nb(function(a,b,c){return[0>c?c+b:c]}),even:nb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:nb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:nb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:nb(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=lb(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=mb(b);function pb(){}pb.prototype=d.filters=d.pseudos,d.setFilters=new pb,g=fb.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=S.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=T.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(R," ")}),h=h.slice(c.length));for(g in d.filter)!(e=X[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?fb.error(a):z(a,i).slice(0)};function qb(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function rb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function sb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function tb(a,b,c){for(var d=0,e=b.length;e>d;d++)fb(a,b[d],c);return c}function ub(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function vb(a,b,c,d,e,f){return d&&!d[u]&&(d=vb(d)),e&&!e[u]&&(e=vb(e,f)),hb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||tb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ub(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ub(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?K.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ub(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):I.apply(g,r)})}function wb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=rb(function(a){return a===b},h,!0),l=rb(function(a){return K.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>i;i++)if(c=d.relative[a[i].type])m=[rb(sb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return vb(i>1&&sb(m),i>1&&qb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&wb(a.slice(i,e)),f>e&&wb(a=a.slice(e)),f>e&&qb(a))}m.push(c)}return sb(m)}function xb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=G.call(i));s=ub(s)}I.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&fb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?hb(f):f}return h=fb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xb(e,d)),f.selector=a}return f},i=fb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&ob(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qb(j),!a)return I.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&ob(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ib(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ib(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||jb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ib(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||jb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ib(function(a){return null==a.getAttribute("disabled")})||jb(L,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fb}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return g.call(b,a)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:l,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(n(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler("ready"),n(l).off("ready"))))}});function I(){l.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),"complete"===l.readyState?setTimeout(n.ready):(l.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},n.ready.promise();var J=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+Math.random()}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b) | ||
| 3 | },_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:n.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=L.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var Q=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,R=["Top","Right","Bottom","Left"],S=function(a,b){return a=b||a,"none"===n.css(a,"display")||!n.contains(a.ownerDocument,a)},T=/^(?:checkbox|radio)$/i;!function(){var a=l.createDocumentFragment(),b=a.appendChild(l.createElement("div")),c=l.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";k.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button;return null==a.pageX&&null!=b.clientX&&(c=a.target.ownerDocument||l,d=c.documentElement,e=c.body,a.pageX=b.clientX+(d&&d.scrollLeft||e&&e.scrollLeft||0)-(d&&d.clientLeft||e&&e.clientLeft||0),a.pageY=b.clientY+(d&&d.scrollTop||e&&e.scrollTop||0)-(d&&d.clientTop||e&&e.clientTop||0)),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},fix:function(a){if(a[n.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=W.test(e)?this.mouseHooks:V.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new n.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=l),3===a.target.nodeType&&(a.target=a.target.parentNode),g.filter?g.filter(a,f):a},special:{load:{noBubble:!0},focus:{trigger:function(){return this!==_()&&this.focus?(this.focus(),!1):void 0},delegateType:"focusin"},blur:{trigger:function(){return this===_()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return"checkbox"===this.type&&this.click&&n.nodeName(this,"input")?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=n.extend(new n.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?n.event.trigger(e,null,b):n.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},n.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)},n.Event=function(a,b){return this instanceof n.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?Z:$):this.type=a,b&&n.extend(this,b),this.timeStamp=a&&a.timeStamp||n.now(),void(this[n.expando]=!0)):new n.Event(a,b)},n.Event.prototype={isDefaultPrevented:$,isPropagationStopped:$,isImmediatePropagationStopped:$,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=Z,a&&a.preventDefault&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=Z,a&&a.stopPropagation&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=Z,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},n.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){n.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!n.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),k.focusinBubbles||n.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){n.event.simulate(b,a.target,n.event.fix(a),!0)};n.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=L.access(d,b);e||d.addEventListener(a,c,!0),L.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=L.access(d,b)-1;e?L.access(d,b,e):(d.removeEventListener(a,c,!0),L.remove(d,b))}}}),n.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(g in a)this.on(g,b,c,a[g],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=$;else if(!d)return this;return 1===e&&(f=d,d=function(a){return n().off(a),f.apply(this,arguments)},d.guid=f.guid||(f.guid=n.guid++)),this.each(function(){n.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,n(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=$),this.each(function(){n.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){n.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?n.event.trigger(a,b,c,!0):void 0}});var ab=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bb=/<([\w:]+)/,cb=/<|&#?\w+;/,db=/<(?:script|style|link)/i,eb=/checked\s*(?:[^=]|=\s*.checked.)/i,fb=/^$|\/(?:java|ecma)script/i,gb=/^true\/(.*)/,hb=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,ib={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ib.optgroup=ib.option,ib.tbody=ib.tfoot=ib.colgroup=ib.caption=ib.thead,ib.th=ib.td;function jb(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function kb(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function lb(a){var b=gb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function mb(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function nb(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function ob(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pb(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=ob(h),f=ob(a),d=0,e=f.length;e>d;d++)pb(f[d],g[d]);if(b)if(c)for(f=f||ob(a),g=g||ob(h),d=0,e=f.length;e>d;d++)nb(f[d],g[d]);else nb(a,h);return g=ob(h,"script"),g.length>0&&mb(g,!i&&ob(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if("object"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(cb.test(e)){f=f||k.appendChild(b.createElement("div")),g=(bb.exec(e)||["",""])[1].toLowerCase(),h=ib[g]||ib._default,f.innerHTML=h[1]+e.replace(ab,"<$1></$2>")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=ob(k.appendChild(e),"script"),i&&mb(f),c)){j=0;while(e=f[j++])fb.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(ob(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&mb(ob(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(ob(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!db.test(a)&&!ib[(bb.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(ab,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ob(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(ob(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&eb.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(ob(c,"script"),kb),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,ob(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,lb),j=0;g>j;j++)h=f[j],fb.test(h.type||"")&&!L.access(h,"globalEval")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(hb,"")))}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qb,rb={};function sb(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],"display");return e.detach(),f}function tb(a){var b=l,c=rb[a];return c||(c=sb(a,b),"none"!==c&&c||(qb=(qb||n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=qb[0].contentDocument,b.write(),b.close(),c=sb(a,b),qb.detach()),rb[a]=c),c}var ub=/^margin/,vb=new RegExp("^("+Q+")(?!px)[a-z%]+$","i"),wb=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)};function xb(a,b,c){var d,e,f,g,h=a.style;return c=c||wb(a),c&&(g=c.getPropertyValue(b)||c[b]),c&&(""!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),vb.test(g)&&ub.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function yb(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d=l.documentElement,e=l.createElement("div"),f=l.createElement("div");if(f.style){f.style.backgroundClip="content-box",f.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===f.style.backgroundClip,e.style.cssText="border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;position:absolute",e.appendChild(f);function g(){f.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",f.innerHTML="",d.appendChild(e);var g=a.getComputedStyle(f,null);b="1%"!==g.top,c="4px"===g.width,d.removeChild(e)}a.getComputedStyle&&n.extend(k,{pixelPosition:function(){return g(),b},boxSizingReliable:function(){return null==c&&g(),c},reliableMarginRight:function(){var b,c=f.appendChild(l.createElement("div"));return c.style.cssText=f.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",c.style.marginRight=c.style.width="0",f.style.width="1px",d.appendChild(e),b=!parseFloat(a.getComputedStyle(c,null).marginRight),d.removeChild(e),b}})}}(),n.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var zb=/^(none|table(?!-c[ea]).+)/,Ab=new RegExp("^("+Q+")(.*)$","i"),Bb=new RegExp("^([+-])=("+Q+")","i"),Cb={position:"absolute",visibility:"hidden",display:"block"},Db={letterSpacing:"0",fontWeight:"400"},Eb=["Webkit","O","Moz","ms"];function Fb(a,b){if(b in a)return b;var c=b[0].toUpperCase()+b.slice(1),d=b,e=Eb.length;while(e--)if(b=Eb[e]+c,b in a)return b;return d}function Gb(a,b,c){var d=Ab.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Hb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=n.css(a,c+R[f],!0,e)),d?("content"===c&&(g-=n.css(a,"padding"+R[f],!0,e)),"margin"!==c&&(g-=n.css(a,"border"+R[f]+"Width",!0,e))):(g+=n.css(a,"padding"+R[f],!0,e),"padding"!==c&&(g+=n.css(a,"border"+R[f]+"Width",!0,e)));return g}function Ib(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=wb(a),g="border-box"===n.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=xb(a,b,f),(0>e||null==e)&&(e=a.style[b]),vb.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Hb(a,b,c||(g?"border":"content"),d,f)+"px"}function Jb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=L.get(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&S(d)&&(f[g]=L.access(d,"olddisplay",tb(d.nodeName)))):(e=S(d),"none"===c&&e||L.set(d,"olddisplay",e?c:n.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=xb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;return b=n.cssProps[h]||(n.cssProps[h]=Fb(i,h)),g=n.cssHooks[b]||n.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b]:(f=typeof c,"string"===f&&(e=Bb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(n.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||n.cssNumber[h]||(c+="px"),k.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=Fb(a.style,h)),g=n.cssHooks[b]||n.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=xb(a,b,d)),"normal"===e&&b in Db&&(e=Db[b]),""===c||c?(f=parseFloat(e),c===!0||n.isNumeric(f)?f||0:e):e}}),n.each(["height","width"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?zb.test(n.css(a,"display"))&&0===a.offsetWidth?n.swap(a,Cb,function(){return Ib(a,b,d)}):Ib(a,b,d):void 0},set:function(a,c,d){var e=d&&wb(a);return Gb(a,c,d?Hb(a,b,d,"border-box"===n.css(a,"boxSizing",!1,e),e):0)}}}),n.cssHooks.marginRight=yb(k.reliableMarginRight,function(a,b){return b?n.swap(a,{display:"inline-block"},xb,[a,"marginRight"]):void 0}),n.each({margin:"",padding:"",border:"Width"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+R[d]+b]=f[d]||f[d-2]||f[0];return e}},ub.test(a)||(n.cssHooks[a+b].set=Gb)}),n.fn.extend({css:function(a,b){return J(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=wb(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b)},a,b,arguments.length>1)},show:function(){return Jb(this,!0)},hide:function(){return Jb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){S(this)?n(this).show():n(this).hide()})}});function Kb(a,b,c,d,e){return new Kb.prototype.init(a,b,c,d,e)}n.Tween=Kb,Kb.prototype={constructor:Kb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?"":"px")},cur:function(){var a=Kb.propHooks[this.prop];return a&&a.get?a.get(this):Kb.propHooks._default.get(this)},run:function(a){var b,c=Kb.propHooks[this.prop];return this.pos=b=this.options.duration?n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Kb.propHooks._default.set(this),this}},Kb.prototype.init.prototype=Kb.prototype,Kb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=n.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[n.cssProps[a.prop]]||n.cssHooks[a.prop])?n.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Kb.propHooks.scrollTop=Kb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},n.fx=Kb.prototype.init,n.fx.step={};var Lb,Mb,Nb=/^(?:toggle|show|hide)$/,Ob=new RegExp("^(?:([+-])=|)("+Q+")([a-z%]*)$","i"),Pb=/queueHooks$/,Qb=[Vb],Rb={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=Ob.exec(b),f=e&&e[3]||(n.cssNumber[a]?"":"px"),g=(n.cssNumber[a]||"px"!==f&&+d)&&Ob.exec(n.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,n.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function Sb(){return setTimeout(function(){Lb=void 0}),Lb=n.now()}function Tb(a,b){var c,d=0,e={height:a};for(b=b?1:0;4>d;d+=2-b)c=R[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function Ub(a,b,c){for(var d,e=(Rb[b]||[]).concat(Rb["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function Vb(a,b,c){var d,e,f,g,h,i,j,k,l=this,m={},o=a.style,p=a.nodeType&&S(a),q=L.get(a,"fxshow");c.queue||(h=n._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,l.always(function(){l.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=n.css(a,"display"),k="none"===j?L.get(a,"olddisplay")||tb(a.nodeName):j,"inline"===k&&"none"===n.css(a,"float")&&(o.display="inline-block")),c.overflow&&(o.overflow="hidden",l.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],Nb.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}m[d]=q&&q[d]||n.style(a,d)}else j=void 0;if(n.isEmptyObject(m))"inline"===("none"===j?tb(a.nodeName):j)&&(o.display=j);else{q?"hidden"in q&&(p=q.hidden):q=L.access(a,"fxshow",{}),f&&(q.hidden=!p),p?n(a).show():l.done(function(){n(a).hide()}),l.done(function(){var b;L.remove(a,"fxshow");for(b in m)n.style(a,b,m[b])});for(d in m)g=Ub(p?q[d]:0,d,l),d in q||(q[d]=g.start,p&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function Wb(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function Xb(a,b,c){var d,e,f=0,g=Qb.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=Lb||Sb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:Lb||Sb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(Wb(k,j.opts.specialEasing);g>f;f++)if(d=Qb[f].call(j,a,k,j.opts))return d;return n.map(k,Ub,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}n.Animation=n.extend(Xb,{tweener:function(a,b){n.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],Rb[c]=Rb[c]||[],Rb[c].unshift(b)},prefilter:function(a,b){b?Qb.unshift(a):Qb.push(a)}}),n.speed=function(a,b,c){var d=a&&"object"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(S).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=Xb(this,n.extend({},a),f);(e||L.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=n.timers,g=L.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&Pb.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=L.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each(["toggle","show","hide"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(Tb(b,!0),a,d,e)}}),n.each({slideDown:Tb("show"),slideUp:Tb("hide"),slideToggle:Tb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=0,c=n.timers;for(Lb=n.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||n.fx.stop(),Lb=void 0},n.fx.timer=function(a){n.timers.push(a),a()?n.fx.start():n.timers.pop()},n.fx.interval=13,n.fx.start=function(){Mb||(Mb=setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){clearInterval(Mb),Mb=null},n.fx.speeds={slow:600,fast:200,_default:400},n.fn.delay=function(a,b){return a=n.fx?n.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a=l.createElement("input"),b=l.createElement("select"),c=b.appendChild(l.createElement("option"));a.type="checkbox",k.checkOn=""!==a.value,k.optSelected=c.selected,b.disabled=!0,k.optDisabled=!c.disabled,a=l.createElement("input"),a.value="t",a.type="radio",k.radioValue="t"===a.value}();var Yb,Zb,$b=n.expr.attrHandle;n.fn.extend({attr:function(a,b){return J(this,n.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===U?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),d=n.attrHooks[b]||(n.expr.match.bool.test(b)?Zb:Yb)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=n.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void n.removeAttr(a,b)) | ||
| 4 | },removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)&&(a[d]=!1),a.removeAttribute(c)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&n.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),Zb={set:function(a,b,c){return b===!1?n.removeAttr(a,c):a.setAttribute(c,c),c}},n.each(n.expr.match.bool.source.match(/\w+/g),function(a,b){var c=$b[b]||n.find.attr;$b[b]=function(a,b,d){var e,f;return d||(f=$b[b],$b[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,$b[b]=f),e}});var _b=/^(?:input|select|textarea|button)$/i;n.fn.extend({prop:function(a,b){return J(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[n.propFix[a]||a]})}}),n.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!n.isXMLDoc(a),f&&(b=n.propFix[b]||b,e=n.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){return a.hasAttribute("tabindex")||_b.test(a.nodeName)||a.href?a.tabIndex:-1}}}}),k.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null}}),n.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){n.propFix[this.toLowerCase()]=this});var ac=/[\t\r\n\f]/g;n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h="string"==typeof a&&a,i=0,j=this.length;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ac," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=n.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0===arguments.length||"string"==typeof a&&a,i=0,j=this.length;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ac," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?n.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(n.isFunction(a)?function(c){n(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=n(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===U||"boolean"===c)&&(this.className&&L.set(this,"__className__",this.className),this.className=this.className||a===!1?"":L.get(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(ac," ").indexOf(b)>=0)return!0;return!1}});var bc=/\r/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e="":"number"==typeof e?e+="":n.isArray(e)&&(e=n.map(e,function(a){return null==a?"":a+""})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(bc,""):null==c?"":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,"value");return null!=b?b:n.trim(n.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&n.nodeName(c.parentNode,"optgroup"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=n.inArray(d.value,f)>=0)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),n.each(["radio","checkbox"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>=0:void 0}},k.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})}),n.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var cc=n.now(),dc=/\?/;n.parseJSON=function(a){return JSON.parse(a+"")},n.parseXML=function(a){var b,c;if(!a||"string"!=typeof a)return null;try{c=new DOMParser,b=c.parseFromString(a,"text/xml")}catch(d){b=void 0}return(!b||b.getElementsByTagName("parsererror").length)&&n.error("Invalid XML: "+a),b};var ec,fc,gc=/#.*$/,hc=/([?&])_=[^&]*/,ic=/^(.*?):[ \t]*([^\r\n]*)$/gm,jc=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,kc=/^(?:GET|HEAD)$/,lc=/^\/\//,mc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,nc={},oc={},pc="*/".concat("*");try{fc=location.href}catch(qc){fc=l.createElement("a"),fc.href="",fc=fc.href}ec=mc.exec(fc.toLowerCase())||[];function rc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(n.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function sc(a,b,c,d){var e={},f=a===oc;function g(h){var i;return e[h]=!0,n.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function tc(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&n.extend(!0,a,d),a}function uc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function vc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:fc,type:"GET",isLocal:jc.test(ec[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":pc,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":n.parseJSON,"text xml":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?tc(tc(a,n.ajaxSettings),b):tc(n.ajaxSettings,a)},ajaxPrefilter:rc(nc),ajaxTransport:rc(oc),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=n.ajaxSetup({},b),l=k.context||k,m=k.context&&(l.nodeType||l.jquery)?n(l):n.event,o=n.Deferred(),p=n.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!f){f={};while(b=ic.exec(e))f[b[1].toLowerCase()]=b[2]}b=f[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?e:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return c&&c.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||fc)+"").replace(gc,"").replace(lc,ec[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=n.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(h=mc.exec(k.url.toLowerCase()),k.crossDomain=!(!h||h[1]===ec[1]&&h[2]===ec[2]&&(h[3]||("http:"===h[1]?"80":"443"))===(ec[3]||("http:"===ec[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=n.param(k.data,k.traditional)),sc(nc,k,b,v),2===t)return v;i=k.global,i&&0===n.active++&&n.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!kc.test(k.type),d=k.url,k.hasContent||(k.data&&(d=k.url+=(dc.test(d)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=hc.test(d)?d.replace(hc,"$1_="+cc++):d+(dc.test(d)?"&":"?")+"_="+cc++)),k.ifModified&&(n.lastModified[d]&&v.setRequestHeader("If-Modified-Since",n.lastModified[d]),n.etag[d]&&v.setRequestHeader("If-None-Match",n.etag[d])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+pc+"; q=0.01":""):k.accepts["*"]);for(j in k.headers)v.setRequestHeader(j,k.headers[j]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(j in{success:1,error:1,complete:1})v[j](k[j]);if(c=sc(oc,k,b,v)){v.readyState=1,i&&m.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,c.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,f,h){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),c=void 0,e=h||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,f&&(u=uc(k,v,f)),u=vc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(n.lastModified[d]=w),w=v.getResponseHeader("etag"),w&&(n.etag[d]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,i&&m.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),i&&(m.trigger("ajaxComplete",[v,k]),--n.active||n.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return n.get(a,b,c,"json")},getScript:function(a,b){return n.get(a,void 0,b,"script")}}),n.each(["get","post"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),n.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),n._evalUrl=function(a){return n.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},n.fn.extend({wrapAll:function(a){var b;return n.isFunction(a)?this.each(function(b){n(this).wrapAll(a.call(this,b))}):(this[0]&&(b=n(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this)},wrapInner:function(a){return this.each(n.isFunction(a)?function(b){n(this).wrapInner(a.call(this,b))}:function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,"body")||n(this).replaceWith(this.childNodes)}).end()}}),n.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0},n.expr.filters.visible=function(a){return!n.expr.filters.hidden(a)};var wc=/%20/g,xc=/\[\]$/,yc=/\r?\n/g,zc=/^(?:submit|button|image|reset|file)$/i,Ac=/^(?:input|select|textarea|keygen)/i;function Bc(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||xc.test(a)?d(a,e):Bc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==n.type(b))d(a,b);else for(e in b)Bc(a+"["+e+"]",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)Bc(c,a[c],b,e);return d.join("&").replace(wc,"+")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,"elements");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(":disabled")&&Ac.test(this.nodeName)&&!zc.test(a)&&(this.checked||!T.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(yc,"\r\n")}}):{name:b.name,value:c.replace(yc,"\r\n")}}).get()}}),n.ajaxSettings.xhr=function(){try{return new XMLHttpRequest}catch(a){}};var Cc=0,Dc={},Ec={0:200,1223:204},Fc=n.ajaxSettings.xhr();a.ActiveXObject&&n(a).on("unload",function(){for(var a in Dc)Dc[a]()}),k.cors=!!Fc&&"withCredentials"in Fc,k.ajax=Fc=!!Fc,n.ajaxTransport(function(a){var b;return k.cors||Fc&&!a.crossDomain?{send:function(c,d){var e,f=a.xhr(),g=++Cc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)f.setRequestHeader(e,c[e]);b=function(a){return function(){b&&(delete Dc[g],b=f.onload=f.onerror=null,"abort"===a?f.abort():"error"===a?d(f.status,f.statusText):d(Ec[f.status]||f.status,f.statusText,"string"==typeof f.responseText?{text:f.responseText}:void 0,f.getAllResponseHeaders()))}},f.onload=b(),f.onerror=b("error"),b=Dc[g]=b("abort");try{f.send(a.hasContent&&a.data||null)}catch(h){if(b)throw h}},abort:function(){b&&b()}}:void 0}),n.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return n.globalEval(a),a}}}),n.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),n.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(d,e){b=n("<script>").prop({async:!0,charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&e("error"===a.type?404:200,a.type)}),l.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Gc=[],Hc=/(=)\?(?=&|$)|\?\?/;n.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Gc.pop()||n.expando+"_"+cc++;return this[a]=!0,a}}),n.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Hc.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Hc.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=n.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Hc,"$1"+e):b.jsonp!==!1&&(b.url+=(dc.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||n.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Gc.push(e)),g&&n.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),n.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||l;var d=v.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=n.buildFragment([a],b,e),e&&e.length&&n(e).remove(),n.merge([],d.childNodes))};var Ic=n.fn.load;n.fn.load=function(a,b,c){if("string"!=typeof a&&Ic)return Ic.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=n.trim(a.slice(h)),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&n.ajax({url:a,type:e,dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?n("<div>").append(n.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,f||[a.responseText,b,a])}),this},n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};var Jc=a.document.documentElement;function Kc(a){return n.isWindow(a)?a:9===a.nodeType&&a.defaultView}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,"position"),l=n(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=n.css(a,"top"),i=n.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d=this[0],e={top:0,left:0},f=d&&d.ownerDocument;if(f)return b=f.documentElement,n.contains(b,d)?(typeof d.getBoundingClientRect!==U&&(e=d.getBoundingClientRect()),c=Kc(f),{top:e.top+c.pageYOffset-b.clientTop,left:e.left+c.pageXOffset-b.clientLeft}):e},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===n.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],"html")||(d=a.offset()),d.top+=n.css(a[0],"borderTopWidth",!0),d.left+=n.css(a[0],"borderLeftWidth",!0)),{top:b.top-d.top-n.css(c,"marginTop",!0),left:b.left-d.left-n.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||Jc;while(a&&!n.nodeName(a,"html")&&"static"===n.css(a,"position"))a=a.offsetParent;return a||Jc})}}),n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(b,c){var d="pageYOffset"===c;n.fn[b]=function(e){return J(this,function(b,e,f){var g=Kc(b);return void 0===f?g?g[c]:b[e]:void(g?g.scrollTo(d?a.pageXOffset:f,d?f:a.pageYOffset):b[e]=f)},b,e,arguments.length,null)}}),n.each(["top","left"],function(a,b){n.cssHooks[b]=yb(k.pixelPosition,function(a,c){return c?(c=xb(a,b),vb.test(c)?n(a).position()[b]+"px":c):void 0})}),n.each({Height:"height",Width:"width"},function(a,b){n.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return J(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.size=function(){return this.length},n.fn.andSelf=n.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return n});var Lc=a.jQuery,Mc=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=Mc),b&&a.jQuery===n&&(a.jQuery=Lc),n},typeof b===U&&(a.jQuery=a.$=n),n}); |
public/libs/lib-jitsi-meet.min.js
0 → 100644
This diff could not be displayed because it is too large.
public/libs/strophe/strophe.disco.min.js
0 → 100644
| 1 | Strophe.addConnectionPlugin("disco",{_connection:null,_identities:[],_features:[],_items:[],init:function(conn){this._connection=conn;this._identities=[];this._features=[];this._items=[];conn.addHandler(this._onDiscoInfo.bind(this),Strophe.NS.DISCO_INFO,"iq","get",null,null);conn.addHandler(this._onDiscoItems.bind(this),Strophe.NS.DISCO_ITEMS,"iq","get",null,null)},addIdentity:function(category,type,name,lang){for(var i=0;i<this._identities.length;i++){if(this._identities[i].category==category&&this._identities[i].type==type&&this._identities[i].name==name&&this._identities[i].lang==lang){return false}}this._identities.push({category:category,type:type,name:name,lang:lang});return true},addFeature:function(var_name){for(var i=0;i<this._features.length;i++){if(this._features[i]==var_name){return false}}this._features.push(var_name);return true},removeFeature:function(var_name){for(var i=0;i<this._features.length;i++){if(this._features[i]===var_name){this._features.splice(i,1);return true}}return false},addItem:function(jid,name,node,call_back){if(node&&!call_back){return false}this._items.push({jid:jid,name:name,node:node,call_back:call_back});return true},info:function(jid,node,success,error,timeout){var attrs={xmlns:Strophe.NS.DISCO_INFO};if(node){attrs.node=node}var info=$iq({from:this._connection.jid,to:jid,type:"get"}).c("query",attrs);this._connection.sendIQ(info,success,error,timeout)},items:function(jid,node,success,error,timeout){var attrs={xmlns:Strophe.NS.DISCO_ITEMS};if(node){attrs.node=node}var items=$iq({from:this._connection.jid,to:jid,type:"get"}).c("query",attrs);this._connection.sendIQ(items,success,error,timeout)},_buildIQResult:function(stanza,query_attrs){var id=stanza.getAttribute("id");var from=stanza.getAttribute("from");var iqresult=$iq({type:"result",id:id});if(from!==null){iqresult.attrs({to:from})}return iqresult.c("query",query_attrs)},_onDiscoInfo:function(stanza){var node=stanza.getElementsByTagName("query")[0].getAttribute("node");var attrs={xmlns:Strophe.NS.DISCO_INFO};if(node){attrs.node=node}var iqresult=this._buildIQResult(stanza,attrs);for(var i=0;i<this._identities.length;i++){var attrs={category:this._identities[i].category,type:this._identities[i].type};if(this._identities[i].name){attrs.name=this._identities[i].name}if(this._identities[i].lang){attrs["xml:lang"]=this._identities[i].lang}iqresult.c("identity",attrs).up()}for(var i=0;i<this._features.length;i++){iqresult.c("feature",{"var":this._features[i]}).up()}this._connection.send(iqresult.tree());return true},_onDiscoItems:function(stanza){var query_attrs={xmlns:Strophe.NS.DISCO_ITEMS};var node=stanza.getElementsByTagName("query")[0].getAttribute("node");if(node){query_attrs.node=node;var items=[];for(var i=0;i<this._items.length;i++){if(this._items[i].node==node){items=this._items[i].call_back(stanza);break}}}else{var items=this._items}var iqresult=this._buildIQResult(stanza,query_attrs);for(var i=0;i<items.length;i++){var attrs={jid:items[i].jid};if(items[i].name){attrs.name=items[i].name}if(items[i].node){attrs.node=items[i].node}iqresult.c("item",attrs).up()}this._connection.send(iqresult.tree());return true}}); | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
public/libs/strophe/strophe.js
0 → 100644
This diff could not be displayed because it is too large.
public/libs/strophe/strophe.min.js
0 → 100644
| 1 | /*! strophe.js v1.2.2 - built on 20-06-2015 */ | ||
| 2 | !function(a){return function(a,b){"function"==typeof define&&define.amd?define("strophe-base64",function(){return b()}):a.Base64=b()}(this,function(){var a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",b={encode:function(b){var c,d,e,f,g,h,i,j="",k=0;do c=b.charCodeAt(k++),d=b.charCodeAt(k++),e=b.charCodeAt(k++),f=c>>2,g=(3&c)<<4|d>>4,h=(15&d)<<2|e>>6,i=63&e,isNaN(d)?(g=(3&c)<<4,h=i=64):isNaN(e)&&(i=64),j=j+a.charAt(f)+a.charAt(g)+a.charAt(h)+a.charAt(i);while(k<b.length);return j},decode:function(b){var c,d,e,f,g,h,i,j="",k=0;b=b.replace(/[^A-Za-z0-9\+\/\=]/g,"");do f=a.indexOf(b.charAt(k++)),g=a.indexOf(b.charAt(k++)),h=a.indexOf(b.charAt(k++)),i=a.indexOf(b.charAt(k++)),c=f<<2|g>>4,d=(15&g)<<4|h>>2,e=(3&h)<<6|i,j+=String.fromCharCode(c),64!=h&&(j+=String.fromCharCode(d)),64!=i&&(j+=String.fromCharCode(e));while(k<b.length);return j}};return b}),function(a,b){"function"==typeof define&&define.amd?define("strophe-sha1",function(){return b()}):a.SHA1=b()}(this,function(){function a(a,d){a[d>>5]|=128<<24-d%32,a[(d+64>>9<<4)+15]=d;var g,h,i,j,k,l,m,n,o=new Array(80),p=1732584193,q=-271733879,r=-1732584194,s=271733878,t=-1009589776;for(g=0;g<a.length;g+=16){for(j=p,k=q,l=r,m=s,n=t,h=0;80>h;h++)16>h?o[h]=a[g+h]:o[h]=f(o[h-3]^o[h-8]^o[h-14]^o[h-16],1),i=e(e(f(p,5),b(h,q,r,s)),e(e(t,o[h]),c(h))),t=s,s=r,r=f(q,30),q=p,p=i;p=e(p,j),q=e(q,k),r=e(r,l),s=e(s,m),t=e(t,n)}return[p,q,r,s,t]}function b(a,b,c,d){return 20>a?b&c|~b&d:40>a?b^c^d:60>a?b&c|b&d|c&d:b^c^d}function c(a){return 20>a?1518500249:40>a?1859775393:60>a?-1894007588:-899497514}function d(b,c){var d=g(b);d.length>16&&(d=a(d,8*b.length));for(var e=new Array(16),f=new Array(16),h=0;16>h;h++)e[h]=909522486^d[h],f[h]=1549556828^d[h];var i=a(e.concat(g(c)),512+8*c.length);return a(f.concat(i),672)}function e(a,b){var c=(65535&a)+(65535&b),d=(a>>16)+(b>>16)+(c>>16);return d<<16|65535&c}function f(a,b){return a<<b|a>>>32-b}function g(a){for(var b=[],c=255,d=0;d<8*a.length;d+=8)b[d>>5]|=(a.charCodeAt(d/8)&c)<<24-d%32;return b}function h(a){for(var b="",c=255,d=0;d<32*a.length;d+=8)b+=String.fromCharCode(a[d>>5]>>>24-d%32&c);return b}function i(a){for(var b,c,d="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",e="",f=0;f<4*a.length;f+=3)for(b=(a[f>>2]>>8*(3-f%4)&255)<<16|(a[f+1>>2]>>8*(3-(f+1)%4)&255)<<8|a[f+2>>2]>>8*(3-(f+2)%4)&255,c=0;4>c;c++)e+=8*f+6*c>32*a.length?"=":d.charAt(b>>6*(3-c)&63);return e}return{b64_hmac_sha1:function(a,b){return i(d(a,b))},b64_sha1:function(b){return i(a(g(b),8*b.length))},binb2str:h,core_hmac_sha1:d,str_hmac_sha1:function(a,b){return h(d(a,b))},str_sha1:function(b){return h(a(g(b),8*b.length))}}}),function(a,b){"function"==typeof define&&define.amd?define("strophe-md5",function(){return b()}):a.MD5=b()}(this,function(a){var b=function(a,b){var c=(65535&a)+(65535&b),d=(a>>16)+(b>>16)+(c>>16);return d<<16|65535&c},c=function(a,b){return a<<b|a>>>32-b},d=function(a){for(var b=[],c=0;c<8*a.length;c+=8)b[c>>5]|=(255&a.charCodeAt(c/8))<<c%32;return b},e=function(a){for(var b="",c=0;c<32*a.length;c+=8)b+=String.fromCharCode(a[c>>5]>>>c%32&255);return b},f=function(a){for(var b="0123456789abcdef",c="",d=0;d<4*a.length;d++)c+=b.charAt(a[d>>2]>>d%4*8+4&15)+b.charAt(a[d>>2]>>d%4*8&15);return c},g=function(a,d,e,f,g,h){return b(c(b(b(d,a),b(f,h)),g),e)},h=function(a,b,c,d,e,f,h){return g(b&c|~b&d,a,b,e,f,h)},i=function(a,b,c,d,e,f,h){return g(b&d|c&~d,a,b,e,f,h)},j=function(a,b,c,d,e,f,h){return g(b^c^d,a,b,e,f,h)},k=function(a,b,c,d,e,f,h){return g(c^(b|~d),a,b,e,f,h)},l=function(a,c){a[c>>5]|=128<<c%32,a[(c+64>>>9<<4)+14]=c;for(var d,e,f,g,l=1732584193,m=-271733879,n=-1732584194,o=271733878,p=0;p<a.length;p+=16)d=l,e=m,f=n,g=o,l=h(l,m,n,o,a[p+0],7,-680876936),o=h(o,l,m,n,a[p+1],12,-389564586),n=h(n,o,l,m,a[p+2],17,606105819),m=h(m,n,o,l,a[p+3],22,-1044525330),l=h(l,m,n,o,a[p+4],7,-176418897),o=h(o,l,m,n,a[p+5],12,1200080426),n=h(n,o,l,m,a[p+6],17,-1473231341),m=h(m,n,o,l,a[p+7],22,-45705983),l=h(l,m,n,o,a[p+8],7,1770035416),o=h(o,l,m,n,a[p+9],12,-1958414417),n=h(n,o,l,m,a[p+10],17,-42063),m=h(m,n,o,l,a[p+11],22,-1990404162),l=h(l,m,n,o,a[p+12],7,1804603682),o=h(o,l,m,n,a[p+13],12,-40341101),n=h(n,o,l,m,a[p+14],17,-1502002290),m=h(m,n,o,l,a[p+15],22,1236535329),l=i(l,m,n,o,a[p+1],5,-165796510),o=i(o,l,m,n,a[p+6],9,-1069501632),n=i(n,o,l,m,a[p+11],14,643717713),m=i(m,n,o,l,a[p+0],20,-373897302),l=i(l,m,n,o,a[p+5],5,-701558691),o=i(o,l,m,n,a[p+10],9,38016083),n=i(n,o,l,m,a[p+15],14,-660478335),m=i(m,n,o,l,a[p+4],20,-405537848),l=i(l,m,n,o,a[p+9],5,568446438),o=i(o,l,m,n,a[p+14],9,-1019803690),n=i(n,o,l,m,a[p+3],14,-187363961),m=i(m,n,o,l,a[p+8],20,1163531501),l=i(l,m,n,o,a[p+13],5,-1444681467),o=i(o,l,m,n,a[p+2],9,-51403784),n=i(n,o,l,m,a[p+7],14,1735328473),m=i(m,n,o,l,a[p+12],20,-1926607734),l=j(l,m,n,o,a[p+5],4,-378558),o=j(o,l,m,n,a[p+8],11,-2022574463),n=j(n,o,l,m,a[p+11],16,1839030562),m=j(m,n,o,l,a[p+14],23,-35309556),l=j(l,m,n,o,a[p+1],4,-1530992060),o=j(o,l,m,n,a[p+4],11,1272893353),n=j(n,o,l,m,a[p+7],16,-155497632),m=j(m,n,o,l,a[p+10],23,-1094730640),l=j(l,m,n,o,a[p+13],4,681279174),o=j(o,l,m,n,a[p+0],11,-358537222),n=j(n,o,l,m,a[p+3],16,-722521979),m=j(m,n,o,l,a[p+6],23,76029189),l=j(l,m,n,o,a[p+9],4,-640364487),o=j(o,l,m,n,a[p+12],11,-421815835),n=j(n,o,l,m,a[p+15],16,530742520),m=j(m,n,o,l,a[p+2],23,-995338651),l=k(l,m,n,o,a[p+0],6,-198630844),o=k(o,l,m,n,a[p+7],10,1126891415),n=k(n,o,l,m,a[p+14],15,-1416354905),m=k(m,n,o,l,a[p+5],21,-57434055),l=k(l,m,n,o,a[p+12],6,1700485571),o=k(o,l,m,n,a[p+3],10,-1894986606),n=k(n,o,l,m,a[p+10],15,-1051523),m=k(m,n,o,l,a[p+1],21,-2054922799),l=k(l,m,n,o,a[p+8],6,1873313359),o=k(o,l,m,n,a[p+15],10,-30611744),n=k(n,o,l,m,a[p+6],15,-1560198380),m=k(m,n,o,l,a[p+13],21,1309151649),l=k(l,m,n,o,a[p+4],6,-145523070),o=k(o,l,m,n,a[p+11],10,-1120210379),n=k(n,o,l,m,a[p+2],15,718787259),m=k(m,n,o,l,a[p+9],21,-343485551),l=b(l,d),m=b(m,e),n=b(n,f),o=b(o,g);return[l,m,n,o]},m={hexdigest:function(a){return f(l(d(a),8*a.length))},hash:function(a){return e(l(d(a),8*a.length))}};return m}),Function.prototype.bind||(Function.prototype.bind=function(a){var b=this,c=Array.prototype.slice,d=Array.prototype.concat,e=c.call(arguments,1);return function(){return b.apply(a?a:this,d.call(e,c.call(arguments,0)))}}),Array.isArray||(Array.isArray=function(a){return"[object Array]"===Object.prototype.toString.call(a)}),Array.prototype.indexOf||(Array.prototype.indexOf=function(a){var b=this.length,c=Number(arguments[1])||0;for(c=0>c?Math.ceil(c):Math.floor(c),0>c&&(c+=b);b>c;c++)if(c in this&&this[c]===a)return c;return-1}),function(a,b){if("function"==typeof define&&define.amd)define("strophe-core",["strophe-sha1","strophe-base64","strophe-md5","strophe-polyfill"],function(){return b.apply(this,arguments)});else{var c=b(a.SHA1,a.Base64,a.MD5);window.Strophe=c.Strophe,window.$build=c.$build,window.$iq=c.$iq,window.$msg=c.$msg,window.$pres=c.$pres,window.SHA1=c.SHA1,window.Base64=c.Base64,window.MD5=c.MD5,window.b64_hmac_sha1=c.SHA1.b64_hmac_sha1,window.b64_sha1=c.SHA1.b64_sha1,window.str_hmac_sha1=c.SHA1.str_hmac_sha1,window.str_sha1=c.SHA1.str_sha1}}(this,function(a,b,c){function d(a,b){return new h.Builder(a,b)}function e(a){return new h.Builder("message",a)}function f(a){return new h.Builder("iq",a)}function g(a){return new h.Builder("presence",a)}var h;return h={VERSION:"1.2.2",NS:{HTTPBIND:"http://jabber.org/protocol/httpbind",BOSH:"urn:xmpp:xbosh",CLIENT:"jabber:client",AUTH:"jabber:iq:auth",ROSTER:"jabber:iq:roster",PROFILE:"jabber:iq:profile",DISCO_INFO:"http://jabber.org/protocol/disco#info",DISCO_ITEMS:"http://jabber.org/protocol/disco#items",MUC:"http://jabber.org/protocol/muc",SASL:"urn:ietf:params:xml:ns:xmpp-sasl",STREAM:"http://etherx.jabber.org/streams",FRAMING:"urn:ietf:params:xml:ns:xmpp-framing",BIND:"urn:ietf:params:xml:ns:xmpp-bind",SESSION:"urn:ietf:params:xml:ns:xmpp-session",VERSION:"jabber:iq:version",STANZAS:"urn:ietf:params:xml:ns:xmpp-stanzas",XHTML_IM:"http://jabber.org/protocol/xhtml-im",XHTML:"http://www.w3.org/1999/xhtml"},XHTML:{tags:["a","blockquote","br","cite","em","img","li","ol","p","span","strong","ul","body"],attributes:{a:["href"],blockquote:["style"],br:[],cite:["style"],em:[],img:["src","alt","style","height","width"],li:["style"],ol:["style"],p:["style"],span:["style"],strong:[],ul:["style"],body:[]},css:["background-color","color","font-family","font-size","font-style","font-weight","margin-left","margin-right","text-align","text-decoration"],validTag:function(a){for(var b=0;b<h.XHTML.tags.length;b++)if(a==h.XHTML.tags[b])return!0;return!1},validAttribute:function(a,b){if("undefined"!=typeof h.XHTML.attributes[a]&&h.XHTML.attributes[a].length>0)for(var c=0;c<h.XHTML.attributes[a].length;c++)if(b==h.XHTML.attributes[a][c])return!0;return!1},validCSS:function(a){for(var b=0;b<h.XHTML.css.length;b++)if(a==h.XHTML.css[b])return!0;return!1}},Status:{ERROR:0,CONNECTING:1,CONNFAIL:2,AUTHENTICATING:3,AUTHFAIL:4,CONNECTED:5,DISCONNECTED:6,DISCONNECTING:7,ATTACHED:8,REDIRECT:9},LogLevel:{DEBUG:0,INFO:1,WARN:2,ERROR:3,FATAL:4},ElementType:{NORMAL:1,TEXT:3,CDATA:4,FRAGMENT:11},TIMEOUT:1.1,SECONDARY_TIMEOUT:.1,addNamespace:function(a,b){h.NS[a]=b},forEachChild:function(a,b,c){var d,e;for(d=0;d<a.childNodes.length;d++)e=a.childNodes[d],e.nodeType!=h.ElementType.NORMAL||b&&!this.isTagEqual(e,b)||c(e)},isTagEqual:function(a,b){return a.tagName==b},_xmlGenerator:null,_makeGenerator:function(){var a;return void 0===document.implementation.createDocument||document.implementation.createDocument&&document.documentMode&&document.documentMode<10?(a=this._getIEXmlDom(),a.appendChild(a.createElement("strophe"))):a=document.implementation.createDocument("jabber:client","strophe",null),a},xmlGenerator:function(){return h._xmlGenerator||(h._xmlGenerator=h._makeGenerator()),h._xmlGenerator},_getIEXmlDom:function(){for(var a=null,b=["Msxml2.DOMDocument.6.0","Msxml2.DOMDocument.5.0","Msxml2.DOMDocument.4.0","MSXML2.DOMDocument.3.0","MSXML2.DOMDocument","MSXML.DOMDocument","Microsoft.XMLDOM"],c=0;c<b.length&&null===a;c++)try{a=new ActiveXObject(b[c])}catch(d){a=null}return a},xmlElement:function(a){if(!a)return null;var b,c,d,e=h.xmlGenerator().createElement(a);for(b=1;b<arguments.length;b++){var f=arguments[b];if(f)if("string"==typeof f||"number"==typeof f)e.appendChild(h.xmlTextNode(f));else if("object"==typeof f&&"function"==typeof f.sort)for(c=0;c<f.length;c++){var g=f[c];"object"==typeof g&&"function"==typeof g.sort&&void 0!==g[1]&&e.setAttribute(g[0],g[1])}else if("object"==typeof f)for(d in f)f.hasOwnProperty(d)&&void 0!==f[d]&&e.setAttribute(d,f[d])}return e},xmlescape:function(a){return a=a.replace(/\&/g,"&"),a=a.replace(/</g,"<"),a=a.replace(/>/g,">"),a=a.replace(/'/g,"'"),a=a.replace(/"/g,""")},xmlunescape:function(a){return a=a.replace(/\&/g,"&"),a=a.replace(/</g,"<"),a=a.replace(/>/g,">"),a=a.replace(/'/g,"'"),a=a.replace(/"/g,'"')},xmlTextNode:function(a){return h.xmlGenerator().createTextNode(a)},xmlHtmlNode:function(a){var b;if(window.DOMParser){var c=new DOMParser;b=c.parseFromString(a,"text/xml")}else b=new ActiveXObject("Microsoft.XMLDOM"),b.async="false",b.loadXML(a);return b},getText:function(a){if(!a)return null;var b="";0===a.childNodes.length&&a.nodeType==h.ElementType.TEXT&&(b+=a.nodeValue);for(var c=0;c<a.childNodes.length;c++)a.childNodes[c].nodeType==h.ElementType.TEXT&&(b+=a.childNodes[c].nodeValue);return h.xmlescape(b)},copyElement:function(a){var b,c;if(a.nodeType==h.ElementType.NORMAL){for(c=h.xmlElement(a.tagName),b=0;b<a.attributes.length;b++)c.setAttribute(a.attributes[b].nodeName,a.attributes[b].value);for(b=0;b<a.childNodes.length;b++)c.appendChild(h.copyElement(a.childNodes[b]))}else a.nodeType==h.ElementType.TEXT&&(c=h.xmlGenerator().createTextNode(a.nodeValue));return c},createHtml:function(a){var b,c,d,e,f,g,i,j,k,l,m;if(a.nodeType==h.ElementType.NORMAL)if(e=a.nodeName.toLowerCase(),h.XHTML.validTag(e))try{for(c=h.xmlElement(e),b=0;b<h.XHTML.attributes[e].length;b++)if(f=h.XHTML.attributes[e][b],g=a.getAttribute(f),"undefined"!=typeof g&&null!==g&&""!==g&&g!==!1&&0!==g)if("style"==f&&"object"==typeof g&&"undefined"!=typeof g.cssText&&(g=g.cssText),"style"==f){for(i=[],j=g.split(";"),d=0;d<j.length;d++)k=j[d].split(":"),l=k[0].replace(/^\s*/,"").replace(/\s*$/,"").toLowerCase(),h.XHTML.validCSS(l)&&(m=k[1].replace(/^\s*/,"").replace(/\s*$/,""),i.push(l+": "+m));i.length>0&&(g=i.join("; "),c.setAttribute(f,g))}else c.setAttribute(f,g);for(b=0;b<a.childNodes.length;b++)c.appendChild(h.createHtml(a.childNodes[b]))}catch(n){c=h.xmlTextNode("")}else for(c=h.xmlGenerator().createDocumentFragment(),b=0;b<a.childNodes.length;b++)c.appendChild(h.createHtml(a.childNodes[b]));else if(a.nodeType==h.ElementType.FRAGMENT)for(c=h.xmlGenerator().createDocumentFragment(),b=0;b<a.childNodes.length;b++)c.appendChild(h.createHtml(a.childNodes[b]));else a.nodeType==h.ElementType.TEXT&&(c=h.xmlTextNode(a.nodeValue));return c},escapeNode:function(a){return"string"!=typeof a?a:a.replace(/^\s+|\s+$/g,"").replace(/\\/g,"\\5c").replace(/ /g,"\\20").replace(/\"/g,"\\22").replace(/\&/g,"\\26").replace(/\'/g,"\\27").replace(/\//g,"\\2f").replace(/:/g,"\\3a").replace(/</g,"\\3c").replace(/>/g,"\\3e").replace(/@/g,"\\40")},unescapeNode:function(a){return"string"!=typeof a?a:a.replace(/\\20/g," ").replace(/\\22/g,'"').replace(/\\26/g,"&").replace(/\\27/g,"'").replace(/\\2f/g,"/").replace(/\\3a/g,":").replace(/\\3c/g,"<").replace(/\\3e/g,">").replace(/\\40/g,"@").replace(/\\5c/g,"\\")},getNodeFromJid:function(a){return a.indexOf("@")<0?null:a.split("@")[0]},getDomainFromJid:function(a){var b=h.getBareJidFromJid(a);if(b.indexOf("@")<0)return b;var c=b.split("@");return c.splice(0,1),c.join("@")},getResourceFromJid:function(a){var b=a.split("/");return b.length<2?null:(b.splice(0,1),b.join("/"))},getBareJidFromJid:function(a){return a?a.split("/")[0]:null},log:function(a,b){},debug:function(a){this.log(this.LogLevel.DEBUG,a)},info:function(a){this.log(this.LogLevel.INFO,a)},warn:function(a){this.log(this.LogLevel.WARN,a)},error:function(a){this.log(this.LogLevel.ERROR,a)},fatal:function(a){this.log(this.LogLevel.FATAL,a)},serialize:function(a){var b;if(!a)return null;"function"==typeof a.tree&&(a=a.tree());var c,d,e=a.nodeName;for(a.getAttribute("_realname")&&(e=a.getAttribute("_realname")),b="<"+e,c=0;c<a.attributes.length;c++)"_realname"!=a.attributes[c].nodeName&&(b+=" "+a.attributes[c].nodeName+"='"+a.attributes[c].value.replace(/&/g,"&").replace(/\'/g,"'").replace(/>/g,">").replace(/</g,"<")+"'");if(a.childNodes.length>0){for(b+=">",c=0;c<a.childNodes.length;c++)switch(d=a.childNodes[c],d.nodeType){case h.ElementType.NORMAL:b+=h.serialize(d);break;case h.ElementType.TEXT:b+=h.xmlescape(d.nodeValue);break;case h.ElementType.CDATA:b+="<![CDATA["+d.nodeValue+"]]>"}b+="</"+e+">"}else b+="/>";return b},_requestId:0,_connectionPlugins:{},addConnectionPlugin:function(a,b){h._connectionPlugins[a]=b}},h.Builder=function(a,b){("presence"==a||"message"==a||"iq"==a)&&(b&&!b.xmlns?b.xmlns=h.NS.CLIENT:b||(b={xmlns:h.NS.CLIENT})),this.nodeTree=h.xmlElement(a,b),this.node=this.nodeTree},h.Builder.prototype={tree:function(){return this.nodeTree},toString:function(){return h.serialize(this.nodeTree)},up:function(){return this.node=this.node.parentNode,this},attrs:function(a){for(var b in a)a.hasOwnProperty(b)&&(void 0===a[b]?this.node.removeAttribute(b):this.node.setAttribute(b,a[b]));return this},c:function(a,b,c){var d=h.xmlElement(a,b,c);return this.node.appendChild(d),"string"!=typeof c&&(this.node=d),this},cnode:function(a){var b,c=h.xmlGenerator();try{b=void 0!==c.importNode}catch(d){b=!1}var e=b?c.importNode(a,!0):h.copyElement(a);return this.node.appendChild(e),this.node=e,this},t:function(a){var b=h.xmlTextNode(a);return this.node.appendChild(b),this},h:function(a){var b=document.createElement("body");b.innerHTML=a;for(var c=h.createHtml(b);c.childNodes.length>0;)this.node.appendChild(c.childNodes[0]);return this}},h.Handler=function(a,b,c,d,e,f,g){this.handler=a,this.ns=b,this.name=c,this.type=d,this.id=e,this.options=g||{matchBare:!1},this.options.matchBare||(this.options.matchBare=!1),this.options.matchBare?this.from=f?h.getBareJidFromJid(f):null:this.from=f,this.user=!0},h.Handler.prototype={isMatch:function(a){var b,c=null;if(c=this.options.matchBare?h.getBareJidFromJid(a.getAttribute("from")):a.getAttribute("from"),b=!1,this.ns){var d=this;h.forEachChild(a,null,function(a){a.getAttribute("xmlns")==d.ns&&(b=!0)}),b=b||a.getAttribute("xmlns")==this.ns}else b=!0;var e=a.getAttribute("type");return!b||this.name&&!h.isTagEqual(a,this.name)||this.type&&(Array.isArray(this.type)?-1==this.type.indexOf(e):e!=this.type)||this.id&&a.getAttribute("id")!=this.id||this.from&&c!=this.from?!1:!0},run:function(a){var b=null;try{b=this.handler(a)}catch(c){throw c.sourceURL?h.fatal("error: "+this.handler+" "+c.sourceURL+":"+c.line+" - "+c.name+": "+c.message):c.fileName?("undefined"!=typeof console&&(console.trace(),console.error(this.handler," - error - ",c,c.message)),h.fatal("error: "+this.handler+" "+c.fileName+":"+c.lineNumber+" - "+c.name+": "+c.message)):h.fatal("error: "+c.message+"\n"+c.stack),c}return b},toString:function(){return"{Handler: "+this.handler+"("+this.name+","+this.id+","+this.ns+")}"}},h.TimedHandler=function(a,b){this.period=a,this.handler=b,this.lastCalled=(new Date).getTime(),this.user=!0},h.TimedHandler.prototype={run:function(){return this.lastCalled=(new Date).getTime(),this.handler()},reset:function(){this.lastCalled=(new Date).getTime()},toString:function(){return"{TimedHandler: "+this.handler+"("+this.period+")}"}},h.Connection=function(a,b){this.service=a,this.options=b||{};var c=this.options.protocol||"";0===a.indexOf("ws:")||0===a.indexOf("wss:")||0===c.indexOf("ws")?this._proto=new h.Websocket(this):this._proto=new h.Bosh(this),this.jid="",this.domain=null,this.features=null,this._sasl_data={},this.do_session=!1,this.do_bind=!1,this.timedHandlers=[],this.handlers=[],this.removeTimeds=[],this.removeHandlers=[],this.addTimeds=[],this.addHandlers=[],this._authentication={},this._idleTimeout=null,this._disconnectTimeout=null,this.authenticated=!1,this.connected=!1,this.disconnecting=!1,this.do_authentication=!0,this.paused=!1,this.restored=!1,this._data=[],this._uniqueId=0,this._sasl_success_handler=null,this._sasl_failure_handler=null,this._sasl_challenge_handler=null,this.maxRetries=5,this._idleTimeout=setTimeout(this._onIdle.bind(this),100);for(var d in h._connectionPlugins)if(h._connectionPlugins.hasOwnProperty(d)){var e=h._connectionPlugins[d],f=function(){};f.prototype=e,this[d]=new f,this[d].init(this)}},h.Connection.prototype={reset:function(){this._proto._reset(),this.do_session=!1,this.do_bind=!1,this.timedHandlers=[],this.handlers=[],this.removeTimeds=[],this.removeHandlers=[],this.addTimeds=[],this.addHandlers=[],this._authentication={},this.authenticated=!1,this.connected=!1,this.disconnecting=!1,this.restored=!1,this._data=[],this._requests=[],this._uniqueId=0},pause:function(){this.paused=!0},resume:function(){this.paused=!1},getUniqueId:function(a){return"string"==typeof a||"number"==typeof a?++this._uniqueId+":"+a:++this._uniqueId+""},connect:function(a,b,c,d,e,f,g){this.jid=a,this.authzid=h.getBareJidFromJid(this.jid),this.authcid=g||h.getNodeFromJid(this.jid),this.pass=b,this.servtype="xmpp",this.connect_callback=c,this.disconnecting=!1,this.connected=!1,this.authenticated=!1,this.restored=!1,this.domain=h.getDomainFromJid(this.jid),this._changeConnectStatus(h.Status.CONNECTING,null),this._proto._connect(d,e,f)},attach:function(a,b,c,d,e,f,g){if(!(this._proto instanceof h.Bosh))throw{name:"StropheSessionError",message:'The "attach" method can only be used with a BOSH connection.'};this._proto._attach(a,b,c,d,e,f,g)},restore:function(a,b,c,d,e){if(!this._sessionCachingSupported())throw{name:"StropheSessionError",message:'The "restore" method can only be used with a BOSH connection.'};this._proto._restore(a,b,c,d,e)},_sessionCachingSupported:function(){if(this._proto instanceof h.Bosh){if(!JSON)return!1;try{window.sessionStorage.setItem("_strophe_","_strophe_"),window.sessionStorage.removeItem("_strophe_")}catch(a){return!1}return!0}return!1},xmlInput:function(a){},xmlOutput:function(a){},rawInput:function(a){},rawOutput:function(a){},send:function(a){if(null!==a){if("function"==typeof a.sort)for(var b=0;b<a.length;b++)this._queueData(a[b]);else this._queueData("function"==typeof a.tree?a.tree():a);this._proto._send()}},flush:function(){clearTimeout(this._idleTimeout),this._onIdle()},sendIQ:function(a,b,c,d){var e=null,f=this;"function"==typeof a.tree&&(a=a.tree());var g=a.getAttribute("id");g||(g=this.getUniqueId("sendIQ"),a.setAttribute("id",g));var i=a.getAttribute("to"),j=this.jid,k=this.addHandler(function(a){e&&f.deleteTimedHandler(e);var d=!1,g=a.getAttribute("from");if((g===i||null===i&&(g===h.getBareJidFromJid(j)||g===h.getDomainFromJid(j)||g===j))&&(d=!0),!d)throw{name:"StropheError",message:"Got answer to IQ from wrong jid:"+g+"\nExpected jid: "+i};var k=a.getAttribute("type");if("result"==k)b&&b(a);else{if("error"!=k)throw{name:"StropheError",message:"Got bad IQ type of "+k};c&&c(a)}},null,"iq",["error","result"],g);return d&&(e=this.addTimedHandler(d,function(){return f.deleteHandler(k),c&&c(null),!1})),this.send(a),g},_queueData:function(a){if(null===a||!a.tagName||!a.childNodes)throw{name:"StropheError",message:"Cannot queue non-DOMElement."};this._data.push(a)},_sendRestart:function(){this._data.push("restart"),this._proto._sendRestart(),this._idleTimeout=setTimeout(this._onIdle.bind(this),100)},addTimedHandler:function(a,b){var c=new h.TimedHandler(a,b);return this.addTimeds.push(c),c},deleteTimedHandler:function(a){this.removeTimeds.push(a)},addHandler:function(a,b,c,d,e,f,g){var i=new h.Handler(a,b,c,d,e,f,g);return this.addHandlers.push(i),i},deleteHandler:function(a){this.removeHandlers.push(a);var b=this.addHandlers.indexOf(a);b>=0&&this.addHandlers.splice(b,1)},disconnect:function(a){if(this._changeConnectStatus(h.Status.DISCONNECTING,a),h.info("Disconnect was called because: "+a),this.connected){var b=!1;this.disconnecting=!0,this.authenticated&&(b=g({xmlns:h.NS.CLIENT,type:"unavailable"})),this._disconnectTimeout=this._addSysTimedHandler(3e3,this._onDisconnectTimeout.bind(this)),this._proto._disconnect(b)}else h.info("Disconnect was called before Strophe connected to the server"),this._proto._abortAllRequests()},_changeConnectStatus:function(a,b){for(var c in h._connectionPlugins)if(h._connectionPlugins.hasOwnProperty(c)){var d=this[c];if(d.statusChanged)try{d.statusChanged(a,b)}catch(e){h.error(""+c+" plugin caused an exception changing status: "+e)}}if(this.connect_callback)try{this.connect_callback(a,b)}catch(f){h.error("User connection callback caused an exception: "+f)}},_doDisconnect:function(a){"number"==typeof this._idleTimeout&&clearTimeout(this._idleTimeout),null!==this._disconnectTimeout&&(this.deleteTimedHandler(this._disconnectTimeout),this._disconnectTimeout=null),h.info("_doDisconnect was called"),this._proto._doDisconnect(),this.authenticated=!1,this.disconnecting=!1,this.restored=!1,this.handlers=[],this.timedHandlers=[],this.removeTimeds=[],this.removeHandlers=[],this.addTimeds=[],this.addHandlers=[],this._changeConnectStatus(h.Status.DISCONNECTED,a),this.connected=!1},_dataRecv:function(a,b){h.info("_dataRecv called");var c=this._proto._reqToData(a);if(null!==c){this.xmlInput!==h.Connection.prototype.xmlInput&&this.xmlInput(c.nodeName===this._proto.strip&&c.childNodes.length?c.childNodes[0]:c),this.rawInput!==h.Connection.prototype.rawInput&&this.rawInput(b?b:h.serialize(c));for(var d,e;this.removeHandlers.length>0;)e=this.removeHandlers.pop(),d=this.handlers.indexOf(e),d>=0&&this.handlers.splice(d,1);for(;this.addHandlers.length>0;)this.handlers.push(this.addHandlers.pop());if(this.disconnecting&&this._proto._emptyQueue())return void this._doDisconnect();var f,g,i=c.getAttribute("type");if(null!==i&&"terminate"==i){if(this.disconnecting)return;return f=c.getAttribute("condition"),g=c.getElementsByTagName("conflict"),null!==f?("remote-stream-error"==f&&g.length>0&&(f="conflict"),this._changeConnectStatus(h.Status.CONNFAIL,f)):this._changeConnectStatus(h.Status.CONNFAIL,"unknown"),void this._doDisconnect(f)}var j=this;h.forEachChild(c,null,function(a){var b,c;for(c=j.handlers,j.handlers=[],b=0;b<c.length;b++){var d=c[b];try{!d.isMatch(a)||!j.authenticated&&d.user?j.handlers.push(d):d.run(a)&&j.handlers.push(d)}catch(e){h.warn("Removing Strophe handlers due to uncaught exception: "+e.message)}}})}},mechanisms:{},_connect_cb:function(a,b,c){h.info("_connect_cb was called"),this.connected=!0;var d=this._proto._reqToData(a);if(d){this.xmlInput!==h.Connection.prototype.xmlInput&&this.xmlInput(d.nodeName===this._proto.strip&&d.childNodes.length?d.childNodes[0]:d),this.rawInput!==h.Connection.prototype.rawInput&&this.rawInput(c?c:h.serialize(d));var e=this._proto._connect_cb(d);if(e!==h.Status.CONNFAIL){this._authentication.sasl_scram_sha1=!1,this._authentication.sasl_plain=!1,this._authentication.sasl_digest_md5=!1,this._authentication.sasl_anonymous=!1,this._authentication.legacy_auth=!1;var f;f=d.getElementsByTagNameNS?d.getElementsByTagNameNS(h.NS.STREAM,"features").length>0:d.getElementsByTagName("stream:features").length>0||d.getElementsByTagName("features").length>0;var g,i,j=d.getElementsByTagName("mechanism"),k=[],l=!1;if(!f)return void this._proto._no_auth_received(b);if(j.length>0)for(g=0;g<j.length;g++)i=h.getText(j[g]),this.mechanisms[i]&&k.push(this.mechanisms[i]);return this._authentication.legacy_auth=d.getElementsByTagName("auth").length>0,(l=this._authentication.legacy_auth||k.length>0)?void(this.do_authentication!==!1&&this.authenticate(k)):void this._proto._no_auth_received(b)}}},authenticate:function(a){var c;for(c=0;c<a.length-1;++c){for(var e=c,g=c+1;g<a.length;++g)a[g].prototype.priority>a[e].prototype.priority&&(e=g);if(e!=c){var i=a[c];a[c]=a[e],a[e]=i}}var j=!1;for(c=0;c<a.length;++c)if(a[c].test(this)){this._sasl_success_handler=this._addSysHandler(this._sasl_success_cb.bind(this),null,"success",null,null),this._sasl_failure_handler=this._addSysHandler(this._sasl_failure_cb.bind(this),null,"failure",null,null),this._sasl_challenge_handler=this._addSysHandler(this._sasl_challenge_cb.bind(this),null,"challenge",null,null),this._sasl_mechanism=new a[c],this._sasl_mechanism.onStart(this);var k=d("auth",{xmlns:h.NS.SASL,mechanism:this._sasl_mechanism.name});if(this._sasl_mechanism.isClientFirst){var l=this._sasl_mechanism.onChallenge(this,null);k.t(b.encode(l))}this.send(k.tree()),j=!0;break}j||(null===h.getNodeFromJid(this.jid)?(this._changeConnectStatus(h.Status.CONNFAIL,"x-strophe-bad-non-anon-jid"),this.disconnect("x-strophe-bad-non-anon-jid")):(this._changeConnectStatus(h.Status.AUTHENTICATING,null),this._addSysHandler(this._auth1_cb.bind(this),null,null,null,"_auth_1"),this.send(f({type:"get",to:this.domain,id:"_auth_1"}).c("query",{xmlns:h.NS.AUTH}).c("username",{}).t(h.getNodeFromJid(this.jid)).tree())))},_sasl_challenge_cb:function(a){var c=b.decode(h.getText(a)),e=this._sasl_mechanism.onChallenge(this,c),f=d("response",{xmlns:h.NS.SASL});return""!==e&&f.t(b.encode(e)),this.send(f.tree()),!0},_auth1_cb:function(a){var b=f({type:"set",id:"_auth_2"}).c("query",{xmlns:h.NS.AUTH}).c("username",{}).t(h.getNodeFromJid(this.jid)).up().c("password").t(this.pass);return h.getResourceFromJid(this.jid)||(this.jid=h.getBareJidFromJid(this.jid)+"/strophe"),b.up().c("resource",{}).t(h.getResourceFromJid(this.jid)),this._addSysHandler(this._auth2_cb.bind(this),null,null,null,"_auth_2"),this.send(b.tree()),!1},_sasl_success_cb:function(a){if(this._sasl_data["server-signature"]){var c,d=b.decode(h.getText(a)),e=/([a-z]+)=([^,]+)(,|$)/,f=d.match(e);if("v"==f[1]&&(c=f[2]),c!=this._sasl_data["server-signature"])return this.deleteHandler(this._sasl_failure_handler),this._sasl_failure_handler=null,this._sasl_challenge_handler&&(this.deleteHandler(this._sasl_challenge_handler),this._sasl_challenge_handler=null),this._sasl_data={},this._sasl_failure_cb(null)}h.info("SASL authentication succeeded."),this._sasl_mechanism&&this._sasl_mechanism.onSuccess(),this.deleteHandler(this._sasl_failure_handler),this._sasl_failure_handler=null,this._sasl_challenge_handler&&(this.deleteHandler(this._sasl_challenge_handler),this._sasl_challenge_handler=null);var g=[],i=function(a,b){for(;a.length;)this.deleteHandler(a.pop());return this._sasl_auth1_cb.bind(this)(b),!1};return g.push(this._addSysHandler(function(a){i.bind(this)(g,a)}.bind(this),null,"stream:features",null,null)),g.push(this._addSysHandler(function(a){i.bind(this)(g,a)}.bind(this),h.NS.STREAM,"features",null,null)),this._sendRestart(),!1},_sasl_auth1_cb:function(a){this.features=a;var b,c;for(b=0;b<a.childNodes.length;b++)c=a.childNodes[b],"bind"==c.nodeName&&(this.do_bind=!0),"session"==c.nodeName&&(this.do_session=!0);if(!this.do_bind)return this._changeConnectStatus(h.Status.AUTHFAIL,null),!1;this._addSysHandler(this._sasl_bind_cb.bind(this),null,null,null,"_bind_auth_2");var d=h.getResourceFromJid(this.jid);return this.send(d?f({type:"set",id:"_bind_auth_2"}).c("bind",{xmlns:h.NS.BIND}).c("resource",{}).t(d).tree():f({type:"set",id:"_bind_auth_2"}).c("bind",{xmlns:h.NS.BIND}).tree()),!1},_sasl_bind_cb:function(a){if("error"==a.getAttribute("type")){h.info("SASL binding failed.");var b,c=a.getElementsByTagName("conflict");return c.length>0&&(b="conflict"),this._changeConnectStatus(h.Status.AUTHFAIL,b),!1}var d,e=a.getElementsByTagName("bind");return e.length>0?(d=e[0].getElementsByTagName("jid"),void(d.length>0&&(this.jid=h.getText(d[0]),this.do_session?(this._addSysHandler(this._sasl_session_cb.bind(this),null,null,null,"_session_auth_2"),this.send(f({type:"set",id:"_session_auth_2"}).c("session",{xmlns:h.NS.SESSION}).tree())):(this.authenticated=!0,this._changeConnectStatus(h.Status.CONNECTED,null))))):(h.info("SASL binding failed."),this._changeConnectStatus(h.Status.AUTHFAIL,null),!1)},_sasl_session_cb:function(a){if("result"==a.getAttribute("type"))this.authenticated=!0,this._changeConnectStatus(h.Status.CONNECTED,null);else if("error"==a.getAttribute("type"))return h.info("Session creation failed."),this._changeConnectStatus(h.Status.AUTHFAIL,null),!1;return!1},_sasl_failure_cb:function(a){return this._sasl_success_handler&&(this.deleteHandler(this._sasl_success_handler),this._sasl_success_handler=null),this._sasl_challenge_handler&&(this.deleteHandler(this._sasl_challenge_handler),this._sasl_challenge_handler=null),this._sasl_mechanism&&this._sasl_mechanism.onFailure(),this._changeConnectStatus(h.Status.AUTHFAIL,null),!1},_auth2_cb:function(a){return"result"==a.getAttribute("type")?(this.authenticated=!0,this._changeConnectStatus(h.Status.CONNECTED,null)):"error"==a.getAttribute("type")&&(this._changeConnectStatus(h.Status.AUTHFAIL,null),this.disconnect("authentication failed")),!1},_addSysTimedHandler:function(a,b){var c=new h.TimedHandler(a,b);return c.user=!1,this.addTimeds.push(c),c},_addSysHandler:function(a,b,c,d,e){var f=new h.Handler(a,b,c,d,e);return f.user=!1,this.addHandlers.push(f),f},_onDisconnectTimeout:function(){return h.info("_onDisconnectTimeout was called"),this._proto._onDisconnectTimeout(),this._doDisconnect(),!1},_onIdle:function(){for(var a,b,c,d;this.addTimeds.length>0;)this.timedHandlers.push(this.addTimeds.pop());for(;this.removeTimeds.length>0;)b=this.removeTimeds.pop(),a=this.timedHandlers.indexOf(b),a>=0&&this.timedHandlers.splice(a,1);var e=(new Date).getTime();for(d=[],a=0;a<this.timedHandlers.length;a++)b=this.timedHandlers[a],(this.authenticated||!b.user)&&(c=b.lastCalled+b.period,0>=c-e?b.run()&&d.push(b):d.push(b));this.timedHandlers=d,clearTimeout(this._idleTimeout),this._proto._onIdle(),this.connected&&(this._idleTimeout=setTimeout(this._onIdle.bind(this),100))}},h.SASLMechanism=function(a,b,c){this.name=a,this.isClientFirst=b, | ||
| 3 | this.priority=c},h.SASLMechanism.prototype={test:function(a){return!0},onStart:function(a){this._connection=a},onChallenge:function(a,b){throw new Error("You should implement challenge handling!")},onFailure:function(){this._connection=null},onSuccess:function(){this._connection=null}},h.SASLAnonymous=function(){},h.SASLAnonymous.prototype=new h.SASLMechanism("ANONYMOUS",!1,10),h.SASLAnonymous.test=function(a){return null===a.authcid},h.Connection.prototype.mechanisms[h.SASLAnonymous.prototype.name]=h.SASLAnonymous,h.SASLPlain=function(){},h.SASLPlain.prototype=new h.SASLMechanism("PLAIN",!0,20),h.SASLPlain.test=function(a){return null!==a.authcid},h.SASLPlain.prototype.onChallenge=function(a){var b=a.authzid;return b+="\x00",b+=a.authcid,b+="\x00",b+=a.pass},h.Connection.prototype.mechanisms[h.SASLPlain.prototype.name]=h.SASLPlain,h.SASLSHA1=function(){},h.SASLSHA1.prototype=new h.SASLMechanism("SCRAM-SHA-1",!0,40),h.SASLSHA1.test=function(a){return null!==a.authcid},h.SASLSHA1.prototype.onChallenge=function(d,e,f){var g=f||c.hexdigest(1234567890*Math.random()),h="n="+d.authcid;return h+=",r=",h+=g,d._sasl_data.cnonce=g,d._sasl_data["client-first-message-bare"]=h,h="n,,"+h,this.onChallenge=function(c,d){for(var e,f,g,h,i,j,k,l,m,n,o,p="c=biws,",q=c._sasl_data["client-first-message-bare"]+","+d+",",r=c._sasl_data.cnonce,s=/([a-z]+)=([^,]+)(,|$)/;d.match(s);){var t=d.match(s);switch(d=d.replace(t[0],""),t[1]){case"r":e=t[2];break;case"s":f=t[2];break;case"i":g=t[2]}}if(e.substr(0,r.length)!==r)return c._sasl_data={},c._sasl_failure_cb();for(p+="r="+e,q+=p,f=b.decode(f),f+="\x00\x00\x00",h=j=a.core_hmac_sha1(c.pass,f),k=1;g>k;k++){for(i=a.core_hmac_sha1(c.pass,a.binb2str(j)),l=0;5>l;l++)h[l]^=i[l];j=i}for(h=a.binb2str(h),m=a.core_hmac_sha1(h,"Client Key"),n=a.str_hmac_sha1(h,"Server Key"),o=a.core_hmac_sha1(a.str_sha1(a.binb2str(m)),q),c._sasl_data["server-signature"]=a.b64_hmac_sha1(n,q),l=0;5>l;l++)m[l]^=o[l];return p+=",p="+b.encode(a.binb2str(m))}.bind(this),h},h.Connection.prototype.mechanisms[h.SASLSHA1.prototype.name]=h.SASLSHA1,h.SASLMD5=function(){},h.SASLMD5.prototype=new h.SASLMechanism("DIGEST-MD5",!1,30),h.SASLMD5.test=function(a){return null!==a.authcid},h.SASLMD5.prototype._quote=function(a){return'"'+a.replace(/\\/g,"\\\\").replace(/"/g,'\\"')+'"'},h.SASLMD5.prototype.onChallenge=function(a,b,d){for(var e,f=/([a-z]+)=("[^"]+"|[^,"]+)(?:,|$)/,g=d||c.hexdigest(""+1234567890*Math.random()),h="",i=null,j="",k="";b.match(f);)switch(e=b.match(f),b=b.replace(e[0],""),e[2]=e[2].replace(/^"(.+)"$/,"$1"),e[1]){case"realm":h=e[2];break;case"nonce":j=e[2];break;case"qop":k=e[2];break;case"host":i=e[2]}var l=a.servtype+"/"+a.domain;null!==i&&(l=l+"/"+i);var m=c.hash(a.authcid+":"+h+":"+this._connection.pass)+":"+j+":"+g,n="AUTHENTICATE:"+l,o="";return o+="charset=utf-8,",o+="username="+this._quote(a.authcid)+",",o+="realm="+this._quote(h)+",",o+="nonce="+this._quote(j)+",",o+="nc=00000001,",o+="cnonce="+this._quote(g)+",",o+="digest-uri="+this._quote(l)+",",o+="response="+c.hexdigest(c.hexdigest(m)+":"+j+":00000001:"+g+":auth:"+c.hexdigest(n))+",",o+="qop=auth",this.onChallenge=function(){return""}.bind(this),o},h.Connection.prototype.mechanisms[h.SASLMD5.prototype.name]=h.SASLMD5,{Strophe:h,$build:d,$msg:e,$iq:f,$pres:g,SHA1:a,Base64:b,MD5:c}}),function(a,b){return"function"==typeof define&&define.amd?void define("strophe-bosh",["strophe-core"],function(a){return b(a.Strophe,a.$build)}):b(Strophe,$build)}(this,function(a,b){return a.Request=function(b,c,d,e){this.id=++a._requestId,this.xmlData=b,this.data=a.serialize(b),this.origFunc=c,this.func=c,this.rid=d,this.date=0/0,this.sends=e||0,this.abort=!1,this.dead=null,this.age=function(){if(!this.date)return 0;var a=new Date;return(a-this.date)/1e3},this.timeDead=function(){if(!this.dead)return 0;var a=new Date;return(a-this.dead)/1e3},this.xhr=this._newXHR()},a.Request.prototype={getResponse:function(){var b=null;if(this.xhr.responseXML&&this.xhr.responseXML.documentElement){if(b=this.xhr.responseXML.documentElement,"parsererror"==b.tagName)throw a.error("invalid response received"),a.error("responseText: "+this.xhr.responseText),a.error("responseXML: "+a.serialize(this.xhr.responseXML)),"parsererror"}else this.xhr.responseText&&(a.error("invalid response received"),a.error("responseText: "+this.xhr.responseText),a.error("responseXML: "+a.serialize(this.xhr.responseXML)));return b},_newXHR:function(){var a=null;return window.XMLHttpRequest?(a=new XMLHttpRequest,a.overrideMimeType&&a.overrideMimeType("text/xml; charset=utf-8")):window.ActiveXObject&&(a=new ActiveXObject("Microsoft.XMLHTTP")),a.onreadystatechange=this.func.bind(null,this),a}},a.Bosh=function(a){this._conn=a,this.rid=Math.floor(4294967295*Math.random()),this.sid=null,this.hold=1,this.wait=60,this.window=5,this.errors=0,this._requests=[]},a.Bosh.prototype={strip:null,_buildBody:function(){var c=b("body",{rid:this.rid++,xmlns:a.NS.HTTPBIND});return null!==this.sid&&c.attrs({sid:this.sid}),this._conn.options.keepalive&&this._cacheSession(),c},_reset:function(){this.rid=Math.floor(4294967295*Math.random()),this.sid=null,this.errors=0,window.sessionStorage.removeItem("strophe-bosh-session")},_connect:function(b,c,d){this.wait=b||this.wait,this.hold=c||this.hold,this.errors=0;var e=this._buildBody().attrs({to:this._conn.domain,"xml:lang":"en",wait:this.wait,hold:this.hold,content:"text/xml; charset=utf-8",ver:"1.6","xmpp:version":"1.0","xmlns:xmpp":a.NS.BOSH});d&&e.attrs({route:d});var f=this._conn._connect_cb;this._requests.push(new a.Request(e.tree(),this._onRequestStateChange.bind(this,f.bind(this._conn)),e.tree().getAttribute("rid"))),this._throttledRequestHandler()},_attach:function(b,c,d,e,f,g,h){this._conn.jid=b,this.sid=c,this.rid=d,this._conn.connect_callback=e,this._conn.domain=a.getDomainFromJid(this._conn.jid),this._conn.authenticated=!0,this._conn.connected=!0,this.wait=f||this.wait,this.hold=g||this.hold,this.window=h||this.window,this._conn._changeConnectStatus(a.Status.ATTACHED,null)},_restore:function(b,c,d,e,f){var g=JSON.parse(window.sessionStorage.getItem("strophe-bosh-session"));if(!("undefined"!=typeof g&&null!==g&&g.rid&&g.sid&&g.jid)||"undefined"!=typeof b&&a.getBareJidFromJid(g.jid)!=a.getBareJidFromJid(b))throw{name:"StropheSessionError",message:"_restore: no restoreable session."};this._conn.restored=!0,this._attach(g.jid,g.sid,g.rid,c,d,e,f)},_cacheSession:function(){this._conn.authenticated?this._conn.jid&&this.rid&&this.sid&&window.sessionStorage.setItem("strophe-bosh-session",JSON.stringify({jid:this._conn.jid,rid:this.rid,sid:this.sid})):window.sessionStorage.removeItem("strophe-bosh-session")},_connect_cb:function(b){var c,d,e=b.getAttribute("type");if(null!==e&&"terminate"==e)return c=b.getAttribute("condition"),a.error("BOSH-Connection failed: "+c),d=b.getElementsByTagName("conflict"),null!==c?("remote-stream-error"==c&&d.length>0&&(c="conflict"),this._conn._changeConnectStatus(a.Status.CONNFAIL,c)):this._conn._changeConnectStatus(a.Status.CONNFAIL,"unknown"),this._conn._doDisconnect(c),a.Status.CONNFAIL;this.sid||(this.sid=b.getAttribute("sid"));var f=b.getAttribute("requests");f&&(this.window=parseInt(f,10));var g=b.getAttribute("hold");g&&(this.hold=parseInt(g,10));var h=b.getAttribute("wait");h&&(this.wait=parseInt(h,10))},_disconnect:function(a){this._sendTerminate(a)},_doDisconnect:function(){this.sid=null,this.rid=Math.floor(4294967295*Math.random()),window.sessionStorage.removeItem("strophe-bosh-session")},_emptyQueue:function(){return 0===this._requests.length},_hitError:function(b){this.errors++,a.warn("request errored, status: "+b+", number of errors: "+this.errors),this.errors>4&&this._conn._onDisconnectTimeout()},_no_auth_received:function(b){b=b?b.bind(this._conn):this._conn._connect_cb.bind(this._conn);var c=this._buildBody();this._requests.push(new a.Request(c.tree(),this._onRequestStateChange.bind(this,b.bind(this._conn)),c.tree().getAttribute("rid"))),this._throttledRequestHandler()},_onDisconnectTimeout:function(){this._abortAllRequests()},_abortAllRequests:function(){for(var a;this._requests.length>0;)a=this._requests.pop(),a.abort=!0,a.xhr.abort(),a.xhr.onreadystatechange=function(){}},_onIdle:function(){var b=this._conn._data;if(this._conn.authenticated&&0===this._requests.length&&0===b.length&&!this._conn.disconnecting&&(a.info("no requests during idle cycle, sending blank request"),b.push(null)),!this._conn.paused){if(this._requests.length<2&&b.length>0){for(var c=this._buildBody(),d=0;d<b.length;d++)null!==b[d]&&("restart"===b[d]?c.attrs({to:this._conn.domain,"xml:lang":"en","xmpp:restart":"true","xmlns:xmpp":a.NS.BOSH}):c.cnode(b[d]).up());delete this._conn._data,this._conn._data=[],this._requests.push(new a.Request(c.tree(),this._onRequestStateChange.bind(this,this._conn._dataRecv.bind(this._conn)),c.tree().getAttribute("rid"))),this._throttledRequestHandler()}if(this._requests.length>0){var e=this._requests[0].age();null!==this._requests[0].dead&&this._requests[0].timeDead()>Math.floor(a.SECONDARY_TIMEOUT*this.wait)&&this._throttledRequestHandler(),e>Math.floor(a.TIMEOUT*this.wait)&&(a.warn("Request "+this._requests[0].id+" timed out, over "+Math.floor(a.TIMEOUT*this.wait)+" seconds since last activity"),this._throttledRequestHandler())}}},_onRequestStateChange:function(b,c){if(a.debug("request id "+c.id+"."+c.sends+" state changed to "+c.xhr.readyState),c.abort)return void(c.abort=!1);var d;if(4==c.xhr.readyState){d=0;try{d=c.xhr.status}catch(e){}if("undefined"==typeof d&&(d=0),this.disconnecting&&d>=400)return void this._hitError(d);var f=this._requests[0]==c,g=this._requests[1]==c;(d>0&&500>d||c.sends>5)&&(this._removeRequest(c),a.debug("request id "+c.id+" should now be removed")),200==d?((g||f&&this._requests.length>0&&this._requests[0].age()>Math.floor(a.SECONDARY_TIMEOUT*this.wait))&&this._restartRequest(0),a.debug("request id "+c.id+"."+c.sends+" got 200"),b(c),this.errors=0):(a.error("request id "+c.id+"."+c.sends+" error "+d+" happened"),(0===d||d>=400&&600>d||d>=12e3)&&(this._hitError(d),d>=400&&500>d&&(this._conn._changeConnectStatus(a.Status.DISCONNECTING,null),this._conn._doDisconnect()))),d>0&&500>d||c.sends>5||this._throttledRequestHandler()}},_processRequest:function(b){var c=this,d=this._requests[b],e=-1;try{4==d.xhr.readyState&&(e=d.xhr.status)}catch(f){a.error("caught an error in _requests["+b+"], reqStatus: "+e)}if("undefined"==typeof e&&(e=-1),d.sends>this._conn.maxRetries)return void this._conn._onDisconnectTimeout();var g=d.age(),h=!isNaN(g)&&g>Math.floor(a.TIMEOUT*this.wait),i=null!==d.dead&&d.timeDead()>Math.floor(a.SECONDARY_TIMEOUT*this.wait),j=4==d.xhr.readyState&&(1>e||e>=500);if((h||i||j)&&(i&&a.error("Request "+this._requests[b].id+" timed out (secondary), restarting"),d.abort=!0,d.xhr.abort(),d.xhr.onreadystatechange=function(){},this._requests[b]=new a.Request(d.xmlData,d.origFunc,d.rid,d.sends),d=this._requests[b]),0===d.xhr.readyState){a.debug("request id "+d.id+"."+d.sends+" posting");try{d.xhr.open("POST",this._conn.service,this._conn.options.sync?!1:!0),d.xhr.setRequestHeader("Content-Type","text/xml; charset=utf-8")}catch(k){return a.error("XHR open failed."),this._conn.connected||this._conn._changeConnectStatus(a.Status.CONNFAIL,"bad-service"),void this._conn.disconnect()}var l=function(){if(d.date=new Date,c._conn.options.customHeaders){var a=c._conn.options.customHeaders;for(var b in a)a.hasOwnProperty(b)&&d.xhr.setRequestHeader(b,a[b])}d.xhr.send(d.data)};if(d.sends>1){var m=1e3*Math.min(Math.floor(a.TIMEOUT*this.wait),Math.pow(d.sends,3));setTimeout(l,m)}else l();d.sends++,this._conn.xmlOutput!==a.Connection.prototype.xmlOutput&&this._conn.xmlOutput(d.xmlData.nodeName===this.strip&&d.xmlData.childNodes.length?d.xmlData.childNodes[0]:d.xmlData),this._conn.rawOutput!==a.Connection.prototype.rawOutput&&this._conn.rawOutput(d.data)}else a.debug("_processRequest: "+(0===b?"first":"second")+" request has readyState of "+d.xhr.readyState)},_removeRequest:function(b){a.debug("removing request");var c;for(c=this._requests.length-1;c>=0;c--)b==this._requests[c]&&this._requests.splice(c,1);b.xhr.onreadystatechange=function(){},this._throttledRequestHandler()},_restartRequest:function(a){var b=this._requests[a];null===b.dead&&(b.dead=new Date),this._processRequest(a)},_reqToData:function(a){try{return a.getResponse()}catch(b){if("parsererror"!=b)throw b;this._conn.disconnect("strophe-parsererror")}},_sendTerminate:function(b){a.info("_sendTerminate was called");var c=this._buildBody().attrs({type:"terminate"});b&&c.cnode(b.tree());var d=new a.Request(c.tree(),this._onRequestStateChange.bind(this,this._conn._dataRecv.bind(this._conn)),c.tree().getAttribute("rid"));this._requests.push(d),this._throttledRequestHandler()},_send:function(){clearTimeout(this._conn._idleTimeout),this._throttledRequestHandler(),this._conn._idleTimeout=setTimeout(this._conn._onIdle.bind(this._conn),100)},_sendRestart:function(){this._throttledRequestHandler(),clearTimeout(this._conn._idleTimeout)},_throttledRequestHandler:function(){a.debug(this._requests?"_throttledRequestHandler called with "+this._requests.length+" requests":"_throttledRequestHandler called with undefined requests"),this._requests&&0!==this._requests.length&&(this._requests.length>0&&this._processRequest(0),this._requests.length>1&&Math.abs(this._requests[0].rid-this._requests[1].rid)<this.window&&this._processRequest(1))}},a}),function(a,b){return"function"==typeof define&&define.amd?void define("strophe-websocket",["strophe-core"],function(a){return b(a.Strophe,a.$build)}):b(Strophe,$build)}(this,function(a,b){return a.Websocket=function(a){this._conn=a,this.strip="wrapper";var b=a.service;if(0!==b.indexOf("ws:")&&0!==b.indexOf("wss:")){var c="";c+="ws"===a.options.protocol&&"https:"!==window.location.protocol?"ws":"wss",c+="://"+window.location.host,c+=0!==b.indexOf("/")?window.location.pathname+b:b,a.service=c}},a.Websocket.prototype={_buildStream:function(){return b("open",{xmlns:a.NS.FRAMING,to:this._conn.domain,version:"1.0"})},_check_streamerror:function(b,c){var d;if(d=b.getElementsByTagNameNS?b.getElementsByTagNameNS(a.NS.STREAM,"error"):b.getElementsByTagName("stream:error"),0===d.length)return!1;for(var e=d[0],f="",g="",h="urn:ietf:params:xml:ns:xmpp-streams",i=0;i<e.childNodes.length;i++){var j=e.childNodes[i];if(j.getAttribute("xmlns")!==h)break;"text"===j.nodeName?g=j.textContent:f=j.nodeName}var k="WebSocket stream error: ";return k+=f?f:"unknown",g&&(k+=" - "+f),a.error(k),this._conn._changeConnectStatus(c,f),this._conn._doDisconnect(),!0},_reset:function(){},_connect:function(){this._closeSocket(),this.socket=new WebSocket(this._conn.service,"xmpp"),this.socket.onopen=this._onOpen.bind(this),this.socket.onerror=this._onError.bind(this),this.socket.onclose=this._onClose.bind(this),this.socket.onmessage=this._connect_cb_wrapper.bind(this)},_connect_cb:function(b){var c=this._check_streamerror(b,a.Status.CONNFAIL);return c?a.Status.CONNFAIL:void 0},_handleStreamStart:function(b){var c=!1,d=b.getAttribute("xmlns");"string"!=typeof d?c="Missing xmlns in <open />":d!==a.NS.FRAMING&&(c="Wrong xmlns in <open />: "+d);var e=b.getAttribute("version");return"string"!=typeof e?c="Missing version in <open />":"1.0"!==e&&(c="Wrong version in <open />: "+e),c?(this._conn._changeConnectStatus(a.Status.CONNFAIL,c),this._conn._doDisconnect(),!1):!0},_connect_cb_wrapper:function(b){if(0===b.data.indexOf("<open ")||0===b.data.indexOf("<?xml")){var c=b.data.replace(/^(<\?.*?\?>\s*)*/,"");if(""===c)return;var d=(new DOMParser).parseFromString(c,"text/xml").documentElement;this._conn.xmlInput(d),this._conn.rawInput(b.data),this._handleStreamStart(d)&&this._connect_cb(d)}else if(0===b.data.indexOf("<close ")){this._conn.rawInput(b.data),this._conn.xmlInput(b);var e=b.getAttribute("see-other-uri");e?(this._conn._changeConnectStatus(a.Status.REDIRECT,"Received see-other-uri, resetting connection"),this._conn.reset(),this._conn.service=e,this._connect()):(this._conn._changeConnectStatus(a.Status.CONNFAIL,"Received closing stream"),this._conn._doDisconnect())}else{var f=this._streamWrap(b.data),g=(new DOMParser).parseFromString(f,"text/xml").documentElement;this.socket.onmessage=this._onMessage.bind(this),this._conn._connect_cb(g,null,b.data)}},_disconnect:function(c){if(this.socket&&this.socket.readyState!==WebSocket.CLOSED){c&&this._conn.send(c);var d=b("close",{xmlns:a.NS.FRAMING});this._conn.xmlOutput(d);var e=a.serialize(d);this._conn.rawOutput(e);try{this.socket.send(e)}catch(f){a.info("Couldn't send <close /> tag.")}}this._conn._doDisconnect()},_doDisconnect:function(){a.info("WebSockets _doDisconnect was called"),this._closeSocket()},_streamWrap:function(a){return"<wrapper>"+a+"</wrapper>"},_closeSocket:function(){if(this.socket)try{this.socket.close()}catch(a){}this.socket=null},_emptyQueue:function(){return!0},_onClose:function(){this._conn.connected&&!this._conn.disconnecting?(a.error("Websocket closed unexcectedly"),this._conn._doDisconnect()):a.info("Websocket closed")},_no_auth_received:function(b){a.error("Server did not send any auth methods"),this._conn._changeConnectStatus(a.Status.CONNFAIL,"Server did not send any auth methods"),b&&(b=b.bind(this._conn))(),this._conn._doDisconnect()},_onDisconnectTimeout:function(){},_abortAllRequests:function(){},_onError:function(b){a.error("Websocket error "+b),this._conn._changeConnectStatus(a.Status.CONNFAIL,"The WebSocket connection could not be established was disconnected."),this._disconnect()},_onIdle:function(){var b=this._conn._data;if(b.length>0&&!this._conn.paused){for(var c=0;c<b.length;c++)if(null!==b[c]){var d,e;d="restart"===b[c]?this._buildStream().tree():b[c],e=a.serialize(d),this._conn.xmlOutput(d),this._conn.rawOutput(e),this.socket.send(e)}this._conn._data=[]}},_onMessage:function(b){var c,d,e='<close xmlns="urn:ietf:params:xml:ns:xmpp-framing" />';if(b.data===e)return this._conn.rawInput(e),this._conn.xmlInput(b),void(this._conn.disconnecting||this._conn._doDisconnect());if(0===b.data.search("<open ")){if(c=(new DOMParser).parseFromString(b.data,"text/xml").documentElement,!this._handleStreamStart(c))return}else d=this._streamWrap(b.data),c=(new DOMParser).parseFromString(d,"text/xml").documentElement;return this._check_streamerror(c,a.Status.ERROR)?void 0:this._conn.disconnecting&&"presence"===c.firstChild.nodeName&&"unavailable"===c.firstChild.getAttribute("type")?(this._conn.xmlInput(c),void this._conn.rawInput(a.serialize(c))):void this._conn._dataRecv(c,b.data)},_onOpen:function(){a.info("Websocket open");var b=this._buildStream();this._conn.xmlOutput(b.tree());var c=a.serialize(b);this._conn.rawOutput(c),this.socket.send(c)},_reqToData:function(a){return a},_send:function(){this._conn.flush()},_sendRestart:function(){clearTimeout(this._conn._idleTimeout),this._conn._onIdle.bind(this._conn)()}},a}),a?a(Strophe,$build,$msg,$iq,$pres):void 0}(function(a,b,c,d,e){window.Strophe=a,window.$build=b,window.$msg=c,window.$iq=d,window.$pres=e}); | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
src/App.vue
0 → 100644
| 1 | <template> | ||
| 2 | <div id="app"> | ||
| 3 | <router-view /> | ||
| 4 | </div> | ||
| 5 | </template> | ||
| 6 | |||
| 7 | <script> | ||
| 8 | export default { | ||
| 9 | methods: { | ||
| 10 | onlineMethod() { | ||
| 11 | this.$notify({ title: '网络恢复正常', type: 'success' }) | ||
| 12 | }, | ||
| 13 | offlineMethod() { | ||
| 14 | this.$notify.error({ title: '网络连接异常' }) | ||
| 15 | } | ||
| 16 | }, | ||
| 17 | beforeMount() { | ||
| 18 | window.addEventListener('online', this.onlineMethod) | ||
| 19 | window.addEventListener('offline', this.offlineMethod) | ||
| 20 | }, | ||
| 21 | beforeDestroy() { | ||
| 22 | window.removeEventListener('online', this.onlineMethod) | ||
| 23 | window.removeEventListener('offline', this.offlineMethod) | ||
| 24 | } | ||
| 25 | } | ||
| 26 | </script> | ||
| 27 | |||
| 28 | <style lang="scss"> | ||
| 29 | @mixin cover { | ||
| 30 | width: 100%; | ||
| 31 | height: 100%; | ||
| 32 | } | ||
| 33 | html, | ||
| 34 | body { | ||
| 35 | @include cover; | ||
| 36 | padding: 0; | ||
| 37 | margin: 0; | ||
| 38 | } | ||
| 39 | #app { | ||
| 40 | font-family: 'Avenir', Helvetica, Arial, sans-serif; | ||
| 41 | -webkit-font-smoothing: antialiased; | ||
| 42 | -moz-osx-font-smoothing: grayscale; | ||
| 43 | text-align: center; | ||
| 44 | color: #2c3e50; | ||
| 45 | @include cover; | ||
| 46 | } | ||
| 47 | #nav { | ||
| 48 | padding: 30px; | ||
| 49 | a { | ||
| 50 | font-weight: bold; | ||
| 51 | color: #2c3e50; | ||
| 52 | &.router-link-exact-active { | ||
| 53 | color: #42b983; | ||
| 54 | } | ||
| 55 | } | ||
| 56 | } | ||
| 57 | .el-main { | ||
| 58 | text-align: left; | ||
| 59 | } | ||
| 60 | a:focus, | ||
| 61 | a:active { | ||
| 62 | outline: none; | ||
| 63 | } | ||
| 64 | |||
| 65 | a, | ||
| 66 | a:focus, | ||
| 67 | a:hover { | ||
| 68 | cursor: pointer; | ||
| 69 | color: inherit; | ||
| 70 | text-decoration: none; | ||
| 71 | } | ||
| 72 | </style> |
src/api/home.js
0 → 100644
| 1 | import request from '@/utils/request' | ||
| 2 | |||
| 3 | /** | ||
| 4 | * 7天业务量 | ||
| 5 | * @param {*} data | ||
| 6 | */ | ||
| 7 | export function volumeCalls(data) { | ||
| 8 | return request({ | ||
| 9 | url: '/chery/homepage/volumeCalls', | ||
| 10 | method: 'post', | ||
| 11 | data | ||
| 12 | }) | ||
| 13 | } | ||
| 14 | |||
| 15 | /** | ||
| 16 | * 通话时长 | ||
| 17 | * @param {*} data | ||
| 18 | */ | ||
| 19 | export function durationsCalls(data) { | ||
| 20 | return request({ | ||
| 21 | url: '/chery/homepage/durationsCalls', | ||
| 22 | method: 'post', | ||
| 23 | data | ||
| 24 | }) | ||
| 25 | } |
src/api/orderList.js
0 → 100644
| 1 | import request from '@/utils/request' | ||
| 2 | |||
| 3 | /** | ||
| 4 | * 删除订单 | ||
| 5 | */ | ||
| 6 | export function deleteOrder(data) { | ||
| 7 | return request({ | ||
| 8 | url: '/chery/order/delete', | ||
| 9 | method: 'post', | ||
| 10 | data | ||
| 11 | }) | ||
| 12 | } | ||
| 13 | |||
| 14 | /** | ||
| 15 | * 全部订单列表查询 | ||
| 16 | */ | ||
| 17 | export function queryOrderList(data) { | ||
| 18 | return request({ | ||
| 19 | url: '/chery/order/query/list', | ||
| 20 | method: 'post', | ||
| 21 | data | ||
| 22 | }) | ||
| 23 | } | ||
| 24 | /** | ||
| 25 | * 全部订单列表查询 | ||
| 26 | */ | ||
| 27 | export function queryMyOrderList(data) { | ||
| 28 | return request({ | ||
| 29 | url: '/chery/order/query/mylist', | ||
| 30 | method: 'post', | ||
| 31 | data | ||
| 32 | }) | ||
| 33 | } | ||
| 34 | /** | ||
| 35 | * 订单详情 | ||
| 36 | */ | ||
| 37 | export function getOrderDetail(data) { | ||
| 38 | return request({ | ||
| 39 | url: '/chery/order/detail/get', | ||
| 40 | method: 'post', | ||
| 41 | data | ||
| 42 | }) | ||
| 43 | } |
src/api/patternManagement.js
0 → 100644
| 1 | import request from '@/utils/request' | ||
| 2 | |||
| 3 | /** | ||
| 4 | * 创建合作商 | ||
| 5 | * @param {*} data | ||
| 6 | */ | ||
| 7 | export function createPattern(data) { | ||
| 8 | return request({ | ||
| 9 | url: '/chery/partner/create', | ||
| 10 | method: 'post', | ||
| 11 | data | ||
| 12 | }) | ||
| 13 | } | ||
| 14 | |||
| 15 | /** | ||
| 16 | * 删除合作商 | ||
| 17 | * @param {*} data | ||
| 18 | */ | ||
| 19 | export function deletePattern(data) { | ||
| 20 | return request({ | ||
| 21 | url: '/chery/partner/delete', | ||
| 22 | method: 'post', | ||
| 23 | data | ||
| 24 | }) | ||
| 25 | } | ||
| 26 | |||
| 27 | /** | ||
| 28 | * 查询合作商 | ||
| 29 | * @param {*} data | ||
| 30 | */ | ||
| 31 | export function queryPattern(data) { | ||
| 32 | return request({ | ||
| 33 | url: '/chery/partner/query', | ||
| 34 | method: 'post', | ||
| 35 | data | ||
| 36 | }) | ||
| 37 | } | ||
| 38 | /** | ||
| 39 | * 合作商code是否存在 | ||
| 40 | * @param {*} data | ||
| 41 | */ | ||
| 42 | export function validateCode(data) { | ||
| 43 | return request({ | ||
| 44 | url: '/chery/partner/valid-code', | ||
| 45 | method: 'post', | ||
| 46 | data | ||
| 47 | }) | ||
| 48 | } | ||
| 49 | |||
| 50 | /** | ||
| 51 | * 报表列表查询 | ||
| 52 | * @param {*} data | ||
| 53 | */ | ||
| 54 | export function reportList(data) { | ||
| 55 | return request({ | ||
| 56 | url: '/chery/order/report/list', | ||
| 57 | method: 'post', | ||
| 58 | data | ||
| 59 | }) | ||
| 60 | } | ||
| 61 | |||
| 62 | /** | ||
| 63 | * 报表下载接口 | ||
| 64 | * @param {*} data | ||
| 65 | */ | ||
| 66 | export function reportDownload(data) { | ||
| 67 | return request({ | ||
| 68 | url: '/chery/order/report/download', | ||
| 69 | method: 'post', | ||
| 70 | responseType: 'blob', | ||
| 71 | data | ||
| 72 | }) | ||
| 73 | } |
src/api/speech.js
0 → 100644
| 1 | import request from '@/utils/request' | ||
| 2 | |||
| 3 | /** | ||
| 4 | * tts开关 | ||
| 5 | * @param {*} data | ||
| 6 | */ | ||
| 7 | export function ttsSwitch(data) { | ||
| 8 | return request({ | ||
| 9 | url: '/chery/tts/option/switch', | ||
| 10 | method: 'post', | ||
| 11 | data | ||
| 12 | }) | ||
| 13 | } | ||
| 14 | |||
| 15 | /** | ||
| 16 | * web查询话术结果 | ||
| 17 | * @param {*} data | ||
| 18 | */ | ||
| 19 | export function getTtsResult(data) { | ||
| 20 | return request({ | ||
| 21 | url: '/chery/tts/result', | ||
| 22 | method: 'post', | ||
| 23 | data | ||
| 24 | }) | ||
| 25 | } | ||
| 26 | /** | ||
| 27 | * 保存tts | ||
| 28 | * @param {*} data | ||
| 29 | */ | ||
| 30 | export function saveTts(data) { | ||
| 31 | return request({ | ||
| 32 | url: '/chery/tts/save', | ||
| 33 | method: 'post', | ||
| 34 | data | ||
| 35 | }) | ||
| 36 | } | ||
| 37 | /** | ||
| 38 | * web查询话术配置 | ||
| 39 | * @param {*} data | ||
| 40 | */ | ||
| 41 | export function getTtsTemplate(data) { | ||
| 42 | return request({ | ||
| 43 | url: '/chery/tts/getTemplate', | ||
| 44 | method: 'post', | ||
| 45 | data | ||
| 46 | }) | ||
| 47 | } | ||
| 48 | /** | ||
| 49 | * 查询tts是否开放 | ||
| 50 | * @param {*} data | ||
| 51 | */ | ||
| 52 | export function getTtsStatus(data) { | ||
| 53 | return request({ | ||
| 54 | url: '/chery/call/workTimeStatus', | ||
| 55 | method: 'post', | ||
| 56 | data | ||
| 57 | }) | ||
| 58 | } |
src/api/user.js
0 → 100644
| 1 | import request from '@/utils/request' | ||
| 2 | |||
| 3 | /** | ||
| 4 | * 登录 | ||
| 5 | * @param {*} data | ||
| 6 | */ | ||
| 7 | export function login(data) { | ||
| 8 | return request({ | ||
| 9 | url: '/chery/account/login', | ||
| 10 | method: 'post', | ||
| 11 | data | ||
| 12 | }) | ||
| 13 | } | ||
| 14 | |||
| 15 | /** | ||
| 16 | * 登出 | ||
| 17 | */ | ||
| 18 | export function logout() { | ||
| 19 | return request({ | ||
| 20 | url: '/chery/account/logout', | ||
| 21 | method: 'post' | ||
| 22 | }) | ||
| 23 | } | ||
| 24 | |||
| 25 | /** | ||
| 26 | * 注册 | ||
| 27 | * @param {*} data | ||
| 28 | */ | ||
| 29 | export function registry(data) { | ||
| 30 | return request({ | ||
| 31 | url: '/chery/account/registry', | ||
| 32 | method: 'post', | ||
| 33 | data | ||
| 34 | }) | ||
| 35 | } | ||
| 36 | |||
| 37 | /** | ||
| 38 | * 重置密码 | ||
| 39 | * @param {*} data | ||
| 40 | */ | ||
| 41 | export function resetPassword(data) { | ||
| 42 | return request({ | ||
| 43 | url: '/chery/account/reset-password', | ||
| 44 | method: 'post', | ||
| 45 | data | ||
| 46 | }) | ||
| 47 | } | ||
| 48 | |||
| 49 | /** | ||
| 50 | * 删除 | ||
| 51 | * @param {*} data | ||
| 52 | */ | ||
| 53 | export function deleteUser(data) { | ||
| 54 | return request({ | ||
| 55 | url: '/chery/account/delete', | ||
| 56 | method: 'post', | ||
| 57 | data | ||
| 58 | }) | ||
| 59 | } | ||
| 60 | |||
| 61 | /** | ||
| 62 | * 禁用账号 | ||
| 63 | * @param {*} data | ||
| 64 | */ | ||
| 65 | export function accountAvailable(data) { | ||
| 66 | return request({ | ||
| 67 | url: '/chery/account/available', | ||
| 68 | method: 'post', | ||
| 69 | data | ||
| 70 | }) | ||
| 71 | } | ||
| 72 | |||
| 73 | /** | ||
| 74 | * 账号列表查询 | ||
| 75 | * @param {*} data | ||
| 76 | */ | ||
| 77 | export function accountList(data) { | ||
| 78 | return request({ | ||
| 79 | url: '/chery/account/list', | ||
| 80 | method: 'post', | ||
| 81 | data | ||
| 82 | }) | ||
| 83 | } | ||
| 84 | /** | ||
| 85 | * 验证工号是否已存在 | ||
| 86 | * @param {*} data | ||
| 87 | */ | ||
| 88 | export function validUsername(data) { | ||
| 89 | return request({ | ||
| 90 | url: '/chery/account/valid-username', | ||
| 91 | method: 'post', | ||
| 92 | data | ||
| 93 | }) | ||
| 94 | } | ||
| 95 | /** | ||
| 96 | * 监控开启关闭 | ||
| 97 | * @param {*} data | ||
| 98 | */ | ||
| 99 | export function switchMonitor(data) { | ||
| 100 | return request({ | ||
| 101 | url: '/chery/account/switch-monitor', | ||
| 102 | method: 'post', | ||
| 103 | data | ||
| 104 | }) | ||
| 105 | } |
src/api/work.js
0 → 100644
| 1 | import request from '@/utils/request' | ||
| 2 | |||
| 3 | /** | ||
| 4 | * 确认接通 | ||
| 5 | * @param {*} data | ||
| 6 | */ | ||
| 7 | export function callWebConfirm(data) { | ||
| 8 | return request({ | ||
| 9 | url: '/chery/call/web/confirm', | ||
| 10 | method: 'post', | ||
| 11 | data | ||
| 12 | }) | ||
| 13 | } | ||
| 14 | /** | ||
| 15 | * 挂断电话 | ||
| 16 | * @param {*} data | ||
| 17 | */ | ||
| 18 | export function callWebDisconnect(data) { | ||
| 19 | return request({ | ||
| 20 | url: '/chery/call/web/disconnect', | ||
| 21 | method: 'post', | ||
| 22 | data | ||
| 23 | }) | ||
| 24 | } | ||
| 25 | |||
| 26 | /** | ||
| 27 | * 拨打电话 | ||
| 28 | * @param {*} data | ||
| 29 | */ | ||
| 30 | export function callWebIn(data) { | ||
| 31 | return request({ | ||
| 32 | url: '/chery/call/web/in', | ||
| 33 | method: 'post', | ||
| 34 | data | ||
| 35 | }) | ||
| 36 | } | ||
| 37 | /** | ||
| 38 | * 创建订单 | ||
| 39 | * @param {*} data | ||
| 40 | */ | ||
| 41 | export function createOrder(data) { | ||
| 42 | return request({ | ||
| 43 | url: 'chery/order/create', | ||
| 44 | method: 'post', | ||
| 45 | data | ||
| 46 | }) | ||
| 47 | } | ||
| 48 | /** | ||
| 49 | * 删除订单 | ||
| 50 | * @param {*} data | ||
| 51 | */ | ||
| 52 | export function deleteOrder(data) { | ||
| 53 | return request({ | ||
| 54 | url: '/chery/order-system/delete', | ||
| 55 | method: 'post', | ||
| 56 | data | ||
| 57 | }) | ||
| 58 | } | ||
| 59 | |||
| 60 | /** | ||
| 61 | * web-推送消息到app | ||
| 62 | * @param {*} data | ||
| 63 | */ | ||
| 64 | export function notifyApp(data) { | ||
| 65 | return request({ | ||
| 66 | url: '/chery/notify/app', | ||
| 67 | method: 'post', | ||
| 68 | data | ||
| 69 | }) | ||
| 70 | } | ||
| 71 | /** | ||
| 72 | * 工作台未沟通/已沟通列表 | ||
| 73 | * @param {*} data | ||
| 74 | */ | ||
| 75 | export function getCommunicationList(data) { | ||
| 76 | return request({ | ||
| 77 | url: '/chery/order/web/list', | ||
| 78 | method: 'post', | ||
| 79 | data | ||
| 80 | }) | ||
| 81 | } | ||
| 82 | /** | ||
| 83 | * WEB-获取排队列表 | ||
| 84 | * @param {*} data | ||
| 85 | */ | ||
| 86 | export function getQueueQuery(data) { | ||
| 87 | return request({ | ||
| 88 | url: '/chery/call/web/queue/query', | ||
| 89 | method: 'post', | ||
| 90 | data | ||
| 91 | }) | ||
| 92 | } | ||
| 93 | /** | ||
| 94 | *WEB-查询订单信息 | ||
| 95 | * @param {*} data | ||
| 96 | */ | ||
| 97 | export function getOrderInfo(data) { | ||
| 98 | return request({ | ||
| 99 | url: '/chery/order/fetch/order-info', | ||
| 100 | method: 'post', | ||
| 101 | data | ||
| 102 | }) | ||
| 103 | } | ||
| 104 | /** | ||
| 105 | * 二要素比图身份认证接口 | ||
| 106 | * @param {*} data | ||
| 107 | */ | ||
| 108 | export function twoElementFace(data) { | ||
| 109 | return request({ | ||
| 110 | url: '/chery/external/two-element-face/verify', | ||
| 111 | method: 'post', | ||
| 112 | data | ||
| 113 | }) | ||
| 114 | } | ||
| 115 | /** | ||
| 116 | *情绪程度识别 | ||
| 117 | * @param {*} data | ||
| 118 | */ | ||
| 119 | export function emotionRecognize(data) { | ||
| 120 | return request({ | ||
| 121 | url: '/chery/external/emotion/recognize', | ||
| 122 | method: 'post', | ||
| 123 | data | ||
| 124 | }) | ||
| 125 | } | ||
| 126 | /** | ||
| 127 | * WEB-等待接通 | ||
| 128 | * @param {*} data | ||
| 129 | */ | ||
| 130 | export function callWebWait(data) { | ||
| 131 | return request({ | ||
| 132 | url: '/chery/call/web/wait', | ||
| 133 | method: 'post', | ||
| 134 | data | ||
| 135 | }) | ||
| 136 | } | ||
| 137 | /** | ||
| 138 | * WEB-等待接通 | ||
| 139 | * @param {*} data | ||
| 140 | */ | ||
| 141 | export function callWebPoll(data) { | ||
| 142 | return request({ | ||
| 143 | url: '/chery/call/web/poll', | ||
| 144 | method: 'post', | ||
| 145 | data | ||
| 146 | }) | ||
| 147 | } |
src/assets/backimage.png
0 → 100644
1.33 MB
src/assets/ding.mp3
0 → 100644
No preview for this file type
src/assets/flower.webm
0 → 100644
No preview for this file type
src/assets/image/403.png
0 → 100644
5.41 KB
src/assets/image/403配图.png
0 → 100644
26.5 KB
src/assets/image/404.png
0 → 100644
4.29 KB
src/assets/image/404image.png
0 → 100644
40.5 KB
src/assets/image/500.png
0 → 100644
6.2 KB
src/assets/image/500配图.png
0 → 100644
35.1 KB
src/assets/image/login-bg.png
0 → 100644
470 KB
src/assets/image/login-form-bg.png
0 → 100644
5.02 KB
src/assets/image/login-form-title.png
0 → 100644
5.23 KB
src/assets/image/password.png
0 → 100644
572 Bytes
src/assets/image/user.png
0 → 100644
646 Bytes
src/assets/image/username.png
0 → 100644
612 Bytes
src/assets/image/validate.png
0 → 100644
721 Bytes
src/assets/logo.png
0 → 100644
6.69 KB
src/assets/test.jpg
0 → 100755
324 KB
src/assets/uploadInfo.png
0 → 100644
30.8 KB
src/base.scss
0 → 100644
| 1 | h1, | ||
| 2 | h2, | ||
| 3 | h3, | ||
| 4 | h4, | ||
| 5 | h5, | ||
| 6 | h6 { | ||
| 7 | padding: 0; | ||
| 8 | margin: 0; | ||
| 9 | } | ||
| 10 | |||
| 11 | .upload-cropper { | ||
| 12 | display: inline-block; | ||
| 13 | width: 300px; | ||
| 14 | background: #f2f2f2; | ||
| 15 | } | ||
| 16 | // 外边距 | ||
| 17 | .mb5 { | ||
| 18 | margin-bottom: 5px; | ||
| 19 | } | ||
| 20 | |||
| 21 | .mb10 { | ||
| 22 | margin-bottom: 10px; | ||
| 23 | } | ||
| 24 | |||
| 25 | .mb20 { | ||
| 26 | margin-bottom: 20px; | ||
| 27 | } | ||
| 28 | .mr5 { | ||
| 29 | margin-right: 5px; | ||
| 30 | } | ||
| 31 | |||
| 32 | .text-align-center { | ||
| 33 | text-align: center; | ||
| 34 | } | ||
| 35 | |||
| 36 | .forbid { | ||
| 37 | background-color: #f5f7fa; | ||
| 38 | border-color: #e4e7ed; | ||
| 39 | color: #c0c4cc; | ||
| 40 | cursor: not-allowed; | ||
| 41 | } | ||
| 42 | // 全局修改card样式 | ||
| 43 | .el-card .el-card__body { | ||
| 44 | padding: 5px; | ||
| 45 | } | ||
| 46 | |||
| 47 | // color | ||
| 48 | .white { | ||
| 49 | color: white; | ||
| 50 | } | ||
| 51 | |||
| 52 | // 图片资源 | ||
| 53 | |||
| 54 | .username-icon { | ||
| 55 | background: center no-repeat url('./assets/image/username.png'); | ||
| 56 | } | ||
| 57 | .password-icon { | ||
| 58 | background: center no-repeat url('./assets/image/password.png'); | ||
| 59 | } | ||
| 60 | .validate-icon { | ||
| 61 | background: center no-repeat url('./assets/image/validate.png'); | ||
| 62 | } | ||
| 63 | .login-form-bg { | ||
| 64 | background: center / cover no-repeat url('./assets/image/login-form-bg.png'); | ||
| 65 | } |
src/components/bread/Bread.vue
0 → 100644
| 1 | <template> | ||
| 2 | <div class="bread"> | ||
| 3 | <div> | ||
| 4 | <slot name="title"></slot> | ||
| 5 | <span class="btn"> | ||
| 6 | <slot name="btn"></slot> | ||
| 7 | </span> | ||
| 8 | </div> | ||
| 9 | <el-button | ||
| 10 | v-if="isShowBack" | ||
| 11 | type="text" | ||
| 12 | style="margin-right:50px;" | ||
| 13 | @click="handleClick" | ||
| 14 | >返回</el-button | ||
| 15 | > | ||
| 16 | </div> | ||
| 17 | </template> | ||
| 18 | <script> | ||
| 19 | export default { | ||
| 20 | name: 'Bread', | ||
| 21 | props: { | ||
| 22 | isShowBack: { | ||
| 23 | type: Boolean, | ||
| 24 | default: false | ||
| 25 | } | ||
| 26 | }, | ||
| 27 | methods: { | ||
| 28 | handleClick() { | ||
| 29 | this.$router.go(-1) | ||
| 30 | } | ||
| 31 | } | ||
| 32 | } | ||
| 33 | </script> | ||
| 34 | <style lang="scss" scoped> | ||
| 35 | .bread { | ||
| 36 | display: flex; | ||
| 37 | align-items: center; | ||
| 38 | justify-content: space-between; | ||
| 39 | height: 50px; | ||
| 40 | border-left: 5px solid #3f51b5; | ||
| 41 | padding-left: 15px; | ||
| 42 | font-size: 16px; | ||
| 43 | font-weight: 700; | ||
| 44 | .btn { | ||
| 45 | display: inline-block; | ||
| 46 | color: #3f51b5; | ||
| 47 | margin-left: 15px; | ||
| 48 | font-size: 20px; | ||
| 49 | cursor: pointer; | ||
| 50 | } | ||
| 51 | } | ||
| 52 | </style> |
src/components/bread/index.js
0 → 100644
src/components/card/index.vue
0 → 100644
| 1 | <template> | ||
| 2 | <div class="card-com"> | ||
| 3 | <div><slot name="title"></slot></div> | ||
| 4 | <slot></slot> | ||
| 5 | </div> | ||
| 6 | </template> | ||
| 7 | |||
| 8 | <script> | ||
| 9 | export default {} | ||
| 10 | </script> | ||
| 11 | |||
| 12 | <style lang="scss" scoped> | ||
| 13 | .card-com { | ||
| 14 | padding: 28px 24px; | ||
| 15 | box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); | ||
| 16 | box-sizing: border-box; | ||
| 17 | background-color: #fff; | ||
| 18 | } | ||
| 19 | </style> |
src/components/countUp/index.vue
0 → 100644
| 1 | <template lang="pug"> | ||
| 2 | span(ref="countUp") | ||
| 3 | </template> | ||
| 4 | <script> | ||
| 5 | import { CountUp } from 'countup.js' | ||
| 6 | |||
| 7 | export default { | ||
| 8 | name: 'CountUp', | ||
| 9 | props: { | ||
| 10 | // 目标数字 | ||
| 11 | end: { | ||
| 12 | type: Number, | ||
| 13 | default: 0 | ||
| 14 | }, | ||
| 15 | // 默认配置 | ||
| 16 | options: { | ||
| 17 | type: Object, | ||
| 18 | default: () => { | ||
| 19 | return { | ||
| 20 | startVal: 0, | ||
| 21 | decimalPlaces: 0, | ||
| 22 | duration: 1, | ||
| 23 | separator: ',', | ||
| 24 | decimal: '.' | ||
| 25 | } | ||
| 26 | } | ||
| 27 | } | ||
| 28 | }, | ||
| 29 | data() { | ||
| 30 | return { | ||
| 31 | numAnim: null | ||
| 32 | } | ||
| 33 | }, | ||
| 34 | watch: { | ||
| 35 | end: { | ||
| 36 | handler(newVal, oldVal) { | ||
| 37 | this.numAnim.update(newVal) | ||
| 38 | } | ||
| 39 | } | ||
| 40 | }, | ||
| 41 | mounted() { | ||
| 42 | this.initCountUp() | ||
| 43 | }, | ||
| 44 | beforeDestroy() { | ||
| 45 | this.numAnim = null | ||
| 46 | }, | ||
| 47 | methods: { | ||
| 48 | initCountUp() { | ||
| 49 | this.numAnim = new CountUp(this.$refs.countUp, this.end, this.options) | ||
| 50 | if (!this.numAnim.error) { | ||
| 51 | this.numAnim.start() | ||
| 52 | } else { | ||
| 53 | console.error(this.numAnim.error) | ||
| 54 | } | ||
| 55 | } | ||
| 56 | } | ||
| 57 | } | ||
| 58 | </script> |
src/components/iconComponent/index.vue
0 → 100644
| 1 | <template> | ||
| 2 | <svg :class="svgClass" aria-hidden="true"> | ||
| 3 | <use :xlink:href="iconName"></use> | ||
| 4 | </svg> | ||
| 5 | </template> | ||
| 6 | |||
| 7 | <script> | ||
| 8 | export default { | ||
| 9 | name: 'icon-svg', | ||
| 10 | props: { | ||
| 11 | iconClass: { | ||
| 12 | type: String, | ||
| 13 | required: true | ||
| 14 | }, | ||
| 15 | className: { | ||
| 16 | type: String | ||
| 17 | } | ||
| 18 | }, | ||
| 19 | computed: { | ||
| 20 | iconName() { | ||
| 21 | return `#icon-${this.iconClass}` | ||
| 22 | }, | ||
| 23 | svgClass() { | ||
| 24 | if (this.className) { | ||
| 25 | return `svg-icon ${this.className}` | ||
| 26 | } else { | ||
| 27 | return `svg-icon` | ||
| 28 | } | ||
| 29 | } | ||
| 30 | } | ||
| 31 | } | ||
| 32 | </script> | ||
| 33 | |||
| 34 | <style> | ||
| 35 | .svg-icon { | ||
| 36 | width: 1em; | ||
| 37 | height: 1em; | ||
| 38 | fill: currentColor; | ||
| 39 | overflow: hidden; | ||
| 40 | } | ||
| 41 | </style> |
src/components/loginForm/LoginForm.vue
0 → 100644
| 1 | <template lang="pug"> | ||
| 2 | div(class="login-main login-form-bg") | ||
| 3 | div(class="title") | ||
| 4 | .main-content | ||
| 5 | el-form(:model="loginForm" ref="form" :rules="rules" @keydown.enter.native="login") | ||
| 6 | el-form-item(prop="username") | ||
| 7 | el-input( | ||
| 8 | ref="username" | ||
| 9 | size="medium" | ||
| 10 | class="login-input" | ||
| 11 | placeholder="请输入工号" | ||
| 12 | v-model.trim="loginForm.username" | ||
| 13 | ) | ||
| 14 | i(slot="prefix" class="icon username-icon") | ||
| 15 | el-form-item(prop="password") | ||
| 16 | el-input( | ||
| 17 | ref="password" | ||
| 18 | type="password" | ||
| 19 | size="medium" | ||
| 20 | placeholder="请输入密码" | ||
| 21 | class="login-input" | ||
| 22 | v-model.trim="loginForm.password" | ||
| 23 | ) | ||
| 24 | i(slot="prefix" class="icon password-icon") | ||
| 25 | el-form-item(prop="verificationCode") | ||
| 26 | .captcha | ||
| 27 | el-input( | ||
| 28 | size="medium" | ||
| 29 | placeholder="请输入验证码" | ||
| 30 | class="captcha-input" | ||
| 31 | v-model.trim="loginForm.verificationCode" | ||
| 32 | ) | ||
| 33 | i(slot="prefix" class="icon validate-icon") | ||
| 34 | <canvas width="93" height="36" id="captcha1"></canvas> | ||
| 35 | el-form-item | ||
| 36 | .buton-warp | ||
| 37 | el-button(class="login-btn" type="primary" @click="login" :loading="loading") | ||
| 38 | span(class="login-btn-text") 登 录 | ||
| 39 | </template> | ||
| 40 | |||
| 41 | <script> | ||
| 42 | import Captcha from 'captcha-mini' | ||
| 43 | import { maxSizeValidate } from '@/views/validate' | ||
| 44 | |||
| 45 | export default { | ||
| 46 | name: 'LoginForm', | ||
| 47 | props: { | ||
| 48 | usernameRules: { | ||
| 49 | type: Array, | ||
| 50 | default: () => { | ||
| 51 | return [ | ||
| 52 | { required: true, message: '账号不能为空', trigger: 'blur' }, | ||
| 53 | maxSizeValidate | ||
| 54 | ] | ||
| 55 | } | ||
| 56 | }, | ||
| 57 | passwordRules: { | ||
| 58 | type: Array, | ||
| 59 | default: () => { | ||
| 60 | return [ | ||
| 61 | { required: true, message: '密码不能为空', trigger: 'blur' }, | ||
| 62 | maxSizeValidate | ||
| 63 | ] | ||
| 64 | } | ||
| 65 | }, | ||
| 66 | loading: { | ||
| 67 | type: Boolean, | ||
| 68 | default: false | ||
| 69 | } | ||
| 70 | }, | ||
| 71 | data() { | ||
| 72 | return { | ||
| 73 | verCode: '', | ||
| 74 | captcha1: null, | ||
| 75 | loginForm: { | ||
| 76 | username: '', | ||
| 77 | password: '', | ||
| 78 | verificationCode: '' | ||
| 79 | } | ||
| 80 | } | ||
| 81 | }, | ||
| 82 | computed: { | ||
| 83 | rules() { | ||
| 84 | return { | ||
| 85 | username: this.usernameRules, | ||
| 86 | password: this.passwordRules, | ||
| 87 | verificationCode: [ | ||
| 88 | { | ||
| 89 | validator: (rule, value, callback) => { | ||
| 90 | if (value === '') { | ||
| 91 | return callback(new Error('验证码不能为空')) | ||
| 92 | } | ||
| 93 | if (value.toLowerCase() !== this.verCode.toLowerCase()) { | ||
| 94 | return callback(new Error('请输入正确的验证码')) | ||
| 95 | } else { | ||
| 96 | callback() | ||
| 97 | } | ||
| 98 | }, | ||
| 99 | trigger: 'blur' | ||
| 100 | }, | ||
| 101 | maxSizeValidate | ||
| 102 | ] | ||
| 103 | } | ||
| 104 | } | ||
| 105 | }, | ||
| 106 | mounted() { | ||
| 107 | if (this.loginForm.username === '') { | ||
| 108 | this.$refs.username.focus() | ||
| 109 | } | ||
| 110 | this.captcha1 = new Captcha() | ||
| 111 | this.updateCaptcha() | ||
| 112 | }, | ||
| 113 | methods: { | ||
| 114 | login() { | ||
| 115 | this.$refs.form.validate(valid => { | ||
| 116 | if (valid) { | ||
| 117 | this.$emit('on-success-valid', { | ||
| 118 | username: this.loginForm.username, | ||
| 119 | password: this.loginForm.password | ||
| 120 | }) | ||
| 121 | } else { | ||
| 122 | this.updateCaptcha() | ||
| 123 | } | ||
| 124 | }) | ||
| 125 | }, | ||
| 126 | updateCaptcha() { | ||
| 127 | this.captcha1.draw(document.querySelector('#captcha1'), r => { | ||
| 128 | this.verCode = r | ||
| 129 | }) | ||
| 130 | } | ||
| 131 | } | ||
| 132 | } | ||
| 133 | </script> | ||
| 134 | |||
| 135 | <style lang="scss"> | ||
| 136 | .login-main { | ||
| 137 | height: 420px; | ||
| 138 | width: 420px; | ||
| 139 | display: flex; | ||
| 140 | flex-flow: column nowrap; | ||
| 141 | align-items: center; | ||
| 142 | padding: 0 48px; | ||
| 143 | box-sizing: border-box; | ||
| 144 | .title { | ||
| 145 | width: 292px; | ||
| 146 | height: 36px; | ||
| 147 | margin: 32px 0 36px 0; | ||
| 148 | } | ||
| 149 | .main-content { | ||
| 150 | .captcha { | ||
| 151 | display: flex; | ||
| 152 | } | ||
| 153 | .login-btn { | ||
| 154 | width: 100%; | ||
| 155 | height: 48px; | ||
| 156 | .login-btn-text { | ||
| 157 | font-size: 18px; | ||
| 158 | } | ||
| 159 | } | ||
| 160 | } | ||
| 161 | } | ||
| 162 | // 重置输入框 图标 | ||
| 163 | .login-input { | ||
| 164 | .el-input__prefix { | ||
| 165 | display: inline-flex; | ||
| 166 | align-items: center; | ||
| 167 | } | ||
| 168 | .el-input__inner { | ||
| 169 | height: 44px; | ||
| 170 | width: 324px; | ||
| 171 | } | ||
| 172 | } | ||
| 173 | .captcha-input { | ||
| 174 | margin-right: 7px; | ||
| 175 | .el-input__prefix { | ||
| 176 | display: inline-flex; | ||
| 177 | align-items: center; | ||
| 178 | } | ||
| 179 | .el-input__inner { | ||
| 180 | height: 44px; | ||
| 181 | } | ||
| 182 | } | ||
| 183 | .login-input, | ||
| 184 | .captcha-input { | ||
| 185 | .el-input__inner { | ||
| 186 | background: #0f1f3b; | ||
| 187 | padding-left: 46px; | ||
| 188 | color: rgba(255, 255, 255, 1); | ||
| 189 | background: rgba(193, 225, 253, 0.03); | ||
| 190 | border-radius: 4px; | ||
| 191 | border: 1px solid rgba(24, 144, 255, 0.2); | ||
| 192 | } | ||
| 193 | .el-input__inner:active, | ||
| 194 | .el-input__inner:focus { | ||
| 195 | background: rgba(193, 225, 253, 0.03); | ||
| 196 | border-radius: 4px; | ||
| 197 | border: 1px solid rgba(94, 178, 255, 0.8); | ||
| 198 | } | ||
| 199 | .el-input__prefix { | ||
| 200 | left: 14px; | ||
| 201 | } | ||
| 202 | } | ||
| 203 | .icon { | ||
| 204 | width: 20px; | ||
| 205 | height: 20px; | ||
| 206 | display: inline-block; | ||
| 207 | } | ||
| 208 | </style> |
src/components/loginForm/index.js
0 → 100644
src/components/magnifierImage/index.vue
0 → 100644
| 1 | <template> | ||
| 2 | <div | ||
| 3 | class="wrapper" | ||
| 4 | ref="wrapper" | ||
| 5 | @mousemove="mousemove" | ||
| 6 | @mouseenter="mouseenter" | ||
| 7 | @mouseleave="mouseleave" | ||
| 8 | @wheel="zoom" | ||
| 9 | > | ||
| 10 | <transition name="fade"> | ||
| 11 | <div class="zoomed-container" v-show="isShow"> | ||
| 12 | <div | ||
| 13 | class="transform-view" | ||
| 14 | :style="{ | ||
| 15 | transform: `scale(${tempScale}, ${tempScale}) translate(${translateX}%, ${translateY}%)` | ||
| 16 | }" | ||
| 17 | > | ||
| 18 | <img :src="url" alt="" /> | ||
| 19 | </div> | ||
| 20 | </div> | ||
| 21 | </transition> | ||
| 22 | <div class="view"> | ||
| 23 | <img :src="url" alt="" /> | ||
| 24 | </div> | ||
| 25 | </div> | ||
| 26 | </template> | ||
| 27 | |||
| 28 | <script> | ||
| 29 | import url from '@/assets/test.jpg' | ||
| 30 | |||
| 31 | export default { | ||
| 32 | props: { | ||
| 33 | scale: { | ||
| 34 | type: Number, | ||
| 35 | default: 2, | ||
| 36 | validator: val => { | ||
| 37 | if (val >= 1 && val <= 10) { | ||
| 38 | return val | ||
| 39 | } else { | ||
| 40 | return 1 | ||
| 41 | } | ||
| 42 | } | ||
| 43 | } | ||
| 44 | }, | ||
| 45 | data() { | ||
| 46 | return { | ||
| 47 | url, | ||
| 48 | translateX: 0, | ||
| 49 | translateY: 0, | ||
| 50 | tempScale: this.scale, | ||
| 51 | isShow: false | ||
| 52 | } | ||
| 53 | }, | ||
| 54 | methods: { | ||
| 55 | zoom(e) { | ||
| 56 | e.preventDefault() | ||
| 57 | this.tempScale += e.deltaY * -0.01 | ||
| 58 | this.tempScale = Math.min(Math.max(1, this.tempScale), 10) | ||
| 59 | }, | ||
| 60 | mousemove(e) { | ||
| 61 | const { | ||
| 62 | left, | ||
| 63 | top, | ||
| 64 | width, | ||
| 65 | height | ||
| 66 | } = this.$refs.wrapper.getBoundingClientRect() | ||
| 67 | const x = e.clientX | ||
| 68 | const y = e.clientY | ||
| 69 | const percentW = (x - left) / width | ||
| 70 | const percentH = (y - top) / height | ||
| 71 | this.translateX = (0.4 - percentW) * 100 | ||
| 72 | this.translateY = (0.4 - percentH) * 100 | ||
| 73 | }, | ||
| 74 | mouseenter() { | ||
| 75 | this.isShow = true | ||
| 76 | }, | ||
| 77 | mouseleave() { | ||
| 78 | this.isShow = false | ||
| 79 | } | ||
| 80 | } | ||
| 81 | } | ||
| 82 | </script> | ||
| 83 | |||
| 84 | <style lang="scss" scoped> | ||
| 85 | // 过度效果 | ||
| 86 | .fade-enter-active, | ||
| 87 | .fade-leave-active { | ||
| 88 | transition: opacity 0.5s; | ||
| 89 | } | ||
| 90 | .fade-enter, | ||
| 91 | .fade-leave-to { | ||
| 92 | opacity: 0; | ||
| 93 | } | ||
| 94 | .wrapper { | ||
| 95 | width: 400px; | ||
| 96 | height: 357px; | ||
| 97 | position: relative; | ||
| 98 | overflow: hidden; | ||
| 99 | box-sizing: border-box; | ||
| 100 | .zoomed-container { | ||
| 101 | background: #000; | ||
| 102 | position: absolute; | ||
| 103 | left: 5px; | ||
| 104 | top: 5px; | ||
| 105 | right: 5px; | ||
| 106 | bottom: 5px; | ||
| 107 | z-index: 9999; | ||
| 108 | overflow: hidden; | ||
| 109 | .transform-view { | ||
| 110 | position: absolute; | ||
| 111 | top: 0; | ||
| 112 | left: 0; | ||
| 113 | bottom: 0; | ||
| 114 | right: 0; | ||
| 115 | text-align: center; | ||
| 116 | img { | ||
| 117 | height: 100%; | ||
| 118 | } | ||
| 119 | } | ||
| 120 | } | ||
| 121 | .view { | ||
| 122 | position: absolute; | ||
| 123 | left: 5px; | ||
| 124 | top: 5px; | ||
| 125 | right: 5px; | ||
| 126 | bottom: 5px; | ||
| 127 | text-align: center; | ||
| 128 | img { | ||
| 129 | height: 100%; | ||
| 130 | } | ||
| 131 | } | ||
| 132 | } | ||
| 133 | </style> |
src/components/playAudio/index.vue
0 → 100644
| 1 | <template lang="pug"> | ||
| 2 | .play-audio | ||
| 3 | audio(ref="audio" :src="mp3") | ||
| 4 | </template> | ||
| 5 | <script> | ||
| 6 | import mp3 from '@/assets/ding.mp3' | ||
| 7 | export default { | ||
| 8 | name: 'PlayAudio', | ||
| 9 | props: { | ||
| 10 | mp3: { | ||
| 11 | type: [String, Blob, null], | ||
| 12 | default: mp3 | ||
| 13 | } | ||
| 14 | }, | ||
| 15 | data() { | ||
| 16 | return { | ||
| 17 | audioStatus: 'pause', | ||
| 18 | audioDuration: 0 | ||
| 19 | } | ||
| 20 | }, | ||
| 21 | methods: { | ||
| 22 | /** | ||
| 23 | * 播放提示音 | ||
| 24 | * */ | ||
| 25 | playMusic() { | ||
| 26 | if (this.audioStatus === 'pause') { | ||
| 27 | this.$refs.audio.play() | ||
| 28 | this.audioStatus = 'play' | ||
| 29 | } else { | ||
| 30 | this.$refs.audio.pause() | ||
| 31 | this.$refs.audio.currentTime = 0 | ||
| 32 | this.audioStatus = 'pause' | ||
| 33 | } | ||
| 34 | } | ||
| 35 | }, | ||
| 36 | mounted() { | ||
| 37 | this.$refs.audio.addEventListener('ended', () => { | ||
| 38 | this.$refs.audio.pause() | ||
| 39 | this.audioStatus = 'pause' | ||
| 40 | }) | ||
| 41 | } | ||
| 42 | } | ||
| 43 | </script> |
src/components/streamStartStep/index.vue
0 → 100644
| 1 | <template lang="pug"> | ||
| 2 | .start-step | ||
| 3 | el-button(type="primary" icon="el-icon-caret-right" class="btn" v-on="buttonListeners") 开始 | ||
| 4 | </template> | ||
| 5 | <script> | ||
| 6 | export default { | ||
| 7 | computed: { | ||
| 8 | buttonListeners() { | ||
| 9 | return Object.assign({}, this.$listeners) | ||
| 10 | } | ||
| 11 | } | ||
| 12 | } | ||
| 13 | </script> | ||
| 14 | <style lang="scss" scoped> | ||
| 15 | .start-step { | ||
| 16 | display: flex; | ||
| 17 | justify-content: center; | ||
| 18 | align-items: center; | ||
| 19 | width: 100%; | ||
| 20 | height: 100%; | ||
| 21 | background-color: #eee; | ||
| 22 | .btn { | ||
| 23 | display: flex; | ||
| 24 | justify-content: flex-start; | ||
| 25 | align-items: center; | ||
| 26 | width: 100px; | ||
| 27 | height: 70px; | ||
| 28 | font-size: 23px; | ||
| 29 | font-weight: 900; | ||
| 30 | padding: 0 10px; | ||
| 31 | border-radius: 13px; | ||
| 32 | box-shadow: 4px 5px 3px; | ||
| 33 | .el-icon-caret-right { | ||
| 34 | font-size: 50px; | ||
| 35 | } | ||
| 36 | } | ||
| 37 | } | ||
| 38 | </style> | ||
| 39 | <style lang="scss"> | ||
| 40 | .start-step { | ||
| 41 | .btn { | ||
| 42 | .el-icon-caret-right { | ||
| 43 | font-size: 50px; | ||
| 44 | margin-left: -20px; | ||
| 45 | } | ||
| 46 | } | ||
| 47 | } | ||
| 48 | </style> |
src/components/titleLine/index.vue
0 → 100644
| 1 | <template lang="pug"> | ||
| 2 | .title-line | ||
| 3 | .header-wrapper | ||
| 4 | .left | ||
| 5 | slot(name="title") | ||
| 6 | .info | ||
| 7 | slot(name="info") | ||
| 8 | .right | ||
| 9 | slot(name="right") | ||
| 10 | .main | ||
| 11 | slot | ||
| 12 | </template> | ||
| 13 | <script> | ||
| 14 | export default { | ||
| 15 | name: 'TitleLine' | ||
| 16 | } | ||
| 17 | </script> | ||
| 18 | <style lang="scss" scoped> | ||
| 19 | .title-line{ | ||
| 20 | width: 100%; | ||
| 21 | font-size: 18px; | ||
| 22 | .header-wrapper{ | ||
| 23 | color: #fff; | ||
| 24 | display: flex; | ||
| 25 | justify-content: flex-start; | ||
| 26 | align-items: center; | ||
| 27 | background: #a3add8; | ||
| 28 | height: 30px; | ||
| 29 | padding: 5px 10px; | ||
| 30 | .left{ | ||
| 31 | padding-right: 5px; | ||
| 32 | } | ||
| 33 | .right{ | ||
| 34 | flex: auto; | ||
| 35 | display: flex; | ||
| 36 | justify-content: flex-end; | ||
| 37 | } | ||
| 38 | } | ||
| 39 | .main{ | ||
| 40 | padding: 10px 5px; | ||
| 41 | } | ||
| 42 | } | ||
| 43 | </style> |
src/components/topTeskDetail/index.vue
0 → 100644
| 1 | <template lang="pug"> | ||
| 2 | .top-tesk-detail | ||
| 3 | .status-text {{statusText}} | ||
| 4 | el-switch( | ||
| 5 | :value="copyValue" | ||
| 6 | @change="change" | ||
| 7 | ) | ||
| 8 | template(v-if="isOpen") | ||
| 9 | .task-info | ||
| 10 | .over-task.mr5 剩余任务 | ||
| 11 | .mr5 已完成 | ||
| 12 | .already.mr5 {{completed}} | ||
| 13 | .mr5 待质检 | ||
| 14 | .wait.mr5 {{wait}} | ||
| 15 | .countDown(v-if="copyCountDownTime !== 0") {{countDownText}} | ||
| 16 | </template> | ||
| 17 | <script> | ||
| 18 | export default { | ||
| 19 | name: 'TopTeskDetails', | ||
| 20 | props: { | ||
| 21 | isOpen: { | ||
| 22 | type: Boolean, | ||
| 23 | required: true | ||
| 24 | }, | ||
| 25 | completed: { | ||
| 26 | type: [Number, String], | ||
| 27 | default: 0 | ||
| 28 | }, | ||
| 29 | wait: { | ||
| 30 | type: [Number, String], | ||
| 31 | default: 0 | ||
| 32 | }, | ||
| 33 | countDownTime: { | ||
| 34 | type: Number, | ||
| 35 | default: 0 | ||
| 36 | } | ||
| 37 | }, | ||
| 38 | data() { | ||
| 39 | return { | ||
| 40 | timer: null, // 计时器 | ||
| 41 | second: this.timeout, // 倒计时时间 | ||
| 42 | copyValue: this.isOpen, | ||
| 43 | copyCountDownTime: this.countDownTime | ||
| 44 | } | ||
| 45 | }, | ||
| 46 | computed: { | ||
| 47 | statusText() { | ||
| 48 | return this.isOpen ? '进行中' : '开始' | ||
| 49 | }, | ||
| 50 | countDownText() { | ||
| 51 | return this.copyCountDownTime === 0 ? '-' : this.copyCountDownTime | ||
| 52 | } | ||
| 53 | }, | ||
| 54 | watch: { | ||
| 55 | isOpen: { | ||
| 56 | handler(val) { | ||
| 57 | if (val && this.copyCountDownTime) { | ||
| 58 | this.startTimeout() | ||
| 59 | } | ||
| 60 | }, | ||
| 61 | immediate: true | ||
| 62 | } | ||
| 63 | }, | ||
| 64 | methods: { | ||
| 65 | startTimeout() { | ||
| 66 | setTimeout(this.nextSecond, 1000) | ||
| 67 | }, | ||
| 68 | nextSecond() { | ||
| 69 | this.copyCountDownTime-- | ||
| 70 | if (this.copyCountDownTime === 0) { | ||
| 71 | this.$emit('update:isOpen', false) | ||
| 72 | return | ||
| 73 | } | ||
| 74 | setTimeout(this.nextSecond, 1000) | ||
| 75 | }, | ||
| 76 | change(val) { | ||
| 77 | this.$nextTick(() => { | ||
| 78 | this.$emit('update:isOpen', val) | ||
| 79 | }) | ||
| 80 | } | ||
| 81 | } | ||
| 82 | } | ||
| 83 | </script> | ||
| 84 | <style lang="scss" scoped> | ||
| 85 | .top-tesk-detail { | ||
| 86 | height: 35px; | ||
| 87 | display: flex; | ||
| 88 | flex-flow: row nowrap; | ||
| 89 | justify-content: flex-start; | ||
| 90 | align-items: center; | ||
| 91 | .status-text { | ||
| 92 | width: 70px; | ||
| 93 | text-align: center; | ||
| 94 | font-size: 16px; | ||
| 95 | color: #333; | ||
| 96 | font-weight: 600; | ||
| 97 | } | ||
| 98 | .task-info { | ||
| 99 | margin: 0 5px; | ||
| 100 | font-size: 14px; | ||
| 101 | display: flex; | ||
| 102 | align-items: center; | ||
| 103 | .over-task { | ||
| 104 | font-weight: 500; | ||
| 105 | } | ||
| 106 | .already { | ||
| 107 | padding: 0 5px; | ||
| 108 | border-radius: 3px; | ||
| 109 | background-color: #52c3f1; | ||
| 110 | } | ||
| 111 | .wait { | ||
| 112 | padding: 0 5px; | ||
| 113 | border-radius: 3px; | ||
| 114 | background-color: #f19b12; | ||
| 115 | } | ||
| 116 | } | ||
| 117 | /* 倒计时*/ | ||
| 118 | .countDown { | ||
| 119 | width: 35px; | ||
| 120 | height: 35px; | ||
| 121 | display: flex; | ||
| 122 | justify-content: center; | ||
| 123 | align-items: center; | ||
| 124 | font-size: 12px; | ||
| 125 | border-radius: 50%; | ||
| 126 | border: 3px solid #3f51b5; | ||
| 127 | box-sizing: border-box; | ||
| 128 | } | ||
| 129 | } | ||
| 130 | </style> |
src/components/uploadInput/index.vue
0 → 100644
| 1 | <template> | ||
| 2 | <div class="upload-wrapper"> | ||
| 3 | <label>{{ placeholderCopy }}</label> | ||
| 4 | <div class="uw-right"> | ||
| 5 | <el-button class="uw-btn"> | ||
| 6 | <slot></slot> | ||
| 7 | </el-button> | ||
| 8 | <input | ||
| 9 | class="uw-input" | ||
| 10 | type="file" | ||
| 11 | id="image_uploads" | ||
| 12 | name="image_uploads" | ||
| 13 | :accept="accept" | ||
| 14 | :multiple="multiple" | ||
| 15 | @change="handleChange" | ||
| 16 | /> | ||
| 17 | </div> | ||
| 18 | </div> | ||
| 19 | </template> | ||
| 20 | |||
| 21 | <script> | ||
| 22 | export default { | ||
| 23 | props: { | ||
| 24 | placeholder: { | ||
| 25 | type: String, | ||
| 26 | default: '上传图片,可多选' | ||
| 27 | }, | ||
| 28 | accept: { | ||
| 29 | type: String, | ||
| 30 | default: '.jpg, .jpeg, .png, .JPG, .JPEG, .PNG, .bmp, .BMP' | ||
| 31 | }, | ||
| 32 | multiple: { | ||
| 33 | type: Boolean, | ||
| 34 | default: false | ||
| 35 | }, | ||
| 36 | onExceed: { | ||
| 37 | type: Function, | ||
| 38 | default: () => {} | ||
| 39 | }, | ||
| 40 | limit: { | ||
| 41 | type: Number | ||
| 42 | }, | ||
| 43 | onChange: { | ||
| 44 | type: Function, | ||
| 45 | default: () => {} | ||
| 46 | } | ||
| 47 | }, | ||
| 48 | data() { | ||
| 49 | return { | ||
| 50 | placeholderCopy: this.placeholder | ||
| 51 | } | ||
| 52 | }, | ||
| 53 | methods: { | ||
| 54 | handleChange(e) { | ||
| 55 | const files = e.currentTarget.files | ||
| 56 | const length = files.length | ||
| 57 | if (!this.isValidator(files)) { | ||
| 58 | this.$emit('onFail', files) | ||
| 59 | return | ||
| 60 | } | ||
| 61 | if (this.limit && length > this.limit) { | ||
| 62 | this.onExceed() | ||
| 63 | return | ||
| 64 | } | ||
| 65 | if (files.length > 0) { | ||
| 66 | this.placeholderCopy = files[0].name | ||
| 67 | this.onChange(Array.from(files)) | ||
| 68 | } | ||
| 69 | }, | ||
| 70 | getAcceptType() { | ||
| 71 | const arr = this.accept | ||
| 72 | .toLowerCase() | ||
| 73 | .split(',') | ||
| 74 | .map(item => `image/${item.slice(item.indexOf('.') + 1)}`) | ||
| 75 | return Array.from(new Set(arr)) | ||
| 76 | }, | ||
| 77 | isValidator(files) { | ||
| 78 | return Array.from(files).every(file => | ||
| 79 | this.getAcceptType().includes(file.type) | ||
| 80 | ) | ||
| 81 | } | ||
| 82 | }, | ||
| 83 | mounted() { | ||
| 84 | this.getAcceptType() | ||
| 85 | } | ||
| 86 | } | ||
| 87 | </script> | ||
| 88 | |||
| 89 | <style lang="scss" scoped> | ||
| 90 | .upload-wrapper { | ||
| 91 | width: 300px; | ||
| 92 | height: 42px; | ||
| 93 | background: #f2f2f2; | ||
| 94 | display: inline-block; | ||
| 95 | position: relative; | ||
| 96 | label { | ||
| 97 | font-size: 12px; | ||
| 98 | line-height: 42px; | ||
| 99 | width: 100%; | ||
| 100 | display: inline-block; | ||
| 101 | height: 100%; | ||
| 102 | overflow: hidden; | ||
| 103 | } | ||
| 104 | .uw-right { | ||
| 105 | position: absolute; | ||
| 106 | top: 0; | ||
| 107 | bottom: 0; | ||
| 108 | right: 0; | ||
| 109 | width: 70px; | ||
| 110 | } | ||
| 111 | input { | ||
| 112 | position: absolute; | ||
| 113 | top: 0; | ||
| 114 | bottom: 0; | ||
| 115 | right: 0; | ||
| 116 | width: 100%; | ||
| 117 | height: 100%; | ||
| 118 | opacity: 0; | ||
| 119 | cursor: pointer; | ||
| 120 | } | ||
| 121 | } | ||
| 122 | </style> |
src/components/videoPlayer/index.vue
0 → 100644
| 1 | <template> | ||
| 2 | <div class="video-player"> | ||
| 3 | <video | ||
| 4 | id="my-player" | ||
| 5 | ref="videoPlayer" | ||
| 6 | class="video-js vjs-big-play-centered" | ||
| 7 | controlslist="nodownload" | ||
| 8 | crossorigin="anonymous" | ||
| 9 | oncontextmenu="return false;" | ||
| 10 | controls | ||
| 11 | ></video> | ||
| 12 | </div> | ||
| 13 | </template> | ||
| 14 | |||
| 15 | <script> | ||
| 16 | import videojs from 'video.js' | ||
| 17 | import { throttle } from '@/utils/util' | ||
| 18 | const mirrerIcon = | ||
| 19 | '<svg t="1594374364946" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2814" width="16" height="16"><path d="M424.2 230.4c0.6 0.2 1.2 0.4 1.6 0.5L160.6 148c-2.9-0.6-6-0.9-9.2-0.9-24.5 0-44.4 19.9-44.4 44.4v634.8c0 24.6 19.9 44.5 44.4 44.5 3.2 0 6.2-0.4 9.2-0.9L432.4 785c17.9-9.2 30.1-27.9 30.1-49.3V283.2c-0.1-24.6-16.1-45.6-38.3-52.8z m-28.4 485.9l-222.1 59.2V242.3l222.1 59.2v414.8z m466.4-569.2c-3.2 0-6.2 0.4-9.2 0.9l-262 82c0.4-0.1 0.7-0.1 0.9-0.2-23.5 6.5-40.8 28-40.8 53.5v452.3c0 21.5 12.2 40.1 30.1 49.4l271.6 84.9c2.9 0.6 6.1 0.9 9.3 0.9 24.5 0 44.4-19.9 44.4-44.5V191.5c0.2-24.5-19.7-44.4-44.3-44.4z" p-id="2815" fill="#ffffff"></path></svg>' | ||
| 20 | // 热键 | ||
| 21 | const leftKey = 37 | ||
| 22 | const rightKey = 39 | ||
| 23 | const spaceKey = 32 | ||
| 24 | const enterKey = 13 | ||
| 25 | |||
| 26 | export default { | ||
| 27 | props: { | ||
| 28 | singHoldingTime: { | ||
| 29 | type: Object, | ||
| 30 | default: () => { | ||
| 31 | return { | ||
| 32 | // signing: { | ||
| 33 | // beginTime: 3, | ||
| 34 | // endTime: 5 | ||
| 35 | // }, | ||
| 36 | // holding: [ | ||
| 37 | // { | ||
| 38 | // beginTime: 20, | ||
| 39 | // endTime: 25 | ||
| 40 | // } | ||
| 41 | // ] | ||
| 42 | } | ||
| 43 | } | ||
| 44 | }, | ||
| 45 | pointList: { | ||
| 46 | type: Array, | ||
| 47 | default: () => { | ||
| 48 | return [ | ||
| 49 | // { | ||
| 50 | // text: '沙和尚', | ||
| 51 | // time: 3 | ||
| 52 | // }, | ||
| 53 | // { | ||
| 54 | // text: '沙和尚', | ||
| 55 | // time: 5 | ||
| 56 | // }, | ||
| 57 | // { | ||
| 58 | // text: '沙和尚', | ||
| 59 | // time: 7 | ||
| 60 | // } | ||
| 61 | ] | ||
| 62 | } | ||
| 63 | }, | ||
| 64 | url: { | ||
| 65 | type: String, | ||
| 66 | default: '' | ||
| 67 | }, | ||
| 68 | // 快进快退的s | ||
| 69 | fastSeconds: { | ||
| 70 | type: Number, | ||
| 71 | default: 5 | ||
| 72 | }, | ||
| 73 | previewImage: { | ||
| 74 | type: Array, | ||
| 75 | default: () => { | ||
| 76 | return [ | ||
| 77 | // { | ||
| 78 | // img: 'https://tupian.sioe.cn/b/bing-home-image/pic/20140801.jpg', | ||
| 79 | // time: 3 | ||
| 80 | // }, | ||
| 81 | ] | ||
| 82 | } | ||
| 83 | } | ||
| 84 | }, | ||
| 85 | data() { | ||
| 86 | return { | ||
| 87 | player: null, | ||
| 88 | duration: 0, | ||
| 89 | signingColor: '#e11920', | ||
| 90 | holdingColor: '#ffd800' | ||
| 91 | } | ||
| 92 | }, | ||
| 93 | computed: { | ||
| 94 | videoEle() { | ||
| 95 | return this.$refs.videoPlayer | ||
| 96 | } | ||
| 97 | }, | ||
| 98 | watch: { | ||
| 99 | url: { | ||
| 100 | handler(val) { | ||
| 101 | // 重新设置video的视频来源 | ||
| 102 | if (this.player) { | ||
| 103 | this.player.pause() | ||
| 104 | this.player.src(val) | ||
| 105 | this.player.load() | ||
| 106 | } | ||
| 107 | } | ||
| 108 | } | ||
| 109 | }, | ||
| 110 | mounted() { | ||
| 111 | this.init() | ||
| 112 | }, | ||
| 113 | beforeDestroy() { | ||
| 114 | if (this.player) { | ||
| 115 | this.player.dispose() | ||
| 116 | } | ||
| 117 | }, | ||
| 118 | // TODO 确认是否删除 | ||
| 119 | // beforeRouteLeave(to, from, next) { | ||
| 120 | // this.stopVideo() | ||
| 121 | // next() | ||
| 122 | // }, | ||
| 123 | methods: { | ||
| 124 | init() { | ||
| 125 | this.player = videojs( | ||
| 126 | 'my-player', | ||
| 127 | { | ||
| 128 | playbackRates: [1, 1.25, 1.5, 2, 2.5], | ||
| 129 | userActions: { | ||
| 130 | // doubleClick: this.myDoubleClickHandler, | ||
| 131 | hotkeys: this.hotkeys | ||
| 132 | }, | ||
| 133 | controlBar: { | ||
| 134 | fullscreenToggle: false, | ||
| 135 | volumePanel: { | ||
| 136 | inline: false | ||
| 137 | } | ||
| 138 | }, | ||
| 139 | notSupportedMessage: '视频加载失败' | ||
| 140 | }, | ||
| 141 | () => { | ||
| 142 | this.player.on('loadedmetadata', () => { | ||
| 143 | this.duration = this.player.duration() // 获取视频长度 | ||
| 144 | this.createProgress() | ||
| 145 | }) | ||
| 146 | this.player.on('timeupdate', throttle(this.timeupdate, 1000, true)) | ||
| 147 | // this.addMirrorComponents() | ||
| 148 | } | ||
| 149 | ) | ||
| 150 | // this.player.on('pause', () => { | ||
| 151 | // // Modals are temporary by default. They dispose themselves when they are | ||
| 152 | // // closed; so, we can create a new one each time the player is paused and | ||
| 153 | // // not worry about leaving extra nodes hanging around. | ||
| 154 | // var modal = this.player.createModal('This is a modal!') | ||
| 155 | |||
| 156 | // // When the modal closes, resume playback. | ||
| 157 | // modal.on('modalclose', () => { | ||
| 158 | // this.player.play() | ||
| 159 | // }) | ||
| 160 | // }) | ||
| 161 | this.player.src(this.url) | ||
| 162 | }, | ||
| 163 | timeupdate() { | ||
| 164 | // 获取视频当前播放时间 | ||
| 165 | this.$emit('timeupdate', this.videoEle.currentTime) | ||
| 166 | }, | ||
| 167 | myDoubleClickHandler() { | ||
| 168 | // console.log('doubleclick') | ||
| 169 | }, | ||
| 170 | hotkeys(e) { | ||
| 171 | if (e.which === spaceKey || e.which === enterKey) { | ||
| 172 | this.playVideo() | ||
| 173 | } | ||
| 174 | if (e.which === leftKey) { | ||
| 175 | this.fastForward(-this.fastSeconds) | ||
| 176 | } | ||
| 177 | if (e.which === rightKey) { | ||
| 178 | this.fastForward(this.fastSeconds) | ||
| 179 | } | ||
| 180 | }, | ||
| 181 | /** | ||
| 182 | * 暂停或播放视频 | ||
| 183 | */ | ||
| 184 | playVideo() { | ||
| 185 | if (this.videoEle) { | ||
| 186 | if (this.videoEle.paused) { | ||
| 187 | this.videoEle.play() | ||
| 188 | } else { | ||
| 189 | this.videoEle.pause() | ||
| 190 | } | ||
| 191 | } | ||
| 192 | }, | ||
| 193 | /** | ||
| 194 | * 强制暂停 | ||
| 195 | */ | ||
| 196 | stopVideo() { | ||
| 197 | this.videoEle.pause() | ||
| 198 | }, | ||
| 199 | /** | ||
| 200 | * 快进视频 | ||
| 201 | */ | ||
| 202 | fastForward(time) { | ||
| 203 | this.videoEle.play() | ||
| 204 | if (this.videoEle.currentTime !== 0) this.videoEle.currentTime += time | ||
| 205 | }, | ||
| 206 | // 设置视频时间 | ||
| 207 | setVideoCurrentTime(time) { | ||
| 208 | this.videoEle.currentTime = time - 0 | ||
| 209 | }, | ||
| 210 | // 添加Mirror镜像控件 | ||
| 211 | addMirrorComponents() { | ||
| 212 | const domTemp = `<button class="vjs-picture-in-picture-control vjs-control vjs-button" type="button" title="Picture-in-Picture" aria-disabled="false"> | ||
| 213 | ${mirrerIcon} | ||
| 214 | <span class="vjs-control-text" aria-live="polite">Picture-in-Picture</span> | ||
| 215 | </button>` | ||
| 216 | const control = document.getElementsByClassName('vjs-control-bar')[0] | ||
| 217 | const span = document.createElement('span') | ||
| 218 | span.innerHTML = domTemp | ||
| 219 | control.appendChild(span) | ||
| 220 | let bool = true | ||
| 221 | span.addEventListener('click', () => { | ||
| 222 | const video = document.getElementsByTagName('video')[0] | ||
| 223 | bool = !bool | ||
| 224 | bool | ||
| 225 | ? (video.style.transform = 'rotateY(0)') | ||
| 226 | : (video.style.transform = 'rotateY(180deg)') | ||
| 227 | }) | ||
| 228 | }, | ||
| 229 | createProgress() { | ||
| 230 | // 视频进度条做标记 | ||
| 231 | const progress = document.getElementsByClassName('vjs-progress-holder')[0] | ||
| 232 | const delDotDiv = document.getElementsByClassName( | ||
| 233 | 'video-face-pair-list' | ||
| 234 | )[0] | ||
| 235 | delDotDiv && progress.removeChild(delDotDiv) | ||
| 236 | const dotDiv = document.createElement('div') | ||
| 237 | dotDiv.setAttribute('class', 'video-face-pair-list') | ||
| 238 | // 视频人脸对比标记 | ||
| 239 | Object.keys(this.singHoldingTime).forEach(a => { | ||
| 240 | const item = this.singHoldingTime[a] | ||
| 241 | const colorDiv = document.createElement('div') | ||
| 242 | colorDiv.setAttribute('class', 'face-pair') | ||
| 243 | if (Array.isArray(item)) { | ||
| 244 | item.forEach(sonItem => { | ||
| 245 | if (sonItem.beginTime < 0) return | ||
| 246 | colorDiv.style.width = | ||
| 247 | ((sonItem.endTime - sonItem.beginTime) / this.duration) * 100 + | ||
| 248 | '%' | ||
| 249 | colorDiv.style.left = | ||
| 250 | (sonItem.beginTime / this.duration) * 100 + '%' | ||
| 251 | colorDiv.style.background = this.holdingColor | ||
| 252 | }) | ||
| 253 | } else { | ||
| 254 | if (item.beginTime < 0) return | ||
| 255 | colorDiv.style.width = | ||
| 256 | ((item.endTime - item.beginTime) / this.duration) * 100 + '%' | ||
| 257 | colorDiv.style.left = (item.beginTime / this.duration) * 100 + '%' | ||
| 258 | colorDiv.style.background = this.signingColor | ||
| 259 | } | ||
| 260 | dotDiv.appendChild(colorDiv) | ||
| 261 | }) | ||
| 262 | // 视频预览图 | ||
| 263 | this.previewImage.forEach(item => { | ||
| 264 | const spanDom = document.createElement('span') | ||
| 265 | spanDom.classList.add('preview-image-dot') | ||
| 266 | spanDom.style.left = `${(item.time / this.duration) * 100}%` | ||
| 267 | spanDom.innerHTML = `<div class="preview-wrapper"> | ||
| 268 | <img | ||
| 269 | src="${item.img}" | ||
| 270 | alt="" | ||
| 271 | /> | ||
| 272 | </div>` | ||
| 273 | dotDiv.appendChild(spanDom) | ||
| 274 | }) | ||
| 275 | // 视频关键打点 | ||
| 276 | this.pointList.forEach(item => { | ||
| 277 | const spanDom = document.createElement('span') | ||
| 278 | spanDom.classList.add('video-dot') | ||
| 279 | spanDom.style.left = `${(item.time / this.duration) * 100}%` | ||
| 280 | spanDom.innerHTML = `<div class="video-dot-tip"> | ||
| 281 | ${item.text} | ||
| 282 | </div>` | ||
| 283 | dotDiv.appendChild(spanDom) | ||
| 284 | }) | ||
| 285 | |||
| 286 | progress.appendChild(dotDiv) | ||
| 287 | } | ||
| 288 | } | ||
| 289 | } | ||
| 290 | </script> | ||
| 291 | <style lang="scss" scope> | ||
| 292 | .video-player { | ||
| 293 | width: 100%; | ||
| 294 | height: 100%; | ||
| 295 | position: relative; | ||
| 296 | .video-js { | ||
| 297 | height: 100%; | ||
| 298 | width: 100%; | ||
| 299 | } | ||
| 300 | // .color-span { | ||
| 301 | // background: black; | ||
| 302 | // width: 130px; | ||
| 303 | // height: 70px; | ||
| 304 | // padding: 5px; | ||
| 305 | // position: absolute; | ||
| 306 | // top: 0; | ||
| 307 | // left: 10px; | ||
| 308 | // color: white; | ||
| 309 | // font-size: 13px; | ||
| 310 | // display: flex; | ||
| 311 | // flex-direction: column; | ||
| 312 | // justify-content: space-around; | ||
| 313 | // align-items: flex-start; | ||
| 314 | // .holding, | ||
| 315 | // .signing { | ||
| 316 | // display: flex; | ||
| 317 | // justify-content: center; | ||
| 318 | // align-items: center; | ||
| 319 | // span:first-child { | ||
| 320 | // display: inline-block; | ||
| 321 | // width: 40px; | ||
| 322 | // height: 20px; | ||
| 323 | // background: red; | ||
| 324 | // margin-right: 10px; | ||
| 325 | // } | ||
| 326 | // span:last-child { | ||
| 327 | // line-height: 20px; | ||
| 328 | // } | ||
| 329 | // } | ||
| 330 | // .holding { | ||
| 331 | // span:first-child { | ||
| 332 | // background: yellow; | ||
| 333 | // } | ||
| 334 | // } | ||
| 335 | // } | ||
| 336 | |||
| 337 | #my-player.video-js { | ||
| 338 | .video-face-pair-list { | ||
| 339 | position: absolute; | ||
| 340 | top: 0; | ||
| 341 | left: 0; | ||
| 342 | width: 100%; | ||
| 343 | height: 100%; | ||
| 344 | .face-pair { | ||
| 345 | position: absolute; | ||
| 346 | height: inherit; | ||
| 347 | } | ||
| 348 | .video-dot { | ||
| 349 | position: absolute; | ||
| 350 | top: -2px; | ||
| 351 | width: 8px; | ||
| 352 | height: 8px; | ||
| 353 | border-radius: 50%; | ||
| 354 | background-color: #fff; | ||
| 355 | overflow: visible; | ||
| 356 | z-index: 1000; | ||
| 357 | box-shadow: 0 0 2px 2px #999; | ||
| 358 | } | ||
| 359 | .video-dot:hover { | ||
| 360 | cursor: pointer; | ||
| 361 | } | ||
| 362 | .video-dot-tip { | ||
| 363 | position: absolute; | ||
| 364 | display: none; | ||
| 365 | top: -76px; | ||
| 366 | left: -75px; | ||
| 367 | max-width: 250px; | ||
| 368 | min-width: 150px; | ||
| 369 | max-height: 60px; | ||
| 370 | min-height: 25px; | ||
| 371 | line-height: 25px; | ||
| 372 | padding: 5px; | ||
| 373 | background-color: #fff; | ||
| 374 | box-shadow: 0 0 -2px 3px #adadad; | ||
| 375 | overflow: auto; | ||
| 376 | letter-spacing: 1px; | ||
| 377 | color: #3d3d3d; | ||
| 378 | border-radius: 5px; | ||
| 379 | z-index: 10; | ||
| 380 | font-size: 12px; | ||
| 381 | font-family: 'Microsoft YaHei'; | ||
| 382 | } | ||
| 383 | .video-dot:hover { | ||
| 384 | .video-dot-tip { | ||
| 385 | display: block; | ||
| 386 | } | ||
| 387 | } | ||
| 388 | .preview-image-dot { | ||
| 389 | display: inline-block; | ||
| 390 | position: absolute; | ||
| 391 | left: 0; | ||
| 392 | top: -11px; | ||
| 393 | width: 0; | ||
| 394 | height: 0; | ||
| 395 | border-right: 5px solid #1a1f26; | ||
| 396 | border-left: 5px solid #1a1f26; | ||
| 397 | // border-top: 4px solid #3248a8; | ||
| 398 | border-top: 5px solid #fff; | ||
| 399 | .preview-wrapper { | ||
| 400 | display: none; | ||
| 401 | position: absolute; | ||
| 402 | bottom: 18px; | ||
| 403 | left: -50px; | ||
| 404 | width: 130px; | ||
| 405 | height: 80px; | ||
| 406 | object-fit: contain; | ||
| 407 | img { | ||
| 408 | width: 100%; | ||
| 409 | height: 100%; | ||
| 410 | } | ||
| 411 | } | ||
| 412 | } | ||
| 413 | .preview-image-dot:hover { | ||
| 414 | background-color: lightblue; | ||
| 415 | .preview-wrapper { | ||
| 416 | display: block; | ||
| 417 | } | ||
| 418 | } | ||
| 419 | } | ||
| 420 | } | ||
| 421 | } | ||
| 422 | </style> | ||
| 423 | <style lang="scss"> | ||
| 424 | .vjs-paused .vjs-big-play-button, | ||
| 425 | .vjs-paused.vjs-has-started .vjs-big-play-button { | ||
| 426 | display: block; | ||
| 427 | } | ||
| 428 | </style> |
src/components/vueCropper/exif-js-min.js
0 → 100644
| 1 | /* eslint-disable */ | ||
| 2 | const Exif = {} | ||
| 3 | |||
| 4 | Exif.getData = img => | ||
| 5 | new Promise((reslove, reject) => { | ||
| 6 | let obj = {} | ||
| 7 | getImageData(img) | ||
| 8 | .then(data => { | ||
| 9 | obj.arrayBuffer = data | ||
| 10 | obj.orientation = getOrientation(data) | ||
| 11 | reslove(obj) | ||
| 12 | }) | ||
| 13 | .catch(error => { | ||
| 14 | reject(error) | ||
| 15 | }) | ||
| 16 | }) | ||
| 17 | |||
| 18 | // 这里的获取exif要将图片转ArrayBuffer对象,这里假设获取了图片的baes64 | ||
| 19 | // 步骤一 | ||
| 20 | // base64转ArrayBuffer对象 | ||
| 21 | function getImageData(img) { | ||
| 22 | let data = null | ||
| 23 | return new Promise((reslove, reject) => { | ||
| 24 | if (img.src) { | ||
| 25 | if (/^data\:/i.test(img.src)) { | ||
| 26 | // Data URI | ||
| 27 | data = base64ToArrayBuffer(img.src) | ||
| 28 | reslove(data) | ||
| 29 | } else if (/^blob\:/i.test(img.src)) { | ||
| 30 | // Object URL | ||
| 31 | var fileReader = new FileReader() | ||
| 32 | fileReader.onload = function(e) { | ||
| 33 | data = e.target.result | ||
| 34 | reslove(data) | ||
| 35 | } | ||
| 36 | objectURLToBlob(img.src, function(blob) { | ||
| 37 | fileReader.readAsArrayBuffer(blob) | ||
| 38 | }) | ||
| 39 | } else { | ||
| 40 | var http = new XMLHttpRequest() | ||
| 41 | http.onload = function() { | ||
| 42 | if (this.status == 200 || this.status === 0) { | ||
| 43 | data = http.response | ||
| 44 | reslove(data) | ||
| 45 | } else { | ||
| 46 | throw 'Could not load image' | ||
| 47 | } | ||
| 48 | http = null | ||
| 49 | } | ||
| 50 | http.open('GET', img.src, true) | ||
| 51 | http.responseType = 'arraybuffer' | ||
| 52 | http.send(null) | ||
| 53 | } | ||
| 54 | } else { | ||
| 55 | reject('img error') | ||
| 56 | } | ||
| 57 | }) | ||
| 58 | } | ||
| 59 | |||
| 60 | function objectURLToBlob(url, callback) { | ||
| 61 | var http = new XMLHttpRequest() | ||
| 62 | http.open('GET', url, true) | ||
| 63 | http.responseType = 'blob' | ||
| 64 | http.onload = function(e) { | ||
| 65 | if (this.status == 200 || this.status === 0) { | ||
| 66 | callback(this.response) | ||
| 67 | } | ||
| 68 | } | ||
| 69 | http.send() | ||
| 70 | } | ||
| 71 | |||
| 72 | function base64ToArrayBuffer(base64) { | ||
| 73 | base64 = base64.replace(/^data\:([^\;]+)\;base64,/gim, '') | ||
| 74 | var binary = atob(base64) | ||
| 75 | var len = binary.length | ||
| 76 | var buffer = new ArrayBuffer(len) | ||
| 77 | var view = new Uint8Array(buffer) | ||
| 78 | for (var i = 0; i < len; i++) { | ||
| 79 | view[i] = binary.charCodeAt(i) | ||
| 80 | } | ||
| 81 | return buffer | ||
| 82 | } | ||
| 83 | // 步骤二,Unicode码转字符串 | ||
| 84 | // ArrayBuffer对象 Unicode码转字符串 | ||
| 85 | function getStringFromCharCode(dataView, start, length) { | ||
| 86 | var str = '' | ||
| 87 | var i | ||
| 88 | for (i = start, length += start; i < length; i++) { | ||
| 89 | str += String.fromCharCode(dataView.getUint8(i)) | ||
| 90 | } | ||
| 91 | return str | ||
| 92 | } | ||
| 93 | |||
| 94 | // 步骤三,获取jpg图片的exif的角度(在ios体现最明显) | ||
| 95 | function getOrientation(arrayBuffer) { | ||
| 96 | var dataView = new DataView(arrayBuffer) | ||
| 97 | var length = dataView.byteLength | ||
| 98 | var orientation | ||
| 99 | var exifIDCode | ||
| 100 | var tiffOffset | ||
| 101 | var firstIFDOffset | ||
| 102 | var littleEndian | ||
| 103 | var endianness | ||
| 104 | var app1Start | ||
| 105 | var ifdStart | ||
| 106 | var offset | ||
| 107 | var i | ||
| 108 | // Only handle JPEG image (start by 0xFFD8) | ||
| 109 | if (dataView.getUint8(0) === 0xff && dataView.getUint8(1) === 0xd8) { | ||
| 110 | offset = 2 | ||
| 111 | while (offset < length) { | ||
| 112 | if ( | ||
| 113 | dataView.getUint8(offset) === 0xff && | ||
| 114 | dataView.getUint8(offset + 1) === 0xe1 | ||
| 115 | ) { | ||
| 116 | app1Start = offset | ||
| 117 | break | ||
| 118 | } | ||
| 119 | offset++ | ||
| 120 | } | ||
| 121 | } | ||
| 122 | if (app1Start) { | ||
| 123 | exifIDCode = app1Start + 4 | ||
| 124 | tiffOffset = app1Start + 10 | ||
| 125 | if (getStringFromCharCode(dataView, exifIDCode, 4) === 'Exif') { | ||
| 126 | endianness = dataView.getUint16(tiffOffset) | ||
| 127 | littleEndian = endianness === 0x4949 | ||
| 128 | |||
| 129 | if (littleEndian || endianness === 0x4d4d /* bigEndian */) { | ||
| 130 | if (dataView.getUint16(tiffOffset + 2, littleEndian) === 0x002a) { | ||
| 131 | firstIFDOffset = dataView.getUint32(tiffOffset + 4, littleEndian) | ||
| 132 | |||
| 133 | if (firstIFDOffset >= 0x00000008) { | ||
| 134 | ifdStart = tiffOffset + firstIFDOffset | ||
| 135 | } | ||
| 136 | } | ||
| 137 | } | ||
| 138 | } | ||
| 139 | } | ||
| 140 | if (ifdStart) { | ||
| 141 | length = dataView.getUint16(ifdStart, littleEndian) | ||
| 142 | |||
| 143 | for (i = 0; i < length; i++) { | ||
| 144 | offset = ifdStart + i * 12 + 2 | ||
| 145 | if ( | ||
| 146 | dataView.getUint16(offset, littleEndian) === 0x0112 /* Orientation */ | ||
| 147 | ) { | ||
| 148 | // 8 is the offset of the current tag's value | ||
| 149 | offset += 8 | ||
| 150 | |||
| 151 | // Get the original orientation value | ||
| 152 | orientation = dataView.getUint16(offset, littleEndian) | ||
| 153 | |||
| 154 | // Override the orientation with its default value for Safari (#120) | ||
| 155 | // if (IS_SAFARI_OR_UIWEBVIEW) { | ||
| 156 | // dataView.setUint16(offset, 1, littleEndian); | ||
| 157 | // } | ||
| 158 | break | ||
| 159 | } | ||
| 160 | } | ||
| 161 | } | ||
| 162 | return orientation | ||
| 163 | } | ||
| 164 | |||
| 165 | export default Exif |
src/components/vueCropper/index.js
0 → 100644
src/components/vueCropper/vueCropper.vue
0 → 100644
| 1 | <template> | ||
| 2 | <div | ||
| 3 | class="vue-cropper" | ||
| 4 | ref="cropper" | ||
| 5 | @mouseover="scaleImg" | ||
| 6 | @mouseout="cancelScale" | ||
| 7 | > | ||
| 8 | <!-- :style="{width:w+'px',height:h+'px'}" --> | ||
| 9 | <div class="cropper-box"> | ||
| 10 | <div | ||
| 11 | class="cropper-box-canvas" | ||
| 12 | v-show="!loading" | ||
| 13 | :style="{ | ||
| 14 | width: trueWidth + 'px', | ||
| 15 | height: trueHeight + 'px', | ||
| 16 | transform: | ||
| 17 | 'scale(' + | ||
| 18 | scale + | ||
| 19 | ',' + | ||
| 20 | scale + | ||
| 21 | ') ' + | ||
| 22 | 'translate3d(' + | ||
| 23 | x / scale + | ||
| 24 | 'px,' + | ||
| 25 | y / scale + | ||
| 26 | 'px,' + | ||
| 27 | '0)' + | ||
| 28 | 'rotateZ(' + | ||
| 29 | rotate * 90 + | ||
| 30 | 'deg)' | ||
| 31 | }" | ||
| 32 | > | ||
| 33 | <img :src="imgs" alt="cropper-img" ref="cropperImg" /> | ||
| 34 | </div> | ||
| 35 | </div> | ||
| 36 | <div | ||
| 37 | class="cropper-drag-box" | ||
| 38 | :class="{ | ||
| 39 | 'cropper-move': move && !crop, | ||
| 40 | 'cropper-crop': crop, | ||
| 41 | 'cropper-modal': cropping | ||
| 42 | }" | ||
| 43 | @mousedown="startMove" | ||
| 44 | @touchstart="startMove" | ||
| 45 | ></div> | ||
| 46 | <div | ||
| 47 | v-show="cropping" | ||
| 48 | class="cropper-crop-box" | ||
| 49 | :style="{ | ||
| 50 | width: cropW + 'px', | ||
| 51 | height: cropH + 'px', | ||
| 52 | transform: | ||
| 53 | 'translate3d(' + cropOffsertX + 'px,' + cropOffsertY + 'px,' + '0)' | ||
| 54 | }" | ||
| 55 | > | ||
| 56 | <span class="cropper-view-box"> | ||
| 57 | <img | ||
| 58 | :style="{ | ||
| 59 | width: trueWidth + 'px', | ||
| 60 | height: trueHeight + 'px', | ||
| 61 | transform: | ||
| 62 | 'scale(' + | ||
| 63 | scale + | ||
| 64 | ',' + | ||
| 65 | scale + | ||
| 66 | ') ' + | ||
| 67 | 'translate3d(' + | ||
| 68 | (x - cropOffsertX) / scale + | ||
| 69 | 'px,' + | ||
| 70 | (y - cropOffsertY) / scale + | ||
| 71 | 'px,' + | ||
| 72 | '0)' + | ||
| 73 | 'rotateZ(' + | ||
| 74 | rotate * 90 + | ||
| 75 | 'deg)' | ||
| 76 | }" | ||
| 77 | :src="imgs" | ||
| 78 | alt="cropper-img" | ||
| 79 | /> | ||
| 80 | </span> | ||
| 81 | <span | ||
| 82 | class="cropper-face cropper-move" | ||
| 83 | @mousedown="cropMove" | ||
| 84 | @touchstart="cropMove" | ||
| 85 | ></span> | ||
| 86 | <span class="crop-info" v-if="info" :style="{ top: cropInfo.top }" | ||
| 87 | >{{ this.cropInfo.width }} × {{ this.cropInfo.height }}</span | ||
| 88 | > | ||
| 89 | <span v-if="!fixedBox"> | ||
| 90 | <span | ||
| 91 | class="crop-line line-w" | ||
| 92 | @mousedown="changeCropSize($event, false, true, 0, 1)" | ||
| 93 | @touchstart="changeCropSize($event, false, true, 0, 1)" | ||
| 94 | ></span> | ||
| 95 | <span | ||
| 96 | class="crop-line line-a" | ||
| 97 | @mousedown="changeCropSize($event, true, false, 1, 0)" | ||
| 98 | @touchstart="changeCropSize($event, true, false, 1, 0)" | ||
| 99 | ></span> | ||
| 100 | <span | ||
| 101 | class="crop-line line-s" | ||
| 102 | @mousedown="changeCropSize($event, false, true, 0, 2)" | ||
| 103 | @touchstart="changeCropSize($event, false, true, 0, 2)" | ||
| 104 | ></span> | ||
| 105 | <span | ||
| 106 | class="crop-line line-d" | ||
| 107 | @mousedown="changeCropSize($event, true, false, 2, 0)" | ||
| 108 | @touchstart="changeCropSize($event, true, false, 2, 0)" | ||
| 109 | ></span> | ||
| 110 | <span | ||
| 111 | class="crop-point point1" | ||
| 112 | @mousedown="changeCropSize($event, true, true, 1, 1)" | ||
| 113 | @touchstart="changeCropSize($event, true, true, 1, 1)" | ||
| 114 | ></span> | ||
| 115 | <span | ||
| 116 | class="crop-point point2" | ||
| 117 | @mousedown="changeCropSize($event, false, true, 0, 1)" | ||
| 118 | @touchstart="changeCropSize($event, false, true, 0, 1)" | ||
| 119 | ></span> | ||
| 120 | <span | ||
| 121 | class="crop-point point3" | ||
| 122 | @mousedown="changeCropSize($event, true, true, 2, 1)" | ||
| 123 | @touchstart="changeCropSize($event, true, true, 2, 1)" | ||
| 124 | ></span> | ||
| 125 | <span | ||
| 126 | class="crop-point point4" | ||
| 127 | @mousedown="changeCropSize($event, true, false, 1, 0)" | ||
| 128 | @touchstart="changeCropSize($event, true, false, 1, 0)" | ||
| 129 | ></span> | ||
| 130 | <span | ||
| 131 | class="crop-point point5" | ||
| 132 | @mousedown="changeCropSize($event, true, false, 2, 0)" | ||
| 133 | @touchstart="changeCropSize($event, true, false, 2, 0)" | ||
| 134 | ></span> | ||
| 135 | <span | ||
| 136 | class="crop-point point6" | ||
| 137 | @mousedown="changeCropSize($event, true, true, 1, 2)" | ||
| 138 | @touchstart="changeCropSize($event, true, true, 1, 2)" | ||
| 139 | ></span> | ||
| 140 | <span | ||
| 141 | class="crop-point point7" | ||
| 142 | @mousedown="changeCropSize($event, false, true, 0, 2)" | ||
| 143 | @touchstart="changeCropSize($event, false, true, 0, 2)" | ||
| 144 | ></span> | ||
| 145 | <span | ||
| 146 | class="crop-point point8" | ||
| 147 | @mousedown="changeCropSize($event, true, true, 2, 2)" | ||
| 148 | @touchstart="changeCropSize($event, true, true, 2, 2)" | ||
| 149 | ></span> | ||
| 150 | </span> | ||
| 151 | </div> | ||
| 152 | </div> | ||
| 153 | </template> | ||
| 154 | |||
| 155 | <script> | ||
| 156 | import exifmin from './exif-js-min' | ||
| 157 | |||
| 158 | export default { | ||
| 159 | data: function() { | ||
| 160 | return { | ||
| 161 | // 容器高宽 | ||
| 162 | w: 0, | ||
| 163 | h: 0, | ||
| 164 | // 图片缩放比例 | ||
| 165 | scale: 1, | ||
| 166 | // 图片偏移x轴 | ||
| 167 | x: 0, | ||
| 168 | // 图片偏移y轴 | ||
| 169 | y: 0, | ||
| 170 | // 图片加载 | ||
| 171 | loading: true, | ||
| 172 | // 图片真实宽度 | ||
| 173 | trueWidth: 0, | ||
| 174 | // 图片真实高度 | ||
| 175 | trueHeight: 0, | ||
| 176 | move: true, | ||
| 177 | // 移动的x | ||
| 178 | moveX: 0, | ||
| 179 | // 移动的y | ||
| 180 | moveY: 0, | ||
| 181 | // 开启截图 | ||
| 182 | crop: false, | ||
| 183 | // 正在截图 | ||
| 184 | cropping: false, | ||
| 185 | // 裁剪框大小 | ||
| 186 | cropW: 0, | ||
| 187 | cropH: 0, | ||
| 188 | cropOldW: 0, | ||
| 189 | cropOldH: 0, | ||
| 190 | // 判断是否能够改变 | ||
| 191 | canChangeX: false, | ||
| 192 | canChangeY: false, | ||
| 193 | // 改变的基准点 | ||
| 194 | changeCropTypeX: 1, | ||
| 195 | changeCropTypeY: 1, | ||
| 196 | // 裁剪框的坐标轴 | ||
| 197 | cropX: 0, | ||
| 198 | cropY: 0, | ||
| 199 | cropChangeX: 0, | ||
| 200 | cropChangeY: 0, | ||
| 201 | cropOffsertX: 0, | ||
| 202 | cropOffsertY: 0, | ||
| 203 | // 支持的滚动事件 | ||
| 204 | support: '', | ||
| 205 | // 移动端手指缩放 | ||
| 206 | touches: [], | ||
| 207 | touchNow: false, | ||
| 208 | // 图片旋转 | ||
| 209 | rotate: 0, | ||
| 210 | isIos: false, | ||
| 211 | orientation: 0, | ||
| 212 | imgs: '', | ||
| 213 | // 图片缩放系数 | ||
| 214 | coe: 0.2, | ||
| 215 | // 是否正在多次缩放 | ||
| 216 | scaling: false, | ||
| 217 | scalingSet: '', | ||
| 218 | coeStatus: '', | ||
| 219 | // 控制emit触发频率 | ||
| 220 | isCanShow: true | ||
| 221 | } | ||
| 222 | }, | ||
| 223 | props: { | ||
| 224 | img: { | ||
| 225 | type: [String, Blob, null, File], | ||
| 226 | default: '' | ||
| 227 | }, | ||
| 228 | // 输出图片压缩比 | ||
| 229 | outputSize: { | ||
| 230 | type: Number, | ||
| 231 | default: 1 | ||
| 232 | }, | ||
| 233 | outputType: { | ||
| 234 | type: String, | ||
| 235 | default: 'jpeg' | ||
| 236 | }, | ||
| 237 | info: { | ||
| 238 | type: Boolean, | ||
| 239 | default: true | ||
| 240 | }, | ||
| 241 | // 是否开启滚轮放大缩小 | ||
| 242 | canScale: { | ||
| 243 | type: Boolean, | ||
| 244 | default: true | ||
| 245 | }, | ||
| 246 | // 是否自成截图框 | ||
| 247 | autoCrop: { | ||
| 248 | type: Boolean, | ||
| 249 | default: false | ||
| 250 | }, | ||
| 251 | autoCropWidth: { | ||
| 252 | type: [Number, String], | ||
| 253 | default: 0 | ||
| 254 | }, | ||
| 255 | autoCropHeight: { | ||
| 256 | type: [Number, String], | ||
| 257 | default: 0 | ||
| 258 | }, | ||
| 259 | // 是否开启固定宽高比 | ||
| 260 | fixed: { | ||
| 261 | type: Boolean, | ||
| 262 | default: false | ||
| 263 | }, | ||
| 264 | // 宽高比 w/h | ||
| 265 | fixedNumber: { | ||
| 266 | type: Array, | ||
| 267 | default: () => { | ||
| 268 | return [1, 1] | ||
| 269 | } | ||
| 270 | }, | ||
| 271 | // 固定大小 禁止改变截图框大小 | ||
| 272 | fixedBox: { | ||
| 273 | type: Boolean, | ||
| 274 | default: false | ||
| 275 | }, | ||
| 276 | // 输出截图是否缩放 | ||
| 277 | full: { | ||
| 278 | type: Boolean, | ||
| 279 | default: false | ||
| 280 | }, | ||
| 281 | // 是否可以拖动图片 | ||
| 282 | canMove: { | ||
| 283 | type: Boolean, | ||
| 284 | default: true | ||
| 285 | }, | ||
| 286 | // 是否可以拖动截图框 | ||
| 287 | canMoveBox: { | ||
| 288 | type: Boolean, | ||
| 289 | default: true | ||
| 290 | }, | ||
| 291 | // 上传图片按照原始比例显示 | ||
| 292 | original: { | ||
| 293 | type: Boolean, | ||
| 294 | default: false | ||
| 295 | }, | ||
| 296 | // 截图框能否超过图片 | ||
| 297 | centerBox: { | ||
| 298 | type: Boolean, | ||
| 299 | default: false | ||
| 300 | }, | ||
| 301 | // 是否根据dpr输出高清图片 | ||
| 302 | high: { | ||
| 303 | type: Boolean, | ||
| 304 | default: true | ||
| 305 | }, | ||
| 306 | // 截图框展示宽高类型 | ||
| 307 | infoTrue: { | ||
| 308 | type: Boolean, | ||
| 309 | default: false | ||
| 310 | }, | ||
| 311 | // 可以压缩图片宽高 默认不超过10000 | ||
| 312 | maxImgSize: { | ||
| 313 | type: Number, | ||
| 314 | default: 10000 | ||
| 315 | }, | ||
| 316 | // 倍数 可渲染当前截图框的n倍 0 - 1000; | ||
| 317 | enlarge: { | ||
| 318 | type: [Number, String], | ||
| 319 | default: 1 | ||
| 320 | }, | ||
| 321 | |||
| 322 | // 自动预览的固定宽度 | ||
| 323 | preW: { | ||
| 324 | type: [Number, String], | ||
| 325 | default: 0 | ||
| 326 | }, | ||
| 327 | /* | ||
| 328 | 图片布局方式 mode 实现和css背景一样的效果 | ||
| 329 | contain 居中布局 默认不会缩放 保证图片在容器里面 mode: 'contain' | ||
| 330 | cover 拉伸布局 填充整个容器 mode: 'cover' | ||
| 331 | 如果仅有一个数值被给定,这个数值将作为宽度值大小,高度值将被设定为auto。 mode: '50px' | ||
| 332 | 如果有两个数值被给定,第一个将作为宽度值大小,第二个作为高度值大小。 mode: '50px 60px' | ||
| 333 | */ | ||
| 334 | mode: { | ||
| 335 | type: String, | ||
| 336 | default: 'contain' | ||
| 337 | } | ||
| 338 | }, | ||
| 339 | computed: { | ||
| 340 | cropInfo() { | ||
| 341 | let obj = {} | ||
| 342 | obj.top = this.cropOffsertY > 21 ? '-21px' : '0px' | ||
| 343 | obj.width = this.cropW > 0 ? this.cropW : 0 | ||
| 344 | obj.height = this.cropH > 0 ? this.cropH : 0 | ||
| 345 | if (this.infoTrue) { | ||
| 346 | let dpr = 1 | ||
| 347 | if (this.high && !this.full) { | ||
| 348 | dpr = window.devicePixelRatio | ||
| 349 | } | ||
| 350 | if ((this.enlarge !== 1) & !this.full) { | ||
| 351 | dpr = Math.abs(Number(this.enlarge)) | ||
| 352 | } | ||
| 353 | obj.width = obj.width * dpr | ||
| 354 | obj.height = obj.height * dpr | ||
| 355 | if (this.full) { | ||
| 356 | obj.width = obj.width / this.scale | ||
| 357 | obj.height = obj.height / this.scale | ||
| 358 | } | ||
| 359 | } | ||
| 360 | obj.width = obj.width.toFixed(0) | ||
| 361 | obj.height = obj.height.toFixed(0) | ||
| 362 | return obj | ||
| 363 | }, | ||
| 364 | |||
| 365 | isIE() { | ||
| 366 | var userAgent = navigator.userAgent // 取得浏览器的userAgent字符串 | ||
| 367 | var isIE = | ||
| 368 | userAgent.indexOf('compatible') > -1 && userAgent.indexOf('MSIE') > -1 // 判断是否IE浏览器 | ||
| 369 | return isIE | ||
| 370 | } | ||
| 371 | }, | ||
| 372 | watch: { | ||
| 373 | // 如果图片改变, 重新布局 | ||
| 374 | img() { | ||
| 375 | // 当传入图片时, 读取图片信息同时展示 | ||
| 376 | this.checkedImg() | ||
| 377 | }, | ||
| 378 | imgs(val) { | ||
| 379 | if (val === '') { | ||
| 380 | return | ||
| 381 | } | ||
| 382 | this.reload() | ||
| 383 | }, | ||
| 384 | cropW() { | ||
| 385 | this.showPreview() | ||
| 386 | }, | ||
| 387 | cropH() { | ||
| 388 | this.showPreview() | ||
| 389 | }, | ||
| 390 | cropOffsertX() { | ||
| 391 | this.showPreview() | ||
| 392 | }, | ||
| 393 | cropOffsertY() { | ||
| 394 | this.showPreview() | ||
| 395 | }, | ||
| 396 | scale(val, oldVal) { | ||
| 397 | this.showPreview() | ||
| 398 | }, | ||
| 399 | x() { | ||
| 400 | this.showPreview() | ||
| 401 | }, | ||
| 402 | y() { | ||
| 403 | this.showPreview() | ||
| 404 | }, | ||
| 405 | autoCrop(val) { | ||
| 406 | if (val) { | ||
| 407 | this.goAutoCrop() | ||
| 408 | } | ||
| 409 | }, | ||
| 410 | // 修改了自动截图框 | ||
| 411 | autoCropWidth() { | ||
| 412 | if (this.autoCrop) { | ||
| 413 | this.goAutoCrop() | ||
| 414 | } | ||
| 415 | }, | ||
| 416 | autoCropHeight() { | ||
| 417 | if (this.autoCrop) { | ||
| 418 | this.goAutoCrop() | ||
| 419 | } | ||
| 420 | }, | ||
| 421 | mode() { | ||
| 422 | this.checkedImg() | ||
| 423 | }, | ||
| 424 | rotate() { | ||
| 425 | this.showPreview() | ||
| 426 | if (this.autoCrop) { | ||
| 427 | this.goAutoCrop(this.cropW, this.cropH) | ||
| 428 | } else { | ||
| 429 | if (this.cropW > 0 || this.cropH > 0) { | ||
| 430 | this.goAutoCrop(this.cropW, this.cropH) | ||
| 431 | } | ||
| 432 | } | ||
| 433 | } | ||
| 434 | }, | ||
| 435 | methods: { | ||
| 436 | checkOrientationImage(img, orientation, width, height) { | ||
| 437 | let canvas = document.createElement('canvas') | ||
| 438 | let ctx = canvas.getContext('2d') | ||
| 439 | ctx.save() | ||
| 440 | |||
| 441 | switch (orientation) { | ||
| 442 | case 2: | ||
| 443 | canvas.width = width | ||
| 444 | canvas.height = height | ||
| 445 | // horizontal flip | ||
| 446 | ctx.translate(width, 0) | ||
| 447 | ctx.scale(-1, 1) | ||
| 448 | break | ||
| 449 | case 3: | ||
| 450 | canvas.width = width | ||
| 451 | canvas.height = height | ||
| 452 | // 180 graus | ||
| 453 | ctx.translate(width / 2, height / 2) | ||
| 454 | ctx.rotate((180 * Math.PI) / 180) | ||
| 455 | ctx.translate(-width / 2, -height / 2) | ||
| 456 | break | ||
| 457 | case 4: | ||
| 458 | canvas.width = width | ||
| 459 | canvas.height = height | ||
| 460 | // vertical flip | ||
| 461 | ctx.translate(0, height) | ||
| 462 | ctx.scale(1, -1) | ||
| 463 | break | ||
| 464 | case 5: | ||
| 465 | // vertical flip + 90 rotate right | ||
| 466 | canvas.height = width | ||
| 467 | canvas.width = height | ||
| 468 | ctx.rotate(0.5 * Math.PI) | ||
| 469 | ctx.scale(1, -1) | ||
| 470 | break | ||
| 471 | case 6: | ||
| 472 | canvas.width = height | ||
| 473 | canvas.height = width | ||
| 474 | // 90 graus | ||
| 475 | ctx.translate(height / 2, width / 2) | ||
| 476 | ctx.rotate((90 * Math.PI) / 180) | ||
| 477 | ctx.translate(-width / 2, -height / 2) | ||
| 478 | break | ||
| 479 | case 7: | ||
| 480 | // horizontal flip + 90 rotate right | ||
| 481 | canvas.height = width | ||
| 482 | canvas.width = height | ||
| 483 | ctx.rotate(0.5 * Math.PI) | ||
| 484 | ctx.translate(width, -height) | ||
| 485 | ctx.scale(-1, 1) | ||
| 486 | break | ||
| 487 | case 8: | ||
| 488 | canvas.height = width | ||
| 489 | canvas.width = height | ||
| 490 | // -90 graus | ||
| 491 | ctx.translate(height / 2, width / 2) | ||
| 492 | ctx.rotate((-90 * Math.PI) / 180) | ||
| 493 | ctx.translate(-width / 2, -height / 2) | ||
| 494 | break | ||
| 495 | default: | ||
| 496 | canvas.width = width | ||
| 497 | canvas.height = height | ||
| 498 | } | ||
| 499 | |||
| 500 | ctx.drawImage(img, 0, 0, width, height) | ||
| 501 | ctx.restore() | ||
| 502 | canvas.toBlob( | ||
| 503 | blob => { | ||
| 504 | let data = URL.createObjectURL(blob) | ||
| 505 | this.imgs = data | ||
| 506 | }, | ||
| 507 | 'image/' + this.outputType, | ||
| 508 | 1 | ||
| 509 | ) | ||
| 510 | }, | ||
| 511 | |||
| 512 | // checkout img | ||
| 513 | checkedImg() { | ||
| 514 | if (this.img === '') return | ||
| 515 | this.loading = true | ||
| 516 | this.scale = 1 | ||
| 517 | this.rotate = 0 | ||
| 518 | this.clearCrop() | ||
| 519 | let img = new Image() | ||
| 520 | img.onload = () => { | ||
| 521 | if (this.img === '') { | ||
| 522 | this.$emit('imgLoad', 'error') | ||
| 523 | return false | ||
| 524 | } | ||
| 525 | |||
| 526 | let width = img.width | ||
| 527 | let height = img.height | ||
| 528 | exifmin.getData(img).then(data => { | ||
| 529 | this.orientation = data.orientation || 1 | ||
| 530 | let max = this.maxImgSize | ||
| 531 | if (!this.orientation && (width < max) & (height < max)) { | ||
| 532 | this.imgs = this.img | ||
| 533 | return | ||
| 534 | } | ||
| 535 | |||
| 536 | if (width > max) { | ||
| 537 | height = (height / width) * max | ||
| 538 | width = max | ||
| 539 | } | ||
| 540 | |||
| 541 | if (height > max) { | ||
| 542 | width = (width / height) * max | ||
| 543 | height = max | ||
| 544 | } | ||
| 545 | |||
| 546 | this.checkOrientationImage(img, this.orientation, width, height) | ||
| 547 | }) | ||
| 548 | } | ||
| 549 | |||
| 550 | img.onerror = () => { | ||
| 551 | this.$emit('imgLoad', 'error') | ||
| 552 | } | ||
| 553 | |||
| 554 | // 判断如果不是base64图片 再添加crossOrigin属性,否则会导致iOS低版本(10.2)无法显示图片 | ||
| 555 | if (this.img.substr(0, 4) !== 'data') { | ||
| 556 | img.crossOrigin = '' | ||
| 557 | } | ||
| 558 | |||
| 559 | if (this.isIE) { | ||
| 560 | var xhr = new XMLHttpRequest() | ||
| 561 | xhr.onload = function() { | ||
| 562 | var url = URL.createObjectURL(this.response) | ||
| 563 | img.src = url | ||
| 564 | } | ||
| 565 | xhr.open('GET', this.img, true) | ||
| 566 | xhr.responseType = 'blob' | ||
| 567 | xhr.send() | ||
| 568 | } else { | ||
| 569 | img.src = this.img | ||
| 570 | } | ||
| 571 | }, | ||
| 572 | // 当按下鼠标键 | ||
| 573 | startMove(e) { | ||
| 574 | e.preventDefault() | ||
| 575 | // 如果move 为true 表示当前可以拖动 | ||
| 576 | if (this.move && !this.crop) { | ||
| 577 | if (!this.canMove) { | ||
| 578 | return false | ||
| 579 | } | ||
| 580 | // 开始移动 | ||
| 581 | this.moveX = (e.clientX ? e.clientX : e.touches[0].clientX) - this.x | ||
| 582 | this.moveY = (e.clientY ? e.clientY : e.touches[0].clientY) - this.y | ||
| 583 | if (e.touches) { | ||
| 584 | window.addEventListener('touchmove', this.moveImg) | ||
| 585 | window.addEventListener('touchend', this.leaveImg) | ||
| 586 | if (e.touches.length == 2) { | ||
| 587 | // 记录手指刚刚放上去 | ||
| 588 | this.touches = e.touches | ||
| 589 | window.addEventListener('touchmove', this.touchScale) | ||
| 590 | window.addEventListener('touchend', this.cancelTouchScale) | ||
| 591 | } | ||
| 592 | } else { | ||
| 593 | window.addEventListener('mousemove', this.moveImg) | ||
| 594 | window.addEventListener('mouseup', this.leaveImg) | ||
| 595 | } | ||
| 596 | // 触发图片移动事件 | ||
| 597 | this.$emit('imgMoving', { | ||
| 598 | moving: true, | ||
| 599 | axis: this.getImgAxis() | ||
| 600 | }) | ||
| 601 | } else { | ||
| 602 | // 截图ing | ||
| 603 | this.cropping = true | ||
| 604 | // 绑定截图事件 | ||
| 605 | window.addEventListener('mousemove', this.createCrop) | ||
| 606 | window.addEventListener('mouseup', this.endCrop) | ||
| 607 | window.addEventListener('touchmove', this.createCrop) | ||
| 608 | window.addEventListener('touchend', this.endCrop) | ||
| 609 | this.cropOffsertX = e.offsetX | ||
| 610 | ? e.offsetX | ||
| 611 | : e.touches[0].pageX - this.$refs.cropper.offsetLeft | ||
| 612 | this.cropOffsertY = e.offsetY | ||
| 613 | ? e.offsetY | ||
| 614 | : e.touches[0].pageY - this.$refs.cropper.offsetTop | ||
| 615 | this.cropX = e.clientX ? e.clientX : e.touches[0].clientX | ||
| 616 | this.cropY = e.clientY ? e.clientY : e.touches[0].clientY | ||
| 617 | this.cropChangeX = this.cropOffsertX | ||
| 618 | this.cropChangeY = this.cropOffsertY | ||
| 619 | this.cropW = 0 | ||
| 620 | this.cropH = 0 | ||
| 621 | console.log( | ||
| 622 | 'cropOffsertX', | ||
| 623 | this.cropOffsertX, | ||
| 624 | 'cropOffsertY', | ||
| 625 | this.cropOffsertY, | ||
| 626 | 'cropX', | ||
| 627 | this.cropX, | ||
| 628 | 'cropY', | ||
| 629 | this.cropY | ||
| 630 | ) | ||
| 631 | } | ||
| 632 | }, | ||
| 633 | |||
| 634 | // 移动端缩放 | ||
| 635 | // touchScale(e) { | ||
| 636 | // e.preventDefault() | ||
| 637 | // let scale = this.scale | ||
| 638 | // // 记录变化量 | ||
| 639 | // // 第一根手指 | ||
| 640 | // var oldTouch1 = { | ||
| 641 | // x: this.touches[0].clientX, | ||
| 642 | // y: this.touches[0].clientY | ||
| 643 | // } | ||
| 644 | // var newTouch1 = { | ||
| 645 | // x: e.touches[0].clientX, | ||
| 646 | // y: e.touches[0].clientY | ||
| 647 | // } | ||
| 648 | // // 第二根手指 | ||
| 649 | // var oldTouch2 = { | ||
| 650 | // x: this.touches[1].clientX, | ||
| 651 | // y: this.touches[1].clientY | ||
| 652 | // } | ||
| 653 | // var newTouch2 = { | ||
| 654 | // x: e.touches[1].clientX, | ||
| 655 | // y: e.touches[1].clientY | ||
| 656 | // } | ||
| 657 | // var oldL = Math.sqrt( | ||
| 658 | // Math.pow(oldTouch1.x - oldTouch2.x, 2) + | ||
| 659 | // Math.pow(oldTouch1.y - oldTouch2.y, 2) | ||
| 660 | // ) | ||
| 661 | // var newL = Math.sqrt( | ||
| 662 | // Math.pow(newTouch1.x - newTouch2.x, 2) + | ||
| 663 | // Math.pow(newTouch1.y - newTouch2.y, 2) | ||
| 664 | // ) | ||
| 665 | // var cha = newL - oldL | ||
| 666 | // // 根据图片本身大小 决定每次改变大小的系数, 图片越大系数越小 | ||
| 667 | // // 1px - 0.2 | ||
| 668 | // var coe = 1 | ||
| 669 | // coe = | ||
| 670 | // coe / this.trueWidth > coe / this.trueHeight | ||
| 671 | // ? coe / this.trueHeight | ||
| 672 | // : coe / this.trueWidth | ||
| 673 | // coe = coe > 0.1 ? 0.1 : coe | ||
| 674 | // var num = coe * cha | ||
| 675 | // if (!this.touchNow) { | ||
| 676 | // this.touchNow = true | ||
| 677 | // if (cha > 0) { | ||
| 678 | // scale += Math.abs(num) | ||
| 679 | // } else if (cha < 0) { | ||
| 680 | // scale > Math.abs(num) ? (scale -= Math.abs(num)) : scale | ||
| 681 | // } | ||
| 682 | // this.touches = e.touches | ||
| 683 | // setTimeout(() => { | ||
| 684 | // this.touchNow = false | ||
| 685 | // }, 8) | ||
| 686 | // if (!this.checkoutImgAxis(this.x, this.y, scale)) { | ||
| 687 | // return false | ||
| 688 | // } | ||
| 689 | // this.scale = scale | ||
| 690 | // } | ||
| 691 | // }, | ||
| 692 | |||
| 693 | // cancelTouchScale(e) { | ||
| 694 | // window.removeEventListener('touchmove', this.touchScale) | ||
| 695 | // }, | ||
| 696 | |||
| 697 | // 移动图片 | ||
| 698 | moveImg(e) { | ||
| 699 | e.preventDefault() | ||
| 700 | if (e.touches && e.touches.length === 2) { | ||
| 701 | this.touches = e.touches | ||
| 702 | window.addEventListener('touchmove', this.touchScale) | ||
| 703 | window.addEventListener('touchend', this.cancelTouchScale) | ||
| 704 | window.removeEventListener('touchmove', this.moveImg) | ||
| 705 | return false | ||
| 706 | } | ||
| 707 | let nowX = e.clientX ? e.clientX : e.touches[0].clientX | ||
| 708 | let nowY = e.clientY ? e.clientY : e.touches[0].clientY | ||
| 709 | |||
| 710 | let changeX, changeY | ||
| 711 | changeX = nowX - this.moveX | ||
| 712 | changeY = nowY - this.moveY | ||
| 713 | |||
| 714 | this.$nextTick(() => { | ||
| 715 | if (this.centerBox) { | ||
| 716 | let axis = this.getImgAxis(changeX, changeY, this.scale) | ||
| 717 | let cropAxis = this.getCropAxis() | ||
| 718 | let imgW = this.trueHeight * this.scale | ||
| 719 | let imgH = this.trueWidth * this.scale | ||
| 720 | let maxLeft, maxTop, maxRight, maxBottom | ||
| 721 | switch (this.rotate) { | ||
| 722 | case 1: | ||
| 723 | case -1: | ||
| 724 | case 3: | ||
| 725 | case -3: | ||
| 726 | maxLeft = | ||
| 727 | this.cropOffsertX - | ||
| 728 | (this.trueWidth * (1 - this.scale)) / 2 + | ||
| 729 | (imgW - imgH) / 2 | ||
| 730 | maxTop = | ||
| 731 | this.cropOffsertY - | ||
| 732 | (this.trueHeight * (1 - this.scale)) / 2 + | ||
| 733 | (imgH - imgW) / 2 | ||
| 734 | maxRight = maxLeft - imgW + this.cropW | ||
| 735 | maxBottom = maxTop - imgH + this.cropH | ||
| 736 | break | ||
| 737 | default: | ||
| 738 | maxLeft = | ||
| 739 | this.cropOffsertX - (this.trueWidth * (1 - this.scale)) / 2 | ||
| 740 | maxTop = | ||
| 741 | this.cropOffsertY - (this.trueHeight * (1 - this.scale)) / 2 | ||
| 742 | maxRight = maxLeft - imgH + this.cropW | ||
| 743 | maxBottom = maxTop - imgW + this.cropH | ||
| 744 | break | ||
| 745 | } | ||
| 746 | |||
| 747 | // 图片左边 图片不能超过截图框 | ||
| 748 | if (axis.x1 >= cropAxis.x1) { | ||
| 749 | changeX = maxLeft | ||
| 750 | } | ||
| 751 | |||
| 752 | // 图片上边 图片不能超过截图框 | ||
| 753 | if (axis.y1 >= cropAxis.y1) { | ||
| 754 | changeY = maxTop | ||
| 755 | } | ||
| 756 | |||
| 757 | // 图片右边 | ||
| 758 | if (axis.x2 <= cropAxis.x2) { | ||
| 759 | changeX = maxRight | ||
| 760 | } | ||
| 761 | |||
| 762 | // 图片下边 | ||
| 763 | if (axis.y2 <= cropAxis.y2) { | ||
| 764 | changeY = maxBottom | ||
| 765 | } | ||
| 766 | } | ||
| 767 | this.x = changeX | ||
| 768 | this.y = changeY | ||
| 769 | // 触发图片移动事件 | ||
| 770 | this.$emit('imgMoving', { | ||
| 771 | moving: true, | ||
| 772 | axis: this.getImgAxis() | ||
| 773 | }) | ||
| 774 | }) | ||
| 775 | }, | ||
| 776 | // 移动图片结束 | ||
| 777 | leaveImg(e) { | ||
| 778 | window.removeEventListener('mousemove', this.moveImg) | ||
| 779 | window.removeEventListener('touchmove', this.moveImg) | ||
| 780 | window.removeEventListener('mouseup', this.leaveImg) | ||
| 781 | window.removeEventListener('touchend', this.leaveImg) | ||
| 782 | // 触发图片移动事件 | ||
| 783 | this.$emit('imgMoving', { | ||
| 784 | moving: false, | ||
| 785 | axis: this.getImgAxis() | ||
| 786 | }) | ||
| 787 | }, | ||
| 788 | // 缩放图片 | ||
| 789 | scaleImg() { | ||
| 790 | if (this.canScale) { | ||
| 791 | window.addEventListener(this.support, this.changeSize, { | ||
| 792 | passive: false | ||
| 793 | }) | ||
| 794 | } | ||
| 795 | }, | ||
| 796 | // 移出框 | ||
| 797 | cancelScale() { | ||
| 798 | if (this.canScale) { | ||
| 799 | window.removeEventListener(this.support, this.changeSize) | ||
| 800 | } | ||
| 801 | }, | ||
| 802 | // 改变大小函数 | ||
| 803 | changeSize(e) { | ||
| 804 | e.preventDefault() | ||
| 805 | let scale = this.scale | ||
| 806 | var change = e.deltaY || e.wheelDelta | ||
| 807 | // 根据图片本身大小 决定每次改变大小的系数, 图片越大系数越小 | ||
| 808 | var isFirefox = navigator.userAgent.indexOf('Firefox') | ||
| 809 | change = isFirefox > 0 ? change * 30 : change | ||
| 810 | // 修复ie的滚动缩放 | ||
| 811 | if (this.isIE) { | ||
| 812 | change = -change | ||
| 813 | } | ||
| 814 | // 1px - 0.2 | ||
| 815 | var coe = this.coe | ||
| 816 | coe = | ||
| 817 | coe / this.trueWidth > coe / this.trueHeight | ||
| 818 | ? coe / this.trueHeight | ||
| 819 | : coe / this.trueWidth | ||
| 820 | var num = coe * change | ||
| 821 | num < 0 | ||
| 822 | ? (scale += Math.abs(num)) | ||
| 823 | : scale > Math.abs(num) | ||
| 824 | ? (scale -= Math.abs(num)) | ||
| 825 | : scale | ||
| 826 | // 延迟0.1s 每次放大大或者缩小的范围 | ||
| 827 | let status = num < 0 ? 'add' : 'reduce' | ||
| 828 | if (status !== this.coeStatus) { | ||
| 829 | this.coeStatus = status | ||
| 830 | this.coe = 0.2 | ||
| 831 | } | ||
| 832 | if (!this.scaling) { | ||
| 833 | this.scalingSet = setTimeout(() => { | ||
| 834 | this.scaling = false | ||
| 835 | this.coe = this.coe += 0.01 | ||
| 836 | }, 50) | ||
| 837 | } | ||
| 838 | this.scaling = true | ||
| 839 | if (!this.checkoutImgAxis(this.x, this.y, scale)) { | ||
| 840 | return false | ||
| 841 | } | ||
| 842 | this.scale = scale | ||
| 843 | }, | ||
| 844 | |||
| 845 | // 修改图片大小函数 | ||
| 846 | changeScale(num) { | ||
| 847 | let scale = this.scale | ||
| 848 | num = num || 1 | ||
| 849 | var coe = 20 | ||
| 850 | coe = | ||
| 851 | coe / this.trueWidth > coe / this.trueHeight | ||
| 852 | ? coe / this.trueHeight | ||
| 853 | : coe / this.trueWidth | ||
| 854 | num = num * coe | ||
| 855 | num > 0 | ||
| 856 | ? (scale += Math.abs(num)) | ||
| 857 | : scale > Math.abs(num) | ||
| 858 | ? (scale -= Math.abs(num)) | ||
| 859 | : scale | ||
| 860 | if (!this.checkoutImgAxis(this.x, this.y, scale)) { | ||
| 861 | return false | ||
| 862 | } | ||
| 863 | this.scale = scale | ||
| 864 | }, | ||
| 865 | // 创建截图框 | ||
| 866 | createCrop(e) { | ||
| 867 | e.preventDefault() | ||
| 868 | // 移动生成大小 | ||
| 869 | var nowX = e.clientX ? e.clientX : e.touches ? e.touches[0].clientX : 0 | ||
| 870 | var nowY = e.clientY ? e.clientY : e.touches ? e.touches[0].clientY : 0 | ||
| 871 | this.$nextTick(() => { | ||
| 872 | // 截图框大小 | ||
| 873 | var fw = nowX - this.cropX | ||
| 874 | var fh = nowY - this.cropY | ||
| 875 | if (fw > 0) { | ||
| 876 | this.cropW = | ||
| 877 | fw + this.cropChangeX > this.w ? this.w - this.cropChangeX : fw | ||
| 878 | this.cropOffsertX = this.cropChangeX | ||
| 879 | } else { | ||
| 880 | this.cropW = | ||
| 881 | this.w - this.cropChangeX + Math.abs(fw) > this.w | ||
| 882 | ? this.cropChangeX | ||
| 883 | : Math.abs(fw) | ||
| 884 | this.cropOffsertX = | ||
| 885 | this.cropChangeX + fw > 0 ? this.cropChangeX + fw : 0 | ||
| 886 | } | ||
| 887 | |||
| 888 | if (!this.fixed) { | ||
| 889 | if (fh > 0) { | ||
| 890 | this.cropH = | ||
| 891 | fh + this.cropChangeY > this.h ? this.h - this.cropChangeY : fh | ||
| 892 | this.cropOffsertY = this.cropChangeY | ||
| 893 | } else { | ||
| 894 | this.cropH = | ||
| 895 | this.h - this.cropChangeY + Math.abs(fh) > this.h | ||
| 896 | ? this.cropChangeY | ||
| 897 | : Math.abs(fh) | ||
| 898 | this.cropOffsertY = | ||
| 899 | this.cropChangeY + fh > 0 ? this.cropChangeY + fh : 0 | ||
| 900 | } | ||
| 901 | } else { | ||
| 902 | var fixedHeight = | ||
| 903 | (this.cropW / this.fixedNumber[0]) * this.fixedNumber[1] | ||
| 904 | if (fixedHeight + this.cropOffsertY > this.h) { | ||
| 905 | this.cropH = this.h - this.cropOffsertY | ||
| 906 | this.cropW = | ||
| 907 | (this.cropH / this.fixedNumber[1]) * this.fixedNumber[0] | ||
| 908 | if (fw > 0) { | ||
| 909 | this.cropOffsertX = this.cropChangeX | ||
| 910 | } else { | ||
| 911 | this.cropOffsertX = this.cropChangeX - this.cropW | ||
| 912 | } | ||
| 913 | } else { | ||
| 914 | this.cropH = fixedHeight | ||
| 915 | } | ||
| 916 | this.cropOffsertY = this.cropOffsertY | ||
| 917 | } | ||
| 918 | }) | ||
| 919 | }, | ||
| 920 | |||
| 921 | // 改变截图框大小 | ||
| 922 | changeCropSize(e, w, h, typeW, typeH) { | ||
| 923 | e.preventDefault() | ||
| 924 | window.addEventListener('mousemove', this.changeCropNow) | ||
| 925 | window.addEventListener('mouseup', this.changeCropEnd) | ||
| 926 | window.addEventListener('touchmove', this.changeCropNow) | ||
| 927 | window.addEventListener('touchend', this.changeCropEnd) | ||
| 928 | this.canChangeX = w | ||
| 929 | this.canChangeY = h | ||
| 930 | this.changeCropTypeX = typeW | ||
| 931 | this.changeCropTypeY = typeH | ||
| 932 | this.cropX = e.clientX ? e.clientX : e.touches[0].clientX | ||
| 933 | this.cropY = e.clientY ? e.clientY : e.touches[0].clientY | ||
| 934 | this.cropOldW = this.cropW | ||
| 935 | this.cropOldH = this.cropH | ||
| 936 | this.cropChangeX = this.cropOffsertX | ||
| 937 | this.cropChangeY = this.cropOffsertY | ||
| 938 | if (this.fixed) { | ||
| 939 | if (this.canChangeX && this.canChangeY) { | ||
| 940 | this.canChangeY = 0 | ||
| 941 | } | ||
| 942 | } | ||
| 943 | }, | ||
| 944 | |||
| 945 | // 正在改变 | ||
| 946 | changeCropNow(e) { | ||
| 947 | e.preventDefault() | ||
| 948 | var nowX = e.clientX ? e.clientX : e.touches ? e.touches[0].clientX : 0 | ||
| 949 | var nowY = e.clientY ? e.clientY : e.touches ? e.touches[0].clientY : 0 | ||
| 950 | // 容器的宽高 | ||
| 951 | let wrapperW = this.w | ||
| 952 | let wrapperH = this.h | ||
| 953 | |||
| 954 | // 不能超过的坐标轴 | ||
| 955 | let minX = 0 | ||
| 956 | let minY = 0 | ||
| 957 | |||
| 958 | if (this.centerBox) { | ||
| 959 | let axis = this.getImgAxis() | ||
| 960 | let imgW = axis.x2 | ||
| 961 | let imgH = axis.y2 | ||
| 962 | minX = axis.x1 > 0 ? axis.x1 : 0 | ||
| 963 | minY = axis.y1 > 0 ? axis.y1 : 0 | ||
| 964 | if (wrapperW > imgW) { | ||
| 965 | wrapperW = imgW | ||
| 966 | } | ||
| 967 | |||
| 968 | if (wrapperH > imgH) { | ||
| 969 | wrapperH = imgH | ||
| 970 | } | ||
| 971 | } | ||
| 972 | |||
| 973 | this.$nextTick(() => { | ||
| 974 | var fw = nowX - this.cropX | ||
| 975 | var fh = nowY - this.cropY | ||
| 976 | if (this.canChangeX) { | ||
| 977 | if (this.changeCropTypeX === 1) { | ||
| 978 | if (this.cropOldW - fw > 0) { | ||
| 979 | this.cropW = | ||
| 980 | wrapperW - this.cropChangeX - fw <= wrapperW - minX | ||
| 981 | ? this.cropOldW - fw | ||
| 982 | : this.cropOldW + this.cropChangeX - minX | ||
| 983 | this.cropOffsertX = | ||
| 984 | wrapperW - this.cropChangeX - fw <= wrapperW - minX | ||
| 985 | ? this.cropChangeX + fw | ||
| 986 | : minX | ||
| 987 | } else { | ||
| 988 | this.cropW = | ||
| 989 | Math.abs(fw) + this.cropChangeX <= wrapperW | ||
| 990 | ? Math.abs(fw) - this.cropOldW | ||
| 991 | : wrapperW - this.cropOldW - this.cropChangeX | ||
| 992 | this.cropOffsertX = this.cropChangeX + this.cropOldW | ||
| 993 | } | ||
| 994 | } else if (this.changeCropTypeX === 2) { | ||
| 995 | if (this.cropOldW + fw > 0) { | ||
| 996 | this.cropW = | ||
| 997 | this.cropOldW + fw + this.cropOffsertX <= wrapperW | ||
| 998 | ? this.cropOldW + fw | ||
| 999 | : wrapperW - this.cropOffsertX | ||
| 1000 | this.cropOffsertX = this.cropChangeX | ||
| 1001 | } else { | ||
| 1002 | // 右侧坐标抽 超过左侧 | ||
| 1003 | this.cropW = | ||
| 1004 | wrapperW - this.cropChangeX + Math.abs(fw + this.cropOldW) <= | ||
| 1005 | wrapperW - minX | ||
| 1006 | ? Math.abs(fw + this.cropOldW) | ||
| 1007 | : this.cropChangeX - minX | ||
| 1008 | this.cropOffsertX = | ||
| 1009 | wrapperW - this.cropChangeX + Math.abs(fw + this.cropOldW) <= | ||
| 1010 | wrapperW - minX | ||
| 1011 | ? this.cropChangeX - Math.abs(fw + this.cropOldW) | ||
| 1012 | : minX | ||
| 1013 | } | ||
| 1014 | } | ||
| 1015 | } | ||
| 1016 | |||
| 1017 | if (this.canChangeY) { | ||
| 1018 | if (this.changeCropTypeY === 1) { | ||
| 1019 | if (this.cropOldH - fh > 0) { | ||
| 1020 | this.cropH = | ||
| 1021 | wrapperH - this.cropChangeY - fh <= wrapperH - minY | ||
| 1022 | ? this.cropOldH - fh | ||
| 1023 | : this.cropOldH + this.cropChangeY - minY | ||
| 1024 | this.cropOffsertY = | ||
| 1025 | wrapperH - this.cropChangeY - fh <= wrapperH - minY | ||
| 1026 | ? this.cropChangeY + fh | ||
| 1027 | : minY | ||
| 1028 | } else { | ||
| 1029 | this.cropH = | ||
| 1030 | Math.abs(fh) + this.cropChangeY <= wrapperH | ||
| 1031 | ? Math.abs(fh) - this.cropOldH | ||
| 1032 | : wrapperH - this.cropOldH - this.cropChangeY | ||
| 1033 | this.cropOffsertY = this.cropChangeY + this.cropOldH | ||
| 1034 | } | ||
| 1035 | } else if (this.changeCropTypeY === 2) { | ||
| 1036 | if (this.cropOldH + fh > 0) { | ||
| 1037 | this.cropH = | ||
| 1038 | this.cropOldH + fh + this.cropOffsertY <= wrapperH | ||
| 1039 | ? this.cropOldH + fh | ||
| 1040 | : wrapperH - this.cropOffsertY | ||
| 1041 | this.cropOffsertY = this.cropChangeY | ||
| 1042 | } else { | ||
| 1043 | this.cropH = | ||
| 1044 | wrapperH - this.cropChangeY + Math.abs(fh + this.cropOldH) <= | ||
| 1045 | wrapperH - minY | ||
| 1046 | ? Math.abs(fh + this.cropOldH) | ||
| 1047 | : this.cropChangeY - minY | ||
| 1048 | this.cropOffsertY = | ||
| 1049 | wrapperH - this.cropChangeY + Math.abs(fh + this.cropOldH) <= | ||
| 1050 | wrapperH - minY | ||
| 1051 | ? this.cropChangeY - Math.abs(fh + this.cropOldH) | ||
| 1052 | : minY | ||
| 1053 | } | ||
| 1054 | } | ||
| 1055 | } | ||
| 1056 | |||
| 1057 | if (this.canChangeX && this.fixed) { | ||
| 1058 | var fixedHeight = | ||
| 1059 | (this.cropW / this.fixedNumber[0]) * this.fixedNumber[1] | ||
| 1060 | if (fixedHeight + this.cropOffsertY > wrapperH) { | ||
| 1061 | this.cropH = wrapperH - this.cropOffsertY | ||
| 1062 | this.cropW = | ||
| 1063 | (this.cropH / this.fixedNumber[1]) * this.fixedNumber[0] | ||
| 1064 | } else { | ||
| 1065 | this.cropH = fixedHeight | ||
| 1066 | } | ||
| 1067 | } | ||
| 1068 | |||
| 1069 | if (this.canChangeY && this.fixed) { | ||
| 1070 | var fixedWidth = | ||
| 1071 | (this.cropH / this.fixedNumber[1]) * this.fixedNumber[0] | ||
| 1072 | if (fixedWidth + this.cropOffsertX > wrapperW) { | ||
| 1073 | this.cropW = wrapperW - this.cropOffsertX | ||
| 1074 | this.cropH = | ||
| 1075 | (this.cropW / this.fixedNumber[0]) * this.fixedNumber[1] | ||
| 1076 | } else { | ||
| 1077 | this.cropW = fixedWidth | ||
| 1078 | } | ||
| 1079 | } | ||
| 1080 | }) | ||
| 1081 | }, | ||
| 1082 | |||
| 1083 | // 结束改变 | ||
| 1084 | changeCropEnd(e) { | ||
| 1085 | // 抛出改变后截图的大小 | ||
| 1086 | this.$emit('changeCropEnd', this.getCropAxis()) | ||
| 1087 | window.removeEventListener('mousemove', this.changeCropNow) | ||
| 1088 | window.removeEventListener('mouseup', this.changeCropEnd) | ||
| 1089 | window.removeEventListener('touchmove', this.changeCropNow) | ||
| 1090 | window.removeEventListener('touchend', this.changeCropEnd) | ||
| 1091 | }, | ||
| 1092 | |||
| 1093 | // 创建完成 | ||
| 1094 | endCrop() { | ||
| 1095 | if (this.cropW === 0 && this.cropH === 0) { | ||
| 1096 | this.cropping = false | ||
| 1097 | } | ||
| 1098 | // 截图完成 截图有效范围是10×10 | ||
| 1099 | if (this.cropInfo.width >= 10 && this.cropInfo.height >= 10) { | ||
| 1100 | this.$emit('cropFinishd', 'end') | ||
| 1101 | } | ||
| 1102 | window.removeEventListener('mousemove', this.createCrop) | ||
| 1103 | window.removeEventListener('mouseup', this.endCrop) | ||
| 1104 | window.removeEventListener('touchmove', this.createCrop) | ||
| 1105 | window.removeEventListener('touchend', this.endCrop) | ||
| 1106 | }, | ||
| 1107 | // 开始截图 | ||
| 1108 | startCrop() { | ||
| 1109 | this.crop = true | ||
| 1110 | // console.log('开始截图') | ||
| 1111 | }, | ||
| 1112 | // 停止截图 | ||
| 1113 | stopCrop() { | ||
| 1114 | this.crop = false | ||
| 1115 | // console.log('停止截图') | ||
| 1116 | }, | ||
| 1117 | // 清除截图 | ||
| 1118 | clearCrop() { | ||
| 1119 | this.cropping = false | ||
| 1120 | this.cropW = 0 | ||
| 1121 | this.cropH = 0 | ||
| 1122 | // console.log('清除截图') | ||
| 1123 | }, | ||
| 1124 | // 截图移动 | ||
| 1125 | cropMove(e) { | ||
| 1126 | e.preventDefault() | ||
| 1127 | if (!this.canMoveBox) { | ||
| 1128 | this.crop = false | ||
| 1129 | this.startMove(e) | ||
| 1130 | return false | ||
| 1131 | } | ||
| 1132 | |||
| 1133 | if (e.touches && e.touches.length === 2) { | ||
| 1134 | this.crop = false | ||
| 1135 | this.startMove(e) | ||
| 1136 | this.leaveCrop() | ||
| 1137 | return false | ||
| 1138 | } | ||
| 1139 | window.addEventListener('mousemove', this.moveCrop) | ||
| 1140 | window.addEventListener('mouseup', this.leaveCrop) | ||
| 1141 | window.addEventListener('touchmove', this.moveCrop) | ||
| 1142 | window.addEventListener('touchend', this.leaveCrop) | ||
| 1143 | let x = e.clientX ? e.clientX : e.touches[0].clientX | ||
| 1144 | let y = e.clientY ? e.clientY : e.touches[0].clientY | ||
| 1145 | let newX, newY | ||
| 1146 | newX = x - this.cropOffsertX | ||
| 1147 | newY = y - this.cropOffsertY | ||
| 1148 | this.cropX = newX | ||
| 1149 | this.cropY = newY | ||
| 1150 | // 触发截图框移动事件 | ||
| 1151 | this.$emit('cropMoving', { | ||
| 1152 | moving: true, | ||
| 1153 | axis: this.getCropAxis() | ||
| 1154 | }) | ||
| 1155 | }, | ||
| 1156 | |||
| 1157 | moveCrop(e, isMove) { | ||
| 1158 | let nowX = 0 | ||
| 1159 | let nowY = 0 | ||
| 1160 | if (e) { | ||
| 1161 | e.preventDefault() | ||
| 1162 | nowX = e.clientX ? e.clientX : e.touches[0].clientX | ||
| 1163 | nowY = e.clientY ? e.clientY : e.touches[0].clientY | ||
| 1164 | } | ||
| 1165 | this.$nextTick(() => { | ||
| 1166 | let cx, cy | ||
| 1167 | let fw = nowX - this.cropX | ||
| 1168 | let fh = nowY - this.cropY | ||
| 1169 | if (isMove) { | ||
| 1170 | fw = this.cropOffsertX | ||
| 1171 | fh = this.cropOffsertY | ||
| 1172 | } | ||
| 1173 | // 不能超过外层容器 | ||
| 1174 | if (fw <= 0) { | ||
| 1175 | cx = 0 | ||
| 1176 | } else if (fw + this.cropW > this.w) { | ||
| 1177 | cx = this.w - this.cropW | ||
| 1178 | } else { | ||
| 1179 | cx = fw | ||
| 1180 | } | ||
| 1181 | |||
| 1182 | if (fh <= 0) { | ||
| 1183 | cy = 0 | ||
| 1184 | } else if (fh + this.cropH > this.h) { | ||
| 1185 | cy = this.h - this.cropH | ||
| 1186 | } else { | ||
| 1187 | cy = fh | ||
| 1188 | } | ||
| 1189 | |||
| 1190 | // 不能超过图片 | ||
| 1191 | if (this.centerBox) { | ||
| 1192 | let axis = this.getImgAxis() | ||
| 1193 | // 横坐标判断 | ||
| 1194 | if (cx <= axis.x1) { | ||
| 1195 | cx = axis.x1 | ||
| 1196 | } | ||
| 1197 | |||
| 1198 | if (cx + this.cropW > axis.x2) { | ||
| 1199 | cx = axis.x2 - this.cropW | ||
| 1200 | } | ||
| 1201 | |||
| 1202 | // 纵坐标纵轴 | ||
| 1203 | if (cy <= axis.y1) { | ||
| 1204 | cy = axis.y1 | ||
| 1205 | } | ||
| 1206 | |||
| 1207 | if (cy + this.cropH > axis.y2) { | ||
| 1208 | cy = axis.y2 - this.cropH | ||
| 1209 | } | ||
| 1210 | } | ||
| 1211 | |||
| 1212 | this.cropOffsertX = cx | ||
| 1213 | this.cropOffsertY = cy | ||
| 1214 | |||
| 1215 | // 触发截图框移动事件 | ||
| 1216 | this.$emit('cropMoving', { | ||
| 1217 | moving: true, | ||
| 1218 | axis: this.getCropAxis() | ||
| 1219 | }) | ||
| 1220 | }) | ||
| 1221 | }, | ||
| 1222 | |||
| 1223 | // 算出不同场景下面 图片相对于外层容器的坐标轴 | ||
| 1224 | getImgAxis(x, y, scale) { | ||
| 1225 | x = x || this.x | ||
| 1226 | y = y || this.y | ||
| 1227 | scale = scale || this.scale | ||
| 1228 | // 如果设置了截图框在图片内, 那么限制截图框不能超过图片的坐标 | ||
| 1229 | // 图片的坐标 | ||
| 1230 | let obj = { | ||
| 1231 | x1: 0, | ||
| 1232 | x2: 0, | ||
| 1233 | y1: 0, | ||
| 1234 | y2: 0 | ||
| 1235 | } | ||
| 1236 | let imgW = this.trueWidth * scale | ||
| 1237 | let imgH = this.trueHeight * scale | ||
| 1238 | switch (this.rotate) { | ||
| 1239 | case 0: | ||
| 1240 | obj.x1 = x + (this.trueWidth * (1 - scale)) / 2 | ||
| 1241 | obj.x2 = obj.x1 + this.trueWidth * scale | ||
| 1242 | obj.y1 = y + (this.trueHeight * (1 - scale)) / 2 | ||
| 1243 | obj.y2 = obj.y1 + this.trueHeight * scale | ||
| 1244 | break | ||
| 1245 | case 1: | ||
| 1246 | case -1: | ||
| 1247 | case 3: | ||
| 1248 | case -3: | ||
| 1249 | obj.x1 = x + (this.trueWidth * (1 - scale)) / 2 + (imgW - imgH) / 2 | ||
| 1250 | obj.x2 = obj.x1 + this.trueHeight * scale | ||
| 1251 | obj.y1 = y + (this.trueHeight * (1 - scale)) / 2 + (imgH - imgW) / 2 | ||
| 1252 | obj.y2 = obj.y1 + this.trueWidth * scale | ||
| 1253 | break | ||
| 1254 | default: | ||
| 1255 | obj.x1 = x + (this.trueWidth * (1 - scale)) / 2 | ||
| 1256 | obj.x2 = obj.x1 + this.trueWidth * scale | ||
| 1257 | obj.y1 = y + (this.trueHeight * (1 - scale)) / 2 | ||
| 1258 | obj.y2 = obj.y1 + this.trueHeight * scale | ||
| 1259 | break | ||
| 1260 | } | ||
| 1261 | return obj | ||
| 1262 | }, | ||
| 1263 | |||
| 1264 | // 获取截图框的坐标轴以及缩放率 | ||
| 1265 | getCropAxis() { | ||
| 1266 | let obj = { | ||
| 1267 | x1: 0, | ||
| 1268 | x2: 0, | ||
| 1269 | y1: 0, | ||
| 1270 | y2: 0, | ||
| 1271 | //以下宽高偏移量用于自动截图 | ||
| 1272 | cropW: 0, | ||
| 1273 | cropH: 0, | ||
| 1274 | cropOffsertX: 0, | ||
| 1275 | cropOffsertY: 0, | ||
| 1276 | scale: this.scale | ||
| 1277 | } | ||
| 1278 | obj.x1 = this.cropOffsertX | ||
| 1279 | obj.x2 = obj.x1 + this.cropW | ||
| 1280 | obj.cropW = this.cropW | ||
| 1281 | obj.cropOffsertX = this.cropOffsertX | ||
| 1282 | obj.y1 = this.cropOffsertY | ||
| 1283 | obj.y2 = obj.y1 + this.cropH | ||
| 1284 | obj.cropH = this.cropH | ||
| 1285 | obj.cropOffsertY = this.cropOffsertY | ||
| 1286 | return obj | ||
| 1287 | }, | ||
| 1288 | leaveCrop(e) { | ||
| 1289 | window.removeEventListener('mousemove', this.moveCrop) | ||
| 1290 | window.removeEventListener('mouseup', this.leaveCrop) | ||
| 1291 | // window.removeEventListener('touchmove', this.moveCrop) | ||
| 1292 | // window.removeEventListener('touchend', this.leaveCrop) | ||
| 1293 | // 触发截图框移动事件 | ||
| 1294 | this.$emit('cropMoving', { | ||
| 1295 | moving: false, | ||
| 1296 | axis: this.getCropAxis() | ||
| 1297 | }) | ||
| 1298 | }, | ||
| 1299 | |||
| 1300 | getCropChecked(cb) { | ||
| 1301 | let canvas = document.createElement('canvas') | ||
| 1302 | let img = new Image() | ||
| 1303 | let rotate = this.rotate | ||
| 1304 | let trueWidth = this.trueWidth | ||
| 1305 | let trueHeight = this.trueHeight | ||
| 1306 | let cropOffsertX = this.cropOffsertX | ||
| 1307 | let cropOffsertY = this.cropOffsertY | ||
| 1308 | img.onload = () => { | ||
| 1309 | if (this.cropW !== 0) { | ||
| 1310 | let ctx = canvas.getContext('2d') | ||
| 1311 | let dpr = 1 | ||
| 1312 | if (this.high & !this.full) { | ||
| 1313 | dpr = window.devicePixelRatio | ||
| 1314 | } | ||
| 1315 | if ((this.enlarge !== 1) & !this.full) { | ||
| 1316 | dpr = Math.abs(Number(this.enlarge)) | ||
| 1317 | console.log(dpr) | ||
| 1318 | } | ||
| 1319 | let width = this.cropW * dpr | ||
| 1320 | let height = this.cropH * dpr | ||
| 1321 | let imgW = trueWidth * this.scale * dpr | ||
| 1322 | let imgH = trueHeight * this.scale * dpr | ||
| 1323 | // 图片x轴偏移 | ||
| 1324 | let dx = | ||
| 1325 | (this.x - cropOffsertX + (this.trueWidth * (1 - this.scale)) / 2) * | ||
| 1326 | dpr | ||
| 1327 | // 图片y轴偏移 | ||
| 1328 | let dy = | ||
| 1329 | (this.y - cropOffsertY + (this.trueHeight * (1 - this.scale)) / 2) * | ||
| 1330 | dpr | ||
| 1331 | // console.log(dx, dy) | ||
| 1332 | // 保存状态 | ||
| 1333 | setCanvasSize(width, height) | ||
| 1334 | ctx.save() | ||
| 1335 | switch (rotate) { | ||
| 1336 | case 0: | ||
| 1337 | if (!this.full) { | ||
| 1338 | ctx.drawImage(img, dx, dy, imgW, imgH) | ||
| 1339 | } else { | ||
| 1340 | // 输出原图比例截图 | ||
| 1341 | setCanvasSize(width / this.scale, height / this.scale) | ||
| 1342 | ctx.drawImage( | ||
| 1343 | img, | ||
| 1344 | dx / this.scale, | ||
| 1345 | dy / this.scale, | ||
| 1346 | imgW / this.scale, | ||
| 1347 | imgH / this.scale | ||
| 1348 | ) | ||
| 1349 | } | ||
| 1350 | break | ||
| 1351 | case 1: | ||
| 1352 | case -3: | ||
| 1353 | if (!this.full) { | ||
| 1354 | // 换算图片旋转后的坐标弥补 | ||
| 1355 | dx = dx + (imgW - imgH) / 2 | ||
| 1356 | dy = dy + (imgH - imgW) / 2 | ||
| 1357 | ctx.rotate((rotate * 90 * Math.PI) / 180) | ||
| 1358 | ctx.drawImage(img, dy, -dx - imgH, imgW, imgH) | ||
| 1359 | } else { | ||
| 1360 | setCanvasSize(width / this.scale, height / this.scale) | ||
| 1361 | // 换算图片旋转后的坐标弥补 | ||
| 1362 | dx = | ||
| 1363 | dx / this.scale + (imgW / this.scale - imgH / this.scale) / 2 | ||
| 1364 | dy = | ||
| 1365 | dy / this.scale + (imgH / this.scale - imgW / this.scale) / 2 | ||
| 1366 | ctx.rotate((rotate * 90 * Math.PI) / 180) | ||
| 1367 | ctx.drawImage( | ||
| 1368 | img, | ||
| 1369 | dy, | ||
| 1370 | -dx - imgH / this.scale, | ||
| 1371 | imgW / this.scale, | ||
| 1372 | imgH / this.scale | ||
| 1373 | ) | ||
| 1374 | } | ||
| 1375 | break | ||
| 1376 | case 2: | ||
| 1377 | case -2: | ||
| 1378 | if (!this.full) { | ||
| 1379 | ctx.rotate((rotate * 90 * Math.PI) / 180) | ||
| 1380 | ctx.drawImage(img, -dx - imgW, -dy - imgH, imgW, imgH) | ||
| 1381 | } else { | ||
| 1382 | setCanvasSize(width / this.scale, height / this.scale) | ||
| 1383 | ctx.rotate((rotate * 90 * Math.PI) / 180) | ||
| 1384 | dx = dx / this.scale | ||
| 1385 | dy = dy / this.scale | ||
| 1386 | ctx.drawImage( | ||
| 1387 | img, | ||
| 1388 | -dx - imgW / this.scale, | ||
| 1389 | -dy - imgH / this.scale, | ||
| 1390 | imgW / this.scale, | ||
| 1391 | imgH / this.scale | ||
| 1392 | ) | ||
| 1393 | } | ||
| 1394 | break | ||
| 1395 | case 3: | ||
| 1396 | case -1: | ||
| 1397 | if (!this.full) { | ||
| 1398 | // 换算图片旋转后的坐标弥补 | ||
| 1399 | dx = dx + (imgW - imgH) / 2 | ||
| 1400 | dy = dy + (imgH - imgW) / 2 | ||
| 1401 | ctx.rotate((rotate * 90 * Math.PI) / 180) | ||
| 1402 | ctx.drawImage(img, -dy - imgW, dx, imgW, imgH) | ||
| 1403 | } else { | ||
| 1404 | setCanvasSize(width / this.scale, height / this.scale) | ||
| 1405 | // 换算图片旋转后的坐标弥补 | ||
| 1406 | dx = | ||
| 1407 | dx / this.scale + (imgW / this.scale - imgH / this.scale) / 2 | ||
| 1408 | dy = | ||
| 1409 | dy / this.scale + (imgH / this.scale - imgW / this.scale) / 2 | ||
| 1410 | ctx.rotate((rotate * 90 * Math.PI) / 180) | ||
| 1411 | ctx.drawImage( | ||
| 1412 | img, | ||
| 1413 | -dy - imgW / this.scale, | ||
| 1414 | dx, | ||
| 1415 | imgW / this.scale, | ||
| 1416 | imgH / this.scale | ||
| 1417 | ) | ||
| 1418 | } | ||
| 1419 | break | ||
| 1420 | default: | ||
| 1421 | if (!this.full) { | ||
| 1422 | ctx.drawImage(img, dx, dy, imgW, imgH) | ||
| 1423 | } else { | ||
| 1424 | // 输出原图比例截图 | ||
| 1425 | setCanvasSize(width / this.scale, height / this.scale) | ||
| 1426 | ctx.drawImage( | ||
| 1427 | img, | ||
| 1428 | dx / this.scale, | ||
| 1429 | dy / this.scale, | ||
| 1430 | imgW / this.scale, | ||
| 1431 | imgH / this.scale | ||
| 1432 | ) | ||
| 1433 | } | ||
| 1434 | } | ||
| 1435 | ctx.restore() | ||
| 1436 | } else { | ||
| 1437 | let width = trueWidth * this.scale | ||
| 1438 | let height = trueHeight * this.scale | ||
| 1439 | let ctx = canvas.getContext('2d') | ||
| 1440 | ctx.save() | ||
| 1441 | switch (rotate) { | ||
| 1442 | case 0: | ||
| 1443 | setCanvasSize(width, height) | ||
| 1444 | ctx.drawImage(img, 0, 0, width, height) | ||
| 1445 | break | ||
| 1446 | case 1: | ||
| 1447 | case -3: | ||
| 1448 | // 旋转90度 或者-270度 宽度和高度对调 | ||
| 1449 | setCanvasSize(height, width) | ||
| 1450 | ctx.rotate((rotate * 90 * Math.PI) / 180) | ||
| 1451 | ctx.drawImage(img, 0, -height, width, height) | ||
| 1452 | break | ||
| 1453 | case 2: | ||
| 1454 | case -2: | ||
| 1455 | setCanvasSize(width, height) | ||
| 1456 | ctx.rotate((rotate * 90 * Math.PI) / 180) | ||
| 1457 | ctx.drawImage(img, -width, -height, width, height) | ||
| 1458 | break | ||
| 1459 | case 3: | ||
| 1460 | case -1: | ||
| 1461 | setCanvasSize(height, width) | ||
| 1462 | ctx.rotate((rotate * 90 * Math.PI) / 180) | ||
| 1463 | ctx.drawImage(img, -width, 0, width, height) | ||
| 1464 | break | ||
| 1465 | default: | ||
| 1466 | setCanvasSize(width, height) | ||
| 1467 | ctx.drawImage(img, 0, 0, width, height) | ||
| 1468 | } | ||
| 1469 | ctx.restore() | ||
| 1470 | } | ||
| 1471 | cb(canvas) | ||
| 1472 | } | ||
| 1473 | // 判断图片是否是base64 | ||
| 1474 | var s = this.img.substr(0, 4) | ||
| 1475 | if (s !== 'data') { | ||
| 1476 | img.crossOrigin = 'Anonymous' | ||
| 1477 | } | ||
| 1478 | img.src = this.imgs | ||
| 1479 | |||
| 1480 | function setCanvasSize(width, height) { | ||
| 1481 | canvas.width = Math.round(width) | ||
| 1482 | canvas.height = Math.round(height) | ||
| 1483 | } | ||
| 1484 | }, | ||
| 1485 | |||
| 1486 | // 获取转换成base64 的图片信息 | ||
| 1487 | getCropData(cb) { | ||
| 1488 | this.getCropChecked(data => { | ||
| 1489 | cb(data.toDataURL('image/' + this.outputType, this.outputSize)) | ||
| 1490 | }) | ||
| 1491 | }, | ||
| 1492 | |||
| 1493 | //canvas获取为blob对象 | ||
| 1494 | getCropBlob(cb) { | ||
| 1495 | this.getCropChecked(data => { | ||
| 1496 | data.toBlob( | ||
| 1497 | blob => cb(blob), | ||
| 1498 | 'image/' + this.outputType, | ||
| 1499 | this.outputSize | ||
| 1500 | ) | ||
| 1501 | }) | ||
| 1502 | }, | ||
| 1503 | |||
| 1504 | // 自动预览函数 | ||
| 1505 | showPreview() { | ||
| 1506 | // 优化不要多次触发 | ||
| 1507 | if (this.isCanShow) { | ||
| 1508 | this.isCanShow = false | ||
| 1509 | setTimeout(() => { | ||
| 1510 | this.isCanShow = true | ||
| 1511 | }, 16) | ||
| 1512 | } else { | ||
| 1513 | return false | ||
| 1514 | } | ||
| 1515 | let w = this.cropW | ||
| 1516 | let h = this.cropH | ||
| 1517 | let scale = this.scale | ||
| 1518 | var obj = {} | ||
| 1519 | obj.div = { | ||
| 1520 | width: `${w}px`, | ||
| 1521 | height: `${h}px` | ||
| 1522 | } | ||
| 1523 | let transformX = (this.x - this.cropOffsertX) / scale | ||
| 1524 | let transformY = (this.y - this.cropOffsertY) / scale | ||
| 1525 | let transformZ = 0 | ||
| 1526 | obj.w = w | ||
| 1527 | obj.h = h | ||
| 1528 | obj.cropOffsertX = this.cropOffsertX | ||
| 1529 | obj.cropOffsertY = this.cropOffsertY | ||
| 1530 | obj.url = this.imgs | ||
| 1531 | obj.img = { | ||
| 1532 | width: `${this.trueWidth}px`, | ||
| 1533 | height: `${this.trueHeight}px`, | ||
| 1534 | transform: `scale(${scale})translate3d(${transformX}px, ${transformY}px, ${transformZ}px)rotateZ(${this | ||
| 1535 | .rotate * 90}deg)` | ||
| 1536 | } | ||
| 1537 | obj.html = ` | ||
| 1538 | <div class="show-preview" style="width: ${obj.w}px; height: ${ | ||
| 1539 | obj.h | ||
| 1540 | }px,; overflow: hidden"> | ||
| 1541 | <div style="width: ${w}px; height: ${h}px"> | ||
| 1542 | <img src=${obj.url} style="width: ${this.trueWidth}px; height: ${ | ||
| 1543 | this.trueHeight | ||
| 1544 | }px; transform: | ||
| 1545 | scale(${scale})translate3d(${transformX}px, ${transformY}px, ${transformZ}px)rotateZ(${this | ||
| 1546 | .rotate * 90}deg)"> | ||
| 1547 | </div> | ||
| 1548 | </div>` | ||
| 1549 | this.$emit('realTime', obj) | ||
| 1550 | }, | ||
| 1551 | // reload 图片布局函数 | ||
| 1552 | reload() { | ||
| 1553 | let img = new Image() | ||
| 1554 | img.onload = () => { | ||
| 1555 | // 读取图片的信息原始信息, 解析是否需要旋转 | ||
| 1556 | // 读取图片的旋转信息 | ||
| 1557 | // 得到外层容器的宽度高度 | ||
| 1558 | this.w = parseFloat(window.getComputedStyle(this.$refs.cropper).width) | ||
| 1559 | this.h = parseFloat(window.getComputedStyle(this.$refs.cropper).height) | ||
| 1560 | //将容器宽高等于图片宽高 | ||
| 1561 | // this.w = img.width | ||
| 1562 | // this.h = img.height | ||
| 1563 | // 存入图片真实高度 | ||
| 1564 | this.trueWidth = img.width | ||
| 1565 | this.trueHeight = img.height | ||
| 1566 | |||
| 1567 | // 判断是否需要压缩大图 | ||
| 1568 | if (!this.original) { | ||
| 1569 | // 判断布局方式 mode | ||
| 1570 | this.scale = this.checkedMode() | ||
| 1571 | } else { | ||
| 1572 | this.scale = 1 | ||
| 1573 | } | ||
| 1574 | |||
| 1575 | this.$nextTick(() => { | ||
| 1576 | this.x = | ||
| 1577 | -(this.trueWidth - this.trueWidth * this.scale) / 2 + | ||
| 1578 | (this.w - this.trueWidth * this.scale) / 2 | ||
| 1579 | this.y = | ||
| 1580 | -(this.trueHeight - this.trueHeight * this.scale) / 2 + | ||
| 1581 | (this.h - this.trueHeight * this.scale) / 2 | ||
| 1582 | this.loading = false | ||
| 1583 | // // 获取是否开启了自动截图 | ||
| 1584 | if (this.autoCrop) { | ||
| 1585 | this.goAutoCrop() | ||
| 1586 | } | ||
| 1587 | // 图片加载成功的回调 | ||
| 1588 | this.$emit('imgLoad', 'success') | ||
| 1589 | setTimeout(() => { | ||
| 1590 | this.showPreview() | ||
| 1591 | }, 20) | ||
| 1592 | }) | ||
| 1593 | } | ||
| 1594 | img.onerror = () => { | ||
| 1595 | this.$emit('imgLoad', 'error') | ||
| 1596 | } | ||
| 1597 | img.src = this.imgs | ||
| 1598 | }, | ||
| 1599 | // 背景布局的函数 | ||
| 1600 | checkedMode() { | ||
| 1601 | let scale = 1 | ||
| 1602 | // 通过字符串分割 | ||
| 1603 | let imgW = this.trueWidth | ||
| 1604 | let imgH = this.trueHeight | ||
| 1605 | const arr = this.mode.split(' ') | ||
| 1606 | switch (arr[0]) { | ||
| 1607 | case 'contain': | ||
| 1608 | if (this.trueWidth > this.w) { | ||
| 1609 | // 如果图片宽度大于容器宽度 | ||
| 1610 | scale = this.w / this.trueWidth | ||
| 1611 | } | ||
| 1612 | |||
| 1613 | if (this.trueHeight * scale > this.h) { | ||
| 1614 | scale = this.h / this.trueHeight | ||
| 1615 | } | ||
| 1616 | break | ||
| 1617 | case 'cover': | ||
| 1618 | // 扩展布局 默认填充满整个容器 | ||
| 1619 | // 图片宽度大于容器 | ||
| 1620 | imgW = this.w | ||
| 1621 | scale = imgW / this.trueWidth | ||
| 1622 | imgH = imgH * scale | ||
| 1623 | // 如果扩展之后高度小于容器的外层高度 继续扩展高度 | ||
| 1624 | if (imgH < this.h) { | ||
| 1625 | imgH = this.h | ||
| 1626 | scale = imgH / this.trueHeight | ||
| 1627 | } | ||
| 1628 | break | ||
| 1629 | default: | ||
| 1630 | try { | ||
| 1631 | let str = arr[0] | ||
| 1632 | if (str.search('px') !== -1) { | ||
| 1633 | str = str.replace('px', '') | ||
| 1634 | imgW = parseFloat(str) | ||
| 1635 | scale = imgW / this.trueWidth | ||
| 1636 | } | ||
| 1637 | if (str.search('%') !== -1) { | ||
| 1638 | str = str.replace('%', '') | ||
| 1639 | imgW = (parseFloat(str) / 100) * this.w | ||
| 1640 | scale = imgW / this.trueWidth | ||
| 1641 | } | ||
| 1642 | |||
| 1643 | if (arr.length === 2 && str === 'auto') { | ||
| 1644 | let str2 = arr[1] | ||
| 1645 | if (str2.search('px') !== -1) { | ||
| 1646 | str2 = str2.replace('px', '') | ||
| 1647 | imgH = parseFloat(str2) | ||
| 1648 | scale = imgH / this.trueHeight | ||
| 1649 | } | ||
| 1650 | if (str2.search('%') !== -1) { | ||
| 1651 | str2 = str2.replace('%', '') | ||
| 1652 | imgH = (parseFloat(str2) / 100) * this.h | ||
| 1653 | scale = imgH / this.trueHeight | ||
| 1654 | } | ||
| 1655 | } | ||
| 1656 | } catch (error) { | ||
| 1657 | scale = 1 | ||
| 1658 | } | ||
| 1659 | } | ||
| 1660 | return scale | ||
| 1661 | }, | ||
| 1662 | // 自动截图函数 | ||
| 1663 | goAutoCrop(cw, ch, offX, offY) { | ||
| 1664 | this.clearCrop() | ||
| 1665 | this.cropping = true | ||
| 1666 | let maxWidth = this.w | ||
| 1667 | let maxHeight = this.h | ||
| 1668 | if (this.centerBox) { | ||
| 1669 | let imgW = this.trueWidth * this.scale | ||
| 1670 | let imgH = this.trueHeight * this.scale | ||
| 1671 | maxWidth = imgW < maxWidth ? imgW : maxWidth | ||
| 1672 | maxHeight = imgH < maxHeight ? imgH : maxHeight | ||
| 1673 | } | ||
| 1674 | // 截图框默认大小 | ||
| 1675 | // 如果为0 那么计算容器大小 默认为80% | ||
| 1676 | var w = cw ? cw : parseFloat(this.autoCropWidth) | ||
| 1677 | var h = ch ? ch : parseFloat(this.autoCropHeight) | ||
| 1678 | if (w === 0 || h === 0) { | ||
| 1679 | w = maxWidth * 0.8 | ||
| 1680 | h = maxHeight * 0.8 | ||
| 1681 | } | ||
| 1682 | w = w > maxWidth ? maxWidth : w | ||
| 1683 | h = h > maxHeight ? maxHeight : h | ||
| 1684 | if (this.fixed) { | ||
| 1685 | h = (w / this.fixedNumber[0]) * this.fixedNumber[1] | ||
| 1686 | } | ||
| 1687 | // 如果比例之后 高度大于h | ||
| 1688 | if (h > this.h) { | ||
| 1689 | h = this.h | ||
| 1690 | w = (h / this.fixedNumber[1]) * this.fixedNumber[0] | ||
| 1691 | } | ||
| 1692 | this.changeCrop(w, h, offX, offY) | ||
| 1693 | }, | ||
| 1694 | // 手动改变截图框大小函数 | ||
| 1695 | changeCrop(w, h, offX, offY) { | ||
| 1696 | let whRate = w / h | ||
| 1697 | if (Number.isNaN(whRate)) | ||
| 1698 | whRate = this.fixedNumber[0] / this.fixedNumber[1] | ||
| 1699 | if (this.centerBox) { | ||
| 1700 | // 修复初始化时候在centerBox=true情况下 | ||
| 1701 | let axis = this.getImgAxis() | ||
| 1702 | if (w > axis.x2 - axis.x1) { | ||
| 1703 | // 宽度超标 | ||
| 1704 | w = axis.x2 - axis.x1 | ||
| 1705 | h = w / whRate | ||
| 1706 | } | ||
| 1707 | if (h > axis.y2 - axis.y1) { | ||
| 1708 | // 高度超标 | ||
| 1709 | h = axis.y2 - axis.y1 | ||
| 1710 | w = h * whRate | ||
| 1711 | } | ||
| 1712 | } | ||
| 1713 | // 判断是否大于容器 | ||
| 1714 | this.cropW = w | ||
| 1715 | this.cropH = h | ||
| 1716 | // 居中走一走 (修改后,以传入的cropOffsertX、Y为准) | ||
| 1717 | // this.cropOffsertX = (this.w - w) / 2 | ||
| 1718 | // this.cropOffsertY = (this.h - h) / 2 | ||
| 1719 | offX ? (this.cropOffsertX = offX) : (this.cropOffsertX = (this.w - w) / 2) | ||
| 1720 | offY ? (this.cropOffsertY = offY) : (this.cropOffsertY = (this.h - h) / 2) | ||
| 1721 | if (this.centerBox) { | ||
| 1722 | this.$nextTick(() => { | ||
| 1723 | this.moveCrop(null, true) | ||
| 1724 | }) | ||
| 1725 | } | ||
| 1726 | }, | ||
| 1727 | // 重置函数, 恢复组件置初始状态 | ||
| 1728 | refresh() { | ||
| 1729 | // console.log('refresh') | ||
| 1730 | let img = this.img | ||
| 1731 | this.imgs = '' | ||
| 1732 | this.scale = 1 | ||
| 1733 | this.crop = false | ||
| 1734 | this.rotate = 0 | ||
| 1735 | this.w = 0 | ||
| 1736 | this.h = 0 | ||
| 1737 | this.trueWidth = 0 | ||
| 1738 | this.trueHeight = 0 | ||
| 1739 | this.clearCrop() | ||
| 1740 | this.$nextTick(() => { | ||
| 1741 | this.checkedImg() | ||
| 1742 | }) | ||
| 1743 | }, | ||
| 1744 | |||
| 1745 | // 向左边旋转 | ||
| 1746 | rotateLeft() { | ||
| 1747 | this.rotate = this.rotate <= -3 ? 0 : this.rotate - 1 | ||
| 1748 | }, | ||
| 1749 | |||
| 1750 | // 向右边旋转 | ||
| 1751 | rotateRight() { | ||
| 1752 | this.rotate = this.rotate >= 3 ? 0 : this.rotate + 1 | ||
| 1753 | }, | ||
| 1754 | |||
| 1755 | // 清除旋转 | ||
| 1756 | rotateClear() { | ||
| 1757 | this.rotate = 0 | ||
| 1758 | }, | ||
| 1759 | |||
| 1760 | // 图片坐标点校验 | ||
| 1761 | checkoutImgAxis(x, y, scale) { | ||
| 1762 | x = x || this.x | ||
| 1763 | y = y || this.y | ||
| 1764 | scale = scale || this.scale | ||
| 1765 | let canGo = true | ||
| 1766 | // 开始校验 如果说缩放之后的坐标在截图框外 则阻止缩放 | ||
| 1767 | if (this.centerBox) { | ||
| 1768 | let axis = this.getImgAxis(x, y, scale) | ||
| 1769 | let cropAxis = this.getCropAxis() | ||
| 1770 | // 左边的横坐标 图片不能超过截图框 | ||
| 1771 | if (axis.x1 >= cropAxis.x1) { | ||
| 1772 | canGo = false | ||
| 1773 | } | ||
| 1774 | |||
| 1775 | // 右边横坐标 | ||
| 1776 | if (axis.x2 <= cropAxis.x2) { | ||
| 1777 | canGo = false | ||
| 1778 | } | ||
| 1779 | |||
| 1780 | // 纵坐标上面 | ||
| 1781 | if (axis.y1 >= cropAxis.y1) { | ||
| 1782 | canGo = false | ||
| 1783 | } | ||
| 1784 | |||
| 1785 | // 纵坐标下面 | ||
| 1786 | if (axis.y2 <= cropAxis.y2) { | ||
| 1787 | canGo = false | ||
| 1788 | } | ||
| 1789 | } | ||
| 1790 | return canGo | ||
| 1791 | } | ||
| 1792 | }, | ||
| 1793 | mounted() { | ||
| 1794 | this.support = | ||
| 1795 | 'onwheel' in document.createElement('div') | ||
| 1796 | ? 'wheel' | ||
| 1797 | : document.onmousewheel !== undefined | ||
| 1798 | ? 'mousewheel' | ||
| 1799 | : 'DOMMouseScroll' | ||
| 1800 | let that = this | ||
| 1801 | var u = navigator.userAgent | ||
| 1802 | this.isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/) | ||
| 1803 | // 兼容blob | ||
| 1804 | if (!HTMLCanvasElement.prototype.toBlob) { | ||
| 1805 | Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', { | ||
| 1806 | value: function(callback, type, quality) { | ||
| 1807 | var binStr = atob(this.toDataURL(type, quality).split(',')[1]), | ||
| 1808 | len = binStr.length, | ||
| 1809 | arr = new Uint8Array(len) | ||
| 1810 | for (var i = 0; i < len; i++) { | ||
| 1811 | arr[i] = binStr.charCodeAt(i) | ||
| 1812 | } | ||
| 1813 | callback(new Blob([arr], { type: that.type || 'image/png' })) | ||
| 1814 | } | ||
| 1815 | }) | ||
| 1816 | } | ||
| 1817 | this.showPreview() | ||
| 1818 | this.checkedImg() | ||
| 1819 | }, | ||
| 1820 | destroyed() { | ||
| 1821 | window.removeEventListener('mousemove', this.moveCrop) | ||
| 1822 | window.removeEventListener('mouseup', this.leaveCrop) | ||
| 1823 | window.removeEventListener('touchmove', this.moveCrop) | ||
| 1824 | window.removeEventListener('touchend', this.leaveCrop) | ||
| 1825 | } | ||
| 1826 | } | ||
| 1827 | </script> | ||
| 1828 | |||
| 1829 | <style scoped lang="css"> | ||
| 1830 | .vue-cropper { | ||
| 1831 | position: relative; | ||
| 1832 | width: 100%; | ||
| 1833 | height: 100%; | ||
| 1834 | box-sizing: border-box; | ||
| 1835 | user-select: none; | ||
| 1836 | -webkit-user-select: none; | ||
| 1837 | -moz-user-select: none; | ||
| 1838 | -ms-user-select: none; | ||
| 1839 | direction: ltr; | ||
| 1840 | touch-action: none; | ||
| 1841 | text-align: left; | ||
| 1842 | background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC'); | ||
| 1843 | } | ||
| 1844 | |||
| 1845 | .cropper-box, | ||
| 1846 | .cropper-box-canvas, | ||
| 1847 | .cropper-drag-box, | ||
| 1848 | .cropper-crop-box, | ||
| 1849 | .cropper-face { | ||
| 1850 | position: absolute; | ||
| 1851 | top: 0; | ||
| 1852 | right: 0; | ||
| 1853 | bottom: 0; | ||
| 1854 | left: 0; | ||
| 1855 | user-select: none; | ||
| 1856 | } | ||
| 1857 | |||
| 1858 | .cropper-box-canvas img { | ||
| 1859 | position: relative; | ||
| 1860 | text-align: left; | ||
| 1861 | user-select: none; | ||
| 1862 | transform: none; | ||
| 1863 | max-width: none; | ||
| 1864 | max-height: none; | ||
| 1865 | } | ||
| 1866 | |||
| 1867 | .cropper-box { | ||
| 1868 | overflow: hidden; | ||
| 1869 | } | ||
| 1870 | |||
| 1871 | .cropper-move { | ||
| 1872 | cursor: move; | ||
| 1873 | } | ||
| 1874 | |||
| 1875 | .cropper-crop { | ||
| 1876 | cursor: crosshair; | ||
| 1877 | } | ||
| 1878 | |||
| 1879 | .cropper-modal { | ||
| 1880 | background: rgba(0, 0, 0, 0.5); | ||
| 1881 | } | ||
| 1882 | |||
| 1883 | .cropper-crop-box { | ||
| 1884 | /*border: 2px solid #39f;*/ | ||
| 1885 | } | ||
| 1886 | |||
| 1887 | .cropper-view-box { | ||
| 1888 | display: block; | ||
| 1889 | overflow: hidden; | ||
| 1890 | width: 100%; | ||
| 1891 | height: 100%; | ||
| 1892 | outline: 1px solid #39f; | ||
| 1893 | outline-color: rgba(51, 153, 255, 0.75); | ||
| 1894 | user-select: none; | ||
| 1895 | } | ||
| 1896 | |||
| 1897 | .cropper-view-box img { | ||
| 1898 | user-select: none; | ||
| 1899 | text-align: left; | ||
| 1900 | max-width: none; | ||
| 1901 | max-height: none; | ||
| 1902 | } | ||
| 1903 | |||
| 1904 | .cropper-face { | ||
| 1905 | top: 0; | ||
| 1906 | left: 0; | ||
| 1907 | background-color: #fff; | ||
| 1908 | opacity: 0.1; | ||
| 1909 | } | ||
| 1910 | |||
| 1911 | .crop-info { | ||
| 1912 | position: absolute; | ||
| 1913 | left: 0px; | ||
| 1914 | min-width: 65px; | ||
| 1915 | text-align: center; | ||
| 1916 | color: white; | ||
| 1917 | line-height: 20px; | ||
| 1918 | background-color: rgba(0, 0, 0, 0.8); | ||
| 1919 | font-size: 12px; | ||
| 1920 | } | ||
| 1921 | |||
| 1922 | .crop-line { | ||
| 1923 | position: absolute; | ||
| 1924 | display: block; | ||
| 1925 | width: 100%; | ||
| 1926 | height: 100%; | ||
| 1927 | opacity: 0.1; | ||
| 1928 | } | ||
| 1929 | |||
| 1930 | .line-w { | ||
| 1931 | top: -3px; | ||
| 1932 | left: 0; | ||
| 1933 | height: 5px; | ||
| 1934 | cursor: n-resize; | ||
| 1935 | } | ||
| 1936 | |||
| 1937 | .line-a { | ||
| 1938 | top: 0; | ||
| 1939 | left: -3px; | ||
| 1940 | width: 5px; | ||
| 1941 | cursor: w-resize; | ||
| 1942 | } | ||
| 1943 | |||
| 1944 | .line-s { | ||
| 1945 | bottom: -3px; | ||
| 1946 | left: 0; | ||
| 1947 | height: 5px; | ||
| 1948 | cursor: s-resize; | ||
| 1949 | } | ||
| 1950 | |||
| 1951 | .line-d { | ||
| 1952 | top: 0; | ||
| 1953 | right: -3px; | ||
| 1954 | width: 5px; | ||
| 1955 | cursor: e-resize; | ||
| 1956 | } | ||
| 1957 | |||
| 1958 | .crop-point { | ||
| 1959 | position: absolute; | ||
| 1960 | width: 8px; | ||
| 1961 | height: 8px; | ||
| 1962 | opacity: 0.75; | ||
| 1963 | background-color: #39f; | ||
| 1964 | border-radius: 100%; | ||
| 1965 | } | ||
| 1966 | |||
| 1967 | .point1 { | ||
| 1968 | top: -4px; | ||
| 1969 | left: -4px; | ||
| 1970 | cursor: nw-resize; | ||
| 1971 | } | ||
| 1972 | |||
| 1973 | .point2 { | ||
| 1974 | top: -5px; | ||
| 1975 | left: 50%; | ||
| 1976 | margin-left: -3px; | ||
| 1977 | cursor: n-resize; | ||
| 1978 | } | ||
| 1979 | |||
| 1980 | .point3 { | ||
| 1981 | top: -4px; | ||
| 1982 | right: -4px; | ||
| 1983 | cursor: ne-resize; | ||
| 1984 | } | ||
| 1985 | |||
| 1986 | .point4 { | ||
| 1987 | top: 50%; | ||
| 1988 | left: -4px; | ||
| 1989 | margin-top: -3px; | ||
| 1990 | cursor: w-resize; | ||
| 1991 | } | ||
| 1992 | |||
| 1993 | .point5 { | ||
| 1994 | top: 50%; | ||
| 1995 | right: -4px; | ||
| 1996 | margin-top: -3px; | ||
| 1997 | cursor: e-resize; | ||
| 1998 | } | ||
| 1999 | |||
| 2000 | .point6 { | ||
| 2001 | bottom: -5px; | ||
| 2002 | left: -4px; | ||
| 2003 | cursor: sw-resize; | ||
| 2004 | } | ||
| 2005 | |||
| 2006 | .point7 { | ||
| 2007 | bottom: -5px; | ||
| 2008 | left: 50%; | ||
| 2009 | margin-left: -3px; | ||
| 2010 | cursor: s-resize; | ||
| 2011 | } | ||
| 2012 | |||
| 2013 | .point8 { | ||
| 2014 | bottom: -5px; | ||
| 2015 | right: -4px; | ||
| 2016 | cursor: se-resize; | ||
| 2017 | } | ||
| 2018 | |||
| 2019 | @media screen and (max-width: 500px) { | ||
| 2020 | .crop-point { | ||
| 2021 | position: absolute; | ||
| 2022 | width: 20px; | ||
| 2023 | height: 20px; | ||
| 2024 | opacity: 0.45; | ||
| 2025 | background-color: #39f; | ||
| 2026 | border-radius: 100%; | ||
| 2027 | } | ||
| 2028 | |||
| 2029 | .point1 { | ||
| 2030 | top: -10px; | ||
| 2031 | left: -10px; | ||
| 2032 | } | ||
| 2033 | |||
| 2034 | .point2, | ||
| 2035 | .point4, | ||
| 2036 | .point5, | ||
| 2037 | .point7 { | ||
| 2038 | display: none; | ||
| 2039 | } | ||
| 2040 | |||
| 2041 | .point3 { | ||
| 2042 | top: -10px; | ||
| 2043 | right: -10px; | ||
| 2044 | } | ||
| 2045 | |||
| 2046 | .point4 { | ||
| 2047 | top: 0; | ||
| 2048 | left: 0; | ||
| 2049 | } | ||
| 2050 | |||
| 2051 | .point6 { | ||
| 2052 | bottom: -10px; | ||
| 2053 | left: -10px; | ||
| 2054 | } | ||
| 2055 | |||
| 2056 | .point8 { | ||
| 2057 | bottom: -10px; | ||
| 2058 | right: -10px; | ||
| 2059 | } | ||
| 2060 | } | ||
| 2061 | </style> |
src/directive/permission/index.js
0 → 100644
src/directive/permission/permission.js
0 → 100644
| 1 | import store from '@/store' | ||
| 2 | |||
| 3 | export default { | ||
| 4 | inserted(el, binding, vnode) { | ||
| 5 | const { value } = binding | ||
| 6 | const roles = store.state.roles | ||
| 7 | if (value && value instanceof Array && value.length > 0) { | ||
| 8 | const permissionRoles = value | ||
| 9 | const hasPermission = roles.some(role => { | ||
| 10 | return permissionRoles.includes(role) | ||
| 11 | }) | ||
| 12 | if (!hasPermission) { | ||
| 13 | el.parentNode && el.parentNode.removeChild(el) | ||
| 14 | } | ||
| 15 | } else { | ||
| 16 | throw new Error(`need roles! Like v-permission="['factory','normal']"`) | ||
| 17 | } | ||
| 18 | } | ||
| 19 | } |
src/element-variables.scss
0 → 100644
src/icons/index.js
0 → 100644
src/icons/svg/acount-active.svg
0 → 100644
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <svg width="14px" height="14px" viewBox="0 0 14 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | ||
| 3 | <!-- Generator: Sketch 55.1 (78136) - https://sketchapp.com --> | ||
| 4 | <title>账号管理-白</title> | ||
| 5 | <desc>Created with Sketch.</desc> | ||
| 6 | <g id="奇瑞后台" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> | ||
| 7 | <g id="图标" transform="translate(-23.000000, -131.000000)"> | ||
| 8 | <g id="编组-4" transform="translate(23.000000, 131.000000)"> | ||
| 9 | <g id="账号管理" fill="#FFFFFF" fill-rule="nonzero"> | ||
| 10 | <path d="M10.2230216,8.05755396 C9.4851496,8.02906906 8.80393552,8.45160855 8.50160716,9.12530285 C8.19927879,9.79899715 8.33644267,10.5887935 8.84821755,11.1211026 C9.35999242,11.6534116 10.1437849,11.8215235 10.8288455,11.545918 C11.5139061,11.2703125 11.9629036,10.6062391 11.9634532,9.86781775 C11.9494922,9.39289432 11.7753247,8.93665107 11.4692566,8.57323741 C11.129455,8.25694548 10.6869616,8.07384474 10.2230216,8.05755396 L10.2230216,8.05755396 Z M10.2230216,10.6467146 C9.81930162,10.6131005 9.50875278,10.2756205 9.50875278,9.8705036 C9.50875278,9.46538668 9.81930162,9.12790668 10.2230216,9.09429257 C10.4178006,9.11007026 10.6040891,9.18085988 10.7601918,9.29841727 C10.9065942,9.44997563 10.9792327,9.65807506 10.9589448,9.86781775 C10.9431396,10.2702783 10.6250454,10.595338 10.2230216,10.6198561 L10.2230216,10.6467146 Z" id="形状"></path> | ||
| 11 | <path d="M13.7790887,8.96 C13.3974741,8.86313379 13.0711026,8.61635671 12.873916,8.27557784 C12.6767294,7.93479897 12.625418,7.52886251 12.7316067,7.14973621 C12.7397811,7.07569471 12.7206831,7.00121265 12.6778897,6.94023981 C12.331848,6.62256644 11.9266321,6.37615136 11.4853717,6.21505995 C11.4130369,6.20722007 11.340353,6.22634744 11.281247,6.26877698 C11.0209363,6.57522731 10.6357013,6.7471014 10.233765,6.73611511 C9.83422948,6.73546094 9.45365256,6.56566509 9.18628297,6.26877698 C9.12953599,6.225711 9.05824525,6.20644323 8.98752998,6.21505995 C8.54460609,6.37602801 8.13760745,6.62241732 7.78964029,6.94023981 C7.72248855,6.98754531 7.70166323,7.07778837 7.74129496,7.14973621 C7.84086816,7.53447 7.78693155,7.94284719 7.59088729,8.28853717 C7.40923551,8.63687962 7.07923085,8.88388909 6.69381295,8.96 C6.64546763,8.96 6.5971223,9.01371703 6.54340528,9.11577938 C6.44660599,9.59438721 6.44660599,10.0875313 6.54340528,10.5661391 C6.54340528,10.6198561 6.5971223,10.6682014 6.69381295,10.7219185 C7.07608824,10.8050007 7.40343248,11.0500189 7.59088729,11.3933813 C7.78725971,11.7409174 7.84117696,12.1510736 7.74129496,12.537554 C7.73460668,12.6090549 7.75159257,12.6807731 7.78964029,12.7416787 C8.13760745,13.0595011 8.54460609,13.3058905 8.98752998,13.4668585 L9.041247,13.4668585 C9.0944142,13.4734903 9.14772828,13.4557189 9.18628297,13.4185132 C9.44559503,13.1168804 9.82528379,12.9457254 10.2230216,12.9511751 C10.634041,12.9446659 11.0270554,13.1195573 11.2973621,13.4292566 C11.3510791,13.4776019 11.3994245,13.4776019 11.5014868,13.4776019 C11.9427472,13.3165105 12.3479631,13.0700954 12.6940048,12.7524221 C12.7477218,12.698705 12.7960671,12.6503597 12.7477218,12.5482974 C12.6182907,12.1794361 12.6506553,11.7730677 12.8368394,11.4293432 C13.0230235,11.0856187 13.3457101,10.8365079 13.7253717,10.7434053 C13.7790887,10.7434053 13.8274341,10.6896882 13.8757794,10.5876259 C13.9779384,10.1095695 13.9779384,9.61532259 13.8757794,9.13726619 C13.8757794,9.06743405 13.8274341,9.01371703 13.7790887,8.96 Z M12.9088729,10.2545803 C12.5570203,10.3738745 12.2571941,10.6110788 12.0601439,10.9260432 C11.8674513,11.2354631 11.812917,11.6113602 11.9097362,11.9627818 C11.6995825,12.1612408 11.4427762,12.3035004 11.1630695,12.3764029 C10.9001251,12.1084012 10.539367,11.9590551 10.1639329,11.9627818 C9.79228538,11.9773991 9.4380279,12.124054 9.16479616,12.3764029 C8.90552032,12.2581748 8.65587259,12.1198807 8.4181295,11.9627818 C8.52125061,11.6117806 8.46633703,11.2332691 8.26772182,10.9260432 C8.07378679,10.6083049 7.77282806,10.3702047 7.41899281,10.2545803 C7.37050545,9.96292879 7.37050545,9.66527265 7.41899281,9.3736211 C7.78078559,9.26252636 8.0899869,9.0239451 8.28920863,8.70215827 C8.48447126,8.39368341 8.53916815,8.01666554 8.43961631,7.66541966 C8.65057904,7.46806986 8.90708761,7.32597519 9.18628297,7.25179856 C9.44922742,7.51980025 9.80998552,7.66914635 10.1854197,7.66541966 C10.5570671,7.65080237 10.9113246,7.50414739 11.1845564,7.25179856 C11.4444148,7.36886747 11.6941537,7.50721202 11.931223,7.66541966 C11.8309713,8.01661891 11.8857103,8.393927 12.0816307,8.70215827 C12.2702379,9.01594747 12.5630021,9.25358071 12.9088729,9.3736211 C12.9573603,9.66527265 12.9573603,9.96292879 12.9088729,10.2545803 L12.9088729,10.2545803 Z M1.51545602,10.8776978 L2.50925659,10.8776978 C2.485191,9.19597558 3.81990192,7.80854717 5.50129496,7.76748201 C5.95305398,7.76791383 6.39837238,7.87464303 6.801247,8.07904077 C6.98750594,7.78214723 7.20348599,7.50497283 7.44585132,7.25179856 C7.35677722,7.2113638 7.27364289,7.15895303 7.198753,7.09601918 C7.74475372,6.60874162 8.06220635,5.9154095 8.07434053,5.18369305 C8.07434053,4.29321926 7.59927844,3.47038755 6.82810553,3.02515066 C6.05693261,2.57991376 5.1068084,2.57991376 4.33563548,3.02515066 C3.56446257,3.47038755 3.08940047,4.29321926 3.08940048,5.18369305 C3.0690725,5.91658356 3.38100313,6.61941459 3.9381295,7.09601918 C2.45694705,7.77021525 1.50876239,9.25030837 1.51545602,10.8776978 L1.51545602,10.8776978 Z M5.50129496,3.63125663 C5.90873661,3.62948611 6.2992156,3.79426079 6.58220695,4.08739519 C6.86519829,4.3805296 7.01612586,4.77656673 7,5.18369305 C7.03332384,5.73956249 6.75569599,6.26807752 6.27908764,6.55608065 C5.80247929,6.84408378 5.20548234,6.84408378 4.72887399,6.55608065 C4.25226564,6.26807752 3.97463779,5.73956249 4.00796163,5.18369305 C3.99340666,4.7779193 4.14411589,4.38360482 4.42560278,4.09097996 C4.70708967,3.7983551 5.09526202,3.63246535 5.50129496,3.63125663 L5.50129496,3.63125663 Z" id="形状"></path> | ||
| 12 | <path d="M12.978705,0 L1.01592326,0 C0.74521743,0.00563905362 0.487846369,0.118615445 0.30045916,0.314062318 C0.113071952,0.509509191 0.0110275373,0.771407006 0.0167865707,1.04211031 L0.0167865707,11.3933813 C0.0077943878,11.9550253 0.454330229,12.4183663 1.01592326,12.4301199 L6.24796163,12.4301199 C6.15347803,12.0905554 6.08700419,11.7438135 6.04920863,11.3933813 L1.51549161,11.3933813 C1.23359784,11.3736011 1.01523013,11.1387971 1.01592326,10.856211 L1.01592326,1.55779376 C1.01523013,1.27520772 1.23359784,1.04040373 1.51549161,1.0206235 L12.4791367,1.0206235 C12.7610305,1.04040373 12.9793982,1.27520772 12.978705,1.55779376 L12.978705,6.1129976 C13.3416127,6.27160518 13.6798936,6.48144788 13.9832134,6.73611511 L13.9832134,1.04211031 C13.9889659,0.770492956 13.8861881,0.507791018 13.6976439,0.312188988 C13.5090997,0.116586957 13.2503504,0.00422874936 12.978705,0 Z" id="路径"></path> | ||
| 13 | <path d="M9.48709832,3.63127098 L11.9795683,3.63127098 C12.1204387,3.63685572 12.2567289,3.58067135 12.3527387,3.47743498 C12.4487485,3.37419862 12.4949119,3.23419632 12.4791367,3.09410072 C12.4968375,2.95359324 12.4513335,2.81246879 12.3548898,2.70876591 C12.2584461,2.60506303 12.120989,2.54945504 11.9795683,2.55693046 L9.48709832,2.55693046 C9.34659209,2.55109685 9.21064377,2.60742026 9.11543115,2.71091224 C9.02021852,2.81440422 8.97539973,2.9545668 8.99290168,3.09410072 C8.97728866,3.23323418 9.02275873,3.37230344 9.1175512,3.47533874 C9.21234368,3.57837404 9.3471483,3.63525552 9.48709832,3.63127098 L9.48709832,3.63127098 Z M9.48709832,5.6993765 L10.9858034,5.6993765 C11.1266737,5.70496124 11.2629639,5.64877687 11.3589737,5.5455405 C11.4549835,5.44230413 11.5011469,5.30230183 11.4853717,5.16220624 C11.5011469,5.02211064 11.4549835,4.88210834 11.3589737,4.77887197 C11.2629639,4.6756356 11.1266737,4.61945123 10.9858034,4.62503597 L9.48709832,4.62503597 C9.3471483,4.62105144 9.21234368,4.67793291 9.1175512,4.78096821 C9.02275873,4.88400351 8.97728866,5.02307277 8.99290168,5.16220624 C8.97539973,5.30174015 9.02021852,5.44190273 9.11543115,5.54539471 C9.21064377,5.64888669 9.34659209,5.70521011 9.48709832,5.6993765 L9.48709832,5.6993765 Z" id="形状"></path> | ||
| 14 | </g> | ||
| 15 | <rect id="账号管理-灰" x="0" y="0" width="14" height="14"></rect> | ||
| 16 | </g> | ||
| 17 | </g> | ||
| 18 | </g> | ||
| 19 | </svg> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
src/icons/svg/acount.svg
0 → 100644
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <svg width="14px" height="14px" viewBox="0 0 14 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | ||
| 3 | <!-- Generator: Sketch 55.1 (78136) - https://sketchapp.com --> | ||
| 4 | <title>账号管理-灰</title> | ||
| 5 | <desc>Created with Sketch.</desc> | ||
| 6 | <g id="奇瑞后台" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> | ||
| 7 | <g id="图标" transform="translate(-57.000000, -131.000000)"> | ||
| 8 | <g id="编组-4" transform="translate(57.000000, 131.000000)"> | ||
| 9 | <g id="账号管理" fill="#A6ADB4" fill-rule="nonzero"> | ||
| 10 | <path d="M10.2230216,8.05755396 C9.4851496,8.02906906 8.80393552,8.45160855 8.50160716,9.12530285 C8.19927879,9.79899715 8.33644267,10.5887935 8.84821755,11.1211026 C9.35999242,11.6534116 10.1437849,11.8215235 10.8288455,11.545918 C11.5139061,11.2703125 11.9629036,10.6062391 11.9634532,9.86781775 C11.9494922,9.39289432 11.7753247,8.93665107 11.4692566,8.57323741 C11.129455,8.25694548 10.6869616,8.07384474 10.2230216,8.05755396 L10.2230216,8.05755396 Z M10.2230216,10.6467146 C9.81930162,10.6131005 9.50875278,10.2756205 9.50875278,9.8705036 C9.50875278,9.46538668 9.81930162,9.12790668 10.2230216,9.09429257 C10.4178006,9.11007026 10.6040891,9.18085988 10.7601918,9.29841727 C10.9065942,9.44997563 10.9792327,9.65807506 10.9589448,9.86781775 C10.9431396,10.2702783 10.6250454,10.595338 10.2230216,10.6198561 L10.2230216,10.6467146 Z" id="形状"></path> | ||
| 11 | <path d="M13.7790887,8.96 C13.3974741,8.86313379 13.0711026,8.61635671 12.873916,8.27557784 C12.6767294,7.93479897 12.625418,7.52886251 12.7316067,7.14973621 C12.7397811,7.07569471 12.7206831,7.00121265 12.6778897,6.94023981 C12.331848,6.62256644 11.9266321,6.37615136 11.4853717,6.21505995 C11.4130369,6.20722007 11.340353,6.22634744 11.281247,6.26877698 C11.0209363,6.57522731 10.6357013,6.7471014 10.233765,6.73611511 C9.83422948,6.73546094 9.45365256,6.56566509 9.18628297,6.26877698 C9.12953599,6.225711 9.05824525,6.20644323 8.98752998,6.21505995 C8.54460609,6.37602801 8.13760745,6.62241732 7.78964029,6.94023981 C7.72248855,6.98754531 7.70166323,7.07778837 7.74129496,7.14973621 C7.84086816,7.53447 7.78693155,7.94284719 7.59088729,8.28853717 C7.40923551,8.63687962 7.07923085,8.88388909 6.69381295,8.96 C6.64546763,8.96 6.5971223,9.01371703 6.54340528,9.11577938 C6.44660599,9.59438721 6.44660599,10.0875313 6.54340528,10.5661391 C6.54340528,10.6198561 6.5971223,10.6682014 6.69381295,10.7219185 C7.07608824,10.8050007 7.40343248,11.0500189 7.59088729,11.3933813 C7.78725971,11.7409174 7.84117696,12.1510736 7.74129496,12.537554 C7.73460668,12.6090549 7.75159257,12.6807731 7.78964029,12.7416787 C8.13760745,13.0595011 8.54460609,13.3058905 8.98752998,13.4668585 L9.041247,13.4668585 C9.0944142,13.4734903 9.14772828,13.4557189 9.18628297,13.4185132 C9.44559503,13.1168804 9.82528379,12.9457254 10.2230216,12.9511751 C10.634041,12.9446659 11.0270554,13.1195573 11.2973621,13.4292566 C11.3510791,13.4776019 11.3994245,13.4776019 11.5014868,13.4776019 C11.9427472,13.3165105 12.3479631,13.0700954 12.6940048,12.7524221 C12.7477218,12.698705 12.7960671,12.6503597 12.7477218,12.5482974 C12.6182907,12.1794361 12.6506553,11.7730677 12.8368394,11.4293432 C13.0230235,11.0856187 13.3457101,10.8365079 13.7253717,10.7434053 C13.7790887,10.7434053 13.8274341,10.6896882 13.8757794,10.5876259 C13.9779384,10.1095695 13.9779384,9.61532259 13.8757794,9.13726619 C13.8757794,9.06743405 13.8274341,9.01371703 13.7790887,8.96 Z M12.9088729,10.2545803 C12.5570203,10.3738745 12.2571941,10.6110788 12.0601439,10.9260432 C11.8674513,11.2354631 11.812917,11.6113602 11.9097362,11.9627818 C11.6995825,12.1612408 11.4427762,12.3035004 11.1630695,12.3764029 C10.9001251,12.1084012 10.539367,11.9590551 10.1639329,11.9627818 C9.79228538,11.9773991 9.4380279,12.124054 9.16479616,12.3764029 C8.90552032,12.2581748 8.65587259,12.1198807 8.4181295,11.9627818 C8.52125061,11.6117806 8.46633703,11.2332691 8.26772182,10.9260432 C8.07378679,10.6083049 7.77282806,10.3702047 7.41899281,10.2545803 C7.37050545,9.96292879 7.37050545,9.66527265 7.41899281,9.3736211 C7.78078559,9.26252636 8.0899869,9.0239451 8.28920863,8.70215827 C8.48447126,8.39368341 8.53916815,8.01666554 8.43961631,7.66541966 C8.65057904,7.46806986 8.90708761,7.32597519 9.18628297,7.25179856 C9.44922742,7.51980025 9.80998552,7.66914635 10.1854197,7.66541966 C10.5570671,7.65080237 10.9113246,7.50414739 11.1845564,7.25179856 C11.4444148,7.36886747 11.6941537,7.50721202 11.931223,7.66541966 C11.8309713,8.01661891 11.8857103,8.393927 12.0816307,8.70215827 C12.2702379,9.01594747 12.5630021,9.25358071 12.9088729,9.3736211 C12.9573603,9.66527265 12.9573603,9.96292879 12.9088729,10.2545803 L12.9088729,10.2545803 Z M1.51545602,10.8776978 L2.50925659,10.8776978 C2.485191,9.19597558 3.81990192,7.80854717 5.50129496,7.76748201 C5.95305398,7.76791383 6.39837238,7.87464303 6.801247,8.07904077 C6.98750594,7.78214723 7.20348599,7.50497283 7.44585132,7.25179856 C7.35677722,7.2113638 7.27364289,7.15895303 7.198753,7.09601918 C7.74475372,6.60874162 8.06220635,5.9154095 8.07434053,5.18369305 C8.07434053,4.29321926 7.59927844,3.47038755 6.82810553,3.02515066 C6.05693261,2.57991376 5.1068084,2.57991376 4.33563548,3.02515066 C3.56446257,3.47038755 3.08940047,4.29321926 3.08940048,5.18369305 C3.0690725,5.91658356 3.38100313,6.61941459 3.9381295,7.09601918 C2.45694705,7.77021525 1.50876239,9.25030837 1.51545602,10.8776978 L1.51545602,10.8776978 Z M5.50129496,3.63125663 C5.90873661,3.62948611 6.2992156,3.79426079 6.58220695,4.08739519 C6.86519829,4.3805296 7.01612586,4.77656673 7,5.18369305 C7.03332384,5.73956249 6.75569599,6.26807752 6.27908764,6.55608065 C5.80247929,6.84408378 5.20548234,6.84408378 4.72887399,6.55608065 C4.25226564,6.26807752 3.97463779,5.73956249 4.00796163,5.18369305 C3.99340666,4.7779193 4.14411589,4.38360482 4.42560278,4.09097996 C4.70708967,3.7983551 5.09526202,3.63246535 5.50129496,3.63125663 L5.50129496,3.63125663 Z" id="形状"></path> | ||
| 12 | <path d="M12.978705,0 L1.01592326,0 C0.74521743,0.00563905362 0.487846369,0.118615445 0.30045916,0.314062318 C0.113071952,0.509509191 0.0110275373,0.771407006 0.0167865707,1.04211031 L0.0167865707,11.3933813 C0.0077943878,11.9550253 0.454330229,12.4183663 1.01592326,12.4301199 L6.24796163,12.4301199 C6.15347803,12.0905554 6.08700419,11.7438135 6.04920863,11.3933813 L1.51549161,11.3933813 C1.23359784,11.3736011 1.01523013,11.1387971 1.01592326,10.856211 L1.01592326,1.55779376 C1.01523013,1.27520772 1.23359784,1.04040373 1.51549161,1.0206235 L12.4791367,1.0206235 C12.7610305,1.04040373 12.9793982,1.27520772 12.978705,1.55779376 L12.978705,6.1129976 C13.3416127,6.27160518 13.6798936,6.48144788 13.9832134,6.73611511 L13.9832134,1.04211031 C13.9889659,0.770492956 13.8861881,0.507791018 13.6976439,0.312188988 C13.5090997,0.116586957 13.2503504,0.00422874936 12.978705,0 Z" id="路径"></path> | ||
| 13 | <path d="M9.48709832,3.63127098 L11.9795683,3.63127098 C12.1204387,3.63685572 12.2567289,3.58067135 12.3527387,3.47743498 C12.4487485,3.37419862 12.4949119,3.23419632 12.4791367,3.09410072 C12.4968375,2.95359324 12.4513335,2.81246879 12.3548898,2.70876591 C12.2584461,2.60506303 12.120989,2.54945504 11.9795683,2.55693046 L9.48709832,2.55693046 C9.34659209,2.55109685 9.21064377,2.60742026 9.11543115,2.71091224 C9.02021852,2.81440422 8.97539973,2.9545668 8.99290168,3.09410072 C8.97728866,3.23323418 9.02275873,3.37230344 9.1175512,3.47533874 C9.21234368,3.57837404 9.3471483,3.63525552 9.48709832,3.63127098 L9.48709832,3.63127098 Z M9.48709832,5.6993765 L10.9858034,5.6993765 C11.1266737,5.70496124 11.2629639,5.64877687 11.3589737,5.5455405 C11.4549835,5.44230413 11.5011469,5.30230183 11.4853717,5.16220624 C11.5011469,5.02211064 11.4549835,4.88210834 11.3589737,4.77887197 C11.2629639,4.6756356 11.1266737,4.61945123 10.9858034,4.62503597 L9.48709832,4.62503597 C9.3471483,4.62105144 9.21234368,4.67793291 9.1175512,4.78096821 C9.02275873,4.88400351 8.97728866,5.02307277 8.99290168,5.16220624 C8.97539973,5.30174015 9.02021852,5.44190273 9.11543115,5.54539471 C9.21064377,5.64888669 9.34659209,5.70521011 9.48709832,5.6993765 L9.48709832,5.6993765 Z" id="形状"></path> | ||
| 14 | </g> | ||
| 15 | <rect id="账号管理-灰" x="0" y="0" width="14" height="14"></rect> | ||
| 16 | </g> | ||
| 17 | </g> | ||
| 18 | </g> | ||
| 19 | </svg> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
src/icons/svg/home-active.svg
0 → 100644
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <svg width="14px" height="14px" viewBox="0 0 14 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | ||
| 3 | <!-- Generator: Sketch 55.1 (78136) - https://sketchapp.com --> | ||
| 4 | <title>首页-白</title> | ||
| 5 | <desc>Created with Sketch.</desc> | ||
| 6 | <g id="奇瑞后台" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> | ||
| 7 | <g id="图标" transform="translate(-23.000000, -263.000000)"> | ||
| 8 | <g id="编组" transform="translate(23.000000, 263.000000)"> | ||
| 9 | <path d="M13.8237634,5.9772172 L7.90871505,1.30222645 C7.39952808,0.899009055 6.60060637,0.899506723 6.09185284,1.30222645 L0.177318171,5.9772172 C-0.0247159515,6.1373194 -0.0592632085,6.43084278 0.100325266,6.6328769 C0.259913757,6.83497523 0.54696755,6.86952251 0.749081932,6.70995006 L0.933376855,6.55869338 L0.933376855,12.2114426 C0.933376855,13.0127402 1.77769805,13.6115061 2.52014332,13.6115061 L11.8542158,13.6115061 C12.5879118,13.6115061 13.0676887,13.0487002 13.0676887,12.2114426 L13.0676887,6.58062254 L13.238017,6.70995006 C13.3239196,6.77759978 13.4293755,6.81028485 13.5306414,6.81028485 C13.6683007,6.81028485 13.8064577,6.74961843 13.8983804,6.6328769 C14.0584826,6.43084278 14.0262952,6.1373194 13.8237634,5.9772172 L13.8237634,5.9772172 Z M6.53379144,12.6781036 L6.53379144,10.0907185 C6.53379144,9.96193677 6.76716211,9.89754593 7.00053278,9.89754593 C7.23390345,9.89754593 7.46725807,9.96193677 7.46725807,10.0907185 L7.46725807,12.6781036 L6.53379144,12.6781036 L6.53379144,12.6781036 Z M12.1342863,12.2114265 C12.1342863,12.5208429 12.0488331,12.6781036 11.8542158,12.6781036 L8.40997157,12.6781036 C8.40997157,12.6711043 8.40064444,12.6655176 8.40064444,12.6585344 L8.40064444,10.0907185 C8.40064444,9.54794743 7.96289584,8.96361372 7.00053278,8.96361372 C6.03821788,8.96361372 5.60040506,9.54794743 5.60040506,10.0907185 L5.60040506,12.6585504 C5.60040506,12.6655337 5.61302317,12.6711203 5.61302317,12.6781036 L2.52014335,12.6781036 C2.22755107,12.6781036 1.86676326,12.4251637 1.86676326,12.2114426 L1.86676326,5.82083943 L6.66405007,2.03452587 C6.8362406,1.89821505 7.14706974,1.89821505 7.31977399,2.03452587 L12.1342863,5.84276861 L12.1342863,12.2114265 L12.1342863,12.2114265 Z" id="形状" fill="#FFFFFF" fill-rule="nonzero"></path> | ||
| 10 | <rect id="首页-白" x="0" y="0" width="14" height="14"></rect> | ||
| 11 | </g> | ||
| 12 | </g> | ||
| 13 | </g> | ||
| 14 | </svg> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
src/icons/svg/home.svg
0 → 100644
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <svg width="14px" height="14px" viewBox="0 0 14 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | ||
| 3 | <!-- Generator: Sketch 55.1 (78136) - https://sketchapp.com --> | ||
| 4 | <title>首页-灰</title> | ||
| 5 | <desc>Created with Sketch.</desc> | ||
| 6 | <g id="奇瑞后台" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> | ||
| 7 | <g id="图标" transform="translate(-57.000000, -263.000000)"> | ||
| 8 | <g id="编组" transform="translate(57.000000, 263.000000)"> | ||
| 9 | <path d="M13.8237634,5.9772172 L7.90871505,1.30222645 C7.39952808,0.899009055 6.60060637,0.899506723 6.09185284,1.30222645 L0.177318171,5.9772172 C-0.0247159515,6.1373194 -0.0592632085,6.43084278 0.100325266,6.6328769 C0.259913757,6.83497523 0.54696755,6.86952251 0.749081932,6.70995006 L0.933376855,6.55869338 L0.933376855,12.2114426 C0.933376855,13.0127402 1.77769805,13.6115061 2.52014332,13.6115061 L11.8542158,13.6115061 C12.5879118,13.6115061 13.0676887,13.0487002 13.0676887,12.2114426 L13.0676887,6.58062254 L13.238017,6.70995006 C13.3239196,6.77759978 13.4293755,6.81028485 13.5306414,6.81028485 C13.6683007,6.81028485 13.8064577,6.74961843 13.8983804,6.6328769 C14.0584826,6.43084278 14.0262952,6.1373194 13.8237634,5.9772172 L13.8237634,5.9772172 Z M6.53379144,12.6781036 L6.53379144,10.0907185 C6.53379144,9.96193677 6.76716211,9.89754593 7.00053278,9.89754593 C7.23390345,9.89754593 7.46725807,9.96193677 7.46725807,10.0907185 L7.46725807,12.6781036 L6.53379144,12.6781036 L6.53379144,12.6781036 Z M12.1342863,12.2114265 C12.1342863,12.5208429 12.0488331,12.6781036 11.8542158,12.6781036 L8.40997157,12.6781036 C8.40997157,12.6711043 8.40064444,12.6655176 8.40064444,12.6585344 L8.40064444,10.0907185 C8.40064444,9.54794743 7.96289584,8.96361372 7.00053278,8.96361372 C6.03821788,8.96361372 5.60040506,9.54794743 5.60040506,10.0907185 L5.60040506,12.6585504 C5.60040506,12.6655337 5.61302317,12.6711203 5.61302317,12.6781036 L2.52014335,12.6781036 C2.22755107,12.6781036 1.86676326,12.4251637 1.86676326,12.2114426 L1.86676326,5.82083943 L6.66405007,2.03452587 C6.8362406,1.89821505 7.14706974,1.89821505 7.31977399,2.03452587 L12.1342863,5.84276861 L12.1342863,12.2114265 L12.1342863,12.2114265 Z" id="形状" fill="#A6ADB4" fill-rule="nonzero"></path> | ||
| 10 | <rect id="首页-灰" x="0" y="0" width="14" height="14"></rect> | ||
| 11 | </g> | ||
| 12 | </g> | ||
| 13 | </g> | ||
| 14 | </svg> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
src/icons/svg/permission-active.svg
0 → 100644
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <svg width="14px" height="14px" viewBox="0 0 14 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | ||
| 3 | <!-- Generator: Sketch 55.1 (78136) - https://sketchapp.com --> | ||
| 4 | <title>角色权限-白</title> | ||
| 5 | <desc>Created with Sketch.</desc> | ||
| 6 | <g id="奇瑞后台" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> | ||
| 7 | <g id="图标" transform="translate(-23.000000, -87.000000)" fill="#FFFFFF" fill-rule="nonzero"> | ||
| 8 | <g id="角色权限-白" transform="translate(23.000000, 87.000000)"> | ||
| 9 | <path d="M11.6451085,6.69136043 C10.6179505,6.69136043 9.78247041,7.52752414 9.78247043,8.55563911 C9.78247043,9.02540014 9.95828902,9.45387252 10.2458057,9.78213104 L9.2224759,10.8062812 L8.6996685,10.2863449 C8.5089477,10.0974014 8.20188039,10.0983584 8.01252677,10.2885323 C7.82344659,10.4791164 7.82467704,10.787004 8.01471424,10.9763577 L8.53533417,11.4941065 L8.02633523,12.0035156 L6.91058441,10.8868078 C6.72082064,10.6969073 6.41347988,10.6969073 6.22371612,10.8868078 C6.03395235,11.0767082 6.03395235,11.3843224 6.22371612,11.5742229 L7.33946694,12.6909308 L6.86068255,13.1701253 C6.67091879,13.3600258 6.67091879,13.66764 6.86068255,13.8575405 C6.95556444,13.9525591 7.07984056,14 7.20411669,14 C7.32839282,14 7.45266895,13.9525591 7.54755084,13.8575405 L11.0729461,10.3290007 C11.2534131,10.387379 11.4453643,10.4197811 11.6449718,10.4197811 C12.6721297,10.4197811 13.5076098,9.58361734 13.5076098,8.55550239 C13.5076098,7.52738744 12.6722664,6.69136043 11.6451085,6.69136043 L11.6451085,6.69136043 Z M11.6451085,9.4474468 C11.1536094,9.4474468 10.7539844,9.04741165 10.7539844,8.55550239 C10.7539844,8.06359313 11.1537461,7.66355797 11.6451085,7.66355797 C12.1366076,7.66355797 12.5362326,8.06359313 12.5362326,8.55550239 C12.5362326,9.04741165 12.1364709,9.4474468 11.6451085,9.4474468 Z" id="形状"></path> | ||
| 10 | <path d="M5.08841471,13.0200096 L0.992497666,13.0200096 C1.23722184,10.1929669 3.59395664,7.96789094 6.45558885,7.96789094 C6.51752184,7.96789094 6.57631033,7.95517622 6.63086058,7.93398502 C8.7374025,7.84060703 10.4238118,6.09062412 10.4238118,3.94703177 C10.4238118,1.77049052 8.64361436,0 6.45558885,0 C4.26770006,0 2.48763931,1.77049052 2.48763931,3.94689505 C2.48763931,5.38393181 3.24737798,6.64241561 4.38117552,7.346647 C1.8374113,8.22081816 6.5953125e-05,10.648646 6.5953125e-05,13.50604 C6.5953125e-05,13.7744163 0.217583365,13.9922071 0.485822928,13.9922071 L5.08841471,13.9922071 C5.35665427,13.9922071 5.57417168,13.7744163 5.57417168,13.50604 C5.57417168,13.2376637 5.35665427,13.0200096 5.08841471,13.0200096 Z M3.45915326,3.94689505 C3.45915326,2.30669623 4.80322217,0.972334248 6.45558885,0.972334248 C8.10795553,0.972334248 9.45229787,2.30669622 9.45229787,3.94689505 C9.45229787,5.61430064 8.10795553,6.9705374 6.45558885,6.9705374 C4.80322217,6.9705374 3.45915326,5.61430064 3.45915326,3.94689505 Z" id="形状"></path> | ||
| 11 | </g> | ||
| 12 | </g> | ||
| 13 | </g> | ||
| 14 | </svg> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
src/icons/svg/permission.svg
0 → 100644
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <svg width="14px" height="14px" viewBox="0 0 14 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | ||
| 3 | <!-- Generator: Sketch 55.1 (78136) - https://sketchapp.com --> | ||
| 4 | <title>角色权限-灰</title> | ||
| 5 | <desc>Created with Sketch.</desc> | ||
| 6 | <g id="奇瑞后台" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> | ||
| 7 | <g id="图标" transform="translate(-57.000000, -87.000000)" fill="#A6ADB4" fill-rule="nonzero"> | ||
| 8 | <g id="角色权限-灰" transform="translate(57.000000, 87.000000)"> | ||
| 9 | <path d="M11.6451085,6.69136043 C10.6179505,6.69136043 9.78247041,7.52752414 9.78247043,8.55563911 C9.78247043,9.02540014 9.95828902,9.45387252 10.2458057,9.78213104 L9.2224759,10.8062812 L8.6996685,10.2863449 C8.5089477,10.0974014 8.20188039,10.0983584 8.01252677,10.2885323 C7.82344659,10.4791164 7.82467704,10.787004 8.01471424,10.9763577 L8.53533417,11.4941065 L8.02633523,12.0035156 L6.91058441,10.8868078 C6.72082064,10.6969073 6.41347988,10.6969073 6.22371612,10.8868078 C6.03395235,11.0767082 6.03395235,11.3843224 6.22371612,11.5742229 L7.33946694,12.6909308 L6.86068255,13.1701253 C6.67091879,13.3600258 6.67091879,13.66764 6.86068255,13.8575405 C6.95556444,13.9525591 7.07984056,14 7.20411669,14 C7.32839282,14 7.45266895,13.9525591 7.54755084,13.8575405 L11.0729461,10.3290007 C11.2534131,10.387379 11.4453643,10.4197811 11.6449718,10.4197811 C12.6721297,10.4197811 13.5076098,9.58361734 13.5076098,8.55550239 C13.5076098,7.52738744 12.6722664,6.69136043 11.6451085,6.69136043 L11.6451085,6.69136043 Z M11.6451085,9.4474468 C11.1536094,9.4474468 10.7539844,9.04741165 10.7539844,8.55550239 C10.7539844,8.06359313 11.1537461,7.66355797 11.6451085,7.66355797 C12.1366076,7.66355797 12.5362326,8.06359313 12.5362326,8.55550239 C12.5362326,9.04741165 12.1364709,9.4474468 11.6451085,9.4474468 Z" id="形状"></path> | ||
| 10 | <path d="M5.08841471,13.0200096 L0.992497666,13.0200096 C1.23722184,10.1929669 3.59395664,7.96789094 6.45558885,7.96789094 C6.51752184,7.96789094 6.57631033,7.95517622 6.63086058,7.93398502 C8.7374025,7.84060703 10.4238118,6.09062412 10.4238118,3.94703177 C10.4238118,1.77049052 8.64361436,0 6.45558885,0 C4.26770006,0 2.48763931,1.77049052 2.48763931,3.94689505 C2.48763931,5.38393181 3.24737798,6.64241561 4.38117552,7.346647 C1.8374113,8.22081816 6.5953125e-05,10.648646 6.5953125e-05,13.50604 C6.5953125e-05,13.7744163 0.217583365,13.9922071 0.485822928,13.9922071 L5.08841471,13.9922071 C5.35665427,13.9922071 5.57417168,13.7744163 5.57417168,13.50604 C5.57417168,13.2376637 5.35665427,13.0200096 5.08841471,13.0200096 Z M3.45915326,3.94689505 C3.45915326,2.30669623 4.80322217,0.972334248 6.45558885,0.972334248 C8.10795553,0.972334248 9.45229787,2.30669622 9.45229787,3.94689505 C9.45229787,5.61430064 8.10795553,6.9705374 6.45558885,6.9705374 C4.80322217,6.9705374 3.45915326,5.61430064 3.45915326,3.94689505 Z" id="形状"></path> | ||
| 11 | </g> | ||
| 12 | </g> | ||
| 13 | </g> | ||
| 14 | </svg> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
src/icons/svg/pm-active.svg
0 → 100644
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <svg width="14px" height="14px" viewBox="0 0 14 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | ||
| 3 | <!-- Generator: Sketch 55.1 (78136) - https://sketchapp.com --> | ||
| 4 | <title>合作商管理-白</title> | ||
| 5 | <desc>Created with Sketch.</desc> | ||
| 6 | <g id="奇瑞后台" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> | ||
| 7 | <g id="图标" transform="translate(-23.000000, -175.000000)"> | ||
| 8 | <g id="编组-5" transform="translate(23.000000, 175.000000)"> | ||
| 9 | <g id="二级-管理员首页" fill="#FFFFFF" fill-rule="nonzero"> | ||
| 10 | <path d="M8.75273438,7 C9.80273438,6.3 10.5902344,5.1625 10.5902344,3.7625 C10.5027344,1.6625 8.84023437,0 6.74023438,0 C4.64023437,0 2.97773437,1.6625 2.97773437,3.7625 C2.97773437,5.1625 3.67773438,6.3 4.81523438,7 C2.01523438,7.875 0.002734375,10.5 0.002734375,13.5625 C0.002734375,13.825 0.177734375,14 0.440234375,14 C0.702734375,14 0.877734375,13.825 0.877734375,13.5625 C0.877734375,10.4125 3.32773438,7.875 6.30273438,7.6125 C6.04023438,8.225 5.42773438,9.8875 5.42773438,11.2 C5.42773438,13.0375 6.56523438,13.5625 6.65273437,13.5625 L7.00273438,13.5625 C7.09023437,13.5625 8.22773438,13.0375 8.22773438,11.2 C8.22773438,9.8875 7.61523438,8.225 7.35273438,7.6125 C10.4152344,7.875 12.7777344,10.4125 12.7777344,13.5625 C12.7777344,13.825 12.9527344,14 13.2152344,14 C13.4777344,14 13.6527344,13.825 13.6527344,13.5625 C13.5652344,10.5 11.5527344,7.875 8.75273438,7 Z M3.85273438,3.7625 C3.85273438,2.1875 5.16523438,0.875 6.74023438,0.875 C8.31523438,0.875 9.62773438,2.1875 9.62773438,3.7625 C9.62773438,5.3375 8.31523438,6.7375 6.74023438,6.7375 C5.16523438,6.7375 3.85273438,5.425 3.85273438,3.7625 Z M6.74023438,12.6875 C6.56523438,12.5125 6.21523438,12.075 6.21523438,11.2875 C6.21523438,10.5 6.47773438,9.5375 6.74023438,8.8375 C7.00273438,9.5375 7.26523438,10.5 7.26523438,11.2875 C7.26523438,12.075 6.91523437,12.5125 6.74023438,12.6875 L6.74023438,12.6875 Z" id="形状"></path> | ||
| 11 | </g> | ||
| 12 | <rect id="合作商管理-灰" x="0" y="0" width="14" height="14"></rect> | ||
| 13 | </g> | ||
| 14 | </g> | ||
| 15 | </g> | ||
| 16 | </svg> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
src/icons/svg/pm.svg
0 → 100644
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <svg width="14px" height="14px" viewBox="0 0 14 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | ||
| 3 | <!-- Generator: Sketch 55.1 (78136) - https://sketchapp.com --> | ||
| 4 | <title>合作商管理-灰</title> | ||
| 5 | <desc>Created with Sketch.</desc> | ||
| 6 | <g id="奇瑞后台" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> | ||
| 7 | <g id="图标" transform="translate(-57.000000, -175.000000)"> | ||
| 8 | <g id="编组-5" transform="translate(57.000000, 175.000000)"> | ||
| 9 | <g id="二级-管理员首页" fill="#A6ADB4" fill-rule="nonzero"> | ||
| 10 | <path d="M8.75273438,7 C9.80273438,6.3 10.5902344,5.1625 10.5902344,3.7625 C10.5027344,1.6625 8.84023437,0 6.74023438,0 C4.64023437,0 2.97773437,1.6625 2.97773437,3.7625 C2.97773437,5.1625 3.67773438,6.3 4.81523438,7 C2.01523438,7.875 0.002734375,10.5 0.002734375,13.5625 C0.002734375,13.825 0.177734375,14 0.440234375,14 C0.702734375,14 0.877734375,13.825 0.877734375,13.5625 C0.877734375,10.4125 3.32773438,7.875 6.30273438,7.6125 C6.04023438,8.225 5.42773438,9.8875 5.42773438,11.2 C5.42773438,13.0375 6.56523438,13.5625 6.65273437,13.5625 L7.00273438,13.5625 C7.09023437,13.5625 8.22773438,13.0375 8.22773438,11.2 C8.22773438,9.8875 7.61523438,8.225 7.35273438,7.6125 C10.4152344,7.875 12.7777344,10.4125 12.7777344,13.5625 C12.7777344,13.825 12.9527344,14 13.2152344,14 C13.4777344,14 13.6527344,13.825 13.6527344,13.5625 C13.5652344,10.5 11.5527344,7.875 8.75273438,7 Z M3.85273438,3.7625 C3.85273438,2.1875 5.16523438,0.875 6.74023438,0.875 C8.31523438,0.875 9.62773438,2.1875 9.62773438,3.7625 C9.62773438,5.3375 8.31523438,6.7375 6.74023438,6.7375 C5.16523438,6.7375 3.85273438,5.425 3.85273438,3.7625 Z M6.74023438,12.6875 C6.56523438,12.5125 6.21523438,12.075 6.21523438,11.2875 C6.21523438,10.5 6.47773438,9.5375 6.74023438,8.8375 C7.00273438,9.5375 7.26523438,10.5 7.26523438,11.2875 C7.26523438,12.075 6.91523437,12.5125 6.74023438,12.6875 L6.74023438,12.6875 Z" id="形状"></path> | ||
| 11 | </g> | ||
| 12 | <rect id="合作商管理-灰" x="0" y="0" width="14" height="14"></rect> | ||
| 13 | </g> | ||
| 14 | </g> | ||
| 15 | </g> | ||
| 16 | </svg> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
src/icons/svg/report-active.svg
0 → 100644
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <svg width="14px" height="14px" viewBox="0 0 14 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | ||
| 3 | <!-- Generator: Sketch 55.1 (78136) - https://sketchapp.com --> | ||
| 4 | <title>报表管理-白</title> | ||
| 5 | <desc>Created with Sketch.</desc> | ||
| 6 | <g id="奇瑞后台" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> | ||
| 7 | <g id="图标" transform="translate(-23.000000, -219.000000)"> | ||
| 8 | <g id="编组-6" transform="translate(23.000000, 219.000000)"> | ||
| 9 | <g id="Group-5-Copy" transform="translate(0.000000, 1.000000)" fill="#FFFFFF" fill-rule="nonzero"> | ||
| 10 | <g id="列表" transform="translate(0.000000, 1.000000)"> | ||
| 11 | <path d="M13.015625,0 L0.984375,0 C0.440234375,0 0,0.461197917 0,1.03125 L0,4.23958333 L0,5.15625 L0,7.10416667 L0,8.02083333 L0,9.96875 C0,10.5388021 0.440234375,11 0.984375,11 L4.375,11 L5.25,11 L8.75,11 L9.625,11 L13.015625,11 C13.5597656,11 14,10.5388021 14,9.96875 L14,8.02083333 L14,7.10416667 L14,5.15625 L14,4.23958333 L14,1.03125 C14,0.461197917 13.5597656,0 13.015625,0 Z M5.25,4.23958333 L5.25,2.29166667 L8.75,2.29166667 L8.75,4.23958333 L5.25,4.23958333 Z M8.75,5.15625 L8.75,7.10416667 L5.25,7.10416667 L5.25,5.15625 L8.75,5.15625 Z M0.984375,2.29166667 L4.375,2.29166667 L4.375,4.23958333 L0.984375,4.23958333 L0.984375,2.29166667 Z M0.984375,5.15625 L4.375,5.15625 L4.375,7.10416667 L0.984375,7.10416667 L0.984375,5.15625 Z M0.984375,9.96875 L0.984375,8.02083333 L4.375,8.02083333 L4.375,9.96875 L0.984375,9.96875 Z M5.25,9.96875 L5.25,8.02083333 L8.75,8.02083333 L8.75,9.96875 L5.25,9.96875 Z M13.015625,9.96875 L9.625,9.96875 L9.625,8.02083333 L13.015625,8.02083333 L13.015625,9.96875 Z M13.015625,7.10416667 L9.625,7.10416667 L9.625,5.15625 L13.015625,5.15625 L13.015625,7.10416667 Z M9.625,4.23958333 L9.625,2.29166667 L13.015625,2.29166667 L13.015625,4.23958333 L9.625,4.23958333 Z" id="Shape"></path> | ||
| 12 | </g> | ||
| 13 | </g> | ||
| 14 | <rect id="报表管理-灰" x="0" y="0" width="14" height="14"></rect> | ||
| 15 | </g> | ||
| 16 | </g> | ||
| 17 | </g> | ||
| 18 | </svg> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
src/icons/svg/report.svg
0 → 100644
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <svg width="14px" height="14px" viewBox="0 0 14 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | ||
| 3 | <!-- Generator: Sketch 55.1 (78136) - https://sketchapp.com --> | ||
| 4 | <title>报表管理-灰</title> | ||
| 5 | <desc>Created with Sketch.</desc> | ||
| 6 | <g id="奇瑞后台" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> | ||
| 7 | <g id="图标" transform="translate(-57.000000, -219.000000)"> | ||
| 8 | <g id="编组-6" transform="translate(57.000000, 219.000000)"> | ||
| 9 | <g id="Group-5-Copy" opacity="0.65" transform="translate(0.000000, 1.000000)" fill="#FFFFFF" fill-rule="nonzero"> | ||
| 10 | <g id="列表" transform="translate(0.000000, 1.000000)"> | ||
| 11 | <path d="M13.015625,0 L0.984375,0 C0.440234375,0 0,0.461197917 0,1.03125 L0,4.23958333 L0,5.15625 L0,7.10416667 L0,8.02083333 L0,9.96875 C0,10.5388021 0.440234375,11 0.984375,11 L4.375,11 L5.25,11 L8.75,11 L9.625,11 L13.015625,11 C13.5597656,11 14,10.5388021 14,9.96875 L14,8.02083333 L14,7.10416667 L14,5.15625 L14,4.23958333 L14,1.03125 C14,0.461197917 13.5597656,0 13.015625,0 Z M5.25,4.23958333 L5.25,2.29166667 L8.75,2.29166667 L8.75,4.23958333 L5.25,4.23958333 Z M8.75,5.15625 L8.75,7.10416667 L5.25,7.10416667 L5.25,5.15625 L8.75,5.15625 Z M0.984375,2.29166667 L4.375,2.29166667 L4.375,4.23958333 L0.984375,4.23958333 L0.984375,2.29166667 Z M0.984375,5.15625 L4.375,5.15625 L4.375,7.10416667 L0.984375,7.10416667 L0.984375,5.15625 Z M0.984375,9.96875 L0.984375,8.02083333 L4.375,8.02083333 L4.375,9.96875 L0.984375,9.96875 Z M5.25,9.96875 L5.25,8.02083333 L8.75,8.02083333 L8.75,9.96875 L5.25,9.96875 Z M13.015625,9.96875 L9.625,9.96875 L9.625,8.02083333 L13.015625,8.02083333 L13.015625,9.96875 Z M13.015625,7.10416667 L9.625,7.10416667 L9.625,5.15625 L13.015625,5.15625 L13.015625,7.10416667 Z M9.625,4.23958333 L9.625,2.29166667 L13.015625,2.29166667 L13.015625,4.23958333 L9.625,4.23958333 Z" id="Shape"></path> | ||
| 12 | </g> | ||
| 13 | </g> | ||
| 14 | <rect id="报表管理-灰" x="0" y="0" width="14" height="14"></rect> | ||
| 15 | </g> | ||
| 16 | </g> | ||
| 17 | </g> | ||
| 18 | </svg> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
src/icons/svg/seven.svg
0 → 100644
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <svg width="48px" height="20px" viewBox="0 0 48 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | ||
| 3 | <!-- Generator: Sketch 55.1 (78136) - https://sketchapp.com --> | ||
| 4 | <title>近7天</title> | ||
| 5 | <desc>Created with Sketch.</desc> | ||
| 6 | <g id="奇瑞后台" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> | ||
| 7 | <g id="标准列表" transform="translate(-1324.000000, -172.000000)" fill="#1890FF"> | ||
| 8 | <g id="编组-7" transform="translate(280.000000, 142.000000)"> | ||
| 9 | <g id="近7天" transform="translate(1044.000000, 30.000000)"> | ||
| 10 | <rect id="矩形" stroke="#1890FF" stroke-width="0.5" fill-opacity="0.04" x="0.25" y="0.25" width="47.5" height="19.5" rx="2"></rect> | ||
| 11 | <text font-family="PingFangSC-Regular, PingFang SC" font-size="13" font-weight="normal" line-spacing="14" letter-spacing="1"> | ||
| 12 | <tspan x="5.0085" y="16.624">近7天</tspan> | ||
| 13 | </text> | ||
| 14 | </g> | ||
| 15 | </g> | ||
| 16 | </g> | ||
| 17 | </g> | ||
| 18 | </svg> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
src/icons/svg/togglemenu.svg
0 → 100644
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <svg width="18px" height="16px" viewBox="0 0 18 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | ||
| 3 | <!-- Generator: Sketch 55.1 (78136) - https://sketchapp.com --> | ||
| 4 | <title>Group</title> | ||
| 5 | <desc>Created with Sketch.</desc> | ||
| 6 | <g id="奇瑞后台" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> | ||
| 7 | <g id="标准列表" transform="translate(-281.000000, -24.000000)"> | ||
| 8 | <g id="Group" transform="translate(290.000000, 32.000000) scale(-1, 1) translate(-290.000000, -32.000000) translate(280.000000, 22.000000)"> | ||
| 9 | <rect id="Rectangle-9" x="0" y="0" width="20" height="20"></rect> | ||
| 10 | <rect id="Combined-Shape" fill-opacity="0.65" fill="#000000" x="1.25" y="2.5" width="17.5" height="1.875" rx="0.9375"></rect> | ||
| 11 | <rect id="Rectangle-Copy" fill-opacity="0.65" fill="#000000" x="1.25" y="9.0625" width="11.25" height="1.875" rx="0.9375"></rect> | ||
| 12 | <path d="M13.0947111,7.8250177 L17.3692475,7.53744049 C17.5414472,7.52585544 17.6904342,7.65605936 17.7020193,7.82825908 C17.7029688,7.8423724 17.7029589,7.85653391 17.7019898,7.87064589 L17.4088387,12.1393768 C17.4029264,12.2254685 17.3283424,12.2904668 17.2422507,12.2845545 C17.2045995,12.2819688 17.1691565,12.2658432 17.1424704,12.2391571 L12.994714,8.09140072 C12.9336946,8.0303813 12.9336946,7.93144927 12.994714,7.87042985 C13.021453,7.84369083 13.0569817,7.82755601 13.0947111,7.8250177 Z" id="Rectangle-6" fill-opacity="0.65" fill="#000000"></path> | ||
| 13 | <rect id="Rectangle-Copy-2" fill-opacity="0.65" fill="#000000" x="1.25" y="15.625" width="17.5" height="1.875" rx="0.9375"></rect> | ||
| 14 | </g> | ||
| 15 | </g> | ||
| 16 | </g> | ||
| 17 | </svg> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
src/icons/svg/user.svg
0 → 100644
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <svg width="28px" height="28px" viewBox="0 0 28 28" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | ||
| 3 | <!-- Generator: Sketch 55.1 (78136) - https://sketchapp.com --> | ||
| 4 | <title>用户</title> | ||
| 5 | <desc>Created with Sketch.</desc> | ||
| 6 | <defs> | ||
| 7 | <rect id="path-1" x="0" y="0" width="20.5333333" height="20.5333333" rx="10.2666667"></rect> | ||
| 8 | <filter x="-73.1%" y="-73.1%" width="246.1%" height="246.1%" filterUnits="objectBoundingBox" id="filter-3"> | ||
| 9 | <feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset> | ||
| 10 | <feGaussianBlur stdDeviation="5" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur> | ||
| 11 | <feColorMatrix values="0 0 0 0 0.839215686 0 0 0 0 0.839215686 0 0 0 0 0.839215686 0 0 0 0.56173514 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix> | ||
| 12 | </filter> | ||
| 13 | <path d="M9.12592593,0 C14.1660356,-9.25853135e-16 18.2518519,4.08581621 18.2518519,9.12592593 C18.2518519,14.1660356 14.1660356,18.2518519 9.12592593,18.2518519 C4.08581621,18.2518519 6.17235423e-16,14.1660356 0,9.12592593 C-6.17235423e-16,4.08581621 4.08581621,9.25853135e-16 9.12592593,0 Z" id="path-4"></path> | ||
| 14 | <linearGradient x1="37.9394531%" y1="0%" x2="50%" y2="137.329102%" id="linearGradient-6"> | ||
| 15 | <stop stop-color="#E4E8F0" offset="0%"></stop> | ||
| 16 | <stop stop-color="#D4DDE6" offset="100%"></stop> | ||
| 17 | </linearGradient> | ||
| 18 | <linearGradient x1="36.9648438%" y1="30.46875%" x2="56.9830204%" y2="68.7200429%" id="linearGradient-7"> | ||
| 19 | <stop stop-color="#DFE5EC" offset="0%"></stop> | ||
| 20 | <stop stop-color="#D6DDED" offset="100%"></stop> | ||
| 21 | </linearGradient> | ||
| 22 | </defs> | ||
| 23 | <g id="奇瑞后台" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> | ||
| 24 | <g id="标准列表" transform="translate(-1305.000000, -18.000000)"> | ||
| 25 | <g id="编组-5" transform="translate(1305.000000, 18.000000)"> | ||
| 26 | <g id="编组-3" transform="translate(3.733333, 3.733333)"> | ||
| 27 | <mask id="mask-2" fill="white"> | ||
| 28 | <use xlink:href="#path-1"></use> | ||
| 29 | </mask> | ||
| 30 | <g id="Mask"> | ||
| 31 | <use fill="black" fill-opacity="1" filter="url(#filter-3)" xlink:href="#path-1"></use> | ||
| 32 | <use fill="#FFFFFF" fill-rule="evenodd" xlink:href="#path-1"></use> | ||
| 33 | </g> | ||
| 34 | <g id="Group" mask="url(#mask-2)"> | ||
| 35 | <g transform="translate(1.140741, 1.140741)"> | ||
| 36 | <mask id="mask-5" fill="white"> | ||
| 37 | <use xlink:href="#path-4"></use> | ||
| 38 | </mask> | ||
| 39 | <use id="Rectangle-16" stroke="none" fill="#F2F4F9" fill-rule="evenodd" xlink:href="#path-4"></use> | ||
| 40 | <g id="通用" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" mask="url(#mask-5)"> | ||
| 41 | <g transform="translate(2.281481, 3.137037)" id="编组-2"> | ||
| 42 | <g transform="translate(0.095062, 0.095062)"> | ||
| 43 | <path d="M6.70185182,0 C8.07732435,0 9.34831338,0.73380583 10.0360497,1.92499998 C10.7237859,3.11619414 10.7237859,4.58380586 10.0360497,5.77500002 C9.34831338,6.96619417 8.07732435,7.7 6.70185182,7.7 C4.57555555,7.7 2.85185185,5.97629629 2.85185185,3.85 C2.85185185,1.72370371 4.57555555,0 6.70185182,0 Z" id="路径" fill="url(#linearGradient-6)" fill-rule="nonzero"></path> | ||
| 44 | <path d="M0.000589300402,15.2355823 C-0.0387694808,11.3476639 1.89836705,8.9336627 4.32663273,7.98518519 L6.81992595,12.0661566 L9.44669678,8.07919358 C11.7893999,9.08642633 13.6512414,11.4718892 13.6888889,15.2389398 C9.38166923,16.9143036 4.84171938,17.0351715 0.000589300402,15.2355823 L0.000589300402,15.2355823 Z" id="路径" fill="url(#linearGradient-7)" fill-rule="nonzero"></path> | ||
| 45 | </g> | ||
| 46 | </g> | ||
| 47 | </g> | ||
| 48 | </g> | ||
| 49 | </g> | ||
| 50 | </g> | ||
| 51 | <rect id="客户" x="0" y="0" width="28" height="28"></rect> | ||
| 52 | </g> | ||
| 53 | </g> | ||
| 54 | </g> | ||
| 55 | </svg> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
src/icons/svg/work-active.svg
0 → 100644
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <svg width="14px" height="14px" viewBox="0 0 14 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | ||
| 3 | <!-- Generator: Sketch 55.1 (78136) - https://sketchapp.com --> | ||
| 4 | <title>任务管理-白</title> | ||
| 5 | <desc>Created with Sketch.</desc> | ||
| 6 | <g id="奇瑞后台" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> | ||
| 7 | <g id="图标" transform="translate(-23.000000, -42.000000)"> | ||
| 8 | <g id="编组-3" transform="translate(23.000000, 42.000000)"> | ||
| 9 | <g id="任务" transform="translate(1.000000, 0.000000)" fill="#FFFFFF" fill-rule="nonzero"> | ||
| 10 | <path d="M8.17930744,8.04981368 C8.13130606,7.87535135 8.06135226,7.71009841 7.97349567,7.55611875 C8.07323534,7.4212771 8.41800092,6.91859168 8.16951953,6.67036046 L8.04226116,6.53597224 C7.83011697,6.32364042 7.28793596,6.65510009 7.15623707,6.74098659 C7.00053749,6.65253584 6.8329392,6.58248823 6.65624098,6.53481521 C6.6280343,6.36627878 6.50426268,5.77745669 6.15507221,5.77745669 L6.01525843,5.77745669 C5.71525765,5.77745669 5.54321884,6.38632365 5.50498973,6.53902119 C5.33038668,6.58761672 5.165337,6.65788323 5.01196713,6.74600562 C4.89077539,6.65591314 4.37142239,6.29695041 4.11804705,6.55032575 L3.98331485,6.66349642 C3.76257106,6.88449038 4.12947669,7.46710512 4.19683497,7.56908068 C4.11177716,7.72062118 4.04371527,7.88273137 3.99660513,8.05416039 C3.85025566,8.07723857 3.22503383,8.19797689 3.22503383,8.55789339 L3.22503383,8.69761336 C3.22503383,9.00938777 3.88097967,9.18258361 4.00076421,9.21149389 C4.04810889,9.38128116 4.11638967,9.54248448 4.20149439,9.69271159 C4.13108716,9.8031773 3.77815978,10.3832591 3.99705856,10.6023768 L4.1245671,10.7083081 C4.41266917,10.9961757 5.01454701,10.5231354 5.01454701,10.5231354 L4.98655924,10.4933026 C5.14792218,10.5889706 5.32111447,10.6631036 5.50172189,10.7138119 C5.5317892,10.8366454 5.70473487,11.4879005 6.01525843,11.4879005 L6.15507221,11.4879005 C6.56253666,11.4879005 6.66346464,10.7273367 6.66346464,10.7273367 L6.62617366,10.7266174 C6.81079915,10.6796324 6.98609017,10.6083183 7.14809091,10.5174128 C7.27559945,10.6019077 7.80869616,10.9358221 8.02126251,10.7229118 L8.16298384,10.5812843 C8.4471301,10.2972475 7.98489404,9.71600867 7.97207283,9.6998258 C8.05996069,9.54609631 8.13010212,9.38117171 8.17857256,9.20681883 C8.33758689,9.1663851 8.93544637,8.99492481 8.93544637,8.69761336 L8.93544637,8.55789339 C8.93544637,8.16323452 8.2238377,8.05645882 8.17930744,8.04981368 Z M6.0811626,9.78898015 C5.4427443,9.78898015 4.92547084,9.27186304 4.92547084,8.63349165 C4.92547084,7.99512026 5.4427443,7.4778937 6.08117824,7.4778937 C6.71917438,7.4778937 7.23641656,7.99515153 7.23641656,8.63350729 C7.23641656,9.27186304 6.71919001,9.78898015 6.08117824,9.78898015 L6.0811626,9.78898015 Z M10.6902641,1.99694963 L10.6902641,1.24392218 C10.6902641,0.502449457 10.2222116,0.0595703125 9.43852268,0.0595703125 C8.65533411,0.0595703125 8.18725033,0.502465093 8.18725033,1.24392218 L8.18725033,1.99693399 L7.33923645,1.99693399 L7.33923645,1.24392218 C7.33923645,0.502449457 6.87163738,0.0595703125 6.08794846,0.0595703125 C5.30429082,0.0595703125 4.83667612,0.502465093 4.83667612,1.24392218 L4.83667612,1.99693399 L3.98819316,1.99693399 L3.98819316,1.24392218 C3.98819316,0.502449457 3.52060973,0.0595703125 2.73692081,0.0595703125 C1.95373224,0.0595703125 1.4856641,0.502465093 1.4856641,1.24392218 L1.4856641,1.99693399 L0.048828125,1.99693399 L0.048828125,14.0595703 L12.1117146,14.0595703 L12.1117146,1.99694963 L10.6902485,1.99694963 L10.6902641,1.99694963 Z M8.85762786,1.24392218 C8.85762786,0.878079768 9.02546068,0.7297133 9.43852268,0.7297133 C9.85249155,0.7297133 10.0198709,0.878064133 10.0198709,1.24392218 L10.0198709,3.25826005 C10.0198709,3.62397737 9.85249155,3.77248456 9.43853832,3.77248456 C9.02547632,3.77248456 8.85762786,3.62400864 8.85762786,3.25826005 L8.85762786,1.24392218 L8.85762786,1.24392218 Z M5.50706927,1.24392218 C5.50706927,0.878079768 5.67443303,0.7297133 6.08793283,0.7297133 C6.50147954,0.7297133 6.66931236,0.878064133 6.66931236,1.24392218 L6.66931236,3.25826005 C6.66931236,3.62397737 6.50147954,3.77248456 6.08794846,3.77248456 C5.67443303,3.77248456 5.50706927,3.62400864 5.50706927,3.25826005 L5.50706927,1.24392218 L5.50706927,1.24392218 Z M2.15557255,1.24392218 C2.15557255,0.878079768 2.32340538,0.7297133 2.73690518,0.7297133 C3.15045188,0.7297133 3.31873814,0.878064133 3.31873814,1.24392218 L3.31873814,3.25826005 C3.31873814,3.62397737 3.15043625,3.77248456 2.73690518,3.77248456 C2.32340538,3.77248456 2.15557255,3.62400864 2.15557255,3.25826005 L2.15557255,1.24392218 Z M11.106594,13.054606 L1.05394879,13.054606 L1.05394879,4.67758412 L11.106594,4.67758412 L11.106594,13.054606 L11.106594,13.054606 Z" id="形状"></path> | ||
| 11 | </g> | ||
| 12 | <rect id="矩形" x="0" y="0" width="14" height="14"></rect> | ||
| 13 | </g> | ||
| 14 | </g> | ||
| 15 | </g> | ||
| 16 | </svg> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
src/icons/svg/work.svg
0 → 100644
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <svg width="14px" height="14px" viewBox="0 0 14 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | ||
| 3 | <!-- Generator: Sketch 55.1 (78136) - https://sketchapp.com --> | ||
| 4 | <title>任务管理-灰</title> | ||
| 5 | <desc>Created with Sketch.</desc> | ||
| 6 | <g id="奇瑞后台" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> | ||
| 7 | <g id="图标" transform="translate(-57.000000, -42.000000)"> | ||
| 8 | <g id="编组-3" transform="translate(57.000000, 42.000000)"> | ||
| 9 | <g id="任务" transform="translate(1.000000, 0.000000)" fill="#A6ADB4" fill-rule="nonzero"> | ||
| 10 | <path d="M8.17930744,8.04981368 C8.13130606,7.87535135 8.06135226,7.71009841 7.97349567,7.55611875 C8.07323534,7.4212771 8.41800092,6.91859168 8.16951953,6.67036046 L8.04226116,6.53597224 C7.83011697,6.32364042 7.28793596,6.65510009 7.15623707,6.74098659 C7.00053749,6.65253584 6.8329392,6.58248823 6.65624098,6.53481521 C6.6280343,6.36627878 6.50426268,5.77745669 6.15507221,5.77745669 L6.01525843,5.77745669 C5.71525765,5.77745669 5.54321884,6.38632365 5.50498973,6.53902119 C5.33038668,6.58761672 5.165337,6.65788323 5.01196713,6.74600562 C4.89077539,6.65591314 4.37142239,6.29695041 4.11804705,6.55032575 L3.98331485,6.66349642 C3.76257106,6.88449038 4.12947669,7.46710512 4.19683497,7.56908068 C4.11177716,7.72062118 4.04371527,7.88273137 3.99660513,8.05416039 C3.85025566,8.07723857 3.22503383,8.19797689 3.22503383,8.55789339 L3.22503383,8.69761336 C3.22503383,9.00938777 3.88097967,9.18258361 4.00076421,9.21149389 C4.04810889,9.38128116 4.11638967,9.54248448 4.20149439,9.69271159 C4.13108716,9.8031773 3.77815978,10.3832591 3.99705856,10.6023768 L4.1245671,10.7083081 C4.41266917,10.9961757 5.01454701,10.5231354 5.01454701,10.5231354 L4.98655924,10.4933026 C5.14792218,10.5889706 5.32111447,10.6631036 5.50172189,10.7138119 C5.5317892,10.8366454 5.70473487,11.4879005 6.01525843,11.4879005 L6.15507221,11.4879005 C6.56253666,11.4879005 6.66346464,10.7273367 6.66346464,10.7273367 L6.62617366,10.7266174 C6.81079915,10.6796324 6.98609017,10.6083183 7.14809091,10.5174128 C7.27559945,10.6019077 7.80869616,10.9358221 8.02126251,10.7229118 L8.16298384,10.5812843 C8.4471301,10.2972475 7.98489404,9.71600867 7.97207283,9.6998258 C8.05996069,9.54609631 8.13010212,9.38117171 8.17857256,9.20681883 C8.33758689,9.1663851 8.93544637,8.99492481 8.93544637,8.69761336 L8.93544637,8.55789339 C8.93544637,8.16323452 8.2238377,8.05645882 8.17930744,8.04981368 Z M6.0811626,9.78898015 C5.4427443,9.78898015 4.92547084,9.27186304 4.92547084,8.63349165 C4.92547084,7.99512026 5.4427443,7.4778937 6.08117824,7.4778937 C6.71917438,7.4778937 7.23641656,7.99515153 7.23641656,8.63350729 C7.23641656,9.27186304 6.71919001,9.78898015 6.08117824,9.78898015 L6.0811626,9.78898015 Z M10.6902641,1.99694963 L10.6902641,1.24392218 C10.6902641,0.502449457 10.2222116,0.0595703125 9.43852268,0.0595703125 C8.65533411,0.0595703125 8.18725033,0.502465093 8.18725033,1.24392218 L8.18725033,1.99693399 L7.33923645,1.99693399 L7.33923645,1.24392218 C7.33923645,0.502449457 6.87163738,0.0595703125 6.08794846,0.0595703125 C5.30429082,0.0595703125 4.83667612,0.502465093 4.83667612,1.24392218 L4.83667612,1.99693399 L3.98819316,1.99693399 L3.98819316,1.24392218 C3.98819316,0.502449457 3.52060973,0.0595703125 2.73692081,0.0595703125 C1.95373224,0.0595703125 1.4856641,0.502465093 1.4856641,1.24392218 L1.4856641,1.99693399 L0.048828125,1.99693399 L0.048828125,14.0595703 L12.1117146,14.0595703 L12.1117146,1.99694963 L10.6902485,1.99694963 L10.6902641,1.99694963 Z M8.85762786,1.24392218 C8.85762786,0.878079768 9.02546068,0.7297133 9.43852268,0.7297133 C9.85249155,0.7297133 10.0198709,0.878064133 10.0198709,1.24392218 L10.0198709,3.25826005 C10.0198709,3.62397737 9.85249155,3.77248456 9.43853832,3.77248456 C9.02547632,3.77248456 8.85762786,3.62400864 8.85762786,3.25826005 L8.85762786,1.24392218 L8.85762786,1.24392218 Z M5.50706927,1.24392218 C5.50706927,0.878079768 5.67443303,0.7297133 6.08793283,0.7297133 C6.50147954,0.7297133 6.66931236,0.878064133 6.66931236,1.24392218 L6.66931236,3.25826005 C6.66931236,3.62397737 6.50147954,3.77248456 6.08794846,3.77248456 C5.67443303,3.77248456 5.50706927,3.62400864 5.50706927,3.25826005 L5.50706927,1.24392218 L5.50706927,1.24392218 Z M2.15557255,1.24392218 C2.15557255,0.878079768 2.32340538,0.7297133 2.73690518,0.7297133 C3.15045188,0.7297133 3.31873814,0.878064133 3.31873814,1.24392218 L3.31873814,3.25826005 C3.31873814,3.62397737 3.15043625,3.77248456 2.73690518,3.77248456 C2.32340538,3.77248456 2.15557255,3.62400864 2.15557255,3.25826005 L2.15557255,1.24392218 Z M11.106594,13.054606 L1.05394879,13.054606 L1.05394879,4.67758412 L11.106594,4.67758412 L11.106594,13.054606 L11.106594,13.054606 Z" id="形状"></path> | ||
| 11 | </g> | ||
| 12 | <rect id="矩形" x="0" y="0" width="14" height="14"></rect> | ||
| 13 | </g> | ||
| 14 | </g> | ||
| 15 | </g> | ||
| 16 | </svg> | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
src/layout/components/AppMain.vue
0 → 100644
| 1 | <template> | ||
| 2 | <section class="app-main"> | ||
| 3 | <transition name="fade-transform" mode="out-in"> | ||
| 4 | <router-view :key="key" /> | ||
| 5 | </transition> | ||
| 6 | <ResetPassDialog></ResetPassDialog> | ||
| 7 | </section> | ||
| 8 | </template> | ||
| 9 | |||
| 10 | <script> | ||
| 11 | import ResetPassDialog from '@/views/components/ResetPassDialog' | ||
| 12 | |||
| 13 | export default { | ||
| 14 | name: 'AppMain', | ||
| 15 | components: { | ||
| 16 | ResetPassDialog | ||
| 17 | }, | ||
| 18 | data() { | ||
| 19 | return { | ||
| 20 | visible: true | ||
| 21 | } | ||
| 22 | }, | ||
| 23 | computed: { | ||
| 24 | key() { | ||
| 25 | return this.$route.fullPath | ||
| 26 | } | ||
| 27 | } | ||
| 28 | } | ||
| 29 | </script> | ||
| 30 | |||
| 31 | <style scoped> | ||
| 32 | .app-main { | ||
| 33 | /* height: calc(100% - 35px); */ | ||
| 34 | padding: 24px 24px 0 24px; | ||
| 35 | background-color: #f0f2f5; | ||
| 36 | } | ||
| 37 | /* 定义过渡时间 */ | ||
| 38 | .fade-transform-enter-active, | ||
| 39 | .fade-transform-live-active { | ||
| 40 | transition: all 0.5s; | ||
| 41 | } | ||
| 42 | |||
| 43 | .fade-transform-enter, | ||
| 44 | .fade-transform-live-to { | ||
| 45 | opacity: 0; | ||
| 46 | } | ||
| 47 | </style> |
src/layout/components/Header.vue
0 → 100644
| 1 | <template lang="pug"> | ||
| 2 | div(class="header") | ||
| 3 | .logo | ||
| 4 | span(@click="expanMenu") | ||
| 5 | <svg-icon className="toggle-icon" icon-class='togglemenu' /> | ||
| 6 | .right-menu | ||
| 7 | el-dropdown(trigger="click" @command="handleCommand") | ||
| 8 | span(class="el-dropdown-link") | ||
| 9 | <svg-icon className="icon" icon-class='user' /> | ||
| 10 | span(class="userInfo-name userInfo-discription") {{name}} | ||
| 11 | i(class="el-icon-arrow-down el-icon-caret-bottom") | ||
| 12 | el-dropdown-menu(slot="dropdown") | ||
| 13 | el-dropdown-item(command="pass") | ||
| 14 | span(class="userInfo-operation userInfo-discription") 修改密码 | ||
| 15 | el-dropdown-item(command="logout") | ||
| 16 | span(class="userInfo-operation userInfo-discription") 退出 | ||
| 17 | </template> | ||
| 18 | |||
| 19 | <script> | ||
| 20 | import { mapState, mapActions, mapMutations } from 'vuex' | ||
| 21 | |||
| 22 | export default { | ||
| 23 | name: 'CommHeader', | ||
| 24 | computed: { | ||
| 25 | ...mapState('app', ['sidebar']), | ||
| 26 | ...mapState(['name', 'userId']), | ||
| 27 | isCollapse() { | ||
| 28 | return this.sidebar.opened | ||
| 29 | } | ||
| 30 | }, | ||
| 31 | data() { | ||
| 32 | return { | ||
| 33 | visible: true, | ||
| 34 | resetObj: null | ||
| 35 | } | ||
| 36 | }, | ||
| 37 | mounted() {}, | ||
| 38 | methods: { | ||
| 39 | ...mapMutations(['TOGGLE_UPDATEPASS_DIALOG']), | ||
| 40 | ...mapActions(['logout']), | ||
| 41 | ...mapActions('app', ['toggleSideBar']), | ||
| 42 | handleLogout() { | ||
| 43 | try { | ||
| 44 | this.logout() | ||
| 45 | this.$router.push('/login') | ||
| 46 | } catch (error) { | ||
| 47 | console.log(error) | ||
| 48 | } | ||
| 49 | }, | ||
| 50 | handleUpdatepass() { | ||
| 51 | this.TOGGLE_UPDATEPASS_DIALOG({ | ||
| 52 | name: this.name, | ||
| 53 | username: this.userId | ||
| 54 | }) | ||
| 55 | }, | ||
| 56 | expanMenu() { | ||
| 57 | this.toggleSideBar() | ||
| 58 | }, | ||
| 59 | handleCommand(data) { | ||
| 60 | if (data === 'pass') { | ||
| 61 | this.handleUpdatepass() | ||
| 62 | } else if (data === 'logout') { | ||
| 63 | this.handleLogout() | ||
| 64 | } | ||
| 65 | } | ||
| 66 | } | ||
| 67 | } | ||
| 68 | </script> | ||
| 69 | |||
| 70 | <style lang="scss" scoped> | ||
| 71 | .header { | ||
| 72 | display: flex; | ||
| 73 | justify-content: space-between; | ||
| 74 | align-items: center; | ||
| 75 | height: 64px; | ||
| 76 | box-shadow: 0px 1px 4px 0px rgba(0, 21, 41, 0.12); | ||
| 77 | padding: 0 20px 0 24px; | ||
| 78 | } | ||
| 79 | .logo { | ||
| 80 | display: flex; | ||
| 81 | justify-content: flex-start; | ||
| 82 | align-items: center; | ||
| 83 | .toggle-icon { | ||
| 84 | width: 20px; | ||
| 85 | height: 20px; | ||
| 86 | } | ||
| 87 | span { | ||
| 88 | font-size: 14px; | ||
| 89 | cursor: pointer; | ||
| 90 | .rotate { | ||
| 91 | transform: rotate(90deg); | ||
| 92 | } | ||
| 93 | } | ||
| 94 | } | ||
| 95 | .right-menu { | ||
| 96 | .el-dropdown-link { | ||
| 97 | display: flex; | ||
| 98 | flex-flow: row nowrap; | ||
| 99 | justify-content: center; | ||
| 100 | align-items: center; | ||
| 101 | height: 100%; | ||
| 102 | .icon { | ||
| 103 | height: 28px; | ||
| 104 | width: 28px; | ||
| 105 | margin-right: 6px; | ||
| 106 | } | ||
| 107 | } | ||
| 108 | .user-icon { | ||
| 109 | font-size: 20px; | ||
| 110 | margin-right: 10px; | ||
| 111 | } | ||
| 112 | .userInfo-name { | ||
| 113 | margin-right: 10px; | ||
| 114 | color: #666666; | ||
| 115 | } | ||
| 116 | } | ||
| 117 | </style> |
src/layout/components/Sidebar/Item.vue
0 → 100644
| 1 | <template> | ||
| 2 | <span> | ||
| 3 | <svg-icon v-if="icon" className="icon" :icon-class="ComIcon" /> | ||
| 4 | <span v-if="title" slot="title">{{ title }}</span> | ||
| 5 | </span> | ||
| 6 | </template> | ||
| 7 | |||
| 8 | <script> | ||
| 9 | import { mapState } from 'vuex' | ||
| 10 | |||
| 11 | export default { | ||
| 12 | name: 'MenuItem', | ||
| 13 | props: { | ||
| 14 | icon: { | ||
| 15 | type: String, | ||
| 16 | default: '' | ||
| 17 | }, | ||
| 18 | title: { | ||
| 19 | type: String, | ||
| 20 | default: '' | ||
| 21 | }, | ||
| 22 | item: { | ||
| 23 | type: Object | ||
| 24 | } | ||
| 25 | }, | ||
| 26 | computed: { | ||
| 27 | ...mapState('permission', ['routes']), | ||
| 28 | ComIcon() { | ||
| 29 | const { path } = this.$route | ||
| 30 | if (path.indexOf(this.item.path) > -1) { | ||
| 31 | return `${this.icon}-active` | ||
| 32 | } else { | ||
| 33 | return this.icon | ||
| 34 | } | ||
| 35 | } | ||
| 36 | } | ||
| 37 | } | ||
| 38 | </script> | ||
| 39 | <style lang="scss" scoped> | ||
| 40 | .icon { | ||
| 41 | width: 14px; | ||
| 42 | height: 14px; | ||
| 43 | } | ||
| 44 | </style> |
src/layout/components/Sidebar/Link.vue
0 → 100644
| 1 | |||
| 2 | <template> | ||
| 3 | <!-- eslint-disable vue/require-component-is --> | ||
| 4 | <component v-bind="linkProps(to)"> | ||
| 5 | <slot/> | ||
| 6 | </component> | ||
| 7 | </template> | ||
| 8 | |||
| 9 | <script> | ||
| 10 | import { isExternal } from '@/utils/validate' | ||
| 11 | |||
| 12 | export default { | ||
| 13 | props: { | ||
| 14 | to: { | ||
| 15 | type: String, | ||
| 16 | required: true | ||
| 17 | } | ||
| 18 | }, | ||
| 19 | methods: { | ||
| 20 | linkProps(url) { | ||
| 21 | if (isExternal(url)) { | ||
| 22 | return { | ||
| 23 | is: 'a', | ||
| 24 | href: url, | ||
| 25 | target: '_blank', | ||
| 26 | rel: 'noopener' | ||
| 27 | } | ||
| 28 | } | ||
| 29 | return { | ||
| 30 | is: 'router-link', | ||
| 31 | to: url | ||
| 32 | } | ||
| 33 | } | ||
| 34 | } | ||
| 35 | } | ||
| 36 | </script> |
| 1 | <template> | ||
| 2 | <div v-if="!item.hidden"> | ||
| 3 | <template | ||
| 4 | v-if="hasOneShowingChild(item.children, item) && !item.alwaysShow" | ||
| 5 | > | ||
| 6 | <app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)"> | ||
| 7 | <el-menu-item :index="resolvePath(onlyOneChild.path)"> | ||
| 8 | <item | ||
| 9 | :icon="onlyOneChild.meta.icon || (item.meta && item.meta.icon)" | ||
| 10 | :title="onlyOneChild.meta.title" | ||
| 11 | :item="onlyOneChild" | ||
| 12 | /> | ||
| 13 | </el-menu-item> | ||
| 14 | </app-link> | ||
| 15 | </template> | ||
| 16 | <el-submenu v-else :index="resolvePath(item.path)" popper-append-to-body> | ||
| 17 | <template slot="title"> | ||
| 18 | <item | ||
| 19 | v-if="item.meta" | ||
| 20 | :icon="item.meta && item.meta.icon" | ||
| 21 | :title="item.meta.title" | ||
| 22 | :item="item" | ||
| 23 | /> | ||
| 24 | </template> | ||
| 25 | <sidebar-item | ||
| 26 | v-for="child in item.children" | ||
| 27 | :key="child.path" | ||
| 28 | :is-nest="true" | ||
| 29 | :item="child" | ||
| 30 | :base-path="resolvePath(child.path)" | ||
| 31 | /> | ||
| 32 | </el-submenu> | ||
| 33 | </div> | ||
| 34 | </template> | ||
| 35 | <script> | ||
| 36 | import path from 'path' | ||
| 37 | import Item from './Item' | ||
| 38 | import { isExternal } from '@/utils/validate' | ||
| 39 | import AppLink from './Link' | ||
| 40 | |||
| 41 | export default { | ||
| 42 | name: 'SidebarItem', | ||
| 43 | components: { | ||
| 44 | Item, | ||
| 45 | AppLink | ||
| 46 | }, | ||
| 47 | props: { | ||
| 48 | item: { | ||
| 49 | type: Object, | ||
| 50 | require: true | ||
| 51 | }, | ||
| 52 | basePath: { | ||
| 53 | type: String, | ||
| 54 | default: '' | ||
| 55 | } | ||
| 56 | }, | ||
| 57 | data() { | ||
| 58 | // To fix https://github.com/PanJiaChen/vue-admin-template/issues/237 | ||
| 59 | this.onlyOneChild = null | ||
| 60 | return {} | ||
| 61 | }, | ||
| 62 | methods: { | ||
| 63 | hasOneShowingChild(children = [], parent) { | ||
| 64 | const showingChildren = children.filter(item => { | ||
| 65 | if (item.hidden) { | ||
| 66 | return false | ||
| 67 | } else { | ||
| 68 | // Temp set(will be used if only has one showing child) | ||
| 69 | this.onlyOneChild = item | ||
| 70 | return true | ||
| 71 | } | ||
| 72 | }) | ||
| 73 | |||
| 74 | // When there is only one child router, the child router is displayed by default | ||
| 75 | if (showingChildren.length === 1) { | ||
| 76 | return true | ||
| 77 | } | ||
| 78 | |||
| 79 | // Show parent if there are no child router to display | ||
| 80 | if (showingChildren.length === 0) { | ||
| 81 | this.onlyOneChild = { ...parent, path: '', noShowingChildren: true } | ||
| 82 | return true | ||
| 83 | } | ||
| 84 | |||
| 85 | return false | ||
| 86 | }, | ||
| 87 | resolvePath(routePath) { | ||
| 88 | if (isExternal(routePath)) { | ||
| 89 | return routePath | ||
| 90 | } | ||
| 91 | if (isExternal(this.basePath)) { | ||
| 92 | return this.basePath | ||
| 93 | } | ||
| 94 | return path.resolve(this.basePath, routePath) | ||
| 95 | } | ||
| 96 | } | ||
| 97 | } | ||
| 98 | </script> | ||
| 99 | <style lang="scss"></style> |
src/layout/components/Sidebar/index.vue
0 → 100644
| 1 | <template> | ||
| 2 | <div class="sidebar-container"> | ||
| 3 | <div class="home-title"> | ||
| 4 | <div class="title title-icon" v-if="!isCollapse"></div> | ||
| 5 | </div> | ||
| 6 | <el-scrollbar> | ||
| 7 | <el-menu | ||
| 8 | mode="vertical" | ||
| 9 | :default-active="activeMenu" | ||
| 10 | :collapse="isCollapse" | ||
| 11 | :unique-opened="false" | ||
| 12 | :collapse-transition="false" | ||
| 13 | > | ||
| 14 | <sidebar-item | ||
| 15 | v-for="route in routes" | ||
| 16 | :key="route.path" | ||
| 17 | :item="route" | ||
| 18 | :base-path="route.path" | ||
| 19 | /> | ||
| 20 | </el-menu> | ||
| 21 | </el-scrollbar> | ||
| 22 | </div> | ||
| 23 | </template> | ||
| 24 | <script> | ||
| 25 | import SidebarItem from './SidebarItem' | ||
| 26 | import { mapState, mapMutations } from 'vuex' | ||
| 27 | |||
| 28 | export default { | ||
| 29 | components: { | ||
| 30 | SidebarItem | ||
| 31 | }, | ||
| 32 | data() { | ||
| 33 | return { | ||
| 34 | menuBg: '#304156', | ||
| 35 | menuText: '#bfcbd9', | ||
| 36 | menuActiveText: '#409EFF' | ||
| 37 | } | ||
| 38 | }, | ||
| 39 | computed: { | ||
| 40 | ...mapState('app', ['sidebar']), | ||
| 41 | ...mapState('permission', ['routes']), | ||
| 42 | activeMenu() { | ||
| 43 | const route = this.$route | ||
| 44 | const { meta, path } = route | ||
| 45 | if (meta.activeMenu) { | ||
| 46 | return meta.activeMenu | ||
| 47 | } | ||
| 48 | return path | ||
| 49 | }, | ||
| 50 | isCollapse() { | ||
| 51 | return this.sidebar.opened | ||
| 52 | } | ||
| 53 | }, | ||
| 54 | methods: { | ||
| 55 | ...mapMutations('app', ['SET_IS_COLLAPSE']) | ||
| 56 | } | ||
| 57 | } | ||
| 58 | </script> | ||
| 59 | <style lang="scss"> | ||
| 60 | .sidebar-container { | ||
| 61 | width: 100%; | ||
| 62 | height: 100%; | ||
| 63 | .home-title { | ||
| 64 | background: #002140; | ||
| 65 | height: 64px; | ||
| 66 | display: flex; | ||
| 67 | justify-content: center; | ||
| 68 | align-items: center; | ||
| 69 | .title { | ||
| 70 | width: 166px; | ||
| 71 | height: 24px; | ||
| 72 | background-size: contain; | ||
| 73 | } | ||
| 74 | } | ||
| 75 | .el-scrollbar { | ||
| 76 | height: calc(100% - 64px); | ||
| 77 | background-color: #001529; | ||
| 78 | .el-scrollbar__wrap { | ||
| 79 | overflow-x: hidden !important; | ||
| 80 | // 导航栏间距 | ||
| 81 | .el-scrollbar__view { | ||
| 82 | > .el-menu { | ||
| 83 | > div { | ||
| 84 | margin: 10px 0; | ||
| 85 | } | ||
| 86 | } | ||
| 87 | } | ||
| 88 | .el-menu { | ||
| 89 | width: 100%; | ||
| 90 | background: #001529; | ||
| 91 | border-right: 0; | ||
| 92 | .el-submenu.is-active { | ||
| 93 | .el-submenu__title { | ||
| 94 | span { | ||
| 95 | color: #fff; | ||
| 96 | } | ||
| 97 | } | ||
| 98 | } | ||
| 99 | .el-submenu, | ||
| 100 | .el-menu-item > span { | ||
| 101 | .icon { | ||
| 102 | margin-right: 14px; | ||
| 103 | } | ||
| 104 | } | ||
| 105 | .el-menu-item, | ||
| 106 | .el-submenu__title { | ||
| 107 | color: #999; | ||
| 108 | background: #001529; | ||
| 109 | text-align: left; | ||
| 110 | } | ||
| 111 | .el-menu-item.is-active { | ||
| 112 | color: #fff; | ||
| 113 | background: #1890ff; | ||
| 114 | } | ||
| 115 | span { | ||
| 116 | font-size: 14px; | ||
| 117 | font-weight: 500; | ||
| 118 | } | ||
| 119 | } | ||
| 120 | .el-menu--collapse { | ||
| 121 | .el-submenu > .el-submenu__title > span { | ||
| 122 | display: inline-flex; | ||
| 123 | flex-flow: row nowrap; | ||
| 124 | justify-content: center; | ||
| 125 | align-items: center; | ||
| 126 | height: 20px; | ||
| 127 | width: 20px; | ||
| 128 | overflow: visible; | ||
| 129 | visibility: visible; | ||
| 130 | .icon { | ||
| 131 | margin: 0; | ||
| 132 | } | ||
| 133 | span { | ||
| 134 | display: none; | ||
| 135 | } | ||
| 136 | } | ||
| 137 | .el-menu-item > span { | ||
| 138 | span { | ||
| 139 | display: none; | ||
| 140 | } | ||
| 141 | } | ||
| 142 | } | ||
| 143 | } | ||
| 144 | } | ||
| 145 | } | ||
| 146 | |||
| 147 | .el-menu--collapse { | ||
| 148 | .el-submenu { | ||
| 149 | & > .el-submenu__title { | ||
| 150 | & > span { | ||
| 151 | height: 0; | ||
| 152 | width: 0; | ||
| 153 | overflow: hidden; | ||
| 154 | visibility: hidden; | ||
| 155 | display: inline-block; | ||
| 156 | } | ||
| 157 | .el-submenu__icon-arrow { | ||
| 158 | display: none; | ||
| 159 | } | ||
| 160 | } | ||
| 161 | } | ||
| 162 | } | ||
| 163 | </style> |
src/layout/components/breadcrumb/index.vue
0 → 100644
| 1 | <template lang="pug"> | ||
| 2 | el-breadcrumb(separator="/" class="app-breadcrumb") | ||
| 3 | transition-group(name="breadcrumb") | ||
| 4 | el-breadcrumb-item(v-for="(item,index) in levelList" :key="item.path") | ||
| 5 | span(v-if="item.redirect==='noRedirect'||index==levelList.length-1" class="no-redirect") {{ item.meta.title }} | ||
| 6 | a(v-else @click.prevent="handleLink(item)") {{ item.meta.title }} | ||
| 7 | </template> | ||
| 8 | |||
| 9 | <script> | ||
| 10 | import pathToRegexp from 'path-to-regexp' | ||
| 11 | |||
| 12 | export default { | ||
| 13 | data() { | ||
| 14 | return { | ||
| 15 | levelList: null | ||
| 16 | } | ||
| 17 | }, | ||
| 18 | watch: { | ||
| 19 | $route() { | ||
| 20 | this.getBreadcrumb() | ||
| 21 | } | ||
| 22 | }, | ||
| 23 | created() { | ||
| 24 | this.getBreadcrumb() | ||
| 25 | }, | ||
| 26 | methods: { | ||
| 27 | getBreadcrumb() { | ||
| 28 | // only show routes with meta.title | ||
| 29 | let matched = this.$route.matched.filter( | ||
| 30 | item => item.meta && item.meta.title | ||
| 31 | ) | ||
| 32 | // const first = matched[0] | ||
| 33 | |||
| 34 | // if (this.isWhoRoute(first, 'dayBillingInquiry')) { | ||
| 35 | // matched = [{ path: '/billing', meta: { title: '账单查询' } }].concat( | ||
| 36 | // matched | ||
| 37 | // ) | ||
| 38 | // } | ||
| 39 | // if (this.isWhoRoute(first, 'billingDetail')) { | ||
| 40 | // matched = [ | ||
| 41 | // { path: '/billing', meta: { title: '账单查询' } }, | ||
| 42 | // { path: '/billing/dayBillingInquiry', meta: { title: '日调用量' } } | ||
| 43 | // ].concat(matched) | ||
| 44 | // } | ||
| 45 | |||
| 46 | this.levelList = matched.filter( | ||
| 47 | item => item.meta && item.meta.title && item.meta.breadcrumb !== false | ||
| 48 | ) | ||
| 49 | }, | ||
| 50 | isWhoRoute(route, str) { | ||
| 51 | const name = route && route.name | ||
| 52 | if (!name) { | ||
| 53 | return false | ||
| 54 | } | ||
| 55 | return name.trim().toLocaleLowerCase() === str.toLocaleLowerCase() | ||
| 56 | }, | ||
| 57 | pathCompile(path) { | ||
| 58 | // To solve this problem https://github.com/PanJiaChen/vue-element-admin/issues/561 | ||
| 59 | const { params } = this.$route | ||
| 60 | const toPath = pathToRegexp.compile(path) | ||
| 61 | return toPath(params) | ||
| 62 | }, | ||
| 63 | handleLink(item) { | ||
| 64 | const { redirect, path } = item | ||
| 65 | if (redirect) { | ||
| 66 | this.$router.push(redirect) | ||
| 67 | return | ||
| 68 | } | ||
| 69 | this.$router.push(this.pathCompile(path)) | ||
| 70 | } | ||
| 71 | } | ||
| 72 | } | ||
| 73 | </script> | ||
| 74 | |||
| 75 | <style lang="scss" scoped> | ||
| 76 | .app-breadcrumb.el-breadcrumb { | ||
| 77 | height: 54px; | ||
| 78 | font-size: 14px; | ||
| 79 | padding-left: 32px; | ||
| 80 | display: flex; | ||
| 81 | align-items: center; | ||
| 82 | .no-redirect { | ||
| 83 | color: #666; | ||
| 84 | cursor: text; | ||
| 85 | } | ||
| 86 | } | ||
| 87 | /* breadcrumb transition */ | ||
| 88 | .breadcrumb-enter-active, | ||
| 89 | .breadcrumb-leave-active { | ||
| 90 | transition: all 0.5s; | ||
| 91 | } | ||
| 92 | |||
| 93 | .breadcrumb-enter, | ||
| 94 | .breadcrumb-leave-active { | ||
| 95 | opacity: 0; | ||
| 96 | transform: translateX(20px); | ||
| 97 | } | ||
| 98 | |||
| 99 | .breadcrumb-move { | ||
| 100 | transition: all 0.5s; | ||
| 101 | } | ||
| 102 | |||
| 103 | .breadcrumb-leave-active { | ||
| 104 | position: absolute; | ||
| 105 | } | ||
| 106 | </style> | ||
| 107 | <style lang="scss" scoped> | ||
| 108 | .app-breadcrumb { | ||
| 109 | .el-breadcrumb__inner.is-link, | ||
| 110 | .el-breadcrumb__inner a { | ||
| 111 | color: rgba(0, 0, 0, 0.45); | ||
| 112 | } | ||
| 113 | .el-breadcrumb__inner .no-redirect { | ||
| 114 | color: rgba(0, 0, 0, 0.65); | ||
| 115 | font-weight: 400; | ||
| 116 | } | ||
| 117 | .el-breadcrumb__inner.is-link:hover, | ||
| 118 | .el-breadcrumb__inner a:hover { | ||
| 119 | cursor: auto; | ||
| 120 | color: rgba(0, 0, 0, 0.45); | ||
| 121 | } | ||
| 122 | } | ||
| 123 | </style> |
src/layout/components/index.js
0 → 100644
src/layout/index.vue
0 → 100644
| 1 | <template lang="pug"> | ||
| 2 | .app | ||
| 3 | el-container | ||
| 4 | el-aside(:width="asideWidth") | ||
| 5 | sidebar | ||
| 6 | el-container | ||
| 7 | el-header(height='118px') | ||
| 8 | Header | ||
| 9 | Breadcrumb | ||
| 10 | el-main | ||
| 11 | AppMain | ||
| 12 | </template> | ||
| 13 | <script> | ||
| 14 | import { Sidebar, AppMain, Header } from './components' | ||
| 15 | import Breadcrumb from './components/breadcrumb' | ||
| 16 | |||
| 17 | import { mapState } from 'vuex' | ||
| 18 | export default { | ||
| 19 | name: 'Layout', | ||
| 20 | components: { | ||
| 21 | Sidebar, | ||
| 22 | Header, | ||
| 23 | AppMain, | ||
| 24 | Breadcrumb | ||
| 25 | }, | ||
| 26 | computed: { | ||
| 27 | ...mapState('app', ['sidebar']), | ||
| 28 | siderbar() { | ||
| 29 | return this.$store.state.app.siderbar | ||
| 30 | }, | ||
| 31 | asideWidth() { | ||
| 32 | return this.sidebar.opened ? '64px' : '256px' | ||
| 33 | } | ||
| 34 | } | ||
| 35 | } | ||
| 36 | </script> | ||
| 37 | <style lang="scss" scope> | ||
| 38 | .app { | ||
| 39 | height: 100%; | ||
| 40 | > .el-container { | ||
| 41 | height: 100%; | ||
| 42 | } | ||
| 43 | .el-header { | ||
| 44 | padding: 0; | ||
| 45 | } | ||
| 46 | .el-main { | ||
| 47 | padding: 0; | ||
| 48 | } | ||
| 49 | .el-aside { | ||
| 50 | transition: width 0.2s ease-in; | ||
| 51 | box-shadow: 2px 0px 6px 0px rgba(0, 21, 41, 0.35); | ||
| 52 | } | ||
| 53 | } | ||
| 54 | </style> |
src/main.js
0 → 100644
| 1 | import Vue from 'vue' | ||
| 2 | import App from './App.vue' | ||
| 3 | import router from './router' | ||
| 4 | import store from './store' | ||
| 5 | import VueParticles from 'vue-particles' | ||
| 6 | import ElementUI from 'element-ui' | ||
| 7 | import './element-variables.scss' | ||
| 8 | import './base.scss' | ||
| 9 | import './permission' | ||
| 10 | import '@/icons' | ||
| 11 | import 'animate.css' | ||
| 12 | import 'video.js/dist/video-js.css' | ||
| 13 | |||
| 14 | import VeLine from 'v-charts/lib/line.common' | ||
| 15 | import VeHistogram from 'v-charts/lib/histogram.common' | ||
| 16 | |||
| 17 | import Card from '_c/card' | ||
| 18 | |||
| 19 | Vue.config.productionTip = false | ||
| 20 | Vue.use(ElementUI) | ||
| 21 | Vue.use(VueParticles) | ||
| 22 | |||
| 23 | Vue.component('Card', Card) | ||
| 24 | Vue.component(VeLine.name, VeLine) | ||
| 25 | Vue.component(VeHistogram.name, VeHistogram) | ||
| 26 | |||
| 27 | new Vue({ | ||
| 28 | router, | ||
| 29 | store, | ||
| 30 | render: h => h(App) | ||
| 31 | }).$mount('#app') |
src/permission.js
0 → 100644
| 1 | import router from './router' | ||
| 2 | import NProgress from 'nprogress' // progress bar | ||
| 3 | import 'nprogress/nprogress.css' // progress bar style | ||
| 4 | import { getToken } from '@/utils/auth' // get token from cookie | ||
| 5 | import store from './store' | ||
| 6 | |||
| 7 | NProgress.configure({ showSpinner: false }) // NProgress Configuration | ||
| 8 | const whiteList = ['/login'] | ||
| 9 | |||
| 10 | router.beforeEach((to, from, next) => { | ||
| 11 | let routerTemp = store.state.resetRouterTemp | ||
| 12 | // start progress bar | ||
| 13 | NProgress.start() | ||
| 14 | // determine whether the user has logged in | ||
| 15 | const hasToken = getToken() | ||
| 16 | if (hasToken) { | ||
| 17 | if (routerTemp) { | ||
| 18 | next() | ||
| 19 | } else { | ||
| 20 | store.commit('SET_ROUTER_TEMP', 'TEMP') | ||
| 21 | let roles = store.state.roles | ||
| 22 | store.commit('permission/SET_ROUTES', { roles }) | ||
| 23 | router.addRoutes(store.state.permission.routes) | ||
| 24 | // hack method to ensure that addRoutes is complete | ||
| 25 | // set the replace: true, so the navigation will not leave a history record | ||
| 26 | next({ ...to, replace: true }) | ||
| 27 | } | ||
| 28 | } else { | ||
| 29 | // other pages that do not have permission to access are redirected to the login page. | ||
| 30 | if (whiteList.indexOf(to.path) !== -1) { | ||
| 31 | next() | ||
| 32 | } else { | ||
| 33 | next(`/login?redirect=${to.path}`) // 重定向到登录页 | ||
| 34 | NProgress.done() | ||
| 35 | } | ||
| 36 | } | ||
| 37 | }) | ||
| 38 | |||
| 39 | router.afterEach(() => { | ||
| 40 | // finish progress bar | ||
| 41 | NProgress.done() | ||
| 42 | }) |
src/router/index.js
0 → 100644
| 1 | import Vue from 'vue' | ||
| 2 | import Router from 'vue-router' | ||
| 3 | |||
| 4 | import Layout from '@/layout' | ||
| 5 | import { PERMISSION_USER_MAP } from '@/utils/mappingData' | ||
| 6 | |||
| 7 | const originalPush = Router.prototype.push | ||
| 8 | Router.prototype.push = function push(location) { | ||
| 9 | return originalPush.call(this, location).catch(err => err) | ||
| 10 | } | ||
| 11 | |||
| 12 | Vue.use(Router) | ||
| 13 | |||
| 14 | /** | ||
| 15 | * Note: sub-menu only appear when route children.length >= 1 | ||
| 16 | * Detail see: https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html | ||
| 17 | * | ||
| 18 | * hidden: true if set true, item will not show in the sidebar(default is false) | ||
| 19 | * alwaysShow: true if set true, will always show the root menu | ||
| 20 | * if not set alwaysShow, when item has more than one children route, | ||
| 21 | * it will becomes nested mode, otherwise not show the root menu | ||
| 22 | * redirect: noRedirect if set noRedirect will no redirect in the breadcrumb | ||
| 23 | * name:'router-name' the name is used by <keep-alive> (must set!!!) | ||
| 24 | * meta : { | ||
| 25 | roles: ['admin','editor'] control the page roles (you can set multiple roles) | ||
| 26 | title: 'title' the name show in sidebar and breadcrumb (recommend set) | ||
| 27 | icon: 'svg-name' the icon show in the sidebar | ||
| 28 | noCache: true if set true, the page will no be cached(default is false) | ||
| 29 | affix: true if set true, the tag will affix in the tags-view | ||
| 30 | breadcrumb: false if set false, the item will hidden in breadcrumb(default is true) | ||
| 31 | activeMenu: '/example/list' if set path, the sidebar will highlight the path you set | ||
| 32 | } | ||
| 33 | */ | ||
| 34 | |||
| 35 | /** | ||
| 36 | * constantRoutes | ||
| 37 | * a base page that does not have permission requirements | ||
| 38 | * all roles can be accessed | ||
| 39 | */ | ||
| 40 | |||
| 41 | export const constantRoutes = [ | ||
| 42 | { | ||
| 43 | path: '/login', | ||
| 44 | component: () => import('@/views/login/index'), | ||
| 45 | hidden: true | ||
| 46 | } | ||
| 47 | ] | ||
| 48 | /** | ||
| 49 | * asyncRoutes | ||
| 50 | * the routes that need to be dynamically loaded based on user roles | ||
| 51 | */ | ||
| 52 | export const asyncRoutes = [ | ||
| 53 | { | ||
| 54 | path: '/', | ||
| 55 | component: Layout, | ||
| 56 | redirect: '/monitor', | ||
| 57 | meta: { | ||
| 58 | roles: [ | ||
| 59 | PERMISSION_USER_MAP.admin.code, | ||
| 60 | PERMISSION_USER_MAP.dataAnalyst.code | ||
| 61 | ] | ||
| 62 | }, | ||
| 63 | children: [ | ||
| 64 | { | ||
| 65 | path: 'monitor', | ||
| 66 | name: 'monitor', | ||
| 67 | component: () => import('@/views/monitor'), | ||
| 68 | meta: { | ||
| 69 | title: '资源监控', | ||
| 70 | icon: 'home' | ||
| 71 | } | ||
| 72 | }, | ||
| 73 | { | ||
| 74 | path: 'monitor-details', | ||
| 75 | name: 'monitor-details', | ||
| 76 | hidden: true, | ||
| 77 | component: () => import('@/views/monitor'), | ||
| 78 | meta: { | ||
| 79 | title: '远程订单详情', | ||
| 80 | icon: 'home' | ||
| 81 | } | ||
| 82 | } | ||
| 83 | ] | ||
| 84 | }, | ||
| 85 | { | ||
| 86 | path: '/404', | ||
| 87 | component: () => import('@/views/404'), | ||
| 88 | hidden: true | ||
| 89 | } | ||
| 90 | // { path: '*', redirect: '/404', hidden: true } | ||
| 91 | ] | ||
| 92 | |||
| 93 | const createRouter = () => | ||
| 94 | new Router({ | ||
| 95 | scrollBehavior: () => ({ y: 0 }), | ||
| 96 | routes: constantRoutes | ||
| 97 | }) | ||
| 98 | |||
| 99 | const router = createRouter() | ||
| 100 | |||
| 101 | export default router |
src/store/index.js
0 → 100644
| 1 | import Vue from 'vue' | ||
| 2 | import Vuex from 'vuex' | ||
| 3 | |||
| 4 | import app from './modules/app' | ||
| 5 | import permission from './modules/permisssion' | ||
| 6 | |||
| 7 | import { login, logout } from '@/api/user' | ||
| 8 | import { getToken, setToken, removeToken } from '@/utils/auth' | ||
| 9 | import { NAME, USER_TYPE, USER_ID, USER_PASS } from '@/utils/mappingData' | ||
| 10 | |||
| 11 | Vue.use(Vuex) | ||
| 12 | |||
| 13 | export default new Vuex.Store({ | ||
| 14 | state: { | ||
| 15 | token: getToken(), | ||
| 16 | name: sessionStorage.getItem(NAME), | ||
| 17 | roles: JSON.parse(sessionStorage.getItem(USER_TYPE)) || '', | ||
| 18 | userId: sessionStorage.getItem(USER_ID), | ||
| 19 | resetRouterTemp: '', | ||
| 20 | userpass: JSON.parse(sessionStorage.getItem(USER_PASS)) || '' | ||
| 21 | }, | ||
| 22 | mutations: { | ||
| 23 | SET_TOKEN: (state, token) => { | ||
| 24 | state.token = token | ||
| 25 | setToken(token) | ||
| 26 | }, | ||
| 27 | SET_NAME: (state, name) => { | ||
| 28 | sessionStorage.setItem(NAME, name) | ||
| 29 | state.name = name | ||
| 30 | }, | ||
| 31 | SET_USER_ID: (state, userId) => { | ||
| 32 | sessionStorage.setItem(USER_ID, userId) | ||
| 33 | state.userId = userId | ||
| 34 | }, | ||
| 35 | SET_ROLES: (state, userType) => { | ||
| 36 | state.roles = userType | ||
| 37 | sessionStorage.setItem(USER_TYPE, JSON.stringify(userType)) | ||
| 38 | }, | ||
| 39 | SET_ROUTER_TEMP(state, payload) { | ||
| 40 | state.resetRouterTemp = payload | ||
| 41 | }, | ||
| 42 | SET_USERPASS(state, payload) { | ||
| 43 | state.userpass = payload | ||
| 44 | sessionStorage.setItem(USER_PASS, payload) | ||
| 45 | } | ||
| 46 | }, | ||
| 47 | actions: { | ||
| 48 | async login({ dispatch, commit }, userinfo) { | ||
| 49 | try { | ||
| 50 | const { username, password } = userinfo | ||
| 51 | const res = await login({ | ||
| 52 | username: username.trim(), | ||
| 53 | password: password | ||
| 54 | }) | ||
| 55 | if (res.code === 0) { | ||
| 56 | commit('SET_ROLES', res.result.roleCode) | ||
| 57 | commit('SET_NAME', res.result.name) | ||
| 58 | commit('SET_USER_ID', res.result.username) | ||
| 59 | commit('SET_TOKEN', res.result.token) | ||
| 60 | } | ||
| 61 | return res | ||
| 62 | } catch (error) { | ||
| 63 | console.log(error) | ||
| 64 | } | ||
| 65 | }, | ||
| 66 | // remove token | ||
| 67 | resetToken({ commit }) { | ||
| 68 | return new Promise(resolve => { | ||
| 69 | removeToken() | ||
| 70 | sessionStorage.clear() | ||
| 71 | resolve() | ||
| 72 | }) | ||
| 73 | }, | ||
| 74 | async logout({ dispatch, commit }) { | ||
| 75 | try { | ||
| 76 | const res = await logout() | ||
| 77 | dispatch('resetToken') | ||
| 78 | return res | ||
| 79 | } catch (error) { | ||
| 80 | console.log(error) | ||
| 81 | } | ||
| 82 | } | ||
| 83 | }, | ||
| 84 | modules: { | ||
| 85 | app, | ||
| 86 | permission | ||
| 87 | } | ||
| 88 | }) |
src/store/modules/app.js
0 → 100644
| 1 | // import Cookies from 'js-cookie' | ||
| 2 | |||
| 3 | const state = { | ||
| 4 | sidebar: { | ||
| 5 | // string => num => boolean | ||
| 6 | opened: !!+sessionStorage.getItem('sidebarStatus'), | ||
| 7 | withoutAnimation: false | ||
| 8 | } | ||
| 9 | } | ||
| 10 | |||
| 11 | const mutations = { | ||
| 12 | TOGGLE_SIDEBAR: state => { | ||
| 13 | state.sidebar.opened = !state.sidebar.opened | ||
| 14 | state.sidebar.withoutAnimation = false | ||
| 15 | if (state.sidebar.opened) { | ||
| 16 | sessionStorage.setItem('sidebarStatus', 1) | ||
| 17 | } else { | ||
| 18 | sessionStorage.setItem('sidebarStatus', 0) | ||
| 19 | } | ||
| 20 | }, | ||
| 21 | CLOSE_SIDEBAR: (state, withoutAnimation) => { | ||
| 22 | sessionStorage.setItem('sidebarStatus', 0) | ||
| 23 | state.sidebar.opened = false | ||
| 24 | state.sidebar.withoutAnimation = withoutAnimation | ||
| 25 | } | ||
| 26 | } | ||
| 27 | |||
| 28 | const actions = { | ||
| 29 | toggleSideBar({ commit }) { | ||
| 30 | commit('TOGGLE_SIDEBAR') | ||
| 31 | }, | ||
| 32 | closeSideBar({ commit }, { withoutAnimation }) { | ||
| 33 | commit('CLOSE_SIDEBAR', withoutAnimation) | ||
| 34 | } | ||
| 35 | } | ||
| 36 | |||
| 37 | export default { | ||
| 38 | namespaced: true, | ||
| 39 | state, | ||
| 40 | mutations, | ||
| 41 | actions | ||
| 42 | } |
src/store/modules/permisssion.js
0 → 100644
| 1 | import { constantRoutes, asyncRoutes } from '@/router' | ||
| 2 | |||
| 3 | function hasPermission(roles, route) { | ||
| 4 | if (route.meta && route.meta.roles) { | ||
| 5 | return route.meta.roles.includes(roles) | ||
| 6 | } else { | ||
| 7 | return true | ||
| 8 | } | ||
| 9 | } | ||
| 10 | |||
| 11 | function filterAsyncRoutes(routes, roles) { | ||
| 12 | const res = [] | ||
| 13 | routes.forEach(route => { | ||
| 14 | const temp = { ...route } | ||
| 15 | if (hasPermission(roles, temp)) { | ||
| 16 | if (temp.children) { | ||
| 17 | temp.children = filterAsyncRoutes(temp.children, roles) | ||
| 18 | } | ||
| 19 | res.push(temp) | ||
| 20 | } | ||
| 21 | }) | ||
| 22 | return res | ||
| 23 | } | ||
| 24 | |||
| 25 | const state = { | ||
| 26 | routes: [], | ||
| 27 | addRoutes: [] | ||
| 28 | } | ||
| 29 | |||
| 30 | const mutations = { | ||
| 31 | SET_ROUTES: (state, payload) => { | ||
| 32 | state.addRoutes = filterAsyncRoutes(asyncRoutes, payload.roles) | ||
| 33 | state.routes = constantRoutes.concat(state.addRoutes) | ||
| 34 | } | ||
| 35 | } | ||
| 36 | |||
| 37 | export default { | ||
| 38 | namespaced: true, | ||
| 39 | state, | ||
| 40 | mutations | ||
| 41 | } |
src/utils/auth.js
0 → 100644
| 1 | import Cookies from 'js-cookie' | ||
| 2 | import { USER_ID } from '@/utils/mappingData' | ||
| 3 | |||
| 4 | export function getToken() { | ||
| 5 | if (sessionStorage.getItem(USER_ID) === null) { | ||
| 6 | return '' | ||
| 7 | } else { | ||
| 8 | return Cookies.get(sessionStorage.getItem(USER_ID)) | ||
| 9 | } | ||
| 10 | } | ||
| 11 | |||
| 12 | export function setToken(token) { | ||
| 13 | let expires = new Date(new Date().getTime() + 60 * 60 * 24 * 1000) | ||
| 14 | return Cookies.set(sessionStorage.getItem(USER_ID), token, { | ||
| 15 | expires: expires | ||
| 16 | }) | ||
| 17 | } | ||
| 18 | |||
| 19 | export function removeToken() { | ||
| 20 | return Cookies.remove(sessionStorage.getItem(USER_ID)) | ||
| 21 | } |
src/utils/mappingData.js
0 → 100644
| 1 | // session key | ||
| 2 | export const NAME = 'name' | ||
| 3 | export const USER_ID = 'userId' | ||
| 4 | export const USER_TYPE = 'userType' | ||
| 5 | export const USER_PASS = 'userpass' | ||
| 6 | |||
| 7 | // 权限字段 | ||
| 8 | export const PERMISSION_USER_MAP = { | ||
| 9 | admin: { | ||
| 10 | code: 'admin', | ||
| 11 | name: '管理员' | ||
| 12 | }, | ||
| 13 | auditor: { | ||
| 14 | code: 'auditor', | ||
| 15 | name: '初级审核员' | ||
| 16 | }, | ||
| 17 | dataAnalyst: { | ||
| 18 | code: 'dataAnalyst', | ||
| 19 | name: '数据分析员' | ||
| 20 | } | ||
| 21 | } | ||
| 22 | |||
| 23 | // contactCard const | ||
| 24 | export const CONTACT_CARD = { | ||
| 25 | ANSWER_END: 'answerEnd', // 接听挂断 | ||
| 26 | ANSWER: 'answer', // 接听 | ||
| 27 | CALL: 'call', // 呼叫 | ||
| 28 | CALL_END: 'callEnd' // 呼叫挂断 | ||
| 29 | } |
src/utils/permission.js
0 → 100644
| 1 | import store from '@/store' | ||
| 2 | |||
| 3 | export default function checkPermission(value) { | ||
| 4 | if (value && value instanceof Array && value.length > 0) { | ||
| 5 | const roles = store.state.roles | ||
| 6 | const permissionRoles = value | ||
| 7 | const hasPermission = roles.some(role => { | ||
| 8 | return permissionRoles.includes(role) | ||
| 9 | }) | ||
| 10 | if (hasPermission) { | ||
| 11 | return true | ||
| 12 | } else { | ||
| 13 | return false | ||
| 14 | } | ||
| 15 | } else { | ||
| 16 | console.error(`need roles! Like v-permission="['admin','editor']"`) | ||
| 17 | return false | ||
| 18 | } | ||
| 19 | } |
src/utils/request.js
0 → 100644
| 1 | import axios from 'axios' | ||
| 2 | // MessageBox | ||
| 3 | import { Message } from 'element-ui' | ||
| 4 | import store from '@/store' | ||
| 5 | import { getToken, removeToken } from '@/utils/auth' | ||
| 6 | import router from '@/router' | ||
| 7 | |||
| 8 | // create an axios instance | ||
| 9 | const service = axios.create({ | ||
| 10 | // baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url | ||
| 11 | withCredentials: false // send cookies when cross-domain requests | ||
| 12 | // timeout: 10000 // request timeout | ||
| 13 | }) | ||
| 14 | |||
| 15 | // request interceptor | ||
| 16 | service.interceptors.request.use( | ||
| 17 | config => { | ||
| 18 | // do something before request is sent | ||
| 19 | if (store.state.token) { | ||
| 20 | // let each request carry token --['X-Token'] as a custom key. | ||
| 21 | // please modify it according to the actual situation. | ||
| 22 | config.headers['X-Source'] = 'web' | ||
| 23 | config.headers['x-auth-token'] = getToken() | ||
| 24 | } | ||
| 25 | return config | ||
| 26 | }, | ||
| 27 | error => { | ||
| 28 | // do something with request error | ||
| 29 | console.log(error) // for debug | ||
| 30 | return Promise.reject(error) | ||
| 31 | } | ||
| 32 | ) | ||
| 33 | |||
| 34 | // response interceptor | ||
| 35 | service.interceptors.response.use( | ||
| 36 | /** | ||
| 37 | * If you want to get information such as headers or status | ||
| 38 | * Please return response => response | ||
| 39 | */ | ||
| 40 | |||
| 41 | /** | ||
| 42 | * Determine the request status by custom code | ||
| 43 | * Here is just an example | ||
| 44 | * You can also judge the status by HTTP Status Code. | ||
| 45 | */ | ||
| 46 | response => { | ||
| 47 | const res = response.data | ||
| 48 | if (response.config.url.includes('download')) { | ||
| 49 | return res | ||
| 50 | } | ||
| 51 | if (response.config.url.includes('recognize')) { | ||
| 52 | return res | ||
| 53 | } | ||
| 54 | if (response.config.url.includes('verify')) { | ||
| 55 | return res | ||
| 56 | } | ||
| 57 | |||
| 58 | // 3703图片未识别 3730报表无数据 | ||
| 59 | if ( | ||
| 60 | (res && res.code === 0) || | ||
| 61 | res.code === 2926 || | ||
| 62 | res.code === 4001 || | ||
| 63 | res.code === 3703 || | ||
| 64 | res.code === 3730 | ||
| 65 | ) { | ||
| 66 | return res | ||
| 67 | } else if (res && res.code === 2909) { | ||
| 68 | // 2909 登录超时 | ||
| 69 | // cookie失效 | ||
| 70 | Message({ | ||
| 71 | message: res.msg || 'error', | ||
| 72 | type: 'error', | ||
| 73 | duration: 5 * 1000 | ||
| 74 | }) | ||
| 75 | removeToken() | ||
| 76 | router.push('/login') | ||
| 77 | } else if (res && res.code) { | ||
| 78 | Message({ | ||
| 79 | message: res.msg || 'error', | ||
| 80 | type: 'error', | ||
| 81 | duration: 5 * 1000 | ||
| 82 | }) | ||
| 83 | } | ||
| 84 | return res | ||
| 85 | }, | ||
| 86 | error => { | ||
| 87 | Message({ | ||
| 88 | message: '网络连接异常', | ||
| 89 | type: 'error', | ||
| 90 | duration: 5 * 1000 | ||
| 91 | }) | ||
| 92 | console.log('err' + error) // for debug | ||
| 93 | return Promise.reject(error) | ||
| 94 | } | ||
| 95 | ) | ||
| 96 | |||
| 97 | export default service |
src/utils/util.js
0 → 100644
| 1 | /** | ||
| 2 | * Parse the time to string | ||
| 3 | * @param {(Object|string|number)} time | ||
| 4 | * @param {string} cFormat | ||
| 5 | * @returns {string} | ||
| 6 | */ | ||
| 7 | export function parseTime(time, cFormat) { | ||
| 8 | if (arguments.length === 0) { | ||
| 9 | return null | ||
| 10 | } | ||
| 11 | const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}' | ||
| 12 | let date | ||
| 13 | if (typeof time === 'object' && time) { | ||
| 14 | date = time | ||
| 15 | } else { | ||
| 16 | if (typeof time === 'string' && /^[0-9]+$/.test(time)) { | ||
| 17 | time = parseInt(time) | ||
| 18 | } | ||
| 19 | if (typeof time === 'number' && time.toString().length === 10) { | ||
| 20 | time = time * 1000 | ||
| 21 | } | ||
| 22 | date = new Date(time) | ||
| 23 | } | ||
| 24 | const formatObj = { | ||
| 25 | y: date.getFullYear(), | ||
| 26 | m: date.getMonth() + 1, | ||
| 27 | d: date.getDate(), | ||
| 28 | h: date.getHours(), | ||
| 29 | i: date.getMinutes(), | ||
| 30 | s: date.getSeconds(), | ||
| 31 | a: date.getDay() | ||
| 32 | } | ||
| 33 | const timeStr = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => { | ||
| 34 | let value = formatObj[key] | ||
| 35 | // Note: getDay() returns 0 on Sunday | ||
| 36 | if (key === 'a') { | ||
| 37 | return ['日', '一', '二', '三', '四', '五', '六'][value] | ||
| 38 | } | ||
| 39 | if (result.length > 0 && value < 10) { | ||
| 40 | value = '0' + value | ||
| 41 | } | ||
| 42 | return value || 0 | ||
| 43 | }) | ||
| 44 | return timeStr | ||
| 45 | } | ||
| 46 | |||
| 47 | /** | ||
| 48 | * @param {string} url | ||
| 49 | * @returns {Object} | ||
| 50 | */ | ||
| 51 | export function getQueryObject(url) { | ||
| 52 | url = url == null ? window.location.href : url | ||
| 53 | const search = url.substring(url.lastIndexOf('?') + 1) | ||
| 54 | const obj = {} | ||
| 55 | const reg = /([^?&=]+)=([^?&=]*)/g | ||
| 56 | search.replace(reg, (rs, $1, $2) => { | ||
| 57 | const name = decodeURIComponent($1) | ||
| 58 | let val = decodeURIComponent($2) | ||
| 59 | val = String(val) | ||
| 60 | obj[name] = val | ||
| 61 | return rs | ||
| 62 | }) | ||
| 63 | return obj | ||
| 64 | } | ||
| 65 | |||
| 66 | /** | ||
| 67 | * @param {string} input value | ||
| 68 | * @returns {number} output value | ||
| 69 | */ | ||
| 70 | export function byteLength(str) { | ||
| 71 | // returns the byte length of an utf8 string | ||
| 72 | let s = str.length | ||
| 73 | for (var i = str.length - 1; i >= 0; i--) { | ||
| 74 | const code = str.charCodeAt(i) | ||
| 75 | if (code > 0x7f && code <= 0x7ff) s++ | ||
| 76 | else if (code > 0x7ff && code <= 0xffff) s += 2 | ||
| 77 | if (code >= 0xdc00 && code <= 0xdfff) i-- | ||
| 78 | } | ||
| 79 | return s | ||
| 80 | } | ||
| 81 | |||
| 82 | /** | ||
| 83 | * @param {Array} actual | ||
| 84 | * @returns {Array} | ||
| 85 | */ | ||
| 86 | export function cleanArray(actual) { | ||
| 87 | const newArray = [] | ||
| 88 | for (let i = 0; i < actual.length; i++) { | ||
| 89 | if (actual[i]) { | ||
| 90 | newArray.push(actual[i]) | ||
| 91 | } | ||
| 92 | } | ||
| 93 | return newArray | ||
| 94 | } | ||
| 95 | |||
| 96 | /** | ||
| 97 | * @param {Object} json | ||
| 98 | * @returns {Array} | ||
| 99 | */ | ||
| 100 | export function param(json) { | ||
| 101 | if (!json) return '' | ||
| 102 | return cleanArray( | ||
| 103 | Object.keys(json).map(key => { | ||
| 104 | if (json[key] === undefined) return '' | ||
| 105 | return encodeURIComponent(key) + '=' + encodeURIComponent(json[key]) | ||
| 106 | }) | ||
| 107 | ).join('&') | ||
| 108 | } | ||
| 109 | |||
| 110 | /** | ||
| 111 | * @param {string} url | ||
| 112 | * @returns {Object} | ||
| 113 | */ | ||
| 114 | export function param2Obj(url) { | ||
| 115 | const search = url.split('?')[1] | ||
| 116 | if (!search) { | ||
| 117 | return {} | ||
| 118 | } | ||
| 119 | return JSON.parse( | ||
| 120 | '{"' + | ||
| 121 | decodeURIComponent(search) | ||
| 122 | .replace(/"/g, '\\"') | ||
| 123 | .replace(/&/g, '","') | ||
| 124 | .replace(/=/g, '":"') | ||
| 125 | .replace(/\+/g, ' ') + | ||
| 126 | '"}' | ||
| 127 | ) | ||
| 128 | } | ||
| 129 | |||
| 130 | /** | ||
| 131 | * Merges two objects, giving the last one precedence | ||
| 132 | * @param {Object} target | ||
| 133 | * @param {(Object|Array)} source | ||
| 134 | * @returns {Object} | ||
| 135 | */ | ||
| 136 | export function objectMerge(target, source) { | ||
| 137 | if (typeof target !== 'object') { | ||
| 138 | target = {} | ||
| 139 | } | ||
| 140 | if (Array.isArray(source)) { | ||
| 141 | return source.slice() | ||
| 142 | } | ||
| 143 | Object.keys(source).forEach(property => { | ||
| 144 | const sourceProperty = source[property] | ||
| 145 | if (typeof sourceProperty === 'object') { | ||
| 146 | target[property] = objectMerge(target[property], sourceProperty) | ||
| 147 | } else { | ||
| 148 | target[property] = sourceProperty | ||
| 149 | } | ||
| 150 | }) | ||
| 151 | return target | ||
| 152 | } | ||
| 153 | |||
| 154 | /** | ||
| 155 | * @param {string} type | ||
| 156 | * @returns {Date} | ||
| 157 | */ | ||
| 158 | export function getTime(type) { | ||
| 159 | if (type === 'start') { | ||
| 160 | return new Date().getTime() - 3600 * 1000 * 24 * 90 | ||
| 161 | } else { | ||
| 162 | return new Date(new Date().toDateString()) | ||
| 163 | } | ||
| 164 | } | ||
| 165 | |||
| 166 | /** | ||
| 167 | * @param {Function} func | ||
| 168 | * @param {number} wait | ||
| 169 | * @param {boolean} immediate | ||
| 170 | * @return {*} | ||
| 171 | */ | ||
| 172 | export function debounce(func, wait, immediate) { | ||
| 173 | let timeout, args, context, timestamp, result | ||
| 174 | |||
| 175 | const later = function() { | ||
| 176 | // 据上一次触发时间间隔 | ||
| 177 | const last = +new Date() - timestamp | ||
| 178 | |||
| 179 | // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait | ||
| 180 | if (last < wait && last > 0) { | ||
| 181 | timeout = setTimeout(later, wait - last) | ||
| 182 | } else { | ||
| 183 | timeout = null | ||
| 184 | // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用 | ||
| 185 | if (!immediate) { | ||
| 186 | result = func.apply(context, args) | ||
| 187 | if (!timeout) context = args = null | ||
| 188 | } | ||
| 189 | } | ||
| 190 | } | ||
| 191 | |||
| 192 | return function(...args) { | ||
| 193 | context = this | ||
| 194 | timestamp = +new Date() | ||
| 195 | const callNow = immediate && !timeout | ||
| 196 | // 如果延时不存在,重新设定延时 | ||
| 197 | if (!timeout) timeout = setTimeout(later, wait) | ||
| 198 | if (callNow) { | ||
| 199 | result = func.apply(context, args) | ||
| 200 | context = args = null | ||
| 201 | } | ||
| 202 | |||
| 203 | return result | ||
| 204 | } | ||
| 205 | } | ||
| 206 | |||
| 207 | /** | ||
| 208 | * 节流 | ||
| 209 | * @param {*} func | ||
| 210 | * @param {*} wait | ||
| 211 | * @param {*} immediate | ||
| 212 | */ | ||
| 213 | export function throttle(fn, wait = 1000, immediate) { | ||
| 214 | let timer = null | ||
| 215 | let callNow = immediate | ||
| 216 | return function(...args) { | ||
| 217 | let context = this | ||
| 218 | if (callNow) { | ||
| 219 | fn.apply(context, args) | ||
| 220 | callNow = null | ||
| 221 | } | ||
| 222 | if (!timer) { | ||
| 223 | timer = setTimeout(() => { | ||
| 224 | fn.apply(context, args) | ||
| 225 | timer = null | ||
| 226 | }, wait) | ||
| 227 | } | ||
| 228 | } | ||
| 229 | } | ||
| 230 | |||
| 231 | /** | ||
| 232 | * @param {Array} arr | ||
| 233 | * @returns {Array} | ||
| 234 | */ | ||
| 235 | export function uniqueArr(arr) { | ||
| 236 | return Array.from(new Set(arr)) | ||
| 237 | } | ||
| 238 | |||
| 239 | /** | ||
| 240 | * @returns {string} | ||
| 241 | */ | ||
| 242 | export function createUniqueString() { | ||
| 243 | const timestamp = +new Date() + '' | ||
| 244 | const randomNum = parseInt((1 + Math.random()) * 65536) + '' | ||
| 245 | return (+(randomNum + timestamp)).toString(32) | ||
| 246 | } | ||
| 247 | /** | ||
| 248 | * 延迟执行某个操作 | ||
| 249 | * @param {} ms | ||
| 250 | */ | ||
| 251 | export function timeout(ms) { | ||
| 252 | return new Promise((resolve, reject) => { | ||
| 253 | setTimeout(resolve, ms, 'done') | ||
| 254 | }) | ||
| 255 | } | ||
| 256 | /** | ||
| 257 | * 二进制转文件 | ||
| 258 | * @param {*} blobs blob对象 | ||
| 259 | * @param {*} fileName 文件名 | ||
| 260 | */ | ||
| 261 | export function blob2File(blobs, fileName) { | ||
| 262 | const blob = new Blob([blobs]) | ||
| 263 | const href = window.URL.createObjectURL(blob) // 创建下载的链接 | ||
| 264 | const aEle = document.createElement('a') // 创建a标签 | ||
| 265 | aEle.href = href | ||
| 266 | aEle.download = fileName // 下载后文件名 | ||
| 267 | document.body.appendChild(aEle) | ||
| 268 | aEle.click() // 点击下载 | ||
| 269 | document.body.removeChild(aEle) // 下载完成移除元素 | ||
| 270 | window.URL.revokeObjectURL(href) // 释放掉blob对象 | ||
| 271 | } | ||
| 272 | /** | ||
| 273 | * url下载文件 | ||
| 274 | * @param {*} url | ||
| 275 | * @param {*} name | ||
| 276 | */ | ||
| 277 | export function downFile(url, name) { | ||
| 278 | const a = document.createElement('a') | ||
| 279 | a.href = url | ||
| 280 | a.download = name | ||
| 281 | document.body.appendChild(a) | ||
| 282 | a.click() | ||
| 283 | document.body.removeChild(a) | ||
| 284 | } | ||
| 285 | |||
| 286 | /** | ||
| 287 | * 对象转换成formdata形式 | ||
| 288 | * @param {*} data | ||
| 289 | */ | ||
| 290 | export function obj2FormData(data) { | ||
| 291 | const form = new FormData() | ||
| 292 | Object.keys(data).forEach(key => { | ||
| 293 | if (data[key] !== undefined) { | ||
| 294 | form.append(key, data[key]) | ||
| 295 | } | ||
| 296 | }) | ||
| 297 | return form | ||
| 298 | } | ||
| 299 | function typeOf(obj) { | ||
| 300 | const toString = Object.prototype.toString | ||
| 301 | const map = { | ||
| 302 | '[object Boolean]': 'boolean', | ||
| 303 | '[object Number]': 'number', | ||
| 304 | '[object String]': 'string', | ||
| 305 | '[object Null]': 'null', | ||
| 306 | '[object Undefined]': 'undefined', | ||
| 307 | '[object Symbol]': 'symbol', | ||
| 308 | '[object Object]': 'object', | ||
| 309 | '[object Function]': 'function', | ||
| 310 | '[object Array]': 'array', | ||
| 311 | '[object Date]': 'date', | ||
| 312 | '[object RegExp]': 'regexp' | ||
| 313 | } | ||
| 314 | return map[toString.call(obj)] | ||
| 315 | } | ||
| 316 | /** | ||
| 317 | * 深克隆 | ||
| 318 | * @param {*} data | ||
| 319 | */ | ||
| 320 | export function deepClone(data) { | ||
| 321 | const type = typeOf(data) | ||
| 322 | let copy | ||
| 323 | if (type === 'array') { | ||
| 324 | copy = [] | ||
| 325 | } else if (type === 'object') { | ||
| 326 | copy = {} | ||
| 327 | } else { | ||
| 328 | return data | ||
| 329 | } | ||
| 330 | if (type === 'array') { | ||
| 331 | for (let i = 0; i < data.length; i++) { | ||
| 332 | copy.push(deepClone(data[i])) | ||
| 333 | } | ||
| 334 | } | ||
| 335 | if (type === 'object') { | ||
| 336 | for (let key in data) { | ||
| 337 | copy[key] = deepClone(data[key]) | ||
| 338 | } | ||
| 339 | } | ||
| 340 | return copy | ||
| 341 | } | ||
| 342 | |||
| 343 | /** | ||
| 344 | * filter undefined | ||
| 345 | * @param {*} temp | ||
| 346 | */ | ||
| 347 | export function parseUndefined(temp) { | ||
| 348 | // 判断是否为0 | ||
| 349 | if (temp === 0 || temp === '0') { | ||
| 350 | return temp | ||
| 351 | } | ||
| 352 | if (temp) { | ||
| 353 | return temp | ||
| 354 | } else { | ||
| 355 | return undefined | ||
| 356 | } | ||
| 357 | } | ||
| 358 | /** | ||
| 359 | * 获取目标的元素的截图 | ||
| 360 | * @param {*} target | ||
| 361 | * @param {*} format | ||
| 362 | */ | ||
| 363 | export function shotTargetToImage(target, format) { | ||
| 364 | const canvas = document.createElement('canvas') // 创建画布 | ||
| 365 | canvas.width = target.videoWidth | ||
| 366 | canvas.height = target.videoHeight // 设定宽高比 | ||
| 367 | canvas.getContext('2d').drawImage(target, 0, 0, canvas.width, canvas.height) // 将视频此刻帧数画入画布 | ||
| 368 | return canvas.toDataURL(format) | ||
| 369 | } | ||
| 370 | |||
| 371 | // 去掉base头部 | ||
| 372 | export function substringBasehead(base64) { | ||
| 373 | let length = 'data:image/png;base64,'.length | ||
| 374 | return base64.substring(length) | ||
| 375 | } | ||
| 376 | |||
| 377 | export function parseTimeSecond(time) { | ||
| 378 | let minutes = parseInt((time % (1000 * 60 * 60)) / (1000 * 60)) | ||
| 379 | let second = parseInt((time % (1000 * 60)) / 1000) | ||
| 380 | if (minutes < 10) { | ||
| 381 | minutes = `0${minutes}` | ||
| 382 | } | ||
| 383 | if (second < 10) { | ||
| 384 | second = `0${second}` | ||
| 385 | } | ||
| 386 | return `${minutes}:${second}` | ||
| 387 | } | ||
| 388 | |||
| 389 | export function sleep(time) { | ||
| 390 | return new Promise(resolve => { | ||
| 391 | setTimeout(resolve, time) | ||
| 392 | }) | ||
| 393 | } |
src/utils/validate.js
0 → 100644
| 1 | /** | ||
| 2 | * Created by PanJiaChen on 16/11/18. | ||
| 3 | */ | ||
| 4 | |||
| 5 | /** | ||
| 6 | * @param {string} path | ||
| 7 | * @returns {Boolean} | ||
| 8 | */ | ||
| 9 | export function isExternal(path) { | ||
| 10 | return /^(https?:|mailto:|tel:)/.test(path) | ||
| 11 | } | ||
| 12 | |||
| 13 | /** | ||
| 14 | * @param {string} str | ||
| 15 | * @returns {Boolean} | ||
| 16 | */ | ||
| 17 | export function validUsername(str) { | ||
| 18 | const validMap = ['admin', 'editor'] | ||
| 19 | return validMap.indexOf(str.trim()) >= 0 | ||
| 20 | } | ||
| 21 | /** | ||
| 22 | * 模型名称校验函数 | ||
| 23 | * @param {*} rule | ||
| 24 | * @param {*} value | ||
| 25 | * @param {*} callback | ||
| 26 | */ | ||
| 27 | export function validateName(rule, value, callback) { | ||
| 28 | if (!value) { | ||
| 29 | return callback(new Error('模型名称不能为空')) | ||
| 30 | } | ||
| 31 | if (/(^\s+)|(\s+$)/.test(value)) { | ||
| 32 | return callback(new Error('首字符和尾字符不得为空格')) | ||
| 33 | } | ||
| 34 | if (value.length < 2 || value.length > 10) { | ||
| 35 | return callback(new Error('长度在 2 到 10 个字符')) | ||
| 36 | } | ||
| 37 | callback() | ||
| 38 | } | ||
| 39 | /** | ||
| 40 | * 模型描述校验函数 | ||
| 41 | * @param {*} rule | ||
| 42 | * @param {*} value | ||
| 43 | * @param {*} callback | ||
| 44 | */ | ||
| 45 | export function validateDes(rule, value, callback) { | ||
| 46 | if (!value) { | ||
| 47 | return callback(new Error('模型描述不能为空')) | ||
| 48 | } | ||
| 49 | if (/(^\s+)|(\s+$)/.test(value)) { | ||
| 50 | return callback(new Error('首字符和尾字符不得为空格')) | ||
| 51 | } | ||
| 52 | if (value.length < 2 || value.length > 20) { | ||
| 53 | return callback(new Error('长度在 2 到 20 个字符')) | ||
| 54 | } | ||
| 55 | callback() | ||
| 56 | } |
src/views/404.vue
0 → 100644
| 1 | <template> | ||
| 2 | <div class="page"> | ||
| 3 | <div class="image-404"></div> | ||
| 4 | <div class="right"> | ||
| 5 | <div class="text-404"></div> | ||
| 6 | <div class="text">抱歉,你访问的页面不存在</div> | ||
| 7 | <el-button type="primary" size="medium" @click="handleClick" | ||
| 8 | >返回首页</el-button | ||
| 9 | > | ||
| 10 | </div> | ||
| 11 | </div> | ||
| 12 | </template> | ||
| 13 | |||
| 14 | <script> | ||
| 15 | import { mapState } from 'vuex' | ||
| 16 | import { PERMISSION_USER_MAP } from '@/utils/mappingData' | ||
| 17 | |||
| 18 | export default { | ||
| 19 | computed: { | ||
| 20 | ...mapState(['roles']) | ||
| 21 | }, | ||
| 22 | methods: { | ||
| 23 | handleClick() { | ||
| 24 | if (this.roles === PERMISSION_USER_MAP.auditor.code) { | ||
| 25 | this.$router.push({ path: '/task/work' }) | ||
| 26 | } else { | ||
| 27 | this.$router.push({ path: '/' }) | ||
| 28 | } | ||
| 29 | } | ||
| 30 | } | ||
| 31 | } | ||
| 32 | </script> | ||
| 33 | |||
| 34 | <style lang="scss" scoped> | ||
| 35 | .page { | ||
| 36 | display: flex; | ||
| 37 | justify-content: center; | ||
| 38 | align-items: center; | ||
| 39 | width: 100%; | ||
| 40 | height: 100%; | ||
| 41 | background-color: #f0f2f5; | ||
| 42 | .image-404 { | ||
| 43 | width: 443px; | ||
| 44 | height: 342px; | ||
| 45 | margin-right: 121px; | ||
| 46 | background-image: url('../assets/image/404image.png'); | ||
| 47 | background-repeat: no-repeat; | ||
| 48 | } | ||
| 49 | .right { | ||
| 50 | height: 342px; | ||
| 51 | display: flex; | ||
| 52 | flex-flow: column nowrap; | ||
| 53 | justify-content: center; | ||
| 54 | align-items: flex-start; | ||
| 55 | .text-404 { | ||
| 56 | width: 161px; | ||
| 57 | height: 74px; | ||
| 58 | background-image: url('../assets/image/404.png'); | ||
| 59 | background-repeat: no-repeat; | ||
| 60 | } | ||
| 61 | .text { | ||
| 62 | margin: 24px 0 16px 0; | ||
| 63 | width: 240px; | ||
| 64 | height: 28px; | ||
| 65 | font-size: 20px; | ||
| 66 | font-weight: 400; | ||
| 67 | color: rgba(0, 0, 0, 0.45); | ||
| 68 | line-height: 28px; | ||
| 69 | } | ||
| 70 | } | ||
| 71 | } | ||
| 72 | </style> |
src/views/login/index.vue
0 → 100644
| 1 | <template lang="pug"> | ||
| 2 | .login | ||
| 3 | LoginForm(class="login-card" ref="loginRef" @on-success-valid="handleLogin" :loading="btnLoading") | ||
| 4 | </template> | ||
| 5 | <script> | ||
| 6 | import LoginForm from '_c/loginForm' | ||
| 7 | import { mapActions, mapState, mapMutations } from 'vuex' | ||
| 8 | |||
| 9 | export default { | ||
| 10 | components: { | ||
| 11 | LoginForm | ||
| 12 | }, | ||
| 13 | data() { | ||
| 14 | return { | ||
| 15 | isRegister: false, | ||
| 16 | btnLoading: false | ||
| 17 | } | ||
| 18 | }, | ||
| 19 | computed: { | ||
| 20 | ...mapState(['roles']) | ||
| 21 | }, | ||
| 22 | mounted() { | ||
| 23 | this.SET_ROUTER_TEMP('') | ||
| 24 | }, | ||
| 25 | methods: { | ||
| 26 | ...mapActions(['login']), | ||
| 27 | ...mapMutations(['SET_ROUTER_TEMP', 'SET_USERPASS']), | ||
| 28 | async handleLogin({ username, password }) { | ||
| 29 | try { | ||
| 30 | this.btnLoading = true | ||
| 31 | const { code } = await this.login({ username, password }) | ||
| 32 | if (code === 0) { | ||
| 33 | this.SET_USERPASS(password) | ||
| 34 | this.$router.push({ path: '/' }) | ||
| 35 | } else { | ||
| 36 | this.$refs.loginRef.updateCaptcha() | ||
| 37 | } | ||
| 38 | } catch (error) { | ||
| 39 | console.log(error) | ||
| 40 | } finally { | ||
| 41 | this.btnLoading = false | ||
| 42 | } | ||
| 43 | } | ||
| 44 | } | ||
| 45 | } | ||
| 46 | </script> | ||
| 47 | <style lang="scss"> | ||
| 48 | .login { | ||
| 49 | width: 100%; | ||
| 50 | height: 100%; | ||
| 51 | background: center / cover no-repeat url('../../assets/image/login-bg.png'); | ||
| 52 | position: relative; | ||
| 53 | .login-card { | ||
| 54 | position: absolute; | ||
| 55 | top: 195px; | ||
| 56 | bottom: 195px; | ||
| 57 | right: 188px; | ||
| 58 | } | ||
| 59 | } | ||
| 60 | </style> |
src/views/monitor.vue
0 → 100644
| 1 | <template> | ||
| 2 | <div class="order-list"> | ||
| 3 | <Card class="order-list-card"> | ||
| 4 | <div class="search"> | ||
| 5 | <el-form | ||
| 6 | class="count-form" | ||
| 7 | ref="ruleForm" | ||
| 8 | size="mini" | ||
| 9 | inline | ||
| 10 | :model="ruleForm" | ||
| 11 | :rules="rules" | ||
| 12 | > | ||
| 13 | <el-form-item label="客户姓名" prop="customerName"> | ||
| 14 | <el-input | ||
| 15 | v-model.trim="ruleForm.customerName" | ||
| 16 | placeholder="请输入" | ||
| 17 | ></el-input> | ||
| 18 | </el-form-item> | ||
| 19 | <el-form-item label="客户电话" prop="customerPhoneNo"> | ||
| 20 | <el-input | ||
| 21 | v-model.trim="ruleForm.customerPhoneNo" | ||
| 22 | placeholder="请输入" | ||
| 23 | ></el-input> | ||
| 24 | </el-form-item> | ||
| 25 | <el-form-item label="呼叫类型" prop="callType"> | ||
| 26 | <el-select clearable v-model="ruleForm.callType"> | ||
| 27 | <el-option label="呼入" :value="1"></el-option> | ||
| 28 | <el-option label="呼出" :value="0"></el-option> | ||
| 29 | </el-select> | ||
| 30 | </el-form-item> | ||
| 31 | <el-form-item label="合作商" prop="partnerDesc"> | ||
| 32 | <el-input | ||
| 33 | v-model.trim="ruleForm.partnerDesc" | ||
| 34 | placeholder="请输入" | ||
| 35 | ></el-input> | ||
| 36 | </el-form-item> | ||
| 37 | <el-form-item label="状态" prop="orderStatus"> | ||
| 38 | <el-select clearable v-model="ruleForm.orderStatus"> | ||
| 39 | <el-option label="待沟通" :value="0"></el-option> | ||
| 40 | <el-option label="已沟通" :value="1"></el-option> | ||
| 41 | </el-select> | ||
| 42 | </el-form-item> | ||
| 43 | <el-form-item> | ||
| 44 | <el-button type="primary" size="mini" @click="onSubmit" | ||
| 45 | >搜索</el-button | ||
| 46 | > | ||
| 47 | <el-button size="mini" @click="onReset">重置</el-button> | ||
| 48 | </el-form-item> | ||
| 49 | </el-form> | ||
| 50 | </div> | ||
| 51 | <el-table | ||
| 52 | class="mb10" | ||
| 53 | :data="tableData" | ||
| 54 | border | ||
| 55 | style="width: 100%" | ||
| 56 | v-loading="loading" | ||
| 57 | > | ||
| 58 | <el-table-column align="center" prop="orderId" label="订单号" fixed> | ||
| 59 | </el-table-column> | ||
| 60 | <el-table-column | ||
| 61 | align="center" | ||
| 62 | prop="createTime" | ||
| 63 | label="创建时间" | ||
| 64 | width="160" | ||
| 65 | > | ||
| 66 | <template v-slot="scope"> | ||
| 67 | <span>{{ | ||
| 68 | scope.row.createTime ? parseTime(scope.row.createTime) : '' | ||
| 69 | }}</span> | ||
| 70 | </template> | ||
| 71 | </el-table-column> | ||
| 72 | <el-table-column | ||
| 73 | align="center" | ||
| 74 | prop="callTime" | ||
| 75 | label="呼叫时间" | ||
| 76 | width="160" | ||
| 77 | > | ||
| 78 | <template v-slot="scope"> | ||
| 79 | <span>{{ | ||
| 80 | scope.row.callTime ? parseTime(scope.row.callTime) : '' | ||
| 81 | }}</span> | ||
| 82 | </template> | ||
| 83 | </el-table-column> | ||
| 84 | <el-table-column align="center" prop="partnerDesc" label="合作商"> | ||
| 85 | </el-table-column> | ||
| 86 | <el-table-column align="center" prop="customerName" label="客户姓名"> | ||
| 87 | </el-table-column> | ||
| 88 | <el-table-column | ||
| 89 | align="center" | ||
| 90 | prop="customerPhoneNo" | ||
| 91 | label="客户电话" | ||
| 92 | width="160" | ||
| 93 | > | ||
| 94 | </el-table-column> | ||
| 95 | <el-table-column align="center" prop="callType" label="呼叫类型"> | ||
| 96 | </el-table-column> | ||
| 97 | <el-table-column align="center" prop="auditorName" label="坐席姓名"> | ||
| 98 | </el-table-column> | ||
| 99 | <el-table-column align="center" prop="username" label="坐席工号"> | ||
| 100 | </el-table-column> | ||
| 101 | <el-table-column align="center" prop="meetTimes" label="面核次数"> | ||
| 102 | </el-table-column> | ||
| 103 | <el-table-column align="center" prop="durationTimeStr" label="通话时长"> | ||
| 104 | </el-table-column> | ||
| 105 | <el-table-column | ||
| 106 | align="center" | ||
| 107 | prop="orderStatus" | ||
| 108 | fixed="right" | ||
| 109 | label="状态" | ||
| 110 | > | ||
| 111 | <template v-slot="scope"> | ||
| 112 | <span class="status"> | ||
| 113 | <span | ||
| 114 | class="dot" | ||
| 115 | :class="{ yellow: scope.row.orderStatus === '待沟通' }" | ||
| 116 | ></span> | ||
| 117 | <span>{{ scope.row.orderStatus }}</span> | ||
| 118 | </span> | ||
| 119 | </template> | ||
| 120 | </el-table-column> | ||
| 121 | <el-table-column align="center" label="操作" fixed="right" width="50"> | ||
| 122 | <template v-slot="scope"> | ||
| 123 | <div> | ||
| 124 | <el-button | ||
| 125 | type="text" | ||
| 126 | size="small" | ||
| 127 | v-if="scope.row.orderStatus === '已沟通'" | ||
| 128 | @click="handleDetail(scope.row)" | ||
| 129 | >查看</el-button | ||
| 130 | > | ||
| 131 | </div> | ||
| 132 | </template> | ||
| 133 | </el-table-column> | ||
| 134 | </el-table> | ||
| 135 | <FooterPaginationfrom | ||
| 136 | @pager="handleGetPager" | ||
| 137 | :total="total" | ||
| 138 | ></FooterPaginationfrom> | ||
| 139 | </Card> | ||
| 140 | </div> | ||
| 141 | </template> | ||
| 142 | |||
| 143 | <script> | ||
| 144 | import { maxSizeValidate } from '@/views/validate' | ||
| 145 | import FooterPaginationfrom from './components/FooterPagination' | ||
| 146 | import { queryOrderList } from '@/api/orderList' | ||
| 147 | import { parseTime } from '@/utils/util' | ||
| 148 | |||
| 149 | export default { | ||
| 150 | components: { | ||
| 151 | FooterPaginationfrom | ||
| 152 | }, | ||
| 153 | data() { | ||
| 154 | return { | ||
| 155 | parseTime, | ||
| 156 | ruleForm: { | ||
| 157 | customerName: '', | ||
| 158 | customerPhoneNo: '', | ||
| 159 | callType: '', | ||
| 160 | orderStatus: '', | ||
| 161 | partnerDesc: '' | ||
| 162 | }, | ||
| 163 | rules: { | ||
| 164 | customerName: [maxSizeValidate], | ||
| 165 | customerPhoneNo: [maxSizeValidate] | ||
| 166 | }, | ||
| 167 | tableData: [], | ||
| 168 | pagination: null, | ||
| 169 | loading: false, | ||
| 170 | total: 0 | ||
| 171 | } | ||
| 172 | }, | ||
| 173 | methods: { | ||
| 174 | onSubmit() { | ||
| 175 | this.$refs.ruleForm.validate(valid => { | ||
| 176 | if (valid) { | ||
| 177 | this.handleQueryOrderList() | ||
| 178 | } else { | ||
| 179 | return false | ||
| 180 | } | ||
| 181 | }) | ||
| 182 | }, | ||
| 183 | onReset() { | ||
| 184 | this.ruleForm = { | ||
| 185 | customerName: '', | ||
| 186 | customerPhoneNo: '', | ||
| 187 | callType: '', | ||
| 188 | orderStatus: '', | ||
| 189 | partnerDesc: '' | ||
| 190 | } | ||
| 191 | this.onSubmit() | ||
| 192 | }, | ||
| 193 | handleGetPager(data) { | ||
| 194 | this.pagination = data | ||
| 195 | this.onSubmit() | ||
| 196 | }, | ||
| 197 | async handleQueryOrderList() { | ||
| 198 | try { | ||
| 199 | this.loading = true | ||
| 200 | const { | ||
| 201 | customerName, | ||
| 202 | customerPhoneNo, | ||
| 203 | callType, | ||
| 204 | partnerDesc, | ||
| 205 | orderStatus | ||
| 206 | } = this.ruleForm | ||
| 207 | const { | ||
| 208 | code, | ||
| 209 | result: { orderInfoList, totalCount } | ||
| 210 | } = await queryOrderList({ | ||
| 211 | customerName, | ||
| 212 | customerPhoneNo, | ||
| 213 | callType, | ||
| 214 | partnerDesc, | ||
| 215 | orderStatus, | ||
| 216 | pageNo: this.pagination.page, | ||
| 217 | pageSize: this.pagination.size | ||
| 218 | }) | ||
| 219 | if (code === 0) { | ||
| 220 | this.tableData = orderInfoList | ||
| 221 | this.total = totalCount | ||
| 222 | } | ||
| 223 | } catch (error) { | ||
| 224 | console.log(error) | ||
| 225 | } finally { | ||
| 226 | this.loading = false | ||
| 227 | } | ||
| 228 | }, | ||
| 229 | handleDetail(row) { | ||
| 230 | this.$router.push({ | ||
| 231 | path: 'order-detail', | ||
| 232 | query: { id: row.orderId } | ||
| 233 | }) | ||
| 234 | } | ||
| 235 | } | ||
| 236 | } | ||
| 237 | </script> | ||
| 238 | |||
| 239 | <style lang="scss" scoped> | ||
| 240 | .order-list { | ||
| 241 | .order-list-card { | ||
| 242 | .search { | ||
| 243 | .count-form { | ||
| 244 | margin-top: 20px; | ||
| 245 | margin-left: 20px; | ||
| 246 | } | ||
| 247 | } | ||
| 248 | .status { | ||
| 249 | display: flex; | ||
| 250 | justify-content: center; | ||
| 251 | align-items: center; | ||
| 252 | .dot { | ||
| 253 | margin-right: 6px; | ||
| 254 | display: inline-block; | ||
| 255 | width: 4px; | ||
| 256 | height: 4px; | ||
| 257 | border-radius: 50%; | ||
| 258 | background-color: #34c780; | ||
| 259 | } | ||
| 260 | .yellow { | ||
| 261 | background-color: #ffaa00; | ||
| 262 | } | ||
| 263 | } | ||
| 264 | } | ||
| 265 | } | ||
| 266 | .flex-end { | ||
| 267 | display: flex; | ||
| 268 | justify-content: flex-end; | ||
| 269 | } | ||
| 270 | </style> |
src/views/validate.js
0 → 100644
tests/unit/example.spec.js
0 → 100644
| 1 | import { expect } from 'chai' | ||
| 2 | import { shallowMount } from '@vue/test-utils' | ||
| 3 | import HelloWorld from '@/components/HelloWorld.vue' | ||
| 4 | |||
| 5 | describe('HelloWorld.vue', () => { | ||
| 6 | it('renders props.msg when passed', () => { | ||
| 7 | const msg = 'new message' | ||
| 8 | const wrapper = shallowMount(HelloWorld, { | ||
| 9 | propsData: { msg } | ||
| 10 | }) | ||
| 11 | expect(wrapper.text()).to.include(msg) | ||
| 12 | }) | ||
| 13 | }) |
vue.config.js
0 → 100644
| 1 | /* eslint-disable indent */ | ||
| 2 | const FilemanagerWebpackPlugin = require('filemanager-webpack-plugin') | ||
| 3 | const path = require('path') | ||
| 4 | // 匹配路径方法 | ||
| 5 | const resolve = dir => path.join(__dirname, dir) | ||
| 6 | |||
| 7 | const BASE_URL = process.env.NODE_ENV === 'production' ? '' : '/' | ||
| 8 | |||
| 9 | const plugins = | ||
| 10 | process.env.NODE_ENV === 'production' | ||
| 11 | ? [ | ||
| 12 | new FilemanagerWebpackPlugin({ | ||
| 13 | onEnd: [ | ||
| 14 | { delete: [resolve('dist.zip')] }, | ||
| 15 | { | ||
| 16 | archive: [ | ||
| 17 | { source: resolve('dist'), destination: resolve('dist.zip') } | ||
| 18 | ] | ||
| 19 | } | ||
| 20 | ] | ||
| 21 | }) | ||
| 22 | ] | ||
| 23 | : [] | ||
| 24 | module.exports = { | ||
| 25 | lintOnSave: undefined, | ||
| 26 | assetsDir: 'static', | ||
| 27 | // 打包时不生成map文件,减少打包体积,加快打包速度 | ||
| 28 | productionSourceMap: false, | ||
| 29 | devServer: { | ||
| 30 | https: true, | ||
| 31 | inline: true, | ||
| 32 | proxy: { | ||
| 33 | '/chery': { | ||
| 34 | target: process.env.VUE_APP_BASE_API | ||
| 35 | } | ||
| 36 | // '/': { | ||
| 37 | // bypass: devServerProxyBypass, | ||
| 38 | // secure: false, | ||
| 39 | // target: serverTarget, | ||
| 40 | // headers: { | ||
| 41 | // Host: new URL(serverTarget).host | ||
| 42 | // } | ||
| 43 | // } | ||
| 44 | } | ||
| 45 | }, | ||
| 46 | configureWebpack: {}, | ||
| 47 | chainWebpack: config => { | ||
| 48 | config.resolve.alias | ||
| 49 | .set('@', resolve('src')) | ||
| 50 | .set('_c', resolve('src/components')) | ||
| 51 | // set svg-sprite-loader | ||
| 52 | config.module | ||
| 53 | .rule('svg') | ||
| 54 | .exclude.add(resolve('src/icons')) | ||
| 55 | .end() | ||
| 56 | config.module | ||
| 57 | .rule('icons') | ||
| 58 | .test(/\.svg$/) | ||
| 59 | .include.add(resolve('src/icons')) | ||
| 60 | .end() | ||
| 61 | .use('svg-sprite-loader') | ||
| 62 | .loader('svg-sprite-loader') | ||
| 63 | .options({ | ||
| 64 | symbolId: 'icon-[name]' | ||
| 65 | }) | ||
| 66 | .end() | ||
| 67 | } | ||
| 68 | } |
-
Please register or sign in to post a comment