Commit bd43cf0e authored by ganjingcun's avatar ganjingcun

ygopro-arena-web-new with vue2.0

parents
{
"presets": [
["env", { "modules": false }],
"stage-2"
],
"plugins": ["transform-runtime"],
"comments": false,
"env": {
"test": {
"presets": ["env", "stage-2"],
"plugins": [ "istanbul" ]
}
}
}
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
.DS_Store
node_modules/
dist/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
// https://github.com/michael-ciniawsky/postcss-load-config
module.exports = {
"plugins": {
// to edit target browsers: use "browserlist" field in package.json
"autoprefixer": {}
}
}
# ygopro-arena-web-new
> A Vue.js project
## Build Setup
``` bash
# install dependencies
npm install
# serve with hot reload at localhost:8080
npm run dev
# build for production with minification
npm run build
# build for production and view the bundle analyzer report
npm run build --report
```
For detailed explanation on how things work, checkout the [guide](http://vuejs-templates.github.io/webpack/) and [docs for vue-loader](http://vuejs.github.io/vue-loader).
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>YGOPro</title>
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-default/index.css">
</head>
<body>
<div id="app">
<el-form :inline="true" :model="formInline">
<el-form-item>
<el-select style="width: 100px;" v-model="type" placeholder="类别" @change="selectChange">
<el-option label="所有" value="0"></el-option>
<el-option label="竞技" value="1"></el-option>
<el-option label="娱乐" value="2"></el-option>
</el-select>
</el-form-item>
<!--<el-date-picker
v-model="date"
type="daterange"
align="right"
placeholder="选择日期范围"
:picker-options="pickerOptions2"
style="width: 220px;">
</el-date-picker>-->
<el-form-item>
<el-input v-model="username" @blur="searchTextChange" icon="search" style="width: 200px;"
placeholder="用户名"></el-input>
</el-form-item>
</el-form>
<el-table :data="history.data" stripe style="width: 100%">
<el-table-column prop="usernamea" label="玩家A" width="180">
<template scope="scope">
<el-tag
:type="scope.row.userscorea > scope.row.userscoreb ? 'success' : 'gray'"
close-transition>{{scope.row.usernamea}}</el-tag>
<el-icon v-if="scope.row.userscorea < 0" class="el-icon-warning"></el-icon>
</template>
</el-table-column>
<el-table-column prop="usernameb" label="玩家B" width="180">
<template scope="scope">
<el-tag
:type="scope.row.userscoreb > scope.row.userscorea ? 'success' : 'gray'"
close-transition>{{scope.row.usernameb}}</el-tag>
<el-icon v-if="scope.row.userscoreb < 0" class="el-icon-warning"></el-icon>
</template>
</el-table-column>
<el-table-column label="类型" :formatter="formatter0" width="80"></el-table-column>
<el-table-column label="开始时间" :formatter="formatter1"></el-table-column>
<el-table-column label="结束时间" :formatter="formatter2"></el-table-column>
</el-table>
<div class="text-center" >
<el-pagination :page-size="pageSize" layout="total, prev, pager, next" :total="history.total" @current-change="clickpage"></el-pagination>
</div>
</div>
</body>
<script src="https://unpkg.com/vue@2.1.10/dist/vue.js"></script>
<script src="https://unpkg.com/vue-resource@1.2.0/dist/vue-resource.min.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script>
new Vue({
el: '#app',
created: function () {
var lang = localStorage.getItem('lang') || 'cn';
this.init(lang)
},
watch: {
date: function (val) {
console.log(val)
if (val[0] != null) {
this.from_date = val[0].toString()
this.to_date = val[1].toString()
} else {
this.from_date = '';
this.to_date = '';
}
this.renderTable()
},
},
data: function () {
return {
page:1,
from_date:'',
to_date:'',
date: '',
username:'' ,
type: '0',
formInline: {
},
pickerOptions2: {
shortcuts: [
{
text: '今天',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime());
picker.$emit('pick', [start, end]);
}
},
{
text: '昨天',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 1);
picker.$emit('pick', [start, end]);
}
},
{
text: '最近一周',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
picker.$emit('pick', [start, end]);
}
}, {
text: '最近一个月',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
picker.$emit('pick', [start, end]);
}
}, {
text: '最近三个月',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
picker.$emit('pick', [start, end]);
}
}]
},
pageSize:15,
history:{
total:0,
data:[]
}
}
},
methods:{
searchTextChange: function () {
var username = this.username
this.renderTable()
},
selectChange: function (val) {
this.type = val
this.renderTable()
},
init:function (lang) {
this.renderTable()
},
clickpage: function (num) {
this.page = num
this.renderTable()
},
formatter0(row, column) {
if('athletic' === row.type){
return '竞技'
}else {
return '娱乐'
}
},
formatter1(row, column) {
var date = new Date(row.start_time)
return date.toLocaleString();
},
formatter2(row, column) {
var date = new Date(row.end_time)
return date.toLocaleString();
},
renderTable: function(){
// var URL = "http://localhost:3000"
var URL = "https://mycard.moe/ygopro"
var params = {
page:this.page,
username:this.username,
type:this.type,
from_date:this.from_date,
to_date:this.to_date
}
Vue.http.get(URL + '/api/history',{'params':params}).then((res) => {
this.history = res.data
}, (res) => {
//
})
}
}
})
</script>
</html>
\ No newline at end of file
require('./check-versions')()
process.env.NODE_ENV = 'production'
var ora = require('ora')
var rm = require('rimraf')
var path = require('path')
var chalk = require('chalk')
var webpack = require('webpack')
var config = require('../config')
var webpackConfig = require('./webpack.prod.conf')
var spinner = ora('building for production...')
spinner.start()
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
if (err) throw err
webpack(webpackConfig, function (err, stats) {
spinner.stop()
if (err) throw err
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false,
chunks: false,
chunkModules: false
}) + '\n\n')
console.log(chalk.cyan(' Build complete.\n'))
console.log(chalk.yellow(
' Tip: built files are meant to be served over an HTTP server.\n' +
' Opening index.html over file:// won\'t work.\n'
))
})
})
var chalk = require('chalk')
var semver = require('semver')
var packageConfig = require('../package.json')
function exec (cmd) {
return require('child_process').execSync(cmd).toString().trim()
}
var versionRequirements = [
{
name: 'node',
currentVersion: semver.clean(process.version),
versionRequirement: packageConfig.engines.node
},
{
name: 'npm',
currentVersion: exec('npm --version'),
versionRequirement: packageConfig.engines.npm
}
]
module.exports = function () {
var warnings = []
for (var i = 0; i < versionRequirements.length; i++) {
var mod = versionRequirements[i]
if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
warnings.push(mod.name + ': ' +
chalk.red(mod.currentVersion) + ' should be ' +
chalk.green(mod.versionRequirement)
)
}
}
if (warnings.length) {
console.log('')
console.log(chalk.yellow('To use this template, you must update following to modules:'))
console.log()
for (var i = 0; i < warnings.length; i++) {
var warning = warnings[i]
console.log(' ' + warning)
}
console.log()
process.exit(1)
}
}
/* eslint-disable */
require('eventsource-polyfill')
var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')
hotClient.subscribe(function (event) {
if (event.action === 'reload') {
window.location.reload()
}
})
require('./check-versions')()
var config = require('../config')
if (!process.env.NODE_ENV) {
process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)
}
var opn = require('opn')
var path = require('path')
var express = require('express')
var webpack = require('webpack')
var proxyMiddleware = require('http-proxy-middleware')
var webpackConfig = require('./webpack.dev.conf')
// default port where dev server listens for incoming traffic
var port = process.env.PORT || config.dev.port
// automatically open browser, if not set will be false
var autoOpenBrowser = !!config.dev.autoOpenBrowser
// Define HTTP proxies to your custom API backend
// https://github.com/chimurai/http-proxy-middleware
var proxyTable = config.dev.proxyTable
var app = express()
var compiler = webpack(webpackConfig)
var devMiddleware = require('webpack-dev-middleware')(compiler, {
publicPath: webpackConfig.output.publicPath,
quiet: true
})
var hotMiddleware = require('webpack-hot-middleware')(compiler, {
log: () => {}
})
// force page reload when html-webpack-plugin template changes
compiler.plugin('compilation', function (compilation) {
compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
hotMiddleware.publish({ action: 'reload' })
cb()
})
})
// proxy api requests
Object.keys(proxyTable).forEach(function (context) {
var options = proxyTable[context]
if (typeof options === 'string') {
options = { target: options }
}
app.use(proxyMiddleware(options.filter || context, options))
})
// handle fallback for HTML5 history API
app.use(require('connect-history-api-fallback')())
// serve webpack bundle output
app.use(devMiddleware)
// enable hot-reload and state-preserving
// compilation error display
app.use(hotMiddleware)
// serve pure static assets
var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)
app.use(staticPath, express.static('./static'))
var uri = 'http://localhost:' + port
var _resolve
var readyPromise = new Promise(resolve => {
_resolve = resolve
})
console.log('> Starting dev server...')
devMiddleware.waitUntilValid(() => {
console.log('> Listening at ' + uri + '\n')
// when env is testing, don't need open it
if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') {
opn(uri)
}
_resolve()
})
var server = app.listen(port)
module.exports = {
ready: readyPromise,
close: () => {
server.close()
}
}
var path = require('path')
var config = require('../config')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
exports.assetsPath = function (_path) {
var assetsSubDirectory = process.env.NODE_ENV === 'production'
? config.build.assetsSubDirectory
: config.dev.assetsSubDirectory
return path.posix.join(assetsSubDirectory, _path)
}
exports.cssLoaders = function (options) {
options = options || {}
var cssLoader = {
loader: 'css-loader',
options: {
minimize: process.env.NODE_ENV === 'production',
sourceMap: options.sourceMap
}
}
// generate loader string to be used with extract text plugin
function generateLoaders (loader, loaderOptions) {
var loaders = [cssLoader]
if (loader) {
loaders.push({
loader: loader + '-loader',
options: Object.assign({}, loaderOptions, {
sourceMap: options.sourceMap
})
})
}
// Extract CSS when that option is specified
// (which is the case during production build)
if (options.extract) {
return ExtractTextPlugin.extract({
use: loaders,
fallback: 'vue-style-loader'
})
} else {
return ['vue-style-loader'].concat(loaders)
}
}
// https://vue-loader.vuejs.org/en/configurations/extract-css.html
return {
css: generateLoaders(),
postcss: generateLoaders(),
less: generateLoaders('less'),
sass: generateLoaders('sass', { indentedSyntax: true }),
scss: generateLoaders('sass'),
stylus: generateLoaders('stylus'),
styl: generateLoaders('stylus')
}
}
// Generate loaders for standalone style files (outside of .vue)
exports.styleLoaders = function (options) {
var output = []
var loaders = exports.cssLoaders(options)
for (var extension in loaders) {
var loader = loaders[extension]
output.push({
test: new RegExp('\\.' + extension + '$'),
use: loader
})
}
return output
}
var utils = require('./utils')
var config = require('../config')
var isProduction = process.env.NODE_ENV === 'production'
module.exports = {
loaders: utils.cssLoaders({
sourceMap: isProduction
? config.build.productionSourceMap
: config.dev.cssSourceMap,
extract: isProduction
})
}
var path = require('path')
var utils = require('./utils')
var config = require('../config')
var vueLoaderConfig = require('./vue-loader.conf')
function resolve (dir) {
return path.join(__dirname, '..', dir)
}
module.exports = {
entry: {
app: './src/main.js'
},
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src')
}
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: vueLoaderConfig
},
{
test: /\.js$/,
loader: 'babel-loader',
include: [resolve('src'), resolve('test')]
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
]
}
}
var utils = require('./utils')
var webpack = require('webpack')
var config = require('../config')
var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
// add hot-reload related code to entry chunks
Object.keys(baseWebpackConfig.entry).forEach(function (name) {
baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
})
module.exports = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })
},
// cheap-module-eval-source-map is faster for development
devtool: '#cheap-module-eval-source-map',
plugins: [
new webpack.DefinePlugin({
'process.env': config.dev.env
}),
// https://github.com/glenjamin/webpack-hot-middleware#installation--usage
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
// https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true
}),
new FriendlyErrorsPlugin()
]
})
var path = require('path')
var utils = require('./utils')
var webpack = require('webpack')
var config = require('../config')
var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
var CopyWebpackPlugin = require('copy-webpack-plugin')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
var env = config.build.env
var webpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({
sourceMap: config.build.productionSourceMap,
extract: true
})
},
devtool: config.build.productionSourceMap ? '#source-map' : false,
output: {
path: config.build.assetsRoot,
filename: utils.assetsPath('js/[name].[chunkhash].js'),
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
},
plugins: [
// http://vuejs.github.io/vue-loader/en/workflow/production.html
new webpack.DefinePlugin({
'process.env': env
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
sourceMap: true
}),
// extract css into its own file
new ExtractTextPlugin({
filename: utils.assetsPath('css/[name].[contenthash].css')
}),
// Compress extracted CSS. We are using this plugin so that possible
// duplicated CSS from different components can be deduped.
new OptimizeCSSPlugin({
cssProcessorOptions: {
safe: true
}
}),
// generate dist index.html with correct asset hash for caching.
// you can customize output by editing /index.html
// see https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: config.build.index,
template: 'index.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
},
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
chunksSortMode: 'dependency'
}),
// split vendor js into its own file
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: function (module, count) {
// any required modules inside node_modules are extracted to vendor
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, '../node_modules')
) === 0
)
}
}),
// extract webpack runtime and module manifest to its own file in order to
// prevent vendor hash from being updated whenever app bundle is updated
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
chunks: ['vendor']
}),
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static/assets'),
to: config.build.assetsSubDirectory,
ignore: ['.*']
},
{
from: path.resolve(__dirname, '../static/history.html'),
to: path.join(config.build.assetsSubDirectory, ".."),
ignore: ['.*']
},
])
]
})
if (config.build.productionGzip) {
var CompressionWebpackPlugin = require('compression-webpack-plugin')
webpackConfig.plugins.push(
new CompressionWebpackPlugin({
asset: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp(
'\\.(' +
config.build.productionGzipExtensions.join('|') +
')$'
),
threshold: 10240,
minRatio: 0.8
})
)
}
if (config.build.bundleAnalyzerReport) {
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}
module.exports = webpackConfig
var merge = require('webpack-merge')
var prodEnv = require('./prod.env')
module.exports = merge(prodEnv, {
NODE_ENV: '"development"'
})
// see http://vuejs-templates.github.io/webpack for documentation.
var path = require('path')
module.exports = {
build: {
env: require('./prod.env'),
index: path.resolve(__dirname, '../dist/index.html'),
assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: 'assets',
assetsPublicPath: './',
productionSourceMap: true,
// Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you.
// Before setting to `true`, make sure to:
// npm install --save-dev compression-webpack-plugin
productionGzip: false,
productionGzipExtensions: ['js', 'css'],
// Run the build command with an extra argument to
// View the bundle analyzer report after build finishes:
// `npm run build --report`
// Set to `true` or `false` to always turn it on or off
bundleAnalyzerReport: process.env.npm_config_report
},
dev: {
env: require('./dev.env'),
port: 8080,
autoOpenBrowser: true,
assetsSubDirectory: 'assets',
assetsPublicPath: '/',
proxyTable: {},
// CSS Sourcemaps off by default because relative paths are "buggy"
// with this option, according to the CSS-Loader README
// (https://github.com/webpack/css-loader#sourcemaps)
// In our experience, they generally work as expected,
// just be aware of this issue when enabling this option.
cssSourceMap: false
}
}
module.exports = {
NODE_ENV: '"production"'
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ygopro-arena-web-new</title>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
<!--<script src="assets/js/jquery.min.js"></script>-->
<!--<script src="assets/bootstrap/js/bootstrap.min.js"></script>-->
</body>
</html>
\ No newline at end of file
{
"name": "ygopro-arena-web-new",
"version": "1.0.0",
"description": "A Vue.js project",
"author": "ganjingcun <343747757@qq.com>",
"private": true,
"scripts": {
"dev": "node build/dev-server.js",
"build": "node build/build.js"
},
"dependencies": {
"bootstrap": "^3.3.7",
"datatables.net": "^1.10.13",
"datatables.net-bs": "^1.10.13",
"element-ui": "^1.2.8",
"moment": "^2.18.1",
"shelljs": "^0.7.7",
"vue": "^2.2.2",
"vue-resource": "^1.3.1",
"vue-router": "^2.2.0",
"vuex": "^2.2.1"
},
"devDependencies": {
"autoprefixer": "^6.7.2",
"babel-core": "^6.22.1",
"babel-loader": "^6.2.10",
"babel-plugin-transform-runtime": "^6.22.0",
"babel-preset-env": "^1.2.1",
"babel-preset-stage-2": "^6.22.0",
"babel-register": "^6.22.0",
"chalk": "^1.1.3",
"connect-history-api-fallback": "^1.3.0",
"copy-webpack-plugin": "^4.0.1",
"css-loader": "^0.26.1",
"eventsource-polyfill": "^0.9.6",
"express": "^4.14.1",
"extract-text-webpack-plugin": "^2.0.0",
"file-loader": "^0.10.0",
"friendly-errors-webpack-plugin": "^1.1.3",
"function-bind": "^1.1.0",
"html-webpack-plugin": "^2.28.0",
"http-proxy-middleware": "^0.17.3",
"webpack-bundle-analyzer": "^2.2.1",
"semver": "^5.3.0",
"opn": "^4.0.2",
"optimize-css-assets-webpack-plugin": "^1.3.0",
"ora": "^1.1.0",
"rimraf": "^2.6.0",
"url-loader": "^0.5.7",
"vue-loader": "^11.1.4",
"vue-style-loader": "^2.0.0",
"vue-template-compiler": "^2.2.4",
"webpack": "^2.2.1",
"webpack-dev-middleware": "^1.10.0",
"webpack-hot-middleware": "^2.16.1",
"webpack-merge": "^2.6.1"
},
"engines": {
"node": ">= 4.0.0",
"npm": ">= 3.0.0"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
}
<template>
<div id="app">
<page-header></page-header>
<router-view></router-view>
<page-footer></page-footer>
</div>
</template>
<script>
import PageHeader from './components/PageHeader'
import PageFooter from './components/PageFooter'
//css
import "./assets/bootstrap/css/bootstrap.min.css"
import "./assets/Projects-Clean.css"
import "./assets/Pretty-Search-Form.css"
import "./assets/styles.css"
//js
window.jQuery = window.$ = require('jquery');
require('bootstrap/dist/js/bootstrap.min.js')
export default {
name: 'app',
components: {
PageHeader,
PageFooter
}
}
</script>
<style scoped>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #2c3e50;
/*margin-top: 60px;*/
}
</style>
\ No newline at end of file
import Vue from 'vue';
import VueResource from 'vue-resource'
import query from 'querystring';
import config from './config';
Vue.use(VueResource)
// const URL = "http://localhost:3000/api"
const URL = "https://api.mycard.moe/ygopro/arena"
export default class Api {
static getCount(opt) {
var request = query.stringify(opt);
const url = `${config.COUNTER_URL}?${request}`;
return Vue.http.get(url);
}
static getUserInfo(opt) {
var request = query.stringify(opt);
const url = `${URL}/user?${request}`;
return Vue.http.get(url);
}
static getUsers(opt) {
var request = query.stringify(opt);
const url = `${URL}/users?${request}`;
return Vue.http.get(url);
}
static getUserDueHistory(opt) {
return Vue.http.get(`${URL}/history`, { 'params': opt });
}
static getDownloadUrls() {
return Vue.http.get('https://api.github.com/repos/mycard/mycard/releases/latest')
}
static getAvatar(opt) {
return `https://ygobbs.com/user_avatar/ygobbs.com/${opt.username}/400/1.png`
}
static getCardInfo(opt) {
var request = query.stringify(opt);
const url = `${URL}/cardinfo?${request}`;
return Vue.http.get(url);
}
}
.search-form {
margin:40px 5px;
font:normal 12px sans-serif;
box-shadow:1px 2px 4px 0 rgba(0, 0, 0, 0.08);
}
.search-form div.input-group-addon {
background:#fff;
color:#80A3BD;
border-bottom-left-radius:2px;
border-top-left-radius:2px;
border:1px solid #b6c3cd;
border-right:0;
}
.search-form .input-group input {
background-color:#ffffff;
box-shadow:none;
color:#4E565C;
outline:none;
border:1px solid #b6c3cd;
border-right:0;
border-left:0;
}
.search-form div.input-group-btn button {
border-bottom-right-radius:2px;
border-top-right-radius:2px;
background:#6caee0;
box-shadow:1px 2px 4px 0 rgba(0, 0, 0, 0.08);
color:#ffffff;
border-color:#6caee0;
outline:none;
opacity:0.9;
}
.search-form div.input-group-btn button:hover {
opacity:1;
}
.search-form div.input-group-btn button:focus:active {
background-color:#6caee0;
color:#ffffff;
outline:none;
}
.projects-clean {
color:#313437;
background-color:#e6effc;
}
.fix-top{
margin-top:50px;
}
.projects-clean p {
color:#7d8285;
}
.projects-clean h2 {
font-weight:bold;
margin-bottom:40px;
padding-top:40px;
color:inherit;
}
@media (max-width:1024px) {
.projects-clean h2 {
margin-bottom:25px;
padding-top:25px;
font-size:24px;
}
}
.projects-clean .intro {
font-size:16px;
max-width:500px;
margin:0 auto;
}
.projects-clean .intro p {
margin-bottom:0;
}
.projects-clean .projects {
padding-bottom:40px;
}
.projects-clean .item {
text-align:center;
padding-top:50px;
/*min-height:360px;*/
/*max-width:450px;*/
box-shadow:10px 10px 15px #73b7d5;
/*border:2px solid;*/
/*border-radius:25px;*/
-moz-border-radius:25px;
}
.projects-clean .item .name {
font-weight:bold;
/*margin-top:28px;*/
/*margin-bottom:8px;*/
color:inherit;
}
.projects-clean .item .description {
/*margin-top:15px;*/
margin-bottom:0;
}
.team-boxed {
color:#313437;
background-color:#ffffff;
margin-top:50px;
}
.team-boxed p {
color:#7d8285;
}
.team-boxed h2 {
font-weight:bold;
margin-bottom:40px;
padding-top:40px;
color:inherit;
font-size: 30px;
}
@media (max-width:767px) {
.team-boxed h2 {
margin-bottom:25px;
padding-top:25px;
font-size:24px;
}
}
.team-boxed .intro {
font-size:16px;
max-width:500px;
margin:0 auto;
}
.team-boxed .intro p {
margin-bottom:0;
margin-bottom:25px;
}
.team-boxed .people {
padding:50px 0;
/*background-color:#eef4f7;*/
}
.team-boxed .item1 {
text-align:center;
box-shadow:10px 10px 15px #73b7d5;
}
.team-boxed .item1 .box {
text-align:center;
padding:30px;
background-color:#fff;
margin-bottom:30px;
}
.team-boxed .item1 .name {
font-weight:bold;
margin-top:28px;
margin-bottom:8px;
color:inherit;
}
.team-boxed .item1 .title {
text-transform:uppercase;
font-weight:bold;
color:#d0d0d0;
letter-spacing:2px;
font-size:13px;
}
.team-boxed .item1 .description {
font-size:15px;
margin-top:15px;
margin-bottom:20px;
}
.team-boxed .item1 img {
max-width:160px;
}
.team-boxed .social {
font-size:18px;
color:#a2a8ae;
}
.team-boxed .social a {
color:inherit;
margin:0 10px;
display:inline-block;
opacity:0.7;
}
.team-boxed .social a:hover {
opacity:1;
}
.item1 i {
font-size:50px;
}
.team-clean {
color:#313437;
background-color:#fff;
margin-top:50px;
}
.team-clean p {
color:#7d8285;
}
.team-clean h2 {
font-weight:bold;
margin-bottom:40px;
padding-top:40px;
color:inherit;
font-size:30px;
}
@media (max-width:767px) {
.team-clean h2 {
margin-bottom:25px;
padding-top:25px;
font-size:24px;
}
}
.team-clean .intro {
font-size:16px;
max-width:500px;
margin:0 auto;
}
.team-clean .intro p {
margin-bottom:0;
margin-bottom:20px;
}
.team-clean .people {
padding-bottom:40px;
}
.team-clean .item1 {
text-align:center;
padding-top:50px;
}
.team-clean .item1 .name {
font-weight:bold;
margin-top:28px;
margin-bottom:8px;
color:inherit;
}
.team-clean .item1 .title {
text-transform:uppercase;
font-weight:bold;
color:#d0d0d0;
letter-spacing:2px;
font-size:13px;
}
.team-clean .item1 .description {
font-size:15px;
margin-top:15px;
margin-bottom:20px;
}
.team-clean .item1 img {
max-width:160px;
}
.team-clean .social {
font-size:18px;
color:#a2a8ae;
}
.team-clean .social a {
color:inherit;
margin:0 10px;
display:inline-block;
opacity:0.7;
}
.team-clean .social a:hover {
opacity:1;
}
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
table.dataTable{clear:both;margin-top:6px !important;margin-bottom:6px !important;max-width:none !important;border-collapse:separate !important}table.dataTable td,table.dataTable th{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}table.dataTable td.dataTables_empty,table.dataTable th.dataTables_empty{text-align:center}table.dataTable.nowrap th,table.dataTable.nowrap td{white-space:nowrap}div.dataTables_wrapper div.dataTables_length label{font-weight:normal;text-align:left;white-space:nowrap}div.dataTables_wrapper div.dataTables_length select{width:75px;display:inline-block}div.dataTables_wrapper div.dataTables_filter{text-align:right}div.dataTables_wrapper div.dataTables_filter label{font-weight:normal;white-space:nowrap;text-align:left}div.dataTables_wrapper div.dataTables_filter input{margin-left:0.5em;display:inline-block;width:auto}div.dataTables_wrapper div.dataTables_info{padding-top:8px;white-space:nowrap}div.dataTables_wrapper div.dataTables_paginate{margin:0;white-space:nowrap;text-align:right}div.dataTables_wrapper div.dataTables_paginate ul.pagination{margin:2px 0;white-space:nowrap}div.dataTables_wrapper div.dataTables_processing{position:absolute;top:50%;left:50%;width:200px;margin-left:-100px;margin-top:-26px;text-align:center;padding:1em 0}table.dataTable thead>tr>th.sorting_asc,table.dataTable thead>tr>th.sorting_desc,table.dataTable thead>tr>th.sorting,table.dataTable thead>tr>td.sorting_asc,table.dataTable thead>tr>td.sorting_desc,table.dataTable thead>tr>td.sorting{padding-right:30px}table.dataTable thead>tr>th:active,table.dataTable thead>tr>td:active{outline:none}table.dataTable thead .sorting,table.dataTable thead .sorting_asc,table.dataTable thead .sorting_desc,table.dataTable thead .sorting_asc_disabled,table.dataTable thead .sorting_desc_disabled{cursor:pointer;position:relative}table.dataTable thead .sorting:after,table.dataTable thead .sorting_asc:after,table.dataTable thead .sorting_desc:after,table.dataTable thead .sorting_asc_disabled:after,table.dataTable thead .sorting_desc_disabled:after{position:absolute;bottom:8px;right:8px;display:block;font-family:'Glyphicons Halflings';opacity:0.5}table.dataTable thead .sorting:after{opacity:0.2;content:"\e150"}table.dataTable thead .sorting_asc:after{content:"\e155"}table.dataTable thead .sorting_desc:after{content:"\e156"}table.dataTable thead .sorting_asc_disabled:after,table.dataTable thead .sorting_desc_disabled:after{color:#eee}div.dataTables_scrollHead table.dataTable{margin-bottom:0 !important}div.dataTables_scrollBody table{border-top:none;margin-top:0 !important;margin-bottom:0 !important}div.dataTables_scrollBody table thead .sorting:after,div.dataTables_scrollBody table thead .sorting_asc:after,div.dataTables_scrollBody table thead .sorting_desc:after{display:none}div.dataTables_scrollBody table tbody tr:first-child th,div.dataTables_scrollBody table tbody tr:first-child td{border-top:none}div.dataTables_scrollFoot table{margin-top:0 !important;border-top:none}@media screen and (max-width: 767px){div.dataTables_wrapper div.dataTables_length,div.dataTables_wrapper div.dataTables_filter,div.dataTables_wrapper div.dataTables_info,div.dataTables_wrapper div.dataTables_paginate{text-align:center}}table.dataTable.table-condensed>thead>tr>th{padding-right:20px}table.dataTable.table-condensed .sorting:after,table.dataTable.table-condensed .sorting_asc:after,table.dataTable.table-condensed .sorting_desc:after{top:6px;right:6px}table.table-bordered.dataTable th,table.table-bordered.dataTable td{border-left-width:0}table.table-bordered.dataTable th:last-child,table.table-bordered.dataTable th:last-child,table.table-bordered.dataTable td:last-child,table.table-bordered.dataTable td:last-child{border-right-width:0}table.table-bordered.dataTable tbody th,table.table-bordered.dataTable tbody td{border-bottom-width:0}div.dataTables_scrollHead table.table-bordered{border-bottom-width:0}div.table-responsive>div.dataTables_wrapper>div.row{margin:0}div.table-responsive>div.dataTables_wrapper>div.row>div[class^="col-"]:first-child{padding-left:0}div.table-responsive>div.dataTables_wrapper>div.row>div[class^="col-"]:last-child{padding-right:0}
This diff is collapsed.
#profile {
text-align:center;
}
#logo {
max-height:42px;
margin-right:10px;
margin-top:-8px;
display:inline-block;
}
#promo {
text-align:center;
padding:40px;
background:url(./banner.jpg) no-repeat;
background-size:cover;
margin-top:50px;
}
div.jumbotron {
border-radius:20px;
padding:40px;
background-color:rgba(255,255,255,0.5);
max-width:800px;
margin:0 auto;
}
body {
font-family:Arial,Helvetica,sans-serif;
}
.site-section {
text-align:center;
padding-bottom:70px;
}
.site-section h1 {
font-weight:normal;
margin-bottom:30px;
margin-top:60px;
}
#why .item i {
font-size:40px;
color:rgb(245,145,30);
}
#welcome p {
max-width:800px;
font-size:20px;
margin:0 auto;
color:#666;
}
#why .item h2 {
font-weight:normal;
margin-top:13px;
margin-bottom:20px;
font-size:20px;
}
.dark-section {
background-color:#e6effc;
}
#head-portrait {
max-height:23px;
margin-right:4px;
margin-top:-3px;
display:inline-block;
}
#ranking-content {
margin-top:-35px;
}
#search-form {
margin-bottom:4px;
}
.search-condition {
display:inline-block;
margin-right:30px;
}
#check-boxes {
text-align:center;
}
.content {
margin-top:85px;
}
div.col-md-4.item {
background-image:url(./images3.jpeg);
background-repeat:initial;
background-size:cover;
}
.table td {
width:15%;
}
<template>
<div class="content">
<div class="container">
<!--<div class="fck">
<form id="search-form" class="search-form" @submit.prevent="onSubmit">
<div class="form-group" v-bind:class="{ 'has-error': hasError}">
<label class="control-label" for="input1" v-if="hasError">{{lang.battle.notfound}}</label>
<div class="input-group">
<div class="input-group-addon"><span><i class="glyphicon glyphicon-search"></i></span></div>
<input class="form-control" type="text" id="input1" v-model="searchText" placeholder="{{lang.battle.ph2}}">
<div class="input-group-btn">
<button class="btn btn-default" type="submit">{{lang.battle.search}}</button>
</div>
</div>
</div>
</form>
</div>-->
<div class="row">
<div class="col-md-5" id="profile">
<div class="thumbnail">
<img v-bind:src="imgSrc" class="avatar">
<div class="caption">
<h3> <strong>{{username}}</strong></h3>
<p class="text-nowrap text-muted c-desc">
<pre>{{card_info.desc}} </pre>
</p>
<!--<p class="text-nowrap text-muted c-desc">{{card_info.desc}}</p>-->
</div>
</div>
</div>
<div class="col-md-7">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">{{lang.cardinfo.cardinfo}} </h3>
</div>
<div class="table-responsive">
<table class="table table-striped table-bordered table-hover">
<tbody>
<tr>
<td>{{lang.cardinfo.name}} </td>
<td>{{card_info.name}} </td>
</tr>
<tr>
<td>{{lang.cardinfo.type}} </td>
<td>{{card_info.type}} </td>
</tr>
<tr>
<td>{{lang.cardinfo.race}} </td>
<td>{{card_info.race}} </td>
</tr>
<tr>
<td>{{lang.cardinfo.attribute}} </td>
<td>{{card_info.attribute}} </td>
</tr>
<tr>
<td>{{lang.cardinfo.level}} </td>
<td>{{card_info.level}} </td>
</tr>
<tr>
<td>{{lang.cardinfo.attack}} </td>
<td>{{card_info.atk}} </td>
</tr>
<tr>
<td>{{lang.cardinfo.defend}} </td>
<td>{{card_info.def}} </td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import querystring from 'querystring';
import language from './lang';
import img1 from '../assets/images1.jpeg'
import img2 from '../assets/images2.jpeg'
import img3 from '../assets/images3.jpeg'
import API from '../api'
import { mapGetters } from 'vuex'
export default {
data() {
return {
searchText: "",
hasError: false,
username: "",
avatar_url: "",
imgSrc: "",
card_info: {
name: "",
level: 0,
desc: "",
atk: 0,
def: 0,
type: "",
attribute: "",
race: ""
},
}
},
created: function () {
var lang = localStorage.getItem('lang')
this.initLang(lang)
},
events: {
'lang-change': function (lang) {
this.initLang(lang)
}
},
watch: {
lang: function (val) {
this.initLang()
},
},
mounted: function () {
this.initLang();
},
computed: {
...mapGetters({
lang: 'getLang',
}),
},
methods: {
onSubmit: function () {
this.searchById(this.searchText)
},
initLang: function () {
var lang = localStorage.getItem('lang') || 'cn';
this.local = lang
var id = querystring.parse(location.search.slice(1)).id
this.searchById(id)
},
searchById: function (id) {
this.imgSrc = `https://github.com/mycard/ygopro-images/blob/master/pics/${id}.jpg?raw=true`
API.getCardInfo({ id: id, lang: this.local }).then((res) => {
this.hasError = false
this.card_info = res.data
}, (res) => {
this.hasError = true
});
}
},
}
</script>
<style scoped>
.fck {
margin-bottom: 20px;
margin-top: -30px;
}
.avatar {
height: 380px;
margin-top: 13px;
}
.c-desc {
font-size: 20px;
}
pre {
white-space: pre-wrap;
word-wrap: break-word;
}
</style>
\ No newline at end of file
This diff is collapsed.
<template>
<div class="team-boxed">
<div class="container">
<div class="intro">
<h2 class="text-center">{{lang.downloadPage.welcome}} </h2>
<p class="text-center"><strong>{{lang.downloadPage.desc}}</strong> </p>
</div>
<div class="row people">
<div @click="gogo('windows')" class="col-md-6 col-sm-6 item1">
<div class="box"><i class="fa fa-windows"></i>
<h3 class="name">Windows </h3>
<!--<p class="title">asd</p>-->
</div>
</div>
<div @click="gogo('mac')" class="col-md-6 col-sm-6 item1">
<div class="box"><i class="fa fa-apple"></i>
<h3 class="name">Mac </h3>
<!--<p class="title">asd</p>-->
</div>
</div>
<!--<div @click="gogo('linux')" class="col-md-4 col-sm-6 item1">
<div class="box"><i class="fa fa-linux"></i>
<h3 class="name">Linux </h3>
<p class="title">asd</p>
</div>
</div>-->
</div>
<div class="intro">
<p class="text-center"><a :href="lang.downloadPage.user_guide_url">{{lang.downloadPage.user_guide}}</a> </p>
</div>
</div>
</div>
</template>
<script>
import querystring from 'querystring';
import API from '../api'
import { mapGetters } from 'vuex'
import "../assets/Team-Boxed.css"
// import "../assets/Team-Clean.css"
export default {
data() {
return {
downloadUrls: {},
}
},
created: function () {
// https://wudizhanche.mycard.moe/download?platform=win32
// https://wudizhanche.mycard.moe/download?platform=darwin
var self = this
API.getDownloadUrls().then((res) => {
let assets = res.data.assets
for (let i of assets) {
if (i.browser_download_url.indexOf('.exe') > -1) {
self.downloadUrls['windows'] = i.browser_download_url
}
if (i.browser_download_url.indexOf('.dmg') > -1) {
self.downloadUrls['mac'] = i.browser_download_url
}
if (i.browser_download_url.indexOf('.AppImage') > -1) {
self.downloadUrls['linux'] = i.browser_download_url
}
}
});
},
computed: {
...mapGetters({
lang: 'getLang',
}),
},
watch: {
lang: function (val) {
this.initLang()
},
},
events: {
'lang-change': function (lang) {
this.initLang(lang)
}
},
methods: {
initLang: function (lang) {
},
gogo: function (url) {
// window.open(url)
window.location.href = this.downloadUrls[url]
}
},
}
</script>
<style scoped>
.team-boxed {
color: #313437;
background-color: #ffffff;
}
.item1 {
cursor: pointer;
}
.box {
background-color: red;
}
</style>
\ No newline at end of file
<template>
<div class="hello">
<h1>{{ msg }}</h1>
</div>
</template>
<script>
export default {
name: 'hello',
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
<template>
<div id="history">
<el-form :inline="true" :model="formInline">
<el-form-item>
<el-select style="width: 100px;" v-model="type" placeholder="类别" @change="selectChange">
<el-option label="所有" value="0"></el-option>
<el-option label="竞技" value="1"></el-option>
<el-option label="娱乐" value="2"></el-option>
</el-select>
</el-form-item>
<!--<el-date-picker
v-model="date"
type="daterange"
align="right"
placeholder="选择日期范围"
:picker-options="pickerOptions2"
style="width: 220px;">
</el-date-picker>-->
<el-form-item>
<el-input v-model="username" @blur="searchTextChange" icon="search" style="width: 200px;" placeholder="用户名"></el-input>
</el-form-item>
</el-form>
<el-table :data="history.data" stripe style="width: 100%">
<el-table-column prop="usernamea" label="玩家A" width="180">
<template scope="scope">
<el-tag :type="scope.row.userscorea > scope.row.userscoreb ? 'success' : 'gray'" close-transition>{{scope.row.usernamea}}</el-tag>
<el-icon v-if="scope.row.userscorea < 0" class="el-icon-warning"></el-icon>
</template>
</el-table-column>
<el-table-column prop="usernameb" label="玩家B" width="180">
<template scope="scope">
<el-tag :type="scope.row.userscoreb > scope.row.userscorea ? 'success' : 'gray'" close-transition>{{scope.row.usernameb}}</el-tag>
<el-icon v-if="scope.row.userscoreb < 0" class="el-icon-warning"></el-icon>
</template>
</el-table-column>
<el-table-column label="类型" :formatter="formatter0" width="80"></el-table-column>
<el-table-column label="开始时间" :formatter="formatter1"></el-table-column>
<el-table-column label="结束时间" :formatter="formatter2"></el-table-column>
</el-table>
<div class="text-center">
<el-pagination :page-size="pageSize" layout="total, prev, pager, next" :total="history.total" @current-change="clickpage"></el-pagination>
</div>
</div>
</template>
<script>
import querystring from 'querystring';
import language from './lang';
import img1 from '../assets/images1.jpeg'
import img2 from '../assets/images2.jpeg'
import img3 from '../assets/images3.jpeg'
import API from '../api'
import tb_language from './tb_lang.js'
import { mapGetters } from 'vuex'
import moment from 'moment'
export default {
created: function () {
var lang = localStorage.getItem('lang') || 'cn';
this.init(lang)
},
watch: {
date: function (val) {
console.log(val)
if (val[0] != null) {
this.from_date = val[0].toString()
this.to_date = val[1].toString()
} else {
this.from_date = '';
this.to_date = '';
}
this.renderTable()
},
},
data: function () {
return {
page: 1,
from_date: '',
to_date: '',
date: '',
username: '',
type: '0',
formInline: {
},
pickerOptions2: {
shortcuts: [
{
text: '今天',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime());
picker.$emit('pick', [start, end]);
}
},
{
text: '昨天',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 1);
picker.$emit('pick', [start, end]);
}
},
{
text: '最近一周',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
picker.$emit('pick', [start, end]);
}
}, {
text: '最近一个月',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
picker.$emit('pick', [start, end]);
}
}, {
text: '最近三个月',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
picker.$emit('pick', [start, end]);
}
}]
},
pageSize: 15,
history: {
total: 0,
data: []
}
}
},
methods: {
searchTextChange: function () {
var username = this.username
this.renderTable()
},
selectChange: function (val) {
this.type = val
this.renderTable()
},
init: function (lang) {
this.renderTable()
},
clickpage: function (num) {
console.log('asdasdasd!!!ASDASD!!!!')
this.page = num
this.renderTable()
},
formatter0(row, column) {
if ('athletic' === row.type) {
return '竞技'
} else {
return '娱乐'
}
},
formatter1(row, column) {
return moment(row.start_time).subtract(8, 'h').format('YYYY-MM-DD HH:mm')
},
formatter2(row, column) {
return moment(row.end_time).subtract(8, 'h').format('YYYY-MM-DD HH:mm')
},
renderTable: function () {
var params = {
page: this.page,
username: this.username,
type: this.type,
from_date: this.from_date,
to_date: this.to_date
}
var _this = this;
API.getUserDueHistory(params).then((res) => {
_this.history = res.data
}, (res) => {
//
})
}
}
}
</script>
<style scoped>
#history{
margin-top: 100px;
}
</style>
\ No newline at end of file
<template>
<div class="hello">
<div id="promo" v-if="!isLogin">
<div class="jumbotron">
<h1>MyCard </h1>
<p>{{lang.index.p1}}</p>
<p><a class="text-uppercase btn btn-info btn-lg" href="#/download">Start Now!</a></p>
</div>
</div>
<div class="projects-clean" v-bind:class="{ 'fix-top': isLogin }">
<div class="container" id="project">
<div class="intro">
<h2 class="text-center">{{lang.index.p2}} </h2>
<p class="text-center">{{lang.index.p3}} </p>
</div>
<div class="row projects">
<div @click="gogo('#/ranking')" class="col-lg-4 col-sm-6 item" v-bind:class="{ 'fix-width': !isMobile , 'fix-width-m': isMobile }"><img class="img-responsive" src="../../static/assets/img/image6.png">
<h3 class="name">
<span style="text-decoration: underline;">{{lang.index.h1}}</span>
</h3>
<p class="description">{{lang.index.p4}}</p>
</div>
<div @click="gogo('#/cards')" class="col-lg-4 col-sm-6 item" v-bind:class="{ 'fix-width': !isMobile , 'fix-width-m': isMobile}"><img class="img-responsive" src="../../static/assets/img/image4.png">
<h3 class="name">
<span style="text-decoration: underline;">{{lang.index.h3}}</span>
</h3>
<p class="description">{{lang.index.p6}}</p>
</div>
<div @click="gogo('#/userinfo')" class="col-lg-4 col-sm-6 item" v-bind:class="{ 'fix-width': !isMobile , 'fix-width-m': isMobile }"><img class="img-responsive" src="../../static/assets/img/image5.png">
<h3 class="name">
<span style="text-decoration: underline;">{{lang.index.h2}}</span>
</h3>
<p class="description">{{lang.index.p5}}</p>
</div>
<div @click="gogo('https://rep.ygobbs.com')" class="col-lg-4 col-sm-6 item" v-bind:class="{ 'fix-width': !isMobile , 'fix-width-m': isMobile}"><img class="img-responsive" src="../../static/assets/img/image3.png">
<h3 class="name">
<span style="text-decoration: underline;">{{lang.index.h4}}</span>
</h3>
<p class="description">{{lang.index.p7}}</p>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import language from './lang';
import querystring from 'querystring';
export default {
data() {
return {
isLogin: false,
isMobile: false,
lang: {},
}
},
created: function () {
var lang = localStorage.getItem('lang') || 'cn';
this.init(lang)
var token = querystring.parse(location.search.slice(1)).sso;
if (token) {
localStorage.setItem('token', token);
this.isLogin = true;
} else {
token = localStorage.getItem('token');
if (token) {
this.isLogin = true;
} else {
this.isLogin = false;
}
}
var clientWidth = document.body.clientWidth;
if (clientWidth < 753) {
this.isMobile = true
}
var self = this;
window.onresize = function () {
var clientWidth = document.body.clientWidth;
if (clientWidth < 753) {
self.isMobile = true;
} else {
self.isMobile = false;
}
}
},
methods: {
init: function (lang) {
this.lang = language[lang]
},
gogo: function (url) {
// window.open(url)
window.location.href = url
}
},
events: {
'lang-change': function (lang) {
this.init(lang)
}
},
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.item {
cursor: pointer;
max-height: 160px;
}
.projects-clean {
color: #313437;
background-color: #ffffff;
}
.fix-width {
width: 50%;
min-height: 435px;
}
.fix-width-m {
min-height: 385px;
}
</style>
\ No newline at end of file
<template>
<!--<div class="other">
<footer>
<div class="row">
<div class="col-md-4 col-sm-6 footer-navigation">
<h3><a href="#">MyCard </a></h3>
<p class="links"><a href="#">社区 </a><strong> · </strong><a href="#">排行榜 </a><strong> · </strong><a href="#">战报系统 </a><strong> · </strong><a href="#">下载 </a> </p>
<p class="company-name">mycard © 2016 </p>
</div>
<div class="col-md-4 col-sm-6 footer-contacts">
<div><span class="fa fa-map-marker footer-contacts-icon"> </span>
<p><span class="new-line-span">21 Revolution Street</span> Paris, France</p>
</div>
<div><i class="fa fa-phone footer-contacts-icon"></i>
<p class="footer-center-info email text-left"> +1 555 123456</p>
</div>
<div><i class="fa fa-envelope footer-contacts-icon"></i>
<p> <a href="#" target="_blank">support@company.com</a></p>
</div>
</div>
<div class="clearfix visible-sm-block"></div>
<div class="col-md-4 footer-about">
<h4>About the company</h4>
<p> Lorem ipsum dolor sit amet, consectateur adispicing elit. Fusce euismod convallis velit, eu auctor lacus vehicula sit amet.
</p>
<div class="social-links social-icons"><a href="#"><i class="fa fa-facebook"></i></a><a href="#"><i class="fa fa-twitter"></i></a><a href="#"><i class="fa fa-linkedin"></i></a><a href="#"><i class="fa fa-github"></i></a></div>
</div>
</div>
</footer>
</div>-->
</template>
<script>
export default {
data () {
return {
msg: 'other!'
}
}
}
</script>
<template>
<div>
<!--<header-component></header-component>-->
<div>
<nav class="navbar navbar-inverse navbar-fixed-top">
<!--<nav class="navbar navbar-inverse">-->
<div class="container">
<div class="navbar-header">
<a class="navbar-brand navbar-link" href="index.html"><img src="../assets/mycardlogo.png" id="logo">MyCard </a>
<button class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navcol-1"><span class="sr-only">Toggle navigation</span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button>
</div>
<div class="collapse navbar-collapse" id="navcol-1">
<ul class="nav navbar-nav navbar-right">
<li role="presentation"><a href="https://ygobbs.com/" target="_blank">{{lang.forum}} </a></li>
<li role="presentation"><a href="#/ranking">{{lang.rank}} </a></li>
<li role="presentation"><a href="#/cards">{{lang.card_rank}} </a></li>
<li role="presentation"><a href="https://rep.ygobbs.com">{{lang.battlelog}} </a></li>
<!--<li role="presentation"><a href="https://mycard.moe/ygopro/">{{lang.download}} </a></li>-->
<li role="presentation"><a href="#/download">{{lang.download}} </a></li>
<li v-if="isLogin" class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" aria-expanded="false" href="#"><img v-bind:src="avatar_url" id="head-portrait">{{username}} <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li role="presentation"><a href="#/profile">{{lang.profile}} </a></li>
<li class="divider" role="presentation"></li>
<li role="presentation"><a @click.prevent="logout" href="#">{{lang.signout}} </a></li>
</ul>
</li>
<li v-else role="presentation"><a @click.prevent="login" href="#">{{lang.signin}} </a></li>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" aria-expanded="false" href="#">
{{lang.lang}} <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li role="presentation"><a @click.prevent="toCn">{{lang.cn}} </a></li>
<li role="presentation"><a @click.prevent="toEn">{{lang.en}} </a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
</div>
<!--<other-component></other-component>-->
</div>
</template>
<script>
import querystring from 'querystring';
import crypto from 'crypto';
import language from './lang';
import { mapGetters } from 'vuex'
export default {
data() {
return {
isLogin: false,
username: "",
avatar_url: "",
}
},
created: function () {
this.init()
},
computed: {
...mapGetters({
lang: 'getLang',
}),
},
methods: {
init: function () {
var token = querystring.parse(location.search.slice(1)).sso;
if (token) {
localStorage.setItem('token', token);
this.render(token);
this.isLogin = true;
} else {
token = localStorage.getItem('token');
if (token) {
this.render(token);
this.isLogin = true;
} else {
this.isLogin = false;
}
}
var lang = localStorage.getItem('lang');
if (lang === 'en') {
this.toEn()
} else {
this.toCn()
}
},
render: function (token) {
var user = querystring.parse(new Buffer(token, 'base64').toString());
this.username = user.username;
this.avatar_url = user.avatar_url;
},
logout: function () {
localStorage.removeItem('token');
// var redirectUrl = "http://localhost:8081/index.html";
var redirectUrl = "https://mycard.moe/ygopro/arena/index.html";
var request = querystring.stringify({
'redirect': redirectUrl
});
location.href = "https://ygobbs.com/logout?" + request;
},
login: function () {
var payload = new Buffer(querystring.stringify({
return_sso_url: location.href
})).toString('base64');
var request = querystring.stringify({
'sso': payload,
'sig': crypto.createHmac('sha256', 'zsZv6LXHDwwtUAGa').update(payload).digest('hex')
});
location.href = "https://ygobbs.com/session/sso_provider?" + request;
},
toCn: function () {
localStorage.setItem('lang', 'cn');
// this.lang = language['cn'];
// this.$dispatch('lang-change', 'cn')
this.curLang = 'cn'
this.$store.dispatch('getLang', this);
},
toEn: function () {
localStorage.setItem('lang', 'en');
// this.lang = language['en'];
// this.$dispatch('lang-change', 'en')
this.curLang = 'en'
this.$store.dispatch('getLang', this);
this.$emit('helloworld')
}
}
}
</script>
\ No newline at end of file
<template>
<div class="content">
<div class="container">
<div class="row">
<div class="col-md-3" id="profile">
<div class="thumbnail">
<img v-bind:src="avatar_url" style="height:200px;margin-top:13px;">
<div class="caption">
<h3> <i class="glyphicon glyphicon-user"></i> <strong>{{username}}</strong></h3>
<!--<p class="text-nowrap text-muted" style="font-size:20px;">有妞不泡,大逆不道;遇妞则泡,替天行道。 </p>-->
</div>
</div>
</div>
<div class="col-md-9">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">{{lang.athletic}} </h3>
</div>
<div class="table-responsive">
<table class="table table-striped table-bordered table-hover">
<tbody>
<tr>
<td>D.P </td>
<td>{{user_info.pt}} </td>
</tr>
<tr>
<td>{{lang.athletic_rank}} </td>
<td>{{user_info.arena_rank}} </td>
</tr>
<tr>
<td>{{lang.win}} </td>
<td>{{user_info.athletic_win}} </td>
</tr>
<tr>
<td>{{lang.lose}} </td>
<td>{{user_info.athletic_lose}} </td>
</tr>
<tr>
<td>{{lang.draw}} </td>
<td>{{user_info.athletic_draw}} </td>
</tr>
<tr>
<td>{{lang.all}} </td>
<td>{{user_info.athletic_all}} </td>
</tr>
<tr>
<td>{{lang.ratio}} </td>
<td>{{user_info.athletic_wl_ratio}}% </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">{{lang.entertain}} </h3>
</div>
<div class="table-responsive">
<table class="table table-striped table-bordered table-hover">
<tbody>
<tr>
<td>EXP </td>
<td>{{user_info.exp}} </td>
</tr>
<tr>
<td>{{lang.exp_rank}} </td>
<td>{{user_info.exp_rank}} </td>
</tr>
<tr>
<td>{{lang.win}} </td>
<td>{{user_info.entertain_win}} </td>
</tr>
<tr>
<td>{{lang.lose}} </td>
<td>{{user_info.entertain_lose}} </td>
</tr>
<tr>
<td>{{lang.draw}} </td>
<td>{{user_info.entertain_draw}} </td>
</tr>
<tr>
<td>{{lang.all}} </td>
<td>{{user_info.entertain_all}} </td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import querystring from 'querystring';
import language from './lang';
import API from '../api'
import { mapGetters } from 'vuex'
export default {
data() {
return {
username: "",
avatar_url: "",
user_info: {
exp: 0,
pt: 500,
entertain_win: 0,
entertain_lose: 0,
entertain_draw: 0,
entertain_all: 0,
entertain_wl_ratio: 0,
exp_rank: 0,
athletic_win: 0,
athletic_lose: 0,
athletic_draw: 0,
athletic_all: 0,
athletic_wl_ratio: 0,
arena_rank: 0
}
}
},
computed: {
...mapGetters({
lang: 'getLang',
}),
},
watch: {
lang: function (val) {
},
},
created: function () {
this.init()
var lang = localStorage.getItem('lang');
this.initLang(lang)
},
events: {
'lang-change': function (lang) {
this.initLang(lang)
}
},
methods: {
init: function () {
var token = querystring.parse(location.search.slice(1)).sso;
if (token) {
this.render(token);
this.isLogin = true;
} else {
token = localStorage.getItem('token');
if (token) {
this.render(token);
this.isLogin = true;
} else {
this.isLogin = false;
}
}
},
initLang: function (lang) {
},
render: function (token) {
var user = querystring.parse(new Buffer(token, 'base64').toString());
this.username = user.username;
this.avatar_url = user.avatar_url;
let opt = {
'username': user.username
}
API.getUserInfo(opt).then((res) => {
this.user_info = res.data
});
}
},
}
</script>
\ No newline at end of file
<template>
<div class=content>
<div class="container">
<ul class="nav nav-tabs">
<li class="active"><a href="#tab-1" role="tab" data-toggle="tab">{{lang.userRank.pointRank}} </a></li>
<li><a href="#tab-2" role="tab" data-toggle="tab">{{lang.userRank.expRank}} </a></li>
</ul>
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="tab-1">
<br>
<p>{{lang.userRank.tableHead2}}</p>
<div class="table-responsive" style="width:100%;overflow-x:auto;overflow-y:hidden;">
<table class="table table-striped table-bordered table-hover example" id="pt_table" :width="width"></table>
</div>
</div>
<div role="tabpanel" class="tab-pane" id="tab-2">
<br>
<p>{{lang.userRank.tableHead1}}</p>
<div class="table-responsive" style="width:100%;overflow-x:auto;overflow-y:hidden;">
<table class="table table-striped table-bordered table-hover example" id="exp_table" :width="width"></table>
</div>
</div>
<div class="form-group" style="display:none">
<button type="submit" id="search" class="form-control btn btn-primary">{{lang.search}}</button>
</div>
</div>
</div>
</div>
</template>
<script>
import tb_language from './tb_lang.js'
import API from '../api';
import { mapGetters } from 'vuex'
var expTable, ptTable
export default {
created: function () {
var regex_match = /(nokia|iphone|android|motorola|^mot-|softbank|foma|docomo|kddi|up.browser|up.link|htc|dopod|blazer|netfront|helio|hosin|huawei|novarra|CoolPad|webos|techfaith|palmsource|blackberry|alcatel|amoi|ktouch|nexian|samsung|^sam-|s[cg]h|^lge|ericsson|philips|sagem|wellcom|bunjalloo|maui|symbian|smartphone|midp|wap|phone|windows ce|iemobile|^spice|^bird|^zte-|longcos|pantech|gionee|^sie-|portalmmm|jigs browser|hiptop|^benq|haier|^lct|operas*mobi|opera*mini|320x320|240x320|176x220)/i;
var u = navigator.userAgent;
if (null == u) {
return true;
}
var result = regex_match.exec(u);
if (null == result) {
} else {
this.width = "250%"
}
var lang = localStorage.getItem('lang') || 'cn';
this.init(lang)
},
data() {
return {
width: "100%",
}
},
watch: {
lang: function (val) {
console.log('lang change1', val)
this.init2()
},
},
mounted: function () {
this.init2();
},
computed: {
...mapGetters({
lang: 'getLang',
}),
},
methods: {
init: function (lang) {
},
init2: function () {
function renderPage() {
if (ptTable) {
ptTable.destroy();
}
if (expTable) {
expTable.destroy();
}
expTable = renderExpTable();
ptTable = renderArenaTable();
API.getUsers({ o: 'pt' }).then((res) => {
if (ptTable) {
ptTable.destroy();
}
ptTable = renderArenaTable(res.data)
}, (res) => {
console.log(res)
});
API.getUsers({ o: 'exp' }).then((res) => {
if (expTable) {
expTable.destroy();
}
expTable = renderExpTable(res.data)
}, (res) => {
console.log(res)
});
}
function renderExpTable(tableData) {
tableData = tableData || [];
var lang = localStorage.getItem('lang') || 'cn';
var rank = 1;
var processData = tableData.map(function (d) {
return [rank++, d.username, parseInt(d.exp), d.entertain_win, d.entertain_lose];
});
var table = $('#exp_table').DataTable({
data: processData,
order: [[0, "asc"]],
"ordering": true,
columns: [
{ title: tb_language[lang].rank },
{ title: tb_language[lang].name },
{ title: tb_language[lang].exp },
{ title: tb_language[lang].win },
{ title: tb_language[lang].lose },
],
"columnDefs": [
{
"render": function (data, type, row) {
return "<a href='#/userinfo?username=" + data + "'>" + data + "</a>";
},
"targets": 1
},
],
"language": lang === 'en' ? tb_language.en : tb_language.cn
});
return table;
}
function renderArenaTable(tableData) {
tableData = tableData || [];
var lang = localStorage.getItem('lang') || 'cn';
var rank = 1;
var processData = tableData.map(function (d) {
let ratio = 0
if (d.athletic_all > 0) {
ratio = (d.athletic_win / d.athletic_all * 100).toFixed(2)
}
return [rank++, d.username, parseInt(d.pt), d.athletic_win, d.athletic_lose, ratio + "%"];
});
var table = $('#pt_table').DataTable({
data: processData,
order: [[0, "asc"]],
"ordering": true,
columns: [
{ title: tb_language[lang].rank },
{ title: tb_language[lang].name },
{ title: tb_language[lang].pt },
{ title: tb_language[lang].win },
{ title: tb_language[lang].lose },
{ title: tb_language[lang].wl },
],
"columnDefs": [
{
"render": function (data, type, row) {
return "<a href='#/userinfo?username=" + data + "'>" + data + "</a>";
},
"targets": 1
},
],
"language": tb_language[lang]
});
return table;
}
renderPage();
$("#search").click(function () {
renderPage();
return false;
})
}
},
events: {
'lang-change': function (lang) {
this.init(lang)
$("#search").trigger('click')
}
},
}
</script>
\ No newline at end of file
This diff is collapsed.
module.exports = {
cn: {
lang: 'Language',
cn: '中文',
en: 'English',
forum: '社区',
rank: '玩家排行榜',
battlelog: '战报系统',
card_rank: '卡片排行榜',
download: '下载',
profile: '个人信息',
signout: '退出',
signin: '登录 | 注册',
qc: '查询条件',
time: '时间范围',
today: '今天',
week: '最近7日',
half_month: '最近15日',
month: '最近一个月',
season: '当前禁卡表',
type: '排名类型',
totalDeck: '卡组总数',
entertain: '娱乐场',
athletic: '竞技场',
source:"数据来源",
tag:"TAG对战",
custom:'自由对战',
search: '查询',
table_data: '列表数据',
monster: '怪兽统计',
spell: '魔法统计',
trap: '陷阱统计',
side: '备牌统计',
extra: '额外统计',
dueHistory: '最近决斗记录',
athleticDueHistory: '竞技场决斗记录',
entertainDueHistory: '娱乐场决斗记录',
tagInfo:'绿色表示获胜方,红色则表示掉线。',
exp_rank: 'EXP 排名',
athletic_rank: 'D.P 排名',
win: '胜场',
lose: '负场',
draw: '平局',
all: '总场',
ratio: '胜率',
violation: '违规次数',
userRank: {
expRank: 'EXP排名',
pointRank: '竞技场排名',
useRank: '使用量排名',
tableHead1: '查看EXP排行榜,这里展示娱乐匹配的成绩,你是否也榜上有名呢?',
tableHead2: '查看竞技场排行榜,这里展示竞技匹配的成绩,你是否也榜上有名呢?',
tableHead3: '查看卡片排行榜.',
},
battle: {
ph: '请输入卡片或用户名..',
ph2: '请输入用户名..',
notfound: '用户名不存在',
search: '检索',
card: '卡片',
user: '用户',
how: '排名是怎么排的?',
resultUser: '检索结果 - 用户',
resultCard: '检索结果 - 卡片',
view: '点击查看',
},
downloadPage: {
welcome: "欢迎来到MyCard下载页面",
desc: "MyCard支持以下2种系统的版本,请下载符合的版本。",
user_guide: "MyCard YGOPro使用说明",
user_guide_url: "https://ygobbs.com/t/MyCard-V3-使用说明/82308/13",
},
cardinfo: {
cardinfo: "卡片信息",
name:"卡名",
type:"卡片种类",
race:"种族",
attribute:"属性",
level:"星级",
attack: "攻击",
defend:"防御"
},
index: {
p1: 'MyCard是一款免费开源的游戏平台,支持着YGOPRO,东方弹幕等游戏的联机。同时平台内也自带制作组自主研发的单机游戏。',
srartNow: 'START NOW!',
p2: '欢迎来到MyCard决斗数据库',
p3: '在这里你可以找到一切MyCard决斗有关的数据。强力的决斗者离不开数据分析参考,请尽情使用这些数据变的更强吧!',
p4: '查看EXP与竞技场排行榜,你是否也是榜上有名的明星决斗者?',
p5: '查看玩家详细资料,记录你的MyCard决斗生涯。',
p6: '查看各卡片 / 卡组的使用状况,这个环境的主流是什么?',
p7: 'Ygopro战队联盟存放统计友谊赛战报的地方。',
h1: '决斗排名',
h2: '玩家信息',
h3: '卡片排名',
h4: '战报系统',
gallery: 'Gallery'
}
},
en: {
lang: '语言',
cn: '中文',
en: 'English',
forum: 'Forum',
rank: 'User rank',
battlelog: 'Battle log',
card_rank: 'Meta Check',
download: 'Download',
profile: 'Profile',
signout: 'Sign out',
signin: 'Sign in | Sign up',
qc: 'Query conditions',
time: 'Time',
today: 'Day',
week: 'Week',
half_month: '15 Days',
month: 'Month',
season: 'Season',
type: 'Rank type',
totalDeck: 'Group count',
entertain: 'Entertain',
athletic: 'Athletic',
source:"DataSource",
tag:"TAG",
custom:'Custom',
search: 'Search',
table_data: 'Data',
monster: 'Monster',
spell: 'Spell',
trap: 'Trap',
side: 'Side',
extra: 'Extra',
dueHistory: 'Recent Due History',
athleticDueHistory: 'Athletic Due History',
entertainDueHistory: 'Entertain Due History',
tagInfo:'Green tag represents the winner.Red tag represents player lost connection.',
exp_rank: 'EXP Rank',
athletic_rank: 'D.P Rank',
win: 'Win',
lose: 'Lose',
draw: 'Draw',
all: 'All',
ratio: 'W/L',
violation: 'Violation',
userRank: {
expRank: 'EXP Rank',
pointRank: 'Athletic Rank',
useRank: 'Used Rank',
tableHead1: 'View Exp rank list, are you in list ?',
tableHead2: 'View Athletic rank list, are you in list ?',
tableHead3: 'View Card Used list .',
},
battle: {
ph: 'Input card name or username..',
ph2: 'Input username..',
notfound: 'username not found',
search: 'Search',
card: 'Card',
user: 'User',
how: 'Ranking is based on what?',
resultUser: 'Search Result - User',
resultCard: 'Search Result - User',
view: 'detail',
},
downloadPage: {
welcome: "MyCard-YGOPro Download Page",
desc: "MyCard has installer for Windows and Mac, please download the correct installer.",
user_guide: "MyCard YGOPro User Guide",
user_guide_url: "https://ygobbs.com/t/MyCard-V3-User-Guide/82335"
},
cardinfo: {
cardinfo: "Card Info",
name:"Name",
type:"Card Type",
race:"Race",
attribute:"Attribute",
level:"Level",
attack: "Attack",
defend:"Defend"
},
index: {
p1: 'MyCard is an open source PC gaming platform, it supports online battles for games like YGOPRO and Touhou. It also includes PC games made by MyCard team itself.',
srartNow: 'START NOW!',
p2: 'Welcome to Duelist Data Base',
p3: 'Duelist Data Base provides you the data related to MyCard duels. Skilled duelists analyse data at their advantage, feel free to level up yourself with it!',
p4: 'Check out who is the best duelist here!',
p5: 'View your duelist details here.',
p6: 'Check out the most popular cards used in the current meta!',
p7: 'Where the Ygopro Team League stores their match records! (Only applicable to Chinese Users so far)',
h1: 'Duelist Ranking',
h2: 'Duelist Info',
h3: 'Meta Check',
h4: 'Team System',
gallery: 'Gallery'
}
}
}
module.exports = {
cn: {
"sProcessing": "处理中...",
"sLengthMenu": "显示 _MENU_ 项结果",
"sZeroRecords": "没有匹配结果",
"sInfo": "显示第 _START_ 至 _END_ 项结果,共 _TOTAL_ 项",
"sInfoEmpty": "显示第 0 至 0 项结果,共 0 项",
"sInfoFiltered": "(由 _MAX_ 项结果过滤)",
"sInfoPostFix": "",
"sSearch": "搜索:",
"sUrl": "",
"sEmptyTable": "表中数据为空",
"sLoadingRecords": "载入中...",
"sInfoThousands": ",",
"oPaginate": {
"sFirst": "首页",
"sPrevious": "上页",
"sNext": "下页",
"sLast": "末页"
},
"oAria": {
"sSortAscending": ": 以升序排列此列",
"sSortDescending": ": 以降序排列此列"
},
rank: "排名",
name: "用户名",
exp: "EXP",
pt: "D.P",
win: "胜局",
lose: "负局",
wl: "胜率",
cardName: "卡名",
used: "使用量",
put1: "投入1",
put2: "投入2",
put3: "投入3",
playerA: '玩家A',
playerB: '玩家B',
startTime: '开始时间',
endTime: '结束时间',
},
en: {
"oPaginate": {
"sPrevious": "Pre",
},
rank: "Rank",
name: "Name",
exp: "EXP",
pt: "D.P",
win: "Win",
lose: "Lose",
wl: "W/L",
cardName: "Card Name",
used: "Used",
put1: "Put one ",
put2: "Put two ",
put3: "Put three ",
playerA: 'PlayerA',
playerB: 'PlayerA',
startTime: 'Start Time',
endTime: 'End Time',
}
}
export default {
COUNTER_URL: 'https://api.mycard.moe/ygopro/analytics/counter/type',
}
export default {
URL_PREFIX: 'http://nbw.dsp-api.ads.cocos.com',
LOGIN_URL: 'https://passport.cocos.com/sso/signin?client_id=221' //本地测试223 内网测试221 正式222
}
/* time related */
export const DEFAULT_TIME_FORMAT = 'YYYY-MM-DD HH:mm:ss.SSS'
export const SIMPLE_TIME_FORMAT = 'YYYY-MM-DD'
export const ONE_DAY_MILLIS = 86400000
export const SHOW_LEFT_DAYS_MILLIS = 259200000
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import VueX from 'vuex'
import store from './store'
import Element from 'element-ui'
import 'element-ui/lib/theme-default/index.css'
Vue.use(Element)
Vue.use(VueX)
Vue.config.productionTip = false
/* eslint-disable no-new */
// new Vue({
// el: '#app',
// router,
// template: '<App/>',
// components: { App }
// })
new Vue({el: '#app', store, router, render: h => h(App)})
\ No newline at end of file
/* eslint-disable */
export default {
install(Vue) {
Vue.locationHref = (url) => {
window.location.href = url;
};
},
};
/* eslint-enable */
import Vue from 'vue';
import query from 'querystring' ;
import config from '../../config/config';
export default class Api {
/** --- campaign --- */
static getCampaignList(opt) {
var request = query.stringify(opt);
const url = `${config.URL_PREFIX}/campaign/get_list?${request}`;
return Vue.http.get(url, {'credentials': true});
}
static getCampaignInfoByCampaignId(campaignId) {
var request = query.stringify({
campaign_id: campaignId
});
const url = `${config.URL_PREFIX}/campaign/get_info?${request}`;
return Vue.http.get(url, {'credentials': true});
}
static getCampaignOption() {
const url = `${config.URL_PREFIX}/campaign/get_option`;
return Vue.http.get(url, {'credentials': true});
}
static changeCampaignStatus(opt) {
const url = `${config.URL_PREFIX}/campaign/update_status`;
return Vue.http.post(url, opt, {'emulateJSON': true, 'credentials': true});
}
static createCampaign(opt) {
const url = `${config.URL_PREFIX}/campaign/create`;
return Vue.http.post(url, opt, {'emulateJSON': true, 'credentials': true});
}
static updateCampaign(opt) {
const url = `${config.URL_PREFIX}/campaign/update`;
return Vue.http.post(url, opt, {'emulateJSON': true, 'credentials': true});
}
/* --- ad --- */
static createAds(opt) {
const url = `${config.URL_PREFIX}/ad/create`;
return Vue.http.post(url, opt, {'emulateJSON': true, 'credentials': true});
}
static updateAds(opt) {
const url = `${config.URL_PREFIX}/ad/update`;
return Vue.http.post(url, opt, {'emulateJSON': true, 'credentials': true});
}
static changeAdStatus(opt) {
const url = `${config.URL_PREFIX}/ad/update_status`;
return Vue.http.post(url, opt, {'emulateJSON': true, 'credentials': true});
}
static adsBatchDelete(adIds) {
const url = `${config.URL_PREFIX}/ad/batch_update`;
return Vue.http.post(url, {'ad_ids': adIds, 'status': 3}, {'emulateJSON': true, 'credentials': true});
}
static adsBatchUpdateStatus(adIds, status) {
const url = `${config.URL_PREFIX}/ad/batch_update`;
return Vue.http.post(url, {'ad_ids': adIds, 'status': status}, {'emulateJSON': true, 'credentials': true});
}
static adsBatchUpdateDate(adIds, starTime, endTime) {
const url = `${config.URL_PREFIX}/ad/batch_update`;
return Vue.http.post(url, {'ad_ids': adIds, 'start_time': starTime, 'end_time': endTime}, {'emulateJSON': true, 'credentials': true});
}
static adsBatchUpdateTime(adIds, scheduleType) {
const url = `${config.URL_PREFIX}/ad/batch_update`;
return Vue.http.post(url, {'ad_ids': adIds, 'schedule_type': scheduleType}, {'emulateJSON': true, 'credentials': true});
}
static adsBatchUpdatePrice(adIds, price) {
const url = `${config.URL_PREFIX}/ad/batch_update`;
return Vue.http.post(url, {'ad_ids': adIds, 'price': price}, {'emulateJSON': true, 'credentials': true});
}
static getAds(opt) {
var request = query.stringify(opt);
const url = `${config.URL_PREFIX}/ad/get_list?${request}`;
return Vue.http.get(url, {'credentials': true});
}
static getStuffImg(adId) {
var request = query.stringify({
ad_id: adId
});
const url = `${config.URL_PREFIX}/ad/get_img_list?${request}`;
return Vue.http.get(url, {'credentials': true});
}
static getAdInfoByAdId(adId) {
var request = query.stringify({
ad_id: adId
});
const url = `${config.URL_PREFIX}/ad/get_info?${request}`;
return Vue.http.get(url, {'credentials': true});
}
/* --- dashboard --- */
static getMoneyAndAds() {
const url = `${config.URL_PREFIX}/stats/get_money_and_ads`;
return Vue.http.get(url, {'credentials': true});
}
/* --- report --- */
static getTop5() {
const url = `${config.URL_PREFIX}/report/get_top5`;
return Vue.http.get(url, {'credentials': true});
}
static getAdsReport(opt) {
var request = query.stringify(opt);
const url = `${config.URL_PREFIX}/report/ads?${request}`;
return Vue.http.get(url, {'credentials': true});
}
static getTrendReport(opt) {
var request = query.stringify(opt);
const url = `${config.URL_PREFIX}/report/trend?${request}`;
return Vue.http.get(url, {'credentials': true});
}
/* --- stuff --- */
static getStuffSize(opt) {
var request = query.stringify(opt);
const url = `${config.URL_PREFIX}/stuff/get_all_size?${request}`;
return Vue.http.get(url, {'credentials': true});
}
static createStuff(opt) {
const url = `${config.URL_PREFIX}/stuff/create`;
return Vue.http.post(url, opt, {'emulateJSON': true, 'credentials': true});
}
static updateStuff(opt) {
const url = `${config.URL_PREFIX}/stuff/update`;
return Vue.http.post(url, opt, {'emulateJSON': true, 'credentials': true});
}
/* --- account --- */
static getAccountBalance() {
const url = `${config.URL_PREFIX}/account/get_balance`;
return Vue.http.get(url, {'credentials': true});
}
static getUserInfo() {
const url = `${config.URL_PREFIX}/account/get_user_info`;
return Vue.http.get(url, {'credentials': true});
}
static getBillList(opt) {
var request = query.stringify(opt);
const url = `${config.URL_PREFIX}/account/get_bill_list?${request}`;
return Vue.http.get(url, {'credentials': true});
}
static getInvoiceList(opt) {
var request = query.stringify(opt);
const url = `${config.URL_PREFIX}/account/get_invoice_list?${request}`;
return Vue.http.get(url, {'credentials': true});
}
static getTaxInfo() {
const url = `${config.URL_PREFIX}/account/get_tax_info`;
return Vue.http.get(url, {'credentials': true});
}
static getAddress() {
const url = `${config.URL_PREFIX}/account/get_address`;
return Vue.http.get(url, {'credentials': true});
}
static applyInvoice(opt) {
const url = `${config.URL_PREFIX}/account/apply_invoice`;
return Vue.http.post(url, opt, {'emulateJSON': true, 'credentials': true});
}
static cancelInvoice(opt) {
var request = query.stringify(opt);
const url = `${config.URL_PREFIX}/account/cancel_invoice?${request}`;
return Vue.http.get(url, {'credentials': true});
}
static createTaxInfo(opt) {
const url = `${config.URL_PREFIX}/account/create_tax_info`;
return Vue.http.post(url, opt, {'emulateJSON': true, 'credentials': true});
}
static createAddress(opt) {
const url = `${config.URL_PREFIX}/account/create_address`;
return Vue.http.post(url, opt, {'emulateJSON': true, 'credentials': true});
}
static getInvoiceAmount(opt) {
var request = query.stringify(opt);
const url = `${config.URL_PREFIX}/account/get_invoice_amount?${request}`;
return Vue.http.get(url, {'credentials': true});
}
/* --- 成功处理 --- */
static successReturn(context) {
context.$notify({
title: '操作成功',
message: '操作成功',
type: 'success'
})
}
/* --- 错误处理 --- */
static errorReturn(opt, context) {
context.$notify({
title: '错误',
message: opt.msg,
type: 'error'
})
if (opt.status === 20001) { // 木有登录
window.location.href = `${config.LOGIN_URL}`;
}
}
static sysErrorReturn(context) {
context.$notify({
title: '服务器开小差~',
message: '服务器开小差,请联系管理员~',
type: 'error'
})
}
}
import Vue from 'vue'
import Router from 'vue-router'
import Hello from '@/components/Hello'
import Index from '@/components/Index'
import Cards from '@/components/Cards'
import Ranking from '@/components/Ranking'
import Download from '@/components/Download'
import Profile from '@/components/Profile'
import Userinfo from '@/components/Userinfo'
import Cardinfo from '@/components/Cardinfo'
import History from '@/components/History'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'Index',
component: Index
},
{
path: '/cards',
name: 'Cards',
component: Cards
},
{
path: '/ranking',
name: 'Ranking',
component: Ranking
},
{
path: '/download',
name: 'Download',
component: Download
},
{
path: '/profile',
name: 'Profile',
component: Profile
},
{
path: '/userinfo',
name: 'Userinfo',
component: Userinfo
},
{
path: '/cardinfo',
name: 'Cardinfo',
component: Cardinfo
},
{
path: '/history',
name: 'History',
component: History
},
]
})
This diff is collapsed.
export const getCampaignList = state => state.campaign
export const getCampaignInfo = state => state.campaign.info
export const getTop5 = state => state.campaign
export const getMoneyAndAds = state => state.campaign
export const getAds = state => state.ads
export const getAdInfo = state => state.ads.info
export const getStuffSize = state => state.ads.sizeList
export const getStuffImg = state => state.ads.imgList
export const getCampaignOption = state => state.campaign.optionList
export const getStuffReport = state => state.ads.stuffReport
export const getAdsReport = state => state.campaign.report
export const getTrendReport = state => state.campaign.trendReport
export const getAccountBalance = state => state.account.account
export const getBillList = state => state.account
export const getInvoiceList = state => state.invoice
export const getAddress = state => state.invoice.address
export const getTax = state => state.invoice.tax
export const getInvoiceAmount = state => state.invoice.amount
export const getUserInfo = state => state.account.userInfo
export const getLang = state => state.invoice.lang
\ No newline at end of file
import Vue from 'vue'
import Vuex from 'vuex'
import * as actions from './actions'
import * as getters from './getters'
import campaign from './modules/campaign'
import ads from './modules/ads'
import account from './modules/account'
import invoice from './modules/invoice'
Vue.use(Vuex)
export default new Vuex.Store({
actions,
getters,
modules: {
campaign,
ads,
account,
invoice,
}
})
import * as types from '../mutation-types'
// initial state
// shape: [{ id, quantity }]
const state = {
userInfo: {
'id': 0,
'name': '',
},
account: {
'balance': 0.00,
'today_cost': 0.00,
},
listData: [],
pageTotal: 1,
}
// getters
const getters = {}
// actions
const actions = {}
// mutations
const mutations = {
[types.GET_ACCOUNT_BALANCE] (state, {data}) {
data.balance = data.balance.toFixed(2)
data.today_cost = data.today_cost.toFixed(2)
state.account = data
},
[types.GET_BILL_LIST] (state, {listData, pageTotal}) {
for (var i in listData) {
listData[i].amount = listData[i].amount.toFixed(2)
}
state.listData = listData
state.pageTotal = pageTotal
},
[types.GET_USER_INFO] (state, {data}) {
state.userInfo = data
},
}
export default {
state,
getters,
actions,
mutations
}
import * as types from '../mutation-types'
// initial state
// shape: [{ id, quantity }]
const state = {
items: [],
count: 0,
info: {},
sizeList: [],
imgList: [],
stuffReport: []
}
// getters
const getters = {}
// actions
const actions = {}
// mutations
const mutations = {
[types.GET_ADS] (state, {data}) {
for (var i in data.items) {
data.items[i].clickcost_avg = data.items[i].clickcost_avg.toFixed(2);
data.items[i].clickrate = data.items[i].clickrate.toFixed(2);
data.items[i].cost = data.items[i].cost.toFixed(2);
data.items[i].day_budget = data.items[i].day_budget.toFixed(2);
data.items[i].price = data.items[i].price.toFixed(2);
}
state.items = data.items
state.count = data.count
},
[types.GET_AD_INFO] (state, {data}) {
state.info = data
},
[types.GET_STUFF_SIZE] (state, {listData}) {
state.sizeList = listData
},
[types.GET_STUFF_IMG] (state, {imgs}) {
state.imgList = imgs
},
[types.CHANGE_AD_STATUS] (state, {data}) {
let index = data.index
let status = data.is_enable
if (status && status === 1) {
state.items[index].ad_status = 1
state.items[index].ad_status_str = '投放中'
} else {
state.items[index].ad_status = 2
state.items[index].ad_status_str = '已暂停'
}
},
[types.GET_ADS_REPORT] (state, {report}) {
var date = [];
var impData = [];
var clickData = [];
var clickrateData = [];
var costData = [];
var costAvgData = [];
for (var i in report) {
date.push(report[i].logdate);
impData.push(report[i].imp);
clickData.push(report[i].click);
clickrateData.push(report[i].clickrate.toFixed(2));
costData.push(report[i].cost);
costAvgData.push(report[i].clickcost_avg.toFixed(2));
}
state.stuffReport = {
'date': date,
'impData': impData,
'clickData': clickData,
'clickrateData': clickrateData,
'costData': costData,
'costAvgData': costAvgData,
}
},
}
export default {
state,
getters,
actions,
mutations
}
This diff is collapsed.
import * as types from '../mutation-types'
import lg from '../../components/lang'
// initial state
// shape: [{ id, quantity }]
const state = {
amount: 0.00, // 可发票金额
address: {},
tax: {},
listData: [],
pageTotal: 1,
lang: lg['cn']
}
// getters
const getters = {}
// actions
const actions = {}
// mutations
const mutations = {
[types.GET_LANG] (state, {lang}) {
state.lang = lg[lang]
},
[types.GET_INVOICE_ADDRESS] (state, {data}) {
state.address = data
},
[types.GET_INVOICE_TAX] (state, {data}) {
state.tax = data
},
[types.CREATE_INVOICE] (state, {id}) {
state.tax.id = id
},
[types.CREATE_ADDRESS] (state, {id}) {
state.address.id = id
},
[types.GET_INVOICE_AMOUNT] (state, {data}) {
state.amount = data.invoice_amount.toFixed(2)
},
[types.CHANGE_INVOICE_STATUS] (state, {data}) {
let index = data.index
state.listData[index].status = 2
state.listData[index].status_str = '已撤销'
},
}
export default {
state,
getters,
actions,
mutations
}
export const GET_CAMPAIGN_LIST = 'GET_CAMPAIGN_LIST'
export const GET_CAMPAIGN_INFO = 'GET_CAMPAIGN_INFO'
export const CHANGE_CAMPAIGN_STATUS = 'CHANGE_CAMPAIGN_STATUS'
export const CHANGE_AD_STATUS = 'CHANGE_AD_STATUS'
export const GET_TOP5 = 'GET_TOP5'
export const GET_MONEY_AND_ADS = 'GET_MONEY_AND_ADS'
export const GET_ADS = 'GET_ADS'
export const GET_AD_INFO = 'GET_AD_INFO'
export const GET_STUFF_SIZE = 'GET_STUFF_SIZE'
export const GET_STUFF_IMG = 'GET_STUFF_IMG'
export const GET_CAMPAIGN_OPTION = 'GET_CAMPAIGN_OPTION'
export const GET_ADS_REPORT = 'GET_ADS_REPORT'
export const GET_TREND_REPORT = 'GET_TREND_REPORT'
export const GET_ACCOUNT_BALANCE = 'GET_ACCOUNT_BALANCE'
export const GET_BILL_LIST = 'GET_BILL_LIST'
export const GET_INVOICE_LIST = 'GET_INVOICE_LIST'
export const GET_INVOICE_ADDRESS = 'GET_INVOICE_ADDRESS'
export const GET_INVOICE_TAX = 'GET_INVOICE_TAX'
export const CREATE_INVOICE = 'CREATE_INVOICE'
export const CREATE_ADDRESS = 'CREATE_ADDRESS'
export const GET_INVOICE_AMOUNT = 'GET_INVOICE_AMOUNT'
export const GET_USER_INFO = 'GET_USER_INFO'
export const CHANGE_INVOICE_STATUS = 'CHANGE_INVOICE_STATUS'
export const GET_LANG = 'GET_LANG'
\ No newline at end of file
export function leftPadding (str, total, padding) {
let i
let result = str
if (str.length < total) {
for (i = str.length; i < total; i += 1) {
result = `${padding}${result}`
}
}
return result
}
export function canonicalActors (actors) {
return actors.split(',').join('/')
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment