This commit is contained in:
yuyongdong 2024-04-10 11:10:07 +08:00
parent a729747776
commit a44228e09c
108 changed files with 9632 additions and 347 deletions

12
.env.development Normal file
View File

@ -0,0 +1,12 @@
# API
VUE_APP_API_URL = 'http://192.168.100.22:3006/api'
VUE_APP_WL_URL = 'https://nftwl.counterfire.games/wl_test'
VUE_APP_CONFIG_URL = 'https://sepolia.infura.io/v3/b6bf7d3508c941499b10025c0776eaf8'
# 活动ID
VUE_APP_TOKENID_ID = '0xaa36a7'
VUE_APP_AES_PASS = 'f0cbc08f7afcaa3baeae386860141d072b6840e1'
# NFT合约
VUE_APP_NFT_URL = '0x59e751c2037B710090035B6ea928e0cce80aC03f'
# BEB合约
VUE_APP_BEB_URL = '0x1304E6AA241eE3C9ea44Db9e593e85Ae76eC41F1'

12
.env.production Normal file
View File

@ -0,0 +1,12 @@
# API
VUE_APP_API_URL = 'https://oauth-svr.cebggame.com/task/'
VUE_APP_WL_URL = 'https://nftwl.counterfire.games/wl_test'
VUE_APP_CONFIG_URL = 'https://sepolia.infura.io/v3/b6bf7d3508c941499b10025c0776eaf8'
# 活动ID
VUE_APP_TOKENID_ID = '0xaa36a7'
VUE_APP_AES_PASS = 'f0cbc08f7afcaa3baeae386860141d072b6840e1'
# NFT合约
VUE_APP_NFT_URL = '0x59e751c2037B710090035B6ea928e0cce80aC03f'
# BEB合约
VUE_APP_BEB_URL = '0x1304E6AA241eE3C9ea44Db9e593e85Ae76eC41F1'

3359
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -4,14 +4,27 @@
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"serve_prod": "vue-cli-service serve --mode production",
"build": "vue-cli-service build --mode development",
"build_prod": "vue-cli-service build --mode production",
"lint": "vue-cli-service lint"
},
"dependencies": {
"@walletconnect/ethereum-provider": "^2.11.2",
"@walletconnect/modal": "^2.6.2",
"axios": "^1.6.8",
"copy-webpack-plugin": "^6.4.1",
"core-js": "^3.8.3",
"crypto-js": "^4.2.0",
"element-ui": "^2.15.14",
"js-cookie": "^3.0.5",
"moment": "^2.30.1",
"postcss-px-to-viewport": "^1.1.1",
"swiper": "^5.4.5",
"vue": "^2.6.14",
"vue-router": "^3.5.1",
"vuex": "^3.6.2"
"vuex": "^3.6.2",
"web3": "^4.5.0"
},
"devDependencies": {
"@babel/core": "^7.12.16",
@ -26,5 +39,19 @@
"sass": "^1.32.7",
"sass-loader": "^12.0.0",
"vue-template-compiler": "^2.6.14"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "@babel/eslint-parser"
},
"rules": {}
}
}

24
postcss.config.cjs Normal file
View File

@ -0,0 +1,24 @@
module.exports = {
plugins: {
'postcss-px-to-viewport': {
unitToConvert: 'px', // 需要转换的单位,默认为"px"
viewportWidth: 1920, // 设计稿的视口宽度
unitPrecision: 5, // 单位转换后保留的精度
propList: ['*'], // 能转化为vw的属性列表
viewportUnit: 'vw', // 希望使用的视口单位
fontViewportUnit: 'vw', // 字体使用的视口单位
selectorBlackList: [], // 需要忽略的CSS选择器不会转为视口单位使用原有的px等单位。
minPixelValue: 1, // 设置最小的转换数值如果为1的话只有大于1的值会被转换
mediaQuery: false, // 媒体查询里的单位是否需要转换单位
replace: true, // 是否直接更换属性值,而不添加备用属性
exclude: undefined, // 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件
include: undefined, // 如果设置了include那将只有匹配到的文件才会被转换
landscape: false, // 是否添加根据 landscapeWidth 生成的媒体查询条件 @media (orientation: landscape)
landscapeUnit: 'vw', // 横屏时使用的单位
landscapeWidth: 1920 // 横屏时使用的视口宽度
}
}
}

View File

@ -0,0 +1 @@
{"paths":{"0":["effects/builtin-2d-graphics",0],"1":["effects/builtin-2d-gray-sprite",0],"2":["effects/builtin-2d-label",0],"3":["effects/builtin-2d-spine",0],"4":["effects/builtin-2d-sprite",0],"5":["effects/builtin-3d-particle",0],"6":["effects/builtin-3d-trail",0],"7":["effects/builtin-clear-stencil",0],"8":["effects/builtin-unlit",0],"9":["materials/builtin-2d-base",1],"10":["materials/builtin-2d-graphics",1],"11":["materials/builtin-2d-gray-sprite",1],"12":["materials/builtin-2d-label",1],"13":["materials/builtin-2d-spine",1],"14":["materials/builtin-2d-sprite",1],"15":["materials/builtin-3d-particle",1],"16":["materials/builtin-3d-trail",1],"17":["materials/builtin-clear-stencil",1],"18":["materials/builtin-unlit",1]},"types":["cc.EffectAsset","cc.Material"],"uuids":["30aC+Hnw1PF4pEcoY3kUYb","14TDKXr2NJ6LjvHPops74o","f1h0LXVtJOta5JLZ1xCzfI","0ek66qC1NOQLjgYmi04HvX","28dPjdQWxEQIG3VVl1Qm6T","82migssElAGb04Ws6NimQX","2afAA24LNP4YmYiaVLiivs","c0BAyVxX9JzZy8EjFrc9DU","6dkeWRTOBGXICfYQ7JUBnG","6fgBCSDDdPMInvyNlggls2","a1U5RdJRFMFL57BdJC9H1X","3ae7efMv1CLq2ilvUY/tQi","e0LYfU5ZlNFoAB4UiRrGUG","7a/QZLET9IDreTiBfRn2PD","ecpdLyjvZBwrvm+cedCcQy","43L6CczwNM/6GGmCYEQIoH","46bU+b5fROqIXVPG6aZWWK","cffgu4qBxEqa150o1DmRAy","2aKWBXJHxKHLvrBUi2yYZQ","60AwGqM1dKELCGhPAR+jK6","02delMVqdBD70a/HSD99FK"],"scenes":{},"redirect":[],"deps":[],"packs":{"0b6c4470e":[20,3,1,4,18,6,0,11,15,16,19,8,9,13,5,10,7,17,12,14,2]},"name":"internal","importBase":"import","nativeBase":"native","debug":false,"isZip":false,"encrypted":false,"versions":{"import":["0b6c4470e","9537f"],"native":[20,"cea68",19,"c3a3a"]}}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
(function r(e,n,t){function i(u,f){if(!n[u]){if(!e[u]){var _=u.split("/");if(_=_[_.length-1],!e[_]){var p="function"==typeof __require&&__require;if(!f&&p)return p(_,!0);if(o)return o(_,!0);throw new Error("Cannot find module '"+u+"'")}u=_}var a=n[u]={exports:{}};e[u][0].call(a.exports,function(r){return i(e[u][1][r]||r)},a,a.exports,r,e,n,t)}return n[u].exports}for(var o="function"==typeof __require&&__require,u=0;u<t.length;u++)i(t[u]);return i})({},{},[]);

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

