parent
5dd33c108c
commit
104cd0fcf2
@ -0,0 +1,125 @@
|
||||
/*https://music.163.com/weapi/song/enhance/player/url //mp3文件
|
||||
https://music.163.com/weapi/song/lyric //歌词
|
||||
https://music.163.com/weapi/v1/resource/comments/get //评论
|
||||
https://music.163.com/weapi/v1/discovery/simiSong //还喜欢听的歌
|
||||
|
||||
|
||||
params:YZDOQB4rCBrSTDdtOlkXOHwkCiDzJW1qPgBn3nzeV3YCCXMjV5G1pI6Jh97A33neWjCa4QQnVRs3hO2cMPPOXfbJNpvy/AZ/1RZEazlH9bM=
|
||||
encSecKey:428701e2ac634debc0e4cb7449c05251ebf5f304ddf01566aeb5bcb6a5a9fa242a9c677b9610450d534328c3b859456ec04a51c54d78709ce4963af260f83006605665abb0bb9a839c8405cb63a8ccef2d0c6afb1a40eb929f5c06714d1162fc5b4dcedf54e9581fd720df036b76d9d27f495a75846dbe378f7553b636b3a327
|
||||
|
||||
|
||||
params:Hw4jg6KU0cN4kAhsAV2ajQVIfUs/f9Ei+WtdQS/OZq+uQdmOgWX3ZQpEGAv6UskES7pHBC3iPiFnXq1CEqT4YoIOE452JIu9yfLzSQVODps=
|
||||
encSecKey:6a9692525559fdef4c0c316a407b36685a01d103b893e819043506a005c5175e647c79ff4d40db801f386aff90e2c82395663ac325ba22871ba02672c9ef7f048975aef92723a399b5f3c01b8d88cb993c8f41f958f8d633df45da9a263295b9ff986da59496551aed97a51c4a9ba738e37f7588f2c431fa9c855a61a508b26c
|
||||
"{"ids":"[525016797]","br":128000,"csrf_token":""}"
|
||||
"{"id":"545272449","c":"[{\"id\":\"545272449\"}]","csrf_token":""}"
|
||||
*/
|
||||
|
||||
var setV = {d:"{\"ids\":\"[\\\"1294899063\\\"]\",\"br\":\"128000\"}",e:'010001',f:"00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7",g:"0CoJUm6Qyw8W8jud"}
|
||||
function __n(e) {
|
||||
var t, r, n = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", i = "";
|
||||
for (t = 0; e > t; t += 1)
|
||||
r = Math.random() * n.length,
|
||||
r = Math.floor(r),
|
||||
i += n.charAt(r);
|
||||
return i
|
||||
}
|
||||
function __i(e, t) { //aes加密
|
||||
var r = CryptoJS.enc.Utf8.parse(t)
|
||||
, n = CryptoJS.enc.Utf8.parse("0102030405060708")
|
||||
, i = CryptoJS.enc.Utf8.parse(e)
|
||||
, o = CryptoJS.AES.encrypt(i, r, {
|
||||
iv: n,
|
||||
mode: CryptoJS.mode.CBC
|
||||
});
|
||||
return o.toString()
|
||||
}
|
||||
function __o(e, t, r) { //rsa加密
|
||||
//jsencrypt.js
|
||||
var n, i;
|
||||
|
||||
return setMaxDigits(131),
|
||||
n = new RSAKeyPair(t,"",r),
|
||||
i = encryptedString(n, e)
|
||||
}
|
||||
//{"ids":"[\"1294899063\"]","br":"128000"}
|
||||
//00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7
|
||||
//010001
|
||||
//0CoJUm6Qyw8W8jud
|
||||
function __a(e, t, r, a) {
|
||||
var s = {}
|
||||
, u = __n(16);
|
||||
return s.encText = __i(e, a),
|
||||
s.encText = __i(s.encText, u),
|
||||
s.encSecKey = __o(u, t, r),
|
||||
s
|
||||
}
|
||||
function __s(e, t, r, n) {
|
||||
var i = {};
|
||||
return i.encText = o(e + n, t, r),
|
||||
i
|
||||
}
|
||||
function __setCookie(){
|
||||
var cookies = "_iuqxldmzr_=32; _ntes_nnid=d34abbe36ac175e613653695a024446f,1535182652738; _ntes_nuid=d34abbe36ac175e613653695a024446f; WM_TID=02fOyLZUkn9Cx1Mk8rdGUIf5JC8MOMzU; __utma=94650624.1729429031.1535186517.1535459615.1535555297.7; __utmz=94650624.1535555297.7.7.utmcsr=baidu|utmccn=(organic)|utmcmd=organic; WM_NI=NrXqwYZgSXniPT5Sj2uwAAmfbnmw9eTbsy%2B9KFG7djd77oeuyenG%2FIVIP7WwEI3lASHxnnKaTIYedIb3zduFfaldpjd0UVGrUtqB1E7%2FpYt4zSYNR3iTtvLCd21g0GwfaHI%3D; WM_NIKE=9ca17ae2e6ffcda170e2e6eed5f662b39e97a9c961b28db6b7ee5c968b9795cc74b387a5a2f15bf8b38695d12af0fea7c3b92a8eae9892f6539ab99db9ed63948cfbb4e93ab7a98fa2f06ea2b2a398bc6f98bebd9aaa33899a89d8e762a8e9f990e87fbbbba2a8ae439697a0d8d67d8797fd8dc4598ca8a28fca6b98979786e743a2edb685f84ea6bfa485f362a8f09bb7c67a97acbfa3b44ff5f1c0baf740ba8d97afd139ab8cbc97cf49a8eeff88b34db5baafa9cc37e2a3; abt=10; JSESSIONID-WYYY=yZ%2F%2FTnIlU%2FEGC52vi1b06eYnhq4z4MCNjQjF%5CZ5aAsEdbr6Zj5cCmCJcyzE13%2Be%2BwcO%2BrQtlGvuJUmV7REDsba3Nmng3ICwVih8xZv9DJAO%2FI45IjIZgMwREShS94WefADq9rO0k%2B70b87pxzplAG0M%5C2vzSW4zkPf%2BNqKasDmExaSGr%3A1535703207465";
|
||||
var colist = cookies.split("; ");
|
||||
for(var i = 0; i<colist.length;i++){
|
||||
var v_a = colist[i].split("=");
|
||||
$.cookie(v_a[0],v_a[1]);
|
||||
}
|
||||
}
|
||||
function __addListenround(id){
|
||||
var la = $.cookie("listenround");
|
||||
if (la == undefined){
|
||||
la="";
|
||||
} else {
|
||||
la = la.replace(id+",","");
|
||||
}
|
||||
$.cookie("listenround",id+","+la);
|
||||
}
|
||||
|
||||
function __addplayList(list){
|
||||
var cookie = "";
|
||||
for(var i = 0 ; list.length > i ;i++){
|
||||
cookie = cookie + list[i].id + ",";
|
||||
}
|
||||
$.cookie("playList",cookie);
|
||||
}
|
||||
function __getplayList(){
|
||||
return $.cookie("playList");
|
||||
}
|
||||
function __getListenround(){
|
||||
return $.cookie("listenround");
|
||||
}
|
||||
function __addCur(point,id,cur){ //最后播放的位置
|
||||
$.cookie("lastCur",point+","+id+","+cur);
|
||||
}
|
||||
function __getlastCur(){ //最后播放的位置
|
||||
return $.cookie("lastCur");
|
||||
}
|
||||
function __getKeyton(){
|
||||
var res = __a(setV.d,setV.e,setV.f,setV.g);
|
||||
return [res.encText,res.encSecKey] ;
|
||||
}
|
||||
function __setSet(val){
|
||||
console.error(val);
|
||||
val.forEach(function (value, key, map) {
|
||||
//$.cookie(key,value);
|
||||
})
|
||||
}
|
||||
|
||||
function __standardLyric(lyric){
|
||||
var lyrics = lyric.lrc.lyric.split("\n");
|
||||
var timeReg = /\[\d*:\d*((\.|\:)\d*)*\]/;
|
||||
var ended = new Array();
|
||||
for(var i=0;i<lyrics.length;i++){
|
||||
var timeRegExpArr = lyrics[i].match(timeReg);
|
||||
if(!timeRegExpArr)continue;
|
||||
var clause = lyrics[i].replace(timeReg,'');
|
||||
var time = 0;
|
||||
var t = timeRegExpArr[0];
|
||||
var min = Number(String(t.match(/\[\d*/)).slice(1));
|
||||
var sec = Number(String(t.match(/\:\d*/)).slice(1));
|
||||
time = min * 60 + sec; //时间秒计
|
||||
ended[time] = clause;
|
||||
}
|
||||
return ended;
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
// BarrettMu, a class for performing Barrett modular reduction computations in
|
||||
// JavaScript.
|
||||
//
|
||||
// Requires BigInt.js.
|
||||
//
|
||||
// Copyright 2004-2005 David Shapiro.
|
||||
//
|
||||
// You may use, re-use, abuse, copy, and modify this code to your liking, but
|
||||
// please keep this header.
|
||||
//
|
||||
// Thanks!
|
||||
//
|
||||
// Dave Shapiro
|
||||
// dave@ohdave.com
|
||||
|
||||
function BarrettMu(m)
|
||||
{
|
||||
this.modulus = biCopy(m);
|
||||
this.k = biHighIndex(this.modulus) + 1;
|
||||
var b2k = new BigInt();
|
||||
b2k.digits[2 * this.k] = 1; // b2k = b^(2k)
|
||||
this.mu = biDivide(b2k, this.modulus);
|
||||
this.bkplus1 = new BigInt();
|
||||
this.bkplus1.digits[this.k + 1] = 1; // bkplus1 = b^(k+1)
|
||||
this.modulo = BarrettMu_modulo;
|
||||
this.multiplyMod = BarrettMu_multiplyMod;
|
||||
this.powMod = BarrettMu_powMod;
|
||||
}
|
||||
|
||||
function BarrettMu_modulo(x)
|
||||
{
|
||||
var q1 = biDivideByRadixPower(x, this.k - 1);
|
||||
var q2 = biMultiply(q1, this.mu);
|
||||
var q3 = biDivideByRadixPower(q2, this.k + 1);
|
||||
var r1 = biModuloByRadixPower(x, this.k + 1);
|
||||
var r2term = biMultiply(q3, this.modulus);
|
||||
var r2 = biModuloByRadixPower(r2term, this.k + 1);
|
||||
var r = biSubtract(r1, r2);
|
||||
if (r.isNeg) {
|
||||
r = biAdd(r, this.bkplus1);
|
||||
}
|
||||
var rgtem = biCompare(r, this.modulus) >= 0;
|
||||
while (rgtem) {
|
||||
r = biSubtract(r, this.modulus);
|
||||
rgtem = biCompare(r, this.modulus) >= 0;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
function BarrettMu_multiplyMod(x, y)
|
||||
{
|
||||
/*
|
||||
x = this.modulo(x);
|
||||
y = this.modulo(y);
|
||||
*/
|
||||
var xy = biMultiply(x, y);
|
||||
return this.modulo(xy);
|
||||
}
|
||||
|
||||
function BarrettMu_powMod(x, y)
|
||||
{
|
||||
var result = new BigInt();
|
||||
result.digits[0] = 1;
|
||||
var a = x;
|
||||
var k = y;
|
||||
while (true) {
|
||||
if ((k.digits[0] & 1) != 0) result = this.multiplyMod(result, a);
|
||||
k = biShiftRight(k, 1);
|
||||
if (k.digits[0] == 0 && biHighIndex(k) == 0) break;
|
||||
a = this.multiplyMod(a, a);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -0,0 +1,643 @@
|
||||
// BigInt, a suite of routines for performing multiple-precision arithmetic in
|
||||
// JavaScript.
|
||||
//
|
||||
// Copyright 1998-2005 David Shapiro.
|
||||
//
|
||||
// You may use, re-use, abuse,
|
||||
// copy, and modify this code to your liking, but please keep this header.
|
||||
// Thanks!
|
||||
//
|
||||
// Dave Shapiro
|
||||
// dave@ohdave.com
|
||||
|
||||
// IMPORTANT THING: Be sure to set maxDigits according to your precision
|
||||
// needs. Use the setMaxDigits() function to do this. See comments below.
|
||||
//
|
||||
// Tweaked by Ian Bunning
|
||||
// Alterations:
|
||||
// Fix bug in function biFromHex(s) to allow
|
||||
// parsing of strings of length != 0 (mod 4)
|
||||
|
||||
// Changes made by Dave Shapiro as of 12/30/2004:
|
||||
//
|
||||
// The BigInt() constructor doesn't take a string anymore. If you want to
|
||||
// create a BigInt from a string, use biFromDecimal() for base-10
|
||||
// representations, biFromHex() for base-16 representations, or
|
||||
// biFromString() for base-2-to-36 representations.
|
||||
//
|
||||
// biFromArray() has been removed. Use biCopy() instead, passing a BigInt
|
||||
// instead of an array.
|
||||
//
|
||||
// The BigInt() constructor now only constructs a zeroed-out array.
|
||||
// Alternatively, if you pass <true>, it won't construct any array. See the
|
||||
// biCopy() method for an example of this.
|
||||
//
|
||||
// Be sure to set maxDigits depending on your precision needs. The default
|
||||
// zeroed-out array ZERO_ARRAY is constructed inside the setMaxDigits()
|
||||
// function. So use this function to set the variable. DON'T JUST SET THE
|
||||
// VALUE. USE THE FUNCTION.
|
||||
//
|
||||
// ZERO_ARRAY exists to hopefully speed up construction of BigInts(). By
|
||||
// precalculating the zero array, we can just use slice(0) to make copies of
|
||||
// it. Presumably this calls faster native code, as opposed to setting the
|
||||
// elements one at a time. I have not done any timing tests to verify this
|
||||
// claim.
|
||||
|
||||
// Max number = 10^16 - 2 = 9999999999999998;
|
||||
// 2^53 = 9007199254740992;
|
||||
|
||||
var biRadixBase = 2;
|
||||
var biRadixBits = 16;
|
||||
var bitsPerDigit = biRadixBits;
|
||||
var biRadix = 1 << 16; // = 2^16 = 65536
|
||||
var biHalfRadix = biRadix >>> 1;
|
||||
var biRadixSquared = biRadix * biRadix;
|
||||
var maxDigitVal = biRadix - 1;
|
||||
var maxInteger = 9999999999999998;
|
||||
|
||||
// maxDigits:
|
||||
// Change this to accommodate your largest number size. Use setMaxDigits()
|
||||
// to change it!
|
||||
//
|
||||
// In general, if you're working with numbers of size N bits, you'll need 2*N
|
||||
// bits of storage. Each digit holds 16 bits. So, a 1024-bit key will need
|
||||
//
|
||||
// 1024 * 2 / 16 = 128 digits of storage.
|
||||
//
|
||||
|
||||
var maxDigits;
|
||||
var ZERO_ARRAY;
|
||||
var bigZero, bigOne;
|
||||
|
||||
function setMaxDigits(value)
|
||||
{
|
||||
maxDigits = value;
|
||||
ZERO_ARRAY = new Array(maxDigits);
|
||||
for (var iza = 0; iza < ZERO_ARRAY.length; iza++) ZERO_ARRAY[iza] = 0;
|
||||
bigZero = new BigInt();
|
||||
bigOne = new BigInt();
|
||||
bigOne.digits[0] = 1;
|
||||
}
|
||||
|
||||
setMaxDigits(20);
|
||||
|
||||
// The maximum number of digits in base 10 you can convert to an
|
||||
// integer without JavaScript throwing up on you.
|
||||
var dpl10 = 15;
|
||||
// lr10 = 10 ^ dpl10
|
||||
var lr10 = biFromNumber(1000000000000000);
|
||||
|
||||
function BigInt(flag)
|
||||
{
|
||||
if (typeof flag == "boolean" && flag == true) {
|
||||
this.digits = null;
|
||||
}
|
||||
else {
|
||||
this.digits = ZERO_ARRAY.slice(0);
|
||||
}
|
||||
this.isNeg = false;
|
||||
}
|
||||
|
||||
function biFromDecimal(s)
|
||||
{
|
||||
var isNeg = s.charAt(0) == '-';
|
||||
var i = isNeg ? 1 : 0;
|
||||
var result;
|
||||
// Skip leading zeros.
|
||||
while (i < s.length && s.charAt(i) == '0') ++i;
|
||||
if (i == s.length) {
|
||||
result = new BigInt();
|
||||
}
|
||||
else {
|
||||
var digitCount = s.length - i;
|
||||
var fgl = digitCount % dpl10;
|
||||
if (fgl == 0) fgl = dpl10;
|
||||
result = biFromNumber(Number(s.substr(i, fgl)));
|
||||
i += fgl;
|
||||
while (i < s.length) {
|
||||
result = biAdd(biMultiply(result, lr10),
|
||||
biFromNumber(Number(s.substr(i, dpl10))));
|
||||
i += dpl10;
|
||||
}
|
||||
result.isNeg = isNeg;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function biCopy(bi)
|
||||
{
|
||||
var result = new BigInt(true);
|
||||
result.digits = bi.digits.slice(0);
|
||||
result.isNeg = bi.isNeg;
|
||||
return result;
|
||||
}
|
||||
|
||||
function biFromNumber(i)
|
||||
{
|
||||
var result = new BigInt();
|
||||
result.isNeg = i < 0;
|
||||
i = Math.abs(i);
|
||||
var j = 0;
|
||||
while (i > 0) {
|
||||
result.digits[j++] = i & maxDigitVal;
|
||||
i >>= biRadixBits;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function reverseStr(s)
|
||||
{
|
||||
var result = "";
|
||||
for (var i = s.length - 1; i > -1; --i) {
|
||||
result += s.charAt(i);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
var hexatrigesimalToChar = new Array(
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
|
||||
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
|
||||
'u', 'v', 'w', 'x', 'y', 'z'
|
||||
);
|
||||
|
||||
function biToString(x, radix)
|
||||
// 2 <= radix <= 36
|
||||
{
|
||||
var b = new BigInt();
|
||||
b.digits[0] = radix;
|
||||
var qr = biDivideModulo(x, b);
|
||||
var result = hexatrigesimalToChar[qr[1].digits[0]];
|
||||
while (biCompare(qr[0], bigZero) == 1) {
|
||||
qr = biDivideModulo(qr[0], b);
|
||||
digit = qr[1].digits[0];
|
||||
result += hexatrigesimalToChar[qr[1].digits[0]];
|
||||
}
|
||||
return (x.isNeg ? "-" : "") + reverseStr(result);
|
||||
}
|
||||
|
||||
function biToDecimal(x)
|
||||
{
|
||||
var b = new BigInt();
|
||||
b.digits[0] = 10;
|
||||
var qr = biDivideModulo(x, b);
|
||||
var result = String(qr[1].digits[0]);
|
||||
while (biCompare(qr[0], bigZero) == 1) {
|
||||
qr = biDivideModulo(qr[0], b);
|
||||
result += String(qr[1].digits[0]);
|
||||
}
|
||||
return (x.isNeg ? "-" : "") + reverseStr(result);
|
||||
}
|
||||
|
||||
var hexToChar = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
||||
'a', 'b', 'c', 'd', 'e', 'f');
|
||||
|
||||
function digitToHex(n)
|
||||
{
|
||||
var mask = 0xf;
|
||||
var result = "";
|
||||
for (i = 0; i < 4; ++i) {
|
||||
result += hexToChar[n & mask];
|
||||
n >>>= 4;
|
||||
}
|
||||
return reverseStr(result);
|
||||
}
|
||||
|
||||
function biToHex(x)
|
||||
{
|
||||
var result = "";
|
||||
var n = biHighIndex(x);
|
||||
for (var i = biHighIndex(x); i > -1; --i) {
|
||||
result += digitToHex(x.digits[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function charToHex(c)
|
||||
{
|
||||
var ZERO = 48;
|
||||
var NINE = ZERO + 9;
|
||||
var littleA = 97;
|
||||
var littleZ = littleA + 25;
|
||||
var bigA = 65;
|
||||
var bigZ = 65 + 25;
|
||||
var result;
|
||||
|
||||
if (c >= ZERO && c <= NINE) {
|
||||
result = c - ZERO;
|
||||
} else if (c >= bigA && c <= bigZ) {
|
||||
result = 10 + c - bigA;
|
||||
} else if (c >= littleA && c <= littleZ) {
|
||||
result = 10 + c - littleA;
|
||||
} else {
|
||||
result = 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function hexToDigit(s)
|
||||
{
|
||||
var result = 0;
|
||||
var sl = Math.min(s.length, 4);
|
||||
for (var i = 0; i < sl; ++i) {
|
||||
result <<= 4;
|
||||
result |= charToHex(s.charCodeAt(i))
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function biFromHex(s)
|
||||
{
|
||||
var result = new BigInt();
|
||||
var sl = s.length;
|
||||
for (var i = sl, j = 0; i > 0; i -= 4, ++j) {
|
||||
result.digits[j] = hexToDigit(s.substr(Math.max(i - 4, 0), Math.min(i, 4)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function biFromString(s, radix)
|
||||
{
|
||||
var isNeg = s.charAt(0) == '-';
|
||||
var istop = isNeg ? 1 : 0;
|
||||
var result = new BigInt();
|
||||
var place = new BigInt();
|
||||
place.digits[0] = 1; // radix^0
|
||||
for (var i = s.length - 1; i >= istop; i--) {
|
||||
var c = s.charCodeAt(i);
|
||||
var digit = charToHex(c);
|
||||
var biDigit = biMultiplyDigit(place, digit);
|
||||
result = biAdd(result, biDigit);
|
||||
place = biMultiplyDigit(place, radix);
|
||||
}
|
||||
result.isNeg = isNeg;
|
||||
return result;
|
||||
}
|
||||
|
||||
function biToBytes(x)
|
||||
// Returns a string containing raw bytes.
|
||||
{
|
||||
var result = "";
|
||||
for (var i = biHighIndex(x); i > -1; --i) {
|
||||
result += digitToBytes(x.digits[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function digitToBytes(n)
|
||||
// Convert two-byte digit to string containing both bytes.
|
||||
{
|
||||
var c1 = String.fromCharCode(n & 0xff);
|
||||
n >>>= 8;
|
||||
var c2 = String.fromCharCode(n & 0xff);
|
||||
return c2 + c1;
|
||||
}
|
||||
|
||||
function biDump(b)
|
||||
{
|
||||
return (b.isNeg ? "-" : "") + b.digits.join(" ");
|
||||
}
|
||||
|
||||
function biAdd(x, y)
|
||||
{
|
||||
var result;
|
||||
|
||||
if (x.isNeg != y.isNeg) {
|
||||
y.isNeg = !y.isNeg;
|
||||
result = biSubtract(x, y);
|
||||
y.isNeg = !y.isNeg;
|
||||
}
|
||||
else {
|
||||
result = new BigInt();
|
||||
var c = 0;
|
||||
var n;
|
||||
for (var i = 0; i < x.digits.length; ++i) {
|
||||
n = x.digits[i] + y.digits[i] + c;
|
||||
result.digits[i] = n & 0xffff;
|
||||
c = Number(n >= biRadix);
|
||||
}
|
||||
result.isNeg = x.isNeg;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function biSubtract(x, y)
|
||||
{
|
||||
var result;
|
||||
if (x.isNeg != y.isNeg) {
|
||||
y.isNeg = !y.isNeg;
|
||||
result = biAdd(x, y);
|
||||
y.isNeg = !y.isNeg;
|
||||
} else {
|
||||
result = new BigInt();
|
||||
var n, c;
|
||||
c = 0;
|
||||
for (var i = 0; i < x.digits.length; ++i) {
|
||||
n = x.digits[i] - y.digits[i] + c;
|
||||
result.digits[i] = n & 0xffff;
|
||||
// Stupid non-conforming modulus operation.
|
||||
if (result.digits[i] < 0) result.digits[i] += biRadix;
|
||||
c = 0 - Number(n < 0);
|
||||
}
|
||||
// Fix up the negative sign, if any.
|
||||
if (c == -1) {
|
||||
c = 0;
|
||||
for (var i = 0; i < x.digits.length; ++i) {
|
||||
n = 0 - result.digits[i] + c;
|
||||
result.digits[i] = n & 0xffff;
|
||||
// Stupid non-conforming modulus operation.
|
||||
if (result.digits[i] < 0) result.digits[i] += biRadix;
|
||||
c = 0 - Number(n < 0);
|
||||
}
|
||||
// Result is opposite sign of arguments.
|
||||
result.isNeg = !x.isNeg;
|
||||
} else {
|
||||
// Result is same sign.
|
||||
result.isNeg = x.isNeg;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function biHighIndex(x)
|
||||
{
|
||||
var result = x.digits.length - 1;
|
||||
while (result > 0 && x.digits[result] == 0) --result;
|
||||
return result;
|
||||
}
|
||||
|
||||
function biNumBits(x)
|
||||
{
|
||||
var n = biHighIndex(x);
|
||||
var d = x.digits[n];
|
||||
var m = (n + 1) * bitsPerDigit;
|
||||
var result;
|
||||
for (result = m; result > m - bitsPerDigit; --result) {
|
||||
if ((d & 0x8000) != 0) break;
|
||||
d <<= 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function biMultiply(x, y)
|
||||
{
|
||||
var result = new BigInt();
|
||||
var c;
|
||||
var n = biHighIndex(x);
|
||||
var t = biHighIndex(y);
|
||||
var u, uv, k;
|
||||
|
||||
for (var i = 0; i <= t; ++i) {
|
||||
c = 0;
|
||||
k = i;
|
||||
for (j = 0; j <= n; ++j, ++k) {
|
||||
uv = result.digits[k] + x.digits[j] * y.digits[i] + c;
|
||||
result.digits[k] = uv & maxDigitVal;
|
||||
c = uv >>> biRadixBits;
|
||||
}
|
||||
result.digits[i + n + 1] = c;
|
||||
}
|
||||
// Someone give me a logical xor, please.
|
||||
result.isNeg = x.isNeg != y.isNeg;
|
||||
return result;
|
||||
}
|
||||
|
||||
function biMultiplyDigit(x, y)
|
||||
{
|
||||
var n, c, uv;
|
||||
|
||||
result = new BigInt();
|
||||
n = biHighIndex(x);
|
||||
c = 0;
|
||||
for (var j = 0; j <= n; ++j) {
|
||||
uv = result.digits[j] + x.digits[j] * y + c;
|
||||
result.digits[j] = uv & maxDigitVal;
|
||||
c = uv >>> biRadixBits;
|
||||
}
|
||||
result.digits[1 + n] = c;
|
||||
return result;
|
||||
}
|
||||
|
||||
function arrayCopy(src, srcStart, dest, destStart, n)
|
||||
{
|
||||
var m = Math.min(srcStart + n, src.length);
|
||||
for (var i = srcStart, j = destStart; i < m; ++i, ++j) {
|
||||
dest[j] = src[i];
|
||||
}
|
||||
}
|
||||
|
||||
var highBitMasks = new Array(0x0000, 0x8000, 0xC000, 0xE000, 0xF000, 0xF800,
|
||||
0xFC00, 0xFE00, 0xFF00, 0xFF80, 0xFFC0, 0xFFE0,
|
||||
0xFFF0, 0xFFF8, 0xFFFC, 0xFFFE, 0xFFFF);
|
||||
|
||||
function biShiftLeft(x, n)
|
||||
{
|
||||
var digitCount = Math.floor(n / bitsPerDigit);
|
||||
var result = new BigInt();
|
||||
arrayCopy(x.digits, 0, result.digits, digitCount,
|
||||
result.digits.length - digitCount);
|
||||
var bits = n % bitsPerDigit;
|
||||
var rightBits = bitsPerDigit - bits;
|
||||
for (var i = result.digits.length - 1, i1 = i - 1; i > 0; --i, --i1) {
|
||||
result.digits[i] = ((result.digits[i] << bits) & maxDigitVal) |
|
||||
((result.digits[i1] & highBitMasks[bits]) >>>
|
||||
(rightBits));
|
||||
}
|
||||
result.digits[0] = ((result.digits[i] << bits) & maxDigitVal);
|
||||
result.isNeg = x.isNeg;
|
||||
return result;
|
||||
}
|
||||
|
||||
var lowBitMasks = new Array(0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F,
|
||||
0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF,
|
||||
0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF);
|
||||
|
||||
function biShiftRight(x, n)
|
||||
{
|
||||
var digitCount = Math.floor(n / bitsPerDigit);
|
||||
var result = new BigInt();
|
||||
arrayCopy(x.digits, digitCount, result.digits, 0,
|
||||
x.digits.length - digitCount);
|
||||
var bits = n % bitsPerDigit;
|
||||
var leftBits = bitsPerDigit - bits;
|
||||
for (var i = 0, i1 = i + 1; i < result.digits.length - 1; ++i, ++i1) {
|
||||
result.digits[i] = (result.digits[i] >>> bits) |
|
||||
((result.digits[i1] & lowBitMasks[bits]) << leftBits);
|
||||
}
|
||||
result.digits[result.digits.length - 1] >>>= bits;
|
||||
result.isNeg = x.isNeg;
|
||||
return result;
|
||||
}
|
||||
|
||||
function biMultiplyByRadixPower(x, n)
|
||||
{
|
||||
var result = new BigInt();
|
||||
arrayCopy(x.digits, 0, result.digits, n, result.digits.length - n);
|
||||
return result;
|
||||
}
|
||||
|
||||
function biDivideByRadixPower(x, n)
|
||||
{
|
||||
var result = new BigInt();
|
||||
arrayCopy(x.digits, n, result.digits, 0, result.digits.length - n);
|
||||
return result;
|
||||
}
|
||||
|
||||
function biModuloByRadixPower(x, n)
|
||||
{
|
||||
var result = new BigInt();
|
||||
arrayCopy(x.digits, 0, result.digits, 0, n);
|
||||
return result;
|
||||
}
|
||||
|
||||
function biCompare(x, y)
|
||||
{
|
||||
if (x.isNeg != y.isNeg) {
|
||||
return 1 - 2 * Number(x.isNeg);
|
||||
}
|
||||
for (var i = x.digits.length - 1; i >= 0; --i) {
|
||||
if (x.digits[i] != y.digits[i]) {
|
||||
if (x.isNeg) {
|
||||
return 1 - 2 * Number(x.digits[i] > y.digits[i]);
|
||||
} else {
|
||||
return 1 - 2 * Number(x.digits[i] < y.digits[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function biDivideModulo(x, y)
|
||||
{
|
||||
var nb = biNumBits(x);
|
||||
var tb = biNumBits(y);
|
||||
var origYIsNeg = y.isNeg;
|
||||
var q, r;
|
||||
if (nb < tb) {
|
||||
// |x| < |y|
|
||||
if (x.isNeg) {
|
||||
q = biCopy(bigOne);
|
||||
q.isNeg = !y.isNeg;
|
||||
x.isNeg = false;
|
||||
y.isNeg = false;
|
||||
r = biSubtract(y, x);
|
||||
// Restore signs, 'cause they're references.
|
||||
x.isNeg = true;
|
||||
y.isNeg = origYIsNeg;
|
||||
} else {
|
||||
q = new BigInt();
|
||||
r = biCopy(x);
|
||||
}
|
||||
return new Array(q, r);
|
||||
}
|
||||
|
||||
q = new BigInt();
|
||||
r = x;
|
||||
|
||||
// Normalize Y.
|
||||
var t = Math.ceil(tb / bitsPerDigit) - 1;
|
||||
var lambda = 0;
|
||||
while (y.digits[t] < biHalfRadix) {
|
||||
y = biShiftLeft(y, 1);
|
||||
++lambda;
|
||||
++tb;
|
||||
t = Math.ceil(tb / bitsPerDigit) - 1;
|
||||
}
|
||||
// Shift r over to keep the quotient constant. We'll shift the
|
||||
// remainder back at the end.
|
||||
r = biShiftLeft(r, lambda);
|
||||
nb += lambda; // Update the bit count for x.
|
||||
var n = Math.ceil(nb / bitsPerDigit) - 1;
|
||||
|
||||
var b = biMultiplyByRadixPower(y, n - t);
|
||||
while (biCompare(r, b) != -1) {
|
||||
++q.digits[n - t];
|
||||
r = biSubtract(r, b);
|
||||
}
|
||||
for (var i = n; i > t; --i) {
|
||||
var ri = (i >= r.digits.length) ? 0 : r.digits[i];
|
||||
var ri1 = (i - 1 >= r.digits.length) ? 0 : r.digits[i - 1];
|
||||
var ri2 = (i - 2 >= r.digits.length) ? 0 : r.digits[i - 2];
|
||||
var yt = (t >= y.digits.length) ? 0 : y.digits[t];
|
||||
var yt1 = (t - 1 >= y.digits.length) ? 0 : y.digits[t - 1];
|
||||
if (ri == yt) {
|
||||
q.digits[i - t - 1] = maxDigitVal;
|
||||
} else {
|
||||
q.digits[i - t - 1] = Math.floor((ri * biRadix + ri1) / yt);
|
||||
}
|
||||
|
||||
var c1 = q.digits[i - t - 1] * ((yt * biRadix) + yt1);
|
||||
var c2 = (ri * biRadixSquared) + ((ri1 * biRadix) + ri2);
|
||||
while (c1 > c2) {
|
||||
--q.digits[i - t - 1];
|
||||
c1 = q.digits[i - t - 1] * ((yt * biRadix) | yt1);
|
||||
c2 = (ri * biRadix * biRadix) + ((ri1 * biRadix) + ri2);
|
||||
}
|
||||
|
||||
b = biMultiplyByRadixPower(y, i - t - 1);
|
||||
r = biSubtract(r, biMultiplyDigit(b, q.digits[i - t - 1]));
|
||||
if (r.isNeg) {
|
||||
r = biAdd(r, b);
|
||||
--q.digits[i - t - 1];
|
||||
}
|
||||
}
|
||||
r = biShiftRight(r, lambda);
|
||||
// Fiddle with the signs and stuff to make sure that 0 <= r < y.
|
||||
q.isNeg = x.isNeg != origYIsNeg;
|
||||
if (x.isNeg) {
|
||||
if (origYIsNeg) {
|
||||
q = biAdd(q, bigOne);
|
||||
} else {
|
||||
q = biSubtract(q, bigOne);
|
||||
}
|
||||
y = biShiftRight(y, lambda);
|
||||
r = biSubtract(y, r);
|
||||
}
|
||||
// Check for the unbelievably stupid degenerate case of r == -0.
|
||||
if (r.digits[0] == 0 && biHighIndex(r) == 0) r.isNeg = false;
|
||||
|
||||
return new Array(q, r);
|
||||
}
|
||||
|
||||
function biDivide(x, y)
|
||||
{
|
||||
return biDivideModulo(x, y)[0];
|
||||
}
|
||||
|
||||
function biModulo(x, y)
|
||||
{
|
||||
return biDivideModulo(x, y)[1];
|
||||
}
|
||||
|
||||
function biMultiplyMod(x, y, m)
|
||||
{
|
||||
return biModulo(biMultiply(x, y), m);
|
||||
}
|
||||
|
||||
function biPow(x, y)
|
||||
{
|
||||
var result = bigOne;
|
||||
var a = x;
|
||||
while (true) {
|
||||
if ((y & 1) != 0) result = biMultiply(result, a);
|
||||
y >>= 1;
|
||||
if (y == 0) break;
|
||||
a = biMultiply(a, a);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function biPowMod(x, y, m)
|
||||
{
|
||||
var result = bigOne;
|
||||
var a = x;
|
||||
var k = y;
|
||||
while (true) {
|
||||
if ((k.digits[0] & 1) != 0) result = biMultiplyMod(result, a, m);
|
||||
k = biShiftRight(k, 1);
|
||||
if (k.digits[0] == 0 && biHighIndex(k) == 0) break;
|
||||
a = biMultiplyMod(a, a, m);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -0,0 +1,62 @@
|
||||
|
||||
JMshake.prototype.canvas = null;
|
||||
JMshake.prototype.stop = false;
|
||||
function JMshake(canvas,audio){
|
||||
this.canvas = canvas;//canvas
|
||||
this.audio = audio;
|
||||
}
|
||||
JMshake.prototype.init = function(){
|
||||
|
||||
}
|
||||
JMshake.prototype.eventBing = function(){
|
||||
|
||||
}
|
||||
JMshake.prototype.loadMusic = function(){
|
||||
var that = this;
|
||||
var context = that.canvas.getContext("2d");
|
||||
var WIDTH = that.canvas.width;
|
||||
var HEIGHT = that.canvas.height;
|
||||
|
||||
//part3: 分析器
|
||||
var AudCtx = new AudioContext();//音频内容
|
||||
var analyser = AudCtx.createAnalyser();
|
||||
var src = AudCtx.createMediaElementSource(that.audio);
|
||||
src.connect(analyser);
|
||||
analyser.connect(AudCtx.destination);
|
||||
analyser.fftSize = 512;//快速傅里叶变换, 必须为2的N次方
|
||||
var bufferLength = analyser.frequencyBinCount;// = fftSize * 0.5
|
||||
|
||||
//part4: 变量
|
||||
var barWidth = 3;//间隔1px
|
||||
var barHeight;
|
||||
var dataArray = new Uint8Array(bufferLength);//8位无符号定长数组
|
||||
|
||||
//part5: 动态监听
|
||||
function renderFrame() {
|
||||
context.fillStyle = 'rgba(255, 255, 255, 0)';
|
||||
context.clearRect(0, 0, WIDTH, HEIGHT);
|
||||
context.fillRect(0, 0, WIDTH, HEIGHT);//画布拓展全屏,动态调整
|
||||
analyser.getByteFrequencyData(dataArray);//获取当前时刻的音频数据
|
||||
//part6: 绘画声压条
|
||||
var x = 0;
|
||||
for (var i = 0; i < bufferLength; i++) {
|
||||
var data = dataArray[i];//int,0~255
|
||||
var percentV = data / 255;//纵向比例
|
||||
var percentH = i / bufferLength;//横向比例
|
||||
barHeight = HEIGHT * percentV;
|
||||
var r = 255 * percentV;//值越大越红
|
||||
var g = 255 * percentH;//越靠右越绿
|
||||
var b = 50;
|
||||
context.fillStyle = "rgb(" + r + "," + g + "," + b + ")";
|
||||
x = i*barWidth;//间隔1px
|
||||
context.fillRect(x, HEIGHT - barHeight, barWidth, barHeight);
|
||||
}
|
||||
that.animation = requestAnimationFrame(renderFrame);
|
||||
}
|
||||
that.audio.oncanplaythrough = function Draw() {
|
||||
window.cancelAnimationFrame(that.animation);
|
||||
delete that.animation;
|
||||
renderFrame();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,572 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Eric Wilde.
|
||||
* Copyright 1998-2015 David Shapiro.
|
||||
*
|
||||
* RSA.js is a suite of routines for performing RSA public-key computations
|
||||
* in JavaScript. The cryptographic functions herein are used for encoding
|
||||
* and decoding strings to be sent over unsecure channels.
|
||||
*
|
||||
* To use these routines, a pair of public/private keys is created through a
|
||||
* number of means (OpenSSL tools on Linux/Unix, Dave Shapiro's
|
||||
* RSAKeyGenerator program on Windows). These keys are passed to RSAKeyPair
|
||||
* as hexadecimal strings to create an encryption key object. This key object
|
||||
* is then used with encryptedString to encrypt blocks of plaintext using the
|
||||
* public key. The resulting cyphertext blocks can be decrypted with
|
||||
* decryptedString.
|
||||
*
|
||||
* Note that the cryptographic functions herein are complementary to those
|
||||
* found in CryptoFuncs.php and CryptoFuncs.pm. Hence, encrypted messages may
|
||||
* be sent between programs written in any of those languages. The most
|
||||
* useful, of course is to send messages encrypted by a Web page using RSA.js
|
||||
* to a PHP or Perl script running on a Web servitron.
|
||||
*
|
||||
* Also, the optional padding flag may be specified on the call to
|
||||
* encryptedString, in which case blocks of cyphertext that are compatible
|
||||
* with real crypto libraries such as OpenSSL or Microsoft will be created.
|
||||
* These blocks of cyphertext can then be sent to Web servitron that uses one
|
||||
* of these crypto libraries for decryption. This allows messages encrypted
|
||||
* with longer keys to be decrypted quickly on the Web server as well as
|
||||
* making for more secure communications when a padding algorithm such as
|
||||
* PKCS1v1.5 is used.
|
||||
*
|
||||
* These routines require BigInt.js and Barrett.js.
|
||||
*/
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Modifications
|
||||
* -------------
|
||||
*
|
||||
* 2014 Jan 11 E. Wilde Add optional padding flag to encryptedString
|
||||
* for compatibility with real crypto libraries
|
||||
* such as OpenSSL or Microsoft. Add PKCS1v1.5
|
||||
* padding.
|
||||
*
|
||||
* 2015 Jan 5 D. Shapiro Add optional encoding flag for encryptedString
|
||||
* and encapsulate padding and encoding constants
|
||||
* in RSAAPP object.
|
||||
*
|
||||
* Original Code
|
||||
* -------------
|
||||
*
|
||||
* Copyright 1998-2005 David Shapiro.
|
||||
*
|
||||
* You may use, re-use, abuse, copy, and modify this code to your liking, but
|
||||
* please keep this header.
|
||||
*
|
||||
* Thanks!
|
||||
*
|
||||
* Dave Shapiro
|
||||
* dave@ohdave.com
|
||||
*/
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
var RSAAPP = {};
|
||||
|
||||
RSAAPP.NoPadding = "NoPadding";
|
||||
RSAAPP.PKCS1Padding = "PKCS1Padding";
|
||||
RSAAPP.RawEncoding = "RawEncoding";
|
||||
RSAAPP.NumericEncoding = "NumericEncoding"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
function RSAKeyPair(encryptionExponent, decryptionExponent, modulus, keylen)
|
||||
/*
|
||||
* encryptionExponent The encryption exponent (i.e. public
|
||||
* encryption key) to be used for
|
||||
* encrypting messages. If you aren't
|
||||
* doing any encrypting, a dummy
|
||||
* exponent such as "10001" can be
|
||||
* passed.
|
||||
*
|
||||
* decryptionExponent The decryption exponent (i.e. private
|
||||
* decryption key) to be used for
|
||||
* decrypting messages. If you aren't
|
||||
* doing any decrypting, a dummy
|
||||
* exponent such as "10001" can be
|
||||
* passed.
|
||||
*
|
||||
* modulus The modulus to be used both for
|
||||
* encrypting and decrypting messages.
|
||||
*
|
||||
* keylen The optional length of the key, in
|
||||
* bits. If omitted, RSAKeyPair will
|
||||
* attempt to derive a key length (but,
|
||||
* see the notes below).
|
||||
*
|
||||
* returns The "new" object creator returns an
|
||||
* instance of a key object that can be
|
||||
* used to encrypt/decrypt messages.
|
||||
*
|
||||
* This routine is invoked as the first step in the encryption or decryption
|
||||
* process to take the three numbers (expressed as hexadecimal strings) that
|
||||
* are used for RSA asymmetric encryption/decryption and turn them into a key
|
||||
* object that can be used for encrypting and decrypting.
|
||||
*
|
||||
* The key object is created thusly:
|
||||
*
|
||||
* RSAKey = new RSAKeyPair("ABC12345", 10001, "987654FE");
|
||||
*
|
||||
* or:
|
||||
*
|
||||
* RSAKey = new RSAKeyPair("ABC12345", 10001, "987654FE", 64);
|
||||
*
|
||||
* Note that RSAKeyPair will try to derive the length of the key that is being
|
||||
* used, from the key itself. The key length is especially useful when one of
|
||||
* the padding options is used and/or when the encrypted messages created by
|
||||
* the routine encryptedString are exchanged with a real crypto library such
|
||||
* as OpenSSL or Microsoft, as it determines how many padding characters are
|
||||
* appended.
|
||||
*
|
||||
* Usually, RSAKeyPair can determine the key length from the modulus of the
|
||||
* key but this doesn't always work properly, depending on the actual value of
|
||||
* the modulus. If you are exchanging messages with a real crypto library,
|
||||
* such as OpenSSL or Microsoft, that depends on the fact that the blocks
|
||||
* being passed to it are properly padded, you'll want the key length to be
|
||||
* set properly. If that's the case, of if you just want to be sure, you
|
||||
* should specify the key length that you used to generated the key, in bits
|
||||
* when this routine is invoked.
|
||||
*/
|
||||
{
|
||||
/*
|
||||
* Convert from hexadecimal and save the encryption/decryption exponents and
|
||||
* modulus as big integers in the key object.
|
||||
*/
|
||||
this.e = biFromHex(encryptionExponent);
|
||||
this.d = biFromHex(decryptionExponent);
|
||||
this.m = biFromHex(modulus);
|
||||
/*
|
||||
* Using big integers, we can represent two bytes per element in the big
|
||||
* integer array, so we calculate the chunk size as:
|
||||
*
|
||||
* chunkSize = 2 * (number of digits in modulus - 1)
|
||||
*
|
||||
* Since biHighIndex returns the high index, not the number of digits, the
|
||||
* number 1 has already been subtracted from its answer.
|
||||
*
|
||||
* However, having said all this, "User Knows Best". If our caller passes us
|
||||
* a key length (in bits), we'll treat it as gospel truth.
|
||||
*/
|
||||
if (typeof(keylen) != 'number') { this.chunkSize = 2 * biHighIndex(this.m); }
|
||||
else { this.chunkSize = keylen / 8; }
|
||||
|
||||
this.radix = 16;
|
||||
/*
|
||||
* Precalculate the stuff used for Barrett modular reductions.
|
||||
*/
|
||||
this.barrett = new BarrettMu(this.m);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
function encryptedString(key, s, pad, encoding)
|
||||
/*
|
||||
* key The previously-built RSA key whose
|
||||
* public key component is to be used to
|
||||
* encrypt the plaintext string.
|
||||
*
|
||||
* s The plaintext string that is to be
|
||||
* encrypted, using the RSA assymmetric
|
||||
* encryption method.
|
||||
*
|
||||
* pad The optional padding method to use
|
||||
* when extending the plaintext to the
|
||||
* full chunk size required by the RSA
|
||||
* algorithm. To maintain compatibility
|
||||
* with other crypto libraries, the
|
||||
* padding method is described by a
|
||||
* string. The default, if not
|
||||
* specified is "OHDave". Here are the
|
||||
* choices:
|
||||
*
|
||||
* OHDave - this is the original
|
||||
* padding method employed by Dave
|
||||
* Shapiro and Rob Saunders. If
|
||||
* this method is chosen, the
|
||||
* plaintext can be of any length.
|
||||
* It will be padded to the correct
|
||||
* length with zeros and then broken
|
||||
* up into chunks of the correct
|
||||
* length before being encrypted.
|
||||
* The resultant cyphertext blocks
|
||||
* will be separated by blanks.
|
||||
*
|
||||
* Note that the original code by
|
||||
* Dave Shapiro reverses the byte
|
||||
* order to little-endian, as the
|
||||
* plaintext is encrypted. If
|
||||
* either these JavaScript routines
|
||||
* or one of the complementary
|
||||
* PHP/Perl routines derived from
|
||||
* this code is used for decryption,
|
||||
* the byte order will be reversed
|
||||
* again upon decryption so as to
|
||||
* come out correctly.
|
||||
*
|
||||
* Also note that this padding
|
||||
* method is claimed to be less
|
||||
* secure than PKCS1Padding.
|
||||
*
|
||||
* NoPadding - this method truncates
|
||||
* the plaintext to the length of
|
||||
* the RSA key, if it is longer. If
|
||||
* its length is shorter, it is
|
||||
* padded with zeros. In either
|
||||
* case, the plaintext string is
|
||||
* reversed to preserve big-endian
|
||||
* order before it is encrypted to
|
||||
* maintain compatibility with real
|
||||
* crypto libraries such as OpenSSL
|
||||
* or Microsoft. When the
|
||||
* cyphertext is to be decrypted
|
||||
* by a crypto library, the
|
||||
* library routine's RSAAPP.NoPadding
|
||||
* flag, or its equivalent, should
|
||||
* be used.
|
||||
*
|
||||
* Note that this padding method is
|
||||
* claimed to be less secure than
|
||||
* PKCS1Padding.
|
||||
*
|
||||
* PKCS1Padding - the PKCS1v1.5
|
||||
* padding method (as described in
|
||||
* RFC 2313) is employed to pad the
|
||||
* plaintext string. The plaintext
|
||||
* string must be no longer than the
|
||||
* length of the RSA key minus 11,
|
||||
* since PKCS1v1.5 requires 3 bytes
|
||||
* of overhead and specifies a
|
||||
* minimum pad of 8 bytes. The
|
||||
* plaintext string is padded with
|
||||
* randomly-generated bytes and then
|
||||
* its order is reversed to preserve
|
||||
* big-endian order before it is
|
||||
* encrypted to maintain
|
||||
* compatibility with real crypto
|
||||
* libraries such as OpenSSL or
|
||||
* Microsoft. When the cyphertext
|
||||
* is to be decrypted by a crypto
|
||||
* library, the library routine's
|
||||
* RSAAPP.PKCS1Padding flag, or its
|
||||
* equivalent, should be used.
|
||||
*
|
||||
* encoding The optional encoding scheme to use
|
||||
* for the return value. If ommitted,
|
||||
* numeric encoding will be used.
|
||||
*
|
||||
* RawEncoding - The return value
|
||||
* is given as its raw value.
|
||||
* This is the easiest method when
|
||||
* interoperating with server-side
|
||||
* OpenSSL, as no additional conversion
|
||||
* is required. Use the constant
|
||||
* RSAAPP.RawEncoding for this option.
|
||||
*
|
||||
* NumericEncoding - The return value
|
||||
* is given as a number in hexadecimal.
|
||||
* Perhaps useful for debugging, but
|
||||
* will need to be translated back to
|
||||
* its raw equivalent (e.g. using
|
||||
* PHP's hex2bin) before using with
|
||||
* OpenSSL. Use the constant
|
||||
* RSAAPP.NumericEncoding for this option.
|
||||
*
|
||||
* returns The cyphertext block that results
|
||||
* from encrypting the plaintext string
|
||||
* s with the RSA key.
|
||||
*
|
||||
* This routine accepts a plaintext string that is to be encrypted with the
|
||||
* public key component of the previously-built RSA key using the RSA
|
||||
* assymmetric encryption method. Before it is encrypted, the plaintext
|
||||
* string is padded to the same length as the encryption key for proper
|
||||
* encryption.
|
||||
*
|
||||
* Depending on the padding method chosen, an optional header with block type
|
||||
* is prepended, the plaintext is padded using zeros or randomly-generated
|
||||
* bytes, and then the plaintext is possibly broken up into chunks.
|
||||
*
|
||||
* Note that, for padding with zeros, this routine was altered by Rob Saunders
|
||||
* (rob@robsaunders.net). The new routine pads the string after it has been
|
||||
* converted to an array. This fixes an incompatibility with Flash MX's
|
||||
* ActionScript.
|
||||
*
|
||||
* The various padding schemes employed by this routine, and as presented to
|
||||
* RSA for encryption, are shown below. Note that the RSA encryption done
|
||||
* herein reverses the byte order as encryption is done:
|
||||
*
|
||||
* Plaintext In
|
||||
* ------------
|
||||
*
|
||||
* d5 d4 d3 d2 d1 d0
|
||||
*
|
||||
* OHDave
|
||||
* ------
|
||||
*
|
||||
* d5 d4 d3 d2 d1 d0 00 00 00 /.../ 00 00 00 00 00 00 00 00
|
||||
*
|
||||
* NoPadding
|
||||
* ---------
|
||||
*
|
||||
* 00 00 00 00 00 00 00 00 00 /.../ 00 00 d0 d1 d2 d3 d4 d5
|
||||
*
|
||||
* PKCS1Padding
|
||||
* ------------
|
||||
*
|
||||
* d0 d1 d2 d3 d4 d5 00 p0 p1 /.../ p2 p3 p4 p5 p6 p7 02 00
|
||||
* \------------ ------------/
|
||||
* \/
|
||||
* Minimum 8 bytes pad length
|
||||
*/
|
||||
{
|
||||
var a = new Array(); // The usual Alice and Bob stuff
|
||||
var sl = s.length; // Plaintext string length
|
||||
var i, j, k; // The usual Fortran index stuff
|
||||
var padtype; // Type of padding to do
|
||||
var encodingtype; // Type of output encoding
|
||||
var rpad; // Random pad
|
||||
var al; // Array length
|
||||
var result = ""; // Cypthertext result
|
||||
var block; // Big integer block to encrypt
|
||||
var crypt; // Big integer result
|
||||
var text; // Text result
|
||||
/*
|
||||
* Figure out the padding type.
|
||||
*/
|
||||
if (typeof(pad) == 'string') {
|
||||
if (pad == RSAAPP.NoPadding) { padtype = 1; }
|
||||
else if (pad == RSAAPP.PKCS1Padding) { padtype = 2; }
|
||||
else { padtype = 0; }
|
||||
}
|
||||
else { padtype = 0; }
|
||||
/*
|
||||
* Determine encoding type.
|
||||
*/
|
||||
if (typeof(encoding) == 'string' && encoding == RSAAPP.RawEncoding) {
|
||||
encodingtype = 1;
|
||||
}
|
||||
else { encodingtype = 0; }
|
||||
|
||||
/*
|
||||
* If we're not using Dave's padding method, we need to truncate long
|
||||
* plaintext blocks to the correct length for the padding method used:
|
||||
*
|
||||
* NoPadding - key length
|
||||
* PKCS1Padding - key length - 11
|
||||
*/
|
||||
if (padtype == 1) {
|
||||
if (sl > key.chunkSize) { sl = key.chunkSize; }
|
||||
}
|
||||
else if (padtype == 2) {
|
||||
if (sl > (key.chunkSize-11)) { sl = key.chunkSize - 11; }
|
||||
}
|
||||
/*
|
||||
* Convert the plaintext string to an array of characters so that we can work
|
||||
* with individual characters.
|
||||
*
|
||||
* Note that, if we're talking to a real crypto library at the other end, we
|
||||
* reverse the plaintext order to preserve big-endian order.
|
||||
*/
|
||||
i = 0;
|
||||
|
||||
if (padtype == 2) { j = sl - 1; }
|
||||
else { j = key.chunkSize - 1; }
|
||||
|
||||
while (i < sl) {
|
||||
if (padtype) { a[j] = s.charCodeAt(i); }
|
||||
else { a[i] = s.charCodeAt(i); }
|
||||
|
||||
i++; j--;
|
||||
}
|
||||
/*
|
||||
* Now is the time to add the padding.
|
||||
*
|
||||
* If we're doing PKCS1v1.5 padding, we pick up padding where we left off and
|
||||
* pad the remainder of the block. Otherwise, we pad at the front of the
|
||||
* block. This gives us the correct padding for big-endian blocks.
|
||||
*
|
||||
* The padding is either a zero byte or a randomly-generated non-zero byte.
|
||||
*/
|
||||
if (padtype == 1) { i = 0; }
|
||||
|
||||
j = key.chunkSize - (sl % key.chunkSize);
|
||||
|
||||
while (j > 0) {
|
||||
if (padtype == 2) {
|
||||
rpad = Math.floor(Math.random() * 256);
|
||||
|
||||
while (!rpad) { rpad = Math.floor(Math.random() * 256); }
|
||||
|
||||
a[i] = rpad;
|
||||
}
|
||||
else { a[i] = 0; }
|
||||
|
||||
i++; j--;
|
||||
}
|
||||
/*
|
||||
* For PKCS1v1.5 padding, we need to fill in the block header.
|
||||
*
|
||||
* According to RFC 2313, a block type, a padding string, and the data shall
|
||||
* be formatted into the encryption block:
|
||||
*
|
||||
* EncrBlock = 00 || BlockType || PadString || 00 || Data
|
||||
*
|
||||
* The block type shall be a single octet indicating the structure of the
|
||||
* encryption block. For this version of the document it shall have value 00,
|
||||
* 01, or 02. For a private-key operation, the block type shall be 00 or 01.
|
||||
* For a public-key operation, it shall be 02.
|
||||
*
|
||||
* The padding string shall consist of enough octets to pad the encryption
|
||||
* block to the length of the encryption key. For block type 00, the octets
|
||||
* shall have value 00; for block type 01, they shall have value FF; and for
|
||||
* block type 02, they shall be pseudorandomly generated and nonzero.
|
||||
*
|
||||
* Note that in a previous step, we wrote padding bytes into the first three
|
||||
* bytes of the encryption block because it was simpler to do so. We now
|
||||
* overwrite them.
|
||||
*/
|
||||
if (padtype == 2)
|
||||
{
|
||||
a[sl] = 0;
|
||||
a[key.chunkSize-2] = 2;
|
||||
a[key.chunkSize-1] = 0;
|
||||
}
|
||||
/*
|
||||
* Carve up the plaintext and encrypt each of the resultant blocks.
|
||||
*/
|
||||
al = a.length;
|
||||
|
||||
for (i = 0; i < al; i += key.chunkSize) {
|
||||
/*
|
||||
* Get a block.
|
||||
*/
|
||||
block = new BigInt();
|
||||
|
||||
j = 0;
|
||||
|
||||
for (k = i; k < (i+key.chunkSize); ++j) {
|
||||
block.digits[j] = a[k++];
|
||||
block.digits[j] += a[k++] << 8;
|
||||
}
|
||||
/*
|
||||
* Encrypt it, convert it to text, and append it to the result.
|
||||
*/
|
||||
crypt = key.barrett.powMod(block, key.e);
|
||||
if (encodingtype == 1) {
|
||||
text = biToBytes(crypt);
|
||||
}
|
||||
else {
|
||||
text = (key.radix == 16) ? biToHex(crypt) : biToString(crypt, key.radix);
|
||||
}
|
||||
result += text;
|
||||
}
|
||||
/*
|
||||
* Return the result, removing the last space.
|
||||
*/
|
||||
//result = (result.substring(0, result.length - 1));
|
||||
return result;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
function decryptedString(key, c)
|
||||
/*
|
||||
* key The previously-built RSA key whose
|
||||
* private key component is to be used
|
||||
* to decrypt the cyphertext string.
|
||||
*
|
||||
* c The cyphertext string that is to be
|
||||
* decrypted, using the RSA assymmetric
|
||||
* encryption method.
|
||||
*
|
||||
* returns The plaintext block that results from
|
||||
* decrypting the cyphertext string c
|
||||
* with the RSA key.
|
||||
*
|
||||
* This routine is the complementary decryption routine that is meant to be
|
||||
* used for JavaScript decryption of cyphertext blocks that were encrypted
|
||||
* using the OHDave padding method of the encryptedString routine (in this
|
||||
* module). It can also decrypt cyphertext blocks that were encrypted by
|
||||
* RSAEncode (in CryptoFuncs.pm or CryptoFuncs.php) so that encrypted
|
||||
* messages can be sent of insecure links (e.g. HTTP) to a Web page.
|
||||
*
|
||||
* It accepts a cyphertext string that is to be decrypted with the public key
|
||||
* component of the previously-built RSA key using the RSA assymmetric
|
||||
* encryption method. Multiple cyphertext blocks are broken apart, if they
|
||||
* are found in c, and each block is decrypted. All of the decrypted blocks
|
||||
* are concatenated back together to obtain the original plaintext string.
|
||||
*
|
||||
* This routine assumes that the plaintext was padded to the same length as
|
||||
* the encryption key with zeros. Therefore, it removes any zero bytes that
|
||||
* are found at the end of the last decrypted block, before it is appended to
|
||||
* the decrypted plaintext string.
|
||||
*
|
||||
* Note that the encryptedString routine (in this module) works fairly quickly
|
||||
* simply by virtue of the fact that the public key most often chosen is quite
|
||||
* short (e.g. 0x10001). This routine does not have that luxury. The
|
||||
* decryption key that it must employ is the full key length. For long keys,
|
||||
* this can result in serious timing delays (e.g. 7-8 seconds to decrypt using
|
||||
* 2048 bit keys on a reasonably fast machine, under the Firefox Web browser).
|
||||
*
|
||||
* If you intend to send encrypted messagess to a JavaScript program running
|
||||
* under a Web browser, you might consider using shorter keys to keep the
|
||||
* decryption times low. Alternately, a better scheme is to generate a random
|
||||
* key for use by a symmetric encryption algorithm and transmit it to the
|
||||
* other end, after encrypting it with encryptedString. The other end can use
|
||||
* a real crypto library (e.g. OpenSSL or Microsoft) to decrypt the key and
|
||||
* then use it to encrypt all of the messages (with a symmetric encryption
|
||||
* algorithm such as Twofish or AES) bound for the JavaScript program.
|
||||
* Symmetric decryption is orders of magnitude faster than asymmetric and
|
||||
* should yield low decryption times, even when executed in JavaScript.
|
||||
*
|
||||
* Also note that only the OHDave padding method (e.g. zeros) is supported by
|
||||
* this routine *AND* that this routine expects little-endian cyphertext, as
|
||||
* created by the encryptedString routine (in this module) or the RSAEncode
|
||||
* routine (in either CryptoFuncs.pm or CryptoFuncs.php). You can use one of
|
||||
* the real crypto libraries to create cyphertext that can be decrypted by
|
||||
* this routine, if you reverse the plaintext byte order first and then
|
||||
* manually pad it with zero bytes. The plaintext should then be encrypted
|
||||
* with the NoPadding flag or its equivalent in the crypto library of your
|
||||
* choice.
|
||||
*/
|
||||
{
|
||||
var blocks = c.split(" "); // Multiple blocks of cyphertext
|
||||
var b; // The usual Alice and Bob stuff
|
||||
var i, j; // The usual Fortran index stuff
|
||||
var bi; // Cyphertext as a big integer
|
||||
var result = ""; // Plaintext result
|
||||
/*
|
||||
* Carve up the cyphertext into blocks.
|
||||
*/
|
||||
for (i = 0; i < blocks.length; ++i) {
|
||||
/*
|
||||
* Depending on the radix being used for the key, convert this cyphertext
|
||||
* block into a big integer.
|
||||
*/
|
||||
if (key.radix == 16) { bi = biFromHex(blocks[i]); }
|
||||
else { bi = biFromString(blocks[i], key.radix); }
|
||||
/*
|
||||
* Decrypt the cyphertext.
|
||||
*/
|
||||
b = key.barrett.powMod(bi, key.d);
|
||||
/*
|
||||
* Convert the decrypted big integer back to the plaintext string. Since
|
||||
* we are using big integers, each element thereof represents two bytes of
|
||||
* plaintext.
|
||||
*/
|
||||
for (j = 0; j <= biHighIndex(b); ++j) {
|
||||
result += String.fromCharCode(b.digits[j] & 255, b.digits[j] >> 8);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Remove trailing null, if any.
|
||||
*/
|
||||
if (result.charCodeAt(result.length - 1) == 0) {
|
||||
result = result.substring(0, result.length - 1);
|
||||
}
|
||||
/*
|
||||
* Return the plaintext.
|
||||
*/
|
||||
return (result);
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
CryptoJS v3.1.2
|
||||
code.google.com/p/crypto-js
|
||||
(c) 2009-2013 by Jeff Mott. All rights reserved.
|
||||
code.google.com/p/crypto-js/wiki/License
|
||||
*/
|
||||
var CryptoJS=CryptoJS||function(u,p){var d={},l=d.lib={},s=function(){},t=l.Base={extend:function(a){s.prototype=this;var c=new s;a&&c.mixIn(a);c.hasOwnProperty("init")||(c.init=function(){c.$super.init.apply(this,arguments)});c.init.prototype=c;c.$super=this;return c},create:function(){var a=this.extend();a.init.apply(a,arguments);return a},init:function(){},mixIn:function(a){for(var c in a)a.hasOwnProperty(c)&&(this[c]=a[c]);a.hasOwnProperty("toString")&&(this.toString=a.toString)},clone:function(){return this.init.prototype.extend(this)}},
|
||||
r=l.WordArray=t.extend({init:function(a,c){a=this.words=a||[];this.sigBytes=c!=p?c:4*a.length},toString:function(a){return(a||v).stringify(this)},concat:function(a){var c=this.words,e=a.words,j=this.sigBytes;a=a.sigBytes;this.clamp();if(j%4)for(var k=0;k<a;k++)c[j+k>>>2]|=(e[k>>>2]>>>24-8*(k%4)&255)<<24-8*((j+k)%4);else if(65535<e.length)for(k=0;k<a;k+=4)c[j+k>>>2]=e[k>>>2];else c.push.apply(c,e);this.sigBytes+=a;return this},clamp:function(){var a=this.words,c=this.sigBytes;a[c>>>2]&=4294967295<<
|
||||
32-8*(c%4);a.length=u.ceil(c/4)},clone:function(){var a=t.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var c=[],e=0;e<a;e+=4)c.push(4294967296*u.random()|0);return new r.init(c,a)}}),w=d.enc={},v=w.Hex={stringify:function(a){var c=a.words;a=a.sigBytes;for(var e=[],j=0;j<a;j++){var k=c[j>>>2]>>>24-8*(j%4)&255;e.push((k>>>4).toString(16));e.push((k&15).toString(16))}return e.join("")},parse:function(a){for(var c=a.length,e=[],j=0;j<c;j+=2)e[j>>>3]|=parseInt(a.substr(j,
|
||||
2),16)<<24-4*(j%8);return new r.init(e,c/2)}},b=w.Latin1={stringify:function(a){var c=a.words;a=a.sigBytes;for(var e=[],j=0;j<a;j++)e.push(String.fromCharCode(c[j>>>2]>>>24-8*(j%4)&255));return e.join("")},parse:function(a){for(var c=a.length,e=[],j=0;j<c;j++)e[j>>>2]|=(a.charCodeAt(j)&255)<<24-8*(j%4);return new r.init(e,c)}},x=w.Utf8={stringify:function(a){try{return decodeURIComponent(escape(b.stringify(a)))}catch(c){throw Error("Malformed UTF-8 data");}},parse:function(a){return b.parse(unescape(encodeURIComponent(a)))}},
|
||||
q=l.BufferedBlockAlgorithm=t.extend({reset:function(){this._data=new r.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=x.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var c=this._data,e=c.words,j=c.sigBytes,k=this.blockSize,b=j/(4*k),b=a?u.ceil(b):u.max((b|0)-this._minBufferSize,0);a=b*k;j=u.min(4*a,j);if(a){for(var q=0;q<a;q+=k)this._doProcessBlock(e,q);q=e.splice(0,a);c.sigBytes-=j}return new r.init(q,j)},clone:function(){var a=t.clone.call(this);
|
||||
a._data=this._data.clone();return a},_minBufferSize:0});l.Hasher=q.extend({cfg:t.extend(),init:function(a){this.cfg=this.cfg.extend(a);this.reset()},reset:function(){q.reset.call(this);this._doReset()},update:function(a){this._append(a);this._process();return this},finalize:function(a){a&&this._append(a);return this._doFinalize()},blockSize:16,_createHelper:function(a){return function(b,e){return(new a.init(e)).finalize(b)}},_createHmacHelper:function(a){return function(b,e){return(new n.HMAC.init(a,
|
||||
e)).finalize(b)}}});var n=d.algo={};return d}(Math);
|
||||
(function(){var u=CryptoJS,p=u.lib.WordArray;u.enc.Base64={stringify:function(d){var l=d.words,p=d.sigBytes,t=this._map;d.clamp();d=[];for(var r=0;r<p;r+=3)for(var w=(l[r>>>2]>>>24-8*(r%4)&255)<<16|(l[r+1>>>2]>>>24-8*((r+1)%4)&255)<<8|l[r+2>>>2]>>>24-8*((r+2)%4)&255,v=0;4>v&&r+0.75*v<p;v++)d.push(t.charAt(w>>>6*(3-v)&63));if(l=t.charAt(64))for(;d.length%4;)d.push(l);return d.join("")},parse:function(d){var l=d.length,s=this._map,t=s.charAt(64);t&&(t=d.indexOf(t),-1!=t&&(l=t));for(var t=[],r=0,w=0;w<
|
||||
l;w++)if(w%4){var v=s.indexOf(d.charAt(w-1))<<2*(w%4),b=s.indexOf(d.charAt(w))>>>6-2*(w%4);t[r>>>2]|=(v|b)<<24-8*(r%4);r++}return p.create(t,r)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="}})();
|
||||
(function(u){function p(b,n,a,c,e,j,k){b=b+(n&a|~n&c)+e+k;return(b<<j|b>>>32-j)+n}function d(b,n,a,c,e,j,k){b=b+(n&c|a&~c)+e+k;return(b<<j|b>>>32-j)+n}function l(b,n,a,c,e,j,k){b=b+(n^a^c)+e+k;return(b<<j|b>>>32-j)+n}function s(b,n,a,c,e,j,k){b=b+(a^(n|~c))+e+k;return(b<<j|b>>>32-j)+n}for(var t=CryptoJS,r=t.lib,w=r.WordArray,v=r.Hasher,r=t.algo,b=[],x=0;64>x;x++)b[x]=4294967296*u.abs(u.sin(x+1))|0;r=r.MD5=v.extend({_doReset:function(){this._hash=new w.init([1732584193,4023233417,2562383102,271733878])},
|
||||
_doProcessBlock:function(q,n){for(var a=0;16>a;a++){var c=n+a,e=q[c];q[c]=(e<<8|e>>>24)&16711935|(e<<24|e>>>8)&4278255360}var a=this._hash.words,c=q[n+0],e=q[n+1],j=q[n+2],k=q[n+3],z=q[n+4],r=q[n+5],t=q[n+6],w=q[n+7],v=q[n+8],A=q[n+9],B=q[n+10],C=q[n+11],u=q[n+12],D=q[n+13],E=q[n+14],x=q[n+15],f=a[0],m=a[1],g=a[2],h=a[3],f=p(f,m,g,h,c,7,b[0]),h=p(h,f,m,g,e,12,b[1]),g=p(g,h,f,m,j,17,b[2]),m=p(m,g,h,f,k,22,b[3]),f=p(f,m,g,h,z,7,b[4]),h=p(h,f,m,g,r,12,b[5]),g=p(g,h,f,m,t,17,b[6]),m=p(m,g,h,f,w,22,b[7]),
|
||||
f=p(f,m,g,h,v,7,b[8]),h=p(h,f,m,g,A,12,b[9]),g=p(g,h,f,m,B,17,b[10]),m=p(m,g,h,f,C,22,b[11]),f=p(f,m,g,h,u,7,b[12]),h=p(h,f,m,g,D,12,b[13]),g=p(g,h,f,m,E,17,b[14]),m=p(m,g,h,f,x,22,b[15]),f=d(f,m,g,h,e,5,b[16]),h=d(h,f,m,g,t,9,b[17]),g=d(g,h,f,m,C,14,b[18]),m=d(m,g,h,f,c,20,b[19]),f=d(f,m,g,h,r,5,b[20]),h=d(h,f,m,g,B,9,b[21]),g=d(g,h,f,m,x,14,b[22]),m=d(m,g,h,f,z,20,b[23]),f=d(f,m,g,h,A,5,b[24]),h=d(h,f,m,g,E,9,b[25]),g=d(g,h,f,m,k,14,b[26]),m=d(m,g,h,f,v,20,b[27]),f=d(f,m,g,h,D,5,b[28]),h=d(h,f,
|
||||
m,g,j,9,b[29]),g=d(g,h,f,m,w,14,b[30]),m=d(m,g,h,f,u,20,b[31]),f=l(f,m,g,h,r,4,b[32]),h=l(h,f,m,g,v,11,b[33]),g=l(g,h,f,m,C,16,b[34]),m=l(m,g,h,f,E,23,b[35]),f=l(f,m,g,h,e,4,b[36]),h=l(h,f,m,g,z,11,b[37]),g=l(g,h,f,m,w,16,b[38]),m=l(m,g,h,f,B,23,b[39]),f=l(f,m,g,h,D,4,b[40]),h=l(h,f,m,g,c,11,b[41]),g=l(g,h,f,m,k,16,b[42]),m=l(m,g,h,f,t,23,b[43]),f=l(f,m,g,h,A,4,b[44]),h=l(h,f,m,g,u,11,b[45]),g=l(g,h,f,m,x,16,b[46]),m=l(m,g,h,f,j,23,b[47]),f=s(f,m,g,h,c,6,b[48]),h=s(h,f,m,g,w,10,b[49]),g=s(g,h,f,m,
|
||||
E,15,b[50]),m=s(m,g,h,f,r,21,b[51]),f=s(f,m,g,h,u,6,b[52]),h=s(h,f,m,g,k,10,b[53]),g=s(g,h,f,m,B,15,b[54]),m=s(m,g,h,f,e,21,b[55]),f=s(f,m,g,h,v,6,b[56]),h=s(h,f,m,g,x,10,b[57]),g=s(g,h,f,m,t,15,b[58]),m=s(m,g,h,f,D,21,b[59]),f=s(f,m,g,h,z,6,b[60]),h=s(h,f,m,g,C,10,b[61]),g=s(g,h,f,m,j,15,b[62]),m=s(m,g,h,f,A,21,b[63]);a[0]=a[0]+f|0;a[1]=a[1]+m|0;a[2]=a[2]+g|0;a[3]=a[3]+h|0},_doFinalize:function(){var b=this._data,n=b.words,a=8*this._nDataBytes,c=8*b.sigBytes;n[c>>>5]|=128<<24-c%32;var e=u.floor(a/
|
||||
4294967296);n[(c+64>>>9<<4)+15]=(e<<8|e>>>24)&16711935|(e<<24|e>>>8)&4278255360;n[(c+64>>>9<<4)+14]=(a<<8|a>>>24)&16711935|(a<<24|a>>>8)&4278255360;b.sigBytes=4*(n.length+1);this._process();b=this._hash;n=b.words;for(a=0;4>a;a++)c=n[a],n[a]=(c<<8|c>>>24)&16711935|(c<<24|c>>>8)&4278255360;return b},clone:function(){var b=v.clone.call(this);b._hash=this._hash.clone();return b}});t.MD5=v._createHelper(r);t.HmacMD5=v._createHmacHelper(r)})(Math);
|
||||
(function(){var u=CryptoJS,p=u.lib,d=p.Base,l=p.WordArray,p=u.algo,s=p.EvpKDF=d.extend({cfg:d.extend({keySize:4,hasher:p.MD5,iterations:1}),init:function(d){this.cfg=this.cfg.extend(d)},compute:function(d,r){for(var p=this.cfg,s=p.hasher.create(),b=l.create(),u=b.words,q=p.keySize,p=p.iterations;u.length<q;){n&&s.update(n);var n=s.update(d).finalize(r);s.reset();for(var a=1;a<p;a++)n=s.finalize(n),s.reset();b.concat(n)}b.sigBytes=4*q;return b}});u.EvpKDF=function(d,l,p){return s.create(p).compute(d,
|
||||
l)}})();
|
||||
CryptoJS.lib.Cipher||function(u){var p=CryptoJS,d=p.lib,l=d.Base,s=d.WordArray,t=d.BufferedBlockAlgorithm,r=p.enc.Base64,w=p.algo.EvpKDF,v=d.Cipher=t.extend({cfg:l.extend(),createEncryptor:function(e,a){return this.create(this._ENC_XFORM_MODE,e,a)},createDecryptor:function(e,a){return this.create(this._DEC_XFORM_MODE,e,a)},init:function(e,a,b){this.cfg=this.cfg.extend(b);this._xformMode=e;this._key=a;this.reset()},reset:function(){t.reset.call(this);this._doReset()},process:function(e){this._append(e);return this._process()},
|
||||
finalize:function(e){e&&this._append(e);return this._doFinalize()},keySize:4,ivSize:4,_ENC_XFORM_MODE:1,_DEC_XFORM_MODE:2,_createHelper:function(e){return{encrypt:function(b,k,d){return("string"==typeof k?c:a).encrypt(e,b,k,d)},decrypt:function(b,k,d){return("string"==typeof k?c:a).decrypt(e,b,k,d)}}}});d.StreamCipher=v.extend({_doFinalize:function(){return this._process(!0)},blockSize:1});var b=p.mode={},x=function(e,a,b){var c=this._iv;c?this._iv=u:c=this._prevBlock;for(var d=0;d<b;d++)e[a+d]^=
|
||||
c[d]},q=(d.BlockCipherMode=l.extend({createEncryptor:function(e,a){return this.Encryptor.create(e,a)},createDecryptor:function(e,a){return this.Decryptor.create(e,a)},init:function(e,a){this._cipher=e;this._iv=a}})).extend();q.Encryptor=q.extend({processBlock:function(e,a){var b=this._cipher,c=b.blockSize;x.call(this,e,a,c);b.encryptBlock(e,a);this._prevBlock=e.slice(a,a+c)}});q.Decryptor=q.extend({processBlock:function(e,a){var b=this._cipher,c=b.blockSize,d=e.slice(a,a+c);b.decryptBlock(e,a);x.call(this,
|
||||
e,a,c);this._prevBlock=d}});b=b.CBC=q;q=(p.pad={}).Pkcs7={pad:function(a,b){for(var c=4*b,c=c-a.sigBytes%c,d=c<<24|c<<16|c<<8|c,l=[],n=0;n<c;n+=4)l.push(d);c=s.create(l,c);a.concat(c)},unpad:function(a){a.sigBytes-=a.words[a.sigBytes-1>>>2]&255}};d.BlockCipher=v.extend({cfg:v.cfg.extend({mode:b,padding:q}),reset:function(){v.reset.call(this);var a=this.cfg,b=a.iv,a=a.mode;if(this._xformMode==this._ENC_XFORM_MODE)var c=a.createEncryptor;else c=a.createDecryptor,this._minBufferSize=1;this._mode=c.call(a,
|
||||
this,b&&b.words)},_doProcessBlock:function(a,b){this._mode.processBlock(a,b)},_doFinalize:function(){var a=this.cfg.padding;if(this._xformMode==this._ENC_XFORM_MODE){a.pad(this._data,this.blockSize);var b=this._process(!0)}else b=this._process(!0),a.unpad(b);return b},blockSize:4});var n=d.CipherParams=l.extend({init:function(a){this.mixIn(a)},toString:function(a){return(a||this.formatter).stringify(this)}}),b=(p.format={}).OpenSSL={stringify:function(a){var b=a.ciphertext;a=a.salt;return(a?s.create([1398893684,
|
||||
1701076831]).concat(a).concat(b):b).toString(r)},parse:function(a){a=r.parse(a);var b=a.words;if(1398893684==b[0]&&1701076831==b[1]){var c=s.create(b.slice(2,4));b.splice(0,4);a.sigBytes-=16}return n.create({ciphertext:a,salt:c})}},a=d.SerializableCipher=l.extend({cfg:l.extend({format:b}),encrypt:function(a,b,c,d){d=this.cfg.extend(d);var l=a.createEncryptor(c,d);b=l.finalize(b);l=l.cfg;return n.create({ciphertext:b,key:c,iv:l.iv,algorithm:a,mode:l.mode,padding:l.padding,blockSize:a.blockSize,formatter:d.format})},
|
||||
decrypt:function(a,b,c,d){d=this.cfg.extend(d);b=this._parse(b,d.format);return a.createDecryptor(c,d).finalize(b.ciphertext)},_parse:function(a,b){return"string"==typeof a?b.parse(a,this):a}}),p=(p.kdf={}).OpenSSL={execute:function(a,b,c,d){d||(d=s.random(8));a=w.create({keySize:b+c}).compute(a,d);c=s.create(a.words.slice(b),4*c);a.sigBytes=4*b;return n.create({key:a,iv:c,salt:d})}},c=d.PasswordBasedCipher=a.extend({cfg:a.cfg.extend({kdf:p}),encrypt:function(b,c,d,l){l=this.cfg.extend(l);d=l.kdf.execute(d,
|
||||
b.keySize,b.ivSize);l.iv=d.iv;b=a.encrypt.call(this,b,c,d.key,l);b.mixIn(d);return b},decrypt:function(b,c,d,l){l=this.cfg.extend(l);c=this._parse(c,l.format);d=l.kdf.execute(d,b.keySize,b.ivSize,c.salt);l.iv=d.iv;return a.decrypt.call(this,b,c,d.key,l)}})}();
|
||||
(function(){for(var u=CryptoJS,p=u.lib.BlockCipher,d=u.algo,l=[],s=[],t=[],r=[],w=[],v=[],b=[],x=[],q=[],n=[],a=[],c=0;256>c;c++)a[c]=128>c?c<<1:c<<1^283;for(var e=0,j=0,c=0;256>c;c++){var k=j^j<<1^j<<2^j<<3^j<<4,k=k>>>8^k&255^99;l[e]=k;s[k]=e;var z=a[e],F=a[z],G=a[F],y=257*a[k]^16843008*k;t[e]=y<<24|y>>>8;r[e]=y<<16|y>>>16;w[e]=y<<8|y>>>24;v[e]=y;y=16843009*G^65537*F^257*z^16843008*e;b[k]=y<<24|y>>>8;x[k]=y<<16|y>>>16;q[k]=y<<8|y>>>24;n[k]=y;e?(e=z^a[a[a[G^z]]],j^=a[a[j]]):e=j=1}var H=[0,1,2,4,8,
|
||||
16,32,64,128,27,54],d=d.AES=p.extend({_doReset:function(){for(var a=this._key,c=a.words,d=a.sigBytes/4,a=4*((this._nRounds=d+6)+1),e=this._keySchedule=[],j=0;j<a;j++)if(j<d)e[j]=c[j];else{var k=e[j-1];j%d?6<d&&4==j%d&&(k=l[k>>>24]<<24|l[k>>>16&255]<<16|l[k>>>8&255]<<8|l[k&255]):(k=k<<8|k>>>24,k=l[k>>>24]<<24|l[k>>>16&255]<<16|l[k>>>8&255]<<8|l[k&255],k^=H[j/d|0]<<24);e[j]=e[j-d]^k}c=this._invKeySchedule=[];for(d=0;d<a;d++)j=a-d,k=d%4?e[j]:e[j-4],c[d]=4>d||4>=j?k:b[l[k>>>24]]^x[l[k>>>16&255]]^q[l[k>>>
|
||||
8&255]]^n[l[k&255]]},encryptBlock:function(a,b){this._doCryptBlock(a,b,this._keySchedule,t,r,w,v,l)},decryptBlock:function(a,c){var d=a[c+1];a[c+1]=a[c+3];a[c+3]=d;this._doCryptBlock(a,c,this._invKeySchedule,b,x,q,n,s);d=a[c+1];a[c+1]=a[c+3];a[c+3]=d},_doCryptBlock:function(a,b,c,d,e,j,l,f){for(var m=this._nRounds,g=a[b]^c[0],h=a[b+1]^c[1],k=a[b+2]^c[2],n=a[b+3]^c[3],p=4,r=1;r<m;r++)var q=d[g>>>24]^e[h>>>16&255]^j[k>>>8&255]^l[n&255]^c[p++],s=d[h>>>24]^e[k>>>16&255]^j[n>>>8&255]^l[g&255]^c[p++],t=
|
||||
d[k>>>24]^e[n>>>16&255]^j[g>>>8&255]^l[h&255]^c[p++],n=d[n>>>24]^e[g>>>16&255]^j[h>>>8&255]^l[k&255]^c[p++],g=q,h=s,k=t;q=(f[g>>>24]<<24|f[h>>>16&255]<<16|f[k>>>8&255]<<8|f[n&255])^c[p++];s=(f[h>>>24]<<24|f[k>>>16&255]<<16|f[n>>>8&255]<<8|f[g&255])^c[p++];t=(f[k>>>24]<<24|f[n>>>16&255]<<16|f[g>>>8&255]<<8|f[h&255])^c[p++];n=(f[n>>>24]<<24|f[g>>>16&255]<<16|f[h>>>8&255]<<8|f[k&255])^c[p++];a[b]=q;a[b+1]=s;a[b+2]=t;a[b+3]=n},keySize:8});u.AES=p._createHelper(d)})();
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,117 @@
|
||||
/*!
|
||||
* jQuery Cookie Plugin v1.4.1
|
||||
* https://github.com/carhartl/jquery-cookie
|
||||
*
|
||||
* Copyright 2013 Klaus Hartl
|
||||
* Released under the MIT license
|
||||
*/
|
||||
(function (factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// AMD
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// CommonJS
|
||||
factory(require('jquery'));
|
||||
} else {
|
||||
// Browser globals
|
||||
factory(jQuery);
|
||||
}
|
||||
}(function ($) {
|
||||
|
||||
var pluses = /\+/g;
|
||||
|
||||
function encode(s) {
|
||||
return config.raw ? s : encodeURIComponent(s);
|
||||
}
|
||||
|
||||
function decode(s) {
|
||||
return config.raw ? s : decodeURIComponent(s);
|
||||
}
|
||||
|
||||
function stringifyCookieValue(value) {
|
||||
return encode(config.json ? JSON.stringify(value) : String(value));
|
||||
}
|
||||
|
||||
function parseCookieValue(s) {
|
||||
if (s.indexOf('"') === 0) {
|
||||
// This is a quoted cookie as according to RFC2068, unescape...
|
||||
s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
|
||||
}
|
||||
|
||||
try {
|
||||
// Replace server-side written pluses with spaces.
|
||||
// If we can't decode the cookie, ignore it, it's unusable.
|
||||
// If we can't parse the cookie, ignore it, it's unusable.
|
||||
s = decodeURIComponent(s.replace(pluses, ' '));
|
||||
return config.json ? JSON.parse(s) : s;
|
||||
} catch(e) {}
|
||||
}
|
||||
|
||||
function read(s, converter) {
|
||||
var value = config.raw ? s : parseCookieValue(s);
|
||||
return $.isFunction(converter) ? converter(value) : value;
|
||||
}
|
||||
|
||||
var config = $.cookie = function (key, value, options) {
|
||||
|
||||
// Write
|
||||
|
||||
if (value !== undefined && !$.isFunction(value)) {
|
||||
options = $.extend({}, config.defaults, options);
|
||||
|
||||
if (typeof options.expires === 'number') {
|
||||
var days = options.expires, t = options.expires = new Date();
|
||||
t.setTime(+t + days * 864e+5);
|
||||
}
|
||||
|
||||
return (document.cookie = [
|
||||
encode(key), '=', stringifyCookieValue(value),
|
||||
options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
|
||||
options.path ? '; path=' + options.path : '',
|
||||
options.domain ? '; domain=' + options.domain : '',
|
||||
options.secure ? '; secure' : ''
|
||||
].join(''));
|
||||
}
|
||||
|
||||
// Read
|
||||
|
||||
var result = key ? undefined : {};
|
||||
|
||||
// To prevent the for loop in the first place assign an empty array
|
||||
// in case there are no cookies at all. Also prevents odd result when
|
||||
// calling $.cookie().
|
||||
var cookies = document.cookie ? document.cookie.split('; ') : [];
|
||||
|
||||
for (var i = 0, l = cookies.length; i < l; i++) {
|
||||
var parts = cookies[i].split('=');
|
||||
var name = decode(parts.shift());
|
||||
var cookie = parts.join('=');
|
||||
|
||||
if (key && key === name) {
|
||||
// If second argument (value) is a function it's a converter...
|
||||
result = read(cookie, value);
|
||||
break;
|
||||
}
|
||||
|
||||
// Prevent storing a cookie that we couldn't decode.
|
||||
if (!key && (cookie = read(cookie)) !== undefined) {
|
||||
result[name] = cookie;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
config.defaults = {};
|
||||
|
||||
$.removeCookie = function (key, options) {
|
||||
if ($.cookie(key) === undefined) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Must not alter options, thus extending a fresh object...
|
||||
$.cookie(key, '', $.extend({}, options, { expires: -1 }));
|
||||
return !$.cookie(key);
|
||||
};
|
||||
|
||||
}));
|
@ -0,0 +1,253 @@
|
||||
var JMusicjsoup = {
|
||||
getRecommends:function(callback){
|
||||
$.ajax({
|
||||
url:'/musicapi/apiqq/musichall/fcgi-bin/fcg_yqqhomepagerecommend.fcg',
|
||||
data:{'g_tk':5381,'uin':0,'format':'json','inCharset':'utf-8','outCharset':'utf-8','notice':0,'platform':'h5','needNewCode':1,'_':1535537714744},
|
||||
dataType:'json',
|
||||
type:'get',
|
||||
async:true,
|
||||
success:function(data){
|
||||
callback._setRecommend(data);
|
||||
}
|
||||
});
|
||||
},
|
||||
getNewsongs:function(num,callback){
|
||||
//"{"limit":10}"
|
||||
setV.d = '{"limit":'+num+'}';
|
||||
var res = __getKeyton();
|
||||
$.ajax({
|
||||
url:'/mapi163/weapi/personalized/newsong',
|
||||
// data:{'params':'ujh2NED7JxtOit8f2Vo/sp+bqzzC9urfBWjZD60xDdA=','encSecKey':'302d922dd30c10cc489121d1e5e956db50d5d3f8cf1f46dae2c501d88d378cb4b4b11d732efafb3c02c8e5b4e6f2633a5422bf8a0f902a10eb1627ee3665d1dbf370de4356b9a9348f0a3ff8ffb188e996d8e2f8878a95effac07ab1295ebb81ff06127e3e58d339a07d6c824128b58d2f60b60c284b7a55b70ea5e4e126136a'},
|
||||
data:{'params':res[0],'encSecKey':res[1]},
|
||||
dataType:'json',
|
||||
type:'post',
|
||||
async:true,
|
||||
success:function(data){
|
||||
callback._setNewsongs(data);
|
||||
}
|
||||
});
|
||||
},
|
||||
getLyric:function(id,callback){
|
||||
setV.d = '{"id":"'+id+'","lv":0,"tv":0}';
|
||||
var res = __getKeyton();
|
||||
$.ajax({
|
||||
url:'/mapi163/weapi/song/lyric',
|
||||
data:{'params':res[0],'encSecKey':res[1]},
|
||||
dataType:'json',
|
||||
type:'post',
|
||||
async:true,
|
||||
success:function(data){
|
||||
callback._setLyric(id,data);
|
||||
}
|
||||
});
|
||||
},
|
||||
getListsongs:function(callback){
|
||||
$.ajax({
|
||||
url:'/mapi163/weapi/v3/playlist/detail',
|
||||
data:{'params':'KvByhpvz7lzKJlmmur31pyP9wun0SzssbTnXHQveNOPYvGMFH7w8U+0pcbpv3NX0','encSecKey':'be25f5794f940eebbde77dba783699e38bc12db41eadee670e69ebd16a3b29277817dd1795814de4c8264a28e5383da8620736d21275cc3b1f32797c4c63ca76db5dcae60fb21cc2b5d02741ed49fef00dcdaf3e16027de3c5ede1c7d8b8c182f1b0c5fedac846a5f511dbcda94936425b7a5df71dfd54cad47120e26d974b64'},
|
||||
dataType:'json',
|
||||
type:'post',
|
||||
async:true,
|
||||
success:function(data){
|
||||
callback._setListsongs(data);
|
||||
}
|
||||
});
|
||||
},
|
||||
getKeywordsHot(){
|
||||
//https://music.163.com/weapi/search/hot
|
||||
//d = "{"type":1111}"
|
||||
},
|
||||
getKeywordsTips(key,callback){ //关键词
|
||||
setV.d = '{"s":"'+key+'"}';
|
||||
var res = __getKeyton();
|
||||
$.ajax({
|
||||
url:'/mapi163/weapi/search/suggest/keyword',
|
||||
data:{'params':res[0],'encSecKey':res[1]},
|
||||
dataType:'json',
|
||||
type:'post',
|
||||
async:true,
|
||||
success:function(data){
|
||||
if(callback!=null){
|
||||
callback._setKeywordsTips(data);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
getSearchRes(key,limit,offset,callback){
|
||||
//"{"s":"神","limit":20,"offset":20,"type":1,"strategy":5,"queryCorrect":true}" 继续获取
|
||||
setV.d = '{"s":"'+key+'","type":1,"limit":'+limit+',"offset":'+offset+',"strategy":5,"queryCorrect":true}';
|
||||
var res = __getKeyton();
|
||||
$.ajax({
|
||||
url:'/mapi163/weapi/search/get/',
|
||||
data:{'params':res[0],'encSecKey':res[1]},
|
||||
dataType:'json',
|
||||
type:'post',
|
||||
async:true,
|
||||
success:function(data){
|
||||
if(callback!=null){
|
||||
callback._setSearchRessong(data);
|
||||
}
|
||||
//data.result;//"songs"下直接取个数 songs[0].name song[0].ar[0].name
|
||||
}
|
||||
});
|
||||
},
|
||||
getSongInfo(id,callback){
|
||||
setV.d ='{"id":"'+id+'","c":"[{\\"id\\":\\"'+id+'\\"}]"}';
|
||||
var res = __getKeyton();
|
||||
$.ajax({
|
||||
url:'/mapi163/weapi/v3/song/detail',
|
||||
data:{'params':res[0],'encSecKey':res[1]},
|
||||
dataType:'json',
|
||||
type:'post',
|
||||
async:true,
|
||||
success:function(data){
|
||||
if(callback!=null){
|
||||
if(data.code==200){
|
||||
callback._setSongInfo(id,data); //songs:data.playlist.[tracks,name]
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
error:function(err){
|
||||
console.log(err);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
getPlayLists(key,limit,offset,callback){
|
||||
//获得歌单内容
|
||||
//https://music.163.com/weapi/v3/playlist/detail
|
||||
//d:"{"id":"2358852380","n":1000}" 歌单ID
|
||||
//"{"s":"神","limit":20,"offset":20,"type":1,"strategy":5,"queryCorrect":true}" 继续获取
|
||||
setV.d = '{"limit":'+limit+',"offset":'+offset+',"s":"'+key+'","total":"true","type":"1000","csrf_token":""}';
|
||||
var res = __getKeyton();
|
||||
$.ajax({
|
||||
url:'/mapi163/weapi/cloudsearch/get/web',
|
||||
data:{'params':res[0],'encSecKey':res[1]},
|
||||
dataType:'json',
|
||||
type:'post',
|
||||
async:true,
|
||||
success:function(data){
|
||||
console.error(data);
|
||||
if(callback!=null){
|
||||
callback._setSearchResplay(data); //songs:data.playlist.[tracks,name]
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
getPlayList(id,callback){
|
||||
//获得歌单内容
|
||||
//https://music.163.com/weapi/v3/playlist/detail
|
||||
//d:"{"id":"2358852380","n":1000}" 歌单ID
|
||||
setV.d = `{"id":"${id}","total":"True","limit":1000,"n":1000,"csrf_token":"09556b378da338d2c373d38422f901a6"}`;
|
||||
var res = __getKeyton();
|
||||
$.ajax({
|
||||
url:'/mapi163/weapi/v3/playlist/detail',
|
||||
// url:'/mapi163/weapi/middle/clientcfg/config/list?csrf_token=',
|
||||
data:{'params':res[0],'encSecKey':res[1]},
|
||||
dataType:'json',
|
||||
type:'post',
|
||||
async:true,
|
||||
success:function(data){
|
||||
if(callback!=null){
|
||||
callback._setPlayList(data); //songs:data.playlist.[tracks,name]
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
getuserPlayList(id,callback){
|
||||
//获得用户的所有歌单
|
||||
//https://music.163.com/weapi/v3/playlist/detail
|
||||
//d:"{"id":"2358852380","n":1000}" 歌单ID
|
||||
//"{"s":"神","limit":20,"offset":20,"type":1,"strategy":5,"queryCorrect":true}" 继续获取
|
||||
setV.d = '{\"uid\":\"'+id+'\",\"offset\":"0","limit":"1001"}';
|
||||
var res = __getKeyton();
|
||||
$.ajax({
|
||||
url:'/mapi163/weapi/user/playlist',
|
||||
data:{'params':res[0],'encSecKey':res[1]},
|
||||
dataType:'json',
|
||||
type:'post',
|
||||
async:true,
|
||||
success:function(data){
|
||||
if(callback!=null){
|
||||
callback._setuserPlayList(data); //songs:data.playlist.[tracks,name]
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
getCommentsByPlayList(id,callback){
|
||||
//获得评论内容
|
||||
//https://music.163.com/weapi/v1/resource/comments/get
|
||||
//d:"{"resourceType":0,"resourceId":"2358852380","limit":15}" 歌单ID
|
||||
setV.d = '{"resourceType":0,"resourceId":"'+id+'","limit":15}';
|
||||
var res = __getKeyton();
|
||||
$.ajax({
|
||||
url:'/mapi163/weapi/v1/resource/comments/get',
|
||||
data:{'params':res[0],'encSecKey':res[1]},
|
||||
dataType:'json',
|
||||
type:'post',
|
||||
async:true,
|
||||
success:function(data){
|
||||
if(callback!=null){
|
||||
callback._setPlayList(data); //songs:data.playlist.[tracks,name]
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
getMp3Url(id,callback){
|
||||
setV.d = `{"ids":"[\\"${id}\\"]","level":"lossless","encodeType":"aac","csrf_token":"","br":"128000"}`;
|
||||
//setV.d = "{\"ids\":\"[\\\""+id+"\\\"]\",\"br\":\"128000\"}";
|
||||
var res = __getKeyton();
|
||||
$.ajax({
|
||||
url:'/mapi163/weapi/song/enhance/player/url',
|
||||
type:'post',
|
||||
dataType:'json',
|
||||
async:true,
|
||||
data:{'params':res[0],'encSecKey':res[1]},
|
||||
success:function(data){
|
||||
if(callback!=null){
|
||||
callback._setMp3Url(id,data);
|
||||
}
|
||||
},
|
||||
error:function(err){
|
||||
|
||||
}
|
||||
});
|
||||
},
|
||||
getOnline(callback){
|
||||
$.ajax({
|
||||
url:'/userarea',
|
||||
type:'post',
|
||||
dataType:'json',
|
||||
async:true,
|
||||
data:{"type":"ONLINE"},
|
||||
success:function(data){
|
||||
if(data.status == 0){
|
||||
if(callback!=null){
|
||||
Jsonp.getUser(data.message,callback);
|
||||
}
|
||||
}
|
||||
},
|
||||
error:function(err){
|
||||
|
||||
}
|
||||
});
|
||||
},
|
||||
getUser(id,callback){
|
||||
$.ajax({
|
||||
url:'/userarea',
|
||||
type:'post',
|
||||
dataType:'json',
|
||||
async:true,
|
||||
data:{"type":"USER","id":id},
|
||||
success:function(data){
|
||||
if(callback!=null){
|
||||
callback._setUser(data);
|
||||
}
|
||||
},
|
||||
error:function(err){
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 3.9 MiB After Width: | Height: | Size: 82 KiB |
Before Width: | Height: | Size: 893 KiB After Width: | Height: | Size: 592 KiB |
Binary file not shown.
@ -0,0 +1,349 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-tag effect="dark" class="my-tag">
|
||||
<svg viewBox="0 0 1024 1024" width="20" height="20" style="vertical-align: -3px;">
|
||||
<path d="M0 0h1024v1024H0V0z" fill="#202425" opacity=".01"></path>
|
||||
<path
|
||||
d="M682.666667 204.8h238.933333a34.133333 34.133333 0 0 1 34.133333 34.133333v648.533334a68.266667 68.266667 0 0 1-68.266666 68.266666h-204.8V204.8z"
|
||||
fill="#FFAA44"></path>
|
||||
<path
|
||||
d="M68.266667 921.6a34.133333 34.133333 0 0 0 34.133333 34.133333h785.066667a68.266667 68.266667 0 0 1-68.266667-68.266666V102.4a34.133333 34.133333 0 0 0-34.133333-34.133333H102.4a34.133333 34.133333 0 0 0-34.133333 34.133333v819.2z"
|
||||
fill="#11AA66"></path>
|
||||
<path
|
||||
d="M238.933333 307.2a34.133333 34.133333 0 0 0 0 68.266667h136.533334a34.133333 34.133333 0 1 0 0-68.266667H238.933333z m0 204.8a34.133333 34.133333 0 1 0 0 68.266667h409.6a34.133333 34.133333 0 1 0 0-68.266667H238.933333z m0 204.8a34.133333 34.133333 0 1 0 0 68.266667h204.8a34.133333 34.133333 0 1 0 0-68.266667H238.933333z"
|
||||
fill="#FFFFFF"></path>
|
||||
</svg>
|
||||
文章信息
|
||||
</el-tag>
|
||||
<el-form :model="article" :rules="rules" ref="ruleForm" label-width="150px"
|
||||
class="demo-ruleForm">
|
||||
<el-form-item label="标题" prop="articleTitle">
|
||||
<el-input v-model="article.articleTitle"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="心情" prop="articleEmotion">
|
||||
<el-input v-model="article.articleEmotion"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="地点" prop="articleAddress">
|
||||
<el-input v-model="article.articleAddress"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="内容" prop="articleContent">
|
||||
<mavon-editor ref="md" @imgAdd="imgAdd" v-model="article.articleContent"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="是否启用评论" prop="commentStatus">
|
||||
<el-tag :type="article.commentStatus === false ? 'danger' : 'success'"
|
||||
disable-transitions>
|
||||
{{article.commentStatus === false ? '否' : '是'}}
|
||||
</el-tag>
|
||||
<el-switch v-model="article.commentStatus"></el-switch>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="是否推荐" prop="recommendStatus">
|
||||
<el-tag :type="article.recommendStatus === false ? 'danger' : 'success'"
|
||||
disable-transitions>
|
||||
{{article.recommendStatus === false ? '否' : '是'}}
|
||||
</el-tag>
|
||||
<el-switch v-model="article.recommendStatus"></el-switch>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="是否可见" prop="viewStatus">
|
||||
<el-tag :type="article.viewStatus === false ? 'danger' : 'success'"
|
||||
disable-transitions>
|
||||
{{article.viewStatus === false ? '否' : '是'}}
|
||||
</el-tag>
|
||||
<el-switch v-model="article.viewStatus"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="配图" >
|
||||
<el-button @click="visable.editPicture=true">修改配图</el-button>
|
||||
<div style="display: flex">
|
||||
<el-input v-model="article.articleCover"></el-input>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-dialog title="配图" :visible.sync="visable.editPicture" fullscreen>
|
||||
<ObjectList @addPicture="addArticleCover" :point="'pt'" :isEdit="visable.editPicture" :prefix="`log-upload/${new Date().getFullYear()}/${new Date().getMonth()+1}`" :isAdmin="true" :maxSize="5" :maxNumber="16" :object="article.articleCover"></ObjectList>
|
||||
</el-dialog>
|
||||
<el-form-item v-if="article.viewStatus === false" label="不可见时的访问密码" prop="password">
|
||||
<el-input v-model="article.password"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="分类" prop="sortId">
|
||||
<el-select v-model="article.sortId" placeholder="请选择分类">
|
||||
<el-option
|
||||
v-for="item in sorts"
|
||||
:key="item.id"
|
||||
:label="item.sortName"
|
||||
:value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="标签" prop="labelId">
|
||||
<el-select v-model="article.labelId" placeholder="请选择标签">
|
||||
<el-option
|
||||
v-for="item in labelsTemp"
|
||||
:key="item.id"
|
||||
:label="item.labelName"
|
||||
:value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="myCenter" style="margin-bottom: 22px">
|
||||
<el-button type="primary" @click="submitForm('ruleForm')">保存</el-button>
|
||||
<el-button type="danger" @click="resetForm('ruleForm')">重置所有修改</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const uploadPicture = () => import( "../common/uploadPicture");
|
||||
const ObjectList = () => import( "./ObjectList");
|
||||
export default {
|
||||
components: {
|
||||
// uploadPicture,
|
||||
ObjectList
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
id: this.$route.query.id,
|
||||
token: "",
|
||||
visable:{editPicture:false},
|
||||
article: {
|
||||
articleTitle: "",
|
||||
articleContent: "",
|
||||
articleAddress:"",
|
||||
commentStatus: true,
|
||||
recommendStatus: false,
|
||||
viewStatus: true,
|
||||
password: "",
|
||||
articleCover: "",
|
||||
sortId: null,
|
||||
labelId: null
|
||||
},
|
||||
sorts: [],
|
||||
labels: [],
|
||||
labelsTemp: [],
|
||||
rules: {
|
||||
articleTitle: [
|
||||
{required: true, message: '请输入标题', trigger: 'change'}
|
||||
],
|
||||
articleContent: [
|
||||
{required: true, message: '请输入内容', trigger: 'change'}
|
||||
],
|
||||
commentStatus: [
|
||||
{required: true, message: '是否启用评论', trigger: 'change'}
|
||||
],
|
||||
recommendStatus: [
|
||||
{required: true, message: '是否推荐', trigger: 'change'}
|
||||
],
|
||||
viewStatus: [
|
||||
{required: true, message: '是否可见', trigger: 'change'}
|
||||
],
|
||||
articleCover: [
|
||||
{required: true, message: '封面', trigger: 'change'}
|
||||
],
|
||||
sortId: [
|
||||
{required: true, message: '分类', trigger: 'change'}
|
||||
],
|
||||
labelId: [
|
||||
{required: true, message: '标签', trigger: 'blur'}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
computed: {},
|
||||
|
||||
watch: {
|
||||
'article.sortId'(newVal, oldVal) {
|
||||
if (oldVal !== null) {
|
||||
this.article.labelId = null;
|
||||
}
|
||||
if (!this.$common.isEmpty(newVal) && !this.$common.isEmpty(this.labels)) {
|
||||
this.labelsTemp = this.labels.filter(l => l.sortId === newVal);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.getSortAndLabel();
|
||||
this.getUpToken();
|
||||
this.article.articleAddress = returnCitySN.cname;
|
||||
},
|
||||
|
||||
mounted() {
|
||||
|
||||
},
|
||||
|
||||
methods: {
|
||||
getUpToken() {
|
||||
this.$http.get(this.$constant.baseURL + "/qiniu/getUpToken", {}, true)
|
||||
.then((res) => {
|
||||
if (!this.$common.isEmpty(res.data)) {
|
||||
this.token = res.data;
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
this.$message({
|
||||
message: error.message,
|
||||
type: "error"
|
||||
});
|
||||
});
|
||||
},
|
||||
imgAdd(pos, file) {
|
||||
if (this.$common.isEmpty(this.token)) {
|
||||
this.$message({
|
||||
message: "上传出错!",
|
||||
type: "warning"
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
let fd = new FormData();
|
||||
fd.append("file", file);
|
||||
fd.append("token", this.token);
|
||||
fd.append("key", "articlePicture" + "/" + this.$store.state.currentAdmin.username.replace(/[^a-zA-Z]/g, '') + this.$store.state.currentAdmin.id + new Date().getTime());
|
||||
|
||||
this.$http.uploadQiniu(this.$constant.qiniuUrl, fd)
|
||||
.then((res) => {
|
||||
if (!this.$common.isEmpty(res.key)) {
|
||||
let url = this.$constant.qiniuDownload + res.key;
|
||||
this.$common.saveResource(this, "articlePicture", url, true);
|
||||
this.$refs.md.$img2Url(pos, url);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
this.$message({
|
||||
message: error.message,
|
||||
type: "error"
|
||||
});
|
||||
});
|
||||
},
|
||||
addArticleCover(res) {
|
||||
console.log(res);
|
||||
this.article.articleCover = res;
|
||||
},
|
||||
getSortAndLabel() {
|
||||
this.$http.get(this.$constant.baseURL + "/webInfo/listSortAndLabel")
|
||||
.then((res) => {
|
||||
if (!this.$common.isEmpty(res.data)) {
|
||||
this.sorts = res.data.sorts;
|
||||
this.labels = res.data.labels;
|
||||
if (!this.$common.isEmpty(this.id)) {
|
||||
this.getArticle();
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
this.$message({
|
||||
message: error.message,
|
||||
type: "error"
|
||||
});
|
||||
});
|
||||
},
|
||||
getArticle() {
|
||||
this.$http.get(this.$constant.baseURL + "/admin/diary/getArticleById", {id: this.id}, true)
|
||||
.then((res) => {
|
||||
if (!this.$common.isEmpty(res.data)) {
|
||||
this.article = res.data;
|
||||
this.article.articleCover = this.article.articleItems;
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
this.$message({
|
||||
message: error.message,
|
||||
type: "error"
|
||||
});
|
||||
});
|
||||
},
|
||||
submitForm(formName) {
|
||||
let md = navigator.userAgent.match(/\((.+?)\)/g)[0];
|
||||
this.article.articleDevice = md?md:'个人主机';
|
||||
if (this.article.viewStatus === false && this.$common.isEmpty(this.article.password)) {
|
||||
this.$message({
|
||||
message: "文章不可见时必须输入密码!",
|
||||
type: "error"
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.$refs[formName].validate((valid) => {
|
||||
if (valid) {
|
||||
if (this.$common.isEmpty(this.id)) {
|
||||
this.saveArticle(this.article, "/diary/saveArticle")
|
||||
} else {
|
||||
this.article.id = this.id;
|
||||
this.saveArticle(this.article, "/diary/updateArticle")
|
||||
}
|
||||
} else {
|
||||
this.$message({
|
||||
message: "请完善必填项!",
|
||||
type: "error"
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
resetForm(formName) {
|
||||
this.$refs[formName].resetFields();
|
||||
if (!this.$common.isEmpty(this.id)) {
|
||||
this.getArticle();
|
||||
}
|
||||
},
|
||||
saveArticle(value, url) {
|
||||
this.$confirm('确认保存?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'success',
|
||||
center: true
|
||||
}).then(() => {
|
||||
this.$http.post(this.$constant.baseURL + url, value, true)
|
||||
.then((res) => {
|
||||
this.$message({
|
||||
message: "保存成功!",
|
||||
type: "success"
|
||||
});
|
||||
this.$router.push({path: '/postList'});
|
||||
})
|
||||
.catch((error) => {
|
||||
this.$message({
|
||||
message: error.message,
|
||||
type: "error"
|
||||
});
|
||||
});
|
||||
}).catch(() => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '已取消保存!'
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.my-tag {
|
||||
margin-bottom: 20px;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
background: var(--lightYellow);
|
||||
border: none;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
font-size: 16px;
|
||||
color: var(--black);
|
||||
}
|
||||
|
||||
.table-td-thumb {
|
||||
border-radius: 2px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.el-switch {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.el-form-item {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,421 @@
|
||||
<template>
|
||||
<div ref="bangumiView">
|
||||
<loader :loading="false">
|
||||
<summary-card :class="{show:vif.isHover}" :fitem="hover_item" :style="summary_card_style"></summary-card>
|
||||
<template >
|
||||
<!-- 首页图片 -->
|
||||
<el-image style="animation: header-effect 2s"
|
||||
class="background-image"
|
||||
v-once
|
||||
:src="$constant.background.bangumi"
|
||||
fit="cover">
|
||||
<div slot="error" class="image-slot background-image-error"></div>
|
||||
</el-image>
|
||||
<!-- 首页文字 -->
|
||||
<div class="signature-wall myCenter my-animation-hideToShow">
|
||||
<h1 class="playful">
|
||||
<span v-for="(a, index) in '🎇分享追番列表🎇'" :key="index">{{a}}</span>
|
||||
</h1>
|
||||
<div class="printer" @click="getGuShi()">
|
||||
<printer :printerInfo="printerInfo">
|
||||
<template slot="paper" slot-scope="scope">
|
||||
<h3>
|
||||
{{ scope.content }}<span class="cursor">|</span>
|
||||
</h3>
|
||||
</template>
|
||||
</printer>
|
||||
</div>
|
||||
<div id="bannerWave1"></div>
|
||||
<div id="bannerWave2"></div>
|
||||
<i class="el-icon-arrow-down" @click="navigation('.page-container-wrap')"></i>
|
||||
</div>
|
||||
<!-- 首页内容 -->
|
||||
<div class="page-container-wrap">
|
||||
<div class="page-container">
|
||||
<div class = "bv_container" >
|
||||
<div class="bv_font">🎃我的追番追剧🎃</div>
|
||||
<div class = "bv_block">
|
||||
<anime @mouseout.native="vif.isHover=false" @mouseover.native="ihover($event,item)" v-for="(item,index) of list" :key="index" :fitem="item"></anime>
|
||||
</div>
|
||||
<!-- <div class="pageBlock"><li v-for="index of Math.ceil(anime.total / anime.limit)" :class="{pageBlock_selcted:pageIndex==index}" @click="getAnime(index,24)" :key="'page1'+index">{{index}}</li></div> -->
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="pagination-wrap">
|
||||
<div @click="pageArticles()" class="pagination" v-if="pagination.total !== articles.length">
|
||||
下一页
|
||||
</div>
|
||||
<div v-else style="user-select: none">
|
||||
~~到底啦~~
|
||||
</div>
|
||||
</div> -->
|
||||
<!-- <el-pagination
|
||||
layout="total, sizes,prev,pager,next,jumper"
|
||||
:page-size="pagination.size"
|
||||
:total="pagination.total"
|
||||
:current-page.sync="pagination.current"
|
||||
@current-change="getAnime(pagination.current,24)"
|
||||
@size-change="SizeChange"
|
||||
/> -->
|
||||
</div>
|
||||
<!-- 页脚 -->
|
||||
<div style="background: var(--background)">
|
||||
<myFooter></myFooter>
|
||||
</div>
|
||||
</template>
|
||||
</loader>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import anime from '../components/common/anime.vue'
|
||||
// import game from '../card/game.vue'
|
||||
const summaryCard = () => import( "./common/summary");
|
||||
const printer = () => import( "./common/printer");
|
||||
const myFooter = () => import( "./common/myFooter");
|
||||
import {getShow,bangu_getCollection,bangu_getCollections} from '../utils/api.js'
|
||||
import {navigation} from '../utils/tools.js'
|
||||
export default {
|
||||
components:{
|
||||
anime,
|
||||
myFooter,
|
||||
printer,
|
||||
"summary-card":summaryCard
|
||||
},
|
||||
name: 'MyAnime',
|
||||
data () {
|
||||
return {
|
||||
loading: false,
|
||||
showAside: true,
|
||||
printerInfo: "观众眼中的热爱最为炽热",
|
||||
pagination: {
|
||||
current: 1,
|
||||
size: 10,
|
||||
total: 0,
|
||||
searchKey: ""
|
||||
},
|
||||
guShi: {
|
||||
"content": "观众眼中的热爱最为炽热.",
|
||||
"origin": "",
|
||||
"author": "",
|
||||
"category": ""
|
||||
},
|
||||
summary_card_style:{}, //用来定位hover卡片
|
||||
hover_item:{subject:{}},
|
||||
vif:{bangumiTv:true,isHover:false},
|
||||
list:[],
|
||||
flag:true,
|
||||
anime:{data:[],total:42,limit:24,pageIndex:1},
|
||||
pageIndex:1,
|
||||
loadtips:"Loading...",
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
this.$store.commit("changePlaylist", 436692330);
|
||||
let thi = this;
|
||||
let timer;
|
||||
this.getAnime(1,24);
|
||||
this.$nextTick(()=>{
|
||||
document.onscroll = function(e){
|
||||
if(!thi.$refs.bangumiView) return
|
||||
let now = document.body.scrollTop || document.documentElement.scrollTop;
|
||||
let clientHeight = window.screen.height;
|
||||
let scrollHeight = document.body.scrollHeight;
|
||||
console.log(now,scrollHeight-clientHeight);
|
||||
if(now>=(scrollHeight-clientHeight-200)&&thi.flag){
|
||||
thi.pageIndex += 1;
|
||||
thi.getAnime(thi.pageIndex,24);
|
||||
}
|
||||
};
|
||||
});
|
||||
},
|
||||
created(){
|
||||
|
||||
},
|
||||
methods:{
|
||||
navigation(target){
|
||||
navigation(target);
|
||||
},
|
||||
getAnime(pageIndex,num){
|
||||
let that = this;
|
||||
this.flag = false;
|
||||
if(pageIndex-1>Math.ceil(this.anime.total / this.anime.limit)){ return;}
|
||||
bangu_getCollection({subject_type:2,limit:num,offset:(pageIndex-1)*num},function(data){
|
||||
console.log(data);
|
||||
that.list.push(...data.data);
|
||||
that.flag = true;
|
||||
});
|
||||
},
|
||||
ihover(e,item){
|
||||
this.vif.isHover = true;
|
||||
this.hover_item = item;
|
||||
let offset = e.currentTarget.getBoundingClientRect();
|
||||
if(offset.x > window.screen.width/2) {
|
||||
this.summary_card_style.left = offset.x-240 + "px";
|
||||
} else {
|
||||
this.summary_card_style.left = offset.x + offset.width + "px";
|
||||
}
|
||||
this.summary_card_style.top = offset.y + "px";
|
||||
},
|
||||
ifout(e){
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped>
|
||||
.signature-wall {
|
||||
/* 向下排列 */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
user-select: none;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.playful {
|
||||
color: var(--white);
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
/*.playful span {*/
|
||||
/* position: relative;*/
|
||||
/* color: #5362f6;*/
|
||||
/* text-shadow: 0.25px 0.25px #e485f8, 0.5px 0.5px #e485f8, 0.75px 0.75px #e485f8,*/
|
||||
/* 1px 1px #e485f8, 1.25px 1.25px #e485f8, 1.5px 1.5px #e485f8, 1.75px 1.75px #e485f8,*/
|
||||
/* 2px 2px #e485f8, 2.25px 2.25px #e485f8, 2.5px 2.5px #e485f8, 2.75px 2.75px #e485f8,*/
|
||||
/* 3px 3px #e485f8, 3.25px 3.25px #e485f8, 3.5px 3.5px #e485f8, 3.75px 3.75px #e485f8,*/
|
||||
/* 4px 4px #e485f8, 4.25px 4.25px #e485f8, 4.5px 4.5px #e485f8, 4.75px 4.75px #e485f8,*/
|
||||
/* 5px 5px #e485f8, 5.25px 5.25px #e485f8, 5.5px 5.5px #e485f8, 5.75px 5.75px #e485f8,*/
|
||||
/* 6px 6px #e485f8;*/
|
||||
/* animation: scatter 1.75s infinite;*/
|
||||
/* font-weight: normal;*/
|
||||
/*}*/
|
||||
|
||||
/*.playful span:nth-child(2n) {*/
|
||||
/* color: #ed625c;*/
|
||||
/* text-shadow: 0.25px 0.25px #f2a063, 0.5px 0.5px #f2a063, 0.75px 0.75px #f2a063,*/
|
||||
/* 1px 1px #f2a063, 1.25px 1.25px #f2a063, 1.5px 1.5px #f2a063, 1.75px 1.75px #f2a063,*/
|
||||
/* 2px 2px #f2a063, 2.25px 2.25px #f2a063, 2.5px 2.5px #f2a063, 2.75px 2.75px #f2a063,*/
|
||||
/* 3px 3px #f2a063, 3.25px 3.25px #f2a063, 3.5px 3.5px #f2a063, 3.75px 3.75px #f2a063,*/
|
||||
/* 4px 4px #f2a063, 4.25px 4.25px #f2a063, 4.5px 4.5px #f2a063, 4.75px 4.75px #f2a063,*/
|
||||
/* 5px 5px #f2a063, 5.25px 5.25px #f2a063, 5.5px 5.5px #f2a063, 5.75px 5.75px #f2a063,*/
|
||||
/* 6px 6px #f2a063;*/
|
||||
/* animation-delay: 0.3s;*/
|
||||
/*}*/
|
||||
|
||||
/*.playful span:nth-child(3n) {*/
|
||||
/* color: #ffd913;*/
|
||||
/* text-shadow: 0.25px 0.25px #6ec0a9, 0.5px 0.5px #6ec0a9, 0.75px 0.75px #6ec0a9,*/
|
||||
/* 1px 1px #6ec0a9, 1.25px 1.25px #6ec0a9, 1.5px 1.5px #6ec0a9, 1.75px 1.75px #6ec0a9,*/
|
||||
/* 2px 2px #6ec0a9, 2.25px 2.25px #6ec0a9, 2.5px 2.5px #6ec0a9, 2.75px 2.75px #6ec0a9,*/
|
||||
/* 3px 3px #6ec0a9, 3.25px 3.25px #6ec0a9, 3.5px 3.5px #6ec0a9, 3.75px 3.75px #6ec0a9,*/
|
||||
/* 4px 4px #6ec0a9, 4.25px 4.25px #6ec0a9, 4.5px 4.5px #6ec0a9, 4.75px 4.75px #6ec0a9,*/
|
||||
/* 5px 5px #6ec0a9, 5.25px 5.25px #6ec0a9, 5.5px 5.5px #6ec0a9, 5.75px 5.75px #6ec0a9,*/
|
||||
/* 6px 6px #6ec0a9;*/
|
||||
/* animation-delay: 0.15s;*/
|
||||
/*}*/
|
||||
|
||||
/*.playful span:nth-child(5n) {*/
|
||||
/* color: #555bff;*/
|
||||
/* text-shadow: 0.25px 0.25px #e485f8, 0.5px 0.5px #e485f8, 0.75px 0.75px #e485f8,*/
|
||||
/* 1px 1px #e485f8, 1.25px 1.25px #e485f8, 1.5px 1.5px #e485f8, 1.75px 1.75px #e485f8,*/
|
||||
/* 2px 2px #e485f8, 2.25px 2.25px #e485f8, 2.5px 2.5px #e485f8, 2.75px 2.75px #e485f8,*/
|
||||
/* 3px 3px #e485f8, 3.25px 3.25px #e485f8, 3.5px 3.5px #e485f8, 3.75px 3.75px #e485f8,*/
|
||||
/* 4px 4px #e485f8, 4.25px 4.25px #e485f8, 4.5px 4.5px #e485f8, 4.75px 4.75px #e485f8,*/
|
||||
/* 5px 5px #e485f8, 5.25px 5.25px #e485f8, 5.5px 5.5px #e485f8, 5.75px 5.75px #e485f8,*/
|
||||
/* 6px 6px #e485f8;*/
|
||||
/* animation-delay: 0.4s;*/
|
||||
/*}*/
|
||||
|
||||
/*.playful span:nth-child(7n) {*/
|
||||
/* color: #ff9c55;*/
|
||||
/* text-shadow: 0.25px 0.25px #ff5555, 0.5px 0.5px #ff5555, 0.75px 0.75px #ff5555,*/
|
||||
/* 1px 1px #ff5555, 1.25px 1.25px #ff5555, 1.5px 1.5px #ff5555, 1.75px 1.75px #ff5555,*/
|
||||
/* 2px 2px #ff5555, 2.25px 2.25px #ff5555, 2.5px 2.5px #ff5555, 2.75px 2.75px #ff5555,*/
|
||||
/* 3px 3px #ff5555, 3.25px 3.25px #ff5555, 3.5px 3.5px #ff5555, 3.75px 3.75px #ff5555,*/
|
||||
/* 4px 4px #ff5555, 4.25px 4.25px #ff5555, 4.5px 4.5px #ff5555, 4.75px 4.75px #ff5555,*/
|
||||
/* 5px 5px #ff5555, 5.25px 5.25px #ff5555, 5.5px 5.5px #ff5555, 5.75px 5.75px #ff5555,*/
|
||||
/* 6px 6px #ff5555;*/
|
||||
/* animation-delay: 0.25s;*/
|
||||
/*}*/
|
||||
|
||||
.printer {
|
||||
cursor: pointer;
|
||||
color: var(--white);
|
||||
background: var(--translucent);
|
||||
border-radius: 10px;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
#bannerWave1 {
|
||||
height: 84px;
|
||||
background: var(--bannerWave1);
|
||||
position: absolute;
|
||||
width: 200%;
|
||||
bottom: 0;
|
||||
z-index: 10;
|
||||
animation: gradientBG 120s linear infinite;
|
||||
}
|
||||
|
||||
#bannerWave2 {
|
||||
height: 100px;
|
||||
background: var(--bannerWave2);
|
||||
position: absolute;
|
||||
width: 400%;
|
||||
bottom: 0;
|
||||
z-index: 5;
|
||||
animation: gradientBG 120s linear infinite;
|
||||
}
|
||||
|
||||
/* 光标 */
|
||||
.cursor {
|
||||
margin-left: 1px;
|
||||
animation: hideToShow 0.7s infinite;
|
||||
font-weight: 200;
|
||||
}
|
||||
|
||||
.el-icon-arrow-down {
|
||||
font-size: 40px;
|
||||
font-weight: bold;
|
||||
color: var(--white);
|
||||
position: absolute;
|
||||
bottom: 60px;
|
||||
animation: my-shake 1.5s ease-out infinite;
|
||||
z-index: 15;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.page-container-wrap {
|
||||
background: var(--background);
|
||||
position: relative;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.page-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 90%;
|
||||
padding: 0 0 40px 0;
|
||||
margin: 0 auto;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
|
||||
.pagination-wrap {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
padding: 13px 15px;
|
||||
border: 1px solid var(--lightGray);
|
||||
border-radius: 3rem;
|
||||
color: var(--greyFont);
|
||||
width: 100px;
|
||||
user-select: none;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.pagination:hover {
|
||||
border: 1px solid var(--themeBackground);
|
||||
color: var(--themeBackground);
|
||||
box-shadow: 0 0 5px var(--themeBackground);
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1100px) {
|
||||
.recent-posts {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.page-container {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1000px) {
|
||||
|
||||
.page-container {
|
||||
/* 文章栏与侧标栏垂直排列 */
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.aside-content {
|
||||
width: 100%;
|
||||
max-width: unset;
|
||||
float: unset;
|
||||
margin: 40px auto 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#BangumiView{
|
||||
color: var(--font-color);
|
||||
margin: auto;
|
||||
text-align:center;
|
||||
display:flex;
|
||||
width:100%;
|
||||
}
|
||||
.bv_container{
|
||||
width:100%;
|
||||
}
|
||||
.bv_font{
|
||||
font-size: 1.8rem;
|
||||
line-height: 3rem;
|
||||
height: 3rem;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
.bv_block{
|
||||
position:relative;
|
||||
display: grid;
|
||||
flex-wrap: wrap;
|
||||
grid-gap: 20px;
|
||||
justify-content: center;
|
||||
grid-template-columns: repeat(6,160px);
|
||||
margin-top: 20px;
|
||||
}
|
||||
.bv_block::-webkit-scrollbar{
|
||||
display: none;
|
||||
}
|
||||
.pageBlock{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
height: 32px;
|
||||
list-style: none;
|
||||
}
|
||||
.pageBlock li {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin: 0 5px 0;
|
||||
line-height: 32px;
|
||||
color: var(--focus-color);
|
||||
background: #dc143c;
|
||||
}
|
||||
.pageBlock li.pageBlock_selcted,.pageBlock li:hover{
|
||||
background-color: var(--font-color);
|
||||
cursor: pointer;
|
||||
}
|
||||
@media screen and (max-width: 768px) {
|
||||
.bv_block{
|
||||
position:relative;
|
||||
width:100%;
|
||||
max-height: 85vh;
|
||||
overflow-y:scroll;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin:0.8em auto;
|
||||
max-width: 340px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 35px;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,670 @@
|
||||
<template>
|
||||
<div id="viewMusicBar" class="viewMusicBar" ref="viewMusicBar" :class="[(attr.bottom)?'bottomStyle':'']">
|
||||
<div id="viewMusic" ref="viewMusic">
|
||||
<div id="JMusic" ref="JMusic" class="showclass">
|
||||
<audio id="JAudio" crossorigin="anonymous" ref="audio" :src="nowplay.song.url" :autoplay="isplay"></audio>
|
||||
<img class="jpicture" :src="nowplay.song.poster"/>
|
||||
<div class="jshow">
|
||||
<div class="jpart1">
|
||||
<p class="p1Title">{{nowplay.song.title}}</p>
|
||||
<p class="p1Author"><font :key="aindex" v-for="(author,aindex) of nowplay.song.author">{{author.name}}/</font></p>
|
||||
</div>
|
||||
<div class="jpart2">
|
||||
<div class="p2Gun"></div>
|
||||
<div class="p2Stick" ref="p2Stick">
|
||||
<div class="stick_cover" ref="stick_cover"></div>
|
||||
<div class="stick_point" ref="stick_point"></div>
|
||||
</div>
|
||||
<a class="p2Time" ref="p2Time" @click="download()" title="点击可下载">{{showObject.curr}}</a>
|
||||
<div class="jpart3">
|
||||
<div class="p3Before" @click="corrct('left')">
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 32 32"><path d="M25.468 6.947c-0.326-0.172-0.724-0.151-1.030 0.057l-6.438 4.38v-3.553c0-0.371-0.205-0.71-0.532-0.884-0.326-0.172-0.724-0.151-1.030 0.057l-12 8.164c-0.274 0.186-0.438 0.496-0.438 0.827s0.164 0.641 0.438 0.827l12 8.168c0.169 0.115 0.365 0.174 0.562 0.174 0.16 0 0.321-0.038 0.468-0.116 0.327-0.173 0.532-0.514 0.532-0.884v-3.556l6.438 4.382c0.169 0.115 0.365 0.174 0.562 0.174 0.16 0 0.321-0.038 0.468-0.116 0.327-0.173 0.532-0.514 0.532-0.884v-16.333c0-0.371-0.205-0.71-0.532-0.884z"/></svg>
|
||||
</div>
|
||||
<div class="p3Play" @click="play()" ref="p3Play">
|
||||
<svg t="1557033482333" class="icon" style="width: 1em; height: 1em;vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1095"><path d="M256 832c-11.712 0-23.36-3.2-33.664-9.536A64.170667 64.170667 0 0 1 192 768V256c0-22.208 11.52-42.816 30.336-54.464a64.298667 64.298667 0 0 1 62.272-2.816l512 256a64.064 64.064 0 0 1 0 114.56l-512 256c-8.96 4.48-18.88 6.72-28.608 6.72z" fill p-id="1096" data-spm-anchor-id="a313x.7781069.0.i0" class="selected"/></svg>
|
||||
</div>
|
||||
<div class="p3Next" @click="corrct('right')">
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 32 32"><path d="M25.468 6.947c-0.326-0.172-0.724-0.151-1.030 0.057l-6.438 4.38v-3.553c0-0.371-0.205-0.71-0.532-0.884-0.326-0.172-0.724-0.151-1.030 0.057l-12 8.164c-0.274 0.186-0.438 0.496-0.438 0.827s0.164 0.641 0.438 0.827l12 8.168c0.169 0.115 0.365 0.174 0.562 0.174 0.16 0 0.321-0.038 0.468-0.116 0.327-0.173 0.532-0.514 0.532-0.884v-3.556l6.438 4.382c0.169 0.115 0.365 0.174 0.562 0.174 0.16 0 0.321-0.038 0.468-0.116 0.327-0.173 0.532-0.514 0.532-0.884v-16.333c0-0.371-0.205-0.71-0.532-0.884z"/></svg>
|
||||
</div>
|
||||
<div class="jvolume" ref="jvolume">
|
||||
<svg @click="JMusicObject.audio.muted = false;vif.muted=false" v-if="vif.muted" t="1626430140328" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9051"><path d="M512 691.2c6.4-99.2 89.6-179.2 192-179.2h6.4V134.4l-246.4 246.4H249.6v265.6h214.4l48 44.8z" fill="#707070" p-id="9052"></path><path d="M627.2 585.6l-22.4 22.4-22.4 22.4 73.6 73.6-73.6 73.6 22.4 22.4 22.4 22.4 73.6-73.6 76.8 73.6 22.4-22.4 22.4-22.4-73.6-73.6 73.6-73.6-22.4-22.4-22.4-22.4-76.8 73.6z" fill="#707070" p-id="9053"></path></svg>
|
||||
<svg @click="JMusicObject.audio.muted = true;vif.muted=true" v-if="!vif.muted" t="1626427775189" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2885" ><path d="M537.6 145.066667L554.666667 128v768l-85.333334-85.333333-298.666666-298.666667 64-64 302.933333-302.933333zM469.333333 341.333333l-166.4 170.666667 166.4 170.666667V341.333333z m170.666667-123.733333c145.066667 21.333333 256 145.066667 256 294.4s-110.933333 273.066667-256 294.4v-85.333333c98.133333-21.333333 170.666667-106.666667 170.666667-209.066667s-72.533333-187.733333-170.666667-209.066667v-85.333333z m0 128c72.533333 17.066667 128 85.333333 128 166.4s-55.466667 145.066667-128 166.4v-89.6c25.6-12.8 42.666667-42.666667 42.666667-72.533333s-17.066667-59.733333-42.666667-72.533334V345.6z" fill="#444444" p-id="2886"></path></svg>
|
||||
<input type="range" value=1 min=0 max=1 step=0.1 v-model="JMusicObject.audio.volume" class="input_volume" />
|
||||
</div>
|
||||
<div class="p3List" @click="selectList()" @click.right.prevent="vif.cplaylist=true">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 22 32"><path d="M20.8 14.4q0.704 0 1.152 0.48t0.448 1.12-0.48 1.12-1.12 0.48h-19.2q-0.64 0-1.12-0.48t-0.48-1.12 0.448-1.12 1.152-0.48h19.2zM1.6 11.2q-0.64 0-1.12-0.48t-0.48-1.12 0.448-1.12 1.152-0.48h19.2q0.704 0 1.152 0.48t0.448 1.12-0.48 1.12-1.12 0.48h-19.2zM20.8 20.8q0.704 0 1.152 0.48t0.448 1.12-0.48 1.12-1.12 0.48h-19.2q-0.64 0-1.12-0.48t-0.48-1.12 0.448-1.12 1.152-0.48h19.2z" /></svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="jhide" ref="jhide" @click.right.prevent="vif.vsetAttr=true">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 32 32"><path d="M22 16l-10.105-10.6-1.895 1.987 8.211 8.613-8.211 8.612 1.895 1.988 8.211-8.613z" /></svg>
|
||||
</div>
|
||||
<div class="jdialog dialog-clist" v-if="vif.cplaylist" @click="vif.cplaylist=false">
|
||||
<input type="text" class="dialog-line" placeholder="更换歌单" v-model="attr.playlist" @click.stop="" @keydown.enter="replayList()"/>
|
||||
</div>
|
||||
<div class="jdialog dialog-slist" v-if="vif.vsetAttr" @click="vif.vsetAttr=false">
|
||||
<input type="checkbox" class="dialog-line" v-model="attr.bottom" @click.stop="" /> 底部
|
||||
<input type="checkbox" class="dialog-line" v-model="attr.shake" @click.stop="" /> 音乐可视化
|
||||
</div>
|
||||
</div>
|
||||
<div class="jlists" ref="JLists">
|
||||
<div :class="[(song==nowplay.song)?'jlists-playing':'','jlists_item']" :key="song.id" v-for="(song,index) in list.songs" @click="corrct(index);">
|
||||
<font>{{song.title}}</font>-
|
||||
<font :key="aindex" v-for="(author,aindex) of song.author">{{author.name}}/</font>
|
||||
</div>
|
||||
</div>
|
||||
<canvas id="CANVAS" ref="canvas" v-show="attr.shake" :style="[{'height':attr.shakeheight}]"></canvas>
|
||||
<div class="jlyric" ref="JLyric"><div><font :style="[{'height':attr.lyricheight+'px','line-height':attr.lyricheight+'px'}]" :key="index" v-for="(item,index) of showObject.Lyrics" :class="item.classname">{{item.text}}</font></div></div>
|
||||
|
||||
</div>
|
||||
<div class="JBg" ref="JBg"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script type="text/ecmascript-6">
|
||||
import { timeout } from 'q';
|
||||
|
||||
export default {
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
JMusicObject:{audio:{volume:{},muted:false},JMshake:null},
|
||||
showObject:{curr:"00:00 / 00:00",Lyrics:new Array()},
|
||||
nowplay:{song:{},currentTime:0,duration:0},
|
||||
list:{songs:[],lyrics:[]},
|
||||
vif:{cplaylist:false,ischange:false,muted:false,vsetAttr:false},
|
||||
isplay:false,
|
||||
attr:{playlist:this.$store.state.playlist,bottom:false,shakeheigh:"200px",shake:false,lyricheight:21},
|
||||
attr_init:{playlist:this.$store.state.playlist,bottom:false,shakeheigh:"200px",shake:false,lyricheight:21},
|
||||
};
|
||||
},
|
||||
beforeRouteEnter(to, from, next) {
|
||||
next(vm => {});
|
||||
},
|
||||
mounted() {
|
||||
let that = this;
|
||||
this.JMusicObject.canvas = this.$refs.canvas;
|
||||
this.JMusicObject.audio = this.$refs.audio;
|
||||
this.setAttr();
|
||||
this.replayList();
|
||||
if(this.attr.shake){this.creCanvas();}
|
||||
this.creInterval();
|
||||
this.creEvent();
|
||||
this.$nextTick(()=>{
|
||||
setTimeout(() => {
|
||||
$(that.$refs.JMusic).toggleClass("showclass")
|
||||
$(that.$refs.JMusic).toggleClass("hideclass")
|
||||
}, 3000);
|
||||
})
|
||||
},
|
||||
watch: {
|
||||
"$store.state.playlist": {
|
||||
immediate: true,
|
||||
handler() {
|
||||
this.attr.playlist = this.$store.state.playlist
|
||||
this.replayList()
|
||||
},
|
||||
},
|
||||
'nowplay.song.lyrics'(to,from){
|
||||
this.standardLyric(this.nowplay.song.lyrics);
|
||||
},
|
||||
'list.songs'(to,from){
|
||||
this.corrct(0);
|
||||
},
|
||||
'attr.shake'(to,from){
|
||||
if(this.attr.shake&&!this.JMusicObject.JMshake){
|
||||
this.creCanvas();
|
||||
}
|
||||
},
|
||||
'isplay'(to,from){
|
||||
if(this.isplay){
|
||||
this.$refs.p3Play.innerHTML = '<svg t="1557034022257" class="icon" style="width: 1em; height: 1em;vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1932" data-spm-anchor-id="a313x.7781069.0.i5"><path d="M597.333333 816.64 768 816.64 768 219.306667 597.333333 219.306667M256 816.64 426.666667 816.64 426.666667 219.306667 256 219.306667 256 816.64Z" p-id="1933" data-spm-anchor-id="a313x.7781069.0.i3"></path></svg>';
|
||||
} else {
|
||||
this.$refs.p3Play.innerHTML = '<svg t="1557033482333" class="icon" style="width: 1em; height: 1em;vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1095"><path d="M256 832c-11.712 0-23.36-3.2-33.664-9.536A64.170667 64.170667 0 0 1 192 768V256c0-22.208 11.52-42.816 30.336-54.464a64.298667 64.298667 0 0 1 62.272-2.816l512 256a64.064 64.064 0 0 1 0 114.56l-512 256c-8.96 4.48-18.88 6.72-28.608 6.72z" fill="" p-id="1096" data-spm-anchor-id="a313x.7781069.0.i0" class="selected"></path></svg>';
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
setJMusic(){
|
||||
$(this.$refs.viewMusic).css(css);
|
||||
},
|
||||
//适合load
|
||||
setAttrByEle(){
|
||||
if(!window.top.document){return false;} //无法获取父级窗口
|
||||
let father = $(window.top.document).find("[name='MUSIC']");
|
||||
if(father.attr("bottom")=="true"){this.attr.bottom=true;}
|
||||
if(father.attr("playlist")){this.attr.playlist=$(father).attr("playlist")}
|
||||
return true;
|
||||
},
|
||||
setAttr(){
|
||||
if(this.setAttrByEle()){return};//父元素name=MUSIC中找属性
|
||||
for(let key in top.JMusicAttr){ //顶级配置中找属性(可调式)
|
||||
this.attr[key] = top.JMusicObject[key];
|
||||
console.log(`配置 ${key} 成功"`);
|
||||
}
|
||||
},
|
||||
creCanvas(){
|
||||
try{
|
||||
this.JMusicObject.JMshake = new JMshake(this.JMusicObject.canvas,this.JMusicObject.audio);
|
||||
this.JMusicObject.JMshake.loadMusic();
|
||||
} catch(e){console.log(e,"音乐可视化加载失败!");}
|
||||
},
|
||||
creInterval(){
|
||||
let that = this;
|
||||
this.gunVal = setInterval(function(){//进度条
|
||||
if(!that.vif.ischange){
|
||||
that.nowplay.duration = that.JMusicObject.audio.duration || 59;
|
||||
that.nowplay.currentTime = that.JMusicObject.audio.currentTime || 0;
|
||||
let width = parseFloat($(that.$refs.p2Stick).eq(0).css("width"));
|
||||
let left = (that.nowplay.currentTime / that.nowplay.duration) *width;
|
||||
$(that.$refs.stick_point).css({"left":left+"px"});
|
||||
$(that.$refs.stick_cover).css({"width":left+"px"});
|
||||
$(that.$refs.p2Time).text(that.getTimeText(that.nowplay.currentTime) +" / "+ that.getTimeText(that.nowplay.duration));
|
||||
}
|
||||
},500);
|
||||
|
||||
this.gunLyric = setInterval(function(){
|
||||
let now = $(".lyricgun"+Math.round(that.nowplay.currentTime));
|
||||
if(now.length==0){} else {
|
||||
$(that.$refs.JLyric).find("div font").removeClass("lyricshow");
|
||||
now.addClass("lyricshow");
|
||||
let index = $(that.$refs.JLyric).find("div font").toArray().indexOf(now[0]);
|
||||
$(that.$refs.JLyric).find("div").css("margin-top",-((index-1) * that.attr.lyricheight)+"px");
|
||||
}
|
||||
},500);
|
||||
},
|
||||
creEvent(){
|
||||
let that = this;
|
||||
this.JMusicObject.audio.onended = function(){
|
||||
that.corrct("right");
|
||||
}
|
||||
this.$refs.p2Stick.onmousedown = function(e){
|
||||
that.vif.ischange = true;
|
||||
let sp = this;
|
||||
let jbg = that.$refs.JBg;
|
||||
jbg.style.display = "block";
|
||||
let l;
|
||||
let move = jbg.onmousemove = function(e){
|
||||
let offset = $(sp).offset();
|
||||
l = e.offsetX - offset.left;
|
||||
if(l<0) l = 0;
|
||||
if(l>sp.offsetWidth) return;
|
||||
that.$refs.stick_point.style.left = l+"px";
|
||||
that.$refs.stick_cover.style.width = l+"px";
|
||||
}
|
||||
let up = jbg.onmouseup = function(e){
|
||||
that.vif.ischange = false;
|
||||
jbg.style.display = "none";
|
||||
l = e.offsetX - $(sp).offset().left;
|
||||
that.$refs.stick_point.style.left = l+"px";
|
||||
that.$refs.stick_cover.style.width = l+"px";
|
||||
that.JMusicObject.audio.currentTime = that.JMusicObject.audio.duration*(l/sp.offsetWidth);
|
||||
}
|
||||
}
|
||||
this.$refs.jhide.onclick = function(e){
|
||||
$(that.$refs.JMusic).toggleClass("showclass")
|
||||
$(that.$refs.JMusic).toggleClass("hideclass")
|
||||
that.$refs.JLists.classList.remove("jlists_show");
|
||||
}
|
||||
},
|
||||
getTimeText(time){
|
||||
let hours = parseInt(time/3600)
|
||||
var minutes = parseInt((time-hours*3600)/60);
|
||||
let seconds = Math.round(time-(hours*3600+minutes*60));
|
||||
return minutes+":"+seconds;
|
||||
},
|
||||
corrct(command){
|
||||
let index = this.list.songs.indexOf(this.nowplay.song);
|
||||
switch (command) {
|
||||
case "right":
|
||||
this.nowplay.song = (index==this.list.songs.length-1)?this.list.songs[0]:this.list.songs[index+1];
|
||||
break;
|
||||
case "left":
|
||||
this.nowplay.song = (index==0)?this.list.songs[this.list.songs.length-1]:this.list.songs[index-1];
|
||||
break;
|
||||
default:
|
||||
this.nowplay.song = this.list.songs[command];
|
||||
break;
|
||||
}
|
||||
if(this.nowplay.song.url=="NULL"){JMusicjsoup.getMp3Url(this.nowplay.song.id,this.nowplay.song);}
|
||||
if(this.nowplay.song.lyrics=="NULL"){JMusicjsoup.getLyric(this.nowplay.song.id,this.nowplay.song);}
|
||||
},
|
||||
play(){
|
||||
if(this.JMusicObject.audio.paused){
|
||||
this.JMusicObject.audio.play();
|
||||
this.isplay=true;
|
||||
}else{
|
||||
this.JMusicObject.audio.pause();
|
||||
this.isplay=false;
|
||||
}
|
||||
},
|
||||
selectList(){
|
||||
$(this.$refs.JLists).toggleClass("jlists_show");
|
||||
},
|
||||
replayList(){
|
||||
let that = this;
|
||||
JMusicjsoup.getPlayList(this.attr.playlist,this);
|
||||
this._setPlayList = function(data){
|
||||
let res = data.playlist.tracks;
|
||||
let songs = new Array();
|
||||
for(let d=0;d<res.length;d++){
|
||||
let song = new Object();
|
||||
song.title=res[d].name;
|
||||
song.id=res[d].id;
|
||||
song.author = res[d].ar;
|
||||
song.poster = res[d].al.picUrl;
|
||||
song.url="NULL";
|
||||
song.lyrics="NULL";
|
||||
song._setMp3Url = function(id,data){
|
||||
this.url = data.data[0].url;
|
||||
}
|
||||
song._setLyric = function(id,data){
|
||||
data.lrc?this.lyrics = data.lrc.lyric:this.lyrics="[00:00.000] nothing..."
|
||||
}
|
||||
songs.push(song);
|
||||
}
|
||||
that.list.songs = songs;
|
||||
};
|
||||
},
|
||||
standardLyric(lyric){//处理载入歌词
|
||||
let lyrics = lyric.split("\n");
|
||||
let timeReg = /\[\d*:\d*((\.|\:)\d*)*\]/;
|
||||
let ended = new Array();
|
||||
let arrLyric = new Array();
|
||||
for(let i=0;i<lyrics.length;i++){
|
||||
let timeRegExpArr = lyrics[i].match(timeReg);
|
||||
if(!timeRegExpArr)continue;
|
||||
let clause = lyrics[i].replace(timeReg,'');
|
||||
let time = 0;
|
||||
let t = timeRegExpArr[0];
|
||||
let min = Number(String(t.match(/\[\d*/)).slice(1));
|
||||
let sec = Number(String(t.match(/\:\d*/)).slice(1));
|
||||
time = min * 60 + sec; //时间秒计
|
||||
if(clause==""){clause=" "}
|
||||
ended[time] = clause;
|
||||
let li = {};
|
||||
li.text = clause;
|
||||
li.classname = "lyricgun"+time;
|
||||
arrLyric.push(li);
|
||||
}
|
||||
this.showObject.Lyrics = arrLyric;
|
||||
return ended;
|
||||
},
|
||||
download(){
|
||||
let that = this;
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', that.nowplay.song.url, true);
|
||||
xhr.responseType = 'blob';
|
||||
xhr.onload = function() {
|
||||
if (xhr.status === 200) {
|
||||
if (window.navigator.msSaveOrOpenBlob) {
|
||||
navigator.msSaveBlob(xhr.response, that.nowplay.song.title);
|
||||
} else {
|
||||
let link = document.createElement('a');
|
||||
let body = document.querySelector('body');
|
||||
link.href = window.URL.createObjectURL(xhr.response);
|
||||
link.download = that.nowplay.song.title+"-"+that.nowplay.song.author[0].name;
|
||||
// fix Firefox
|
||||
link.style.display = 'none';
|
||||
body.appendChild(link);
|
||||
link.click();
|
||||
body.removeChild(link);
|
||||
window.URL.revokeObjectURL(link.href);
|
||||
};
|
||||
}
|
||||
};
|
||||
xhr.send();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.viewMusicBar{
|
||||
height:100%;
|
||||
width:100%;
|
||||
min-height:64px;
|
||||
cursor:default;
|
||||
}
|
||||
#viewMusic{
|
||||
position : absolute;
|
||||
width:100%;
|
||||
top:0;left:0;
|
||||
min-height:64px;
|
||||
}
|
||||
#viewMusic p{
|
||||
margin: 0;
|
||||
}
|
||||
#JMusic{
|
||||
z-index:2;
|
||||
position : absolute;
|
||||
display : flex;
|
||||
width : 100%;
|
||||
height:100%;
|
||||
overflow:hidden;
|
||||
background:#fff;
|
||||
pointer-events: auto;
|
||||
}
|
||||
#JAudio{
|
||||
display:none;
|
||||
}
|
||||
.JBg{
|
||||
display: none;
|
||||
position:absolute;
|
||||
pointer-events: auto;
|
||||
z-index:999;
|
||||
left:0;
|
||||
top:0;
|
||||
height:100%;
|
||||
width:100%;
|
||||
}
|
||||
.jpicture{
|
||||
min-width: 64px;
|
||||
height:100%;
|
||||
}
|
||||
.jshow{
|
||||
padding: 0px 10px 0 10px;
|
||||
display:flex;
|
||||
flex:1;
|
||||
flex-direction:column;
|
||||
}
|
||||
.jpart1{
|
||||
flex-direction:column;
|
||||
flex:1;
|
||||
width:100%;
|
||||
}
|
||||
.p1Title{
|
||||
font-size:13px;
|
||||
color:#444;
|
||||
}
|
||||
.p1Author{
|
||||
font-size:12px;
|
||||
color:#666;
|
||||
}
|
||||
.p1Title,.p1Author{
|
||||
text-indent:.2rem;
|
||||
line-height: 1.5em;
|
||||
overflow: hidden;
|
||||
max-width: 60%;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
transition: .4s ease-in-out;
|
||||
}
|
||||
.jpart1 font:hover,.p1Title:hover,.p2Time:hover{
|
||||
color:#ff4777;
|
||||
transition: .4s ease-in-out;
|
||||
}
|
||||
.jpart2{
|
||||
position:relative;
|
||||
display:flex;
|
||||
flex-wrap: nowrap;
|
||||
justify-content:space-around;
|
||||
flex:1;
|
||||
width:100%;
|
||||
align-items:center;
|
||||
}
|
||||
.jpart3{
|
||||
display:flex;
|
||||
}
|
||||
.p2Time{
|
||||
overflow:hidden;
|
||||
font-size:12px;
|
||||
text-align: center;
|
||||
min-width:80px;
|
||||
color:#666;
|
||||
cursor: pointer;
|
||||
}
|
||||
.p2Stick{
|
||||
width:100%;
|
||||
height:5px;
|
||||
background-color:#666;
|
||||
position:relative;
|
||||
}
|
||||
.stick_point{
|
||||
border: 1px solid #ccc;
|
||||
position:absolute;
|
||||
border-radius:50%;
|
||||
height:12px;
|
||||
width:12px;
|
||||
background:#eee;
|
||||
top:50%;
|
||||
transform:translate(0, -50%);
|
||||
}
|
||||
.stick_point:hover{
|
||||
border: 1px solid #fe8e8e;
|
||||
transition:all 0.4s ease-in-out ;
|
||||
cursor: pointer;
|
||||
}
|
||||
.stick_cover{
|
||||
position:absolute;
|
||||
height:100%;
|
||||
background:#eee;
|
||||
}
|
||||
.p3Next, .p3Play, .p3Before, .p3List, .jvolume {
|
||||
display: flex;
|
||||
margin:auto;
|
||||
height:20px;
|
||||
width:20px;
|
||||
text-align:center;
|
||||
}
|
||||
.p3Next svg,.p3Play svg,.p3Before svg,.jhide svg,.p3List svg{
|
||||
height:100% !important;
|
||||
width:100% !important;
|
||||
}
|
||||
.p3Next{
|
||||
transform-origin: 50% 50% 0px;
|
||||
transform:rotateY(180deg);
|
||||
}
|
||||
.viewMusicBar .icon{
|
||||
width:20px !important;
|
||||
}
|
||||
.viewMusicBar svg {
|
||||
cursor:pointer;
|
||||
}
|
||||
.viewMusicBar svg path{
|
||||
transition:0.4s ease-in-out ;
|
||||
fill:#888;
|
||||
}
|
||||
.p3Before:hover svg path{
|
||||
fill:#db5a6b;
|
||||
}
|
||||
.p3Play:hover svg path{
|
||||
fill:#a1afc9;
|
||||
}
|
||||
.p3Next:hover svg path{
|
||||
fill:#60281e;
|
||||
}
|
||||
.p3List:hover svg path{
|
||||
fill:#425066;
|
||||
}
|
||||
.jhide:hover svg path{
|
||||
fill:#2e4e7e;
|
||||
}
|
||||
.jvolume:hover svg path{
|
||||
fill:#2e7e71;
|
||||
}
|
||||
.jvolume:hover .input_volume{
|
||||
display: inline-block;
|
||||
height:10px;
|
||||
}
|
||||
.jvolume{
|
||||
position: relative;
|
||||
}
|
||||
.viewMusicBar .input_volume{
|
||||
position: absolute;
|
||||
display: none;
|
||||
height: 0;
|
||||
left: 50%;
|
||||
transform: translate(-50%, 0);
|
||||
width: 80px;
|
||||
bottom: 100%;
|
||||
transform-origin: center center;
|
||||
}
|
||||
.jhide{
|
||||
display:inline-block;
|
||||
width:20px;
|
||||
line-height:50px;
|
||||
height:100%;
|
||||
text-align:center;
|
||||
background:rgba(255,255,255,0.5);
|
||||
}
|
||||
.hideclass{
|
||||
left:20px;
|
||||
transform: translate(-100%,0);
|
||||
transition:all 0.4s ease-in-out ;
|
||||
}
|
||||
.showclass{
|
||||
left:0;
|
||||
transform: translate(0,0);
|
||||
transition:all 0.4s ease-in-out ;
|
||||
}
|
||||
.showclass .jhide svg{
|
||||
transform-origin: 50% 50% 0px;
|
||||
transform:rotateY(180deg);
|
||||
transition:all 0.4s ease-in-out ;
|
||||
}
|
||||
.jlyric{
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top:0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
pointer-events:none;
|
||||
}
|
||||
.lyricshow{
|
||||
font-size:1rem !important;
|
||||
opacity:1 !important;
|
||||
}
|
||||
.jlyric > div{
|
||||
text-align: center;
|
||||
transition: all 0.4s ease-in-out;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
margin-top:0px;
|
||||
}
|
||||
.jlyric font{
|
||||
width:100%;
|
||||
color:#fff;
|
||||
text-shadow: 0 1px 5px #4c8dae;
|
||||
overflow:hidden;
|
||||
font-size:.9em;
|
||||
opacity:.5;
|
||||
}
|
||||
.jlists{
|
||||
z-index:1;
|
||||
opacity:0;
|
||||
width:100%;
|
||||
position:absolute;
|
||||
left:0px;top:100%;
|
||||
background:#fff;
|
||||
max-height: 0px;
|
||||
overflow:hidden;
|
||||
overflow-y:scroll;
|
||||
transition: .4s ease-in-out ;
|
||||
}
|
||||
.jlists_item{
|
||||
height:20px;
|
||||
width:100%;
|
||||
font-size:12px;
|
||||
line-height:20px;
|
||||
text-indent:1em;
|
||||
color:#444;
|
||||
cursor:pointer;
|
||||
transition:all 0.4s ease-in-out ;
|
||||
overflow: hidden;
|
||||
text-overflow:ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.jlists_item:hover{
|
||||
background:rgb(214, 214, 214);
|
||||
transition:all 0.4s ease-in-out ;
|
||||
}
|
||||
.jlists-playing::before{
|
||||
width:6px;
|
||||
height:100%;
|
||||
position: absolute;
|
||||
content:"";
|
||||
left:0;
|
||||
transition: .4s ease-in-out;
|
||||
background: #8ea9a7;
|
||||
}
|
||||
.jlists-playing{
|
||||
position: relative;
|
||||
background:rgb(214, 214, 214);
|
||||
transition:all 0.4s ease-in-out ;
|
||||
}
|
||||
.jlists_show{
|
||||
opacity:1;
|
||||
max-height:200px;
|
||||
pointer-events: auto;
|
||||
}
|
||||
.viewMusicBar.bottomStyle #viewMusic{
|
||||
bottom:0;top:unset;
|
||||
}
|
||||
.viewMusicBar.bottomStyle .jlists{
|
||||
top:0 !important;
|
||||
transform: translate(0,100%);
|
||||
transition: .4s ease-in-out;
|
||||
}
|
||||
.viewMusicBar.bottomStyle .jlists.jlists_show{
|
||||
transform: translate(0,-100%) !important;
|
||||
transition: .4s ease-in-out;
|
||||
}
|
||||
.viewMusicBar.bottomStyle #CANVAS{
|
||||
bottom:0;left:0;top:unset;
|
||||
transform: none !important;
|
||||
}
|
||||
.jlists::-webkit-scrollbar{
|
||||
width: 4px;
|
||||
}
|
||||
.jlists::-webkit-scrollbar-thumb{
|
||||
border-radius: 10px;
|
||||
box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
|
||||
background: rgba(0,0,0,0.2);
|
||||
}
|
||||
.jlists::-webkit-scrollbar-track {
|
||||
border-radius: 0;
|
||||
background: rgba(0,0,0,0.0);
|
||||
}
|
||||
#CANVAS{
|
||||
z-index: 0;
|
||||
position: absolute;
|
||||
top:0;left:0;
|
||||
width:100%;
|
||||
height:200%;
|
||||
transform: rotate(180deg);
|
||||
pointer-events: none;
|
||||
}
|
||||
.jdialog input{
|
||||
outline: none;
|
||||
border: none;
|
||||
}
|
||||
.dialog-clist,.dialog-slist{
|
||||
position: absolute;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width:100%;
|
||||
height:100%;
|
||||
z-index: 50;
|
||||
color:#FFF;
|
||||
background: rgba(0, 0, 0, 0.3);;
|
||||
}
|
||||
.dialog-clist .dialog-line{
|
||||
width:300px;
|
||||
height:28px;
|
||||
line-height: 28px;
|
||||
text-indent: 1.2rem;
|
||||
}
|
||||
.dialog-slist{
|
||||
|
||||
}
|
||||
@media screen and (max-width: 600px) {
|
||||
}
|
||||
</style>
|
@ -0,0 +1 @@
|
||||
{}
|
@ -0,0 +1,409 @@
|
||||
<template>
|
||||
<div class="shuoshuo-card">
|
||||
<div class="shuoshuo-topper">
|
||||
<img src="https://q1.qlogo.cn/g?b=qq&s=100&nk=983341575" alt="" class="shuoshuo-avatar">
|
||||
<div class="shuoshuo-toptitle">
|
||||
<span style="font-size:1.2em;color:var(--fontColor)">Janx</span>
|
||||
<div class="shuoshuo-meta">
|
||||
<span style="font-size:0.9em">{{source.createTime}}</span>
|
||||
<span>
|
||||
<svg viewBox="0 0 1024 1024" width="14" height="14" >
|
||||
<path d="M14.656 512a497.344 497.344 0 1 0 994.688 0 497.344 497.344 0 1 0-994.688 0z"
|
||||
fill="#FF0000"></path>
|
||||
<path
|
||||
d="M374.976 872.64c-48.299-100.032-22.592-157.44 14.421-211.37 40.448-58.966 51.115-117.611 51.115-117.611s31.659 41.386 19.115 106.005c56.149-62.72 66.816-162.133 58.325-200.405 127.317 88.746 181.59 281.002 108.181 423.381C1016 652.501 723.093 323.2 672.277 285.867c16.939 37.333 20.054 100.032-14.101 130.474-58.027-219.84-201.664-265.002-201.664-265.002 16.96 113.536-61.781 237.397-137.344 330.24-2.816-45.163-5.632-76.544-29.483-119.808-5.333 82.176-68.373 149.269-85.29 231.445-22.912 111.637 17.237 193.173 170.581 279.424z"
|
||||
fill="#FFFFFF"></path>
|
||||
</svg> {{source.articleEmotion}}
|
||||
</span>
|
||||
<span>
|
||||
<svg viewBox="0 0 1024 1024" width="14" height="14" >
|
||||
<path
|
||||
d="M113.834667 291.84v449.194667a29.013333 29.013333 0 0 0 28.842666 29.013333h252.928v90.453333l160.597334-90.453333h252.928a29.013333 29.013333 0 0 0 29.013333-29.013333V291.84a29.013333 29.013333 0 0 0-29.013333-29.013333h-665.6a29.013333 29.013333 0 0 0-29.696 29.013333z"
|
||||
fill="#FFDEAD"></path>
|
||||
<path
|
||||
d="M809.130667 262.826667h-665.6a29.013333 29.013333 0 0 0-28.842667 29.013333v40.106667a29.013333 29.013333 0 0 1 28.842667-29.013334h665.6a29.013333 29.013333 0 0 1 29.013333 29.013334V291.84a29.013333 29.013333 0 0 0-29.013333-29.013333z"
|
||||
fill="#FFF3DB"></path>
|
||||
<path
|
||||
d="M556.202667 770.048h252.928a29.013333 29.013333 0 0 0 29.013333-29.013333V362.837333s-59.733333 392.533333-724.309333 314.709334v63.488a29.013333 29.013333 0 0 0 28.842666 29.013333h253.098667v90.453333z"
|
||||
fill="#F2C182"></path>
|
||||
<path
|
||||
d="M619.008 632.32l101.888-35.157333-131.754667-76.117334 29.866667 111.274667zM891.904 148.992a61.44 61.44 0 0 0-84.138667 22.528l-19.968 34.133333 106.666667 61.610667 19.968-34.133333a61.781333 61.781333 0 0 0-22.528-84.138667z"
|
||||
fill="#69BAF9"></path>
|
||||
<path d="M775.338667 198.775467l131.669333 76.032-186.026667 322.218666-131.6864-76.032z"
|
||||
fill="#F7FBFF"></path>
|
||||
<path
|
||||
d="M775.168 198.826667l-5.290667 9.216 59.221334 34.133333a34.133333 34.133333 0 0 1 12.458666 46.592l-139.946666 242.346667a34.133333 34.133333 0 0 1-46.762667 12.629333l-59.050667-34.133333-6.656 11.434666 88.746667 51.2L720.896 597.333333l186.026667-322.56z"
|
||||
fill="#D8E3F0"></path>
|
||||
<path
|
||||
d="M616.448 622.592l2.56 9.728 101.888-35.157333-44.885333-25.941334-59.562667 51.370667zM891.904 148.992c-1.024 0-2.218667-0.853333-3.242667-1.536A61.610667 61.610667 0 0 1 887.466667 204.8l-19.968 34.133333-73.728-42.496-5.12 8.704 106.666666 61.610667 19.968-34.133333a61.781333 61.781333 0 0 0-23.381333-83.626667z"
|
||||
fill="#599ED4"></path>
|
||||
<path
|
||||
d="M265.898667 417.621333H494.933333a17.066667 17.066667 0 1 0 0-34.133333H265.898667a17.066667 17.066667 0 1 0 0 34.133333zM265.898667 533.504H494.933333a17.066667 17.066667 0 0 0 0-34.133333H265.898667a17.066667 17.066667 0 0 0 0 34.133333z"
|
||||
fill="#3D3D63"></path>
|
||||
<path
|
||||
d="M959.488 354.645333a99.84 99.84 0 0 0-23.722667-127.488 78.677333 78.677333 0 0 0-142.848-64.170666l-11.605333 20.138666a17.066667 17.066667 0 0 0-20.821333 7.168l-32.085334 55.466667H142.677333a46.250667 46.250667 0 0 0-45.909333 46.08v449.194667a46.08 46.08 0 0 0 45.909333 46.08h236.032v73.386666a17.066667 17.066667 0 0 0 8.362667 14.848 17.066667 17.066667 0 0 0 8.704 2.218667 17.066667 17.066667 0 0 0 8.362667-2.218667l156.672-88.234666h248.32a46.08 46.08 0 0 0 46.08-46.08V398.677333L921.6 283.306667a17.066667 17.066667 0 0 0-4.266667-21.504l1.877334-3.413334a65.365333 65.365333 0 0 1 10.410666 79.189334l-53.077333 91.989333a56.832 56.832 0 0 0 20.821333 77.653333 17.066667 17.066667 0 0 0 24.234667-6.314666 17.066667 17.066667 0 0 0-6.997333-23.04 23.04 23.04 0 0 1-8.362667-31.061334z m-138.410667 386.389334a11.946667 11.946667 0 0 1-11.946666 11.946666H556.202667a17.066667 17.066667 0 0 0-8.362667 2.218667l-134.997333 76.117333v-61.269333a17.066667 17.066667 0 0 0-17.066667-17.066667H142.677333a11.946667 11.946667 0 0 1-11.776-11.946666V291.84a11.946667 11.946667 0 0 1 11.776-11.946667h565.930667L574.464 512a17.066667 17.066667 0 0 0-1.706667 12.970667L597.333333 615.253333H265.898667a17.066667 17.066667 0 1 0 0 34.133334h352.938666a17.066667 17.066667 0 0 0 5.802667 0l102.4-35.328a17.066667 17.066667 0 0 0 9.216-7.509334l85.333333-147.968z m-204.8-184.661334l63.829334 36.864-49.322667 17.066667z m206.848-170.666666v1.365333l-108.373333 186.709333-102.4-59.050666L781.482667 221.866667l102.4 59.050666z m76.458667-161.28L887.466667 244.224l-76.970667-44.373333 11.264-19.797334a44.544 44.544 0 1 1 77.141333 44.544z"
|
||||
fill="#3D3D63"></path>
|
||||
</svg> {{source.likeCount}} 条评论
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="shuoshuo-container" v-html="source.articleContent">
|
||||
</div>
|
||||
<div class="shuoshuo-piclist" ref="imgList" :class="picClassname">
|
||||
<!-- v-viewer.rebuild="{inline: false,'url': 'data-source',images:picList[0]}" -->
|
||||
<a :href="item" v-for="item,index in picList[0]" v-show="(index<9)?true:false" :key="item"
|
||||
:overtip="`+ ${picList[0].length-9}`"
|
||||
:data-sub-html="picList[1][index]||'Have a good life!'"
|
||||
data-fb-html='这里可以写些东西呢'
|
||||
>
|
||||
<div class="imgbox">
|
||||
<img :click="clickPicture" :title="picList[1][index]" class="lazyload_images" :data-source="item" :src="item+'-poster'" alt="">
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="shuoshuo-tailer">
|
||||
<span style="font-size:0.9em;line-height: 1.5em;">{{source.articleAddress}}</span>
|
||||
<span style="font-size:0.9em;line-height: 1.5em;">{{source.articleDevice}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// const graffiti = () => import( "./graffiti");
|
||||
const proPage = () => import( "../common/proPage");
|
||||
import MarkdownIt from 'markdown-it';
|
||||
// import 'lightgallery.js'
|
||||
// import 'lg-thumbnail.js'
|
||||
export default {
|
||||
components: {
|
||||
},
|
||||
props: {
|
||||
source: {
|
||||
type: Number
|
||||
},
|
||||
userId: {
|
||||
type: Number
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isGraffiti: false,
|
||||
total: 0,
|
||||
replyDialogVisible: false,
|
||||
floorComment: {},
|
||||
replyComment: {},
|
||||
comments: [],
|
||||
picList:[],
|
||||
picClassname:"",
|
||||
pagination: {
|
||||
current: 1,
|
||||
size: 10,
|
||||
total: 0,
|
||||
source: this.source,
|
||||
floorCommentId: null
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
computed: {},
|
||||
|
||||
created() {
|
||||
// this.getComments(this.pagination);
|
||||
// this.getTotal();
|
||||
this.checkPicList();
|
||||
},
|
||||
mounted() {
|
||||
new lightGallery(this.$refs.imgList,{
|
||||
plugins: [lgThumbnail,lgHash,lgRotate,lgVideo,lgZoom,lgFullscreen,lgAutoplay,lgComment],
|
||||
mode: 'lg-slide',
|
||||
cssEasing: 'ease',
|
||||
commentBox: true,
|
||||
fbComments: true,
|
||||
galleryId:this.source.id,
|
||||
speed: 300
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
toPage(page) {
|
||||
this.pagination.current = page;
|
||||
window.scrollTo({
|
||||
top: document.getElementById('comment-content').offsetTop
|
||||
});
|
||||
// this.getComments(this.pagination);
|
||||
},
|
||||
getTotal() {
|
||||
this.$http.get(this.$constant.baseURL + "/comment/getCommentCount", {source: this.source})
|
||||
.then((res) => {
|
||||
if (!this.$common.isEmpty(res.data)) {
|
||||
this.total = res.data;
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
this.$message({
|
||||
message: error.message,
|
||||
type: "error"
|
||||
});
|
||||
});
|
||||
},
|
||||
toChildPage(floorComment) {
|
||||
floorComment.childComments.current += 1;
|
||||
let pagination = {
|
||||
current: floorComment.childComments.current,
|
||||
size: 5,
|
||||
total: 0,
|
||||
source: this.source,
|
||||
floorCommentId: floorComment.id
|
||||
}
|
||||
// this.getComments(pagination, floorComment, true);
|
||||
},
|
||||
emoji(comments, flag) {
|
||||
comments.forEach(c => {
|
||||
c.commentContent = c.commentContent.replace(/\n/g, '<br/>');
|
||||
c.commentContent = this.$common.faceReg(c.commentContent);
|
||||
c.commentContent = this.$common.pictureReg(c.commentContent);
|
||||
if (flag) {
|
||||
if (!this.$common.isEmpty(c.childComments) && !this.$common.isEmpty(c.childComments.records)) {
|
||||
c.childComments.records.forEach(cc => {
|
||||
c.commentContent = c.commentContent.replace(/\n/g, '<br/>');
|
||||
cc.commentContent = this.$common.faceReg(cc.commentContent);
|
||||
cc.commentContent = this.$common.pictureReg(cc.commentContent);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
// getComments(pagination, floorComment = {}, isToPage = false) {
|
||||
// this.$http.post(this.$constant.baseURL + "/comment/listComment", pagination)
|
||||
// .then((res) => {
|
||||
// if (!this.$common.isEmpty(res.data) && !this.$common.isEmpty(res.data.records)) {
|
||||
// if (this.$common.isEmpty(floorComment)) {
|
||||
// this.comments = res.data.records;
|
||||
// pagination.total = res.data.total;
|
||||
// this.emoji(this.comments, true);
|
||||
// } else {
|
||||
// if (isToPage === false) {
|
||||
// floorComment.childComments = res.data;
|
||||
// } else {
|
||||
// floorComment.childComments.total = res.data.total;
|
||||
// floorComment.childComments.records = floorComment.childComments.records.concat(res.data.records);
|
||||
// }
|
||||
// this.emoji(floorComment.childComments.records, false);
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// .catch((error) => {
|
||||
// this.$message({
|
||||
// message: error.message,
|
||||
// type: "error"
|
||||
// });
|
||||
// });
|
||||
// },
|
||||
addGraffitiComment(graffitiComment) {
|
||||
this.submitComment(graffitiComment);
|
||||
},
|
||||
submitComment(commentContent) {
|
||||
let comment = {
|
||||
source: this.source,
|
||||
commentContent: commentContent
|
||||
};
|
||||
|
||||
this.$http.post(this.$constant.baseURL + "/comment/saveComment", comment)
|
||||
.then((res) => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '保存成功!'
|
||||
});
|
||||
this.pagination = {
|
||||
current: 1,
|
||||
size: 10,
|
||||
total: 0,
|
||||
source: this.source,
|
||||
floorCommentId: null
|
||||
}
|
||||
// this.getComments(this.pagination);
|
||||
this.getTotal();
|
||||
})
|
||||
.catch((error) => {
|
||||
this.$message({
|
||||
message: error.message,
|
||||
type: "error"
|
||||
});
|
||||
});
|
||||
},
|
||||
submitReply(commentContent) {
|
||||
let comment = {
|
||||
source: this.source,
|
||||
floorCommentId: this.floorComment.id,
|
||||
commentContent: commentContent,
|
||||
parentCommentId: this.replyComment.id,
|
||||
parentUserId: this.replyComment.userId
|
||||
};
|
||||
|
||||
let floorComment = this.floorComment;
|
||||
|
||||
this.$http.post(this.$constant.baseURL + "/comment/saveComment", comment)
|
||||
.then((res) => {
|
||||
let pagination = {
|
||||
current: 1,
|
||||
size: 5,
|
||||
total: 0,
|
||||
source: this.source,
|
||||
floorCommentId: floorComment.id
|
||||
}
|
||||
// this.getComments(pagination, floorComment);
|
||||
this.getTotal();
|
||||
})
|
||||
.catch((error) => {
|
||||
this.$message({
|
||||
message: error.message,
|
||||
type: "error"
|
||||
});
|
||||
});
|
||||
this.handleClose();
|
||||
},
|
||||
replyDialog(comment, floorComment) {
|
||||
this.replyComment = comment;
|
||||
this.floorComment = floorComment;
|
||||
this.replyDialogVisible = true;
|
||||
},
|
||||
handleClose() {
|
||||
this.replyDialogVisible = false;
|
||||
this.floorComment = {};
|
||||
this.replyComment = {};
|
||||
},
|
||||
checkPicList(){
|
||||
this.picList = JSON.parse(this.source.articleItems);
|
||||
let classname = ["","pic1","pic2","pic3"];
|
||||
if(this.picList[0].length<3)
|
||||
this.picClassname = classname[this.picList[0].length]
|
||||
else
|
||||
this.picClassname = classname[3]
|
||||
if(this.picList[0].length>9){ this.picClassname = classname[3] + " pic-overload"}
|
||||
},
|
||||
clickPicture(e){
|
||||
//获取viewer实例
|
||||
const viewer = this.$el.querySelector('.images').$viewer
|
||||
//调用show方法进行显示预览图
|
||||
viewer.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.shuoshuo-card{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 15px;
|
||||
box-sizing: border-box;
|
||||
box-shadow: 1px 1px 5px #66666655;
|
||||
max-width: 720px;
|
||||
animation-name: zoomIn;
|
||||
margin:20px auto 20px auto;
|
||||
border-radius: .5em;
|
||||
}
|
||||
.shuoshuo-topper{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
.shuoshuo-topper .shuoshuo-avatar{
|
||||
width:64px;
|
||||
height:64px;
|
||||
}
|
||||
.shuoshuo-container{
|
||||
margin-top: .6em;
|
||||
margin-bottom: .2em;
|
||||
}
|
||||
.shuoshuo-toptitle{
|
||||
margin-left: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.shuoshuo-piclist{
|
||||
width: 100%;
|
||||
position: relative;
|
||||
user-select: none;
|
||||
margin:5px 0 5px 0;
|
||||
}
|
||||
.shuoshuo-piclist a {
|
||||
list-style: none;
|
||||
cursor: zoom-in;
|
||||
}
|
||||
.shuoshuo-piclist img{
|
||||
width:100%;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.pic1 a img{
|
||||
max-height: 520px;
|
||||
max-width: 100%;
|
||||
width: unset;
|
||||
}
|
||||
.pic2 {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
width: 100%;
|
||||
}
|
||||
.pic2 a{
|
||||
flex:1;
|
||||
margin: 2px;
|
||||
}
|
||||
.pic3{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
width: 100%;
|
||||
}
|
||||
.pic3 a{
|
||||
width:33.33%;
|
||||
padding: 1px;
|
||||
position: relative;
|
||||
}
|
||||
.pic3 .imgbox{
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
padding-bottom: 56.25%;/*重要属性*/
|
||||
}
|
||||
.pic3 .imgbox img{
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.pic3.pic-overload a:nth-child(9)::after {
|
||||
content: attr(overtip);
|
||||
display: flex;
|
||||
font-size: 2.5em;
|
||||
position: absolute;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
color: #FFF;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
pointer-events: none;
|
||||
background: #00000088;
|
||||
}
|
||||
.shuoshuo-meta{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
.shuoshuo-meta span{
|
||||
margin-right: .8em;
|
||||
}
|
||||
.shuoshuo-topper span,.shuoshuo-tailer span{
|
||||
display:block;
|
||||
color:var(--greyFont);
|
||||
}
|
||||
@media screen and (max-width: 768px) {
|
||||
|
||||
.pic3 .imgbox{
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
padding-bottom: 100%;/*重要属性*/
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,62 @@
|
||||
<template>
|
||||
<div class="summary-card" data-table="SUMMARY">
|
||||
<div>{{fitem.subject.short_summary||"无简介内容"}}</div>
|
||||
<hr />
|
||||
<div>{{fitem.comment||"无个人点评"}}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {formatDate} from '../../utils/tools.js'
|
||||
export default {
|
||||
props:['fitem'],
|
||||
name: 'summary_card',
|
||||
data () {
|
||||
return {
|
||||
time:123,
|
||||
}
|
||||
},
|
||||
created(){
|
||||
|
||||
this.time = formatDate(this.fitem.time)
|
||||
},
|
||||
methods:{
|
||||
getEventBus(){
|
||||
|
||||
},
|
||||
intoAnime(){
|
||||
window.open("https://bgm.tv/subject/"+this.fitem.subject.id);
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.summary-card{
|
||||
width:240px;
|
||||
position:fixed;
|
||||
opacity: 0;
|
||||
z-index:-1;
|
||||
font-size: 14px;
|
||||
line-height: 20px;;
|
||||
box-sizing: border-box;
|
||||
padding: 8px;
|
||||
box-shadow: #00000055 5px 0px 10px;
|
||||
background-color: var(--background);
|
||||
color: var(--fontColor);
|
||||
backdrop-filter: saturate(2) blur(10px);
|
||||
border-radius: 10px;
|
||||
text-align: left;
|
||||
transition: .5s;
|
||||
}
|
||||
.summary-card.show{
|
||||
opacity: 1;
|
||||
z-index: 5;
|
||||
transition: .5s;
|
||||
}
|
||||
.summary-card:hover{
|
||||
opacity: 1 !important;
|
||||
z-index: 5 !important;
|
||||
transition: .5s;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,406 @@
|
||||
<template>
|
||||
<div>
|
||||
<loader :loading="loading">
|
||||
<!-- 加载页面 -->
|
||||
<template slot="loader">
|
||||
<div>
|
||||
<zombie></zombie>
|
||||
</div>
|
||||
</template>
|
||||
<!-- 内容页面 -->
|
||||
<template slot="body">
|
||||
<!-- 首页图片 -->
|
||||
<el-image style="animation: header-effect 2s"
|
||||
class="background-image"
|
||||
v-once
|
||||
:src="$constant.background.view_random"
|
||||
fit="cover">
|
||||
<div slot="error" class="image-slot background-image-error"></div>
|
||||
</el-image>
|
||||
<!-- 首页文字 -->
|
||||
<div class="signature-wall myCenter my-animation-hideToShow">
|
||||
<h1 class="playful">
|
||||
<span v-for="(a, index) in '💎我的空间💎'" :key="index">{{a}}</span>
|
||||
</h1>
|
||||
<div class="printer" @click="getGuShi()">
|
||||
<printer :printerInfo="printerInfo">
|
||||
<template slot="paper" slot-scope="scope">
|
||||
<h3>
|
||||
{{ scope.content }}<span class="cursor">|</span>
|
||||
</h3>
|
||||
</template>
|
||||
</printer>
|
||||
</div>
|
||||
<div id="bannerWave1"></div>
|
||||
<div id="bannerWave2"></div>
|
||||
<i class="el-icon-arrow-down" @click="navigation('.page-container-wrap')"></i>
|
||||
</div>
|
||||
<!-- 首页内容 -->
|
||||
<div class="page-container-wrap">
|
||||
<div class="page-container">
|
||||
<div class="aside-content" v-if="showAside">
|
||||
<myAside class="aside-content-myAside"></myAside>
|
||||
</div>
|
||||
<div class="recent-posts" >
|
||||
<div class="announcement background-opacity">
|
||||
<i class="fa fa-volume-up" aria-hidden="true"></i>
|
||||
<div>
|
||||
<div v-for="(notice, index) in $store.state.webInfo.notices" :key="index">
|
||||
{{ notice }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div ref="pictureList">
|
||||
|
||||
<shuoshuo v-for="item in articles" :key="item" :source = "item"></shuoshuo>
|
||||
</div>
|
||||
<!-- -->
|
||||
<div class="pagination-wrap">
|
||||
<div @click="pageArticles()" class="pagination" v-if="pagination.total !== articles.length">
|
||||
下一页
|
||||
</div>
|
||||
<div v-else style="user-select: none">
|
||||
~~到底啦~~
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 页脚 -->
|
||||
<div style="background: var(--background)">
|
||||
<myFooter></myFooter>
|
||||
</div>
|
||||
</template>
|
||||
</loader>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
const loader = () => import( "./common/loader");
|
||||
const zombie = () => import( "./common/zombie");
|
||||
const printer = () => import( "./common/printer");
|
||||
const shuoshuo = () => import( "./common/shuoshuo");
|
||||
const myFooter = () => import( "./common/myFooter");
|
||||
const myAside = () => import( "./myAside");
|
||||
|
||||
export default {
|
||||
components: {
|
||||
loader,
|
||||
zombie,
|
||||
printer,
|
||||
myFooter,
|
||||
shuoshuo,
|
||||
myAside
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
showAside: true,
|
||||
printerInfo: "你看对面的青山多漂亮",
|
||||
pagination: {
|
||||
current: 1,
|
||||
size: 10,
|
||||
total: 0,
|
||||
searchKey: ""
|
||||
},
|
||||
guShi: {
|
||||
"content": "",
|
||||
"origin": "",
|
||||
"author": "",
|
||||
"category": ""
|
||||
},
|
||||
articles: []
|
||||
};
|
||||
},
|
||||
|
||||
watch: {},
|
||||
|
||||
created() {
|
||||
this.getGuShi();
|
||||
this.getArticles();
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.$store.commit("changePlaylist", 370417370);
|
||||
},
|
||||
|
||||
methods: {
|
||||
pageArticles() {
|
||||
this.pagination.current = this.pagination.current + 1;
|
||||
this.getArticles();
|
||||
},
|
||||
|
||||
getArticles() {
|
||||
this.$http.post(this.$constant.baseURL + "/diary/listArticle", this.pagination)
|
||||
.then((res) => {
|
||||
if (!this.$common.isEmpty(res.data)) {
|
||||
this.articles = this.articles.concat(res.data.records);
|
||||
this.pagination.total = res.data.total;
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
this.$message({
|
||||
message: error.message,
|
||||
type: "error"
|
||||
});
|
||||
});
|
||||
},
|
||||
navigation(selector) {
|
||||
let pageId = document.querySelector(selector);
|
||||
window.scrollTo({
|
||||
top: pageId.offsetTop,
|
||||
behavior: "smooth"
|
||||
});
|
||||
},
|
||||
getGuShi() {
|
||||
let that = this;
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open('get', this.$constant.jinrishici);
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState === 4) {
|
||||
that.guShi = JSON.parse(xhr.responseText);
|
||||
that.printerInfo = that.guShi.content;
|
||||
}
|
||||
};
|
||||
xhr.send();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.signature-wall {
|
||||
/* 向下排列 */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
user-select: none;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.playful {
|
||||
color: var(--white);
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
/*.playful span {*/
|
||||
/* position: relative;*/
|
||||
/* color: #5362f6;*/
|
||||
/* text-shadow: 0.25px 0.25px #e485f8, 0.5px 0.5px #e485f8, 0.75px 0.75px #e485f8,*/
|
||||
/* 1px 1px #e485f8, 1.25px 1.25px #e485f8, 1.5px 1.5px #e485f8, 1.75px 1.75px #e485f8,*/
|
||||
/* 2px 2px #e485f8, 2.25px 2.25px #e485f8, 2.5px 2.5px #e485f8, 2.75px 2.75px #e485f8,*/
|
||||
/* 3px 3px #e485f8, 3.25px 3.25px #e485f8, 3.5px 3.5px #e485f8, 3.75px 3.75px #e485f8,*/
|
||||
/* 4px 4px #e485f8, 4.25px 4.25px #e485f8, 4.5px 4.5px #e485f8, 4.75px 4.75px #e485f8,*/
|
||||
/* 5px 5px #e485f8, 5.25px 5.25px #e485f8, 5.5px 5.5px #e485f8, 5.75px 5.75px #e485f8,*/
|
||||
/* 6px 6px #e485f8;*/
|
||||
/* animation: scatter 1.75s infinite;*/
|
||||
/* font-weight: normal;*/
|
||||
/*}*/
|
||||
|
||||
/*.playful span:nth-child(2n) {*/
|
||||
/* color: #ed625c;*/
|
||||
/* text-shadow: 0.25px 0.25px #f2a063, 0.5px 0.5px #f2a063, 0.75px 0.75px #f2a063,*/
|
||||
/* 1px 1px #f2a063, 1.25px 1.25px #f2a063, 1.5px 1.5px #f2a063, 1.75px 1.75px #f2a063,*/
|
||||
/* 2px 2px #f2a063, 2.25px 2.25px #f2a063, 2.5px 2.5px #f2a063, 2.75px 2.75px #f2a063,*/
|
||||
/* 3px 3px #f2a063, 3.25px 3.25px #f2a063, 3.5px 3.5px #f2a063, 3.75px 3.75px #f2a063,*/
|
||||
/* 4px 4px #f2a063, 4.25px 4.25px #f2a063, 4.5px 4.5px #f2a063, 4.75px 4.75px #f2a063,*/
|
||||
/* 5px 5px #f2a063, 5.25px 5.25px #f2a063, 5.5px 5.5px #f2a063, 5.75px 5.75px #f2a063,*/
|
||||
/* 6px 6px #f2a063;*/
|
||||
/* animation-delay: 0.3s;*/
|
||||
/*}*/
|
||||
|
||||
/*.playful span:nth-child(3n) {*/
|
||||
/* color: #ffd913;*/
|
||||
/* text-shadow: 0.25px 0.25px #6ec0a9, 0.5px 0.5px #6ec0a9, 0.75px 0.75px #6ec0a9,*/
|
||||
/* 1px 1px #6ec0a9, 1.25px 1.25px #6ec0a9, 1.5px 1.5px #6ec0a9, 1.75px 1.75px #6ec0a9,*/
|
||||
/* 2px 2px #6ec0a9, 2.25px 2.25px #6ec0a9, 2.5px 2.5px #6ec0a9, 2.75px 2.75px #6ec0a9,*/
|
||||
/* 3px 3px #6ec0a9, 3.25px 3.25px #6ec0a9, 3.5px 3.5px #6ec0a9, 3.75px 3.75px #6ec0a9,*/
|
||||
/* 4px 4px #6ec0a9, 4.25px 4.25px #6ec0a9, 4.5px 4.5px #6ec0a9, 4.75px 4.75px #6ec0a9,*/
|
||||
/* 5px 5px #6ec0a9, 5.25px 5.25px #6ec0a9, 5.5px 5.5px #6ec0a9, 5.75px 5.75px #6ec0a9,*/
|
||||
/* 6px 6px #6ec0a9;*/
|
||||
/* animation-delay: 0.15s;*/
|
||||
/*}*/
|
||||
|
||||
/*.playful span:nth-child(5n) {*/
|
||||
/* color: #555bff;*/
|
||||
/* text-shadow: 0.25px 0.25px #e485f8, 0.5px 0.5px #e485f8, 0.75px 0.75px #e485f8,*/
|
||||
/* 1px 1px #e485f8, 1.25px 1.25px #e485f8, 1.5px 1.5px #e485f8, 1.75px 1.75px #e485f8,*/
|
||||
/* 2px 2px #e485f8, 2.25px 2.25px #e485f8, 2.5px 2.5px #e485f8, 2.75px 2.75px #e485f8,*/
|
||||
/* 3px 3px #e485f8, 3.25px 3.25px #e485f8, 3.5px 3.5px #e485f8, 3.75px 3.75px #e485f8,*/
|
||||
/* 4px 4px #e485f8, 4.25px 4.25px #e485f8, 4.5px 4.5px #e485f8, 4.75px 4.75px #e485f8,*/
|
||||
/* 5px 5px #e485f8, 5.25px 5.25px #e485f8, 5.5px 5.5px #e485f8, 5.75px 5.75px #e485f8,*/
|
||||
/* 6px 6px #e485f8;*/
|
||||
/* animation-delay: 0.4s;*/
|
||||
/*}*/
|
||||
|
||||
/*.playful span:nth-child(7n) {*/
|
||||
/* color: #ff9c55;*/
|
||||
/* text-shadow: 0.25px 0.25px #ff5555, 0.5px 0.5px #ff5555, 0.75px 0.75px #ff5555,*/
|
||||
/* 1px 1px #ff5555, 1.25px 1.25px #ff5555, 1.5px 1.5px #ff5555, 1.75px 1.75px #ff5555,*/
|
||||
/* 2px 2px #ff5555, 2.25px 2.25px #ff5555, 2.5px 2.5px #ff5555, 2.75px 2.75px #ff5555,*/
|
||||
/* 3px 3px #ff5555, 3.25px 3.25px #ff5555, 3.5px 3.5px #ff5555, 3.75px 3.75px #ff5555,*/
|
||||
/* 4px 4px #ff5555, 4.25px 4.25px #ff5555, 4.5px 4.5px #ff5555, 4.75px 4.75px #ff5555,*/
|
||||
/* 5px 5px #ff5555, 5.25px 5.25px #ff5555, 5.5px 5.5px #ff5555, 5.75px 5.75px #ff5555,*/
|
||||
/* 6px 6px #ff5555;*/
|
||||
/* animation-delay: 0.25s;*/
|
||||
/*}*/
|
||||
|
||||
.printer {
|
||||
cursor: pointer;
|
||||
color: var(--white);
|
||||
background: var(--translucent);
|
||||
border-radius: 10px;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
#bannerWave1 {
|
||||
height: 84px;
|
||||
background: var(--bannerWave1);
|
||||
position: absolute;
|
||||
width: 200%;
|
||||
bottom: 0;
|
||||
z-index: 10;
|
||||
animation: gradientBG 120s linear infinite;
|
||||
}
|
||||
|
||||
#bannerWave2 {
|
||||
height: 100px;
|
||||
background: var(--bannerWave2);
|
||||
position: absolute;
|
||||
width: 400%;
|
||||
bottom: 0;
|
||||
z-index: 5;
|
||||
animation: gradientBG 120s linear infinite;
|
||||
}
|
||||
|
||||
/* 光标 */
|
||||
.cursor {
|
||||
margin-left: 1px;
|
||||
animation: hideToShow 0.7s infinite;
|
||||
font-weight: 200;
|
||||
}
|
||||
|
||||
.el-icon-arrow-down {
|
||||
font-size: 40px;
|
||||
font-weight: bold;
|
||||
color: var(--white);
|
||||
position: absolute;
|
||||
bottom: 60px;
|
||||
animation: my-shake 1.5s ease-out infinite;
|
||||
z-index: 15;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.page-container-wrap {
|
||||
background: var(--background);
|
||||
position: relative;
|
||||
transition: .5s;
|
||||
}
|
||||
|
||||
.page-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 90%;
|
||||
max-width: 1280px;
|
||||
padding: 0 20px 40px 20px;
|
||||
margin: 0 auto;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.recent-posts {
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
.announcement {
|
||||
padding: 22px;
|
||||
border: 1px dashed var(--lightGray);
|
||||
color: var(--greyFont);
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
max-width: 780px;
|
||||
margin: 40px auto 40px;
|
||||
}
|
||||
|
||||
.announcement i {
|
||||
color: var(--themeBackground);
|
||||
font-size: 22px;
|
||||
margin: auto 0;
|
||||
animation: scale 0.8s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.announcement div div {
|
||||
margin-left: 20px;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.aside-content {
|
||||
width: calc(30% - 40px);
|
||||
user-select: none;
|
||||
margin-top: 40px;
|
||||
margin-right: 40px;
|
||||
max-width: 300px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.pagination-wrap {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
padding: 13px 15px;
|
||||
border: 1px solid var(--lightGray);
|
||||
border-radius: 3rem;
|
||||
color: var(--greyFont);
|
||||
width: 100px;
|
||||
user-select: none;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
}
|
||||
.aside-content-myAside{
|
||||
position: sticky;
|
||||
top: 10px;
|
||||
}
|
||||
.pagination:hover {
|
||||
border: 1px solid var(--themeBackground);
|
||||
color: var(--themeBackground);
|
||||
box-shadow: 0 0 5px var(--themeBackground);
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1100px) {
|
||||
.recent-posts {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.page-container {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1000px) {
|
||||
|
||||
.page-container {
|
||||
/* 文章栏与侧标栏垂直排列 */
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.aside-content {
|
||||
width: 100%;
|
||||
max-width: unset;
|
||||
float: unset;
|
||||
margin: 40px auto 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
|
||||
h1 {
|
||||
font-size: 35px;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
@ -0,0 +1,200 @@
|
||||
export const getShowByIds = function (data, callback) {
|
||||
$.ajax({
|
||||
url: `/ablaze/get/works/ids/${data.point}`,
|
||||
type: "get",
|
||||
data: data,
|
||||
async: true,
|
||||
success: function (data) {
|
||||
callback(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
export const getShow = function (data, callback) {
|
||||
$.ajax({
|
||||
url: '/ablaze/get/works/'+data.point,
|
||||
type: "get",
|
||||
data: data,
|
||||
async: true,
|
||||
success: function (data) {
|
||||
callback(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
export const getComments = function (data, callback){
|
||||
$.ajax({
|
||||
url : `/ablaze/get/comments/${data.type}/${data.wid}/${data.fid}/${data.start}/${data.num}`,
|
||||
type : "get",
|
||||
async : true,
|
||||
success : function(data) {
|
||||
callback(data);
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
export const addComment = function(data, callback){
|
||||
$.ajax({
|
||||
url : `/ablaze/insert/comment`,
|
||||
type : "post",
|
||||
headers: {
|
||||
Authorization: window.localStorage.getItem("token")
|
||||
},
|
||||
data:data,
|
||||
async : true,
|
||||
success : function(data) {
|
||||
callback(data);
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
export const getWork = function(data, callback){
|
||||
$.ajax({
|
||||
url : `/ablaze/get/work/${data.point}/${data.id}`,
|
||||
type : "get",
|
||||
data:data,
|
||||
async : true,
|
||||
success : function(data) {
|
||||
callback(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param {*} data
|
||||
* @param {*} callback
|
||||
*/
|
||||
export const actWork = function(data, callback){
|
||||
$.ajax({
|
||||
url : `/ablaze/act/work/${data.point}/${data.wid}/${data.act}`,
|
||||
type : "post",
|
||||
headers: {
|
||||
Authorization: window.localStorage.getItem("token")
|
||||
},
|
||||
async : true,
|
||||
success : function(data) {
|
||||
callback(data);
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param {point,start,num,keys} data
|
||||
* @param {*} callback
|
||||
*/
|
||||
export const searchWork = function(data, callback){
|
||||
$.ajax({
|
||||
url : `/ablaze/search/works/${data.point}`,
|
||||
type : "get",
|
||||
data:data,
|
||||
async : true,
|
||||
success : function(data) {
|
||||
callback(data);
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
export const getHotKeys = function(data, callback){
|
||||
$.ajax({
|
||||
url : `/ablaze/get/keywords/${data.start}/${data.num}/${data.key}`,
|
||||
type : "get",
|
||||
async : true,
|
||||
success : function(data) {
|
||||
callback(data);
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
export const getUser = function(data,callback){
|
||||
$.ajax({
|
||||
url:`/ablaze/get/user/${data.id}`,
|
||||
type:"get",
|
||||
async: true,
|
||||
success: function (data) {
|
||||
callback(data);
|
||||
}
|
||||
})
|
||||
}
|
||||
export const setUserPassword = function(data,callback){
|
||||
$.ajax({
|
||||
url : `/ablaze/set/userpassword`,
|
||||
type : "post",
|
||||
headers: {
|
||||
Authorization: window.localStorage.getItem("token")
|
||||
},
|
||||
data:data,
|
||||
async : true,
|
||||
success : function(data) {
|
||||
callback(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
export const updateUser = function(data,callback){
|
||||
$.ajax({
|
||||
url : `/ablaze/set/user`,
|
||||
type : "post",
|
||||
headers: {
|
||||
Authorization: window.localStorage.getItem("token")
|
||||
},
|
||||
data:data,
|
||||
async : true,
|
||||
success : function(data) {
|
||||
callback(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
export const updateUserSafe = function(data,callback){
|
||||
$.ajax({
|
||||
url : `/ablaze/set/safe/user`,
|
||||
type : "post",
|
||||
headers: {
|
||||
Authorization: window.localStorage.getItem("token")
|
||||
},
|
||||
data:data,
|
||||
async : true,
|
||||
success : function(data) {
|
||||
callback(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
export const followUser = function(data,callback){
|
||||
$.ajax({
|
||||
url:`/ablaze/act/user/${data.tid}/${data.act}`,
|
||||
type:"post",
|
||||
headers: {
|
||||
Authorization: window.localStorage.getItem("token")
|
||||
},
|
||||
async: true,
|
||||
success: function (data) {
|
||||
callback(data);
|
||||
}
|
||||
})
|
||||
}
|
||||
export let bangu_getCollection = function(data,callback){
|
||||
let arr = [];
|
||||
for(var p in data){
|
||||
if(data.hasOwnProperty(p)){
|
||||
arr.push(encodeURIComponent(p)+"="+encodeURIComponent(data[p]))
|
||||
}
|
||||
};
|
||||
$.ajax({
|
||||
url:`/api/common/gethtml?url=${encodeURIComponent("https://api.bgm.tv/v0/users/607071/collections?"+arr.join("&"))}`,
|
||||
type:"get",
|
||||
dataType:'json',
|
||||
async: true,
|
||||
success: function (data) {
|
||||
callback(data);
|
||||
}
|
||||
})
|
||||
}
|
||||
export let bangu_getCollections = function(data,callback){
|
||||
$.ajax({
|
||||
url:`/ablaze/gethtml?url=https://api.bgm.tv/user/607071/collections/${data.type}?app_id=bgm191760e15e1785468`,
|
||||
type:"get",
|
||||
async: true,
|
||||
dataType:'json',
|
||||
success: function (data) {
|
||||
callback(data);
|
||||
}
|
||||
})
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
|
||||
|
||||
|
||||
export const isMobile = function(){
|
||||
var ua = navigator.userAgent;
|
||||
var ipad = ua.match(/(iPad).*OS\s([\d_]+)/),
|
||||
isIphone = /(mobile|mobi|wap|iphone)/i.test(ua),
|
||||
isAndroid = ua.match(/(Android)\s+([\d.]+)/),
|
||||
isMobile = isIphone || isAndroid;
|
||||
if(isMobile) {
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
export const navigation = function(selector) {
|
||||
let pageId = document.querySelector(selector);
|
||||
window.scrollTo({
|
||||
top: pageId.offsetTop,
|
||||
behavior: "smooth"
|
||||
});
|
||||
}
|
||||
export const formatDate = function(date) {
|
||||
var date = new Date(date);
|
||||
var YY = date.getFullYear() + '-';
|
||||
var MM = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
|
||||
var DD = (date.getDate() < 10 ? '0' + (date.getDate()) : date.getDate());
|
||||
var hh = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ':';
|
||||
var mm = (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()) + ':';
|
||||
var ss = (date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds());
|
||||
return YY + MM + DD +" "+hh + mm + ss;
|
||||
}
|
||||
export const dataURItoBlob = function(dataURI) {//图片转成Buffer
|
||||
var byteString = atob(dataURI.split(',')[1]);
|
||||
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
|
||||
var ab = new ArrayBuffer(byteString.length);
|
||||
var ia = new Uint8Array(ab);
|
||||
for (var i = 0; i < byteString.length; i++) {
|
||||
ia[i] = byteString.charCodeAt(i);
|
||||
}
|
||||
return new Blob([ab], {type: mimeString});
|
||||
}
|
@ -1,5 +1,37 @@
|
||||
module.exports = {
|
||||
devServer: {
|
||||
port: 80
|
||||
// 代理配置
|
||||
proxy: {
|
||||
'/v': {
|
||||
target: 'http://janxland.xyz/v/',
|
||||
changeOrigin: true,
|
||||
headers: {
|
||||
Host: 'www.janxland.xyz'
|
||||
},
|
||||
pathRewrite: {
|
||||
'/v': ''
|
||||
}
|
||||
},
|
||||
'/api': {
|
||||
target: 'http://janxland.xyz/ablaze/',
|
||||
changeOrigin: true,
|
||||
headers: {
|
||||
Host: 'www.janxland.xyz'
|
||||
},
|
||||
pathRewrite: {
|
||||
'/api': '/'
|
||||
}
|
||||
},
|
||||
'/mapi163/weapi': {
|
||||
target: 'http://janxland.xyz/',
|
||||
changeOrigin: true,
|
||||
headers: {
|
||||
Host: 'www.janxland.xyz'
|
||||
},
|
||||
pathRewrite: {
|
||||
'/mapi163/weapi': '/mapi163/weapi'
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in new issue