├── .gitignore
├── README.md
├── build
├── asset-manifest.json
├── eos.min.js
├── favicon.ico
├── ff.js
├── img
│ ├── Chevron@2x.png
│ ├── check.png
│ ├── check_h.png
│ ├── chevron.png
│ ├── eos_icon.png
│ ├── help.png
│ └── nodevote.png
├── index.html
├── manifest.json
├── scatter.min.js
├── service-worker.js
└── static
│ ├── js
│ ├── 0.4a16e162.chunk.js
│ ├── 0.4a16e162.chunk.js.map
│ ├── 1.8200ab96.chunk.js
│ ├── 1.8200ab96.chunk.js.map
│ ├── 2.592e2146.chunk.js
│ ├── 2.592e2146.chunk.js.map
│ ├── 3.3b02c771.chunk.js
│ ├── 3.3b02c771.chunk.js.map
│ ├── 4.0719ea29.chunk.js
│ ├── 4.0719ea29.chunk.js.map
│ ├── 5.a20c2834.chunk.js
│ ├── 5.a20c2834.chunk.js.map
│ ├── 6.a18169a3.chunk.js
│ ├── 6.a18169a3.chunk.js.map
│ ├── main.79d81733.js
│ └── main.79d81733.js.map
│ └── media
│ └── SourceHanSansCN-Light.424662ea.otf
├── config-overrides.js
├── package-lock.json
├── package.json
├── public
├── eos.min.js
├── favicon.ico
├── ff.js
├── img
│ ├── Chevron@2x.png
│ ├── check.png
│ ├── check_h.png
│ ├── chevron.png
│ ├── eos_icon.png
│ ├── help.png
│ └── nodevote.png
├── index.html
├── manifest.json
└── scatter.min.js
├── rex_abi.md
├── src
├── fonts
│ ├── SourceHanSansCN-Light.otf
│ ├── SourceHanSansCN-Medium.otf
│ └── SourceHanSansCN-Regular.otf
├── index.css
├── index.js
├── locales
│ ├── en-US.js
│ ├── en.js
│ ├── zh-CN.js
│ └── zh.js
├── models
│ ├── commonModel.js
│ ├── index.js
│ ├── rexModel.js
│ └── voteModel.js
├── registerServiceWorker.js
├── router.js
├── routes
│ ├── BuyandSell.js
│ ├── DetailsList.js
│ ├── GameDescription.js
│ ├── Index.js
│ ├── MyRexDetails.js
│ ├── NodeVoting.js
│ └── Withdraw.js
└── utils
│ ├── Api.js
│ ├── Auto.js
│ ├── Constants.js
│ ├── EosUtil.js
│ ├── EventEmitter.js
│ ├── FormatUtil.js
│ ├── RequestUtil.js
│ ├── Utils.js
│ ├── eos.min.js
│ └── scatter.min.js
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules/
2 | /.history/
3 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | An open source dapp of rex
2 |
3 | 原型图:https://pro.modao.cc/app/wuCVWCSX3MnmEIuENmMm2hxIW8cShDp
4 | ABI接口:https://github.com/eostoken/eosrex/blob/master/rex_abi.md
5 |
6 | 背景:
7 | rex 开发已经完成 很快就要上线(具体进度:https://eosauthority.com/rex/) ,想必各个钱包将支持。
8 |
9 | 目的:
10 | 1. 我们希望做成一个dapp,可以无缝接入到所有钱包。
11 | 2. 我们会将代码全部开源,开发者可以随意使用,为社区和生态贡献我们的力量。
12 | 3. DAPP内部不包含任何开发方的任何可识别标识,欢迎所有开发者共同维护和使用。
13 |
14 |
15 | 路线图:
16 | 1. 原型图确定
17 | 2. 美术设计
18 | 3. 开发
19 | 1. 前端技术选型 初步定为 react + antd-moblie + scatter
20 | 4. 发布
21 |
22 | 发起方:
23 | XXXXXXXXXXX
24 | XXXXXXXXXXX
25 |
26 |
27 | 接入项目列表:
28 |
29 | ET钱包
30 | 虎符钱包
31 | PocketECO
32 | ONEChain
33 | 块信
34 | Awake钱包
35 |
--------------------------------------------------------------------------------
/build/asset-manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "main.js": "static/js/main.79d81733.js",
3 | "main.js.map": "static/js/main.79d81733.js.map",
4 | "static/js/0.4a16e162.chunk.js": "static/js/0.4a16e162.chunk.js",
5 | "static/js/0.4a16e162.chunk.js.map": "static/js/0.4a16e162.chunk.js.map",
6 | "static/js/1.8200ab96.chunk.js": "static/js/1.8200ab96.chunk.js",
7 | "static/js/1.8200ab96.chunk.js.map": "static/js/1.8200ab96.chunk.js.map",
8 | "static/js/2.592e2146.chunk.js": "static/js/2.592e2146.chunk.js",
9 | "static/js/2.592e2146.chunk.js.map": "static/js/2.592e2146.chunk.js.map",
10 | "static/js/3.3b02c771.chunk.js": "static/js/3.3b02c771.chunk.js",
11 | "static/js/3.3b02c771.chunk.js.map": "static/js/3.3b02c771.chunk.js.map",
12 | "static/js/4.0719ea29.chunk.js": "static/js/4.0719ea29.chunk.js",
13 | "static/js/4.0719ea29.chunk.js.map": "static/js/4.0719ea29.chunk.js.map",
14 | "static/js/5.a20c2834.chunk.js": "static/js/5.a20c2834.chunk.js",
15 | "static/js/5.a20c2834.chunk.js.map": "static/js/5.a20c2834.chunk.js.map",
16 | "static/js/6.a18169a3.chunk.js": "static/js/6.a18169a3.chunk.js",
17 | "static/js/6.a18169a3.chunk.js.map": "static/js/6.a18169a3.chunk.js.map",
18 | "static/media/SourceHanSansCN-Light.otf": "static/media/SourceHanSansCN-Light.424662ea.otf"
19 | }
--------------------------------------------------------------------------------
/build/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/etwallet/eosrex/f017e24986f36c920fb1184944fe82657136629d/build/favicon.ico
--------------------------------------------------------------------------------
/build/ff.js:
--------------------------------------------------------------------------------
1 | !function(){var a="@charset \"utf-8\";html{color:#000;background:#fff;overflow-y:scroll;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}html *{outline:0;-webkit-text-size-adjust:none;-webkit-tap-highlight-color:rgba(0,0,0,0)}html,body{font-family:sans-serif}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td,hr,button,article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{margin:0;padding:0}input,select,textarea{font-size:100%}table{border-collapse:collapse;border-spacing:0}fieldset,img{border:0}abbr,acronym{border:0;font-variant:normal}del{text-decoration:line-through}address,caption,cite,code,dfn,em,th,var{font-style:normal;font-weight:500}ol,ul{list-style:none}caption,th{text-align:left}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:500}q:before,q:after{content:''}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}a:hover{text-decoration:underline}ins,a{text-decoration:none}",b=document.createElement("style");if(document.getElementsByTagName("head")[0].appendChild(b),b.styleSheet)b.styleSheet.disabled||(b.styleSheet.cssText=a);else try{b.innerHTML=a}catch(c){b.innerText=a}}();!function(a,b){function c(){var b=f.getBoundingClientRect().width;b/i>540&&(b=540*i);var c=b/10;f.style.fontSize=c+"px",k.rem=a.rem=c}var d,e=a.document,f=e.documentElement,g=e.querySelector('meta[name="viewport"]'),h=e.querySelector('meta[name="flexible"]'),i=0,j=0,k=b.flexible||(b.flexible={});if(g){console.warn("将根据已有的meta标签来设置缩放比例");var l=g.getAttribute("content").match(/initial\-scale=([\d\.]+)/);l&&(j=parseFloat(l[1]),i=parseInt(1/j))}else if(h){var m=h.getAttribute("content");if(m){var n=m.match(/initial\-dpr=([\d\.]+)/),o=m.match(/maximum\-dpr=([\d\.]+)/);n&&(i=parseFloat(n[1]),j=parseFloat((1/i).toFixed(2))),o&&(i=parseFloat(o[1]),j=parseFloat((1/i).toFixed(2)))}}if(!i&&!j){var p=(a.navigator.appVersion.match(/android/gi),a.navigator.appVersion.match(/iphone/gi)),q=a.devicePixelRatio;i=p?q>=3&&(!i||i>=3)?3:q>=2&&(!i||i>=2)?2:1:1,j=1/i}if(f.setAttribute("data-dpr",i),!g)if(g=e.createElement("meta"),g.setAttribute("name","viewport"),g.setAttribute("content","initial-scale="+j+", maximum-scale="+j+", minimum-scale="+j+", user-scalable=no"),f.firstElementChild)f.firstElementChild.appendChild(g);else{var r=e.createElement("div");r.appendChild(g),e.write(r.innerHTML)}a.addEventListener("resize",function(){clearTimeout(d),d=setTimeout(c,300)},!1),a.addEventListener("pageshow",function(a){a.persisted&&(clearTimeout(d),d=setTimeout(c,300))},!1),"complete"===e.readyState?e.body.style.fontSize=12*i+"px":e.addEventListener("DOMContentLoaded",function(){e.body.style.fontSize=12*i+"px"},!1),c(),k.dpr=a.dpr=i,k.refreshRem=c,k.rem2px=function(a){var b=parseFloat(a)*this.rem;return"string"==typeof a&&a.match(/rem$/)&&(b+="px"),b},k.px2rem=function(a){var b=parseFloat(a)/this.rem;return"string"==typeof a&&a.match(/px$/)&&(b+="rem"),b}}(window,window.lib||(window.lib={}));
--------------------------------------------------------------------------------
/build/img/Chevron@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/etwallet/eosrex/f017e24986f36c920fb1184944fe82657136629d/build/img/Chevron@2x.png
--------------------------------------------------------------------------------
/build/img/check.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/etwallet/eosrex/f017e24986f36c920fb1184944fe82657136629d/build/img/check.png
--------------------------------------------------------------------------------
/build/img/check_h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/etwallet/eosrex/f017e24986f36c920fb1184944fe82657136629d/build/img/check_h.png
--------------------------------------------------------------------------------
/build/img/chevron.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/etwallet/eosrex/f017e24986f36c920fb1184944fe82657136629d/build/img/chevron.png
--------------------------------------------------------------------------------
/build/img/eos_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/etwallet/eosrex/f017e24986f36c920fb1184944fe82657136629d/build/img/eos_icon.png
--------------------------------------------------------------------------------
/build/img/help.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/etwallet/eosrex/f017e24986f36c920fb1184944fe82657136629d/build/img/help.png
--------------------------------------------------------------------------------
/build/img/nodevote.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/etwallet/eosrex/f017e24986f36c920fb1184944fe82657136629d/build/img/nodevote.png
--------------------------------------------------------------------------------
/build/index.html:
--------------------------------------------------------------------------------
1 |
REX
--------------------------------------------------------------------------------
/build/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "ETRobot",
3 | "name": "ETRobot",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "192x192",
8 | "type": "image/png"
9 | }
10 | ],
11 | "start_url": "./index.html",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#25242B"
15 | }
16 |
--------------------------------------------------------------------------------
/build/service-worker.js:
--------------------------------------------------------------------------------
1 | "use strict";var precacheConfig=[["/index.html","2e6651315951cf55cedf8a0ce2ebec64"],["/static/js/0.4a16e162.chunk.js","3f18861545c2c4f29baf23644c87c73e"],["/static/js/1.8200ab96.chunk.js","fbc7e00a6dbc44bae9c0e8232bdc0de3"],["/static/js/2.592e2146.chunk.js","bd1a3971d34e1d5b3a1d08856f8291d6"],["/static/js/3.3b02c771.chunk.js","eb966b97eb1486f49bf06931cfbe2bd2"],["/static/js/4.0719ea29.chunk.js","0a409d5f804301e0585c77db1c688ddf"],["/static/js/5.a20c2834.chunk.js","54587ed1dda671b7c10be8fb5eac1a70"],["/static/js/6.a18169a3.chunk.js","522ff997cdaf4a58a68c526bffa224f5"],["/static/js/main.79d81733.js","d732d536b5bd49fe2cf24d5fc040b225"]],cacheName="sw-precache-v3-sw-precache-webpack-plugin-"+(self.registration?self.registration.scope:""),ignoreUrlParametersMatching=[/^utm_/],addDirectoryIndex=function(e,t){var n=new URL(e);return"/"===n.pathname.slice(-1)&&(n.pathname+=t),n.toString()},cleanResponse=function(t){return t.redirected?("body"in t?Promise.resolve(t.body):t.blob()).then(function(e){return new Response(e,{headers:t.headers,status:t.status,statusText:t.statusText})}):Promise.resolve(t)},createCacheKey=function(e,t,n,r){var a=new URL(e);return r&&a.pathname.match(r)||(a.search+=(a.search?"&":"")+encodeURIComponent(t)+"="+encodeURIComponent(n)),a.toString()},isPathWhitelisted=function(e,t){if(0===e.length)return!0;var n=new URL(t).pathname;return e.some(function(e){return n.match(e)})},stripIgnoredUrlParameters=function(e,n){var t=new URL(e);return t.hash="",t.search=t.search.slice(1).split("&").map(function(e){return e.split("=")}).filter(function(t){return n.every(function(e){return!e.test(t[0])})}).map(function(e){return e.join("=")}).join("&"),t.toString()},hashParamName="_sw-precache",urlsToCacheKeys=new Map(precacheConfig.map(function(e){var t=e[0],n=e[1],r=new URL(t,self.location),a=createCacheKey(r,hashParamName,n,/\.\w{8}\./);return[r.toString(),a]}));function setOfCachedUrls(e){return e.keys().then(function(e){return e.map(function(e){return e.url})}).then(function(e){return new Set(e)})}self.addEventListener("install",function(e){e.waitUntil(caches.open(cacheName).then(function(r){return setOfCachedUrls(r).then(function(n){return Promise.all(Array.from(urlsToCacheKeys.values()).map(function(t){if(!n.has(t)){var e=new Request(t,{credentials:"same-origin"});return fetch(e).then(function(e){if(!e.ok)throw new Error("Request for "+t+" returned a response with status "+e.status);return cleanResponse(e).then(function(e){return r.put(t,e)})})}}))})}).then(function(){return self.skipWaiting()}))}),self.addEventListener("activate",function(e){var n=new Set(urlsToCacheKeys.values());e.waitUntil(caches.open(cacheName).then(function(t){return t.keys().then(function(e){return Promise.all(e.map(function(e){if(!n.has(e.url))return t.delete(e)}))})}).then(function(){return self.clients.claim()}))}),self.addEventListener("fetch",function(t){if("GET"===t.request.method){var e,n=stripIgnoredUrlParameters(t.request.url,ignoreUrlParametersMatching),r="index.html";(e=urlsToCacheKeys.has(n))||(n=addDirectoryIndex(n,r),e=urlsToCacheKeys.has(n));var a="/index.html";!e&&"navigate"===t.request.mode&&isPathWhitelisted(["^(?!\\/__).*"],t.request.url)&&(n=new URL(a,self.location).toString(),e=urlsToCacheKeys.has(n)),e&&t.respondWith(caches.open(cacheName).then(function(e){return e.match(urlsToCacheKeys.get(n)).then(function(e){if(e)return e;throw Error("The cached response that was expected is missing.")})}).catch(function(e){return console.warn('Couldn\'t serve response for "%s" from cache: %O',t.request.url,e),fetch(t.request)}))}});
--------------------------------------------------------------------------------
/build/static/js/6.a18169a3.chunk.js:
--------------------------------------------------------------------------------
1 | webpackJsonp([6],{559:function(e,t,n){"use strict";function i(e){if(null==e)throw new TypeError("Cannot destructure undefined")}function s(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function r(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!==typeof t&&"function"!==typeof t?e:t}function a(e,t){if("function"!==typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var o=n(7),u=n.n(o),l=n(244),d=n(243),h=(n.n(d),n(584)),c=n(246),f=(n.n(c),n(247),function(){function e(e,t){for(var n=0;n0)for(n=0;n0?"future":"past"];return Y(n)?n(t):n.replace(/%s/i,t)}function R(e,t){var n=e.toLowerCase();Vi[n]=Vi[n+"s"]=Vi[t]=e}function F(e){return"string"===typeof e?Vi[e]||Vi[e.toLowerCase()]:void 0}function U(e){var t,n,i={};for(n in e)l(e,n)&&(t=F(n))&&(i[t]=e[n]);return i}function E(e,t){ji[e]=t}function N(e){var t=[];for(var n in e)t.push({unit:n,priority:ji[n]});return t.sort(function(e,t){return e.priority-t.priority}),t}function G(e,t,n){var i=""+Math.abs(e),s=t-i.length;return(e>=0?n?"+":"":"-")+Math.pow(10,Math.max(0,s)).toString().substr(1)+i}function V(e,t,n,i){var s=i;"string"===typeof i&&(s=function(){return this[i]()}),e&&(Zi[e]=s),t&&(Zi[t[0]]=function(){return G(s.apply(this,arguments),t[1],t[2])}),n&&(Zi[n]=function(){return this.localeData().ordinal(s.apply(this,arguments),e)})}function j(e){return e.match(/\[[\s\S]/)?e.replace(/^\[|\]$/g,""):e.replace(/\\/g,"")}function A(e){var t,n,i=e.match(Ai);for(t=0,n=i.length;t=0&&Ii.test(e);)e=e.replace(Ii,n),Ii.lastIndex=0,i-=1;return e}function Z(e,t,n){ds[e]=Y(t)?t:function(e,i){return e&&n?n:t}}function $(e,t){return l(ds,e)?ds[e](t._strict,t._locale):new RegExp(q(e))}function q(e){return J(e.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(e,t,n,i,s){return t||n||i||s}))}function J(e){return e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function B(e,t){var n,i=t;for("string"===typeof e&&(e=[e]),a(t)&&(i=function(e,n){n[t]=v(e)}),n=0;n=0?(o=new Date(e+400,t,n,i,s,r,a),isFinite(o.getFullYear())&&o.setFullYear(e)):o=new Date(e,t,n,i,s,r,a),o}function ve(e){var t;if(e<100&&e>=0){var n=Array.prototype.slice.call(arguments);n[0]=e+400,t=new Date(Date.UTC.apply(null,n)),isFinite(t.getUTCFullYear())&&t.setUTCFullYear(e)}else t=new Date(Date.UTC.apply(null,arguments));return t}function Me(e,t,n){var i=7+t-n;return-(7+ve(e,0,i).getUTCDay()-t)%7+i-1}function ke(e,t,n,i,s){var r,a,o=(7+n-i)%7,u=Me(e,i,s),l=1+7*(t-1)+o+u;return l<=0?(r=e-1,a=K(r)+l):l>K(e)?(r=e+1,a=l-K(e)):(r=e,a=l),{year:r,dayOfYear:a}}function De(e,t,n){var i,s,r=Me(e.year(),t,n),a=Math.floor((e.dayOfYear()-r-1)/7)+1;return a<1?(s=e.year()-1,i=a+Se(s,t,n)):a>Se(e.year(),t,n)?(i=a-Se(e.year(),t,n),s=e.year()+1):(s=e.year(),i=a),{week:i,year:s}}function Se(e,t,n){var i=Me(e,t,n),s=Me(e+1,t,n);return(K(e)-i+s)/7}function Ye(e){return De(e,this._week.dow,this._week.doy).week}function Oe(){return this._week.dow}function Te(){return this._week.doy}function be(e){var t=this.localeData().week(this);return null==e?t:this.add(7*(e-t),"d")}function xe(e){var t=De(this,1,4).week;return null==e?t:this.add(7*(e-t),"d")}function Pe(e,t){return"string"!==typeof e?e:isNaN(e)?(e=t.weekdaysParse(e),"number"===typeof e?e:null):parseInt(e,10)}function We(e,t){return"string"===typeof e?t.weekdaysParse(e)%7||7:isNaN(e)?null:e}function He(e,t){return e.slice(t,7).concat(e.slice(0,t))}function Ce(e,t){var i=n(this._weekdays)?this._weekdays:this._weekdays[e&&!0!==e&&this._weekdays.isFormat.test(t)?"format":"standalone"];return!0===e?He(i,this._week.dow):e?i[e.day()]:i}function Le(e){return!0===e?He(this._weekdaysShort,this._week.dow):e?this._weekdaysShort[e.day()]:this._weekdaysShort}function Re(e){return!0===e?He(this._weekdaysMin,this._week.dow):e?this._weekdaysMin[e.day()]:this._weekdaysMin}function Fe(e,t,n){var i,s,r,a=e.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],i=0;i<7;++i)r=h([2e3,1]).day(i),this._minWeekdaysParse[i]=this.weekdaysMin(r,"").toLocaleLowerCase(),this._shortWeekdaysParse[i]=this.weekdaysShort(r,"").toLocaleLowerCase(),this._weekdaysParse[i]=this.weekdays(r,"").toLocaleLowerCase();return n?"dddd"===t?(s=Ms.call(this._weekdaysParse,a),-1!==s?s:null):"ddd"===t?(s=Ms.call(this._shortWeekdaysParse,a),-1!==s?s:null):(s=Ms.call(this._minWeekdaysParse,a),-1!==s?s:null):"dddd"===t?-1!==(s=Ms.call(this._weekdaysParse,a))?s:-1!==(s=Ms.call(this._shortWeekdaysParse,a))?s:(s=Ms.call(this._minWeekdaysParse,a),-1!==s?s:null):"ddd"===t?-1!==(s=Ms.call(this._shortWeekdaysParse,a))?s:-1!==(s=Ms.call(this._weekdaysParse,a))?s:(s=Ms.call(this._minWeekdaysParse,a),-1!==s?s:null):-1!==(s=Ms.call(this._minWeekdaysParse,a))?s:-1!==(s=Ms.call(this._weekdaysParse,a))?s:(s=Ms.call(this._shortWeekdaysParse,a),-1!==s?s:null)}function Ue(e,t,n){var i,s,r;if(this._weekdaysParseExact)return Fe.call(this,e,t,n);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),i=0;i<7;i++){if(s=h([2e3,1]).day(i),n&&!this._fullWeekdaysParse[i]&&(this._fullWeekdaysParse[i]=new RegExp("^"+this.weekdays(s,"").replace(".","\\.?")+"$","i"),this._shortWeekdaysParse[i]=new RegExp("^"+this.weekdaysShort(s,"").replace(".","\\.?")+"$","i"),this._minWeekdaysParse[i]=new RegExp("^"+this.weekdaysMin(s,"").replace(".","\\.?")+"$","i")),this._weekdaysParse[i]||(r="^"+this.weekdays(s,"")+"|^"+this.weekdaysShort(s,"")+"|^"+this.weekdaysMin(s,""),this._weekdaysParse[i]=new RegExp(r.replace(".",""),"i")),n&&"dddd"===t&&this._fullWeekdaysParse[i].test(e))return i;if(n&&"ddd"===t&&this._shortWeekdaysParse[i].test(e))return i;if(n&&"dd"===t&&this._minWeekdaysParse[i].test(e))return i;if(!n&&this._weekdaysParse[i].test(e))return i}}function Ee(e){if(!this.isValid())return null!=e?this:NaN;var t=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=e?(e=Pe(e,this.localeData()),this.add(e-t,"d")):t}function Ne(e){if(!this.isValid())return null!=e?this:NaN;var t=(this.day()+7-this.localeData()._week.dow)%7;return null==e?t:this.add(e-t,"d")}function Ge(e){if(!this.isValid())return null!=e?this:NaN;if(null!=e){var t=We(e,this.localeData());return this.day(this.day()%7?t:t-7)}return this.day()||7}function Ve(e){return this._weekdaysParseExact?(l(this,"_weekdaysRegex")||Ie.call(this),e?this._weekdaysStrictRegex:this._weekdaysRegex):(l(this,"_weekdaysRegex")||(this._weekdaysRegex=Hs),this._weekdaysStrictRegex&&e?this._weekdaysStrictRegex:this._weekdaysRegex)}function je(e){return this._weekdaysParseExact?(l(this,"_weekdaysRegex")||Ie.call(this),e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(l(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=Cs),this._weekdaysShortStrictRegex&&e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)}function Ae(e){return this._weekdaysParseExact?(l(this,"_weekdaysRegex")||Ie.call(this),e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(l(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=Ls),this._weekdaysMinStrictRegex&&e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)}function Ie(){function e(e,t){return t.length-e.length}var t,n,i,s,r,a=[],o=[],u=[],l=[];for(t=0;t<7;t++)n=h([2e3,1]).day(t),i=this.weekdaysMin(n,""),s=this.weekdaysShort(n,""),r=this.weekdays(n,""),a.push(i),o.push(s),u.push(r),l.push(i),l.push(s),l.push(r);for(a.sort(e),o.sort(e),u.sort(e),l.sort(e),t=0;t<7;t++)o[t]=J(o[t]),u[t]=J(u[t]),l[t]=J(l[t]);this._weekdaysRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+o.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+a.join("|")+")","i")}function ze(){return this.hours()%12||12}function Ze(){return this.hours()||24}function $e(e,t){V(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)})}function qe(e,t){return t._meridiemParse}function Je(e){return"p"===(e+"").toLowerCase().charAt(0)}function Be(e,t,n){return e>11?n?"pm":"PM":n?"am":"AM"}function Qe(e){return e?e.toLowerCase().replace("_","-"):e}function Xe(e){for(var t,n,i,s,r=0;r0;){if(i=Ke(s.slice(0,t).join("-")))return i;if(n&&n.length>=t&&M(s,n,!0)>=t-1)break;t--}r++}return Rs}function Ke(t){var n=null;if(!Ns[t]&&"undefined"!==typeof e&&e&&e.exports)try{n=Rs._abbr;!function(){var e=new Error('Cannot find module "./locale"');throw e.code="MODULE_NOT_FOUND",e}(),et(n)}catch(e){}return Ns[t]}function et(e,t){var n;return e&&(n=r(t)?it(e):tt(e,t),n?Rs=n:"undefined"!==typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),Rs._abbr}function tt(e,t){if(null!==t){var n,i=Es;if(t.abbr=e,null!=Ns[e])S("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),i=Ns[e]._config;else if(null!=t.parentLocale)if(null!=Ns[t.parentLocale])i=Ns[t.parentLocale]._config;else{if(null==(n=Ke(t.parentLocale)))return Gs[t.parentLocale]||(Gs[t.parentLocale]=[]),Gs[t.parentLocale].push({name:e,config:t}),null;i=n._config}return Ns[e]=new b(T(i,t)),Gs[e]&&Gs[e].forEach(function(e){tt(e.name,e.config)}),et(e),Ns[e]}return delete Ns[e],null}function nt(e,t){if(null!=t){var n,i,s=Es;i=Ke(e),null!=i&&(s=i._config),t=T(s,t),n=new b(t),n.parentLocale=Ns[e],Ns[e]=n,et(e)}else null!=Ns[e]&&(null!=Ns[e].parentLocale?Ns[e]=Ns[e].parentLocale:null!=Ns[e]&&delete Ns[e]);return Ns[e]}function it(e){var t;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return Rs;if(!n(e)){if(t=Ke(e))return t;e=[e]}return Xe(e)}function st(){return Fi(Ns)}function rt(e){var t,n=e._a;return n&&-2===f(e).overflow&&(t=n[fs]<0||n[fs]>11?fs:n[ms]<1||n[ms]>ue(n[cs],n[fs])?ms:n[_s]<0||n[_s]>24||24===n[_s]&&(0!==n[ys]||0!==n[ps]||0!==n[gs])?_s:n[ys]<0||n[ys]>59?ys:n[ps]<0||n[ps]>59?ps:n[gs]<0||n[gs]>999?gs:-1,f(e)._overflowDayOfYear&&(tms)&&(t=ms),f(e)._overflowWeeks&&-1===t&&(t=ws),f(e)._overflowWeekday&&-1===t&&(t=vs),f(e).overflow=t),e}function at(e,t,n){return null!=e?e:null!=t?t:n}function ot(e){var n=new Date(t.now());return e._useUTC?[n.getUTCFullYear(),n.getUTCMonth(),n.getUTCDate()]:[n.getFullYear(),n.getMonth(),n.getDate()]}function ut(e){var t,n,i,s,r,a=[];if(!e._d){for(i=ot(e),e._w&&null==e._a[ms]&&null==e._a[fs]&<(e),null!=e._dayOfYear&&(r=at(e._a[cs],i[cs]),(e._dayOfYear>K(r)||0===e._dayOfYear)&&(f(e)._overflowDayOfYear=!0),n=ve(r,0,e._dayOfYear),e._a[fs]=n.getUTCMonth(),e._a[ms]=n.getUTCDate()),t=0;t<3&&null==e._a[t];++t)e._a[t]=a[t]=i[t];for(;t<7;t++)e._a[t]=a[t]=null==e._a[t]?2===t?1:0:e._a[t];24===e._a[_s]&&0===e._a[ys]&&0===e._a[ps]&&0===e._a[gs]&&(e._nextDay=!0,e._a[_s]=0),e._d=(e._useUTC?ve:we).apply(null,a),s=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[_s]=24),e._w&&"undefined"!==typeof e._w.d&&e._w.d!==s&&(f(e).weekdayMismatch=!0)}}function lt(e){var t,n,i,s,r,a,o,u;if(t=e._w,null!=t.GG||null!=t.W||null!=t.E)r=1,a=4,n=at(t.GG,e._a[cs],De(Ot(),1,4).year),i=at(t.W,1),((s=at(t.E,1))<1||s>7)&&(u=!0);else{r=e._locale._week.dow,a=e._locale._week.doy;var l=De(Ot(),r,a);n=at(t.gg,e._a[cs],l.year),i=at(t.w,l.week),null!=t.d?((s=t.d)<0||s>6)&&(u=!0):null!=t.e?(s=t.e+r,(t.e<0||t.e>6)&&(u=!0)):s=r}i<1||i>Se(n,r,a)?f(e)._overflowWeeks=!0:null!=u?f(e)._overflowWeekday=!0:(o=ke(n,i,s,r,a),e._a[cs]=o.year,e._dayOfYear=o.dayOfYear)}function dt(e){var t,n,i,s,r,a,o=e._i,u=Vs.exec(o)||js.exec(o);if(u){for(f(e).iso=!0,t=0,n=Is.length;t0&&f(e).unusedInput.push(a),o=o.slice(o.indexOf(i)+i.length),l+=i.length),Zi[r]?(i?f(e).empty=!1:f(e).unusedTokens.push(r),X(r,i,e)):e._strict&&!i&&f(e).unusedTokens.push(r);f(e).charsLeftOver=u-l,o.length>0&&f(e).unusedInput.push(o),e._a[_s]<=12&&!0===f(e).bigHour&&e._a[_s]>0&&(f(e).bigHour=void 0),f(e).parsedDateParts=e._a.slice(0),f(e).meridiem=e._meridiem,e._a[_s]=wt(e._locale,e._a[_s],e._meridiem),ut(e),rt(e)}function wt(e,t,n){var i;return null==n?t:null!=e.meridiemHour?e.meridiemHour(t,n):null!=e.isPM?(i=e.isPM(n),i&&t<12&&(t+=12),i||12!==t||(t=0),t):t}function vt(e){var t,n,i,s,r;if(0===e._f.length)return f(e).invalidFormat=!0,void(e._d=new Date(NaN));for(s=0;sthis.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()}function $t(){if(!r(this._isDSTShifted))return this._isDSTShifted;var e={};if(y(e,this),e=Dt(e),e._a){var t=e._isUTC?h(e._a):Ot(e._a);this._isDSTShifted=this.isValid()&&M(e._a,t.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}function qt(){return!!this.isValid()&&!this._isUTC}function Jt(){return!!this.isValid()&&this._isUTC}function Bt(){return!!this.isValid()&&(this._isUTC&&0===this._offset)}function Qt(e,t){var n,i,s,r=e,o=null;return Lt(e)?r={ms:e._milliseconds,d:e._days,M:e._months}:a(e)?(r={},t?r[t]=e:r.milliseconds=e):(o=er.exec(e))?(n="-"===o[1]?-1:1,r={y:0,d:v(o[ms])*n,h:v(o[_s])*n,m:v(o[ys])*n,s:v(o[ps])*n,ms:v(Rt(1e3*o[gs]))*n}):(o=tr.exec(e))?(n="-"===o[1]?-1:1,r={y:Xt(o[2],n),M:Xt(o[3],n),w:Xt(o[4],n),d:Xt(o[5],n),h:Xt(o[6],n),m:Xt(o[7],n),s:Xt(o[8],n)}):null==r?r={}:"object"===typeof r&&("from"in r||"to"in r)&&(s=en(Ot(r.from),Ot(r.to)),r={},r.ms=s.milliseconds,r.M=s.months),i=new Ct(r),Lt(e)&&l(e,"_locale")&&(i._locale=e._locale),i}function Xt(e,t){var n=e&&parseFloat(e.replace(",","."));return(isNaN(n)?0:n)*t}function Kt(e,t){var n={};return n.months=t.month()-e.month()+12*(t.year()-e.year()),e.clone().add(n.months,"M").isAfter(t)&&--n.months,n.milliseconds=+t-+e.clone().add(n.months,"M"),n}function en(e,t){var n;return e.isValid()&&t.isValid()?(t=Et(t,e),e.isBefore(t)?n=Kt(e,t):(n=Kt(t,e),n.milliseconds=-n.milliseconds,n.months=-n.months),n):{milliseconds:0,months:0}}function tn(e,t){return function(n,i){var s,r;return null===i||isNaN(+i)||(S(t,"moment()."+t+"(period, number) is deprecated. Please use moment()."+t+"(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."),r=n,n=i,i=r),n="string"===typeof n?+n:n,s=Qt(n,i),nn(this,s,e),this}}function nn(e,n,i,s){var r=n._milliseconds,a=Rt(n._days),o=Rt(n._months);e.isValid()&&(s=null==s||s,o&&fe(e,ie(e,"Month")+o*i),a&&se(e,"Date",ie(e,"Date")+a*i),r&&e._d.setTime(e._d.valueOf()+r*i),s&&t.updateOffset(e,a||o))}function sn(e,t){var n=e.diff(t,"days",!0);return n<-6?"sameElse":n<-1?"lastWeek":n<0?"lastDay":n<1?"sameDay":n<2?"nextDay":n<7?"nextWeek":"sameElse"}function rn(e,n){var i=e||Ot(),s=Et(i,this).startOf("day"),r=t.calendarFormat(this,s)||"sameElse",a=n&&(Y(n[r])?n[r].call(this,i):n[r]);return this.format(a||this.localeData().calendar(r,this,Ot(i)))}function an(){return new p(this)}function on(e,t){var n=g(e)?e:Ot(e);return!(!this.isValid()||!n.isValid())&&(t=F(t)||"millisecond","millisecond"===t?this.valueOf()>n.valueOf():n.valueOf()9999?I(n,t?"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYYYY-MM-DD[T]HH:mm:ss.SSSZ"):Y(Date.prototype.toISOString)?t?this.toDate().toISOString():new Date(this.valueOf()+60*this.utcOffset()*1e3).toISOString().replace("Z",I(n,"Z")):I(n,t?"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYY-MM-DD[T]HH:mm:ss.SSSZ")}function pn(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var e="moment",t="";this.isLocal()||(e=0===this.utcOffset()?"moment.utc":"moment.parseZone",t="Z");var n="["+e+'("]',i=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY",s=t+'[")]';return this.format(n+i+"-MM-DD[T]HH:mm:ss.SSS"+s)}function gn(e){e||(e=this.isUtc()?t.defaultFormatUtc:t.defaultFormat);var n=I(this,e);return this.localeData().postformat(n)}function wn(e,t){return this.isValid()&&(g(e)&&e.isValid()||Ot(e).isValid())?Qt({to:this,from:e}).locale(this.locale()).humanize(!t):this.localeData().invalidDate()}function vn(e){return this.from(Ot(),e)}function Mn(e,t){return this.isValid()&&(g(e)&&e.isValid()||Ot(e).isValid())?Qt({from:this,to:e}).locale(this.locale()).humanize(!t):this.localeData().invalidDate()}function kn(e){return this.to(Ot(),e)}function Dn(e){var t;return void 0===e?this._locale._abbr:(t=it(e),null!=t&&(this._locale=t),this)}function Sn(){return this._locale}function Yn(e,t){return(e%t+t)%t}function On(e,t,n){return e<100&&e>=0?new Date(e+400,t,n)-ur:new Date(e,t,n).valueOf()}function Tn(e,t,n){return e<100&&e>=0?Date.UTC(e+400,t,n)-ur:Date.UTC(e,t,n)}function bn(e){var n;if(void 0===(e=F(e))||"millisecond"===e||!this.isValid())return this;var i=this._isUTC?Tn:On;switch(e){case"year":n=i(this.year(),0,1);break;case"quarter":n=i(this.year(),this.month()-this.month()%3,1);break;case"month":n=i(this.year(),this.month(),1);break;case"week":n=i(this.year(),this.month(),this.date()-this.weekday());break;case"isoWeek":n=i(this.year(),this.month(),this.date()-(this.isoWeekday()-1));break;case"day":case"date":n=i(this.year(),this.month(),this.date());break;case"hour":n=this._d.valueOf(),n-=Yn(n+(this._isUTC?0:this.utcOffset()*ar),or);break;case"minute":n=this._d.valueOf(),n-=Yn(n,ar);break;case"second":n=this._d.valueOf(),n-=Yn(n,rr)}return this._d.setTime(n),t.updateOffset(this,!0),this}function xn(e){var n;if(void 0===(e=F(e))||"millisecond"===e||!this.isValid())return this;var i=this._isUTC?Tn:On;switch(e){case"year":n=i(this.year()+1,0,1)-1;break;case"quarter":n=i(this.year(),this.month()-this.month()%3+3,1)-1;break;case"month":n=i(this.year(),this.month()+1,1)-1;break;case"week":n=i(this.year(),this.month(),this.date()-this.weekday()+7)-1;break;case"isoWeek":n=i(this.year(),this.month(),this.date()-(this.isoWeekday()-1)+7)-1;break;case"day":case"date":n=i(this.year(),this.month(),this.date()+1)-1;break;case"hour":n=this._d.valueOf(),n+=or-Yn(n+(this._isUTC?0:this.utcOffset()*ar),or)-1;break;case"minute":n=this._d.valueOf(),n+=ar-Yn(n,ar)-1;break;case"second":n=this._d.valueOf(),n+=rr-Yn(n,rr)-1}return this._d.setTime(n),t.updateOffset(this,!0),this}function Pn(){return this._d.valueOf()-6e4*(this._offset||0)}function Wn(){return Math.floor(this.valueOf()/1e3)}function Hn(){return new Date(this.valueOf())}function Cn(){var e=this;return[e.year(),e.month(),e.date(),e.hour(),e.minute(),e.second(),e.millisecond()]}function Ln(){var e=this;return{years:e.year(),months:e.month(),date:e.date(),hours:e.hours(),minutes:e.minutes(),seconds:e.seconds(),milliseconds:e.milliseconds()}}function Rn(){return this.isValid()?this.toISOString():null}function Fn(){return m(this)}function Un(){return d({},f(this))}function En(){return f(this).overflow}function Nn(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}}function Gn(e,t){V(0,[e,e.length],0,t)}function Vn(e){return zn.call(this,e,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)}function jn(e){return zn.call(this,e,this.isoWeek(),this.isoWeekday(),1,4)}function An(){return Se(this.year(),1,4)}function In(){var e=this.localeData()._week;return Se(this.year(),e.dow,e.doy)}function zn(e,t,n,i,s){var r;return null==e?De(this,i,s).year:(r=Se(e,i,s),t>r&&(t=r),Zn.call(this,e,t,n,i,s))}function Zn(e,t,n,i,s){var r=ke(e,t,n,i,s),a=ve(r.year,0,r.dayOfYear);return this.year(a.getUTCFullYear()),this.month(a.getUTCMonth()),this.date(a.getUTCDate()),this}function $n(e){return null==e?Math.ceil((this.month()+1)/3):this.month(3*(e-1)+this.month()%3)}function qn(e){var t=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==e?t:this.add(e-t,"d")}function Jn(e,t){t[gs]=v(1e3*("0."+e))}function Bn(){return this._isUTC?"UTC":""}function Qn(){return this._isUTC?"Coordinated Universal Time":""}function Xn(e){return Ot(1e3*e)}function Kn(){return Ot.apply(null,arguments).parseZone()}function ei(e){return e}function ti(e,t,n,i){var s=it(),r=h().set(i,t);return s[n](r,e)}function ni(e,t,n){if(a(e)&&(t=e,e=void 0),e=e||"",null!=t)return ti(e,t,n,"month");var i,s=[];for(i=0;i<12;i++)s[i]=ti(e,i,n,"month");return s}function ii(e,t,n,i){"boolean"===typeof e?(a(t)&&(n=t,t=void 0),t=t||""):(t=e,n=t,e=!1,a(t)&&(n=t,t=void 0),t=t||"");var s=it(),r=e?s._week.dow:0;if(null!=n)return ti(t,(n+r)%7,i,"day");var o,u=[];for(o=0;o<7;o++)u[o]=ti(t,(o+r)%7,i,"day");return u}function si(e,t){return ni(e,t,"months")}function ri(e,t){return ni(e,t,"monthsShort")}function ai(e,t,n){return ii(e,t,n,"weekdays")}function oi(e,t,n){return ii(e,t,n,"weekdaysShort")}function ui(e,t,n){return ii(e,t,n,"weekdaysMin")}function li(){var e=this._data;return this._milliseconds=yr(this._milliseconds),this._days=yr(this._days),this._months=yr(this._months),e.milliseconds=yr(e.milliseconds),e.seconds=yr(e.seconds),e.minutes=yr(e.minutes),e.hours=yr(e.hours),e.months=yr(e.months),e.years=yr(e.years),this}function di(e,t,n,i){var s=Qt(t,n);return e._milliseconds+=i*s._milliseconds,e._days+=i*s._days,e._months+=i*s._months,e._bubble()}function hi(e,t){return di(this,e,t,1)}function ci(e,t){return di(this,e,t,-1)}function fi(e){return e<0?Math.floor(e):Math.ceil(e)}function mi(){var e,t,n,i,s,r=this._milliseconds,a=this._days,o=this._months,u=this._data;return r>=0&&a>=0&&o>=0||r<=0&&a<=0&&o<=0||(r+=864e5*fi(yi(o)+a),a=0,o=0),u.milliseconds=r%1e3,e=w(r/1e3),u.seconds=e%60,t=w(e/60),u.minutes=t%60,n=w(t/60),u.hours=n%24,a+=w(n/24),s=w(_i(a)),o+=s,a-=fi(yi(s)),i=w(o/12),o%=12,u.days=a,u.months=o,u.years=i,this}function _i(e){return 4800*e/146097}function yi(e){return 146097*e/4800}function pi(e){if(!this.isValid())return NaN;var t,n,i=this._milliseconds;if("month"===(e=F(e))||"quarter"===e||"year"===e)switch(t=this._days+i/864e5,n=this._months+_i(t),e){case"month":return n;case"quarter":return n/3;case"year":return n/12}else switch(t=this._days+Math.round(yi(this._months)),e){case"week":return t/7+i/6048e5;case"day":return t+i/864e5;case"hour":return 24*t+i/36e5;case"minute":return 1440*t+i/6e4;case"second":return 86400*t+i/1e3;case"millisecond":return Math.floor(864e5*t)+i;default:throw new Error("Unknown unit "+e)}}function gi(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*v(this._months/12):NaN}function wi(e){return function(){return this.as(e)}}function vi(){return Qt(this)}function Mi(e){return e=F(e),this.isValid()?this[e+"s"]():NaN}function ki(e){return function(){return this.isValid()?this._data[e]:NaN}}function Di(){return w(this.days()/7)}function Si(e,t,n,i,s){return s.relativeTime(t||1,!!n,e,i)}function Yi(e,t,n){var i=Qt(e).abs(),s=Cr(i.as("s")),r=Cr(i.as("m")),a=Cr(i.as("h")),o=Cr(i.as("d")),u=Cr(i.as("M")),l=Cr(i.as("y")),d=s<=Lr.ss&&["s",s]||s0,d[4]=n,Si.apply(null,d)}function Oi(e){return void 0===e?Cr:"function"===typeof e&&(Cr=e,!0)}function Ti(e,t){return void 0!==Lr[e]&&(void 0===t?Lr[e]:(Lr[e]=t,"s"===e&&(Lr.ss=t-1),!0))}function bi(e){if(!this.isValid())return this.localeData().invalidDate();var t=this.localeData(),n=Yi(this,!e,t);return e&&(n=t.pastFuture(+this,n)),t.postformat(n)}function xi(e){return(e>0)-(e<0)||+e}function Pi(){if(!this.isValid())return this.localeData().invalidDate();var e,t,n,i=Rr(this._milliseconds)/1e3,s=Rr(this._days),r=Rr(this._months);e=w(i/60),t=w(e/60),i%=60,e%=60,n=w(r/12),r%=12;var a=n,o=r,u=s,l=t,d=e,h=i?i.toFixed(3).replace(/\.?0+$/,""):"",c=this.asSeconds();if(!c)return"P0D";var f=c<0?"-":"",m=xi(this._months)!==xi(c)?"-":"",_=xi(this._days)!==xi(c)?"-":"",y=xi(this._milliseconds)!==xi(c)?"-":"";return f+"P"+(a?m+a+"Y":"")+(o?m+o+"M":"")+(u?_+u+"D":"")+(l||d||h?"T":"")+(l?y+l+"H":"")+(d?y+d+"M":"")+(h?y+h+"S":"")}var Wi,Hi;Hi=Array.prototype.some?Array.prototype.some:function(e){for(var t=Object(this),n=t.length>>>0,i=0;i68?1900:2e3)};var Ms,ks=ne("FullYear",!0);Ms=Array.prototype.indexOf?Array.prototype.indexOf:function(e){var t;for(t=0;tthis?this:e:_()}),Qs=function(){return Date.now?Date.now():+new Date},Xs=["year","quarter","month","week","day","hour","minute","second","millisecond"];Ft("Z",":"),Ft("ZZ",""),Z("Z",os),Z("ZZ",os),B(["Z","ZZ"],function(e,t,n){n._useUTC=!0,n._tzm=Ut(os,e)});var Ks=/([\+\-]|\d\d)/gi;t.updateOffset=function(){};var er=/^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/,tr=/^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;Qt.fn=Ct.prototype,Qt.invalid=Ht;var nr=tn(1,"add"),ir=tn(-1,"subtract");t.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",t.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var sr=D("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(e){return void 0===e?this.localeData():this.locale(e)}),rr=1e3,ar=60*rr,or=60*ar,ur=3506328*or;V(0,["gg",2],0,function(){return this.weekYear()%100}),V(0,["GG",2],0,function(){return this.isoWeekYear()%100}),Gn("gggg","weekYear"),Gn("ggggg","weekYear"),Gn("GGGG","isoWeekYear"),Gn("GGGGG","isoWeekYear"),R("weekYear","gg"),R("isoWeekYear","GG"),E("weekYear",1),E("isoWeekYear",1),Z("G",rs),Z("g",rs),Z("GG",Xi,qi),Z("gg",Xi,qi),Z("GGGG",ns,Bi),Z("gggg",ns,Bi),Z("GGGGG",is,Qi),Z("ggggg",is,Qi),Q(["gggg","ggggg","GGGG","GGGGG"],function(e,t,n,i){t[i.substr(0,2)]=v(e)}),Q(["gg","GG"],function(e,n,i,s){n[s]=t.parseTwoDigitYear(e)}),V("Q",0,"Qo","quarter"),R("quarter","Q"),E("quarter",7),Z("Q",$i),B("Q",function(e,t){t[fs]=3*(v(e)-1)}),V("D",["DD",2],"Do","date"),R("date","D"),E("date",9),Z("D",Xi),Z("DD",Xi,qi),Z("Do",function(e,t){return e?t._dayOfMonthOrdinalParse||t._ordinalParse:t._dayOfMonthOrdinalParseLenient}),B(["D","DD"],ms),B("Do",function(e,t){t[ms]=v(e.match(Xi)[0])});var lr=ne("Date",!0);V("DDD",["DDDD",3],"DDDo","dayOfYear"),R("dayOfYear","DDD"),E("dayOfYear",4),Z("DDD",ts),Z("DDDD",Ji),B(["DDD","DDDD"],function(e,t,n){n._dayOfYear=v(e)}),V("m",["mm",2],0,"minute"),R("minute","m"),E("minute",14),Z("m",Xi),Z("mm",Xi,qi),B(["m","mm"],ys);var dr=ne("Minutes",!1);V("s",["ss",2],0,"second"),R("second","s"),E("second",15),Z("s",Xi),Z("ss",Xi,qi),B(["s","ss"],ps);var hr=ne("Seconds",!1);V("S",0,0,function(){return~~(this.millisecond()/100)}),V(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),V(0,["SSS",3],0,"millisecond"),V(0,["SSSS",4],0,function(){return 10*this.millisecond()}),V(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),V(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),V(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),V(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),V(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),R("millisecond","ms"),E("millisecond",16),Z("S",ts,$i),Z("SS",ts,qi),Z("SSS",ts,Ji);var cr;for(cr="SSSS";cr.length<=9;cr+="S")Z(cr,ss);for(cr="S";cr.length<=9;cr+="S")B(cr,Jn);var fr=ne("Milliseconds",!1);V("z",0,0,"zoneAbbr"),V("zz",0,0,"zoneName");var mr=p.prototype;mr.add=nr,mr.calendar=rn,mr.clone=an,mr.diff=fn,mr.endOf=xn,mr.format=gn,mr.from=wn,mr.fromNow=vn,mr.to=Mn,mr.toNow=kn,mr.get=re,mr.invalidAt=En,mr.isAfter=on,mr.isBefore=un,mr.isBetween=ln,mr.isSame=dn,mr.isSameOrAfter=hn,mr.isSameOrBefore=cn,mr.isValid=Fn,mr.lang=sr,mr.locale=Dn,mr.localeData=Sn,mr.max=Bs,mr.min=Js,mr.parsingFlags=Un,mr.set=ae,mr.startOf=bn,mr.subtract=ir,mr.toArray=Cn,mr.toObject=Ln,mr.toDate=Hn,mr.toISOString=yn,mr.inspect=pn,mr.toJSON=Rn,mr.toString=_n,mr.unix=Wn,mr.valueOf=Pn,mr.creationData=Nn,mr.year=ks,mr.isLeapYear=te,mr.weekYear=Vn,mr.isoWeekYear=jn,mr.quarter=mr.quarters=$n,mr.month=me,mr.daysInMonth=_e,mr.week=mr.weeks=be,mr.isoWeek=mr.isoWeeks=xe,mr.weeksInYear=In,mr.isoWeeksInYear=An,mr.date=lr,mr.day=mr.days=Ee,mr.weekday=Ne,mr.isoWeekday=Ge,mr.dayOfYear=qn,mr.hour=mr.hours=Us,mr.minute=mr.minutes=dr,mr.second=mr.seconds=hr,mr.millisecond=mr.milliseconds=fr,mr.utcOffset=Gt,mr.utc=jt,mr.local=At,mr.parseZone=It,mr.hasAlignedHourOffset=zt,mr.isDST=Zt,mr.isLocal=qt,mr.isUtcOffset=Jt,mr.isUtc=Bt,mr.isUTC=Bt,mr.zoneAbbr=Bn,mr.zoneName=Qn,mr.dates=D("dates accessor is deprecated. Use date instead.",lr),mr.months=D("months accessor is deprecated. Use month instead",me),mr.years=D("years accessor is deprecated. Use year instead",ks),mr.zone=D("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",Vt),mr.isDSTShifted=D("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",$t);var _r=b.prototype;_r.calendar=x,_r.longDateFormat=P,_r.invalidDate=W,_r.ordinal=H,_r.preparse=ei,_r.postformat=ei,_r.relativeTime=C,_r.pastFuture=L,_r.set=O,_r.months=le,_r.monthsShort=de,_r.monthsParse=ce,_r.monthsRegex=pe,_r.monthsShortRegex=ye,_r.week=Ye,_r.firstDayOfYear=Te,_r.firstDayOfWeek=Oe,_r.weekdays=Ce,_r.weekdaysMin=Re,_r.weekdaysShort=Le,_r.weekdaysParse=Ue,_r.weekdaysRegex=Ve,_r.weekdaysShortRegex=je,_r.weekdaysMinRegex=Ae,_r.isPM=Je,_r.meridiem=Be,et("en",{dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(e){var t=e%10;return e+(1===v(e%100/10)?"th":1===t?"st":2===t?"nd":3===t?"rd":"th")}}),t.lang=D("moment.lang is deprecated. Use moment.locale instead.",et),t.langData=D("moment.langData is deprecated. Use moment.localeData instead.",it);var yr=Math.abs,pr=wi("ms"),gr=wi("s"),wr=wi("m"),vr=wi("h"),Mr=wi("d"),kr=wi("w"),Dr=wi("M"),Sr=wi("Q"),Yr=wi("y"),Or=ki("milliseconds"),Tr=ki("seconds"),br=ki("minutes"),xr=ki("hours"),Pr=ki("days"),Wr=ki("months"),Hr=ki("years"),Cr=Math.round,Lr={ss:44,s:45,m:45,h:22,d:26,M:11},Rr=Math.abs,Fr=Ct.prototype;return Fr.isValid=Wt,Fr.abs=li,Fr.add=hi,Fr.subtract=ci,Fr.as=pi,Fr.asMilliseconds=pr,Fr.asSeconds=gr,Fr.asMinutes=wr,Fr.asHours=vr,Fr.asDays=Mr,Fr.asWeeks=kr,Fr.asMonths=Dr,Fr.asQuarters=Sr,Fr.asYears=Yr,Fr.valueOf=gi,Fr._bubble=mi,Fr.clone=vi,Fr.get=Mi,Fr.milliseconds=Or,Fr.seconds=Tr,Fr.minutes=br,Fr.hours=xr,Fr.days=Pr,Fr.weeks=Di,Fr.months=Wr,Fr.years=Hr,Fr.humanize=bi,Fr.toISOString=Pi,Fr.toString=Pi,Fr.toJSON=Pi,Fr.locale=Dn,Fr.localeData=Sn,Fr.toIsoString=D("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",Pi),Fr.lang=sr,V("X",0,0,"unix"),V("x",0,0,"valueOf"),Z("x",rs),Z("X",us),B("X",function(e,t,n){n._d=new Date(1e3*parseFloat(e,10))}),B("x",function(e,t,n){n._d=new Date(v(e))}),t.version="2.24.0",function(e){Wi=e}(Ot),t.fn=mr,t.min=bt,t.max=xt,t.now=Qs,t.utc=h,t.unix=Xn,t.months=si,t.isDate=o,t.locale=et,t.invalid=_,t.duration=Qt,t.isMoment=g,t.weekdays=ai,t.parseZone=Kn,t.localeData=it,t.isDuration=Lt,t.monthsShort=ri,t.weekdaysMin=ui,t.defineLocale=tt,t.updateLocale=nt,t.locales=st,t.weekdaysShort=oi,t.normalizeUnits=F,t.relativeTimeRounding=Oi,t.relativeTimeThreshold=Ti,t.calendarFormat=sn,t.prototype=mr,t.HTML5_FMT={DATETIME_LOCAL:"YYYY-MM-DDTHH:mm",DATETIME_LOCAL_SECONDS:"YYYY-MM-DDTHH:mm:ss",DATETIME_LOCAL_MS:"YYYY-MM-DDTHH:mm:ss.SSS",DATE:"YYYY-MM-DD",TIME:"HH:mm",TIME_SECONDS:"HH:mm:ss",TIME_MS:"HH:mm:ss.SSS",WEEK:"GGGG-[W]WW",MONTH:"YYYY-MM"},t})}).call(t,n(586)(e))},584:function(e,t,n){"use strict";t.a={WHT:function(e){return(e/75).toExponential(2)+"rem"}}},585:function(e,t,n){!function(e,t){t(n(574))}(0,function(e){"use strict";return e.defineLocale("zh-cn",{months:"\u4e00\u6708_\u4e8c\u6708_\u4e09\u6708_\u56db\u6708_\u4e94\u6708_\u516d\u6708_\u4e03\u6708_\u516b\u6708_\u4e5d\u6708_\u5341\u6708_\u5341\u4e00\u6708_\u5341\u4e8c\u6708".split("_"),monthsShort:"1\u6708_2\u6708_3\u6708_4\u6708_5\u6708_6\u6708_7\u6708_8\u6708_9\u6708_10\u6708_11\u6708_12\u6708".split("_"),weekdays:"\u661f\u671f\u65e5_\u661f\u671f\u4e00_\u661f\u671f\u4e8c_\u661f\u671f\u4e09_\u661f\u671f\u56db_\u661f\u671f\u4e94_\u661f\u671f\u516d".split("_"),weekdaysShort:"\u5468\u65e5_\u5468\u4e00_\u5468\u4e8c_\u5468\u4e09_\u5468\u56db_\u5468\u4e94_\u5468\u516d".split("_"),weekdaysMin:"\u65e5_\u4e00_\u4e8c_\u4e09_\u56db_\u4e94_\u516d".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"YYYY/MM/DD",LL:"YYYY\u5e74M\u6708D\u65e5",LLL:"YYYY\u5e74M\u6708D\u65e5Ah\u70b9mm\u5206",LLLL:"YYYY\u5e74M\u6708D\u65e5ddddAh\u70b9mm\u5206",l:"YYYY/M/D",ll:"YYYY\u5e74M\u6708D\u65e5",lll:"YYYY\u5e74M\u6708D\u65e5 HH:mm",llll:"YYYY\u5e74M\u6708D\u65e5dddd HH:mm"},meridiemParse:/\u51cc\u6668|\u65e9\u4e0a|\u4e0a\u5348|\u4e2d\u5348|\u4e0b\u5348|\u665a\u4e0a/,meridiemHour:function(e,t){return 12===e&&(e=0),"\u51cc\u6668"===t||"\u65e9\u4e0a"===t||"\u4e0a\u5348"===t?e:"\u4e0b\u5348"===t||"\u665a\u4e0a"===t?e+12:e>=11?e:e+12},meridiem:function(e,t,n){var i=100*e+t;return i<600?"\u51cc\u6668":i<900?"\u65e9\u4e0a":i<1130?"\u4e0a\u5348":i<1230?"\u4e2d\u5348":i<1800?"\u4e0b\u5348":"\u665a\u4e0a"},calendar:{sameDay:"[\u4eca\u5929]LT",nextDay:"[\u660e\u5929]LT",nextWeek:"[\u4e0b]ddddLT",lastDay:"[\u6628\u5929]LT",lastWeek:"[\u4e0a]ddddLT",sameElse:"L"},dayOfMonthOrdinalParse:/\d{1,2}(\u65e5|\u6708|\u5468)/,ordinal:function(e,t){switch(t){case"d":case"D":case"DDD":return e+"\u65e5";case"M":return e+"\u6708";case"w":case"W":return e+"\u5468";default:return e}},relativeTime:{future:"%s\u5185",past:"%s\u524d",s:"\u51e0\u79d2",ss:"%d \u79d2",m:"1 \u5206\u949f",mm:"%d \u5206\u949f",h:"1 \u5c0f\u65f6",hh:"%d \u5c0f\u65f6",d:"1 \u5929",dd:"%d \u5929",M:"1 \u4e2a\u6708",MM:"%d \u4e2a\u6708",y:"1 \u5e74",yy:"%d \u5e74"},week:{dow:1,doy:4}})})},586:function(e,t){e.exports=function(e){return e.webpackPolyfill||(e.deprecate=function(){},e.paths=[],e.children||(e.children=[]),Object.defineProperty(e,"loaded",{enumerable:!0,get:function(){return e.l}}),Object.defineProperty(e,"id",{enumerable:!0,get:function(){return e.i}}),e.webpackPolyfill=1),e}}});
2 | //# sourceMappingURL=6.a18169a3.chunk.js.map
--------------------------------------------------------------------------------
/build/static/media/SourceHanSansCN-Light.424662ea.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/etwallet/eosrex/f017e24986f36c920fb1184944fe82657136629d/build/static/media/SourceHanSansCN-Light.424662ea.otf
--------------------------------------------------------------------------------
/config-overrides.js:
--------------------------------------------------------------------------------
1 | const { injectBabelPlugin, getLoader } = require('react-app-rewired');
2 | const fileLoaderMatcher = function (rule) {
3 | return rule.loader && rule.loader.indexOf(`file-loader`) != -1;
4 | }
5 |
6 | module.exports = function override(config, env) {
7 | // babel-plugin-import
8 | config = injectBabelPlugin(['import', {
9 | libraryName: 'antd-mobile',
10 | //style: 'css',
11 | style: true, // use less for customized theme
12 | }], config);
13 |
14 | // customize theme
15 | config.module.rules[1].oneOf.unshift(
16 | {
17 | test: /\.less$/,
18 | use: [
19 | require.resolve('style-loader'),
20 | require.resolve('css-loader'),
21 | {
22 | loader: require.resolve('postcss-loader'),
23 | options: {
24 | // Necessary for external CSS imports to work
25 | // https://github.com/facebookincubator/create-react-app/issues/2677
26 | ident: 'postcss',
27 | plugins: () => [
28 | require('postcss-flexbugs-fixes'),
29 | autoprefixer({
30 | browsers: [
31 | '>1%',
32 | 'last 4 versions',
33 | 'Firefox ESR',
34 | 'not ie < 9', // React doesn't support IE8 anyway
35 | ],
36 | flexbox: 'no-2009',
37 | }),
38 | ],
39 | },
40 | },
41 | {
42 | loader: require.resolve('less-loader'),
43 | options: {
44 | // theme vars, also can use theme.js instead of this.
45 | modifyVars: {
46 | "@hd": "1px", // 基本单位
47 |
48 | "@font-family":"SourceHanSansCN-Light,SourceHanSansCN-Medium,SourceHanSansCN-Regular",
49 |
50 | // 文字色
51 | "@color-text-base":"#323232", // 基本
52 | "@color-text-base-inverse":"#FFFFFF", // 基本 - 反色
53 | "@color-text-secondary": "#a4a9b0", // 辅助色
54 | "@color-text-placeholder": "#bbb", // 文本框提示
55 | "@color-text-disabled": "#bbb", // 失效
56 | "@color-text-caption": "#888", // 辅助描述
57 | "@color-text-paragraph": "#333", // 段落
58 | "@color-link": "@brand-primary", // 链接
59 |
60 | // 背景色
61 | "@fill-base": "#FFFFFF", // 组件默认背景
62 | "@fill-body": "#F8F8F8", // 页面背景
63 | "@fill-tap": "#ddd", // 组件默认背景 - 按下
64 | "@fill-disabled": "#ddd", // 通用失效背景
65 | "@fill-mask": "rgba(0, 0, 0, 0.4)", // 遮罩背景
66 | "@color-icon-base": "#ccc", // 许多小图标的背景,比如一些小圆点,加减号
67 | "@fill-grey": "#f7f7f7",
68 |
69 | // 透明度
70 | "@opacity-disabled": "0.3", // switch checkbox radio 等组件禁用的透明度
71 |
72 | // 全局/品牌色
73 | "@brand-primary": "#108EE9",
74 | "@brand-primary-tap": "#0e80d2",
75 | "@brand-success": "#6abf47",
76 | "@brand-warning": "#ffc600",
77 | "@brand-error": "#f4333c",
78 | "@brand-important": "#ff5b05", // 用于小红点
79 | "@brand-wait": "#108EE9",
80 |
81 | "@border-color-base":"#F4F4F4", // 边框色
82 |
83 | // 字体尺寸
84 | "@font-size-icontext": "10 * @hd",
85 | "@font-size-caption-sm": "12 * @hd",
86 | "@font-size-base": "14 * @hd",
87 | "@font-size-subhead": "15 * @hd",
88 | "@font-size-caption": "16 * @hd",
89 | "@font-size-heading": "17 * @hd",
90 |
91 | // 圆角
92 | "@radius-xs": "2 * @hd",
93 | "@radius-sm": "3 * @hd",
94 | "@radius-md": "5 * @hd",
95 | "@radius-lg": "7 * @hd",
96 | "@radius-circle": "50%",
97 |
98 | // 边框尺寸
99 | "@border-width-sm": "1PX",
100 | "@border-width-md": "1PX",
101 | "@border-width-lg": "2 * @hd",
102 |
103 | // 水平间距
104 | "@h-spacing-sm": "5 * @hd",
105 | "@h-spacing-md": "8 * @hd",
106 | "@h-spacing-lg": "15 * @hd",
107 |
108 | // 垂直间距
109 | "@v-spacing-xs": "3 * @hd",
110 | "@v-spacing-sm": "6 * @hd",
111 | "@v-spacing-md": "9 * @hd",
112 | "@v-spacing-lg": "15 * @hd",
113 | "@v-spacing-xl": "21 * @hd",
114 |
115 | // 高度
116 | "@line-height-base": "1", // 单行行高
117 | "@line-height-paragraph": "1.5", // 多行行高
118 |
119 | // 图标尺寸 导航条上的图标、grid的图标大小
120 | "@icon-size-xxs": "15 * @hd",
121 | "@icon-size-xs": "18 * @hd",
122 | "@icon-size-sm": "21 * @hd",
123 | "@icon-size-md": "22 * @hd",
124 | "@icon-size-lg": "32 * @hd",
125 |
126 | // 动画缓动
127 | "@ease-in-out-quint": "cubic-bezier(.86, 0, .07, 1)",
128 |
129 | // 组件变量
130 | "@actionsheet-item-height": "50 * @hd",
131 | "@actionsheet-item-font-size": "18 * @hd",
132 |
133 | // button
134 | "@button-height":" 47 * @hd",
135 | "@button-font-size":" 18 * @hd",
136 |
137 | "@button-height-sm":" 30 * @hd",
138 | "@button-font-size-sm":" 13 * @hd",
139 |
140 | "@primary-button-fill":" @brand-primary",
141 | "@primary-button-fill-tap":" @brand-primary-tap",
142 |
143 | "@ghost-button-color":" @brand-primary", // 同时应用于背景、文字颜色、边框色
144 | "@ghost-button-fill-tap":" fade(@brand-primary, 60%)",
145 |
146 | "@warning-button-fill":" #e94f4f",
147 | "@warning-button-fill-tap":" #d24747",
148 |
149 | "@link-button-fill-tap":" #ddd",
150 | "@link-button-font-size":" 16 * @hd",
151 |
152 | // menu
153 | "@menu-multi-select-btns-height":" @button-height",
154 |
155 | // modal
156 | "@modal-font-size-heading": "14 * @hd",
157 | "@modal-button-font-size": "14 * @hd", // 按钮字号
158 | "@modal-button-height": "42 * @hd", // 按钮高度
159 |
160 | // list
161 | "@list-title-height":" 30 * @hd",
162 | "@list-item-height-sm":" 35 * @hd",
163 | "@list-item-height":" 40 * @hd",
164 |
165 | // input
166 | "@input-label-width": "15 * @hd", // InputItem、TextareaItem 文字长度基础值
167 | "@input-font-size": "15 * @hd",
168 | "@input-color-icon":" #ccc", // input clear icon 的背景色
169 | "@input-color-icon-tap":" @brand-primary",
170 |
171 | // tabs
172 | "@tabs-color": "#108EE9",
173 | "@tabs-height": "auto",
174 | "@tabs-font-size-heading": "20 * @hd",
175 | "@tabs-ink-bar-height": "5 * @hd",
176 |
177 | // segmented-control
178 | "@segmented-control-color":" @brand-primary", // 同时应用于背景、文字颜色、边框色
179 | "@segmented-control-height":" 27 * @hd",
180 | "@segmented-control-fill-tap":" fade(@brand-primary, 0.1)",
181 |
182 | // tab-bar
183 | "@tab-bar-fill":" #ebeeef",
184 | "@tab-bar-height":" 50 * @hd",
185 |
186 | // toast
187 | "@toast-fill":" rgba(58, 58, 58, 0.9)", // toast, activity-indicator 的背景颜色
188 |
189 | // search-bar
190 | "@search-bar-fill":" #efeff4",
191 | "@search-bar-height":" 44 * @hd",
192 | "@search-bar-input-height":" 28 * @hd",
193 | "@search-bar-font-size":" 15 * @hd",
194 | "@search-color-icon":" #bbb", // input search icon 的背景色
195 |
196 | // notice-bar
197 | "@notice-bar-fill":" #fefcec",
198 | "@notice-bar-height":" 36 * @hd",
199 | "@notice-bar-color":" #f76a24",
200 |
201 | // switch
202 | "@switch-fill":" #4dd865",
203 | "@switch-fill-android":" @brand-primary",
204 |
205 | // tag
206 | "@tag-height":" 25 * @hd",
207 | "@tag-height-sm":" 15 * @hd",
208 | "@tag-color":" @brand-primary",
209 |
210 | // keyboard
211 | "@keyboard-confirm-color":" @brand-primary",
212 | "@keyboard-confirm-tap-color":" @brand-primary-tap",
213 |
214 | // picker
215 | "@option-height":" 42 * @hd", // picker 标题的高度
216 |
217 | // z-index
218 | "@progress-zindex":" 2000",
219 | "@popover-zindex":" 1999",
220 | "@toast-zindex":" 1999",
221 | "@action-sheet-zindex":" 1000", // actonsheet 会放到 popup / modal 中
222 | "@picker-zindex":" 1000",
223 | "@popup-zindex":" 999",
224 | "@modal-zindex":" 999", // modal.alert 应该最大,其他应该较小
225 | "@tabs-pagination-zindex":" 999"
226 |
227 | },
228 | },
229 | },
230 | ]
231 | }
232 | );
233 |
234 | // css-modules
235 | config.module.rules[1].oneOf.unshift(
236 | {
237 | test: /\.css$/,
238 | exclude: /node_modules|antd-mobile\.css/,
239 | use: [
240 | require.resolve('style-loader'),
241 | {
242 | loader: require.resolve('css-loader'),
243 | options: {
244 | modules: true,
245 | importLoaders: 1,
246 | localIdentName: '[local]___[hash:base64:5]'
247 | },
248 | },
249 | {
250 | loader: require.resolve('postcss-loader'),
251 | options: {
252 | // Necessary for external CSS imports to work
253 | // https://github.com/facebookincubator/create-react-app/issues/2677
254 | ident: 'postcss',
255 | plugins: () => [
256 | require('postcss-flexbugs-fixes'),
257 | autoprefixer({
258 | browsers: [
259 | '>1%',
260 | 'last 4 versions',
261 | 'Firefox ESR',
262 | 'not ie < 9', // React doesn't support IE8 anyway
263 | ],
264 | flexbox: 'no-2009',
265 | }),
266 | ],
267 | },
268 | },
269 | ]
270 | }
271 | );
272 |
273 | // module: {
274 | // rules: [
275 | // {
276 | // test: /\.js$/,
277 | // use: {
278 | // loader: 'babel-loader',
279 | // options: {
280 | // presets: [
281 | // ['env',{
282 | // targets: {
283 | // browsers: ['> 1%', 'last 2 versions']
284 | // }
285 | // }]
286 | // ]
287 | // }
288 | // },
289 | // exclude: '/node_modules/'
290 | // }
291 | // ]
292 | // }
293 | // file-loader exclude
294 | let l = getLoader(config.module.rules, fileLoaderMatcher);
295 | l.exclude.push(/\.less$/);
296 |
297 | return config;
298 | };
299 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ETRobot",
3 | "version": "1.0.0",
4 | "private": true,
5 | "dependencies": {
6 | "antd-mobile": "^2.2.6",
7 | "copy-to-clipboard": "^3.0.5",
8 | "dva": "^2.4.0",
9 | "dva-loading": "^2.0.5",
10 | "events": "^3.0.0",
11 | "intl": "^1.2.5",
12 | "moment": "^2.24.0",
13 | "react": "^15.6.1",
14 | "react-dev-utils": "^8.0.0",
15 | "react-dom": "^15.6.1",
16 | "react-intl": "^2.7.2",
17 | "react-moment": "^0.8.4",
18 | "react-native-keyboard-aware-scroll-view": "^0.8.0",
19 | "react-scripts": "1.0.13",
20 | "storejs": "^1.0.20"
21 | },
22 | "scripts": {
23 | "start": "react-app-rewired start",
24 | "build": "react-app-rewired build",
25 | "test": "react-app-rewired test --env=jsdom",
26 | "eject": "react-scripts eject"
27 | },
28 | "devDependencies": {
29 | "babel-core": "^6.26.3",
30 | "babel-loader": "^8.0.4",
31 | "babel-plugin-dva-hmr": "^0.3.2",
32 | "babel-plugin-import": "^1.2.0",
33 | "babel-preset-env": "^1.7.0",
34 | "babel-preset-es2015": "^6.24.1",
35 | "babel-preset-react": "^6.24.1",
36 | "babel-preset-stage-0": "^6.24.1",
37 | "less": "^2.7.3",
38 | "less-loader": "^4.0.5",
39 | "react-app-rewired": "^1.2.9"
40 | },
41 | "theme": {
42 | "primary-color": "#1088ae"
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/etwallet/eosrex/f017e24986f36c920fb1184944fe82657136629d/public/favicon.ico
--------------------------------------------------------------------------------
/public/ff.js:
--------------------------------------------------------------------------------
1 | !function(){var a="@charset \"utf-8\";html{color:#000;background:#fff;overflow-y:scroll;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}html *{outline:0;-webkit-text-size-adjust:none;-webkit-tap-highlight-color:rgba(0,0,0,0)}html,body{font-family:sans-serif}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td,hr,button,article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{margin:0;padding:0}input,select,textarea{font-size:100%}table{border-collapse:collapse;border-spacing:0}fieldset,img{border:0}abbr,acronym{border:0;font-variant:normal}del{text-decoration:line-through}address,caption,cite,code,dfn,em,th,var{font-style:normal;font-weight:500}ol,ul{list-style:none}caption,th{text-align:left}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:500}q:before,q:after{content:''}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}a:hover{text-decoration:underline}ins,a{text-decoration:none}",b=document.createElement("style");if(document.getElementsByTagName("head")[0].appendChild(b),b.styleSheet)b.styleSheet.disabled||(b.styleSheet.cssText=a);else try{b.innerHTML=a}catch(c){b.innerText=a}}();!function(a,b){function c(){var b=f.getBoundingClientRect().width;b/i>540&&(b=540*i);var c=b/10;f.style.fontSize=c+"px",k.rem=a.rem=c}var d,e=a.document,f=e.documentElement,g=e.querySelector('meta[name="viewport"]'),h=e.querySelector('meta[name="flexible"]'),i=0,j=0,k=b.flexible||(b.flexible={});if(g){console.warn("将根据已有的meta标签来设置缩放比例");var l=g.getAttribute("content").match(/initial\-scale=([\d\.]+)/);l&&(j=parseFloat(l[1]),i=parseInt(1/j))}else if(h){var m=h.getAttribute("content");if(m){var n=m.match(/initial\-dpr=([\d\.]+)/),o=m.match(/maximum\-dpr=([\d\.]+)/);n&&(i=parseFloat(n[1]),j=parseFloat((1/i).toFixed(2))),o&&(i=parseFloat(o[1]),j=parseFloat((1/i).toFixed(2)))}}if(!i&&!j){var p=(a.navigator.appVersion.match(/android/gi),a.navigator.appVersion.match(/iphone/gi)),q=a.devicePixelRatio;i=p?q>=3&&(!i||i>=3)?3:q>=2&&(!i||i>=2)?2:1:1,j=1/i}if(f.setAttribute("data-dpr",i),!g)if(g=e.createElement("meta"),g.setAttribute("name","viewport"),g.setAttribute("content","initial-scale="+j+", maximum-scale="+j+", minimum-scale="+j+", user-scalable=no"),f.firstElementChild)f.firstElementChild.appendChild(g);else{var r=e.createElement("div");r.appendChild(g),e.write(r.innerHTML)}a.addEventListener("resize",function(){clearTimeout(d),d=setTimeout(c,300)},!1),a.addEventListener("pageshow",function(a){a.persisted&&(clearTimeout(d),d=setTimeout(c,300))},!1),"complete"===e.readyState?e.body.style.fontSize=12*i+"px":e.addEventListener("DOMContentLoaded",function(){e.body.style.fontSize=12*i+"px"},!1),c(),k.dpr=a.dpr=i,k.refreshRem=c,k.rem2px=function(a){var b=parseFloat(a)*this.rem;return"string"==typeof a&&a.match(/rem$/)&&(b+="px"),b},k.px2rem=function(a){var b=parseFloat(a)/this.rem;return"string"==typeof a&&a.match(/px$/)&&(b+="rem"),b}}(window,window.lib||(window.lib={}));
--------------------------------------------------------------------------------
/public/img/Chevron@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/etwallet/eosrex/f017e24986f36c920fb1184944fe82657136629d/public/img/Chevron@2x.png
--------------------------------------------------------------------------------
/public/img/check.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/etwallet/eosrex/f017e24986f36c920fb1184944fe82657136629d/public/img/check.png
--------------------------------------------------------------------------------
/public/img/check_h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/etwallet/eosrex/f017e24986f36c920fb1184944fe82657136629d/public/img/check_h.png
--------------------------------------------------------------------------------
/public/img/chevron.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/etwallet/eosrex/f017e24986f36c920fb1184944fe82657136629d/public/img/chevron.png
--------------------------------------------------------------------------------
/public/img/eos_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/etwallet/eosrex/f017e24986f36c920fb1184944fe82657136629d/public/img/eos_icon.png
--------------------------------------------------------------------------------
/public/img/help.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/etwallet/eosrex/f017e24986f36c920fb1184944fe82657136629d/public/img/help.png
--------------------------------------------------------------------------------
/public/img/nodevote.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/etwallet/eosrex/f017e24986f36c920fb1184944fe82657136629d/public/img/nodevote.png
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | REX
13 |
14 |
15 |
16 |
17 |
18 |
29 |
30 |
31 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "ETRobot",
3 | "name": "ETRobot",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "192x192",
8 | "type": "image/png"
9 | }
10 | ],
11 | "start_url": "./index.html",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#25242B"
15 | }
16 |
--------------------------------------------------------------------------------
/rex_abi.md:
--------------------------------------------------------------------------------
1 | ## ABI接口
2 | ### 充值
3 | cleos --wallet-url http://localhost:6666 --url http://localhost:8000 push action eosio deposit '["user11111111","100000.0000 EOS"]' -p user11111111
4 |
5 | actions: [{
6 | account: 'eosio',
7 | name: 'deposit',
8 | authorization: [{
9 | actor: 'user11111111',
10 | permission: 'active',
11 | }],
12 | data: {
13 | owner: 'useraaaaaaaa',
14 | amount: '100000.0000 EOS',
15 | },
16 | }]
17 |
18 | ### 提现
19 | cleos --wallet-url http://localhost:6666 --url http://localhost:8000 push action eosio withdraw '["user22222222","50000.0000 EOS"]' -p user22222222
20 |
21 | actions: [{
22 | account: 'eosio',
23 | name: 'withdraw',
24 | authorization: [{
25 | actor: 'user22222222',
26 | permission: 'active',
27 | }],
28 | data: {
29 | owner: 'user22222222',
30 | amount: '50000.0000 EOS',
31 | },
32 | }]
33 |
34 | ### 购买REX
35 | cleos --wallet-url http://localhost:6666 --url http://localhost:8000 push action eosio buyrex '["user11111111","50000.0000 EOS"]' -p user11111111
36 |
37 | actions: [{
38 | account: 'eosio',
39 | name: 'buyrex',
40 | authorization: [{
41 | actor: 'user11111111',
42 | permission: 'active',
43 | }],
44 | data: {
45 | owner: 'user11111111',
46 | amount: '50000.0000 EOS',
47 | },
48 | }]
49 |
50 | ### 使用抵押资源购买REX
51 | cleos --wallet-url http://localhost:6666 --url http://localhost:8000 push action eosio unstaketorex '["user22222222","user22222222","50.0000 EOS","50.0000 EOS"]' -p user22222222
52 |
53 | actions: [{
54 | account: 'eosio',
55 | name: 'unstaketorex',
56 | authorization: [{
57 | actor: 'user22222222',
58 | permission: 'active',
59 | }],
60 | data: {
61 | owner: 'user22222222',
62 | receiver: 'user22222222',
63 | from_net: '50.0000 EOS',
64 | from_cpu: '50.0000 EOS',
65 | },
66 | }]
67 |
68 |
69 | ### 卖出REX
70 | cleos --wallet-url http://localhost:6666 --url http://localhost:8000 push action eosio sellrex '["user11111111","500000000.0000 REX"]' -p user11111111
71 |
72 | actions: [{
73 | account: 'eosio',
74 | name: 'sellrex',
75 | authorization: [{
76 | actor: 'user11111111',
77 | permission: 'active',
78 | }],
79 | data: {
80 | from: 'user11111111',
81 | rex: '500000000.0000 REX',
82 | },
83 | }]
84 |
85 | ### 取消订单
86 | cleos --wallet-url http://localhost:6666 --url http://localhost:8000 push action eosio cnclrexorder '["user11111111"]' -p user11111111
87 |
88 | actions: [{
89 | account: 'eosio',
90 | name: 'cnclrexorder',
91 | authorization: [{
92 | actor: 'user11111111',
93 | permission: 'active',
94 | }],
95 | data: {
96 | owner: 'user11111111',
97 | },
98 | }]
99 |
100 |
101 | ### 租赁CPU
102 | cleos --wallet-url http://localhost:6666 --url http://localhost:8000 push action eosio rentcpu '["user22222222","user22222222","20.0000 EOS","0.0000 EOS"]' -p user22222222
103 |
104 | actions: [{
105 | account: 'eosio',
106 | name: 'rentcpu',
107 | authorization: [{
108 | actor: 'user22222222',
109 | permission: 'active',
110 | }],
111 | data: {
112 | from: 'user22222222',
113 | receiver: 'user22222222',
114 | loan_payment: '20.0000 EOS',
115 | loan_fund: '0.0000 EOS',
116 | },
117 | }]
118 |
119 | ### 租赁NET
120 | cleos --wallet-url http://localhost:6666 --url http://localhost:8000 push action eosio rentnet '["user22222222","user22222222","20.0000 EOS","0.0000 EOS"]' -p user22222222
121 |
122 | actions: [{
123 | account: 'eosio',
124 | name: 'rentnet',
125 | authorization: [{
126 | actor: 'user22222222',
127 | permission: 'active',
128 | }],
129 | data: {
130 | from: 'user22222222',
131 | receiver: 'user22222222',
132 | loan_payment: '20.0000 EOS',
133 | loan_fund: '0.0000 EOS',
134 | },
135 | }]
136 |
137 | ### 存CPU贷款基金
138 | cleos --wallet-url http://localhost:6666 --url http://localhost:8000 push action eosio fundcpuloan '["user22222222", "1", "20.0000 EOS"]' -p user22222222
139 |
140 | actions: [{
141 | account: 'eosio',
142 | name: 'fundcpuloan',
143 | authorization: [{
144 | actor: 'user22222222',
145 | permission: 'active',
146 | }],
147 | data: {
148 | from: 'user22222222',
149 | loan_num: '1',
150 | amount: '20.0000 EOS',
151 | },
152 | }]
153 | ### 存NET贷款基金
154 | cleos --wallet-url http://localhost:6666 --url http://localhost:8000 push action eosio fundnetloan '["user22222222", "1", "20.0000 EOS"]' -p user22222222
155 |
156 | actions: [{
157 | account: 'eosio',
158 | name: 'fundnetloan',
159 | authorization: [{
160 | actor: 'user22222222',
161 | permission: 'active',
162 | }],
163 | data: {
164 | from: 'user22222222',
165 | loan_num: '1',
166 | amount: '20.0000 EOS',
167 | },
168 | }]
169 |
170 | ### 取回CPU贷款基金
171 | cleos --wallet-url http://localhost:6666 --url http://localhost:8000 push action eosio defcpuloan '["user22222222", "1", "20.0000 EOS"]' -p user22222222
172 |
173 | actions: [{
174 | account: 'eosio',
175 | name: 'defcpuloan',
176 | authorization: [{
177 | actor: 'user22222222',
178 | permission: 'active',
179 | }],
180 | data: {
181 | from: 'user22222222',
182 | loan_num: '1',
183 | amount: '20.0000 EOS',
184 | },
185 | }]
186 | ### 取回NET贷款基金
187 | cleos --wallet-url http://localhost:6666 --url http://localhost:8000 push action eosio defnetloan '["user22222222", "1", "20.0000 EOS"]' -p user22222222
188 |
189 | actions: [{
190 | account: 'eosio',
191 | name: 'defnetloan',
192 | authorization: [{
193 | actor: 'user22222222',
194 | permission: 'active',
195 | }],
196 | data: {
197 | from: 'user22222222',
198 | loan_num: '1',
199 | amount: '20.0000 EOS',
200 | },
201 | }]
202 |
203 |
204 |
205 | ### 查看节点:
206 | cleos --wallet-url http://localhost:6666 --url http://localhost:8000 system listproducers
207 |
208 | ### 投票
209 | cleos --wallet-url http://localhost:6666 --url http://localhost:8000 system voteproducer prods user11111111 producer1111 producer1114 producer111f producer111h producer111p producer111w producer111b producer111c producer111d producer111e producer111g producer111j producer111k producer111l producer111q producer111r producer111z producer1113 producer111u producer111v producer111i
210 |
211 | actions: [{
212 | account: 'eosio',
213 | name: 'voteproducer',
214 | authorization: [{
215 | actor: 'user11111111',
216 | permission: 'active',
217 | }],
218 | data: {
219 | voter: 'user11111111',
220 | proxy: '',
221 | producers: [
222 | "producer1111",
223 | "producer1114",
224 | "producer111f"
225 | ]
226 | },
227 | }]
228 |
229 |
230 | ### 查看投票结果
231 | cleos --wallet-url http://localhost:6666 --url http://localhost:8000 get table eosio eosio voters -L user11111111 -l 1
232 |
233 | ### 购买REX: 价格:
234 | [total_rex*(total_lendable+amount)/total_lendable - total_rex] / amount
235 | ### 租赁CPU: 价格:
236 | [total_unlent*amount / (total_rent + amount)]/ amount
237 |
238 | cleos --wallet-url http://localhost:6666 --url http://localhost:8000 get table eosio eosio rexpool
239 | {
240 | "rows": [{
241 | "version": 0,
242 | "total_lent": "0.0149 EOS", 已租出的EOS总量
243 | "total_unlent": "300.9851 EOS", 可出租的EOS总量
244 | "total_rent": "20001.0000 EOS", 总的租金=20000.0000(初始值) + 1.0000(实际)
245 | "total_lendable": "301.0000 EOS", 总的EOS量=total_lent+total_unlent
246 | "total_rex": "3000000.0000 REX", REX总量
247 | "namebid_proceeds": "0.0000 EOS",
248 | "loan_num": 1
249 | }
250 | ],
251 | "more": false
252 | }
253 |
254 |
255 | cleos --wallet-url http://localhost:6666 --url http://localhost:8000 get table eosio eosio rexfund -l 1 -L user11111111
256 | {
257 | "rows": [{
258 | "version": 0,
259 | "owner": "user11111111",
260 | "balance": "400.0000 EOS" 充值但未花费的EOS量
261 | }
262 | ],
263 | "more": true
264 | }
265 |
266 |
267 | cleos --wallet-url http://localhost:6666 --url http://localhost:8000 get table eosio eosio rexbal -l 1 -L user11111111
268 | {
269 | "rows": [{
270 | "version": 0,
271 | "owner": "user11111111",
272 | "vote_stake": "200.0000 EOS", 已花费的EOS量
273 | "rex_balance": "2000000.0000 REX", 用户REX持有量
274 | "matured_rex": 0,
275 | "rex_maturities": [{
276 | "first": "2019-03-31T00:00:00", 解冻时间
277 | "second": "20000000000"
278 | }
279 | ]
280 | }
281 | ],
282 | "more": true
283 | }
284 |
285 |
286 |
287 |
288 |
289 |
290 |
--------------------------------------------------------------------------------
/src/fonts/SourceHanSansCN-Light.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/etwallet/eosrex/f017e24986f36c920fb1184944fe82657136629d/src/fonts/SourceHanSansCN-Light.otf
--------------------------------------------------------------------------------
/src/fonts/SourceHanSansCN-Medium.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/etwallet/eosrex/f017e24986f36c920fb1184944fe82657136629d/src/fonts/SourceHanSansCN-Medium.otf
--------------------------------------------------------------------------------
/src/fonts/SourceHanSansCN-Regular.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/etwallet/eosrex/f017e24986f36c920fb1184944fe82657136629d/src/fonts/SourceHanSansCN-Regular.otf
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 |
2 | @font-face{
3 | font-family: 'SourceHanSansCN-Light';
4 | src:url('./fonts/SourceHanSansCN-Light.otf') format('otf')
5 | }
6 | body,p,span,div {
7 | font-family: "SourceHanSansCN-Light";
8 | display:"flex";
9 | background-color: "#F8F8F8"
10 | }
11 |
12 | #root, body, html {
13 | width: 100%;
14 | height: 100%;
15 | margin: 0;
16 | padding: 0;
17 | font-family: "SourceHanSansCN-Light";
18 | -webkit-text-size-adjust: none;
19 | background-color: "#F8F8F8"
20 | }
21 | body :global(#root) {
22 | width: 100%;
23 | height: 100%;
24 | }
25 |
26 | input:-ms-input-placeholder {
27 | color: #D9D9D9;
28 | opacity: 1;
29 | }
30 | input::-webkit-input-placeholder {
31 | color: #D9D9D9;
32 | opacity: 1;
33 | }
34 |
35 |
36 | /* 列表上下边框 */
37 | body :global(.am-list-body) {
38 | position: relative;
39 | background-color: #F8F8F8;
40 | border: none;
41 | }
42 |
43 | body :global(.am-list-header) {
44 | padding: 0
45 | }
46 |
47 | body :global(.am-modal-button-group-h .am-modal-button:first-child) {
48 | color: #B5B5B5;
49 | }
50 |
51 | body :global(.am-navbar-left) {
52 | padding-left: 0;
53 | }
54 | body :global(.am-navbar-light) {
55 | color: #323232;
56 | }
57 |
58 | body :global(.am-popover .am-popover-item-container) {
59 | justify-content: center;
60 | }
61 |
62 |
63 | /* 单行输入框 */
64 | body :global(.am-list-item:not(:last-child) .am-list-line) {
65 | border: none;
66 | }
67 |
68 | /* 图片选择器 */
69 | body :global(.am-image-picker-list) {
70 | padding: 10px 10px 1px;
71 | margin: 0;
72 | }
73 |
74 | body :global(.am-image-picker-list .am-flexbox .am-flexbox-item) {
75 | margin-left: 5px;
76 | margin-right: 5px;
77 | }
78 | body :global(.am-image-picker-list .am-flexbox) {
79 | margin-bottom: 10px;
80 | }
81 | body :global(.am-image-picker-list .am-image-picker-item .am-image-picker-item-remove) {
82 | width: 20px;
83 | height: 20px;
84 | background-size: 20px auto;
85 | }
86 |
87 |
88 | body :global(.am-list-item .am-list-line .am-list-content) {
89 | display: flex;
90 | flex-direction: row
91 | }
92 |
93 | /* 长输入框 */
94 | body :global(.am-textarea-has-count) {
95 | min-height: 30px;
96 | border: 1PX solid #D9D9D9;
97 | background: #F8F8F8;
98 | border-radius: 2px;
99 | padding: 0;
100 | }
101 | body :global(.am-textarea-control) {
102 | padding: 2px;
103 | }
104 | body :global(.am-textarea-control textarea) {
105 | font-size: 14px;
106 | }
107 | /* 单选按钮 */
108 | body :global(.am-radio-item) {
109 | min-height: 30px;
110 | padding: 0;
111 | }
112 | body :global(.am-list .am-list-item.am-radio-item .am-list-line .am-list-extra .am-radio) {
113 | height: 30px;
114 | }
115 | body :global(.am-list .am-list-item.am-radio-item .am-list-line .am-list-extra .am-radio-inner) {
116 | top: 7.5px;
117 | }
118 |
119 |
120 | body :global(.am-list-item .am-input-label) {
121 | margin-right: 15px;
122 | }
123 | body :global(.am-list-item .am-list-line .am-list-extra) {
124 | padding-top: 2px;
125 | padding-bottom: 2px;
126 | }
127 | body :global(.am-list-item .am-list-line .am-list-content) {
128 | color: #888888;
129 | font-size: 15px;
130 | }
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import dva from 'dva';
2 | import createLoading from 'dva-loading';
3 | import createHistory from 'history/createBrowserHistory';
4 | import registerServiceWorker from './registerServiceWorker';
5 | import './index.css';
6 |
7 | const app = dva({
8 | history: createHistory(),
9 | onError(e) {
10 | console.log(e);
11 | },
12 | });
13 |
14 | app.use(createLoading());
15 |
16 | app.router(require('./router').default);
17 |
18 | app.start('#root');
19 |
20 | registerServiceWorker();
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/locales/en-US.js:
--------------------------------------------------------------------------------
1 | import enUS from 'antd-mobile/lib/locale-provider/en_US';
2 | import appLocaleData from 'react-intl/locale-data/en';
3 | import en from './en';
4 |
5 | window.appLocale = {
6 | messages: {...en},
7 | antd: enUS,
8 | locale: 'en-US',
9 | data: appLocaleData,
10 | }
11 |
--------------------------------------------------------------------------------
/src/locales/en.js:
--------------------------------------------------------------------------------
1 | const en = {
2 | "index.slogn":"ETRobot"
3 | }
4 | export default en;
5 |
--------------------------------------------------------------------------------
/src/locales/zh-CN.js:
--------------------------------------------------------------------------------
1 | import appLocaleData from 'react-intl/locale-data/zh';
2 | import zh from './zh';
3 |
4 | window.appLocale = {
5 | messages: {...zh},
6 | antd: null,
7 | locale: 'zh-Hans-CN',
8 | data: appLocaleData,
9 | };
10 |
--------------------------------------------------------------------------------
/src/locales/zh.js:
--------------------------------------------------------------------------------
1 | const zh = {
2 | "index.slogn":"ET交易所",
3 | "index.intr":"全国首家开源、开放、透明去中心化交易所"
4 | }
5 | export default zh;
6 |
--------------------------------------------------------------------------------
/src/models/commonModel.js:
--------------------------------------------------------------------------------
1 | import Request from '../utils/RequestUtil';
2 | import { noAttentionPage, attentionPage, plazaPage, biggiePage,} from '../utils/Api';
3 | import { Toast } from 'antd-mobile';
4 | import Utils from '../utils/Utils'
5 |
6 | export default {
7 | namespace: 'common',
8 |
9 | state: {
10 | account: '',
11 | permission: 'active',
12 | eosBalance: '0.0000',
13 | delegated_eosBalance: '0.0000',
14 | cpuDelegated: '0.0000',
15 | netDelegated: '0.0000',
16 | network: {
17 | blockchain:'eos',
18 | protocol:'http',
19 | host:'api.fn.eosbixin.com',
20 | port:80,
21 | chainId:'aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906'
22 | },
23 | rexpool:{
24 | total_lent: '0.0000 EOS', // 已出租的EOS总量
25 | total_unlent: '0.0000 EOS', // 可出租的EOS总量
26 | total_rent: '0.0000 EOS', // 总租金
27 | total_lendable: '0.0000', //总的EOS量
28 | total_rex: '0.0000 REX', // REX总量
29 | },
30 | lent_percent: 0, //出租百分比
31 | isVoted: false,
32 | myVotes: [],
33 | },
34 |
35 | effects: {
36 | // 登录
37 | *login({ payload, callback }, { select, call, put }) {
38 | try {
39 | const requiredFields={
40 | accounts:[{protocol:"https",
41 | blockchain:"eos",
42 | host:"eosapi.big.game",
43 | port:8889,
44 | chainId:"aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906"}]
45 | };
46 | let identity = yield window.scatter.getIdentity(requiredFields);
47 | if(window.scatter.identity && window.scatter.identity.accounts && window.scatter.identity.accounts.length>0){
48 | let account = window.scatter.identity.accounts[0];
49 | if(account.blockchain=="eos"){
50 |
51 |
52 | yield put({ type: 'update', payload: {account: account.name, permission: account.authority}});
53 |
54 | yield put({ type: 'getAccountInfo', payload: {account: account.name}});
55 |
56 | yield put({ type: 'getRexInfo', payload: {}});
57 |
58 | if(callback) callback(account);
59 | }
60 | }else{
61 | // Toast.info("登录失败,请重新登录", 1);
62 | }
63 | } catch (error) {
64 | // Toast.info("登录失败,请重新登录", 1);
65 | console.log("+++++app/models/commonModel.js++++login:",JSON.stringify(error));
66 | }
67 | },
68 |
69 | // 获取账户信息
70 | *getAccountInfo({ payload, callback }, { select, call, put }) {
71 | try {
72 | let network = yield select(state => state.common.network)
73 | var eos = window.scatter.eos(network, window.Eos);
74 |
75 | let eosBalance = '0.0000';
76 | let delegated_eosBalance = '0.0000';
77 | let cpu_weight = '0.0000';
78 | let net_weight = '0.0000';
79 |
80 | let accountInfo = yield eos.getAccount(payload.account);
81 | if(accountInfo){
82 | if(accountInfo.core_liquid_balance){
83 | eosBalance = accountInfo.core_liquid_balance.replace("EOS", "").replace(" ", "");
84 | }
85 | if(accountInfo.self_delegated_bandwidth){
86 | if(accountInfo.self_delegated_bandwidth.cpu_weight)
87 | {
88 | cpu_weight = accountInfo.self_delegated_bandwidth.cpu_weight.replace("EOS", "").replace(" ", "");
89 | }
90 | if(accountInfo.self_delegated_bandwidth.net_weight)
91 | {
92 | net_weight = accountInfo.self_delegated_bandwidth.net_weight.replace("EOS", "").replace(" ", "");
93 | }
94 | delegated_eosBalance = (parseFloat(cpu_weight) + parseFloat(net_weight)).toFixed(4);
95 | }
96 | }
97 |
98 | let isVoted = false; // 是否已经投票过
99 | let myVotes = [];
100 | if(accountInfo && accountInfo.voter_info && accountInfo.voter_info.producers){
101 | myVotes = accountInfo.voter_info.producers;
102 | if(myVotes && myVotes.length >= 21){
103 | isVoted = true;
104 | }
105 | }
106 | yield put({ type: 'update', payload: {myVotes: myVotes, isVoted: isVoted, eosBalance: eosBalance,delegated_eosBalance:delegated_eosBalance, cpuDelegated: cpu_weight, netDelegated: net_weight}});
107 |
108 | } catch (error) {
109 | console.log("+++++app/models/commonModel.js++++getAccountInfo-error:",JSON.stringify(error));
110 | }
111 | },
112 |
113 | // 获取REX信息
114 | *getRexInfo({ payload, callback }, { select, call, put }) {
115 | try {
116 | let network = yield select(state => state.common.network);
117 | var eos = window.scatter.eos(network, window.Eos);
118 | var obj = new Object();
119 | obj.json = true;
120 | obj.code = 'eosio';
121 | obj.scope = 'eosio';
122 | obj.table = 'rexpool';
123 | obj.limit = 1;
124 | let info = yield eos.getTableRows(obj);
125 |
126 | let rexpoolRemote = info.rows[0];
127 | let rexpoolLocal = yield select(state => state.common.rexpool);
128 | let rexpool = {...rexpoolLocal, ...rexpoolRemote};
129 |
130 | let lent_percent = 0;
131 | if(rexpool && rexpool.total_lent && rexpool.total_lendable)
132 | {
133 | let total_lent = Utils.sliceUnit(rexpool.total_lent);
134 | let total_lendable = Utils.sliceUnit(rexpool.total_lendable);
135 | // alert('total_lent = ' + total_lent + ' total_lendable = ' + total_lendable);
136 | let float_total_lent = parseFloat(total_lent).toFixed(4);
137 | let float_total_lendable = parseFloat(total_lendable).toFixed(4);
138 | lent_percent = (float_total_lent * 100 / float_total_lendable).toFixed(2);
139 | }
140 | yield put({ type: 'update', payload: {rexpool: rexpool,lent_percent: lent_percent} });
141 | if(callback) callback(true);
142 | } catch (error) {
143 | console.log("+++++app/models/commonModel.js++++getRexInfo-error:",JSON.stringify(error));
144 | if(callback) callback(false);
145 | }
146 | },
147 | // 发送eos交易
148 | *sendEosAction({ payload, callback }, { select, call, put }) {
149 | try {
150 | let network = yield select(state => state.common.network);
151 | var eos = window.scatter.eos(network, window.Eos);
152 | let resp = yield eos.transaction({actions: payload.actions});
153 | if(resp.transaction_id){
154 | let account = yield select(state => state.common.account);
155 | yield put({ type: 'getAccountInfo', payload: {account: account}});
156 | yield put({ type: 'getRexInfo', payload: {}});
157 | }
158 | if(callback) callback(resp);
159 | } catch (error) {
160 | console.log("+++++app/models/commonModel.js++++sendEosAction-error:",JSON.stringify(error));
161 | if(callback) callback(null);
162 | }
163 | },
164 | //查询卖单
165 | *querySellRexInfo({ payload, callback }, { select, call, put }) {
166 | try {
167 | if(!payload.account){
168 | if(callback) callback(null);
169 | return;
170 | }
171 |
172 | let network = yield select(state => state.common.network);
173 | var eos = window.scatter.eos(network, window.Eos);
174 | var obj = new Object();
175 | obj.json = true;
176 | obj.code = 'eosio';
177 | obj.scope = 'eosio';
178 | obj.table = 'rexqueue';
179 | obj.limit = 1;
180 | obj.lower_bound = payload.account;
181 | // obj.table_key = 'owner';
182 | let resp = yield eos.getTableRows(obj);
183 |
184 | if(callback) callback(resp);
185 | } catch (error) {
186 | console.log("+++++app/models/common.js++++querySellRexInfo-error:",JSON.stringify(error));
187 | if(callback) callback(null);
188 | }
189 | },
190 | //查询可提币余额
191 | *queryWithdrawInfo({ payload, callback }, { select, call, put }) {
192 | try {
193 | if(!payload.account){
194 | if(callback) callback(null);
195 | return;
196 | }
197 |
198 | let network = yield select(state => state.common.network);
199 | var eos = window.scatter.eos(network, window.Eos);
200 | var obj = new Object();
201 | obj.json = true;
202 | obj.code = 'eosio';
203 | obj.scope = 'eosio';
204 | obj.table = 'rexfund';
205 | obj.limit = 1;
206 | obj.lower_bound = payload.account;
207 | // obj.table_key = 'owner';
208 | let resp = yield eos.getTableRows(obj);
209 |
210 | if(callback) callback(resp);
211 | } catch (error) {
212 | console.log("+++++app/models/common.js++++queryWithdrawInfo-error:",JSON.stringify(error));
213 | if(callback) callback(null);
214 | }
215 | },
216 |
217 | },
218 |
219 | reducers: {
220 | update(state, action) {
221 | return { ...state, ...action.payload };
222 | },
223 |
224 | },
225 |
226 | subscriptions: {
227 |
228 | }
229 | };
230 |
--------------------------------------------------------------------------------
/src/models/index.js:
--------------------------------------------------------------------------------
1 | import commonModel from './commonModel';
2 | import rexModel from './rexModel';
3 | import voteModel from './voteModel';
4 |
5 | const models = [
6 | commonModel,
7 | rexModel,
8 | voteModel,
9 | ]
10 | export default models;
--------------------------------------------------------------------------------
/src/models/rexModel.js:
--------------------------------------------------------------------------------
1 | import Request from '../utils/RequestUtil';
2 | import { noAttentionPage, attentionPage, plazaPage, biggiePage,} from '../utils/Api';
3 | import { Toast } from 'antd-mobile';
4 | import Utils from '../utils/Utils'
5 |
6 | export default {
7 | namespace: 'rex',
8 |
9 | state: {
10 | myRexInfo:{
11 | total_rex: 0, // 总rex
12 | sell_available_rex: 0, // 可卖的rex
13 | },
14 |
15 | },
16 |
17 | effects: {
18 | // 获取REX信息
19 | *getMyRexInfo({ payload, callback }, { select, call, put }) {
20 | try {
21 | if(!payload.account){
22 | return;
23 | }
24 | let network = yield select(state => state.common.network);
25 | var eos = window.scatter.eos(network, window.Eos);
26 | var obj = new Object();
27 | obj.json = true;
28 | obj.code = 'eosio';
29 | obj.scope = 'eosio';
30 | obj.table = 'rexbal';
31 | obj.limit = 1;
32 | obj.lower_bound = payload.account;
33 | let info = yield eos.getTableRows(obj);
34 |
35 | let rexInfo = info.rows[0];
36 | if(rexInfo && rexInfo.owner != payload.account){
37 | return;
38 | }
39 |
40 | rexInfo.sell_available_rex = 0;
41 | rexInfo.total_rex = 0;
42 | if(rexInfo.rex_balance){
43 | rexInfo.total_rex = Utils.sliceUnit(rexInfo.rex_balance);
44 | rexInfo.sell_available_rex = rexInfo.total_rex;
45 | }
46 |
47 | if(rexInfo.rex_maturities){
48 | rexInfo.rex_maturities.forEach(item => {
49 | try {
50 | if(Utils.isTimeExpire(new Date(item.first).valueOf())){
51 | return;
52 | }
53 | rexInfo.sell_available_rex = (parseFloat(rexInfo.sell_available_rex) - (item.second/10000).toFixed(4)).toFixed(4);
54 | } catch (error) {
55 |
56 | }
57 | });
58 | }
59 |
60 | yield put({ type: 'update', payload: {myRexInfo: rexInfo} });
61 | } catch (error) {
62 | console.log("+++++app/models/rexModel.js++++getMyRexInfo-error:",JSON.stringify(error));
63 | }
64 | },
65 | },
66 |
67 | reducers: {
68 | update(state, action) {
69 | return { ...state, ...action.payload };
70 | },
71 |
72 | },
73 |
74 | subscriptions: {
75 |
76 | }
77 | };
78 |
--------------------------------------------------------------------------------
/src/models/voteModel.js:
--------------------------------------------------------------------------------
1 | import Request from '../utils/RequestUtil';
2 | import { noAttentionPage, attentionPage, plazaPage, biggiePage,} from '../utils/Api';
3 | import { Toast } from 'antd-mobile';
4 | import Utils from '../utils/Utils'
5 |
6 | export default {
7 | namespace: 'vote',
8 |
9 | state: {
10 | myVoteInfo:[],
11 | isVoted: false, // 是否进行投票过
12 | producers: [], // 节点列表
13 | },
14 |
15 | effects: {
16 | // 获取投票信息
17 | *getMyVoteInfo({ payload, callback }, { select, call, put }) {
18 | try {
19 | if(!payload.account){
20 | return;
21 | }
22 | let network = yield select(state => state.common.network);
23 | var eos = window.scatter.eos(network, window.Eos);
24 | var obj = new Object();
25 | obj.json = true;
26 | obj.code = 'eosio';
27 | obj.scope = 'eosio';
28 | obj.table = 'voters';
29 | obj.limit = 1;
30 | obj.lower_bound = payload.account;
31 | obj.table_key = 'owner';
32 | let info = yield eos.getTableRows(obj);
33 |
34 | let voteInfo = info.rows;
35 | yield put({ type: 'update', payload: {myVoteInfo: voteInfo, isVoted:true} });
36 | } catch (error) {
37 | console.log("+++++app/models/voteModel.js++++getMyVoteInfo-error:",JSON.stringify(error));
38 | }
39 | },
40 |
41 | /**
42 | * 根据排名获取投票列表
43 | */
44 | *listProducers({ payload, callback }, { select, call, put }) {
45 | try {
46 | let network = yield select(state => state.common.network);
47 | var eos = window.scatter.eos(network, window.Eos);
48 | var obj = new Object();
49 | obj.json = true;
50 | obj.code = 'eosio';
51 | obj.scope = 'eosio';
52 | obj.table = 'producers';
53 | obj.limit = 100;
54 | obj.index_position = 2;
55 | obj.key_type = 'float64'
56 | let info = yield eos.getTableRows(obj);
57 |
58 | let producers = info.rows;
59 |
60 | let myVotes = yield select(state => state.common.myVotes);
61 | producers.forEach((p) => {
62 | p.isSelect = false;
63 | if(myVotes && myVotes.includes(p.owner)){
64 | p.isSelect = true;
65 | }
66 | });
67 |
68 | // alert("listProducers: " + JSON.stringify(producers));
69 |
70 | yield put({ type: 'update', payload: {producers: producers} });
71 | if(callback) callback(producers);
72 | } catch (error) {
73 | console.log("+++++app/models/voteModel.js++++listProducers-error:",JSON.stringify(error));
74 | if(callback) callback([]);
75 | }
76 | },
77 | },
78 |
79 | reducers: {
80 | update(state, action) {
81 | return { ...state, ...action.payload };
82 | },
83 |
84 | },
85 |
86 | subscriptions: {
87 |
88 | }
89 | };
90 |
--------------------------------------------------------------------------------
/src/registerServiceWorker.js:
--------------------------------------------------------------------------------
1 | // In production, we register a service worker to serve assets from local cache.
2 |
3 | // This lets the app load faster on subsequent visits in production, and gives
4 | // it offline capabilities. However, it also means that developers (and users)
5 | // will only see deployed updates on the "N+1" visit to a page, since previously
6 | // cached resources are updated in the background.
7 |
8 | // To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
9 | // This link also includes instructions on opting out of this behavior.
10 |
11 | const isLocalhost = Boolean(
12 | window.location.hostname === 'localhost' ||
13 | // [::1] is the IPv6 localhost address.
14 | window.location.hostname === '[::1]' ||
15 | // 127.0.0.1/8 is considered localhost for IPv4.
16 | window.location.hostname.match(
17 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
18 | )
19 | );
20 |
21 | export default function register() {
22 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
23 | // The URL constructor is available in all browsers that support SW.
24 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location);
25 | if (publicUrl.origin !== window.location.origin) {
26 | // Our service worker won't work if PUBLIC_URL is on a different origin
27 | // from what our page is served on. This might happen if a CDN is used to
28 | // serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374
29 | return;
30 | }
31 |
32 | window.addEventListener('load', () => {
33 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
34 |
35 | if (!isLocalhost) {
36 | // Is not local host. Just register service worker
37 | registerValidSW(swUrl);
38 | } else {
39 | // This is running on localhost. Lets check if a service worker still exists or not.
40 | checkValidServiceWorker(swUrl);
41 | }
42 | });
43 | }
44 | }
45 |
46 | function registerValidSW(swUrl) {
47 | navigator.serviceWorker
48 | .register(swUrl)
49 | .then(registration => {
50 | registration.onupdatefound = () => {
51 | const installingWorker = registration.installing;
52 | installingWorker.onstatechange = () => {
53 | if (installingWorker.state === 'installed') {
54 | if (navigator.serviceWorker.controller) {
55 | // At this point, the old content will have been purged and
56 | // the fresh content will have been added to the cache.
57 | // It's the perfect time to display a "New content is
58 | // available; please refresh." message in your web app.
59 | console.log('New content is available; please refresh.');
60 | } else {
61 | // At this point, everything has been precached.
62 | // It's the perfect time to display a
63 | // "Content is cached for offline use." message.
64 | console.log('Content is cached for offline use.');
65 | }
66 | }
67 | };
68 | };
69 | })
70 | .catch(error => {
71 | console.error('Error during service worker registration:', error);
72 | });
73 | }
74 |
75 | function checkValidServiceWorker(swUrl) {
76 | // Check if the service worker can be found. If it can't reload the page.
77 | fetch(swUrl)
78 | .then(response => {
79 | // Ensure service worker exists, and that we really are getting a JS file.
80 | if (
81 | response.status === 404 ||
82 | response.headers.get('content-type').indexOf('javascript') === -1
83 | ) {
84 | // No service worker found. Probably a different app. Reload the page.
85 | navigator.serviceWorker.ready.then(registration => {
86 | registration.unregister().then(() => {
87 | window.location.reload();
88 | });
89 | });
90 | } else {
91 | // Service worker found. Proceed as normal.
92 | registerValidSW(swUrl);
93 | }
94 | })
95 | .catch(() => {
96 | console.log(
97 | 'No internet connection found. App is running in offline mode.'
98 | );
99 | });
100 | }
101 |
102 | export function unregister() {
103 | if ('serviceWorker' in navigator) {
104 | navigator.serviceWorker.ready.then(registration => {
105 | registration.unregister();
106 | });
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/src/router.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Router, Route, Switch } from 'dva/router';
3 | import Dynamic from 'dva/dynamic';
4 | import { LocaleProvider } from 'antd-mobile';
5 | import { addLocaleData, IntlProvider } from 'react-intl';
6 | import store from 'storejs';
7 |
8 | let lan = store.get("language");
9 | if(!lan){
10 | let language = navigator.language;
11 | if(language){
12 | lan = language.split('-')[0];
13 | }else{
14 | lan="en";
15 | }
16 | }
17 | switch(lan){
18 | case 'en':
19 | require("./locales/en-US");
20 | break;
21 | case 'zh':
22 | require("./locales/zh-CN");
23 | break;
24 | default:
25 | require("./locales/en-US");
26 | break;
27 | }
28 | const appLocale = window.appLocale;
29 | addLocaleData(appLocale.data);
30 |
31 | export default function RouterConfig({history,app}) {
32 | const Index = Dynamic({app,models:()=>[require("./models/")],component:()=>import('./routes/Index')});
33 | const GameDescription = Dynamic({app,models:()=>[require("./models/")],component:()=>import('./routes/GameDescription')});
34 | const BuyandSell = Dynamic({app,models:()=>[require("./models/")],component:()=>import('./routes/BuyandSell')});
35 | const DetailsList = Dynamic({app,models:()=>[require("./models/")],component:()=>import('./routes/DetailsList')});
36 | const Withdraw = Dynamic({app,models:()=>[require("./models/")],component:()=>import('./routes/Withdraw')});
37 | const NodeVoting = Dynamic({app,models:()=>[require("./models/")],component:()=>import('./routes/NodeVoting')});
38 | const MyRexDetails = Dynamic({app,models:()=>[require("./models/")],component:()=>import('./routes/MyRexDetails')});
39 |
40 | return (
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | );
57 | }
58 |
--------------------------------------------------------------------------------
/src/routes/BuyandSell.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Toast, PullToRefresh, ListView, Button, Modal, InputItem, List, WhiteSpace, SegmentedControl} from 'antd-mobile';
3 | import { injectIntl } from 'react-intl';
4 | import { connect } from 'dva';
5 | import Auto from '../utils/Auto'
6 | import {routerRedux} from 'dva/router';
7 | import Utils from '../utils/Utils'
8 | import {formatEosQua} from '../utils/FormatUtil';
9 |
10 | require('moment/locale/zh-cn');
11 | var ScreenWidth = window.screen.width
12 | var ScreenHeight = window.screen.height
13 | const alert = Modal.alert;
14 |
15 | var TransType = {
16 | BUY: 0,
17 | SELL: 1,
18 | };
19 |
20 | class BuyandSell extends React.Component {
21 | constructor(props) {
22 | super(props);
23 | const dataSource = new ListView.DataSource({ rowHasChanged: (row1, row2) => row1 !== row2 });
24 | this.state = {
25 | dataSource,
26 | isSwitch: true,
27 | values: ['购买', '出售'],
28 | netQuantity: '0.0000',
29 | cpuQuantity: '0.0000',
30 | quantity: '0.0000',
31 | quantity_rex: '0.0000',
32 | transType: TransType.BUY,
33 | actionsList: [
34 | {actions: this.getBuyActions},
35 | {actions: this.getSellActions},
36 | ],
37 | defaultProducers:[
38 | 'argentinaeos',
39 | 'atticlabeosb',
40 | 'bitfinexeos1',
41 | 'cochainworld',
42 | 'eos42freedom',
43 | 'eosauthority',
44 | 'eosbeijingbp',
45 | 'eosbixinboot',
46 | 'eoscannonchn',
47 | 'eosflytomars',
48 | 'eoshuobipool',
49 | 'eosiosg11111',
50 | 'eoslaomaocom',
51 | 'eosliquideos',
52 | 'eosnewyorkio',
53 | 'eosriobrazil',
54 | 'eosswedenorg',
55 | 'helloeoscnbp',
56 | 'jedaaaaaaaaa',
57 | 'starteosiobp',
58 | 'zbeosbp11111',
59 | // "producer1111",
60 | // "producer1114",
61 | // "producer111f"
62 | ],
63 | exchangeradio: 0, //兑换比例
64 | selectedIndex: 0,
65 | };
66 | }
67 |
68 | componentDidMount() {
69 | Utils.dispatchActiionData(this, { type: 'rex/getMyRexInfo', payload:{account: this.props.account}});
70 | this.calcExchangRadio();
71 | }
72 |
73 | onlease = () => {
74 | this.props.dispatch(routerRedux.push({pathname: '/', query: { }}))
75 | }
76 |
77 | description = () => {
78 | this.props.dispatch(routerRedux.push({pathname: '/GameDescription', query: {lease:false}}))
79 | }
80 |
81 | onChange = (e) => {
82 | this.setState({selectedIndex: e.nativeEvent.selectedSegmentIndex})
83 | }
84 |
85 | onValueChange = (value) => {
86 | if(value == this.state.values[1]){
87 | this.setState({transType: TransType.SELL})
88 | }else{
89 | this.setState({transType: TransType.BUY})
90 | }
91 | }
92 |
93 | onBuySellList = () => {
94 | let isBuySell = (this.state.transType == TransType.BUY) ? true : false;
95 | localStorage.setItem('buy_sell', isBuySell);
96 | this.props.dispatch(routerRedux.push({pathname: '/DetailsList', query: { isBuySell: isBuySell }}))
97 | }
98 |
99 | onNodeVoting = () => {
100 | this.props.dispatch(routerRedux.push({pathname: '/NodeVoting', query: { }}))
101 | }
102 |
103 | calcExchangRadio(){
104 | let val_price = 0;
105 | try {
106 | let total_rex = Utils.sliceUnit(this.props.rexpool.total_rex);
107 | let total_lendable = Utils.sliceUnit(this.props.rexpool.total_lendable);
108 | let float_total_rex = parseFloat(total_rex);
109 | let float_total_lendable = parseFloat(total_lendable);
110 | let amount = 1.0000;
111 | let val = (float_total_lendable + amount).toFixed(4);
112 |
113 | let tmp = (float_total_rex * val).toFixed(4);
114 | let tmp1 = (tmp/float_total_lendable).toFixed(4);
115 | let tmp2 = (tmp1 - float_total_rex).toFixed(4);
116 | val_price = (tmp2/amount).toFixed(4);
117 | } catch (error) {
118 | val_price = 0;
119 | }
120 | this.setState({exchangeradio:val_price});
121 | }
122 | //查询冻结的 EOS
123 | queryWithdrawAmount = async () => {
124 | let tmp_amount = 0.0000;
125 | let resp = await Utils.dispatchActiionData(this, { type: 'common/queryWithdrawInfo', payload:{account: this.props.account}});
126 | if(resp && resp.rows){
127 | resp.rows.forEach(function(val,index){
128 | if(val.balance){
129 | let amount = 0.0000;
130 | try {
131 | let s3 = Utils.sliceUnit(val.balance);
132 | amount = parseFloat(s3).toFixed(4);
133 | } catch (error) {
134 | amount = 0.0000;
135 | }
136 | tmp_amount = amount;
137 | return ;
138 | }
139 | });
140 | }
141 | console.log('resp tmp_amount',tmp_amount);
142 | return tmp_amount;
143 | }
144 | withdraw = async () => {
145 | let tmp_amount = await this.queryWithdrawAmount();
146 | if(tmp_amount < 0.0001){
147 | Toast.info("没有冻结的币,无需提币");
148 | return ;
149 | }
150 | this.props.dispatch(routerRedux.push({pathname: '/Withdraw', query: {balance: tmp_amount}}))
151 | }
152 | auto_sendWithdraw = async (amount) => {
153 | try {
154 | let actions = [{
155 | account: 'eosio',
156 | name: 'withdraw',
157 | authorization: [{
158 | actor: this.props.account,
159 | permission: this.props.permission,
160 | }],
161 | data: {
162 | owner: this.props.account,
163 | amount: formatEosQua(amount + ' EOS'),
164 | },
165 | }];
166 | console.log('actions=',JSON.stringify(actions));
167 | let resp = await Utils.dispatchActiionData(this, { type: 'common/sendEosAction', payload:{actions: actions}});
168 | console.log('resp =',JSON.stringify(resp));
169 | if(resp){
170 | Utils.dispatchActiionData(this, { type: 'common/getAccountInfo', payload:{account: this.props.account}});
171 | Toast.info("交易成功");
172 | }else{
173 | Toast.info("提币失败");
174 | }
175 | } catch (error) {
176 | console.log('err=',JSON.stringify(error));
177 | }
178 | }
179 |
180 |
181 | doTrans = async (transType) => {
182 | try {
183 | let quantity;
184 | let banlance;
185 | if(transType == TransType.BUY){
186 | quantity = parseFloat(this.state.quantity);
187 | let cpuQuantity = parseFloat(this.state.cpuQuantity);
188 | let netQuantity = parseFloat(this.state.netQuantity);
189 | banlance = parseFloat(this.state.isSwitch ? this.props.eosBalance :this.props.delegated_eosBalance);
190 | if(this.state.isSwitch){
191 | if(quantity < 0.0001){
192 | Toast.info('购买数量错误');
193 | return ;
194 | }
195 | }else{
196 | if(cpuQuantity < 0.0001 && netQuantity < 0.0001){
197 | Toast.info('购买数量错误');
198 | return ;
199 | }
200 | }
201 |
202 | }else{
203 | quantity = parseFloat(this.state.quantity_rex);
204 | banlance = parseFloat(this.props.myRexInfo.total_rex);
205 | if(quantity < 0.0001){
206 | Toast.info('出售数量错误');
207 | return ;
208 | }
209 | }
210 | if(quantity > banlance){
211 | Toast.info('余额不足');
212 | return ;
213 | }
214 |
215 | if(this.props.isVoted){ // 投过票了
216 | let rexTransActions = this.getRexTransActions();
217 | let resp = await this.doEosTransact(rexTransActions);
218 | if(resp){
219 | console.log('doEosTransact+++++');
220 | // if(this.state.transType == TransType.SELL){
221 | //卖了REX,自动发起提币
222 | // setTimeout(async () => {
223 | // let tmp_amount = await this.queryWithdrawAmount();
224 | // console.log('tmp_amount 11',tmp_amount);
225 | // if(tmp_amount >= 0.0001){
226 | // console.log('tmp_amount 22');
227 | // // resp = await this.auto_sendWithdraw('' + tmp_amount);
228 | // resp = await this.auto_sendWithdraw('0.1000');
229 | // }
230 | // }, 1000);
231 | // }
232 | Toast.info('交易成功');
233 | }else{
234 | Toast.info('交易失败');
235 | }
236 | return;
237 | }
238 |
239 | // 还没投过票
240 | Modal.alert('温馨提示', 在进行买卖REX之前,您必须要对至少21个节点投过票或代理投票,我们已经帮您进行了默认的节点投票。
, [
241 | { text: '高级设置 >', onPress: () => {this.onNodeVoting()}},
242 | { text: '确定', onPress: () => this.doVoteAndRexTrans() },
243 | ])
244 | } catch (error) {
245 |
246 | }
247 | }
248 |
249 | getdefaultVoteActions = () => {
250 | let actions = [{
251 | account: 'eosio',
252 | name: 'voteproducer',
253 | authorization: [{
254 | actor: this.props.account,
255 | permission: this.props.permission,
256 | }],
257 | data: {
258 | voter: this.props.account,
259 | proxy: '',
260 | producers: this.state.defaultProducers,
261 | },
262 | }];
263 |
264 | return actions;
265 | }
266 |
267 | // 使用抵押资源购买rex
268 | getBuyByStakeActions(){
269 | let actions = [{
270 | account: 'eosio',
271 | name: 'unstaketorex',
272 | authorization: [{
273 | actor: this.props.account,
274 | permission: this.props.permission,
275 | }],
276 | data: {
277 | owner: this.props.account,
278 | receiver: this.props.account,
279 | from_net: formatEosQua(this.state.netQuantity + ' EOS'),
280 | from_cpu: formatEosQua(this.state.cpuQuantity + ' EOS'),
281 | },
282 | }];
283 |
284 | return actions;
285 | }
286 |
287 | // 使用余额购买rex
288 | getBuyByBalanceActions(){
289 | let actions = [{
290 | account: 'eosio',
291 | name: 'deposit',
292 | authorization: [{
293 | actor: this.props.account,
294 | permission: this.props.permission,
295 | }],
296 | data: {
297 | owner: this.props.account,
298 | amount: formatEosQua(this.state.quantity + ' EOS'),
299 | },
300 | },
301 | {
302 | account: 'eosio',
303 | name: 'buyrex',
304 | authorization: [{
305 | actor: this.props.account,
306 | permission: this.props.permission,
307 | }],
308 | data: {
309 | from: this.props.account,
310 | amount: formatEosQua(this.state.quantity + ' EOS'),
311 | },
312 | }];
313 |
314 | return actions;
315 | }
316 |
317 | /**
318 | * 买rex
319 | */
320 | getBuyActions = () => {
321 | if(this.state.isSwitch){ // 使用余额购买rex
322 | return this.getBuyByBalanceActions();
323 | }
324 |
325 | return this.getBuyByStakeActions();
326 | }
327 |
328 | /**
329 | * 卖rex
330 | */
331 | getSellActions = () => {
332 | let actions = [{
333 | account: 'eosio',
334 | name: 'sellrex',
335 | authorization: [{
336 | actor: this.props.account,
337 | permission: this.props.permission,
338 | }],
339 | data: {
340 | from: this.props.account,
341 | rex: formatEosQua(this.state.quantity_rex + ' REX'),
342 | },
343 | },
344 | ]
345 |
346 | return actions;
347 | }
348 |
349 | onQuantityRex = () => {
350 | this.setState({quantity_rex: this.props.myRexInfo.sell_available_rex})
351 | }
352 |
353 | getRexTransActions = () => {
354 | let actions = this.state.actionsList[this.state.transType].actions();
355 | return actions;
356 | }
357 |
358 | doVoteAndRexTrans = () => {
359 | let voteActions = this.getdefaultVoteActions();
360 | let rexTransActions = this.getRexTransActions();
361 | let actions = voteActions.concat(rexTransActions);
362 | this.doEosTransact(actions);
363 | }
364 |
365 | async doEosTransact(actions){
366 | let resp = await Utils.dispatchActiionData(this, { type: 'common/sendEosAction', payload:{actions: actions}});
367 | return resp;
368 | }
369 |
370 | showMyRexDetails = () => {
371 | if(!this.props.myRexInfo.rex_maturities || this.props.myRexInfo.rex_maturities.length == 0){
372 | Modal.alert('温馨提示', 您没有冻结的REX
, [
373 | { text: '关闭', onPress: () => {}},
374 | ]);
375 | return;
376 | }
377 | this.props.dispatch(routerRedux.push({pathname: '/MyRexDetails', query: { }}))
378 | }
379 |
380 | render() {
381 | return (
382 |
383 |
384 |
总量(REX)
385 |
386 |
387 |
388 |
{Utils.sliceUnit(this.props.rexpool.total_rex)}
389 |
390 |
REX趋势
391 |

392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
账户信息:{this.props.account}
400 |
403 |
404 |
405 | 兑换比例:
406 | 1 EOS ≈ {this.state.exchangeradio} REX
407 |
408 |
409 | 我的REX:
410 | {this.props.myRexInfo.total_rex} REX
411 | 详情
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 | {this.state.transType == TransType.BUY ?
424 |
425 |
426 | {this.state.isSwitch ?
427 |
我的余额:{this.props.eosBalance} EOS
428 | :
429 |
430 |
抵押资源:{this.props.delegated_eosBalance} EOS
431 |
{'(net:' + this.props.netDelegated + ' cpu:' + this.props.cpuDelegated + ')'}
432 |
433 | }
434 |
435 |
436 | {this.state.isSwitch ?
437 |
438 |
439 |
440 | this.setState({ quantity: Utils.chkEosQuantity(quantity)})} >购买数量:
441 |
442 |
443 |
444 | :
445 |
446 |
447 |
448 | this.setState({ netQuantity: Utils.chkEosQuantity(quantity)})} >使用net:
449 |
450 |
451 |
452 |
453 |
454 | this.setState({ cpuQuantity: Utils.chkEosQuantity(quantity)})} >使用cpu:
455 |
456 |
457 |
458 | }
459 |
460 |
461 |
462 | :
463 |
464 |
465 | this.setState({ quantity_rex: Utils.chkEosQuantity(quantity_rex)})} >出售数量:
466 |
467 |
468 |
469 |
470 |
可卖数量:{this.props.myRexInfo.sell_available_rex} REX
471 |
472 |
473 |
474 | }
475 |
476 |
477 | {(this.state.transType == TransType.BUY) &&
478 |
479 |
订单确认:
480 |
花费{this.state.isSwitch ? this.state.quantity : parseFloat(this.state.netQuantity) + parseFloat(this.state.cpuQuantity)} EOS,为您兑换{((this.state.isSwitch ? parseFloat(this.state.quantity) : parseFloat(this.state.netQuantity) + parseFloat(this.state.cpuQuantity)) * this.state.exchangeradio).toFixed(4)} REX
481 |
}
482 |
483 |
484 |
486 |
487 |
488 |
489 |
491 |
492 |
)
493 | }
494 | }
495 |
496 | export default connect(({ common, rex }) => ({ ...common, ...rex }))(injectIntl(BuyandSell));
497 |
498 | const styles = {
499 | rootDiv:{
500 | width: ScreenWidth,
501 | height: ScreenHeight,
502 | background:"#F8F8F8",
503 | boxSizing: 'border-box',
504 | },
505 |
506 | headtopout: {
507 | display:"flex",
508 | flexDirection: 'row',
509 | alignItems: 'center',
510 | height: Auto.WHT(88),
511 | paddingLeft: Auto.WHT(30),
512 | paddingRight: Auto.WHT(30),
513 | },
514 | headtoptext: {
515 | flex: 1,
516 | color: '#000000',
517 | fontSize: Auto.WHT(34),
518 | lineHeight: Auto.WHT(42),
519 | },
520 | headtopbtn: {
521 | width: Auto.WHT(164),
522 | height: Auto.WHT(60),
523 | lineHeight: Auto.WHT(60),
524 | background: '#FFFFFF',
525 | border: '1px #108EE9 solid',
526 | textDecoration: 'none',
527 | borderRadius: Auto.WHT(6),
528 | fontSize: Auto.WHT(26),
529 | color: '#108EE9',
530 | },
531 | headbottomout: {
532 | display: 'flex',
533 | flexDirection: 'row',
534 | alignItems: 'center',
535 | justifyContent: 'space-between',
536 | padding: Auto.WHT(30),
537 | },
538 | headbottomleft: {
539 | color: '#000000',
540 | fontSize: Auto.WHT(48),
541 | lineHeight: Auto.WHT(67),
542 | paddingBottom: Auto.WHT(22),
543 | },
544 | headbottomright: {
545 | display: 'flex',
546 | flexDirection: 'row',
547 | alignItems: 'center',
548 | },
549 | headbottomtext: {
550 | color: '#888888',
551 | fontSize: Auto.WHT(32),
552 | lineHeight: Auto.WHT(45),
553 | },
554 | headbottomimg: {
555 | width: Auto.WHT(16),
556 | height: Auto.WHT(26),
557 | marginLeft: Auto.WHT(30)
558 | },
559 |
560 | centerDiv: {
561 | display: 'flex',
562 | flexDirection: 'column',
563 | background: '#FFFFFF',
564 | },
565 | centertopout:{
566 | height: Auto.WHT(110),
567 | display:"flex",
568 | flexDirection: 'row',
569 | alignItems: 'center',
570 | justifyContent: 'space-between',
571 | borderBottom: '1px solid #DDDDDD',
572 | },
573 | centertoptext: {
574 | flex: 1,
575 | color: '#000000',
576 | fontSize: Auto.WHT(34),
577 | lineHeight: Auto.WHT(42),
578 | paddingLeft: Auto.WHT(30),
579 | },
580 | graytext: {
581 | flex: 1,
582 | color: 'gray',
583 | fontSize: Auto.WHT(30),
584 | lineHeight: Auto.WHT(42),
585 | paddingLeft: Auto.WHT(30),
586 | },
587 | centertopbtn: {
588 | border: 'none',
589 | borderRadius: 0,
590 | color: '#D9D9D9',
591 | padding: '0 0.4rem',
592 | height: Auto.WHT(36),
593 | textDecoration: 'none',
594 | },
595 | reportimg: {
596 | width: Auto.WHT(30),
597 | height: Auto.WHT(30),
598 | margin: 0,
599 | },
600 | centerbottom: {
601 | color: '#888888',
602 | fontSize: Auto.WHT(28),
603 | },
604 | centerbottom1: {
605 | display: 'flex',
606 | flex: 1,
607 | color: '#888888',
608 | fontSize: Auto.WHT(28),
609 | },
610 | rexDetail: {
611 |
612 | color: '#108EE9',
613 | fontSize: Auto.WHT(28),
614 | },
615 | listDiv: {
616 | display: 'flex',
617 | flexDirection: 'column',
618 | background: '#FFFFFF',
619 | },
620 | sellbtn: {
621 | flex: 1,
622 | background: 'transparent',
623 | border: 'none',
624 | textDecoration: 'none',
625 | borderRadius: 0,
626 | fontSize: Auto.WHT(28),
627 | color: '#BBBBBB',
628 | },
629 | listitemout: {
630 | display: 'flex',
631 | flexDirection: 'row',
632 | alignItems: 'center',
633 | height: Auto.WHT(110),
634 | paddingRight: Auto.WHT(30),
635 | },
636 | listbtn: {
637 | width: Auto.WHT(112),
638 | height: Auto.WHT(60),
639 | lineHeight: Auto.WHT(60),
640 | background: '#108EE9',
641 | border: 'none',
642 | textDecoration: 'none',
643 | borderRadius: Auto.WHT(6),
644 | fontSize: Auto.WHT(26),
645 | color: '#FFFFFF',
646 |
647 | },
648 | ordertext: {
649 | color: '#000000',
650 | fontSize: Auto.WHT(28),
651 | paddingTop: Auto.WHT(10),
652 | paddingBottom: Auto.WHT(10),
653 | },
654 | orderout: {
655 | color: '#888888',
656 | fontSize: Auto.WHT(28),
657 | lineHeight: Auto.WHT(40),
658 | },
659 |
660 | footDiv: {
661 | width: ScreenWidth,
662 | boxSizing: 'border-box',
663 | paddingTop: Auto.WHT(40),
664 | paddingLeft: Auto.WHT(30),
665 | paddingRight: Auto.WHT(30),
666 | paddingBottom: Auto.WHT(40),
667 | },
668 | footbtn: {
669 | width: '100%',
670 | border: 'none',
671 | color: '#FFFFFF',
672 | height: Auto.WHT(94),
673 | background: '#108EE9',
674 | textDecoration: 'none',
675 | fontSize: Auto.WHT(36),
676 | lineHeight: Auto.WHT(94),
677 | borderRadius: Auto.WHT(10),
678 | },
679 |
680 | footDivWithdraw: {
681 | width: ScreenWidth,
682 | boxSizing: 'border-box',
683 | paddingTop: Auto.WHT(15),
684 | paddingLeft: Auto.WHT(30),
685 | paddingRight: Auto.WHT(30),
686 | paddingBottom: Auto.WHT(40),
687 | },
688 | footbtnWithdraw: {
689 | width: '100%',
690 | border: '1px #108EE9 solid',
691 | color: '#108EE9',
692 | height: Auto.WHT(94),
693 | background: '#FFFFFF',
694 | textDecoration: 'none',
695 | fontSize: Auto.WHT(36),
696 | lineHeight: Auto.WHT(94),
697 | borderRadius: Auto.WHT(10),
698 | },
699 |
700 | listitemout11: {
701 | display: 'flex',
702 | flexDirection: 'row',
703 | alignItems: 'center',
704 | justifyContent: 'center',
705 | height: Auto.WHT(88),
706 | // paddingRight: Auto.WHT(30),
707 | },
708 | centertoptext11: {
709 | flex: 1,
710 | textAlign: 'center',
711 | color: '#888888',
712 | fontSize: Auto.WHT(26),
713 | lineHeight: Auto.WHT(37),
714 | // paddingLeft: Auto.WHT(30),
715 | },
716 |
717 | }
718 |
--------------------------------------------------------------------------------
/src/routes/DetailsList.js:
--------------------------------------------------------------------------------
1 | import React,{Component} from 'react'
2 | import { connect } from 'dva';
3 | import {routerRedux} from 'dva/router';
4 | import { injectIntl } from 'react-intl';
5 | import moment from "moment";
6 | import PropTypes from 'prop-types';
7 | import Auto from '../utils/Auto'
8 | import Utils from '../utils/Utils'
9 | import Constants from '../utils/Constants'
10 | import { Toast, PullToRefresh, ListView, Button, WhiteSpace, List, Modal} from 'antd-mobile';
11 | var ScreenWidth = document.documentElement.clientWidth;
12 | var ScreenHeight = document.documentElement.clientHeight;
13 | require('moment/locale/zh-cn');
14 |
15 | class DetailsList extends Component{
16 | constructor(props) {
17 | super(props);
18 | const dataSource = new ListView.DataSource({ rowHasChanged: (row1, row2) => row1 !== row2 });
19 | this.state = {
20 | dataSource,
21 | isbuysell: this.props.location.query ? this.props.location.query.isBuySell : localStorage.getItem('buy_sell'),
22 | data: []
23 | }
24 | }
25 | componentWillMount(){
26 | this.getListData();
27 | }
28 | componentDidMount() {
29 |
30 | }
31 | async getListData(){
32 | // alert(JSON.stringify(this.props.rexpool));
33 | let total_rex = 0.0000;
34 | let total_lendable = 0.0000;
35 | try {
36 | let s1 = Utils.sliceUnit(this.props.rexpool.total_rex);
37 | let s2 = Utils.sliceUnit(this.props.rexpool.total_lendable);
38 | total_rex = parseFloat(s1);
39 | total_lendable = parseFloat(s2);
40 | } catch (error) {
41 | total_rex = 0.0000;
42 | total_lendable = 0.0000;
43 | }
44 | // alert("total_rex="+total_rex+" total_lendable=" + total_lendable);
45 | let resp = await Utils.dispatchActiionData(this, { type: 'common/querySellRexInfo', payload:{account: this.props.account}});
46 | // let resp = [
47 | // {transaction: false, quantity: '9 REX', conversionratio: '1 EOS ≈ 500 REX', createdate: 1520840297000, },
48 | // ];
49 | // alert("resp"+JSON.stringify(resp));
50 | if(resp && resp.rows){
51 | let retArray = new Array();
52 | resp.rows.forEach(function(val,index){
53 | let price = 0;
54 | try {
55 | let s3 = Utils.sliceUnit(val.rex_requested);
56 | let amount = parseFloat(s3);
57 | let tmp1 = (total_lendable+amount).toFixed(4);
58 | let tmp2 = (total_rex*tmp1/total_lendable).toFixed(4);
59 | let tmp3 = (tmp2 - total_rex).toFixed(4);
60 | price = (tmp3/amount).toFixed(4);
61 | // alert("tmp1="+tmp1 + " tmp2=" + tmp2 + " tmp3=" + tmp3 +" price="+price);
62 | } catch (error) {
63 | price = 0;
64 | }
65 | retArray[index] = {
66 | transaction: false, quantity: val.rex_requested, conversionratio: '1 EOS ≈ '+price+' REX', createdate: val.order_time,
67 | };
68 | });
69 | this.setState({data: retArray});
70 | }else{
71 | Toast.info("暂无更多数据");
72 | }
73 | }
74 | onRefresh() {
75 |
76 | }
77 |
78 | onEndReached() {
79 |
80 | }
81 | async refundTransaction(){
82 | let actions = [{
83 | account: 'eosio',
84 | name: 'cnclrexorder',
85 | authorization: [{
86 | actor: this.props.account,
87 | permission: this.props.permission,
88 | }],
89 | data: {
90 | owner: this.props.account,
91 | },
92 | }];
93 | // alert('refundTransaction='+JSON.stringify(actions));
94 | let resp = await Utils.dispatchActiionData(this, { type: 'common/sendEosAction', payload:{actions: actions}});
95 | // alert("resp="+JSON.stringify(resp));
96 | if(resp){
97 | Toast.info("撤单成功");
98 | }else{
99 | Toast.info("撤单失败");
100 | }
101 | }
102 | onWithdraw = () => {
103 | Modal.alert('', '您是否撤回这次交易?', [
104 | { text: '取消', onPress: () => console.log('取消'), style: 'default' },
105 | { text: '确定', onPress: () => this.refundTransaction() },
106 | ]);
107 | }
108 |
109 | render() {
110 | return
111 |
this.lv = el}
115 | dataSource={this.state.dataSource.cloneWithRows(this.state.data)}
116 | pullToRefresh={
119 | }
120 | onEndReached={this.onEndReached}
121 | renderRow={this._renderRow}
122 | />
123 |
124 | }
125 |
126 | _renderRow= (rowData, sectionID, rowID) => {
127 | return (
128 |
129 |
{this.state.isbuysell ? '卖' : '买'}
130 |
{moment(rowData.createdate).format('MM-DD')}
131 |
{rowData.transaction ? '已成交' : '待成交'}
132 |
133 | {!rowData.transaction &&
}
134 |
135 |
136 | 出售数量:{rowData.quantity}
137 | 兑换比例:{rowData.conversionratio}
138 | 成交时间:{moment(rowData.createdate).format('HH:mm:ss')}
139 |
140 |
141 |
)
142 | }
143 |
144 | }
145 |
146 | export default connect(({ common,}) => ({ ...common,}))(injectIntl(DetailsList));
147 |
148 | const styles = {
149 | rootDiv: {
150 | width: ScreenWidth,
151 | height: ScreenHeight,
152 | background: '#F5F5F9',
153 | boxSizing: 'border-box',
154 | },
155 | rowDiv: {
156 | background: '#F5F5F9',
157 | },
158 | listTopout: {
159 | display:"flex",
160 | flexDirection: 'row',
161 | alignItems: 'center',
162 | height: Auto.WHT(88),
163 | paddingLeft: Auto.WHT(30),
164 | paddingRight: Auto.WHT(30),
165 | backgroundColor: '#FFFFFF',
166 | borderBottom: '1px #DDDDDD solid',
167 | },
168 | buyselltext: {
169 | color: '#000000',
170 | fontSize: Auto.WHT(34),
171 | lineHeight: Auto.WHT(48),
172 | },
173 | datetext: {
174 | color: '#BBBBBB',
175 | fontSize: Auto.WHT(34),
176 | lineHeight: Auto.WHT(48),
177 | paddingLeft: Auto.WHT(30),
178 | paddingRight: Auto.WHT(30),
179 | },
180 | clinchtext: {
181 | color: '#108EE9',
182 | textAlign: 'center',
183 | width: Auto.WHT(110),
184 | fontSize: Auto.WHT(28),
185 | lineHeight: Auto.WHT(42),
186 | border: '1px #108EE9 solid',
187 | },
188 | listTopbtn: {
189 | width: Auto.WHT(112),
190 | height: Auto.WHT(60),
191 | lineHeight: Auto.WHT(60),
192 | background: '#108EE9',
193 | border: 'none',
194 | textDecoration: 'none',
195 | borderRadius: Auto.WHT(6),
196 | fontSize: Auto.WHT(26),
197 | color: '#FFFFFF',
198 | },
199 | }
--------------------------------------------------------------------------------
/src/routes/GameDescription.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { ListView, Button, InputItem, } from 'antd-mobile';
3 | import { injectIntl } from 'react-intl';
4 | import { connect } from 'dva';
5 | import Auto from '../utils/Auto'
6 | import {routerRedux} from 'dva/router';
7 | import Constants from '../utils/Constants'
8 | require('moment/locale/zh-cn');
9 | var ScreenWidth = window.screen.width
10 | var ScreenHeight = window.screen.height
11 |
12 | class GameDescription extends React.Component {
13 | constructor(props) {
14 | super(props);
15 | this.state = {
16 | lease: this.props.location.query ? this.props.location.query.lease : false,
17 | };
18 | }
19 |
20 | componentDidMount() {
21 |
22 | }
23 |
24 | render() {
25 | return (
26 |
REX玩法说明
27 |
1、在进行买卖REX之前,用户必须要对至少21个节点投过票或代理投票,并且买入4天后方可卖出,之后就不需要进行节点投票。
28 |
2、如果REX里面没有足够的EOS,则排入队列,等到EOS足够再卖出,并且卖出时才计算REX价格,用户是可以取消尚未成交的卖出订单。
29 | {this.state.lease &&
30 |
31 |
租赁介绍
32 |
1、您可以根据自己的需要填写足量的CPU,NET,租用时长,默认接收账户是您当前使用的账户,可给当前账户租赁,还可以帮助朋友租赁,
33 | 默认接收账户是您当前使用账户,您可以修改为朋友账户,填写完成后,在订单确认里您可以看到当前可以租用的EOS金额,确认无误后,点击一键租赁完成资源租赁。
34 |
35 | }
36 |
37 | )
38 | }
39 | }
40 |
41 | export default connect(({ }) => ({ }))(injectIntl(GameDescription));
42 |
43 | const styles = {
44 | rootDiv:{
45 | width: ScreenWidth,
46 | height: ScreenHeight,
47 | background:"#F5F5F9",
48 | boxSizing: 'border-box',
49 | padding: Auto.WHT(30),
50 | },
51 | description: {
52 | color: '#000000',
53 | fontSize: Auto.WHT(48),
54 | lineHeight: Auto.WHT(67),
55 | paddingTop: Auto.WHT(10),
56 | },
57 | explaintext: {
58 | color: '#333333',
59 | fontSize: Auto.WHT(28),
60 | lineHeight: Auto.WHT(36),
61 | paddingTop: Auto.WHT(30),
62 | },
63 | descriptiontitle: {
64 | color: '#000000',
65 | fontSize: Auto.WHT(48),
66 | lineHeight: Auto.WHT(67),
67 | paddingTop: Auto.WHT(70),
68 | },
69 | }
70 |
--------------------------------------------------------------------------------
/src/routes/Index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Toast, ListView, Button, Progress, InputItem, List, WhiteSpace,Stepper} from 'antd-mobile';
3 | import { injectIntl } from 'react-intl';
4 | import { connect } from 'dva';
5 | import {routerRedux} from 'dva/router';
6 | import Auto from '../utils/Auto'
7 | import Utils from '../utils/Utils'
8 | import {formatEosQua} from '../utils/FormatUtil';
9 |
10 | require('moment/locale/zh-cn');
11 | var ScreenWidth = window.screen.width
12 | var ScreenHeight = window.screen.height
13 |
14 | class Index extends React.Component {
15 | constructor(props) {
16 | super(props);
17 | const dataSource = new ListView.DataSource({ rowHasChanged: (row1, row2) => row1 !== row2 });
18 | this.state = {
19 | dataSource,
20 | cpuval: 0.1,
21 | netval: 0.1,
22 | timeval: 30,
23 | cpuval_price: 0,
24 | netval_price: 0,
25 | toAccount: this.props.account,
26 | };
27 | }
28 |
29 | componentDidMount() {
30 | document.addEventListener('scatterLoaded', scatterExtension => {
31 | this.login();
32 | });
33 |
34 | setTimeout(()=>{
35 | this.login();
36 | }, 10);
37 | }
38 |
39 | async login() {
40 | let accountInfo = await Utils.dispatchActiionData(this, { type: 'common/login', payload:{}});
41 | if(!accountInfo){
42 | return;
43 | }
44 | this.setState({toAccount: accountInfo.name});
45 | let resp = await Utils.dispatchActiionData(this, { type: 'common/getRexInfo', payload:{}});
46 | if(resp){
47 | this.update_costval_cpu(this.state.cpuval);
48 | this.update_costval_net(this.state.netval);
49 | }
50 | }
51 |
52 | calc_costval(tmp_val){
53 | let val_price = 0;
54 | try {
55 | let total_rent = Utils.sliceUnit(this.props.rexpool.total_rent);
56 | let total_unlent = Utils.sliceUnit(this.props.rexpool.total_unlent);
57 | let float_total_rent = parseFloat(total_rent);
58 | let float_total_unlent = parseFloat(total_unlent);
59 | let val = parseFloat(tmp_val);
60 |
61 | let tmp = (float_total_rent + val).toFixed(4);
62 | let tmp1 = ((float_total_unlent*val)/tmp).toFixed(4);
63 | val_price = (tmp1/val).toFixed(4);
64 |
65 | // alert("tmp="+tmp + "tmp1="+tmp1 + " val_price="+val_price);
66 | } catch (error) {
67 | val_price = 0;
68 | }
69 | return val_price;
70 | }
71 | //计算 租赁 CPU价格
72 | update_costval_cpu(tmp_cpuval){
73 | let cpuval_price = this.calc_costval(tmp_cpuval);
74 | this.setState({cpuval_price: cpuval_price});
75 | }
76 | //计算 租赁 NET价格
77 | update_costval_net(tmp_netval){
78 | let netval_price = this.calc_costval(tmp_netval);
79 | this.setState({netval_price: netval_price});
80 | }
81 |
82 | onCpuChange = (cpuval) => {
83 | // console.log(val);
84 | this.setState({ cpuval });
85 | this.update_costval_cpu(cpuval);
86 | }
87 |
88 | onNetChange = (netval) => {
89 | // console.log(val);
90 | this.setState({ netval });
91 | this.update_costval_net(netval);
92 | }
93 |
94 | onTimeChange = (timeval) => {
95 | // console.log(val);
96 | this.setState({ timeval });
97 | }
98 |
99 | onbuysell = () => {
100 | this.props.dispatch(routerRedux.push({pathname: '/BuyandSell', query: { }}))
101 | }
102 |
103 | description = () => {
104 | this.props.dispatch(routerRedux.push({pathname: '/GameDescription', query: {lease:true}}))
105 | }
106 |
107 | doRent = async () => {
108 | if(!this.props.account){
109 | Toast.info("请先登录", 1);
110 | return;
111 | }
112 | try {
113 | let tmp_cpuval = parseFloat(this.state.cpuval);
114 | let cpu_loan_fund = ((this.state.timeval/30 -1) * tmp_cpuval).toFixed(4);
115 |
116 | let tmp_netval = parseFloat(this.state.netval);
117 | let net_loan_fund = ((this.state.timeval/30 -1) * tmp_netval).toFixed(4);
118 |
119 | let actions = [
120 | {
121 | account: 'eosio',
122 | name: 'deposit',
123 | authorization: [{
124 | actor: this.props.account,
125 | permission: this.props.permission,
126 | }],
127 | data: {
128 | owner: this.props.account,
129 | amount: formatEosQua( (this.state.cpuval + this.state.netval).toFixed(4) + ' EOS'),
130 | },
131 | },
132 | {
133 | account: 'eosio',
134 | name: 'rentcpu',
135 | authorization: [{
136 | actor: this.props.account,
137 | permission: this.props.permission,
138 | }],
139 | data: {
140 | from: this.props.account,
141 | receiver: this.state.toAccount,
142 | loan_payment: formatEosQua(this.state.cpuval + ' EOS'),
143 | loan_fund: cpu_loan_fund + ' EOS',
144 | },
145 | },
146 | {
147 | account: 'eosio',
148 | name: 'rentnet',
149 | authorization: [{
150 | actor: this.props.account,
151 | permission: this.props.permission,
152 | }],
153 | data: {
154 | from: this.props.account,
155 | receiver: this.state.toAccount,
156 | loan_payment: formatEosQua(this.state.netval + ' EOS'),
157 | loan_fund: net_loan_fund + ' EOS',
158 | },
159 | }
160 | ];
161 | let resp = await Utils.dispatchActiionData(this, { type: 'common/sendEosAction', payload:{actions: actions}});
162 | if(resp){
163 | Toast.info('交易成功');
164 | }else{
165 | Toast.info('交易失败');
166 | }
167 | } catch (error) {
168 |
169 | }
170 | }
171 |
172 | render() {
173 | return (
174 |
175 |
176 |
可出租资源:(EOS)
177 |
178 |
179 |
180 |
{Utils.sliceUnit(this.props.rexpool.total_unlent)}
181 |
187 |
188 |
189 |
190 |
191 |
192 |
租用资源
193 |
我的余额:{this.props.eosBalance} EOS
194 |
195 |
{'付款账户: ' + this.props.account}
196 |
this.setState({ toAccount })}
199 | ref={el => this.autoFocusInst = el}>接收账户:
200 |
201 |
202 |
203 |
204 |
205 |
租赁费用
206 |
209 |
210 | {this.onCpuChange(cpuval)}}/>}
213 | >CPU
214 | {this.onNetChange(netval)}}/>}
217 | >NET
218 | {this.onTimeChange(timeval)}}/>}
221 | >租用时长(天)
222 |
223 |
224 |
225 |
226 |
订单确认:
227 |
{this.props.account}为{this.state.toAccount}租赁抵押{this.state.timeval}天,花费{(this.state.cpuval + this.state.netval).toFixed(1)} EOS租赁CPU {this.state.cpuval_price},租赁NET {this.state.netval_price}。
228 |
229 |
230 |
)
231 | }
232 | }
233 |
234 | export default connect(({common, vote }) => ({...common, ...vote }))(injectIntl(Index));
235 |
236 | const styles = {
237 | rootDiv:{
238 | width: ScreenWidth,
239 | height: ScreenHeight,
240 | background:"#F8F8F8",
241 | boxSizing: 'border-box',
242 | },
243 |
244 | headtopout: {
245 | height: Auto.WHT(88),
246 | paddingLeft: Auto.WHT(30),
247 | paddingRight: Auto.WHT(30),
248 | display:"flex",
249 | flexDirection: 'row',
250 | alignItems: 'center',
251 | },
252 | headtoptext: {
253 | flex: 1,
254 | color: '#000000',
255 | fontSize: Auto.WHT(34),
256 | lineHeight: Auto.WHT(42),
257 | },
258 | headtopbtn: {
259 | width: Auto.WHT(164),
260 | height: Auto.WHT(60),
261 | lineHeight: Auto.WHT(60),
262 | background: '#FFFFFF',
263 | border: '1px #108EE9 solid',
264 | textDecoration: 'none',
265 | borderRadius: Auto.WHT(10),
266 | fontSize: Auto.WHT(26),
267 | color: '#108EE9',
268 | },
269 | headbottomout: {
270 | display: 'flex',
271 | flexDirection: 'column',
272 | padding: Auto.WHT(30),
273 | paddingTop: Auto.WHT(10),
274 | },
275 | headbottomtext: {
276 | color: '#000000',
277 | fontSize: Auto.WHT(48),
278 | lineHeight: Auto.WHT(67),
279 | paddingBottom: Auto.WHT(22),
280 | },
281 | progress: {
282 | height: Auto.WHT(34),
283 | background: '#FFFFFF',
284 | border: '1PX solid #E9E9E9',
285 | borderRadius: Auto.WHT(17)
286 | },
287 | barout: {
288 | background: '#108EE9',
289 | borderWidth: Auto.WHT(17),
290 | borderStyle: 'solid',
291 | borderColor: '#108EE9',
292 | borderRadius: Auto.WHT(17)
293 | },
294 | rentout: {
295 | width: '100%',
296 | display:"flex",
297 | flexDirection: 'row',
298 | alignItems: 'center',
299 | justifyContent: 'space-between',
300 | paddingTop: Auto.WHT(30),
301 | },
302 | renttext: {
303 | color: '#888888',
304 | fontSize: Auto.WHT(30),
305 | lineHeight: Auto.WHT(34),
306 | },
307 |
308 | centerDiv: {
309 | display: 'flex',
310 | flexDirection: 'column',
311 | background: '#FFFFFF',
312 | },
313 | centertop: {
314 | height: Auto.WHT(88),
315 | display:"flex",
316 | flexDirection: 'row',
317 | alignItems: 'center',
318 | justifyContent: 'space-between',
319 | borderBottom: '1px solid #DDDDDD',
320 | },
321 | centertoptitle: {
322 | color: '#000000',
323 | fontSize: Auto.WHT(30),
324 | lineHeight: Auto.WHT(84),
325 | paddingLeft: Auto.WHT(30),
326 | },
327 | centertoptext: {
328 | color: '#888888',
329 | fontSize: Auto.WHT(30),
330 | lineHeight: Auto.WHT(34),
331 | paddingRight: Auto.WHT(30),
332 | },
333 | centertopbtn: {
334 | border: 'none',
335 | borderRadius: 0,
336 | color: '#D9D9D9',
337 | padding: '0 0.4rem',
338 | height: Auto.WHT(36),
339 | textDecoration: 'none',
340 | },
341 | reportimg: {
342 | width: Auto.WHT(30),
343 | height: Auto.WHT(30),
344 | margin: 0,
345 | },
346 |
347 | footDiv: {
348 | flex: 1,
349 | padding: Auto.WHT(30),
350 | },
351 | description: {
352 | color: '#000000',
353 | fontSize: Auto.WHT(28),
354 | paddingTop: Auto.WHT(10),
355 | paddingBottom: Auto.WHT(10),
356 | },
357 | explaintext: {
358 | color: '#888888',
359 | fontSize: Auto.WHT(28),
360 | lineHeight: Auto.WHT(40),
361 | },
362 | footbtn: {
363 | width: '100%',
364 | height: Auto.WHT(94),
365 | lineHeight: Auto.WHT(94),
366 | background: '#108EE9',
367 | border: 'none',
368 | textDecoration: 'none',
369 | borderRadius: Auto.WHT(10),
370 | fontSize: Auto.WHT(36),
371 | color: '#FFFFFF',
372 | marginTop: Auto.WHT(40),
373 | marginBottom: Auto.WHT(40),
374 | },
375 | }
376 |
--------------------------------------------------------------------------------
/src/routes/MyRexDetails.js:
--------------------------------------------------------------------------------
1 | import React,{Component} from 'react'
2 | import { connect } from 'dva';
3 | import {routerRedux} from 'dva/router';
4 | import { injectIntl } from 'react-intl';
5 | import moment from "moment";
6 | import PropTypes from 'prop-types';
7 | import Auto from '../utils/Auto'
8 | import Utils from '../utils/Utils'
9 | import Constants from '../utils/Constants'
10 | import { Toast, PullToRefresh, ListView, Button, WhiteSpace, List, Modal} from 'antd-mobile';
11 | var ScreenWidth = document.documentElement.clientWidth;
12 | var ScreenHeight = document.documentElement.clientHeight;
13 | require('moment/locale/zh-cn');
14 |
15 | class MyRexDetails extends Component{
16 | constructor(props) {
17 | super(props);
18 | const dataSource = new ListView.DataSource({ rowHasChanged: (row1, row2) => row1 !== row2 });
19 | this.state = {
20 | dataSource,
21 | }
22 | }
23 | componentWillMount(){
24 |
25 | }
26 | componentDidMount() {
27 |
28 | }
29 |
30 | render() {
31 | return
32 | {/*
33 | 总量:{this.props.myRexInfo.total_rex + ' REX'}
34 | 可卖:{this.props.myRexInfo.sell_available_rex + ' REX'}
35 |
*/}
36 |
我的REX
37 |
总量:{this.props.myRexInfo.total_rex + ' REX'}
38 |
可卖:{this.props.myRexInfo.sell_available_rex + ' REX'}
39 |
this.lv = el}
43 | dataSource={this.state.dataSource.cloneWithRows(this.props.myRexInfo.rex_maturities)}
44 | renderRow={this._renderRow}
45 | />
46 |
47 | }
48 |
49 | _renderRow= (rowData, sectionID, rowID) => {
50 | return (
51 |
52 |
53 |
{(rowData.second/10000).toFixed(4)+ ' REX'}
54 |
{rowData.first + ' 解冻'}
55 |
56 |
)
57 | }
58 |
59 | }
60 |
61 | export default connect(({ rex,}) => ({ ...rex,}))(injectIntl(MyRexDetails));
62 |
63 | const styles = {
64 | rootDiv: {
65 | width: ScreenWidth,
66 | height: ScreenHeight,
67 | background: '#F5F5F9',
68 | boxSizing: 'border-box',
69 | },
70 | rowDiv: {
71 | background: '#F5F5F9',
72 | },
73 | listTopout: {
74 | display:"flex",
75 | flexDirection: 'row',
76 | alignItems: 'center',
77 | height: Auto.WHT(88),
78 | paddingLeft: Auto.WHT(30),
79 | paddingRight: Auto.WHT(30),
80 | backgroundColor: '#FFFFFF',
81 | borderBottom: '1px #DDDDDD solid',
82 | },
83 | datetext: {
84 | color: '#BBBBBB',
85 | fontSize: Auto.WHT(28),
86 | lineHeight: Auto.WHT(48),
87 | paddingLeft: Auto.WHT(30),
88 | paddingRight: Auto.WHT(30),
89 | },
90 | titletext: {
91 | background: '#FFFFFF',
92 | textAlign: 'center',
93 | fontSize: Auto.WHT(40),
94 | lineHeight: Auto.WHT(50),
95 | },
96 | headtext: {
97 | background: '#FFFFFF',
98 | fontSize: Auto.WHT(28),
99 | lineHeight: Auto.WHT(42),
100 | paddingLeft: Auto.WHT(30),
101 | paddingRight: Auto.WHT(30),
102 | paddingTop: Auto.WHT(10),
103 | },
104 | clinchtext: {
105 | background: '#FFFFFF',
106 | // color: '#108EE9',
107 | // textAlign: 'center',
108 | // width: Auto.WHT(110),
109 | fontSize: Auto.WHT(28),
110 | lineHeight: Auto.WHT(42),
111 | // border: '1px #108EE9 solid',
112 | },
113 | listTopbtn: {
114 | width: Auto.WHT(112),
115 | height: Auto.WHT(60),
116 | lineHeight: Auto.WHT(60),
117 | background: '#108EE9',
118 | border: 'none',
119 | textDecoration: 'none',
120 | borderRadius: Auto.WHT(6),
121 | fontSize: Auto.WHT(26),
122 | color: '#FFFFFF',
123 | },
124 | }
--------------------------------------------------------------------------------
/src/routes/NodeVoting.js:
--------------------------------------------------------------------------------
1 | import React,{Component} from 'react'
2 | import { connect } from 'dva';
3 | import {routerRedux} from 'dva/router';
4 | import { injectIntl } from 'react-intl';
5 | import moment from "moment";
6 | import PropTypes from 'prop-types';
7 | import Auto from '../utils/Auto'
8 | import Utils from '../utils/Utils'
9 | import { Toast, PullToRefresh, ListView, Button, WhiteSpace, List, Modal, Checkbox} from 'antd-mobile';
10 | var ScreenWidth = document.documentElement.clientWidth;
11 | var ScreenHeight = document.documentElement.clientHeight;
12 | const CheckboxItem = Checkbox.CheckboxItem;
13 | require('moment/locale/zh-cn');
14 |
15 | class NodeVoting extends Component{
16 | constructor(props) {
17 | super(props);
18 | const dataSource = new ListView.DataSource({ rowHasChanged: (row1, row2) => row1 !== row2 });
19 | this.state = {
20 | dataSource,
21 | selected: 0,
22 | producers: []
23 | }
24 | }
25 |
26 | componentDidMount() {
27 | this.onRefresh();
28 | }
29 |
30 | onRefresh() {
31 | this.getVoteInfo();
32 | }
33 |
34 | onEndReached() {
35 |
36 | }
37 |
38 | async getVoteInfo(){
39 | try {
40 | let producers = await Utils.dispatchActiionData(this, { type: 'vote/listProducers', payload:{}});
41 | let selected = 0;
42 | producers.forEach((item) => {
43 | if(item.isSelect){
44 | selected++;
45 | }
46 | })
47 | this.setState({producers: producers, selected: selected});
48 | } catch (error) {
49 |
50 | }
51 | }
52 |
53 | getVoteActions = () => {
54 | let producers = [];
55 | this.state.producers.forEach((p) => {
56 | if(p.isSelect){
57 | producers.push(p.owner);
58 | }
59 | });
60 | producers.sort();
61 |
62 | let actions = [{
63 | account: 'eosio',
64 | name: 'voteproducer',
65 | authorization: [{
66 | actor: this.props.account,
67 | permission: this.props.permission,
68 | }],
69 | data: {
70 | voter: this.props.account,
71 | proxy: '',
72 | producers: producers,
73 | },
74 | }];
75 |
76 | return actions;
77 | }
78 |
79 | async doVote (){
80 | let actions = this.getVoteActions();
81 | let resp = await Utils.dispatchActiionData(this, { type: 'common/sendEosAction', payload:{actions: actions}});
82 | if(resp && resp.transaction_id){
83 | Toast.info("投票成功");
84 | return;
85 | }
86 |
87 | Toast.info("投票失败");
88 | }
89 |
90 | voteProc = () =>{
91 | if(this.state.selected < 21){
92 | let dialog = Modal.alert('温馨提示', 您的选择少于21个节点,交易REX必须要对至少21个节点投过票或代理投票,确定进行投票?
, [
93 | { text: '重新选择', onPress: () => {}},
94 | { text: '确定', onPress: () =>{dialog.close(); this.doVote()}},
95 | ])
96 | return;
97 | }
98 |
99 | this.doVote();
100 | }
101 |
102 | selectItem = (rowData) => {
103 | let newdata = new Array();
104 | let quantity = 0;
105 | this.state.producers.forEach((item) => {
106 | if(item.owner == rowData.owner){
107 | item.isSelect = !item.isSelect;
108 | }
109 |
110 | if(item.isSelect){
111 | quantity++;
112 | }
113 | newdata.push(item);
114 | })
115 |
116 | this.setState({producers: newdata, selected: quantity});
117 | }
118 | render() {
119 | return
120 |
121 |

122 |
节点投票
123 |
1、在进行买卖REX之前,用户必须要对至少21个节点投过票或代理投票。
124 |
2、在进行投票前,用户需要进行EOS抵押换取投票权。
125 |
126 |
127 |
this.lv = el}
131 | style={{paddingLeft: Auto.WHT(30), backgroundColor: '#FFFFFF', paddingBottom: Auto.WHT(100), }}
132 | dataSource={this.state.dataSource.cloneWithRows(this.state.producers)}
133 | pullToRefresh={
136 | }
137 | onEndReached={this.onEndReached}
138 | renderRow={this._renderRow}
139 | />
140 |
141 |
已选节点:{this.state.selected}/21
142 |
143 |
144 |
145 | }
146 |
147 | _renderRow = (rowData, sectionID, rowID) => {
148 | return (
149 |

150 |
151 |
{rowData.owner}
152 | {/*
{rowData.region}
*/}
153 |
154 |
}/>
156 |
)
157 | }
158 |
159 | }
160 |
161 | export default connect(({ common, rex, vote }) => ({ ...common, ...rex, ...vote }))(injectIntl(NodeVoting));
162 |
163 | const styles = {
164 | rootDiv: {
165 | width: ScreenWidth,
166 | height: ScreenHeight,
167 | background: '#F5F5F9',
168 | boxSizing: 'border-box',
169 |
170 | },
171 | headerDiv: {
172 | display:"flex",
173 | alignItems: 'center',
174 | background: '#FFFFFF',
175 | flexDirection: 'column',
176 | paddingTop: Auto.WHT(40),
177 | paddingLeft: Auto.WHT(30),
178 | paddingRight: Auto.WHT(30),
179 | },
180 | headerimg: {
181 | width: Auto.WHT(133),
182 | height: Auto.WHT(133),
183 | },
184 | headertitle: {
185 | color: '#333333',
186 | padding: Auto.WHT(20),
187 | fontSize: Auto.WHT(28),
188 | lineHeight: Auto.WHT(36),
189 | },
190 | headertext: {
191 | color: '#333333',
192 | fontSize: Auto.WHT(28),
193 | lineHeight: Auto.WHT(36),
194 | paddingBottom: Auto.WHT(30),
195 | },
196 |
197 | rowDiv: {
198 | display:"flex",
199 | flexDirection: 'row',
200 | alignItems: 'center',
201 | paddingTop: Auto.WHT(18),
202 | paddingBottom: Auto.WHT(18),
203 | background: '#FFFFFF',
204 | borderBottom: '1px #DDDDDD solid',
205 | },
206 | nodeimg: {
207 | width: Auto.WHT(100),
208 | height: Auto.WHT(100),
209 | },
210 | rownodeout: {
211 | flex: 1,
212 | paddingLeft: Auto.WHT(30),
213 | },
214 | nodename: {
215 | color: '#000000',
216 | fontSize: Auto.WHT(34),
217 | lineHeight: Auto.WHT(48),
218 | },
219 | regiontext: {
220 | color: '#888888',
221 | fontSize: Auto.WHT(28),
222 | lineHeight: Auto.WHT(40),
223 | },
224 | buyselltext: {
225 | color: '#000000',
226 | fontSize: Auto.WHT(34),
227 | lineHeight: Auto.WHT(48),
228 | },
229 | datetext: {
230 | color: '#BBBBBB',
231 | fontSize: Auto.WHT(34),
232 | lineHeight: Auto.WHT(48),
233 | paddingLeft: Auto.WHT(30),
234 | paddingRight: Auto.WHT(30),
235 | },
236 | clinchtext: {
237 | color: '#108EE9',
238 | textAlign: 'center',
239 | width: Auto.WHT(110),
240 | fontSize: Auto.WHT(28),
241 | lineHeight: Auto.WHT(42),
242 | border: '1px #108EE9 solid',
243 | },
244 | listbtn: {
245 | border: 'none',
246 | borderRadius: 0,
247 | color: '#FFFFFF',
248 | textDecoration: 'none',
249 | fontSize: Auto.WHT(26),
250 | },
251 | listbtnimg: {
252 | width: Auto.WHT(42),
253 | height: Auto.WHT(42),
254 | margin: Auto.WHT(30),
255 | },
256 |
257 | footDiv: {
258 | width: ScreenWidth,
259 | bottom: 0,
260 | display:"flex",
261 | position: 'fixed',
262 | flexDirection: 'row',
263 | alignItems: 'center',
264 | backgroundColor: '#FFFFFF',
265 | borderTop: '1px #DDDDDD solid',
266 | },
267 | foottext: {
268 | flex: 1,
269 | color: '#000000',
270 | fontSize: Auto.WHT(28),
271 | lineHeight: Auto.WHT(40),
272 | paddingLeft: Auto.WHT(20),
273 | },
274 | footbtn: {
275 | width: Auto.WHT(230),
276 | height: Auto.WHT(100),
277 | lineHeight: Auto.WHT(100),
278 | background: '#108EE9',
279 | border: 'none',
280 | textDecoration: 'none',
281 | borderRadius: 0,
282 | fontSize: Auto.WHT(36),
283 | color: '#FFFFFF',
284 | },
285 | }
--------------------------------------------------------------------------------
/src/routes/Withdraw.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Toast, Button, Modal, InputItem,} from 'antd-mobile';
3 | import { injectIntl } from 'react-intl';
4 | import { connect } from 'dva';
5 | import Auto from '../utils/Auto';
6 | import Utils from '../utils/Utils';
7 | import {formatEosQua} from '../utils/FormatUtil';
8 |
9 | require('moment/locale/zh-cn');
10 | var ScreenWidth = window.screen.width
11 | var ScreenHeight = window.screen.height
12 | const alert = Modal.alert;
13 |
14 |
15 | class Withdraw extends React.Component {
16 | constructor(props) {
17 | super(props);
18 | this.state = {
19 | balance: this.props.location.query ? this.props.location.query.balance : '0.0000',
20 | quantity: '',
21 | };
22 | }
23 |
24 | componentDidMount() {
25 | // Utils.dispatchActiionData(this, { type: 'rex/getMyRexInfo', payload:{account: this.props.account}});
26 | }
27 |
28 |
29 | sendWithdraw = async () => {
30 | try {
31 | let quantity = parseFloat(this.state.quantity).toFixed(4);
32 | let banlance = parseFloat(this.state.balance).toFixed(4);
33 | if(quantity < 0.0001){
34 | Toast.info('请输入提现数量');
35 | return ;
36 | }
37 | if(quantity > banlance){
38 | Toast.info('余额不足');
39 | return ;
40 | }
41 | let actions = [{
42 | account: 'eosio',
43 | name: 'withdraw',
44 | authorization: [{
45 | actor: this.props.account,
46 | permission: this.props.permission,
47 | }],
48 | data: {
49 | owner: this.props.account,
50 | amount: formatEosQua(this.state.quantity + ' EOS'),
51 | },
52 | }];
53 | console.log('sendWithdraw actions=',JSON.stringify(actions));
54 | let resp = await Utils.dispatchActiionData(this, { type: 'common/sendEosAction', payload:{actions: actions}});
55 | console.log('sendWithdraw resp=',JSON.stringify(resp));
56 | if(resp){
57 | //更新EOS 余额
58 | Utils.dispatchActiionData(this, { type: 'common/getAccountInfo', payload:{account: this.props.account}});
59 | Toast.info("成功");
60 | window.history.go(-1);
61 | }else{
62 | Toast.info("失败");
63 | }
64 | } catch (error) {
65 |
66 | }
67 | }
68 |
69 |
70 | render() {
71 | return (
72 |
73 |
74 |

75 |
余额: {this.state.balance} EOS
76 |
收款账户:{ this.props.account}
77 |
78 |
79 | this.autoFocusInst = el} onChange={(quantity) => this.setState({ quantity: Utils.chkEosQuantity(quantity) })} >提现数量:
80 |
81 |
82 |
83 |
84 |
85 |
)
86 | }
87 | }
88 |
89 | export default connect(({ common, rex }) => ({ ...common, ...rex }))(injectIntl(Withdraw));
90 |
91 | const styles = {
92 | rootDiv:{
93 | width: ScreenWidth,
94 | height: ScreenHeight,
95 | background:"#F8F8F8",
96 | boxSizing: 'border-box',
97 | },
98 |
99 | headtopout: {
100 | display:"flex",
101 | flexDirection: 'column',
102 | alignItems: 'center',
103 | justifyContent: 'center',
104 | paddingTop: Auto.WHT(61),
105 | paddingBottom: Auto.WHT(75),
106 | },
107 |
108 | headbottomleft: {
109 | color: '#333333',
110 | fontSize: Auto.WHT(34),
111 | lineHeight: Auto.WHT(42),
112 | paddingTop: Auto.WHT(25),
113 | },
114 | centertoptext: {
115 | color: '#888888',
116 | fontSize: Auto.WHT(30),
117 | lineHeight: Auto.WHT(34),
118 | paddingTop: Auto.WHT(18),
119 | },
120 | reportimg: {
121 | width: Auto.WHT(120),
122 | height: Auto.WHT(120),
123 | margin: 0,
124 | },
125 | listitemout: {
126 | display: 'flex',
127 | flexDirection: 'row',
128 | alignItems: 'center',
129 | height: Auto.WHT(90),
130 | boxSizing: 'border-box',
131 | borderTop: '1px #DDDDDD solid',
132 | borderBottom: '1px #DDDDDD solid',
133 | },
134 | footDiv: {
135 | width: ScreenWidth,
136 | boxSizing: 'border-box',
137 | paddingTop: Auto.WHT(40),
138 | paddingLeft: Auto.WHT(30),
139 | paddingRight: Auto.WHT(30),
140 | paddingBottom: Auto.WHT(40),
141 |
142 | },
143 | footbtn: {
144 | width: '100%',
145 | border: 'none',
146 | color: '#FFFFFF',
147 | height: Auto.WHT(94),
148 | background: '#108EE9',
149 | textDecoration: 'none',
150 | fontSize: Auto.WHT(36),
151 | lineHeight: Auto.WHT(94),
152 | borderRadius: Auto.WHT(10),
153 | },
154 | }
155 |
--------------------------------------------------------------------------------
/src/utils/Api.js:
--------------------------------------------------------------------------------
1 |
2 | var rootaddr = "";
3 | export const getBigRamRank = rootaddr + '/ramprice/getLargeRamRank';
--------------------------------------------------------------------------------
/src/utils/Auto.js:
--------------------------------------------------------------------------------
1 | export default {
2 | WHT: function (value) {
3 | return (value/75).toExponential(2) + 'rem';
4 | },
5 | }
--------------------------------------------------------------------------------
/src/utils/Constants.js:
--------------------------------------------------------------------------------
1 | export default {
2 | loginUser:null,
3 | token:null,
4 | uid: '',
5 | PWD_MIN_LENGTH:4, //密码最小长度
6 | PWD_MAX_LENGTH:18, //密码最大长度
7 | isNetWorkOffline:false,
8 | FitPhone: 20,
9 | };
--------------------------------------------------------------------------------
/src/utils/EosUtil.js:
--------------------------------------------------------------------------------
1 | import '../shim.js'
2 | import eos from 'eosjs'
3 | var ecc = require('eosjs-ecc');
4 |
5 | const RPC_API_URL = "http://47.52.250.41:8001";
6 |
7 | export class Eos {
8 | static respSucc(e){
9 | return {isSuccess:!0,msg:"success",data:e};
10 | }
11 |
12 | static respErr(e){
13 | return {isSuccess:!1,msg:"error",data:e};
14 | }
15 |
16 | static getEos(){
17 | config = {
18 | httpEndpoint: RPC_API_URL,
19 | chainId: "aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906",
20 | }
21 |
22 | var eoss = eos(config);
23 | return eoss;
24 | }
25 |
26 |
27 | static getInfo(){
28 | let eos = Eos.getEos();
29 | return eos.getInfo({}).then(info => {
30 | return info;
31 | });
32 | }
33 |
34 | static checkPrivateKey(privatekey,callback){
35 | try{
36 | if(ecc.isValidPrivate(privatekey)){
37 | callback(Eos.respSucc(!0));
38 | }else{
39 | callback(Eos.respErr({code:500,msg:"私钥格式错误"}));
40 | }
41 | }catch(t){
42 | callback(Eos.respErr({code:500,msg:"校验私钥失败"}));
43 | }
44 | }
45 |
46 | static privateToPublic(privateKey,callback){
47 | try{
48 | var publicKey=ecc.privateToPublic(privateKey);
49 | callback(Eos.respSucc({publicKey:publicKey}));
50 | }catch(t){
51 | callback(Eos.respErr({code:500,msg:"生成公钥失败"}));
52 | }
53 | }
54 |
55 | /**
56 | * 生成随机私钥
57 | * @param {回调函数} callback
58 | */
59 | static randomPrivateKey(callback){
60 | try{
61 | ecc.randomKey().then(privateKey => {
62 | alert('Private Key:\t', privateKey) // wif
63 | alert('Public Key:\t', ecc.privateToPublic(privateKey)) // EOSkey...
64 | })
65 | // ecc.randomKey().then(t =>{
66 | // alert(t)
67 | // if(t){
68 | // var e=t;
69 | // var r=ecc.privateToPublic(e);
70 | // callback(Eos.respSucc({ownerPrivate:e,ownerPublic:r}));
71 | // }else{
72 | // callback(Eos.respErr({code:500,msg:"生成私钥失败"}));
73 | // }
74 | // }).catch(function(t){
75 | // alert("222");
76 | // callback(Eos.respErr({code:500,msg:"生成私钥失败"}));
77 | // })
78 | }catch(t){
79 | callback(Eos.respErr({code:500,msg:"生成私钥失败"}));
80 | }
81 | }
82 | }
83 |
84 |
--------------------------------------------------------------------------------
/src/utils/EventEmitter.js:
--------------------------------------------------------------------------------
1 | import { EventEmitter } from "events";
2 | export default new EventEmitter();
3 |
--------------------------------------------------------------------------------
/src/utils/FormatUtil.js:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | * Copyright 2016-present reading
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | */
18 | export const formatDateString = (timestamp) => {
19 | if (timestamp === undefined) {
20 | return '';
21 | }
22 | const date = new Date(parseInt(timestamp) * 1000);
23 | const year = date.getFullYear();
24 | const month = parseInt(date.getMonth()) + 1;
25 | const day = date.getDate();
26 | return `${year}-${month}-${day}`;
27 | };
28 |
29 | export const formatStringWithHtml = (originString) => {
30 | if (originString === undefined) {
31 | return '';
32 | }
33 | const newString = originString
34 | .replace(/ /g, ' ')
35 | .replace(/"/g, '"')
36 | .replace(/&/g, '&')
37 | .replace(/</g, '<')
38 | .replace(/>/g, '>');
39 | return newString;
40 | };
41 |
42 | export const formatterNumber = (number) =>{
43 | return (number || 0).toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,');
44 | }
45 | export const formatterUnit = (number) =>{
46 | if(number>100000000){
47 | let f = number/100000000;
48 | let value = Math.floor(f * 100) / 100;
49 | return value+"亿"
50 | }else if(number>10000){
51 | let f = number/10000;
52 | let value = Math.floor(f * 100) / 100;
53 | return value+"万"
54 | }else{
55 | return number;
56 | }
57 | }
58 |
59 | export const formatEosQua = (amount, precision = 4) =>{
60 | var e = amount.split(" ");
61 | // if(e.length > 1 && e[1] == "IQ"){
62 | // precision = 3;
63 | // }
64 | // if(e.length > 1 && e[1] == "QB"){
65 | // return amount; // QB精度为1,这里不做精度转换
66 | // }
67 | if(precision === 0){
68 | return amount;
69 | }
70 | let r=e[0].split(".");
71 | if(r.length>1){
72 | if(r[1].length <= precision){
73 | var n=precision-r[1].length;
74 | amount=e[0];
75 | for(var i=0;i {
4 | const request1 = new Promise((resolve, reject) => {
5 | fetch(url,{
6 | method: method,
7 | headers: {
8 | 'Content-Type': 'application/json;charset=utf-8',
9 | // "uid":Constants.uid|'',
10 | // "token":Constants.token,
11 | // "version":Constants.version,
12 | // "os":Constants.os,
13 | // "osVersion":Constants.osVersion,
14 | // "model":Constants.model,
15 | // "deviceId":Constants.deviceId
16 | },
17 | body:JSON.stringify(body)
18 | }).then((response) => {
19 | return response.json();
20 | }).then((responseData) => {
21 | resolve(responseData);
22 | }).catch((error) => {
23 | reject(error);
24 | });
25 | });
26 |
27 | // 定义一个延时函数
28 | const timeoutRequest = new Promise((resolve, reject) => {
29 | setTimeout(reject, timeout, 'Request timed out');
30 | });
31 |
32 | // 竞时函数,谁先完成调用谁
33 | return Promise.race([request1, timeoutRequest]).then(res => {
34 | return res
35 | }, m => {
36 | throw new Error(m);
37 | });
38 | };
39 |
40 | const request = (url,method,body, timeout = 30000)=>{
41 | if(Constants.isNetWorkOffline){
42 | return { code: 500, msg: '网络繁忙,请稍后再试' };
43 | }
44 | return getRootaddr().then(res=>{
45 | let okUrl = url
46 | let rootaddr = res
47 | if(okUrl.indexOf("/")==0){
48 | okUrl = rootaddr+url
49 | }
50 | return requestO(okUrl, method, body, timeout)
51 | }).catch(e=>{
52 | console.log(e);
53 | return { code: 500, msg: '网络繁忙,请稍后再试' };
54 | })
55 | };
56 |
57 | const getRootaddr = ()=>{
58 | return requestO(Constants.gateurl, 'post',{}).then(res => {
59 | Constants.rootaddr = res.url
60 | return Constants.rootaddr;
61 | }).catch(e=>{
62 | console.log(e);
63 | Constants.rootaddr = Constants.defaultrootaddr
64 | return Constants.rootaddr;
65 | })
66 | }
67 |
68 | export default {
69 | request,
70 | requestO,
71 | getRootaddr
72 | };
73 |
--------------------------------------------------------------------------------
/src/utils/Utils.js:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | * Copyright 2016-present reading
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | */
18 |
19 | export default class Utils {
20 |
21 | static async sendActionToModel(context,action) {
22 | let pthis = context;
23 | var p = new Promise(function (resolve, reject) {
24 | action.callback=(ret) => {
25 | // 只要回调 有调用 就返回 不管是返回对
26 | resolve(ret);
27 | }
28 | pthis.props.dispatch(action);
29 | });
30 | return p;
31 | }
32 |
33 | static async dispatchActiionData(context, action) {
34 | if(!action.hasOwnProperty("type"))
35 | {
36 | console.error("action hava not type");
37 | return;
38 | }
39 | if(action.hasOwnProperty("callback"))
40 | {
41 | console.error("callback action is not allowed");
42 | }
43 | return await Utils.sendActionToModel(context,action);
44 | }
45 |
46 | static sliceUnit(val){
47 | try {
48 | var e = val.split(" ");
49 | return e[0];
50 | } catch (error) {
51 | return '0.0000';
52 | }
53 | }
54 |
55 | static chkEosQuantity(obj) {
56 | obj = obj.replace(/[^\d.]/g, ""); //清除 "数字"和 "."以外的字符
57 | obj = obj.replace(/^\./g, ""); //验证第一个字符是否为数字
58 | obj = obj.replace(/\.{2,}/g, "."); //只保留第一个小数点,清除多余的
59 | obj = obj
60 | .replace(".", "$#$")
61 | .replace(/\./g, "")
62 | .replace("$#$", ".");
63 | obj = obj.replace(/^(\-)*(\d+)\.(\d\d\d\d).*$/,'$1$2.$3'); //只能输入四个小数
64 | // var max = 9999999999.9999; // 100亿 -1
65 | // var min = 0.0000;
66 | // var value = 0.0000;
67 | // var floatbalance;
68 | // try {
69 | // value = parseFloat(obj);
70 | // floatbalance = parseFloat(this.state.balance);
71 | // } catch (error) {
72 | // value = 0.0000;
73 | // floatbalance = 0.0000;
74 | // }
75 | // if(value < min|| value > max){
76 | // EasyToast.show(Translate.getT("输入错误"));
77 | // obj = "";
78 | // }
79 | // if (value > floatbalance) {
80 | // EasyToast.show(Translate.getT('账户余额不足,请重输'));
81 | // obj = "";
82 | // }
83 | return obj;
84 | }
85 |
86 | static async isTimeExpire(tUs){
87 | var myDate = new Date();
88 | var now = myDate.valueOf();
89 | var time = new Date(tUs).valueOf();
90 | if(now <= time){
91 | return true;
92 | }else{
93 | return false;
94 | }
95 | }
96 | }
--------------------------------------------------------------------------------