View File

@ -0,0 +1 @@
{"paths":{},"types":[],"uuids":["85Yo8ieB1L+5t4NeJAicyY","45xxgR+1tP9q/yy6jsntv7","1fpMSBIbRNrax3EZiP9dFc","9edAJWXRdE3o3xN8mQUVY5","16b718030","ecpdLyjvZBwrvm+cedCcQy","55Oj5vvJFPK6wvdzaMzvJT","c2BXIl3pVMZZ+qL/5YYFpM","8ea//Lb5hL7aI/BoWvuJUP","3bnx2WF0lM5Z8ID7iThSxL","4bBp4y08pMa554g3H5ZyUC","bbXTMIxQtCCJ42Kyg0VKRU","ea5oIts2RBQKoItkc09mUc","c1FoV8F81GfJ++wfx9nJW0","39PpowGpBHUZ/3KKKtN8aW","7a/QZLET9IDreTiBfRn2PD","35AgXTC3pIuLVnJq8/sgRL","d2TwR7NrJPSK1k/W7fhZxD"],"scenes":{"db://assets/scene/main.fire":0},"redirect":[5,0,15,0],"deps":["internal"],"packs":{"04c39efaa":[16,14,9,10,6,0,8,11,13,7,17,12],"0f7209727":[4,2,1,3]},"name":"main","importBase":"import","nativeBase":"native","debug":false,"isZip":false,"encrypted":false,"versions":{"import":["04c39efaa","f0b4c","0f7209727","e4479"],"native":[4,"dc8fa",2,"c6409",1,"cda95",3,"c7f1c"]}}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"type":"cc.Texture2D","data":"0,9729,9729,33071,33071,0,0,0|0,9729,9729,33071,33071,0,0,1|0,9729,9729,33071,33071,0,0,1|0,9729,9729,33071,33071,0,0,1"}

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 960 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 KiB

View File

@ -0,0 +1 @@
{"paths":{},"types":[],"uuids":[],"scenes":{},"redirect":[],"deps":[],"packs":{},"name":"resources","importBase":"import","nativeBase":"native","debug":false,"isZip":false,"encrypted":false,"versions":{"import":[],"native":[]}}

View File

@ -0,0 +1 @@
(function r(e,n,t){function i(u,f){if(!n[u]){if(!e[u]){var _=u.split("/");if(_=_[_.length-1],!e[_]){var p="function"==typeof __require&&__require;if(!f&&p)return p(_,!0);if(o)return o(_,!0);throw new Error("Cannot find module '"+u+"'")}u=_}var a=n[u]={exports:{}};e[u][0].call(a.exports,function(r){return i(e[u][1][r]||r)},a,a.exports,r,e,n,t)}return n[u].exports}for(var o="function"==typeof __require&&__require,u=0;u<t.length;u++)i(t[u]);return i})({},{},[]);

File diff suppressed because one or more lines are too long

144
public/cocojs/main.5e05f.js Normal file
View File

@ -0,0 +1,144 @@
window.boot = function () {
var settings = window._CCSettings;
window._CCSettings = undefined;
var onProgress = null;
var RESOURCES = cc.AssetManager.BuiltinBundleName.RESOURCES;
var INTERNAL = cc.AssetManager.BuiltinBundleName.INTERNAL;
var MAIN = cc.AssetManager.BuiltinBundleName.MAIN;
function setLoadingDisplay () {
// Loading splash scene
// var splash = document.getElementById('splash');
// var progressBar = splash.querySelector('.progress-bar span');
// onProgress = function (finish, total) {
// var percent = 100 * finish / total;
// if (progressBar) {
// progressBar.style.width = percent.toFixed(2) + '%';
// }
// };
// splash.style.display = 'block';
// progressBar.style.width = '0%';
cc.director.once(cc.Director.EVENT_AFTER_SCENE_LAUNCH, function () {
// splash.style.display = 'none';
});
}
var onStart = function () {
cc.view.enableRetina(true);
cc.view.resizeWithBrowserSize(true);
if (cc.sys.isBrowser) {
setLoadingDisplay();
}
if (cc.sys.isMobile) {
if (settings.orientation === 'landscape') {
cc.view.setOrientation(cc.macro.ORIENTATION_LANDSCAPE);
}
else if (settings.orientation === 'portrait') {
cc.view.setOrientation(cc.macro.ORIENTATION_PORTRAIT);
}
cc.view.enableAutoFullScreen([
cc.sys.BROWSER_TYPE_BAIDU,
cc.sys.BROWSER_TYPE_BAIDU_APP,
cc.sys.BROWSER_TYPE_WECHAT,
cc.sys.BROWSER_TYPE_MOBILE_QQ,
cc.sys.BROWSER_TYPE_MIUI,
cc.sys.BROWSER_TYPE_HUAWEI,
cc.sys.BROWSER_TYPE_UC,
].indexOf(cc.sys.browserType) < 0);
}
// Limit downloading max concurrent task to 2,
// more tasks simultaneously may cause performance draw back on some android system / browsers.
// You can adjust the number based on your own test result, you have to set it before any loading process to take effect.
if (cc.sys.isBrowser && cc.sys.os === cc.sys.OS_ANDROID) {
cc.assetManager.downloader.maxConcurrency = 2;
cc.assetManager.downloader.maxRequestsPerFrame = 2;
}
var launchScene = settings.launchScene;
var bundle = cc.assetManager.bundles.find(function (b) {
return b.getSceneInfo(launchScene);
});
bundle.loadScene(launchScene, null, onProgress,
function (err, scene) {
if (!err) {
cc.director.runSceneImmediate(scene);
if (cc.sys.isBrowser) {
// show canvas
var canvas = document.getElementById('GameCanvas');
canvas.style.visibility = '';
var div = document.getElementById('GameDiv');
if (div) {
div.style.backgroundImage = '';
}
console.log('Success to load scene: ' + launchScene);
}
}
}
);
};
var option = {
id: 'GameCanvas',
debugMode: settings.debug ? cc.debug.DebugMode.INFO : cc.debug.DebugMode.ERROR,
showFPS: settings.debug,
frameRate: 60,
groupList: settings.groupList,
collisionMatrix: settings.collisionMatrix,
};
cc.assetManager.init({
bundleVers: settings.bundleVers,
remoteBundles: settings.remoteBundles,
server: settings.server
});
var bundleRoot = [INTERNAL];
settings.hasResourcesBundle && bundleRoot.push(RESOURCES);
var count = 0;
function cb (err) {
if (err) return console.error(err.message, err.stack);
count++;
if (count === bundleRoot.length + 1) {
cc.assetManager.loadBundle(MAIN, function (err) {
if (!err) cc.game.run(option, onStart);
});
}
}
cc.assetManager.loadScript(settings.jsList.map(function (x) { return '/src/' + x;}), cb);
for (var i = 0; i < bundleRoot.length; i++) {
cc.assetManager.loadBundle(bundleRoot[i], cb);
}
};
if (window.jsb) {
var isRuntime = (typeof loadRuntime === 'function');
if (isRuntime) {
require('/src/settings.e6bae.js');
require('/src/cocos2d-runtime.js');
if (CC_PHYSICS_BUILTIN || CC_PHYSICS_CANNON) {
require('/src/physics.js');
}
require('/jsb-adapter/engine/index.js');
}
else {
require('/src/settings.e6bae.js');
require('/src/cocos2d-jsb.js');
if (CC_PHYSICS_BUILTIN || CC_PHYSICS_CANNON) {
require('/src/physics.js');
}
require('/jsb-adapter/jsb-engine.js');
}
cc.macro.CLEANUP_IMAGE_CACHE = true;
window.boot();
}

