88a5d542 by simon

Merge branch 'master' of 120.27.44.69:dev/pingan-life-index-pro

2 parents e4b1fe00 0125693b
NODE_ENV = 'sandbox'
VUE_APP_TITLE = 'sandbox'
REQUEST_DOMAIN= 'https://ow.go.qudone.com'
RSA_PUBLIC_KEY = 'B5FE03847F02046C47292AF0FF2DE88977241483DD40C123046EB39CBE4C48167B120096CFF12CD16559322884A3C56FA92B07B89AB51FC8C91A75127622151DDD730DFF1F993D5A290CEAC0BBA7FC88285D8994ACBAFF50101EDE9A0925AD5DFFAFE96D53C370E9C5B37DF2F871F81C4D7CA6B7EC37FF459C07975AD9A74A95'
RSA_KEY_INDEX = '10001'
\ No newline at end of file
......
......@@ -18,6 +18,7 @@
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
<script src="./js/unionrsa.js"></script>
</body>
</html>
......
var dbits;
var canary = 0xdeadbeefcafe;
var j_lm = ((canary&0xffffff)==0xefcafe);
function BigInteger(a,b,c) {
if(a != null)
if("number" == typeof a) this.fromNumber(a,b,c);
else if(b == null && "string" != typeof a) this.fromString(a,256);
else this.fromString(a,b);
}
function nbi() { return new BigInteger(null); }
function am1(i,x,w,j,c,n) {
while(--n >= 0) {
var v = x*this[i++]+w[j]+c;
c = Math.floor(v/0x4000000);
w[j++] = v&0x3ffffff;
}
return c;
}
function am2(i,x,w,j,c,n) {
var xl = x&0x7fff, xh = x>>15;
while(--n >= 0) {
var l = this[i]&0x7fff;
var h = this[i++]>>15;
var m = xh*l+h*xl;
l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff);
c = (l>>>30)+(m>>>15)+xh*h+(c>>>30);
w[j++] = l&0x3fffffff;
}
return c;
}
function am3(i,x,w,j,c,n) {
var xl = x&0x3fff, xh = x>>14;
while(--n >= 0) {
var l = this[i]&0x3fff;
var h = this[i++]>>14;
var m = xh*l+h*xl;
l = xl*l+((m&0x3fff)<<14)+w[j]+c;
c = (l>>28)+(m>>14)+xh*h;
w[j++] = l&0xfffffff;
}
return c;
}
if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) {
BigInteger.prototype.am = am2;
dbits = 30;
}
else if(j_lm && (navigator.appName != "Netscape")) {
BigInteger.prototype.am = am1;
dbits = 26;
}
else {
BigInteger.prototype.am = am3;
dbits = 28;
}
BigInteger.prototype.DB = dbits;
BigInteger.prototype.DM = ((1<<dbits)-1);
BigInteger.prototype.DV = (1<<dbits);
var BI_FP = 52;
BigInteger.prototype.FV = Math.pow(2,BI_FP);
BigInteger.prototype.F1 = BI_FP-dbits;
BigInteger.prototype.F2 = 2*dbits-BI_FP;
var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
var BI_RC = new Array();
var rr,vv;
rr = "0".charCodeAt(0);
for(vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv;
rr = "a".charCodeAt(0);
for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
rr = "A".charCodeAt(0);
for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
function int2char(n) { return BI_RM.charAt(n); }
function intAt(s,i) {
var c = BI_RC[s.charCodeAt(i)];
return (c==null)?-1:c;
}
function bnpCopyTo(r) {
for(var i = this.t-1; i >= 0; --i) r[i] = this[i];
r.t = this.t;
r.s = this.s;
}
function bnpFromInt(x) {
this.t = 1;
this.s = (x<0)?-1:0;
if(x > 0) this[0] = x;
else if(x < -1) this[0] = x+DV;
else this.t = 0;
}
function nbv(i) { var r = nbi(); r.fromInt(i); return r; }
function bnpFromString(s,b) {
var k;
if(b == 16) k = 4;
else if(b == 8) k = 3;
else if(b == 256) k = 8;
else if(b == 2) k = 1;
else if(b == 32) k = 5;
else if(b == 4) k = 2;
else { this.fromRadix(s,b); return; }
this.t = 0;
this.s = 0;
var i = s.length, mi = false, sh = 0;
while(--i >= 0) {
var x = (k==8)?s[i]&0xff:intAt(s,i);
if(x < 0) {
if(s.charAt(i) == "-") mi = true;
continue;
}
mi = false;
if(sh == 0)
this[this.t++] = x;
else if(sh+k > this.DB) {
this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<<sh;
this[this.t++] = (x>>(this.DB-sh));
}
else
this[this.t-1] |= x<<sh;
sh += k;
if(sh >= this.DB) sh -= this.DB;
}
if(k == 8 && (s[0]&0x80) != 0) {
this.s = -1;
if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)<<sh;
}
this.clamp();
if(mi) BigInteger.ZERO.subTo(this,this);
}
function bnpClamp() {
var c = this.s&this.DM;
while(this.t > 0 && this[this.t-1] == c) --this.t;
}
function bnToString(b) {
if(this.s < 0) return "-"+this.negate().toString(b);
var k;
if(b == 16) k = 4;
else if(b == 8) k = 3;
else if(b == 2) k = 1;
else if(b == 32) k = 5;
else if(b == 4) k = 2;
else return this.toRadix(b);
var km = (1<<k)-1, d, m = false, r = "", i = this.t;
var p = this.DB-(i*this.DB)%k;
if(i-- > 0) {
if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); }
while(i >= 0) {
if(p < k) {
d = (this[i]&((1<<p)-1))<<(k-p);
d |= this[--i]>>(p+=this.DB-k);
}
else {
d = (this[i]>>(p-=k))&km;
if(p <= 0) { p += this.DB; --i; }
}
if(d > 0) m = true;
if(m) r += int2char(d);
}
}
return m?r:"0";
}
function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; }
function bnAbs() { return (this.s<0)?this.negate():this; }
function bnCompareTo(a) {
var r = this.s-a.s;
if(r != 0) return r;
var i = this.t;
r = i-a.t;
if(r != 0) return r;
while(--i >= 0) if((r=this[i]-a[i]) != 0) return r;
return 0;
}
function nbits(x) {
var r = 1, t;
if((t=x>>>16) != 0) { x = t; r += 16; }
if((t=x>>8) != 0) { x = t; r += 8; }
if((t=x>>4) != 0) { x = t; r += 4; }
if((t=x>>2) != 0) { x = t; r += 2; }
if((t=x>>1) != 0) { x = t; r += 1; }
return r;
}
function bnBitLength() {
if(this.t <= 0) return 0;
return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM));
}
function bnpDLShiftTo(n,r) {
var i;
for(i = this.t-1; i >= 0; --i) r[i+n] = this[i];
for(i = n-1; i >= 0; --i) r[i] = 0;
r.t = this.t+n;
r.s = this.s;
}
function bnpDRShiftTo(n,r) {
for(var i = n; i < this.t; ++i) r[i-n] = this[i];
r.t = Math.max(this.t-n,0);
r.s = this.s;
}
function bnpLShiftTo(n,r) {
var bs = n%this.DB;
var cbs = this.DB-bs;
var bm = (1<<cbs)-1;
var ds = Math.floor(n/this.DB), c = (this.s<<bs)&this.DM, i;
for(i = this.t-1; i >= 0; --i) {
r[i+ds+1] = (this[i]>>cbs)|c;
c = (this[i]&bm)<<bs;
}
for(i = ds-1; i >= 0; --i) r[i] = 0;
r[ds] = c;
r.t = this.t+ds+1;
r.s = this.s;
r.clamp();
}
function bnpRShiftTo(n,r) {
r.s = this.s;
var ds = Math.floor(n/this.DB);
if(ds >= this.t) { r.t = 0; return; }
var bs = n%this.DB;
var cbs = this.DB-bs;
var bm = (1<<bs)-1;
r[0] = this[ds]>>bs;
for(var i = ds+1; i < this.t; ++i) {
r[i-ds-1] |= (this[i]&bm)<<cbs;
r[i-ds] = this[i]>>bs;
}
if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<<cbs;
r.t = this.t-ds;
r.clamp();
}
function bnpSubTo(a,r) {
var i = 0, c = 0, m = Math.min(a.t,this.t);
while(i < m) {
c += this[i]-a[i];
r[i++] = c&this.DM;
c >>= this.DB;
}
if(a.t < this.t) {
c -= a.s;
while(i < this.t) {
c += this[i];
r[i++] = c&this.DM;
c >>= this.DB;
}
c += this.s;
}
else {
c += this.s;
while(i < a.t) {
c -= a[i];
r[i++] = c&this.DM;
c >>= this.DB;
}
c -= a.s;
}
r.s = (c<0)?-1:0;
if(c < -1) r[i++] = this.DV+c;
else if(c > 0) r[i++] = c;
r.t = i;
r.clamp();
}
function bnpMultiplyTo(a,r) {
var x = this.abs(), y = a.abs();
var i = x.t;
r.t = i+y.t;
while(--i >= 0) r[i] = 0;
for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t);
r.s = 0;
r.clamp();
if(this.s != a.s) BigInteger.ZERO.subTo(r,r);
}
function bnpSquareTo(r) {
var x = this.abs();
var i = r.t = 2*x.t;
while(--i >= 0) r[i] = 0;
for(i = 0; i < x.t-1; ++i) {
var c = x.am(i,x[i],r,2*i,0,1);
if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) {
r[i+x.t] -= x.DV;
r[i+x.t+1] = 1;
}
}
if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1);
r.s = 0;
r.clamp();
}
function bnpDivRemTo(m,q,r) {
var pm = m.abs();
if(pm.t <= 0) return;
var pt = this.abs();
if(pt.t < pm.t) {
if(q != null) q.fromInt(0);
if(r != null) this.copyTo(r);
return;
}
if(r == null) r = nbi();
var y = nbi(), ts = this.s, ms = m.s;
var nsh = this.DB-nbits(pm[pm.t-1]);
if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); }
else { pm.copyTo(y); pt.copyTo(r); }
var ys = y.t;
var y0 = y[ys-1];
if(y0 == 0) return;
var yt = y0*(1<<this.F1)+((ys>1)?y[ys-2]>>this.F2:0);
var d1 = this.FV/yt, d2 = (1<<this.F1)/yt, e = 1<<this.F2;
var i = r.t, j = i-ys, t = (q==null)?nbi():q;
y.dlShiftTo(j,t);
if(r.compareTo(t) >= 0) {
r[r.t++] = 1;
r.subTo(t,r);
}
BigInteger.ONE.dlShiftTo(ys,t);
t.subTo(y,y);
while(y.t < ys) y[y.t++] = 0;
while(--j >= 0) {
var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2);
if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) {
y.dlShiftTo(j,t);
r.subTo(t,r);
while(r[i] < --qd) r.subTo(t,r);
}
}
if(q != null) {
r.drShiftTo(ys,q);
if(ts != ms) BigInteger.ZERO.subTo(q,q);
}
r.t = ys;
r.clamp();
if(nsh > 0) r.rShiftTo(nsh,r);
if(ts < 0) BigInteger.ZERO.subTo(r,r);
}
function bnMod(a) {
var r = nbi();
this.abs().divRemTo(a,null,r);
if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r);
return r;
}
function Classic(m) { this.m = m; }
function cConvert(x) {
if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m);
else return x;
}
function cRevert(x) { return x; }
function cReduce(x) { x.divRemTo(this.m,null,x); }
function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
Classic.prototype.convert = cConvert;
Classic.prototype.revert = cRevert;
Classic.prototype.reduce = cReduce;
Classic.prototype.mulTo = cMulTo;
Classic.prototype.sqrTo = cSqrTo;
function bnpInvDigit() {
if(this.t < 1) return 0;
var x = this[0];
if((x&1) == 0) return 0;
var y = x&3;
y = (y*(2-(x&0xf)*y))&0xf;
y = (y*(2-(x&0xff)*y))&0xff;
y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff;
y = (y*(2-x*y%this.DV))%this.DV;
return (y>0)?this.DV-y:-y;
}
function Montgomery(m) {
this.m = m;
this.mp = m.invDigit();
this.mpl = this.mp&0x7fff;
this.mph = this.mp>>15;
this.um = (1<<(m.DB-15))-1;
this.mt2 = 2*m.t;
}
function montConvert(x) {
var r = nbi();
x.abs().dlShiftTo(this.m.t,r);
r.divRemTo(this.m,null,r);
if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r);
return r;
}
function montRevert(x) {
var r = nbi();
x.copyTo(r);
this.reduce(r);
return r;
}
function montReduce(x) {
while(x.t <= this.mt2)
x[x.t++] = 0;
for(var i = 0; i < this.m.t; ++i) {
var j = x[i]&0x7fff;
var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM;
j = i+this.m.t;
x[j] += this.m.am(0,u0,x,i,0,this.m.t);
while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; }
}
x.clamp();
x.drShiftTo(this.m.t,x);
if(x.compareTo(this.m) >= 0) x.subTo(this.m,x);
}
function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
Montgomery.prototype.convert = montConvert;
Montgomery.prototype.revert = montRevert;
Montgomery.prototype.reduce = montReduce;
Montgomery.prototype.mulTo = montMulTo;
Montgomery.prototype.sqrTo = montSqrTo;
function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; }
function bnpExp(e,z) {
if(e > 0xffffffff || e < 1) return BigInteger.ONE;
var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1;
g.copyTo(r);
while(--i >= 0) {
z.sqrTo(r,r2);
if((e&(1<<i)) > 0) z.mulTo(r2,g,r);
else { var t = r; r = r2; r2 = t; }
}
return z.revert(r);
}
function bnModPowInt(e,m) {
var z;
if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m);
return this.exp(e,z);
}
BigInteger.prototype.copyTo = bnpCopyTo;
BigInteger.prototype.fromInt = bnpFromInt;
BigInteger.prototype.fromString = bnpFromString;
BigInteger.prototype.clamp = bnpClamp;
BigInteger.prototype.dlShiftTo = bnpDLShiftTo;
BigInteger.prototype.drShiftTo = bnpDRShiftTo;
BigInteger.prototype.lShiftTo = bnpLShiftTo;
BigInteger.prototype.rShiftTo = bnpRShiftTo;
BigInteger.prototype.subTo = bnpSubTo;
BigInteger.prototype.multiplyTo = bnpMultiplyTo;
BigInteger.prototype.squareTo = bnpSquareTo;
BigInteger.prototype.divRemTo = bnpDivRemTo;
BigInteger.prototype.invDigit = bnpInvDigit;
BigInteger.prototype.isEven = bnpIsEven;
BigInteger.prototype.exp = bnpExp;
BigInteger.prototype.toString = bnToString;
BigInteger.prototype.negate = bnNegate;
BigInteger.prototype.abs = bnAbs;
BigInteger.prototype.compareTo = bnCompareTo;
BigInteger.prototype.bitLength = bnBitLength;
BigInteger.prototype.mod = bnMod;
BigInteger.prototype.modPowInt = bnModPowInt;
BigInteger.ZERO = nbv(0);
BigInteger.ONE = nbv(1);
function Arcfour() {
this.i = 0;
this.j = 0;
this.S = new Array();
}
function ARC4init(key) {
var i, j, t;
for(i = 0; i < 256; ++i)
this.S[i] = i;
j = 0;
for(i = 0; i < 256; ++i) {
j = (j + this.S[i] + key[i % key.length]) & 255;
t = this.S[i];
this.S[i] = this.S[j];
this.S[j] = t;
}
this.i = 0;
this.j = 0;
}
function ARC4next() {
var t;
this.i = (this.i + 1) & 255;
this.j = (this.j + this.S[this.i]) & 255;
t = this.S[this.i];
this.S[this.i] = this.S[this.j];
this.S[this.j] = t;
return this.S[(t + this.S[this.i]) & 255];
}
Arcfour.prototype.init = ARC4init;
Arcfour.prototype.next = ARC4next;
function prng_newstate() {
return new Arcfour();
}
var rng_psize = 256;
var rng_state;
var rng_pool;
var rng_pptr;
function rng_seed_int(x) {
rng_pool[rng_pptr++] ^= x & 255;
rng_pool[rng_pptr++] ^= (x >> 8) & 255;
rng_pool[rng_pptr++] ^= (x >> 16) & 255;
rng_pool[rng_pptr++] ^= (x >> 24) & 255;
if(rng_pptr >= rng_psize) rng_pptr -= rng_psize;
}
function rng_seed_time() {
rng_seed_int(new Date().getTime());
}
if(rng_pool == null) {
rng_pool = new Array();
rng_pptr = 0;
var t;
if(navigator.appName == "Netscape" && navigator.appVersion < "5" && window.crypto) {
var z = window.crypto.random(32);
for(t = 0; t < z.length; ++t)
rng_pool[rng_pptr++] = z.charCodeAt(t) & 255;
}
while(rng_pptr < rng_psize) {
t = Math.floor(65536 * Math.random());
rng_pool[rng_pptr++] = t >>> 8;
rng_pool[rng_pptr++] = t & 255;
}
rng_pptr = 0;
rng_seed_time();
}
function rng_get_byte() {
if(rng_state == null) {
rng_seed_time();
rng_state = prng_newstate();
rng_state.init(rng_pool);
for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr)
rng_pool[rng_pptr] = 0;
rng_pptr = 0;
}
return rng_state.next();
}
function rng_get_bytes(ba) {
var i;
for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte();
}
function SecureRandom() {}
SecureRandom.prototype.nextBytes = rng_get_bytes;
function parseBigInt(str,r) {
return new BigInteger(str,r);
}
function linebrk(s,n) {
var ret = "";
var i = 0;
while(i + n < s.length) {
ret += s.substring(i,i+n) + "\n";
i += n;
}
return ret + s.substring(i,s.length);
}
function byte2Hex(b) {
if(b < 0x10)
return "0" + b.toString(16);
else
return b.toString(16);
}
function pkcs1pad2(s,n) {
if(n < s.length + 11) {
alert("Message too long for RSA");
return null;
}
var ba = new Array();
var i = s.length - 1;
while(i >= 0 && n > 0) {
var c = s.charCodeAt(i--);
if(c < 128) {
ba[--n] = c;
}
else if((c > 127) && (c < 2048)) {
ba[--n] = (c & 63) | 128;
ba[--n] = (c >> 6) | 192;
}
else {
ba[--n] = (c & 63) | 128;
ba[--n] = ((c >> 6) & 63) | 128;
ba[--n] = (c >> 12) | 224;
}
}
ba[--n] = 0;
var rng = new SecureRandom();
var x = new Array();
while(n > 2) {
x[0] = 0;
while(x[0] == 0) rng.nextBytes(x);
ba[--n] = x[0];
}
ba[--n] = 2;
ba[--n] = 0;
return new BigInteger(ba);
}
function pkcs1pad2Bank(s,n) {
//2位长度+pin+rnd
if(n < s.length + 2) {
alert("密码太长!");
return null;
}
var ba = new Array();
var i = s.length - 1;
var len = s.length;
if(len<100){
ba[0]=0x30+len/10;
ba[1]=0x30+len%10;
}else{
alert("密码太长!");
return null;
}
var j=2;
i=0;
while(i < len && n > 0) {
ba[j++] = s.charCodeAt(i++);
}
var rng = new SecureRandom();
var x = new Array();
while(j<n) {
x[0] = 0;
while(x[0] == 0)
rng.nextBytes(x);
ba[j++] = x[0];
}
return new BigInteger(ba);
}
function RSAKey() {
this.n = null;
this.e = 0;
this.d = null;
this.p = null;
this.q = null;
this.dmp1 = null;
this.dmq1 = null;
this.coeff = null;
}
function RSASetPublic(N,E) {
if(N != null && E != null && N.length > 0 && E.length > 0) {
this.n = parseBigInt(N,16);
this.e = parseInt(E,16);
}
else{
alert("Invalid RSA public key");
}
}
function RSADoPublic(x) {
return x.modPowInt(this.e, this.n);
}
function RSAEncrypt(text) {
var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3);
if(m == null) return null;
var c = this.doPublic(m);
if(c == null) return null;
var h = c.toString(16).toUpperCase();
var gapLen = 256 - h.length;
for(var i = 0; i < gapLen; i = i + 1){
h = "0" + h;
}
return h;
}
function RSAEncryptPama(text) {
var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3);
if(m == null) return null;
var c = this.doPublic(m);
if(c == null) return null;
var h = c.toString(16).toUpperCase();
var gapLen = 512 - h.length;
for(var i = 0; i < gapLen; i = i + 1){
h = "0" + h;
}
return "PAMA" + h;
}
function RSAEncryptBank(text) {
var m = pkcs1pad2Bank(text,(this.n.bitLength()+7)>>3);
if(m == null) return null;
var c = this.doPublic(m);
if(c == null) return null;
var h = c.toString(16).toUpperCase();
var gapLen = 256 - h.length;
for(var i = 0; i < gapLen; i = i + 1){
h = "0" + h;
}
return h;
}
RSAKey.prototype.doPublic = RSADoPublic;
RSAKey.prototype.setPublic = RSASetPublic;
RSAKey.prototype.encrypt = RSAEncrypt;/*通用RSA加密*/
RSAKey.prototype.encryptPama = RSAEncryptPama;/*PAMA RSA加密*/
RSAKey.prototype.encryptBank = RSAEncryptBank;/*银行RSA加密*/
var b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var b64pad="=";
function hex2b64(h) {
var i;
var c;
var ret = "";
for(i = 0; i+3 <= h.length; i+=3) {
c = parseInt(h.substring(i,i+3),16);
ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63);
}
if(i+1 == h.length) {
c = parseInt(h.substring(i,i+1),16);
ret += b64map.charAt(c << 2);
}
else if(i+2 == h.length) {
c = parseInt(h.substring(i,i+2),16);
ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4);
}
while((ret.length & 3) > 0) ret += b64pad;
return ret;
}
function b64tohex(s) {
var ret = ""
var i;
var k = 0;
var slop;
for(i = 0; i < s.length; ++i) {
if(s.charAt(i) == b64pad) break;
v = b64map.indexOf(s.charAt(i));
if(v < 0) continue;
if(k == 0) {
ret += int2char(v >> 2);
slop = v & 3;
k = 1;
}
else if(k == 1) {
ret += int2char((slop << 2) | (v >> 4));
slop = v & 0xf;
k = 2;
}
else if(k == 2) {
ret += int2char(slop);
ret += int2char(v >> 2);
slop = v & 3;
k = 3;
}
else {
ret += int2char((slop << 2) | (v >> 4));
ret += int2char(v & 0xf);
k = 0;
}
}
if(k == 1)
ret += int2char(slop << 2);
return ret;
}
function b64toBA(s) {
var h = b64tohex(s);
var i;
var a = new Array();
for(i = 0; 2*i < h.length; ++i) {
a[i] = parseInt(h.substring(2*i,2*i+2),16);
}
return a;
}
......@@ -2,7 +2,7 @@
<div id="app">
<v-header></v-header>
<main ref="container" class="main-container">
<router-view/>
<router-view />
</main>
<v-footer></v-footer>
</div>
......@@ -11,6 +11,7 @@
<script>
import { mapGetters, mapActions, mapState } from "vuex";
import { getCookie } from "@utils/utils.js";
import VHeader from "@components/home/header/header.vue";
import VFooter from "@components/home/footer/footer.vue";
var UA = require("ua-device");
......@@ -36,6 +37,15 @@ export default {
let deviceType = output.device.type;
let isMobile = deviceType == "mobile";
this.$store.commit("IS_MOBILE", isMobile);
//
let userInfoStr = decodeURIComponent(getCookie("_user_profile"));
if (userInfoStr) {
try {
let userInfo = JSON.parse(decodeURIComponent(userInfoStr));
this.$store.commit("SET_USER_INFO", userInfo);
} catch (e) {}
}
}
};
</script>
......@@ -44,7 +54,7 @@ export default {
@import "@/styles/_support";
html {
font-family: "Microsoft YaHei","Arial";
font-family: "Microsoft YaHei", "Arial";
font-size: 12px;
word-spacing: 1px;
word-break: break-word;
......
module.exports = {
testListGet: '/xxx/xxx/list'
logout : "/pingan_hklife_webapi/logout",
// 是否显示图形验证码接口
stdIsShowImageVcode : "/pingan_hklife_webapi/auth/stdIsShowImageVcode",
// 刷新图形验证码接口
stdRefreshVcode : "/pingan_hklife_webapi/auth/stdRefreshVcode",
// OTP发送接口
stdSendOTP : "/pingan_hklife_webapi/auth/stdSendOTP",
// OTP验证与验重接口
stdValidateOTPandRepeat : "/pingan_hklife_webapi/auth/stdValidateOTPandRepeat",
// 注册手机号验重接口
gsRegCheck : "/pingan_hklife_webapi/auth/gsRegCheck",
// 账户整合登录接口
gsLogin : "/pingan_hklife_webapi/auth/gsLogin",
// 注册接口
stdRegister : "/pingan_hklife_webapi/auth/stdRegister",
// 找回密码定位用户信息
gsLocateUserV2 : "/pingan_hklife_webapi/auth/gsLocateUserV2",
// 账户整合忘记密码重置用户密码
gsResetPwd : "/pingan_hklife_webapi/auth/gsResetPwd",
// 账户整合修改密码接口
gsModifyPwd : "/pingan_hklife_webapi/auth/gsModifyPwd",
// 短信验证码登录
otpLogin : "/pingan_hklife_webapi/otpLogin",
}
\ No newline at end of file
......
......@@ -11,10 +11,7 @@ function Toast(msg) {
// axios.defaults.baseURL = ""
// 服务器地址
let base = "https://ow.go.qudone.com";
if (location.href.indexOf("//k.wxpai.cn") > 0) {
base = "https://api.k.wxpai.cn/bizproxy"
}
let base = process.env.REQUEST_DOMAIN || "http://localhost:9101";
// let base = COM.baseUrl;
// 请求拦截器
......
......@@ -15,21 +15,25 @@ module.exports = {
list: [{
name: "register",
path: "/register",
type : "noAuth",
value: ""
}, {
name: "login",
path: "/login",
type : "noAuth",
value: ""
},
{
name: "modify password",
path: "",
type : "auth",
value: ""
},
{
name: "logout",
path: "",
value: ""
type : "auth",
value: "logout"
},
]
},
......@@ -133,6 +137,18 @@ module.exports = {
verifyCodeGet: "獲取驗證碼",
},
register: {
mobileOptions: [{
type: "hk",
name: "香港手機號",
placeHolder: "請輸入8位手機號碼",
areaCode: "+852"
}, {
type: "zh",
name: "大陸手機號",
placeHolder: "請輸入11位手機號碼",
areaCode: "+86"
}],
coutTips : "{second}秒後重新獲取",
title: "歡迎註冊一賬通",
title2: "請設置新的密碼",
mobilePlaceholder: "请输入8位手机号码",
......
......@@ -15,23 +15,26 @@ module.exports = {
list: [{
name: "註冊",
path: "/register",
type: "noAuth",
value: ""
}, {
name: "登入",
path: "/login",
type: "noAuth",
value: ""
},
{
name: "修改密碼",
path: "",
type: "auth",
value: ""
},
{
name: "登出",
path: "",
value: ""
},
]
type: "auth",
value: "logout"
}]
},
navList: [{
name: "產品介紹",
......@@ -133,6 +136,18 @@ module.exports = {
verifyCodeGet: "獲取驗證碼",
},
register: {
mobileOptions: [{
type: "hk",
name: "香港手機號",
placeHolder: "請輸入8位手機號碼",
areaCode: "+852"
}, {
type: "zh",
name: "大陸手機號",
placeHolder: "請輸入11位手機號碼",
areaCode: "+86"
}],
coutTips : "{second}秒後重新獲取",
title: "歡迎註冊一賬通",
title2: "請設置新的密碼",
mobilePlaceholder: "請輸入8位手機號碼",
......
......@@ -15,23 +15,26 @@ module.exports = {
list: [{
name: "注册",
path: "/register",
type: "noAuth",
value: ""
}, {
name: "登陆",
path: "/login",
type: "noAuth",
value: ""
},
{
name: "修改密码",
path: "",
type: "auth",
value: ""
},
{
name: "登出",
path: "",
value: ""
},
]
type: "auth",
value: "logout"
}]
},
navList: [{
name: "产品介绍",
......@@ -133,6 +136,18 @@ module.exports = {
verifyCodeGet: "获取验证码",
},
register: {
mobileOptions: [{
type: "hk",
name: "香港手机号",
placeHolder: "请输入8位手机号码",
areaCode: "+852"
}, {
type: "zh",
name: "大陆手机号",
placeHolder: "请输入11位手机号码",
areaCode: "+86"
}],
coutTips : "{second}秒后重新获取",
title: "欢迎注册一账通",
title2: "请设置新的密码",
mobilePlaceholder: "请输入8位手机号码",
......
......@@ -2,6 +2,9 @@ import {
mapState
} from 'vuex'
import api from '@/api/api'
import { httpPost } from '@/api/fetch-api.js'
export default {
name: "DropDownList",
data() {
......@@ -13,25 +16,25 @@ export default {
props: {
type: {
type: String,
default () {
default() {
return "nav";
}
},
dataObj: {
type: Object,
default () {
default() {
return {};
}
},
dataList: {
type: Array,
default () {
default() {
return [];
}
},
labelProperty: {
type: String,
default () {
default() {
return "name";
}
}
......@@ -81,16 +84,32 @@ export default {
this.sTitle = curData.name;
window.location.reload();
} else {
// console.log("curData.value == =", curData.value)
if (curData.value == "logout") {
// this.$store.commit("SET_USER_INFO", null);
this._loginHandler();
} else {
// 不是的话,跳转页面
this.$router.push({
path: curData.path
})
}
}
// console.log("name:", this.dataList[index].name);
// this.$emit("change", {
// index: index,
// value: this.dataList[index]
// });
},
_loginHandler() {
httpPost({ url: api.logout }).then(() => {
this.$store.commit("SET_USER_INFO", null);
this._showLogoutTip();
});
},
_showLogoutTip() {
// 登出后的提示
alert("登出成功");
}
},
computed: {
......
......@@ -57,6 +57,13 @@
justify-content: center;
color: #ffffff;
span {
max-width: 4.25rem ;/* 51/12 */
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.icon-img {
margin: 0 .5rem;
}
......
......@@ -4,7 +4,8 @@
<!-- 登陆下拉样式 -->
<template v-if="type=='login'">
<div class="user">
<img class="icon-img" src="@/assets/images/home/icon-user.png"> {{dataObj.name}}
<img class="icon-img" src="@/assets/images/home/icon-user.png">
<span>{{dataObj.name}}</span>
</div>
</template>
<!-- 其他下拉样式 -->
......
......@@ -46,7 +46,8 @@ export default {
},
computed: {
...mapState({
isSmallScreen: state => state.isSmallScreen
isSmallScreen: state => state.isSmallScreen,
userInfo: state => state.userInfo
})
},
methods: {
......@@ -65,10 +66,33 @@ export default {
},
initData() {
let i18n = this.$i18n.messages[this.$i18n.locale] || {};
this.loginData = i18n.nav.loginData;
// this.loginData = i18n.nav.loginData;
this._buildLoginMenu();
this.navList = i18n.nav.navList;
let curLang = getObjByListKeyValue(this.$i18n.locale, "value", this.langData.list)
this.langData.name = curLang.name;
},
_buildLoginMenu() {
// 构建登录页
let i18n = this.$i18n.messages[this.$i18n.locale] || {};
let menuData = JSON.parse(JSON.stringify(i18n.nav.loginData));
let list = [];
if (this.userInfo && this.userInfo.name) {
menuData.name = this.userInfo.name;
menuData.list.forEach(element => {
if (element.type == "auth") {
list.push(element);
}
});
} else {
menuData.list.forEach(element => {
if (element.type == "noAuth") {
list.push(element);
}
});
}
menuData.list = list;
this.$set(this, 'loginData', menuData);
}
},
mounted() {
......@@ -78,6 +102,11 @@ export default {
self.checkIsSmallScreen();
}
},
watch: {
userInfo(val) {
this._buildLoginMenu();
}
},
created() {
this.initData();
},
......
......@@ -7,7 +7,7 @@ import store from './store/index';
import VueAwesomeSwiper from 'vue-awesome-swiper'
// require styles
import 'swiper/dist/css/swiper.css'
Vue.use(VueAwesomeSwiper, /* { default global options } */ )
Vue.use(VueAwesomeSwiper)
import Mock from './mock'
......
import { mapGetters, mapActions, mapState } from "vuex";
import api from '@/api/api'
import {
httpGet,
httpPost
} from '@/api/fetch-api.js'
let PK = 'B5FE03847F02046C47292AF0FF2DE88977241483DD40C123046EB39CBE4C48167B120096CFF12CD16559322884A3C56FA92B07B89AB51FC8C91A75127622151DDD730DFF1F993D5A290CEAC0BBA7FC88285D8994ACBAFF50101EDE9A0925AD5DFFAFE96D53C370E9C5B37DF2F871F81C4D7CA6B7EC37FF459C07975AD9A74A95';
let E = '10001';
export default {
data() {
return {
key: 'value',
type: 1, // 1:帐密登陆 2:OTP登陆
type: 1, // 1:帐密登陆 2:OTP登陆,
values: {
// 返回的token,串连整个流程,后台安全校验使用
token: "",
deviceId: "",
vcodeuuid: "",
token: "",
deviceId: "",
imageBase64: "",
password: "",
passwordRepeat: ""
},
times: {
interval: 0, // 索引
remain: 0, // 剩余时间
tip: "" // 显示的文字
},
loginForm: {
// userId: "18334783910",
// password: "qweqwe123"
userId: "",
password: "",
imageValue: "",
mobileNo: "",
otp: ""
},
loginCheck: {
showImageCode: false,
agreeProtocol: false
},
PK: process.env.RSA_PUBLIC_KEY || PK,
E: process.env.RSA_KEY_INDEX || E,
}
},
components: {},
computed: {
...mapState({
userInfo: state => state.userInfo
}),
locale() {
return this.$i18n.locale || 'tc';
},
......@@ -43,8 +84,254 @@ export default {
onLoginTypeHandler(val) {
this.type = val;
},
initData() {}
initData() { },
handlerIsShowImageVcode() {
return new Promise((resolve, reject) => {
httpPost({
url: api.stdIsShowImageVcode,
data: {
deviceId: this.values.deviceId,
userId: this.loginForm.userId
}
}).then(response => {
// 判断是否显示图形验证码
if (this._handlerIsShowImageVcodeResponse(response)) {
resolve(response);
}
})
});
},
_handlerIsShowImageVcodeResponse(response) {
if (response.returnCode == "0" && response.data.isShowVcode == "N") {
return true;
}
this.values.token = response.data.token;
return false;
},
handlerRefreshVcode() {
// 刷新图形二维码
},
handlerLogin() {
this.refreshDeviceId();
if (!this.loginCheck.agreeProtocol) {
this._showAgreeProtocalTips();
return;
}
if (this.type == 1) {
this._passwordLogin();
} else {
this._otpLogin();
}
},
_passwordLogin() {
// 刷新图形二维码
this.handlerIsShowImageVcode().then(() => {
httpPost({
url: api.gsLogin,
data: {
deviceId: this.values.deviceId,
loginName: this.loginForm.userId,
loginPwd: this._passwordEncrypt(this.loginForm.password)
}
}).then(response => {
this._handlerLoginResponse(response);
})
});
},
// 处理登录结果
_handlerLoginResponse(response) {
// let res = response.content;
if (response.returnCode == 0 || response.resultCode == "0") {
this.$store.commit("SET_USER_INFO", response.data);
this._redirectTo();
} else {
let msg = response.returnMsg;
this._showLoginErrorMessage(msg);
}
},
_showAgreeProtocalTips() {
alert("请同意《平安一账通会员服务协议》");
},
_showLoginErrorMessage(message) {
alert(message);
},
_redirectTo() {
let path = this.$route.query.callback || "/index";
this.$router.push({
path: path
});
},
_otpLogin() {
this._checkOptParams().then(() => {
let data = {
mobileNo: this.loginForm.mobileNo,
token: this.values.token,
otp: this.loginForm.otp,
deviceId: this.refreshDeviceId()
};
httpPost({
url: api.otpLogin,
data: data
}).then(response => {
this._handlerLoginResponse(response);
});
});
},
_checkOptParams() {
return new Promise((resolve, reject) => {
this._checkMobileLegal().then(() => {
if (!this.loginForm.otp) {
this._showOtpEmptyTips();
return;
}
if (!this.values.token) {
this._showGetOptTips();
return;
}
resolve();
});
})
},
_showGetOptTips() {
alert('请先获取短信验证码');
},
_showImageValueTip() {
alert("请输入图片验证码")
},
_showOtpEmptyTips() {
alert('请输入短信验证码');
},
handlerStdSendOTP() {
// 发送短信验证码
this._checkMobileLegal().then(() => {
if (this.times.remain > 0) {
return;
}
if (this.values.vcodeuuid && !this.loginForm.imageValue) {
this._showImageValueTip();
return;
}
this._handlerIsShowImageVcode().then(() => {
this._startStdSendOTP();
this._startTimeClick();
});
});
},
handlerRefreshImageValue() {
httpPost({
url: api.stdRefreshVcode,
data: {
vcodeuuid: this.values.vcodeuuid
}
}).then(response => {
this.values.imageBase64 = response.data.image;
})
},
_checkMobileLegal() {
// 检测手机号是否正确
return new Promise((resolve, reject) => {
let mobile = this.loginForm.mobileNo;
if (mobile.length != 8 && mobile.length != 11) {
this._showMobileNoIllegalTip()
return;
}
resolve(true);
});
},
_handlerIsShowImageVcode() {
return new Promise((resolve, reject) => {
// 如果这个值不为空,标识出现了图片验证码,不需要重新询问是否需要图像验证码了
if (this.values.vcodeuuid) {
resolve();
return;
}
httpPost({
url: api.stdIsShowImageVcode,
data: {
deviceId: this.values.deviceId,
userId: this.loginForm.mobileNo
}
}).then(response => {
// 判断是否显示图形验证码
if (response.returnCode == "0") {
this.values.token = response.data.token;
if (response.data.isShowVcode == "N") {
// if (!this.values.vcodeuuid) {
// this.loginCheck.showImageCode = true;
// this.values.vcodeuuid = "123456";
// return;
// }
this.values.vcodeuuid = null;
resolve(response);
} else {
// image 值:
this.loginCheck.showImageCode = true;
this.values.vcodeuuid = response.data.vcodeuuid;
this.values.imageBase64 = response.data.image;
}
}
return false;
})
});
},
_showMobileNoIllegalTip() {
alert("手机号不正确");
},
_startStdSendOTP() {
// 正式发送OTP信号
let data = {
mobileNo: this.loginForm.mobileNo,
token: this.values.token,
signFactor: new Date().getTime(),
scene: "otpLogin",
deviceId: this.refreshDeviceId()
}
if (this.values.vcodeuuid) {
data["vcodeuuid"] = this.values.vcodeuuid;
data["imageValue"] = this.loginForm.imageValue;
}
httpPost({ url: api.stdSendOTP, data: data });
},
_startTimeClick() {
this.times.remain = 120;
let _this = this;
let i18n = this.$i18n.messages[this.$i18n.locale] || {};
let msg = i18n.register.coutTips;
_this.times.tip = msg.replace("{second}", _this.times.remain);
this.times.interval = setInterval(function () {
if (_this.times.remain <= 0) {
clearInterval(_this.times.interval);
_this.times.interval = 0;
_this.times.remain = 0;
return;
}
_this.times.remain--;
_this.times.tip = msg.replace("{second}", _this.times.remain);
_this.$set(_this, 'times', _this.times);
}, 1000);
},
refreshDeviceId() {
if (!this.values.deviceId) {
this.values.deviceId = (Math.random() + "").substring(2)
}
return this.values.deviceId
},
_passwordEncrypt(rawPwd) {
let rsa = new RSAKey();
rsa.setPublic(this.PK, this.E);
let res = rsa.encrypt(rawPwd);
if (res == null) return rawPwd;
return res;
}
},
watch: {
type() {
this.loginCheck.showImageCode = false;
}
},
mounted() {
// console.log("PK === ", this.PK)
// console.log("E === ", this.E)
},
mounted() {},
created() {}
created() { }
}
......
......@@ -124,6 +124,15 @@
justify-content: space-between;
flex-wrap: wrap;
.vcode {
background-color: transparent !important;
padding: 0 !important;
overflow: hidden;
img {
width: 100%;
height: 100%;
}
}
&-item {
position: relative;
......@@ -160,6 +169,8 @@
border-radius: 3.5rem;
padding: 0 1.75rem;
flex: 1;
font-size: 1.166667rem; /* 14/12 */
letter-spacing: .1rem;/* 1.2/12 */
}
// 长文本
......@@ -187,6 +198,7 @@
color: #4c4948;
}
// 框内按钮
.ipt2 {
display: flex;
......@@ -202,13 +214,12 @@
color: #f05a23;
text-decoration: underline;
}
}
.veri-btn-default {
color: #aaaaaa;
}
}
}
}
}
......
......@@ -24,7 +24,7 @@
<img src="@/assets/images/login/icon-login-user.png"> {{$t('login.account')}}
</div>
<div class="ipt-wrap">
<input :placeholder="$t('login.accountPlaceholder')" class="ipt" type="text">
<input v-model="loginForm.userId" :placeholder="$t('login.accountPlaceholder')" class="ipt" type="text">
</div>
</div>
<div class="pure-u-1 form-item">
......@@ -32,21 +32,25 @@
<img src="@/assets/images/login/icon-login-password.png"> {{$t('login.password')}}
</div>
<div class="ipt-wrap">
<input :placeholder="$t('login.passwordPlaceholder')" class="ipt" type="text">
<input v-model="loginForm.password" :placeholder="$t('login.passwordPlaceholder')" class="ipt" type="password">
</div>
</div>
<div class="pure-u-1 form-item">
<div class="pure-u-1 form-item" v-if="type == 1 && loginCheck.showImageCode">
<div class="ipt-wrap">
<input :placeholder="$t('login.verifyPlaceholder')" class="ipt ipt-verify" type="text">
<div class="ipt verify-btn pointer">5136</div>
<input :placeholder="$t('login.verifyPlaceholder')" class="ipt ipt-verify" type="text" v-model="loginForm.imageValue">
<div class="ipt verify-btn pointer vcode" @click="handlerRefreshImageValue">
<img :src="values.imageBase64">
</div>
</div>
</div>
</div>
<div class="login-protocol">
<img @click="onCheckHandler()" class="check pointer" src="@/assets/images/login/login-check.png"> {{$t('login.agree')}}
<div class="login-protocol pointer" @click="loginCheck.agreeProtocol = !loginCheck.agreeProtocol" >
<img v-if="!loginCheck.agreeProtocol" class="check" src="@/assets/images/login/un-check.png">
<img v-if="loginCheck.agreeProtocol" class="check" src="@/assets/images/login/check.png">
{{$t('login.agree')}}
<span @click="onProtocolHandler()" class="protocol pointer">{{$t('login.protocol')}}</span>
</div>
<div @click="onSubmitHandler()" class="login-submit pointer">{{$t('login.login')}}</div>
<div @click="handlerLogin()" class="login-submit pointer">{{$t('login.login')}}</div>
<div class="login-func">
<div @click="onRegisterHandler()" class="login-func-btn pointer">{{$t('login.register')}}</div>
<div @click="onForgetHandler()" class="login-func-btn pointer">{{$t('login.forget')}}</div>
......@@ -71,7 +75,15 @@
<img src="@/assets/images/login/icon-login-phone.png"> {{$t('login.mobile')}}
</div>
<div class="ipt-wrap">
<input :placeholder="$t('login.mobilePlaceholder')" class="ipt" type="text">
<input :placeholder="$t('login.mobilePlaceholder')" class="ipt" type="text" v-model="loginForm.mobileNo">
</div>
</div>
<div class="pure-u-1 form-item" v-if="type == 2 && loginCheck.showImageCode">
<div class="ipt-wrap">
<input :placeholder="$t('login.verifyPlaceholder')" class="ipt ipt-verify" type="text" v-model="loginForm.imageValue">
<div class="ipt verify-btn pointer vcode" @click="handlerRefreshImageValue">
<img :src="values.imageBase64">
</div>
</div>
</div>
<div class="pure-u-1 form-item">
......@@ -80,17 +92,20 @@
</div>
<div class="ipt-wrap">
<div class="ipt ipt2">
<input :placeholder="$t('login.verifyCodePlaceholder')" class="ipt-code" type="text">
<div class="veri-btn pointer"> {{$t('login.verifyCodeGet')}}</div>
<input :placeholder="$t('login.verifyCodePlaceholder')" class="ipt-code" type="text" v-model="loginForm.otp">
<div v-if="times.remain == 0" class="veri-btn pointer" @click="handlerStdSendOTP" >{{$t('register.verifyCodeGet')}}</div>
<div v-else class="veri-btn-default">{{times.tip}}</div>
</div>
</div>
</div>
</div>
<div class="login-protocol">
<img @click="onCheckHandler()" class="check pointer" src="@/assets/images/login/login-check.png"> {{$t('login.agree')}}
<div class="login-protocol pointer" @click="loginCheck.agreeProtocol = !loginCheck.agreeProtocol" >
<img v-if="!loginCheck.agreeProtocol" class="check" src="@/assets/images/login/un-check.png">
<img v-if="loginCheck.agreeProtocol" class="check" src="@/assets/images/login/check.png">
{{$t('login.agree')}}
<span @click="onProtocolHandler()" class="protocol pointer">{{$t('login.protocol')}}</span>
</div>
<div @click="onSubmitHandler()" class="login-submit pointer">{{$t('login.login')}}</div>
<div @click="handlerLogin()" class="login-submit pointer">{{$t('login.login')}}</div>
<div class="login-func">
<div @click="onRegisterHandler()" class="login-func-btn pointer">{{$t('login.register')}}</div>
<div @click="onForgetHandler()" class="login-func-btn pointer">{{$t('login.forget')}}</div>
......
......@@ -4,11 +4,43 @@ import {
httpPost
} from '@/api/fetch-api.js'
let PK = 'B5FE03847F02046C47292AF0FF2DE88977241483DD40C123046EB39CBE4C48167B120096CFF12CD16559322884A3C56FA92B07B89AB51FC8C91A75127622151DDD730DFF1F993D5A290CEAC0BBA7FC88285D8994ACBAFF50101EDE9A0925AD5DFFAFE96D53C370E9C5B37DF2F871F81C4D7CA6B7EC37FF459C07975AD9A74A95';
let E = '10001';
export default {
data() {
return {
key: 'value',
type: 1, // 1:手机验证 2:输入密码
mobileNoType: "hk",// 选择的手机好类型
mobileTip: {},
mobileOptions: [],
registerCheck: {
showImageCode: false,
agreeProtocol: false
},
values: {
// 返回的token,串连整个流程,后台安全校验使用
vcodeuuid: "",
token: "",
deviceId: "",
imageBase64: "",
password: "",
passwordRepeat: ""
},
registerForm: {
imageValue: "",
mobileNo: "",
otp: ""
},
times: {
interval: 0, // 索引
remain: 0, // 剩余时间
tip: "" // 显示的文字
},
PK: process.env.RSA_PUBLIC_KEY || PK,
E: process.env.RSA_KEY_INDEX || E,
}
},
components: {},
......@@ -21,19 +53,324 @@ export default {
}
},
methods: {
onCheckHandler() {
},
onProtocolHandler() {
this.$router.push({
path: "/protocol"
})
},
handlerStdSendOTP() {
// 发送短信验证码
this._checkMobileLegal().then(() => {
if (this.times.remain > 0) {
return;
}
if (this.values.vcodeuuid && !this.registerForm.imageValue) {
this._showImageValueTip();
return;
}
this._handlerIsShowImageVcode().then(() => {
this._startStdSendOTP();
this._startTimeClick();
});
});
},
_checkMobileLegal() {
// 检测手机号是否正确
return new Promise((resolve, reject) => {
let mobile = this.registerForm.mobileNo;
if (this.mobileNoType == "hk") {
if (mobile.length != 8) {
this._showMobileNoIllegalTip()
return;
}
} else {
if (mobile.length != 11) {
this._showMobileNoIllegalTip()
return;
}
}
resolve(true);
});
},
_handlerIsShowImageVcode() {
return new Promise((resolve, reject) => {
// 如果这个值不为空,标识出现了图片验证码,不需要重新询问是否需要图像验证码了
if (this.values.vcodeuuid) {
resolve();
return;
}
httpPost({
url: api.stdIsShowImageVcode,
data: {
deviceId: this.values.deviceId,
userId: this.registerForm.mobileNo
}
}).then(response => {
// 判断是否显示图形验证码
if (response.returnCode == "0") {
this.values.token = response.data.token;
if (response.data.isShowVcode == "N") {
// 测试代码
// if (!this.values.vcodeuuid) {
// this.registerCheck.showImageCode = true;
// this.values.vcodeuuid = "123456";
// return;
// }
this.values.vcodeuuid = null;
resolve(response);
} else {
// image 值:
this.registerCheck.showImageCode = true;
this.values.vcodeuuid = response.data.vcodeuuid;
this.values.imageBase64 = response.data.image;
}
}
return false;
})
});
},
_showMobileNoIllegalTip() {
alert("手机号不正确");
},
_startStdSendOTP() {
// 正式发送OTP信号
let data = {
mobileNo: this.registerForm.mobileNo,
token: this.values.token,
signFactor: new Date().getTime(),
scene: "register",
}
if (this.values.vcodeuuid) {
data["vcodeuuid"] = this.values.vcodeuuid;
data["imageValue"] = this.registerForm.imageValue;
}
httpPost({ url: api.stdSendOTP, data: data });
},
_startTimeClick() {
this.times.remain = 120;
let _this = this;
let i18n = this.$i18n.messages[this.$i18n.locale] || {};
let msg = i18n.register.coutTips;
_this.times.tip = msg.replace("{second}", _this.times.remain);
this.times.interval = setInterval(function () {
if (_this.times.remain <= 0) {
clearInterval(_this.times.interval);
_this.times.interval = 0;
_this.times.remain = 0;
return;
}
_this.times.remain--;
_this.times.tip = msg.replace("{second}", _this.times.remain);
_this.$set(_this, 'times', _this.times);
}, 1000);
},
onSubmitHandler() {
// this.type = 2;
this._checkParams().then(() => {
this._regCheck().then(() => {
// 验证短信验证码
this._validateOTPandRepeat().then(() => {
this.type = 2;
});
});
});
},
_validateOTPandRepeat() {
return new Promise((resolve, reject) => {
let data = {
mobileNo: this.registerForm.mobileNo,
token: this.values.token,
signFactor: new Date().getTime(),
otp: this.registerForm.opt
};
httpPost({
url: api.stdValidateOTPandRepeat,
data: data
}).then(response => {
if (response.returnCode != "0") {
this._showCheckOTPErrTip(response.returnMsg);
// TODO 测试代码
// resolve();
} else {
// this.type = 2;
resolve();
}
})
});
},
_regCheck() {
// 检测手机号注册情况
return new Promise((resolve, reject) => {
let data = {
mobileNo: this.registerForm.mobileNo,
};
httpPost({
url: api.gsRegCheck,
data: data
}).then(response => {
if (response.returnCode == "0") {
if (response.data.mobileStatus == "N") {
resolve();
} else {
// 重复注册
this._showDuplicateRegistrationTip();
}
} else {
// 错误提示
this._showCheckOTPErrTip(response.returnMsg);
}
})
});
},
_checkParams() {
return new Promise((resolve, reject) => {
if (!this.registerCheck.agreeProtocol) {
this._showAgreeProtocolTip();
return;
}
if (!this.values.token) {
this._showTokenTip();
return;
}
if (this.values.vcodeuuid && !this.registerForm.imageValue) {
this._showImageValueTip();
return;
}
if (!this.registerForm.opt) {
this._showOTPTip();
return;
}
this._checkMobileLegal().then(() => {
resolve();
})
});
},
_showAgreeProtocolTip() {
alert("请同意协议")
},
_showOTPTip() {
alert("请填写短信验证码")
},
_showTokenTip() {
alert("请先请求短信验证码")
},
_showDuplicateRegistrationTip() {
alert("手机号已经被注册,请使用其他手机号重新注册")
},
_showImageValueTip() {
alert("请输入图片验证码")
},
_showCheckOTPErrTip(msg) {
alert(msg);
},
onRegisterHandler() {
this._checkPassword().then(() => {
let data = {
token: this.values.token,
mobileNo: this.registerForm.mobileNo,
loginPwd: this._passwordEncrypt(this.values.password)
};
httpPost({
url: api.stdRegister,
data: data
}).then(response => {
if (response.returnCode != 0) {
this._showRegisterFailure(response);
this.type = 1;
} else {
this._showSuccessMessage();
this.$router.push({
path: "/login"
});
}
})
});
},
_checkPassword() {
return new Promise((resolve, reject) => {
let password = this.values.password;
if (password.length < 8) {
this._showPasswordLenthNotEnouth();
return;
}
// 匹配字母
let m1 = /([a-z])+/.test(password);
let m2 = /([A-Z])+/.test(password);
// 匹配数字
let m3 = /([0-9])+/.test(password);
// 匹配特殊字符
let m4 = /[^a-zA-Z0-9]+/.test(password);
console.log(m1, m2, m3, m4)
if ((m1 | m2) & m3 & m4) {
if (password != this.values.passwordRepeat) {
this._showPasswordNotTheSameTips();
} else {
resolve();
}
} else {
this._showPasswordComplexityTips();
}
});
},
_showPasswordLenthNotEnouth() {
alert("密码长度不能少于8位")
},
_showPasswordComplexityTips() {
alert("密码必须同时包含数字、字母、特殊字符")
},
_showPasswordNotTheSameTips() {
alert("两次输入的密码不一致")
},
_showRegisterFailure(response) {
if ("COMMON_ERROR_052" == response.returnCode) {
this._resetRegisterParam();
this.handlerRefreshImageVcode();
alert("验证码过期,请重新申请验证码");
} else {
this._resetAllParams();
alert("注册失败,请联系工作人员");
}
},
_resetAllParams() {
this.values.vcodeuuid = "";
this.values.token = "";
this.values.imageBase64 = "";
this.values.password = "";
this.values.passwordRepeat = "";
this.registerForm.imageValue = "";
this.registerForm.mobileNo = "";
this.registerForm.otp = "";
this.times.interval = "";
this.times.remain = "";
this.times.tip = "";
},
_resetRegisterParam() {
this.values.token = "";
this.registerForm.otp = "";
this.times.interval = "";
this.times.remain = "";
this.times.tip = "";
},
handlerRefreshImageVcode() {
if (this.values.vcodeuuid) {
let data = {
vcodeuuid: this.values.vcodeuuid
}
httpPost({
url: api.stdRefreshVcode,
data: data
}).then(response => {
this.$set(this.values, 'imageBase64', response.data.image);
})
}
},
_showSuccessMessage() {
alert("注册成功")
},
onForgetHandler() {
......@@ -41,8 +378,31 @@ export default {
onLoginTypeHandler(val) {
},
initData() {}
_passwordEncrypt(rawPwd) {
let rsa = new RSAKey();
rsa.setPublic(this.PK, this.E);
let res = rsa.encrypt(rawPwd);
if (res == null) return rawPwd;
return res;
},
mounted() {},
created() {}
initData() {
let i18n = this.$i18n.messages[this.$i18n.locale] || {};
let mobileOptions = JSON.parse(JSON.stringify(i18n.register.mobileOptions));
this.mobileOptions = mobileOptions;
this.mobileTip = this.mobileOptions[0];
}
},
mounted() { },
watch: {
mobileNoType() {
this.mobileOptions.forEach(element => {
if (element.type == this.mobileNoType) {
this.$set(this, 'mobileTip', element);
}
})
}
},
created() {
this.initData();
}
}
......
......@@ -120,6 +120,20 @@
justify-content: space-between;
flex-wrap: wrap;
.vcode {
background-color: transparent !important;
padding: 0 !important;
overflow: hidden;
img {
width: 100%;
height: 100%;
}
}
input {
font-size: 1.166667rem; /* 14/12 */
letter-spacing: .1rem;/* 1.2/12 */
}
&-item {
position: relative;
......@@ -206,6 +220,9 @@
color: #f05a23;
text-decoration: underline;
}
.veri-btn-default {
color: #aaaaaa;
}
}
}
......
......@@ -16,36 +16,44 @@
<div class="pure-u-1 form-item">
<div class="ipt-wrap">
<img class="down-arrow" src="@/assets/images/reservation/re-down-arrow.png" alt="">
<select class="ipt">
<template v-if="locale == 'zh'">
<option>香港手机号</option>
</template>
<template v-else>
<option>香港手機號</option>
</template>
<select class="ipt" v-model="mobileNoType">
<option v-for="(item,index) in mobileOptions" :key="index" :value="item.type">{{item.name}}</option>
</select>
</div>
</div>
<div class="pure-u-1 form-item">
<div class="ipt-wrap">
<div class="ipt ipt2">
<div class="region-tel">+852</div>
<input :placeholder="$t('register.mobilePlaceholder')" class="ipt-tel" type="text">
<div class="region-tel">{{mobileTip.areaCode}}</div>
<input :placeholder="mobileTip.placeHolder" class="ipt-tel" type="text" v-model="registerForm.mobileNo">
</div>
</div>
</div>
<div class="pure-u-1 form-item" v-if="registerCheck.showImageCode">
<div class="ipt-wrap">
<input :placeholder="$t('login.verifyPlaceholder')" class="ipt ipt-verify" type="text" v-model="registerForm.imageValue">
<div class="ipt verify-btn pointer vcode" @click="handlerRefreshImageVcode">
<img :src="values.imageBase64">
</div>
</div>
</div>
<div class="pure-u-1 form-item">
<div class="ipt-wrap">
<div class="ipt ipt2">
<input :placeholder="$t('register.verifyCodePlaceholder')" class="ipt-code" type="text">
<div class="veri-btn pointer">{{$t('register.verifyCodeGet')}}</div>
<input :placeholder="$t('register.verifyCodePlaceholder')" class="ipt-code" type="text" v-model="registerForm.opt">
<div v-if="times.remain == 0" class="veri-btn pointer" @click="handlerStdSendOTP" >{{$t('register.verifyCodeGet')}}</div>
<div v-else class="veri-btn-default">{{times.tip}}</div>
</div>
</div>
</div>
</div>
<div class="login-protocol">
<img @click="onCheckHandler()" class="check pointer" src="@/assets/images/login/login-check.png">{{$t('register.agree')}}
<span @click="onProtocolHandler()" class="protocol pointer">{{$t('register.protocol')}}</span>
<div class="login-protocol pointer" @click="registerCheck.agreeProtocol = !registerCheck.agreeProtocol" >
<img v-if="!registerCheck.agreeProtocol" class="check" src="@/assets/images/login/un-check.png">
<img v-if="registerCheck.agreeProtocol" class="check" src="@/assets/images/login/check.png">
{{$t('login.agree')}}
<span @click="onProtocolHandler()" class="protocol pointer">{{$t('login.protocol')}}</span>
</div>
<div @click="onSubmitHandler()" class="login-submit pointer">{{$t('register.register')}}</div>
</div>
......@@ -57,7 +65,7 @@
<img src="@/assets/images/register/icon-register-lock.png"> {{$t('register.newPassword')}}
</div>
<div class="ipt-wrap">
<input :placeholder="$t('register.newPasswordPlaceholder')" class="ipt" type="text">
<input :placeholder="$t('register.newPasswordPlaceholder')" class="ipt" type="password" v-model="values.password">
</div>
</div>
<div class="pure-u-1 form-item">
......@@ -65,11 +73,11 @@
<img src="@/assets/images/register/icon-register-lock.png"> {{$t('register.newPasswordSure')}}
</div>
<div class="ipt-wrap">
<input :placeholder="$t('register.newPasswordSurePlaceholder')" class="ipt" type="text">
<input :placeholder="$t('register.newPasswordSurePlaceholder')" class="ipt" type="password" v-model="values.passwordRepeat">
</div>
</div>
</div>
<div @click="onSubmitHandler()" class="login-submit pointer">{{$t('register.sure')}}</div>
<div @click="onRegisterHandler()" class="login-submit pointer">{{$t('register.sure')}}</div>
</div>
</div>
</div>
......
import { setCookie, getCookie } from '@/utils/utils.js'
import { stat } from 'fs';
export function INCREMENT(state) {
state.counter++
}
......@@ -9,3 +12,13 @@ export function IS_MOBILE(state, bool) {
export function IS_SMALL_SCREEN(state, bool) {
state.isSmallScreen = bool
}
export function SET_USER_INFO(state, val) {
if (val) {
setCookie("_user_profile", encodeURIComponent(JSON.stringify(val)), 7200);
state.userInfo = val;
} else {
setCookie("_user_profile", "", 1);
state.userInfo = null;
}
}
\ No newline at end of file
......
......@@ -2,4 +2,10 @@ export default {
counter: 2, // 例子
isMobile: false, //是否手机访问
isSmallScreen: false, // 是否小屏幕 (PC时,小屏幕机导航栏会改变))
userInfo : {
sid : "",
name : "",
hadFullInfo: ""
}
}
......
......@@ -40,10 +40,10 @@ export function getCookie(name) {
}
//设置cookie
export function setCookie(c_name, value, expiredays) {
export function setCookie(c_name, value, second) {
var exdate = new Date();
exdate.setDate(exdate.getDate() + expiredays);
document.cookie = c_name + "=" + escape(value) + ((expiredays == null) ? "" : ";expires=" + exdate.toGMTString());
exdate.setTime(exdate.getTime() + second * 1000);
document.cookie = c_name + "=" + escape(value) + ((second == null) ? "" : ";expires=" + exdate.toGMTString());
};
//删除cookie
......