View File

@ -0,0 +1 @@
window._CCSettings={platform:"web-mobile",groupList:["default"],collisionMatrix:[[true]],hasResourcesBundle:true,hasStartSceneBundle:false,remoteBundles:[],subpackages:[],launchScene:"db://assets/scene/main.fire",orientation:"",jsList:[],bundleVers:{internal:"1b082",resources:"1b2f5",main:"ab450"}};

View File

@ -13,5 +13,62 @@
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
<script src="https://www.google.com/recaptcha/api.js?render=6Ld3xoIpAAAAABW7f5ImgAC6GcWLeDCbt5HPXqe2"></script>
<script th:inline="javascript">
/**
* 加载外部js
*/
var loadSingleScript = function (src, isModule) {
return new Promise((resolve, reject) => {
console.log(`>> begin load script: ${src}`);
let s = document.createElement('script');
s.async = true;
if (isModule)s.type = 'module';
s.src =src;
s.addEventListener('load', function () {
console.log(`<< finish load script: ${src}`);
s.parentNode.removeChild(s);
s.removeEventListener('load', arguments.callee, false);
resolve && resolve();
}, false);
document.body.appendChild(s);
})
};
var scripts = [
'/cocojs/main.5e05f.js',
'/cocojs/cocos2d-js-min.1ced2.js',
'/cocojs/settings.e6bae.js',
]
var loadScripts = function (list, refresh = false) {
var loaded = 0;
return new Promise((resolve, reject) => {
var loadNext = function () {
var current = list[loaded];
var src = current;
var isModule = false;
if (typeof current === 'object' && current instanceof Array) {
src = current[0];
isModule = current.length > 1 && current[1] == 1
}
if (refresh) {
src = src + (src.indexOf("?") == -1 ? "?" : "&") + "t=" + Date.now();
}
loadSingleScript(src, isModule).then(() => {
if (++loaded >= list.length) {
resolve && resolve();
} else {
return loadNext();
}
})
};
loadNext();
})
};
window.loadGame = function(cb){
loadScripts(scripts, false).then(()=>{cb();});
}
</script>
</body>
</html>

View File

@ -1,9 +1,9 @@
<template>
<div id="app">
<nav>
<!-- <nav>
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</nav>
</nav> -->
<router-view/>
</div>
</template>
@ -13,20 +13,99 @@
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
height: 100vh;
text-align: center;
color: #2c3e50;
background: #0f1013;
}
.grecaptcha-badge {
display: none !important
}
nav {
padding: 30px;
html,
body,
div,
span,
object,
iframe,
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote,
pre,
abbr,
address,
cite,
code,
del,
dfn,
em,
img,
ins,
kbd,
q,
samp,
small,
strong,
sub,
sup,
var,
b,
i,
dl,
dt,
dd,
ol,
ul,
li,
fieldset,
form,
label,
legend,
table,
caption,
tbody,
tfoot,
thead,
tr,
th,
td,
article,
aside,
canvas,
details,
figcaption,
figure,
footer,
header,
hgroup,
menu,
nav,
section,
summary,
time,
mark,
audio,
video {
margin: 0;
a {
font-weight: bold;
color: #2c3e50;
padding: 0;
&.router-link-exact-active {
color: #42b983;
}
}
border: 0;
outline: 0;
font-size: 100%;
vertical-align: baseline;
background: transparent;
list-style: none;
text-align: center;
}
</style>

BIN
src/assets/box/box01.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

BIN
src/assets/box/box02.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

BIN
src/assets/box/box03.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

BIN
src/assets/box/box04.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 KiB

BIN
src/assets/common/Box.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
src/assets/common/Box9.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 630 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 521 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 460 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 394 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 516 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 405 B

BIN
src/assets/common/P1-up.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
src/assets/common/P1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

BIN
src/assets/common/P2-up.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
src/assets/common/P2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

BIN
src/assets/common/P3-up.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
src/assets/common/P3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
src/assets/common/P4-up.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
src/assets/common/P4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
src/assets/home/Button.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 280 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

BIN
src/assets/home/Done.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
src/assets/home/Glow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
src/assets/home/Icon_.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 B

BIN
src/assets/home/Laag 5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
src/assets/home/Missed.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
src/assets/home/box.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 731 B

BIN
src/assets/home/discord.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 726 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
src/assets/home/twitter.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 624 B

BIN
src/assets/home/youtube.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

20
src/assets/text/text.css Normal file
View File

@ -0,0 +1,20 @@
@font-face {
font-family: 'Anton-Regular';
font-style: normal;
font-weight: 600;
src: url('./Anton-Regular.ttf') format('truetype');
}
@font-face {
font-family: 'Poppins-SemiBold';
font-style: normal;
font-weight: 600;
src: url('./Poppins-SemiBold.ttf') format('truetype');
}
@font-face {
font-family: 'Poppins-Light';
font-style: normal;
font-weight: 600;
src: url('./Poppins-Regular.ttf') format('truetype');
}

View File

@ -1,60 +0,0 @@
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<p>
For a guide and recipes on how to configure / customize this project,<br>
check out the
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
</p>
<h3>Installed CLI Plugins</h3>
<ul>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router" target="_blank" rel="noopener">router</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-vuex" target="_blank" rel="noopener">vuex</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
</ul>
<h3>Essential Links</h3>
<ul>
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
</ul>
<h3>Ecosystem</h3>
<ul>
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
</ul>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>

View File

@ -0,0 +1,106 @@
<template>
<div @click="getWalletConnected">{{ text }}</div>
</template>
<script>
import Web3 from 'web3';
import { getWalletAddress } from './../../wallet/index.js'
import { loginNonce, hexToBase58, aesEncrypt, loginWithSignature } from './../../utils/webapi.js'
import { SiweMessage } from './../../utils/siwe.js'
import { GlobalData } from './../../utils/GlobalData.js'
import { parseTokenData } from './../../utils/utils.js'
export default {
props: {
text: String
},
data() {
return {
myAddress: null,
activity: 'uaw_activity',
token: null,
}
},
mounted() {},
methods: {
//
async getWalletConnected() {
const provider = window.ethereum;
let ethereum = window.ethereum;
var web3 = new Web3(provider);
if (ethereum) {
ethereum.request({ method: "eth_requestAccounts" });
this.myAddress = await getWalletAddress();
const address = web3.utils.toChecksumAddress(this.myAddress);
localStorage.setItem("myAddress", address);
let chainId = await web3.eth.getChainId();
chainId = parseInt(chainId);
// console.log(chainId, "----");
const nonce = await loginNonce(address);
// console.log(nonce, "nonce-------------");
const nonceStr = `${nonce}|okx`;
const nonceEncrypt = hexToBase58(
aesEncrypt(nonceStr, "uaw_activity")
);
const message = new SiweMessage({
domain: document.location.host,
address: address,
chainId,
uri: document.location.origin,
version: "1",
statement: "Tasks test",
nonce: nonceEncrypt
});
let msgSign = message.toMessage();
let signature = await provider.request({
method: "personal_sign",
params: [web3.utils.utf8ToHex(msgSign), address]
});
let resLogin = await loginWithSignature(
message,
signature,
this.activity
);
console.log(resLogin.errcode,'61')
if (!resLogin.errcode) {
new GlobalData().token = resLogin.data.token;
this.token = resLogin.data.token;
localStorage.setItem("token", resLogin.data.token);
localStorage.setItem(
`${this.TOKEN_KEY}+ ${address}`,
resLogin.data.token
);
// console.log(resLogin.data.token);
// console.log(parseTokenData(resLogin.data.token),'------------------');
this.getUserState(resLogin.data.token)
}
} else {
console.log("Please install the MetaMask plugin");
}
},
//
getUserState(token) {
this.$axios.get('/api/user/state',{ params: '',
headers: { Authorization: `Bearer ${token}` },
}).then(res => {
localStorage.setItem('userData', JSON.stringify(res.data.data))
location.reload()
})
},
logOut() {
let NewTime = new Date()
console.log(NewTime,'------NewTime');
}
}
}
</script>
<style lang="scss" scoped>
div {
cursor: pointer;
}
</style>

View File

@ -0,0 +1,72 @@
<template>
<div class="pagination">
<el-pagination
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-size="pageSize"
layout="prev, pager, next"
:total="total"
/>
</div>
</template>
<script>
export default {
data() {
return {
total: 50,
pageSize: 10,
currentPage: 1,
}
},
mounted() {},
methods: {
handleCurrentChange(val) {
console.log(val)
},
},
}
</script>
<style lang="scss" scoped>
.pagination {
::v-deep .el-pagination {
font-size: 12px;
.el-icon-arrow-left:before {
content: "上一页";
font-size: 12px;
}
.el-icon-arrow-right:before {
content: "下一页";
font-size: 12px;
}
button {
height: 20px;
}
.el-pager {
li {
min-width: 20px;
height: 20px;
line-height: 20px;
font-size: 12px;
margin: 0 5px;
border-radius: 50%;
border: 1px solid #f0f0f0;
}
li.active {
font-size: 12px;
background: #db9c21;
border: 1px solid #000;
color: #000;
}
.more {
&::before {
line-height: 20px;
}
}
}
}
}
</style>

View File

@ -0,0 +1,361 @@
<template>
<div class>
<el-dialog class="dialog-wallet" :visible.sync="walletDialogVisible" :modal="false" :before-close="handleClose">
<div class="dialog-header">
<div>Please connect your wallet</div>
<div @click="handleClose">
<img src="./../../assets/home/close_btn.png" alt />
</div>
</div>
<div class="dialog-content">
<p>Connect your wallet to start your Counter Fire journey</p>
<div class="wallet-content" v-if="isWallet != null">
<li v-for="(item, index) in walletList" :key="index" @click="getLinkWallet(item.value)">
<div class="disconnect" v-if="index == 2">
<span>{{ item.name }}</span>
</div>
<div v-else>
<img :src="item.imgUrl" alt />
<span>{{ item.name }}</span>
</div>
</li>
</div>
<div class="wallet-content" v-else>
<li
v-for="(item, index1) in isWalletList"
:key="index1"
@click="getLinkWallet(item.value)"
>
<div>
<img :src="item.imgUrl" alt />
<span>{{ item.name }}</span>
</div>
</li>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
import Web3 from 'web3';
import { loginNonce, hexToBase58, aesEncrypt, loginWithSignature } from './../../utils/webapi.js'
import { isWalletConnected, linkWallet, disconnectLink, addNetwork } from './../../wallet/index.js';
import { SiweMessage } from './../../utils/siwe.js'
import { GlobalData } from './../../utils/GlobalData.js'
import { parseTokenData } from './../../utils/utils.js'
import { setToken, getToken } from './../../utils/cookies.js'
export default {
props: {
walletDialogVisible: Boolean,
},
data() {
return {
walletList: [
{
name: "MetaMask",
value: "ethereum",
imgUrl: require("./../../assets/home/icon_metaMask.png")
},
{
name: "OKXwallet",
value: "okxwallet",
imgUrl: require("./../../assets/home/icon_OKXwallet.png")
// },
// {
// name: "WalletConnect",
// value: "connect",
// imgUrl: require("./../../assets/home/icon_ConnectWallet.png")
},
{
name: "Disconnect",
value: "disconnect"
}
],
isWalletList: [
{
name: "MetaMask",
value: "ethereum",
imgUrl: require("./../../assets/home/icon_metaMask.png")
},
{
name: "OKXwallet",
value: "okxwallet",
imgUrl: require("./../../assets/home/icon_OKXwallet.png")
// },
// {
// name: "WalletConnect",
// value: "connect",
// imgUrl: require("./../../assets/home/icon_ConnectWallet.png")
}
],
isWallet: localStorage.getItem('walletName'),
myAddress: '',
activity: 'uaw_activity',
};
},
mounted() {
},
methods: {
//
async getLinkWallet(val) {
await addNetwork(val)
// return
if(localStorage.getItem('walletName')) {
let res = await linkWallet(val)
this.myAddress = res
localStorage.setItem('walletName',val)
localStorage.setItem('myAddress',res)
this.handleClose()
this.getWalletConnected()
} else {
disconnectLink(val)
if(val == 'connect') {
this.handleClose()
let res = await linkWallet(val)
localStorage.setItem('walletName',val)
localStorage.setItem('myAddress',res)
this.myAddress = res
} else if(val == "disconnect") {
this.logOut()
} else {
let res = await linkWallet(val)
this.handleClose()
localStorage.setItem('walletName',val)
localStorage.setItem('myAddress',res)
this.myAddress = res
await this.getWalletConnected()
}
}
},
//
async getWalletConnected() {
const provider = window.ethereum;
let ethereum = window.ethereum;
var web3 = new Web3(provider);
if (ethereum) {
if(localStorage.getItem("walletName") == 'ethereum') {
ethereum.request({ method: "eth_requestAccounts" });
} else if(localStorage.getItem("walletName") == 'okxwallet') {
okxwallet.request({ method: "eth_requestAccounts" });
console.log('这里')
}
const address = web3.utils.toChecksumAddress(this.myAddress);
// return
let chainId = await web3.eth.getChainId();
chainId = parseInt(chainId);
// console.log(chainId, "----");
const nonce = await loginNonce(address);
// console.log(nonce, "nonce-------------");
const nonceStr = `${nonce}|okx`;
const nonceEncrypt = hexToBase58(
aesEncrypt(nonceStr, "uaw_activity")
);
const message = new SiweMessage({
domain: document.location.host,
address: address,
chainId,
uri: document.location.origin,
version: "1",
statement: "Tasks test",
nonce: nonceEncrypt
});
let msgSign = message.toMessage();
let signature = await provider.request({
method: "personal_sign",
params: [web3.utils.utf8ToHex(msgSign), address]
});
let resLogin = await loginWithSignature(
message,
signature,
this.activity
);
console.log(resLogin.errcode,'61')
if (!resLogin.errcode) {
new GlobalData().token = resLogin.data.token;
this.token = resLogin.data.token;
localStorage.setItem("token", resLogin.data.token);
localStorage.setItem(
`${this.TOKEN_KEY}+ ${address}`,
resLogin.data.token
);
setToken(resLogin.data.token)
// console.log(resLogin.data.token);
console.log(parseTokenData(resLogin.data.token),'------------------');
this.getUserState(resLogin.data.token)
}
} else {
console.log("Please install the MetaMask plugin");
}
},
//
getUserState(token) {
this.$axios.get('/api/user/state',{ params: '',
headers: { Authorization: `Bearer ${token}` },
}).then(res => {
localStorage.setItem('userData', JSON.stringify(res.data.data))
location.reload()
})
},
//
handleClose() {
this.$emit("closeDialog");
},
async isWallet1() {
let res = await isWalletConnected()
console.log('isWalletConnected' ,res)
},
// token
setCookie(exdays) {
setToken('1')
console.log(getToken())
return
var exdate = new Date(); //
exdate.setTime(exdate.getTime() + 24 * 60 * 60 * 1000 * exdays); //
//cookie
// window.document.cookie =
// "userName" + "=" + 'time' + ";path=/;expires=" + exdate.toGMTString();
// window.document.cookie =
// "userPwd" + "=" + c_pwd + ";path=/;expires=" + exdate.toGMTString();
// window.document.cookie =
// "rememeber" +
// "=" +
// c_rememeber +
// ";path=/;expires=" +
// exdate.toGMTString();
},
//cookie
getCookie() {
console.log(document.cookie,'document.cookie-------------------------------------------------------')
// if (document.cookie.length > 0) {
// var arr = document.cookie.split("; "); //
// for (var i = 0; i < arr.length; i++) {
// var arr2 = arr[i].split("="); //
// //
// if (arr2[0] === "userName") {
// this.loginForm.email = arr2[1]; //
// } else if (arr2[0] === "userPwd") {
// this.loginForm.password = arr2[1];
// } else if (arr2[0] === "rememeber") {
// this.loginForm.isRememeber = arr2[1] !== true;
// }
// }
// }
},
//cookie
clearCookie: function () {
this.setCookie("", -1); //21
// localStorage.clear()
},
// 退
logOut() {
localStorage.removeItem('userData')
localStorage.removeItem('myAddress')
localStorage.removeItem('token')
localStorage.removeItem('walletName')
// location.reload()
},
}
};
</script>
<style lang="scss" scoped>
div {
.dialog-wallet {
::v-deep .el-dialog {
width: 600px;
border-radius: 20px;
overflow: hidden;
background: #2d2738;
.el-dialog__header {
// display: none;
padding: 0;
button {
display: none;
}
}
.el-dialog__body {
padding: 0;
color: #fff;
.dialog-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 30px;
height: 60px;
line-height: 60px;
background: #1c1725;
border-radius: 20px 20px 0 0;
font-size: 26px;
font-family: "Anton";
div {
display: flex;
justify-content: space-between;
align-items: center;
img {
width: 30px;
height: 30px;
cursor: pointer;
}
}
}
.dialog-content {
background: #2d2738;
padding: 0 30px;
padding-bottom: 20px;
p {
text-align: left;
padding: 20px 0;
font-size: 16px;
}
.wallet-content {
li {
display: flex;
align-items: center;
margin: 20px 0;
cursor: pointer;
border: 2px solid #625a6b;
border-radius: 8px;
text-align: left;
padding: 15px 30px;
div {
display: flex;
align-items: center;
img {
width: 40px;
height: 40px;
}
span {
margin-left: 20px;
font-size: 24px;
}
}
&:hover {
background: #d5befa;
color: #000;
border: 2px solid #d5befa;
}
}
li:nth-child(3) {
background: #d5befa;
.disconnect {
text-align: center;
margin: 0 auto;
color: #000;
}
}
}
}
}
}
}
}
</style>

View File

@ -2,11 +2,27 @@ import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import './assets/text/text.css'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import moment from 'moment'
import axios from 'axios'
Vue.prototype.$axios = axios
// import Web3 from 'web3'
Vue.use(ElementUI)
import {Message} from 'element-ui'
Vue.prototype.$message = Message
Vue.filter('formatDate', function (value) {
return moment(value).format('YYYY-MM-DD HH:mm:ss')
})
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
render: h => h(App),
}).$mount('#app')

View File

@ -10,6 +10,11 @@ const routes = [
name: 'home',
component: HomeView
},
{
path: '/home/:name/:box/:boxId',
name: 'home',
component: HomeView
},
{
path: '/about',
name: 'about',

9
src/utils/GlobalData.js Normal file
View File

@ -0,0 +1,9 @@
export class GlobalData {
token = ''
constructor() {
if (GlobalData.instance) {
return GlobalData.instance;
}
GlobalData.instance = this;
}
}

111
src/utils/chainapi.js Normal file
View File

@ -0,0 +1,111 @@
const targetAddress = '0x50A8e60041A206AcaA5F844a1104896224be6F39';
import Web3 from 'web3'
// 签到
export const sendDailyCheckIn = async (address) => {
// const web3 = Web3;
// console.log( web3.utils.utf8ToHex(dataStr))
// return
const dataStr = 'data:,{"p":"cf-20","op":"check"}';
const data = Web3.utils.utf8ToHex(dataStr)
const provider = new Web3(window.ethereum);
let gasPrice = await provider.eth.getGasPrice()
gasPrice = gasPrice * 2n
// const gasPrice = 100000000n;
console.log('gasPrice: ',gasPrice)
// return
let sendObj = {
from: address,
to: targetAddress,
value: '0x0',
data
}
let gasLimit = await provider.eth.estimateGas(sendObj)
console.log('gasLimit: ', gasLimit,sendObj)
Object.assign(sendObj, {gasPrice, gasLimit})
return provider.eth.sendTransaction(sendObj)
}
// 开宝箱
export const sendOpenChest = async (address, chestId) => {
// const web3 = window.w3;
const openChestStr = `data:,{"p":"cf-20","op":"chest_open","id":"${chestId}"}`
const data = Web3.utils.utf8ToHex(openChestStr)
const provider = new Web3(window.ethereum);
let gasPrice = await provider.eth.getGasPrice() * 2n
// const gasPrice = 100000000n;
console.log('gasPrice: ',gasPrice)
let sendObj = {
from: address,
to: targetAddress,
value: '0x0',
data
}
let gasLimit = await provider.eth.estimateGas(sendObj)
console.log('gasLimit: ', gasLimit)
Object.assign(sendObj, {gasPrice, gasLimit})
return provider.eth.sendTransaction(sendObj)
}
// 领积分
export const sendClaimTask = async (address, taskId) => {
const openClaimTaskStr = `data:,{"p":"cf-20","op":"task_claim","val":"${taskId}"}`
const data = Web3.utils.utf8ToHex(openClaimTaskStr)
const provider = new Web3(window.ethereum);
console.log(provider)
let gasPrice = await provider.eth.getGasPrice() * 2n
// const gasPrice = 100000000n;
console.log('gasPrice: ',gasPrice)
let sendObj = {
from: address,
to: targetAddress,
value: '0x0',
data
}
let gasLimit = await provider.eth.estimateGas(sendObj)
console.log('gasLimit: ', gasLimit)
Object.assign(sendObj, {gasPrice, gasLimit})
return provider.eth.sendTransaction(sendObj)
}
// 探索
export const sendExplore = async (address, explore_id) => {
const openCExploreStr = `data:,{"p":"cf-20","op":"explore","val":"${explore_id}"}`
const data = Web3.utils.utf8ToHex(openCExploreStr)
const provider = new Web3(window.ethereum);
let gasPrice = await provider.eth.getGasPrice() * 2n
// const gasPrice = 100000000n;
console.log('gasPrice: ',gasPrice)
let sendObj = {
from: address,
to: targetAddress,
value: '0x0',
data
}
let gasLimit = await provider.eth.estimateGas(sendObj)
console.log('gasLimit: ', gasLimit)
Object.assign(sendObj, {gasPrice, gasLimit})
return provider.eth.sendTransaction(sendObj)
}
// 助力
export const sendHelp = async (address, shareCode) => {
const openHelpStr = `data:,{"p":"cf-20","op":"chest_enhance","val":"${shareCode}"}`
const data = Web3.utils.utf8ToHex(openHelpStr)
const provider = new Web3(window.ethereum);
let gasPrice = await provider.eth.getGasPrice() * 2n
// const gasPrice = 100000000n;
console.log('gasPrice: ',gasPrice)
let sendObj = {
from: address,
to: targetAddress,
value: '0x0',
data
}
let gasLimit = await provider.eth.estimateGas(sendObj)
console.log('gasLimit: ', gasLimit)
Object.assign(sendObj, {gasPrice, gasLimit})
return provider.eth.sendTransaction(sendObj)
}

14
src/utils/cookies.js Normal file
View File

@ -0,0 +1,14 @@
import Cookies from 'js-cookie'
const TokenKey = 'Admin-Token'
export function getToken() {
return Cookies.get(TokenKey)
}
export function setToken(token) {
return Cookies.set(TokenKey, token,{expires: 1,path: ""})
}
export function removeToken() {
return Cookies.remove(TokenKey)
}

49
src/utils/siwe.js Normal file
View File

@ -0,0 +1,49 @@
export class SiweMessage {
constructor(param) {
Object.assign(this, param);
}
toMessage() {
const header = `${this.domain} wants you to sign in with your Ethereum account:`;
const uriField = `URI: ${this.uri}`;
let prefix = [header, this.address].join('\n');
const versionField = `Version: ${this.version}`;
const chainField = `Chain ID: ` + this.chainId || '1';
const nonceField = `Nonce: ${this.nonce}`;
const suffixArray = [uriField, versionField, chainField, nonceField];
this.issuedAt = this.issuedAt || new Date().toISOString();
suffixArray.push(`Issued At: ${this.issuedAt}`);
if (this.expirationTime) {
const expiryField = `Expiration Time: ${this.expirationTime}`;
suffixArray.push(expiryField);
}
if (this.notBefore) {
suffixArray.push(`Not Before: ${this.notBefore}`);
}
if (this.requestId) {
suffixArray.push(`Request ID: ${this.requestId}`);
}
if (this.resources) {
suffixArray.push(
[`Resources:`, ...this.resources.map(x => `- ${x}`)].join('\n')
);
}
const suffix = suffixArray.join('\n');
prefix = [prefix, this.statement].join('\n\n');
if (this.statement) {
prefix += '\n';
}
return [prefix, suffix].join('\n');
}
}

14
src/utils/utils.js Normal file
View File

@ -0,0 +1,14 @@
export const parseTokenData = (token) =>{
if (!token) {
return {};
}
let datas = token.split(".");
if (datas.length < 2) {
return {};
}
try {
return JSON.parse(atob(datas[1]));
} catch (err) {
return {};
}
}

211
src/utils/webapi.js Normal file
View File

@ -0,0 +1,211 @@
const API_BASE = 'http://192.168.100.22:3006'
import CryptoJS from 'crypto-js'
import axios from 'axios'
const toJson = res => res.json();
const token = localStorage.getItem('token')
const httpPost = async (url, data) => {
let headers = {"Content-Type": "application/json"};
// let token = token;
if (token) {
headers['Authorization'] = `Bearer ${token}`;
}
return fetch(url, {
method: "POST",
body: JSON.stringify(data),
headers
}).then(toJson);
}
const base58Alphabet = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
export const hexToBase58 = (hexString) => {
const bytes = hexString.match(/.{1,2}/g).map(byte => parseInt(byte, 16));
let base58String = '';
let num = BigInt('0x' + hexString);
while (num > 0n) {
const remainder = num % 58n;
num = num / 58n;
base58String = base58Alphabet[Number(remainder)] + base58String;
}
return base58String;
}
export const aesEncrypt = (plaintText, key) => {
key = CryptoJS.SHA1(key).toString().substring(0,16)
key = CryptoJS.enc.Base64.parse(key)
let encryptedData = CryptoJS.AES.encrypt(plaintText, key, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
return encryptedData.toString(CryptoJS.format.Hex);
}
export const loginNonce = async (address) => {
const nonceRes = await fetch(`${API_BASE}/api/wallet/nonce?address=${address}`).then(toJson);
const { nonce } = nonceRes.data;
return nonce;
}
export const loginWithSignature = async (message, signature, activity) => {
return fetch(`${API_BASE}/api/wallet/login`, {
method: "POST",
body: JSON.stringify({ message, signature, activity }),
headers: {
"Content-Type": "application/json",
},
}).then(toJson);
}
export const beginPost = async (activity) => {
return fetch(`${API_BASE}/api/tasks/begin_task`, {
method: "POST",
body: JSON.stringify({ activity }),
headers: {
"Content-Type": "application/json",
},
}).then(toJson);
}
/**
* past 方法
* @param {string} url [请求地址]
* @param {object} params [请求参数]
*/
function post(url, params) {
return new Promise((resolve, reject) => {
axios
.post(url, QS.stringify(params))
.then((res) => {
resolve(res.data);
})
.catch((err) => {
reject(err.data);
});
});
}
// export async function apiBeginActivity( data) {
// axios.post('/api/tasks/begin_task',{ params: data,
// headers: { Authorization: `Bearer ${token}` },
// }).then(res => {
// return res.data.data
// })
// }
// export async function apiCheckActivity( data) {
// console.log(data)
// axios.get('/api/tasks/check_task',{ params: {task: data},
// headers: { Authorization: `Bearer ${token}` },
// }).then(res => {
// return res.data.data
// })
// }
// 开始任务
export const apiBeginActivity = async (task) => {
const url = `${API_BASE}/api/tasks/begin_task`;
return httpPost(url, { task })
}
// 检查任务状态
export const apiCheckActivity = async (task) => {
const url = `${API_BASE}/api/tasks/check_task`;
return httpPost(url, { task })
}
// 查看任务进度
export const apiProgress = async () => {
const url = `${API_BASE}/api/tasks/progress`;
return httpPost(url, { })
}
// 领取奖励
export const apiTaskClaim = async (task) => {
const url = `${API_BASE}/api/tasks/claim`;
return httpPost(url, { task })
}
// 用户状态
export const apiUserState = async () => {
const url = `${API_BASE}/api/user/state`;
return httpPost(url, { })
}
// 探索状态
export const apiGameStat = async () => {
const url = `${API_BASE}/api/game/stat`;
return httpPost(url, { })
}
// 开启地图
export const apiUsercheckin = async () => {
const url = `${API_BASE}/api/user/checkin`;
return httpPost(url, { })
}
// 探索
export const apiGameStep = async (id) => {
const url = `${API_BASE}/api/game/step`;
return httpPost(url, { id })
}
// 签到列表
export const apiCheckin = async () => {
const url = `${API_BASE}/api/user/checkin/list/tag`;
return httpPost(url, { })
}
// 连续签到奖励
export const apiCheckinClaimSeq = async (days) => {
const url = `${API_BASE}/api/user/checkin/claim_seq`;
return httpPost(url, { days })
}
// 累计签到奖励
export const apiCheckinClaim = async (days) => {
const url = `${API_BASE}/api/user/checkin/claim`;
return httpPost(url, { days })
}
// 积分排行榜
export const apiLeaderBoard = async (data) => {
const url = `${API_BASE}/api/activity/leaderboard/${data.activity}/${data.page}`;
return httpPost(url, { })
}
// 宝箱列表
export const apiBoxList = async () => {
const url = `${API_BASE}/api/chest/list`;
return httpPost(url, { })
}
export const checkReCaptcha = async(action) =>{
console.log(action)
const site_key = '6Ld3xoIpAAAAABW7f5ImgAC6GcWLeDCbt5HPXqe2'
return new Promise((resolve,reject) => {
window.grecaptcha.ready(function() {
window.grecaptcha.execute(site_key, { action }).then(function(token) {
resolve && resolve(token)
}).catch(e => {
reject && reject(e)
})
});
})
}
// 转发推特
export const retweetTwitter = async(desc) => {
const url = 'https://twitter.com/intent/tweet?text=';
const hashtags = encodeURIComponent(`${desc}`);
// const imageUrl = encodeURIComponent(`https://opensea.io/assets/ethereum/0xec23679653337d4c6390d0eeba682246a6067777/${this.NFTID}`);
// const params = `${hashtags}&url=${imageUrl}`;
const params = `${hashtags}`;
window.open(`${url}${params}`, '_blank');
}

View File

@ -1,18 +1,237 @@
<template>
<div class="home">
<img alt="Vue logo" src="../assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
<div class="carousel">
<Home />
<!-- <Zillionaire ref="zillionaireRef" v-model="currentIndex" /> -->
<!-- <div class="swiper-container" ref="mySwiper" @slideChange="handleSlideChange">
<div class="swiper-wrapper">
<div class="swiper-slide">
<Home />
</div>
<div class="swiper-slide">
<Bonus @click="dialogVisible = true" />
</div>
<div class="swiper-slide">
<Ranking />
</div>
</div>
<div class="swiper-pagination"></div>
</div> -->
</div>
<!-- <Zillionaire ref="zillionaireRef" v-model="currentIndex" /> -->
<!-- <div class="navigation">
<li :style="`${bgCor};`" class @click="toSwiper(0)"></li>
<li @click="toSwiper(1)"></li>
<li @click="toSwiper(2)"></li>
</div> -->
<!-- 登录 -->
<div class="login" v-if="isLogin">
<div class="login-header">
<span @click="isLogin = false"><i class="el-icon-error"></i></span>
</div>
<div class="login-content">
登录钱包账号
</div>
<div class="login-btn">
<span @click="isLogin = false">取消</span>
<span class="submit">
<LinkBtn text="登录" />
</span>
</div>
</div>
</div>
</template>
<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue'
// import HelloWorld from '@/components/HelloWorld.vue'
import Home from "./home/index.vue";
import Bonus from "./bonus/index.vue";
import Ranking from "./ranking/index.vue";
import LinkBtn from './../components/linkButton/linkBtnView.vue'
import Swiper from "swiper";
import "swiper/css/swiper.css";
export default {
name: 'HomeView',
name: "HomeView",
components: {
HelloWorld
Home,
Bonus,
Ranking,
LinkBtn
// HelloWorld
},
data() {
return {
showIndex: 0,
isLogin: true,
};
},
computed: {
bgCor() {
// if(this.activeIndex == 1) {
// console.log(this.activeIndex)
// return `background: #87uy67`
// }
}
},
created() {},
mounted() {
if(localStorage.getItem('token')) {
this.isLogin = false
}
this.$nextTick(() => {
this.onSwiper();
});
},
methods: {
onSwiper() {
new Swiper(this.$refs.mySwiper, {
autoHeight: true, //
initialSlide: this.showIndex,
direction: "vertical", //
// mousewheel: true, //
createElements: true, //
pagination: {
el: ".swiper-pagination",
clickable: true,
renderBullet: function(index, className) {
return '<span class="' + className + '">' + (index + 1) + "</span>";
}
},
ashNavigation: {
watchState: true
}
});
},
toSwiper(index) {
this.showIndex = index;
this.$nextTick(() => {
this.onSwiper();
});
console.log(index);
},
handleSlideChange() {
const activeIndex = this.$refs.mySwiper.Swiper;
console.log(activeIndex, "-------------------------------");
}
}
};
</script>
<style lang="scss" scoped>
.home {
// position: relative;
height: 100%;
.carousel {
width: 100%;
height: 100%;
color: #000;
// padding-right: 60px;
box-sizing: border-box;
::v-deep .swiper-container {
width: 100%;
height: 100vh;
.swiper-wrapper {
width: 100%;
height: 100%;
.swiper-slide {
width: 100%;
height: 100%;
z-index: -1;
}
}
.swiper-pagination {
position: fixed;
top: 51.5%;
right: 30px;
transform: translateY(-50%);
z-index: 9999;
.swiper-pagination-bullet {
display: block;
width: 30px;
height: 30px;
margin-top: 30px;
background: none;
}
}
}
}
.navigation {
width: 30px;
height: 100px;
position: fixed;
top: 50%;
right: 30px;
transform: translateY(-50%);
z-index: 0;
li {
width: 30px;
height: 30px;
line-height: 30px;
border-radius: 10px;
background: rgba(0, 0, 0, 0.5);
margin-bottom: 30px;
cursor: pointer;
&::after {
content: "";
display: block;
width: 4px;
height: 30px;
border-left: 1px solid #000;
border-right: 1px solid #000;
position: relative;
top: 30px;
left: 50%;
transform: translateX(-50%);
z-index: -1;
}
}
li:nth-child(3) {
&::after {
display: none;
}
}
}
.login {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 500px;
height: 300px;
padding: 10px 20px;
box-sizing: border-box;
border: 1px solid #f0f0f0;
background: #fff;
z-index: 999;
.login-header {
text-align: right;
font-size: 26px;
cursor: pointer;
}
.login-content {
height: 200px;
}
.login-btn {
span {
display: inline-block;
width: 100px;
height: 40px;
line-height: 40px;
cursor: pointer;
border: 1px solid #f0f0f0;
margin: 0 10px;
font-weight: 700;
}
.submit {
background: #e99d42;
}
}
}
}
</style>

422
src/views/bonus/index.vue Normal file
View File

@ -0,0 +1,422 @@
<template>
<div class="bonus">
<div class="bonus-top">
<div class="bonus-records">
<div class="img-records">
<!-- <img src="" alt=""> -->
图片
</div>
<div class="records" @click="getRecords">
<i class="el-icon-tickets"></i>
</div>
<div class="dialog-records" v-if="recordsDialogVisible">
<div class="bonus-header">
Historical records
<span @click="recordsDialogVisible = false">
<i class="el-icon-circle-close"></i>
</span>
</div>
<div class="records-list">
<el-table :data="recordsList">
<template slot="empty">
<div>No Data</div>
</template>
<el-table-column prop="rank" label="Action" :width="80"></el-table-column>
<el-table-column label="Time" :width="180">
<template
slot-scope="scope"
>{{ scope.row.address.slice(0,4) }}{{ '……'+scope.row.address.slice(-4) }}</template>
</el-table-column>
<el-table-column prop="post" label="Points"></el-table-column>
</el-table>
</div>
</div>
</div>
<div class="bonus-box">
<p>Invite friends to Boost,Earn more rewards</p>
<div class="img-box">
<!-- <img src="" alt=""> -->
图片
</div>
</div>
<div class="bonus-boosting">
<h3>Boosting Records</h3>
<li v-for="(item, index) in boostingList" :key="index">
<div class="img-user">
<img src alt />
</div>
<div class="name">{{ item.nickname }}</div>
<div class="score">
+
<span>{{ item.score }}</span> Pts
</div>
</li>
</div>
</div>
<div class="bonus-content">
<div class="bonus-content-top">
<p>Invite friends to Boost</p>
<p>Earn more rewards</p>
<div class="box-amount">{{ boxData.bounsCount }}</div>
<div class="invite" @click="copyLink(boxData.shareCode)">
<p>Invite friends to Boost</p>
<p><i class="el-icon-link"></i></p>
</div>
</div>
<div class="bonus-content-btm">
<div class="turn-btn" @click="turnBox(boxData.id)">Turn ON</div>
<div class="turn-check">
<el-checkbox v-model="turn.check">
<span>Unlock the treasure will consume a small amount of</span>
</el-checkbox>
</div>
<!-- <p>Unlock the treasure will consume a small amount of</p> -->
</div>
</div>
<div class="bonus-btm">
<div class="turn-all-btn">Turn On All</div>
<div class="turn-list">
<li v-for="(item, index) in boxList" :key="index">
<div class="box-img">图片</div>
<div class="box-name">{{ item.level }}</div>
</li>
</div>
</div>
<!-- <el-dialog class="records-dialog" :visible.sync="recordsDialogVisible" :before-close="handleClose">
jkjkj
<br>
<br>
<br>
<br>
<br>
<br>
<br>llklklklklk
</el-dialog>-->
</div>
</template>
<script>
import { sendOpenChest } from './../../utils/chainapi.js'
import { getToken } from './../../utils/cookies.js'
export default {
data() {
return {
token: getToken(),
boxList: [],
boxData: {},
boostingList: [
{
level: 1, //
nickname: "用户昵称",
score: 100 //
},
{
level: 1, //
nickname: "用户昵称",
score: 100 //
},
{
level: 1, //
nickname: "用户昵称",
score: 100 //
}
],
recordsDialogVisible: false,
recordsList: [],
turn: {
check: false,
},
userData: [],
};
},
mounted() {
this.getBoosting();
this.getBoxList()
this.getOpenBox()
this.userData = JSON.parse(localStorage.getItem("userData"));
},
methods: {
//
async getHistorical(id) {
let res = await this.$axios
.post(
"/api/chest/enhance/list",
{ chestid: id },
{
headers: { Authorization: `Bearer ${this.token}` }
}
)
if(res.data.errcode == 0) {
this.boostingList = res.data.data
}
},
//
getBoosting() {
this.$axios
.get("/api/activity/invite_list", {
params: "",
headers: { Authorization: `Bearer ${this.token}` }
})
.then(res => {
console.log('getBoosting',res.data);
// boostingList
});
},
getRecords() {
this.recordsDialogVisible = true;
},
//
copyLink(text) {
console.log(text)
let url = `http://192.168.100.216:8030/home/new=${this.userData.code}/box=${text}/id=${this.boxList[0].id}`
let oInput = document.createElement("input");
oInput.value = url;
document.body.appendChild(oInput);
oInput.select();
document.execCommand("Copy");
oInput.className = "oInput";
oInput.style.display = "none";
this.$message.success("Copy succeeded");
},
//
async getBoxList() {
let res = await this.$axios
.get("/api/chest/list", {
params: "",
headers: { Authorization: `Bearer ${this.token}` }
})
console.log('boxList', res.data.data)
if(res.data.errcode == 0) {
this.boxList = res.data.data
console.log('宝箱列表', this.boxList)
this.boxData = res.data.data[0]
this.getHistorical(this.boxList[0].id);
}
},
//
async getOpenBox() {
let res = await this.$axios.get('/api/chest/open/history',{params: '',headers: { Authorization: `Bearer ${this.token}` }})
console.log('宝箱开启记录', res.data)
},
//
async turnBox(id) {
// const address = localStorage.getItem('address')
try{
// let res = await sendOpenChest(address,id)
let res = await this.$axios.post('/api/chest/open',{chestId: id},{
headers: { Authorization: `Bearer ${this.token}` }
})
console.log('开宝箱', res)
} catch(e){
console.info(e)
}
}
}
};
</script>
<style lang="scss" scoped>
.bonus {
padding: 20px;
.bonus-top {
display: flex;
justify-content: flex-end;
.bonus-records {
width: 120px;
padding-right: 20px;
position: relative;
.img-records {
// text-align: right;
width: 80px;
height: 50px;
background: #4095e5;
margin-left: 40px;
}
.records {
text-align: left;
cursor: pointer;
}
.dialog-records {
width: 360px;
// height: 280px;
border: 2px solid #f0f0f0;
border-bottom: 0px;
position: absolute;
left: -300px;
.bonus-header {
color: #fff;
width: 100%;
height: 40px;
line-height: 40px;
background: #4095e5;
span {
display: inline-block;
position: absolute;
right: 20px;
color: #000;
font-size: 24px;
cursor: pointer;
text-align: right;
}
}
.records-list {
::v-deep .el-table {
thead {
color: #000;
}
.el-table__body-wrapper {
.el-table__empty-block {
.el-table__empty-text {
color: #000;
}
}
}
}
}
}
}
.bonus-box {
width: 400px;
height: 320px;
p {
font-size: 14px;
}
.img-box {
width: 360px;
height: 280px;
background: rgba(0, 0, 0, 0.5);
}
}
.bonus-boosting {
width: 280px;
min-height: 320px;
border: 2px solid #f0f0f0;
h3 {
background: #4095e5;
height: 40px;
line-height: 40px;
}
li {
display: flex;
align-items: center;
justify-content: space-evenly;
height: 40px;
.img-user {
width: 30px;
height: 30px;
border-radius: 8px;
border: 1px solid #f0f0f0;
}
.name {
font-size: 16px;
}
.score {
color: #f59a23;
font-size: 14px;
}
}
}
}
.bonus-content {
.bonus-content-top {
width: 320px;
padding: 10px;
margin: 0 auto;
border: 1px solid #f0f0f0;
position: relative;
p {
font-size: 14px;
}
.box-amount {
font-size: 42px;
font-weight: 700;
}
.invite {
position: absolute;
top: 50%;
right: -137px;
transform: translateY(-50%);
padding: 10px;
background: #f59a23;
cursor: pointer;
p {
font-size: 12px;
}
}
}
.bonus-content-btm {
margin-bottom: 10px;
.turn-btn {
width: 120px;
height: 35px;
line-height: 35px;
margin: 15px auto;
background: #f59a23;
border-radius: 10px;
font-size: 16px;
font-weight: 700;
cursor: pointer;
}
.turn-check {
::v-deep .el-checkbox {
.el-checkbox__input {
.el-checkbox__inner {
border: 0px;
background: #4095e5;
border-radius: 50%;
&::after {
border: 0px;
}
}
}
.el-checkbox__label {
color: #000;
}
}
}
p {
font-size: 12px;
}
}
}
.bonus-btm {
width: 1080px;
height: 300px;
margin: 0 auto;
border: 2px solid #f0f0f0;
padding: 10px;
.turn-all-btn {
width: 120px;
height: 35px;
line-height: 35px;
background: #f59a23;
font-size: 14px;
font-weight: 600;
cursor: pointer;
}
.turn-list {
display: flex;
justify-content: space-evenly;
li {
.box-img {
width: 180px;
height: 220px;
border: 1px solid #f0f0f0;
}
.box-name {
margin-top: 20px;
}
}
}
}
.records-dialog {
position: absolute;
}
}
</style>

Some files were not shown because too many files have changed in this diff Show More