Commit 7644663e authored by jsz315's avatar jsz315

首次提交版本

parents
Pipeline #111088 failed with stages
in 0 seconds
{
"presets": ["es2015", "stage-2"],
"plugins": ["transform-runtime", "transform-async-to-generator"]
}
\ No newline at end of file
/build/
/config/
/dist/
/bin/
/server/
/*.js
**/pao/
/config/entry.js
/src/common/js/
**/lib/
/src/pages/welcome/components/
**/game/
\ No newline at end of file
// https://eslint.org/docs/user-guide/configuring
module.exports = {
root: true,
parser: 'babel-eslint',
parserOptions: {
ecmaVersion: 6,
sourceType: 'module'
},
env: {
browser: true,
},
extends: [
// https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention
// consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/reccommended` for stricter rules.
// 'plugin:vue/essential',
// https://github.com/standard/standard/blob/master/docs/RULES-en.md
'standard'
],
// required to lint *.vue files
plugins: [
// 'vue'
],
// add your custom rules here
rules: {
'semi': [2, 'always'],//语句强制分号结尾
// allow trailing-spaces
'no-trailing-spaces': 'off',
// allow async-await
'generator-star-spacing': 'off',
// allow debugger during development
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
},
globals: {
$: true,
Zepto: true,
localStorage: true,
alert: true,
createjs: true,
lib: true,
anime: true,
CREATE: true,
Loader: true,
CFG: true,
wx: true
}
}
\ No newline at end of file
.DS_Store
node_modules/
/dist/
/gulp/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
config/entry.js
/src/pages/labs/
gulpfile.js
debug.log
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.psd
package-lock.json
# Egret
**/bin-debug/
**/bin-release/
**/libs/modules/
**/libs/exml.e.d.ts
**/.wing/
**/template/runtime/native_require.js
**/manifest.json
**/default.thm.json
registry = https://registry.npm.taobao.org
const express = require('express');
const proxy = require('express-http-proxy');
const path = require('path');
var bodyParser = require('body-parser');
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');
const webpackHotMiddleware = require('webpack-hot-middleware');
const devConfig = require('./build/webpack.dev.conf');
const compiler = webpack(devConfig);
const entry = require('./config/entry.js');
const utils = require('./build/utils');
const http = require('./config/http');
// const initApiRoutes = require('./mock/apis');
const opn = require('opn');
const app = express();
const NODE_ENV = process.env.NODE_ENV;
console.log(NODE_ENV, '=========>')
if (NODE_ENV === 'development') {
// webpack
app.use(webpackDevMiddleware(compiler, {
publicPath: devConfig.output.publicPath,
logLevel: 'silent'
}));
app.use(webpackHotMiddleware(compiler, {
log: false,
}));
if(http.dev.PROXY){
app.use('/mock', proxy(http.server));
}
}
app.use(express.static('./static'));
app.use(express.static('./dist'));
app.use(express.static('./src/pages'));
// app.use(express.static('./src'));
//使用mock数据
app.use('/mock', express.static('./mock'))
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, './dist/'));
app.engine('ejs', require('ejs').__express);
app.engine('html', require('ejs').__express);
app.get('/' , function (req, res) {
res.redirect('/index/entry.html')
});
// 输出entry目录
app.get('/api/entry', function (req, res) {
res.json(entry)
});
Object.defineProperty(app, '_$_proxyCache', {
value: {}
})
Object.defineProperty(app, 'getProxy', {
value: function (url, proxy, cb) {
console.log(url)
console.log(proxy)
app._$_proxyCache[url] = proxy;
// console.log(app._$_proxyCache);
app.get(url, (req, res)=>{
var url = req.url;
if(url.indexOf('?')) {
var url = url.split('?')[0];
}
var prox = app._$_proxyCache[url];
cb(req, res, prox);
});
}
})
app.use(bodyParser.json({
limit: '1000kb'
}));
app.use(bodyParser.urlencoded({ extended: false,limit: '1000kb'}));
// initApiRoutes(app);
let browserUrl = `http://${utils.getHost()}:${utils.getPort()}`
console.log(`Your application is running here: ${browserUrl}`);
// 在默认浏览器中打开
opn(browserUrl);
module.exports = app;
/**
* @note
* @author miaokefu <miaokefu@duiba.com.cn>
* @create 2018-05-02
* @des
*/
const fs = require("fs");
const path = require("path");
const tips = "// This file is auto gererated by /bin/build-entry.js";
const pagePath = 'src/pages'
const entryDir = path.join(__dirname, '..', pagePath);
// 直接忽略资源文件夹,加快遍历速度
const exclude = /(img|image)s?\//;
// 指定必须包含的入口文件
const include = /index\/entry\.js/;
let args = process.argv.splice(2);
let entryResult = [];
function filterFile(fileDir) {
fileDir = replaceBackSlash(fileDir);
if (fileDir.match(include)) {
return true;
}
return fileDir.match(/entry\.(js|ts)/) && fileDir.indexOf(args[0] || '') > -1;
}
function replaceBackSlash(str) {
let n = str.split('\\').length - 1;
for (let i = 0; i < n; i++) {
str = str.replace('\\', '/');
}
return str;
}
function getFileExt(path) {
let dotIndex = path.lastIndexOf('.');
return path.substring(dotIndex, path.length);
}
/**
* 递归文件夹
* @param dir
* @param cb
*/
function loopDir(dir, cb) {
const pages = fs.readdirSync(dir);
pages.map(name => {
const fileDir = path.join(dir, name);
const stat = fs.statSync(fileDir);
// 当前为文件结束
if (stat.isFile()) {
// 过滤不需要的文件
if (filterFile(fileDir)) {
cb && cb(fileDir);
}
} else if (stat.isDirectory()) {
// 当前为文件夹继续遍历
if (replaceBackSlash(fileDir).match(exclude)) {
return;
}
loopDir(fileDir, cb);
}
});
}
/**
* 生成入口文件数组
* @param dir
* @returns {Array}
*/
function getEntryArray(dir) {
loopDir(dir, (fileDir)=>{
pushFileToEntry(fileDir);
});
return entryResult;
}
function pushFileToEntry(fileDir) {
let relative = path.relative(entryDir, fileDir)
// 统一处理为posix平台的斜杠
relative = replaceBackSlash(relative)
let lastIndex = relative.lastIndexOf('/')
let ext = getFileExt(relative);
let name = 'entry'
let rpath = relative.substring(0, lastIndex + 1) // 加最后/
let template = pagePath + '/' + relative
template = template.replace(/entry\.(js|ts)/, 'entry.html');
// 获取html的title
let regExp = /<title>(.*)<\/title>/;
let htmlPath = path.join(__dirname , '..' , template);
let htmlContent = fs.readFileSync(htmlPath, 'utf8');
let title= '';
let matchObj = htmlContent.match(regExp);
if (matchObj && matchObj[1]) {
title = matchObj[1];
}
entryResult.push(
` {
path: '${rpath}',
name: '${name}',
template: '${template}',
ext: '${ext}',
title: '${title}'
}`
);
}
function buildEntry(dir) {
let entryArray = getEntryArray(dir);
let content = `${tips}
module.exports = [
${entryArray.join(',\n')}
]`;
fs.writeFileSync(path.join(__dirname, "../config/entry.js"), content);
}
buildEntry(entryDir);
\ No newline at end of file
/**
* @note
* @author miaokefu <miaokefu@duiba.com.cn>
* @create 2018-05-16
* @des
*/
const exec = require('child_process').exec;
const path = require('path');
const chalk = require('chalk');
const chalkWarning = chalk.keyword('orange');
const log = console.log;
const webpack = require('webpack');
const config = require('../config');
const OssUpload = require('../build/ossupload');
let args = process.argv.splice(2);
let cmd = `npm run build:file ${args[0] ? args[0] : ''}`;
const execCmd = (cmd) => new Promise((resolve, reject) => {
exec(cmd, function (error, stdout, stderr) {
// 获取命令执行的输出
if (error) {
reject(error);
}
log(chalkWarning(`----------${cmd}-----------`));
resolve();
});
});
execCmd(cmd).then(() => {
// webpack require的时候才会读取文件
// 入口文件构建结束后,再引入配置文件,保证entry最新
// const entries = require('../config/entry');
const webpackConfig = require('../build/webpack.prod.conf');
webpack(webpackConfig, function (err, stats) {
if (err) throw err;
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false,
chunks: false,
chunkModules: false
}) + '\n\n');
log(chalk.cyan(' Build complete.\n'));
// 打包具体项目时才执行自动上传,避免一次性把工程里的所有资源都同步上去了
if (args[0]) {
// 自动上传cdn资源
const uploader = new OssUpload({
dir: path.join(__dirname, '../dist/'),
originDir: config.build.cdnDir
});
uploader.start();
} else {
log(chalkWarning(`----------打包整个工程暂不上传资源到cdn-----------`));
}
});
}).catch((error) => {
console.error(error);
});
\ No newline at end of file
/**
* @note
* @author miaokefu <miaokefu@duiba.com.cn>
* @create 2018-06-21
* @des
*/
const chalk = require('chalk');
const log = console.log;
const chalkError = chalk.bold.red;
const chalkInfo = chalk.blue;
const chalkWarning = chalk.keyword('orange');
// exec 子进程输出一次性返回
// spawn 返回一个带有stdout和stderr流的对象
const {spawn, exec} = require('child_process');
let arguments = process.argv.splice(2);
const buildEntry = `npm run build:file ${arguments[0] ? arguments[0] : ''}`;
const execCmd = (cmd) => new Promise((resolve, reject) => {
exec(cmd, function (error, stdout, stderr) {
// 获取命令执行的输出
if (error) {
reject(error);
}
if (stderr) {
reject(stderr);
}
log(chalkWarning(`----------${cmd}-----------`));
resolve();
});
});
execCmd(buildEntry)
.then(() => {
const www = spawn('node', ['./bin/www']);
www.stdout.on('data', (data) => {
if (data.toString().match(/error\s{2,}/ig)) {
log(chalkError(data));
} else if (data.toString().match(/done\s{2,}/ig)) {
log(chalkWarning(data));
} else {
log(chalkInfo(`${data}`));
}
});
www.stderr.on('data', (data) => {
log(chalkError(`stderr: ${data}`));
});
www.on('close', (code) => {
log(chalk.blue(`child process exited with code ${code}`));
});
})
.catch((error) => {
log(chalkError(error));
});
\ No newline at end of file
/**
* @note 打包bundle中entry.js引入的组件
* @author miaokefu <miaokefu@duiba.com.cn>
* @create 2018-05-21
* @des 公用的js打包文件放在dui88下便于修改,暂不自动上传资源
*/
const exec = require('child_process').exec;
const chalk = require('chalk');
const webpack = require('webpack');
let arguments = process.argv.splice(2);
let cmd = `npm run build:file ${arguments[0] ? arguments[0] : ''}`;
const execCmd = (cmd) => new Promise((resolve, reject) => {
exec(cmd, function (error, stdout, stderr) {
// 获取命令执行的输出
if (error) {
reject(error);
}
resolve();
});
});
execCmd(cmd).then(() => {
// webpack require的时候才会读取文件
// 入口文件构建结束后,再引入配置文件,保证entry最新
const webpackConfig = require('../build/webpack.pack.conf');
webpack(webpackConfig, function (err, stats) {
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'));
});
}).catch((error) => {
console.error(error);
});
\ No newline at end of file
/**
* @note
* @author miaokefu <miaokefu@duiba.com.cn>
* @create 2018-06-27
* @des
*/
const OssUpload = require('../build/ossupload');
const chalk = require('chalk');
const path =require('path');
const config = require('../config/index');
const chalkWarning = chalk.keyword('orange');
const log = console.log;
let args = process.argv.splice(2);
let localDir = args[0];
if (localDir) {
// 自动上传cdn资源
const uploader = new OssUpload({
dir: path.join(__dirname, '../', localDir),
originDir: config.build.cdnDir
});
uploader.start();
} else {
log(chalkWarning(`----------请输入要上传的文件夹-----------`));
}
\ No newline at end of file
#!/usr/bin/env node
const config = require('../config');
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')('epack:server');
var http = require('http');
/**
* Get port from environment and store in Express.
*/
var port = normalizePort(process.env.PORT || config.dev.port);
app.set('port', port);
/**
* Create HTTP server.
*/
var server = http.createServer(app);
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
/**
* Normalize a port into a number, string, or false.
*/
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}
/**
* @note 阿里云cdn上传
* @author miaokefu <miaokefu@duiba.com.cn>
* @create 2018-06-22
* @des
*/
const fs = require('fs');
const co = require('co');
const OSS = require('ali-oss');
const chalk = require('chalk');
const ProgressBar = require('progress');
const path = require('path');
let NODE_ENV = process.env.NODE_ENV;
function replaceBackSlash(str) {
let n = str.split('\\').length - 1;
for (let i = 0; i < n; i++) {
str = str.replace('\\', '/');
}
return str;
}
class OssUpload {
constructor(props) {
const defaultOptions = {
exclude: /(\.(html|htm))|(manifest\.json)/,
dir: undefined,
originDir: undefined
};
this.options = Object.assign({}, defaultOptions, props);
if (!this.options.dir || !this.options.originDir) {
console.log(chalk.red('缺少参数,初始化失败'));
return;
}
this.sum = 0; // 文件总数
this.count = 0;
this.init();
}
/**
* 获取所有文件数
*/
getFilesCount() {
this.walk(this.options.dir, () => {
this.sum++;
});
}
start() {
this.walk(this.options.dir, this.uploadFile.bind(this));
}
/**
* 上传单个文件
* @param fileDir
*/
uploadFile(fileDir) {
this.count++;
let _this = this;
const path = fileDir;
let originFile;
this.existFiles = 0;
this.uploadFiles = 0;
this.errorFiles = 0;
co(function*() {
let relativeDir = _this.getRelativePath(fileDir);
const originPath = `${_this.options.originDir}${relativeDir}`; // cdn 路径
try {
originFile = yield _this.client.head(originPath);
} catch (error) {
originFile = error;
}
// console.log(chalk.red(originFile))
// console.log(originFile)
if (NODE_ENV === 'production') {
if (originFile.status === 404 && originFile.code === 'NoSuchKey') {
// status=404 , code=NoSuchKey 文件不存在
yield _this.client.put(originPath, path);
console.log('push file');
_this.uploadFiles += 1;
} else {
_this.existFiles += 1;
}
} else {
// //存在replace参数且dev环境时,覆盖cdn资源
let replace = true || process.env.npm_config_replace;
if ((originFile.status === 404 && originFile.code === 'NoSuchKey') || replace) {
yield _this.client.put(originPath, path, {
headers: {
'Cache-Control': 'no-cache'
}
});
_this.uploadFiles += 1;
} else {
_this.existFiles += 1;
}
}
_this.bar.tick();
}).catch(function(err) {
_this.errorFiles += 1;
console.log(err);
});
}
getRelativePath(fileDir) {
let relative = path.relative(this.options.dir, fileDir);
// 统一处理为posix平台的斜杠
relative = replaceBackSlash(relative);
return relative;
}
filterFile(fileDir) {
fileDir = replaceBackSlash(fileDir);
return !fileDir.match(this.options.exclude);
}
/**
* 遍历文件树
* @param dir
* @param cb
*/
walk(dir, cb) {
const pages = fs.readdirSync(dir);
pages.map(name => {
const fileDir = path.join(dir, name);
const stat = fs.statSync(fileDir);
// 当前为文件结束
if (stat.isFile()) {
// 过滤不需要的文件
if (this.filterFile(fileDir)) {
cb && cb(fileDir);
}
} else if (stat.isDirectory()) {
// 当前为文件夹继续遍历
this.walk(fileDir, cb);
}
});
}
init() {
this.getFilesCount();
this.client = new OSS({
region: 'oss-cn-hangzhou',
accessKeyId: 'LTAIdGi1IOap7fkF',
accessKeySecret: 'SKrOOp6EVtDGEV47yn0t2h97gyNioQ',
bucket: NODE_ENV === 'production' ? 'duiba' : 'daily-duiba'
});
console.log(chalk.red(NODE_ENV));
this.bar = new ProgressBar(chalk.yellow(` 文件上传中 [:bar] :current/${this.sum} :percent :elapseds`), {
complete: '',
incomplete: '',
width: 20,
total: this.sum,
callback: () => {
console.log(chalk.green('\n All complete.'));
console.log(
chalk.blue(
`\n 本次队列文件共${this.sum}个,已存在文件${this.existFiles}个,上传文件${this.uploadFiles}个,上传失败文件${this.errorFiles}个\n`
)
);
}
});
return this;
}
}
module.exports = OssUpload;
/*
* @Author: miaokefu@duiba.com.cn
* @Date: 2018-08-29 20:48:34
* @desc 在entry.html同级生成自定义的html代码块
*/
// TODO 打包时运行git log写入最近一次提交记录
const pluginName = 'WebpackCustomOutputPlugin';
class CustomOutputPlugin {
constructor(opts) {
let defaultOpts = {
removeArr: [] // 需要去除的字符串
};
this.options = Object.assign({}, defaultOpts, opts);
}
apply(compiler) {
if (compiler.hooks) {
// webpack 4 support
compiler.hooks.compilation.tap(pluginName, compilation => {
compilation.hooks.htmlWebpackPluginAfterHtmlProcessing.tapAsync(
pluginName,
(htmlPluginData, callback) => {
this.getCustomBodyContent(compilation, htmlPluginData, callback);
}
);
});
} else {
// Hook into the html-webpack-plugin-after-html-processing
compiler.plugin('compilation', compilation => {
compilation.plugin(
'html-webpack-plugin-after-html-processing',
(htmlPluginData, callback) => {
this.getCustomBodyContent(compilation, htmlPluginData, callback);
}
);
});
}
}
getCustomBodyContent(compilation, data, callback) {
let dir = this.getFileDir(data.outputName);
let body = this.getHtmlBody(data.html);
let cssTags = '';
cssTags = data.assets.css.reduce((accumulator, currentValue) => {
return accumulator + this.getCssTag(currentValue) + '\n';
}, cssTags);
body = cssTags + body;
this.options.removeArr.forEach(item => {
let regExp = new RegExp(item, 'g');
body = body.replace(regExp, '');
});
compilation.assets[dir + 'output.html'] = {
source: function() {
return body;
},
size: function() {
return body.length;
}
};
callback(null, data);
}
getFileDir(filePath) {
let lastIndex = filePath.lastIndexOf('/');
return filePath.substring(0, lastIndex + 1); // 加最后/
}
getHtmlBody(str) {
let regExp = /<body[\s]*>([\s\S]*)<\/body>/;
let body = '';
let matchObj = str.match(regExp);
if (matchObj && matchObj[1]) {
body = matchObj[1];
}
return body;
}
getCssTag(url) {
return `<link href="${url}" rel="stylesheet">`;
}
}
module.exports = CustomOutputPlugin;
# webpack-custom-output-plugin
输出自定义的html代码块
## 使用方法
```
new CustomOutputPlugin({
removeArr: [
'<script src="//yun.playpangu.com/h5-mami/webgame/lib/zepto-1.1.4.min.js" type="text/javascript"></script>',
'<script src="//yun.playpangu.com/h5-mami/webgame/lib/statistics_201710271800.js"></script>'
]
}),
```
## 参数
### 1. removeArr
需要删除的字符串数组
\ No newline at end of file
/**
* @note
* @author miaokefu <miaokefu@duiba.com.cn>
* @create 2018-05-02
* @des
*/
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const HtmlWebpackScriptAttributesPlugin = require('html-webpack-script-attributes-plugin');
const CustomOutputPlugin = require('./plugins/webpack-custom-output-plugin');
const config = require('../config');
function resolve(dir) {
return path.join(__dirname, dir);
}
let assetsSubDirectory = function() {
let assetsSubDirectory = process.env.NODE_ENV === 'production' ? config.build.assetsSubDirectory : config.dev.assetsSubDirectory;
// console.log(arguments);
[].slice.call(arguments, 0).unshift(assetsSubDirectory);
// console.log(arguments)
return path.posix.join.apply(null, arguments);
};
exports.assetsSubDirectory = assetsSubDirectory;
exports.cssLoaders = function(options) {
options = options || {};
const cssLoader = {
loader: 'css-loader',
options: {
sourceMap: options.sourceMap
// module: true // 指定启用css modules
}
};
const postcssLoader = {
loader: 'postcss-loader',
options: {
sourceMap: options.sourceMap
}
};
// generate loader string to be used with extract text plugin
function generateLoaders(loader, loaderOptions) {
const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [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: ['style-loader']
});
} else {
// style-loader,insert style into html
return [{ loader: 'style-loader' }].concat(loaders);
}
}
// https://vue-loader.vuejs.org/en/configurations/extract-css.html
return {
css: generateLoaders(),
postcss: generateLoaders(),
less: generateLoaders('less', { javascriptEnabled: true }),
sass: generateLoaders('sass', { indentedSyntax: true }),
scss: generateLoaders('sass')
// stylus: generateLoaders("stylus"),
// styl: generateLoaders("stylus")
};
};
exports.styleLoaders = function(options) {
const output = [];
const loaders = exports.cssLoaders(options);
for (const extension in loaders) {
const loader = loaders[extension];
output.push({
test: new RegExp('\\.' + extension + '$'),
use: loader
});
}
return output;
};
exports.computeEntry = function(entry) {
entry = entry || [];
let result = {};
for (let i = 0, len = entry.length; i < len; i++) {
let item = entry[i];
let path = item.path;
let name = item.name;
let ext = item.ext;
// let pathBuild = path.replace(/\//g, '-')
let pathBuild = path;
let entryJsPath = resolve('../src/pages/' + path + name + ext);
result[pathBuild + name] = [entryJsPath];
}
return result;
};
exports.computeHtmlWebpackEntry = function(entry) {
entry = entry || [];
let result = [];
for (let i = 0, len = entry.length; i < len; i++) {
let item = entry[i];
let path = item.path;
let name = item.name;
// let pathBuild = path.replace(/\//g, '-')
let pathBuild = path;
let template = item.template;
result.push(
new HtmlWebpackPlugin({
template: template,
filename: path + name + '.html',
inject: true, // 默认值,script标签位于html文件的 body 底部
chunks: [pathBuild + name], // 不指定的话就会加载所有的chunk
// chunks: [pathBuild + name, 'runtime~' + pathBuild + name, 'vendors', 'app', 'default'], // 不指定的话就会加载所有的chunk
// chunks: [pathBuild + name, 'vendors', 'default'], // 不指定的话就会加载所有的chunk
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
chunksSortMode: 'dependency',
minify: true // Pass html-minifier's options as object to minify the output
})
);
}
result.push(
new HtmlWebpackScriptAttributesPlugin({
crossorigin: 'anonymous'
})
);
result.push(
new CustomOutputPlugin({
removeArr: [
'<script src="//yun.playpangu.com/h5-mami/webgame/lib/zepto-1.1.4.min.js" type="text/javascript"></script>',
'<script src="//yun.playpangu.com/h5-mami/webgame/lib/statistics_201710271800.js"></script>'
]
}),
)
return result;
};
exports.getHost = function() {
const HOST = process.env.HOST;
return HOST || config.dev.host;
};
exports.getPort = function() {
const PORT = process.env.PORT && Number(process.env.PORT);
return PORT || config.dev.port;
};
/**
* @note
* @author miaokefu <miaokefu@duiba.com.cn>
* @create 2018-05-02
* @des
*/
const path = require('path');
const utils = require('./utils');
const entry = require('../config/entry');
const config = require('../config');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ManifestPlugin = require('webpack-manifest-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
function resolve(dir) {
return path.join(__dirname, dir);
}
function replaceBackSlash(str) {
let n = str.split('\\').length - 1;
for (let i = 0; i < n; i++) {
str = str.replace('\\', '/');
}
return str;
}
function getAssetFileName(file, originName) {
let curPath = resolve('../src/pages');
let relative = file.replace(curPath, '');
relative = replaceBackSlash(relative);
let lastIndex = relative.lastIndexOf('/');
let rpath = relative.substring(0, lastIndex + 1); // 加最后/
return utils.assetsSubDirectory(rpath, originName);
}
const createLintingRule = () => ({
test: /\.(js)$/,
loader: 'eslint-loader',
enforce: 'pre',
include: [resolve('../src')],
options: {
formatter: require('eslint-friendly-formatter'),
emitWarning: config.dev.showEslintErrorsInOverlay,
},
});
module.exports = {
entry: utils.computeEntry(entry),
output: {
path: config.build.assetsRoot,
filename: "[name].js",
chunkFilename: "[id].bundle.js",
pathinfo: false // 输出文件不再携带路径信息
// 在对应的dev.conf和prod.conf中配置
// publicPath: process.env.NODE_ENV === 'production'
// ? config.build.assetsPublicPath
// : config.dev.assetsPublicPath
},
resolve: {
extensions: ['.js', '.json', '.ts', '.vue'],
alias: {
'@': resolve('../src'),
'@css': resolve('../src/common/css'),
'@assets': resolve('../src/common/assets'),
'@js': resolve('../src/common/js'),
'@lib': resolve('../src/common/lib'),
'@layout': resolve('../src/common/layout'),
'@pages': resolve('../src/pages'),
'@components': resolve('../src/components'),
'@common': resolve('../src/common'),
'@apis': resolve('../service/apis'),
'@service': resolve('../service'),
// You are using the runtime-only build of Vue where the template compiler is not available
vue$: 'vue/dist/vue.common.js',
},
},
module: {
rules: [
...(config.dev.useEslint ? [createLintingRule()] : []),
{
test: /\.vue$/,
loader: 'vue-loader',
include: [resolve("../src"),resolve("../node_modules/vue-core-image-upload")],
options: {
loaders: {},
// other vue-loader options go here
},
},
{
test: /\.(jsx|js)$/,
use: {
loader: 'babel-loader',
},
exclude: /node_modules/,
},
{
test: /\.(ts)$/,
use: {
loader: "ts-loader",
options: {
transpileOnly: true, // 用于真正快速增量构建
experimentalWatchApi: true // experimentalWatchApi 与普通 TypeScript watch mode 共享同样的逻辑,并且在开发环境使用时非常稳定
}
},
exclude: /node_modules/,
},
{
test: /\.(woff2?|eot|ttf|otf)$/i,
include: [resolve("../src")],
use: {
loader: 'file-loader',
options: {
limit: 2048,
name(file) {
return getAssetFileName(file, '[name]_[hash:7].[ext]');
},
outputPath: utils.assetsSubDirectory(''),
},
},
},
{
test: /\.(png|jpe?g|gif|mp3|mp4)$/,
include: [resolve("../src")],
use: {
loader: 'url-loader',
// mimetype: 'video/mpeg', // 指定mp3类型
options: {
limit: 2048,
name(file) {
return getAssetFileName(file, '[name]_[hash:7].[ext]');
},
outputPath: utils.assetsSubDirectory(''),
},
},
},
{
test: /\.(htm|html)$/,
include: [resolve("../src")],
use: 'html-withimg-loader?min=false'
}
]
},
plugins: [
new ManifestPlugin(),
// make sure to include the plugin for the magic
new VueLoaderPlugin(),
// new CopyWebpackPlugin([{
// from: resolve('../src/pages'),
// to: '[0]-[1]-[2].[hash].[ext]',
// test: /(.+)\.js$/,
// toType: 'template'
// }])
],
};
/**
* @note
* @author miaokefu <miaokefu@duiba.com.cn>
* @create 2018-05-02
* @des
*/
const merge = require("webpack-merge");
const webpack = require("webpack");
const path = require("path");
const FriendlyErrorsPlugin = require("friendly-errors-webpack-plugin");
const baseWebpackConfig = require("./webpack.base.conf");
const utils = require("./utils");
const config = require("../config");
const entry = require("../config/entry");
const http = require("../config/http");
const host = utils.getHost();
const port = utils.getPort();
function resolve(dir) {
return path.join(__dirname, dir);
}
Object.keys(baseWebpackConfig.entry).forEach(function(name) {
if (name !== 'vendor') {
baseWebpackConfig.entry[name] = baseWebpackConfig.entry[name].concat('webpack-hot-middleware/client?reload=true');
}
});
const devWebpackConfig = merge(baseWebpackConfig, {
// Provides process.env.NODE_ENV with value development. Enables NamedChunksPlugin and NamedModulesPlugin.
mode: 'development',
output: {
publicPath: config.dev.assetsPublicPath
},
module: {
rules: utils.styleLoaders({
sourceMap: config.build.cssSourceMap,
usePostCSS: true
})
},
devtool: config.build.devtool,
plugins: [
new webpack.DefinePlugin({
HTTP: http.dev.HTTP,
MOCK: http.dev.MOCK,
PROXY: http.dev.PROXY
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin(), // 启用此插件后,webpack 进程遇到错误代码将不会退出
new FriendlyErrorsPlugin({
compilationSuccessInfo: {
messages: [`Your application is running here: http://${host}:${port}`],
notes: ['Some additionnal notes to be displayed unpon successful compilation']
},
// should the console be cleared between each compilation?
// default is true
clearConsole: true
})
// new webpack.ProvidePlugin({
// _: "underscore"
// })
].concat(utils.computeHtmlWebpackEntry(entry))
});
module.exports = devWebpackConfig;
/**
* @note
* @author miaokefu <miaokefu@duiba.com.cn>
* @create 2018-05-02
* @des
*/
const path = require('path');
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const merge = require('webpack-merge');
const config = require('../config');
const baseWebpackConfig = require('./webpack.base.conf');
const utils = require('./utils');
const entry = require('../config/entry');
const http = require("../config/http");
const isDev = process.env.NODE_ENV == 'development'
// TODO 先执行tinypng再打包,减少内联base64图片大小
function resolve(dir) {
return path.join(__dirname, dir);
}
////存在replace参数且dev环境时,替换时间戳,覆盖cdn资源
const time = process.env.npm_config_replace
? process.env.npm_config_replace
: (function() {
var date = new Date();
var Y = date.getFullYear();
var M = date.getMonth() + 1;
var D = date.getDate();
var h = date.getHours();
var m = date.getMinutes();
function addZero(num) {
return num > 9 ? num : '0' + num;
}
return [Y, addZero(M), addZero(D), addZero(h), addZero(m)].join('');
})();
const webpackConifg = merge(baseWebpackConfig, {
// Provides process.env.NODE_ENV with value production.
// Enables FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin and UglifyJsPlugin.
mode: 'production',
module: {
rules: utils.styleLoaders({
sourceMap: config.build.productionSourceMap,
extract: true,
usePostCSS: true
})
},
devtool: config.build.productionSourceMap ? config.build.devtool : false,
output: {
path: resolve('../dist'),
filename: isDev ? `[name]_develop.js` : `[name]-${time}.js`,
// chunks文件统一放chunks文件夹下管理,避免cdn根目录下文件太乱
chunkFilename: 'chunks/[name].[chunkhash].min.js',
publicPath: config.build.assetsPublicPath
},
optimization: {
// minimize: false,
minimizer: [
new UglifyJsPlugin({
uglifyOptions: config.build.uglifyConfig
})
],
// 分割代码块
splitChunks: {
chunks: 'async',
minSize: 30000,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
name: true,
cacheGroups: {
// default: {
// name: 'default',
// minChunks: 2,
// priority: -20,
// // chunks: 'initial',
// reuseExistingChunk: true,
// },
// // commons: {
// // name: 'commons',
// // chunks: 'initial',
// // minChunks: 2
// // },
// vendors: {
// name: 'vendors',
// test: /[\\/]node_modules[\\/]/,
// priority: -10
// }
}
}
// runtimeChunk: true
},
plugins: [
new webpack.DefinePlugin({
HTTP: http.prod.HTTP,
MOCK: http.prod.MOCK,
PROXY: http.prod.PROXY
}),
new webpack.BannerPlugin('create-game'),
new webpack.optimize.OccurrenceOrderPlugin(),
new ExtractTextPlugin({
filename: utils.assetsSubDirectory(isDev ? `[name]_develop.css` : `[name]-${time}.css`),
// Vue 项目打包后访问报错:Uncaught TypeError: Cannot read property 'call' of undefined
// Extract from all additional chunks too (by default it extracts only from the initial chunk(s))
// When using CommonsChunkPlugin and there are extracted chunks (from ExtractTextPlugin.extract) in the commons chunk, allChunks must be set to true
allChunks: true
}),
new CleanWebpackPlugin(['dist'], {
root: resolve('../'),
verbose: true,
dry: false
}),
// Compress extracted CSS. We are using this plugin so that possible
// duplicated CSS from different components can be deduped.
new OptimizeCSSPlugin({
cssProcessorOptions: config.build.productionSourceMap ? { safe: true, map: { inline: false } } : { safe: true }
})
].concat(utils.computeHtmlWebpackEntry(entry))
});
module.exports = webpackConifg;
\ No newline at end of file
/**
* @note
* @author miaokefu <miaokefu@duiba.com.cn>
* @create 2018-05-25
* @des 全局配置axios
*/
const axios = require('axios');
const utils = require('../build/utils');
// Global axios defaults
// default: 127.0.0.1:80
axios.defaults.baseURL = `http://${utils.getHost()}:${utils.getPort()}`;
console.log("axios.defaults.baseURL = " + axios.defaults.baseURL)
module.exports = axios;
\ No newline at end of file
module.exports = {
//代理服务器
server: "kjj.m.duibatest.com.cn",
// 开发环境
dev: {
// 单引号不能少
HTTP: '"/mock"',
MOCK: false,
PROXY: true
},
// 生产环境
prod: {
// 单引号不能少
HTTP: '""',
MOCK: false,
PROXY: false
}
}
\ No newline at end of file
/**
* @note
* @author miaokefu <miaokefu@duiba.com.cn>
* @create 2018-05-02
* @des
*/
const path = require('path');
const testDomain = '//yun.dui88.com/';
const prodDomain = '//yun.playpangu.com/';
const cdnDir = 'h5-mami/webgame/';
const proxyServer = require('./proxy-server');
const http = require("./http");
console.log("http.server = " + http.server);
module.exports = {
dev: {
// Paths
assetsSubDirectory: '',
assetsPublicPath: '/',
host: '127.0.0.1',
port: 4000,
devtool: '#cheap-module-eval-source-map',
autoOpenBrowser: false,
cssSourceMap: true,
useEslint: false,
showEslintErrorsInOverlay: false,
// proxy: {
// '/mock': {
// target: http.server,
// pathRewrite: { '^/mock': '' },
// changeOrigin: true,
// secure: false
// }
// },
},
build: {
// Template for index.html
index: path.resolve(__dirname, '../dist/index.html'),
// Paths
assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: '',
assetsPublicPath: process.env.NODE_ENV === 'production' ? `${prodDomain + cdnDir}` : `${testDomain + cdnDir}`,
// assetsPublicPath: '',
cdnDir: cdnDir,
/**
* Source Maps
*/
productionSourceMap: false,
// https://webpack.js.org/configuration/devtool/#production
devtool: '#source-map',
uglifyConfig: {
compress: {
warnings: false,
drop_debugger: true,
drop_console: process.env.NODE_ENV === 'production' ? true : false
}
}
}
};
module.exports = {
// 开发环境
dev: {
// 协议
protocol: 'http://',
// 主机名(带上端口号和前缀路径)
host: '127.0.0.1:4000'
},
// 测试环境
test: {
protocol: 'http://',
host: 'youtui.tuiatest.cn'
},
// easymock
easymock: {
protocol: 'http://',
host: '172.16.35.80:7300/mock/5bd12f0f4865581fb8cc79ff/qushai',
mock: true
}
}
\ No newline at end of file
/**
* @note
* @author miaokefu <miaokefu@duiba.com.cn>
* @create 2017-10-27
* @des 根据mock/routes自动生成所有的服务器api
*/
var fs = require('fs');
var axios = require('../config/axios-config');
var config = require('../config');
var proxyConfig = config.dev.proxy;
// mock路由
var routeConfig = require('./routes');
function readJson(filePath) {
return function (req, res) {
var url = 'mock' + filePath + '.json';
fs.readFile(url, function (err, data) {
if (err) throw err;
res.json(JSON.parse(data));
});
};
}
function transfromResponse(res) {
if (proxyConfig.server.mock) {
// 统计修改easymock的code值
res = Object.assign({}, res, {
code: '0000000'
})
}
return res;
}
/**
* 请求后端接口
* @param req
* @param res
*/
function getAxiosData(req, res) {
var url = req.url;
var params = req.body;
var method = req.method.toLowerCase();
// 拼接请求路径
var server = proxyConfig.server;
url = server.protocol + server.host + url;
console.log(`request url = ${url}`);
if (method === 'get') {
axios.get(url)
.then(function (response) {
res.json(transfromResponse(response.data));
})
.catch(function (err) {
res.json(err);
});
} else if (method === 'post') {
axios.post(url, params)
.then(function (response) {
res.json(transfromResponse(response.data));
})
.catch(function (err) {
res.json(err);
});
} else {
res.json('unkown http method');
}
}
function doGetAxio(req, res, proxy) {
var url = req.url;
var params = req.body;
var method = req.method.toLowerCase();
// 拼接请求路径
url = proxyConfig.protocol + proxy + url;
console.log(`request url = ${url}`);
if (method === 'get') {
axios.get(url)
.then(function (response) {
res.json(transfromResponse(response.data));
})
.catch(function (err) {
res.json(err);
});
} else if (method === 'post') {
axios.post(url, params)
.then(function (response) {
res.json(transfromResponse(response.data));
})
.catch(function (err) {
res.json(err);
});
} else {
res.json('unkown http method');
}
}
function initApiRoutes(router) {
// api路由配置
for (var i in routeConfig) {
var page = routeConfig[i];
for (var j in page) {
var pageRoutes = page[j];
if (j === 'get') {
for (var k in pageRoutes) {
var routeContent = pageRoutes[k];
if (proxyConfig.open) {
if (routeContent instanceof Array) {
router.getProxy(k, routeContent[1], doGetAxio);
} else {
router.get(k, getAxiosData)
}
} else {
router.get(k, readJson(pageRoutes[k]));
}
}
} else if (j === 'post') {
for (var k in pageRoutes) {
if (proxyConfig.open) {
router.post(k, getAxiosData)
} else {
router.post(k, readJson(pageRoutes[k]));
}
}
}
}
}
}
module.exports = initApiRoutes;
\ No newline at end of file
{
"code": "string",
"data": {
"endTime": 0,
"participantNum": 0,
"participateStatus": 0,
"winnerHeadUrl": "string",
"winnerName": "string"
},
"desc": "string",
"success": true
}
{
"code":"0000000",
"desc":"试试",
"data":"https://www.duiba.com.cn/autoLogin/autologin?dcustom=avatar%253Dhttp%253A%252F%252Fthirdwx.qlogo.cn%252Fmmopen%252Fvi_32%252FQ0j4TwGTfTKVYMDRRnF7JbriaXC3OTWrlAXnpxUuld91HmLO05PTmiaZUKp2jCtQEIESibessxZ0SEyHwqHwn26XQ%252F132%2526nickname%253D%25E5%2595%258A%25E4%25BC%258D%2526sex%253D1&uid=4933222376&transfer=27355_2380&credits=19711&sign=4b63691a126902f5665ccb387444778c&appKey=3Tk5P8XeSP6XMRkjPZCZSucRrJmH&timestamp=1524809031094&",
"success":true
}
\ No newline at end of file
{
"success": true,
"code": "000000",
"desc": "OK",
"timestamp": 1552446227949,
"data": {
"appid": "wxcb8c36279dd7dff2",
"noncestr": "c9f41cbe37284ca8b36ae271fc4a3b0d",
"timestamp": "1552446227",
"sign": "8ac477805e862d9873179be1a9cbfc52510c49c4"
}
}
\ No newline at end of file
/**
* @note
* @author miaokefu <miaokefu@duiba.com.cn>
* @create 2018-05-16
* @des
*/
let path = '/kejiji';
module.exports = {
get: {
'/direct/getDuibaUrl': path + '/getDuibaUrl',
'/kjy/mp/seller/getOaJssdk': path + '/getOaJssdk'
},
post: {
'/direct/cashUserAmount': path + '/cashUserAmount',
}
};
\ No newline at end of file
{
"success": true,
"code": "000000",
"desc": "OK",
"timestamp": 1552446227949,
"data": {
"title": "1",
"releaseTime": 1552474107973,
"mainImgUrl": "",
"dailyData": "{\"footerImage\":\"//yun.dui88.com/h5/miniprogram/kejiji/web/rili.png\", \"todayFortune\":{\"suitable\":\"2\",\"avoid\":\"3\"},\"headlines\":{\"title\":\"5\",\"origin\":\"6\",\"imgUrl\":\"//yun.dui88.com/h5/miniprogram/kejiji/web/rili.png\",\"des\":\"7\",\"limit\":{\"maxSize\":1024}},\"domesticNews\":[{\"title\":\"8\",\"origin\":\"9\",\"des\":\"0\"},{\"title\":\"11\",\"des\":\"33\",\"origin\":\"22\"}],\"intelNews\":[{\"title\":\"44\",\"origin\":\"55\",\"des\":\"66\"}],\"socialNews\":[{\"title\":\"77\",\"origin\":\"88\",\"des\":\"99\"},{\"title\":\"77654\",\"des\":\"545\",\"origin\":\"66\"}]}"
}
}
\ No newline at end of file
{
"success": true,
"code": "000000",
"desc": "OK",
"timestamp": 1552446227949,
"data": {
"title": "1",
"releaseTime": 1552474107973,
"mainImgUrl": "",
"dailyData": "{\"todayFortune\":{\"suitable\":\"2\",\"avoid\":\"3\"},\"headlines\":{\"title\":\"5\",\"origin\":\"6\",\"imgUrl\":\"//yun.dui88.com/h5/miniprogram/kejiji/web/rili.png\",\"des\":\"7\",\"limit\":{\"maxSize\":1024}},\"domesticNews\":[{\"title\":\"8\",\"origin\":\"9\",\"des\":\"0\"},{\"title\":\"11\",\"des\":\"33\",\"origin\":\"22\"}],\"intelNews\":[{\"title\":\"44\",\"origin\":\"55\",\"des\":\"66\"}],\"socialNews\":[{\"title\":\"77\",\"origin\":\"88\",\"des\":\"99\"},{\"title\":\"77654\",\"des\":\"545\",\"origin\":\"66\"}]}"
}
}
\ No newline at end of file
{
"success": true,
"code": "000000",
"desc": "OK",
"timestamp": 1552446227949,
"data": {
"appid": "wxcb8c36279dd7dff2",
"noncestr": "c9f41cbe37284ca8b36ae271fc4a3b0d",
"timestamp": "1552446227",
"sign": "8ac477805e862d9873179be1a9cbfc52510c49c4"
}
}
\ No newline at end of file
{
"success": true,
"code": "000000",
"desc": "OK",
"timestamp": 1552446227949,
"data": 1234567
}
\ No newline at end of file
{
"empty": true,
"reference": true,
"status": "100",
"view": {
"contentType": "string"
},
"viewName": "string"
}
\ No newline at end of file
{
"code": "success",
"data": {
"amount": 388,
"cdKey": "stringabcde",
"pageType": 0
},
"desc": "this is a item of description",
"success": true
}
\ No newline at end of file
let path = '/landingTest';
module.exports = {
get: {
'/youtui/article/getLandPageRefluxReward': path + '/getLandPageRefluxReward',
'/youtui/article/getLandPage': path + '/getLandPage'
},
post: {}
};
\ No newline at end of file
var game = require('../game/index');
var gameroom = require('../gameroom/index');
var common = require('../common/index');
var qa = require('../qa/index');
var answerking = require('../answerking/index');
var frendsArticle = require('../friendsArticle/index');
var share_packet = require('../share_packet/index');
var drawGuess = require('../activity/drawGuess');
var luckdraw = require('../luckdraw/index');
var qixi = require('../activity/qixi');
var landingTest = require('../landingTest');
var strategy = require('../activity/strategy');
var keyword = require('../activity/keyword');
var article = require('../activity/article');
var farm = require('../game/farm/index');
var testTemplate = require('../testTemplate');
var coinsend = require('../activity/coinsend');
var goldRain = require('../landing/goldRain');
var laCoinsend = require('../landing/coinsend');
var farmLanding = require('../landing/farm');
var journalAccount = require('../client/journalAccount');
var nationalday = require('../activity/nationalday');
var greetingCard = require('../activity/greetingCard');
var dayHappy = require('../activity/dayHappy');
var pdd = require('../pdd');
var musicTemplate = require('../activity/musicTemplate');
module.exports = {
game,
gameroom,
common,
qa,
answerking,
frendsArticle,
share_packet,
drawGuess,
luckdraw,
qixi,
article,
farm,
strategy,
keyword,
article,
testTemplate,
coinsend,
goldRain,
journalAccount,
laCoinsend,
farmLanding,
nationalday,
greetingCard,
dayHappy,
pdd,
musicTemplate
}
{
"code": "0000000",
"desc": "成功",
"data": {
"timeStamp": "1531279137",
"debug": true,
"jsApiList": [],
"signature": "2387728d2589e01287806321bf9c604e25a60ab1",
"appId": "wxf72640a6e689aed1",
"nonceStr": "c507d418-18c3-471c-81df-68cd9c76a792"
},
"success": true
}
\ No newline at end of file
/**
* @note
* @author miaokefu <miaokefu@duiba.com.cn>
* @create 2018-05-16
* @des
*/
/**
* @note
* @author miaokefu <miaokefu@duiba.com.cn>
* @create 2018-05-02
* @des
*/
let path = '/share_packet';
module.exports = {
get: {
'/youtui/temporary/redPacket/share': path + '/share',
},
post: {
}
};
\ No newline at end of file
{
"code": "0000000",
"desc": "成功",
"data": {
"hasAnswer": 0,
"unlockNum": 3,
"shareUrl": "http://localhost:17801/youtui/consumer/share?id=31&type=2&sourceToken=emyBkF63T7h",
"nickName": "vivi",
"userImg": "//yun.playpangu.com/h5-mami/webgame/web-login/header/header1.png"
},
"success": true
}
\ No newline at end of file
{
"code": "0000000",
"desc": "成功",
"data": [
{
"contentName": "极限手速",
"contentDesc": "比手速,拼排名,上榜就有现金领",
"imgUrl": "//yun.dui88.com/h5-mami/webgame/activity/icon.png",
"outside": false,
"playUrl": "http://www.baidu.com"
},
{
"contentName": "极限手速",
"contentDesc": "比手速,拼排名,上榜就有现金领",
"imgUrl": "//yun.dui88.com/h5-mami/webgame/activity/icon.png",
"outside": true,
"playUrl": "http://www.baidu.com"
}
],
"success": true
}
{
"code": "0000000",
"data": {
"bottomAndroid": "//yun.dui88.com/h5-mami/webgame/testTemplate/answer/img/bottom.png",
"bottomIos": "//yun.dui88.com/h5-mami/webgame/testTemplate/answer/img/bottom.png",
"bottomUrlAndroid": "www.baidu.com",
"bottomUrlIos": "www.weibo.com",
"morePagePic": "//yun.dui88.com/h5-mami/webgame/testTemplate/answer/img/more-testmodel.png"
},
"desc": "string",
"success": true
}
\ No newline at end of file
This diff is collapsed.
let path = '/testTemplate';
module.exports = {
get: {
'/youtui/tempalate/test/answer/index': path + '/config',
'/youtui/tempalate/test/answer/share': path + '/result',
'/youtui/content/backFlow': path + '/backFlow',
'/youtui/tempalate/banners': path + '/bottom',
},
post: {
'/youtui/tempalate/test/random/result': path + '/randomResult'
}
};
{
"code": "0000000",
"data": {
"cardImgUrl": "string",
"finalResult": "string",
"index": 0,
"mainUrlTitle": "string",
"maxNum": 0,
"minNum": 0,
"rate": 0,
"ratio": 0,
"result": "string",
"resultImgUrl": "string",
"subUrlTitle": "string"
},
"desc": "string",
"success": true
}
\ No newline at end of file
{
"code": "0000000",
"desc": "成功",
"data": {
"clickUrl": "http://activity.playpangu.com/youtui/consumer/share?id=71&type=8&sourceToken=8PAKwa3RAcNn12&sourceUserId=5512301980&consumerIdOrder=3&pageShareSource=2",
"title": "你知道这些简单的养生常识吗?",
"desc": "全部答对的人不超过1%",
"picUrl": "https://yun.tuitiger.com/mami-youtui/img/pa8tj2fyc1.png",
"shareContentIndex": 1
},
"success": true
}
{
"name": "webpack",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build:file": "node bin/build-entry.js",
"start": "npm run dev",
"dev": "cross-env NODE_ENV=development node bin/dev.js",
"server": "cross-env NODE_ENV=production node ./bin/www",
"lint": "eslint --ext .js src/pages",
"fix": "eslint --fix .js src/pages",
"build": "cross-env NODE_ENV=development node bin/build.js",
"build-prod": "cross-env NODE_ENV=production node bin/build.js",
"pack": "cross-env NODE_ENV=production node bin/pack.js",
"upload": "cross-env NODE_ENV=development node bin/upload.js",
"upload-prod": "cross-env NODE_ENV=production node bin/upload.js"
},
"author": "",
"license": "ISC",
"devDependencies": {
"ali-oss": "^5.3.0",
"autoprefixer": "^8.6.3",
"axios": "^0.18.0",
"babel-core": "^6.26.3",
"babel-eslint": "^8.2.3",
"babel-loader": "^7.1.4",
"babel-plugin-transform-async-to-generator": "^6.24.1",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-env": "^1.7.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-stage-2": "^6.24.1",
"body-parser": "^1.18.3",
"clean-webpack-plugin": "^0.1.19",
"copy-webpack-plugin": "^4.5.1",
"cross-env": "^5.2.0",
"css-loader": "^0.28.11",
"cssnext": "^1.8.4",
"del": "^3.0.0",
"ejs": "^2.6.1",
"ejs-compiled-loader": "^1.1.0",
"ejs-loader": "^0.3.1",
"eslint": "^4.19.1",
"eslint-config-standard": "^11.0.0",
"eslint-friendly-formatter": "^4.0.1",
"eslint-loader": "^2.0.0",
"eslint-plugin-import": "^2.12.0",
"eslint-plugin-node": "^6.0.1",
"eslint-plugin-promise": "^3.8.0",
"eslint-plugin-standard": "^3.1.0",
"express": "^4.16.3",
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"file-loader": "^1.1.11",
"friendly-errors-webpack-plugin": "^1.7.0",
"gulp": "^3.9.1",
"gulp-autoprefixer": "^4.1.0",
"gulp-babel": "^7.0.1",
"gulp-concat": "^2.6.1",
"gulp-less": "^3.4.0",
"gulp-minify-css": "^1.2.4",
"gulp-rename": "^1.3.0",
"gulp-uglify": "^3.0.0",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.2.0",
"html-webpack-script-attributes-plugin": "^1.0.2",
"html-withimg-loader": "^0.1.16",
"less-loader": "^4.1.0",
"node-sass": "^4.9.0",
"opn": "^5.3.0",
"optimize-css-assets-webpack-plugin": "^4.0.2",
"postcss-cssnext": "^3.1.0",
"postcss-import": "^11.1.0",
"postcss-loader": "^2.1.5",
"postcss-px2rem": "^0.3.0",
"precss": "^3.1.2",
"sass-loader": "^7.0.3",
"style-loader": "^0.21.0",
"ts-loader": "^4.4.1",
"url-loader": "^1.0.1",
"vue-loader": "^15.2.4",
"vue-template-compiler": "^2.5.16",
"webpack": "^4.12.0",
"webpack-cli": "^3.0.8",
"webpack-dev-middleware": "^3.1.3",
"webpack-hot-middleware": "^2.22.2",
"webpack-manifest-plugin": "^2.0.3",
"webpack-merge": "^4.1.3"
},
"dependencies": {
"animejs": "^2.2.0",
"better-scroll": "^1.13.2",
"clipboard": "^2.0.1",
"html2canvas": "^1.0.0-alpha.12",
"ifvisible.js": "^1.0.6",
"inline-worker": "^1.1.0",
"jquery": "^3.3.1",
"js-base64": "^2.4.9",
"less": "^2.7.3",
"lodash": "^4.17.10",
"lottie-web": "^5.2.1",
"pako": "^1.0.6",
"promise-polyfill": "^8.0.0",
"qrious": "^4.0.2",
"typescript": "^2.9.2",
"vconsole": "^3.1.0",
"vue": "^2.5.16",
"vue-awesome-swiper": "^3.1.3",
"vue-router": "^3.0.1",
"vue-scroller": "^2.2.4",
"vuex": "^3.0.1",
"babylonjs": "^3.3.0-rc.5",
"babylonjs-gui": "^3.3.0-rc.5",
"babylonjs-loaders": "^3.3.0-rc.5",
"babylonjs-materials": "^3.3.0-rc.5",
"cannon": "^0.6.2",
"earcut": "^2.1.3",
"oimo": "^1.0.9",
"rxjs": "^6.3.3"
}
}
{
"name": "webpack",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build:file": "node bin/build-entry.js",
"start": "npm run dev",
"dev": "cross-env NODE_ENV=development node bin/dev.js",
"server": "cross-env NODE_ENV=production node ./bin/www",
"lint": "eslint --ext .js src/pages",
"fix": "eslint --fix .js src/pages",
"build-dev": "cross-env NODE_ENV=development node bin/build.js",
"build-prod": "cross-env NODE_ENV=production node bin/build.js",
"pack": "cross-env NODE_ENV=production node bin/pack.js",
"upload": "cross-env NODE_ENV=development node bin/upload.js",
"upload-prod": "cross-env NODE_ENV=production node bin/upload.js"
},
"author": "",
"license": "ISC",
"devDependencies": {
"ali-oss": "^5.3.0",
"autoprefixer": "^8.6.3",
"axios": "^0.18.0",
"babel-core": "^6.26.3",
"babel-eslint": "^8.2.3",
"babel-loader": "^7.1.4",
"babel-plugin-transform-async-to-generator": "^6.24.1",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-env": "^1.7.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-stage-2": "^6.24.1",
"body-parser": "^1.18.3",
"clean-webpack-plugin": "^0.1.19",
"copy-webpack-plugin": "^4.5.1",
"cross-env": "^5.2.0",
"css-loader": "^0.28.11",
"cssnext": "^1.8.4",
"del": "^3.0.0",
"ejs": "^2.6.1",
"ejs-compiled-loader": "^1.1.0",
"ejs-loader": "^0.3.1",
"eslint": "^4.19.1",
"eslint-config-standard": "^11.0.0",
"eslint-friendly-formatter": "^4.0.1",
"eslint-loader": "^2.0.0",
"eslint-plugin-import": "^2.12.0",
"eslint-plugin-node": "^6.0.1",
"eslint-plugin-promise": "^3.8.0",
"eslint-plugin-standard": "^3.1.0",
"express": "^4.16.3",
"express-http-proxy": "^1.5.1",
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"file-loader": "^1.1.11",
"friendly-errors-webpack-plugin": "^1.7.0",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.2.0",
"html-webpack-script-attributes-plugin": "^1.0.2",
"html-withimg-loader": "^0.1.16",
"less-loader": "^4.1.0",
"opn": "^5.4.0",
"optimize-css-assets-webpack-plugin": "^4.0.2",
"postcss-cssnext": "^3.1.0",
"postcss-import": "^11.1.0",
"postcss-loader": "^2.1.5",
"postcss-px2rem": "^0.3.0",
"precss": "^3.1.2",
"sass-loader": "^7.0.3",
"style-loader": "^0.21.0",
"ts-loader": "^4.4.1",
"uglifyjs-webpack-plugin": "^2.1.2",
"url-loader": "^1.0.1",
"vue-loader": "^15.2.4",
"vue-template-compiler": "^2.5.16",
"webpack": "^4.12.0",
"webpack-cli": "^3.0.8",
"webpack-dev-middleware": "^3.1.3",
"webpack-dev-server": "^3.2.1",
"webpack-hot-middleware": "^2.22.2",
"webpack-manifest-plugin": "^2.0.3",
"webpack-merge": "^4.1.3"
},
"dependencies": {
"less": "^2.7.3",
"lodash": "^4.17.10",
"promise-polyfill": "^8.0.0",
"typescript": "^2.9.2",
"vconsole": "^3.1.0",
"vue": "^2.5.16",
"vue-awesome-swiper": "^3.1.3",
"vue-router": "^3.0.1",
"vue-scroller": "^2.2.4",
"vuex": "^3.0.1"
}
}
/**
* @note
* @author miaokefu <alfred>
* @create 2018-04-03
* @des
*/
module.exports = {
plugins: [
// require('postcss-import')(),
// require('precss')(),
// require('postcss-calc')(),
// require('postcss-cssnext')()
require('postcss-px2rem')({remUnit: 200}),
require('autoprefixer')({
browsers: ['Android >= 4.0', 'iOS >= 7']
})
]
};
# 推啊游戏webpack工程
## 安装和开发
``` bash
# 安装依赖(建议使用cnpm或yarn)
npm install
# 开发模式 localhost:4000
# 访问地址 http://127.0.0.1:4000/kejiji/webview/content/entry.html
**不传对应文件夹名默认编译所有文件**
npm run dev '文件夹名'
npm start '文件夹名'
# 构建
由于打包会自动上传图片,请先使用tinypng压缩图片,减少资源体积
npm run build '文件夹名' --replace='时间戳' 打包到测试环境,添加一个replace时间戳参数,用来覆盖cdn,只在dev环境下有效
npm run build-prod '文件夹名' 打包到线上环境
# 自动生成入口文件
npm run build:file
# 打包单个组件(css嵌入到js中)
npm run build pack '文件夹名'
bundle文件夹下创建对应的入口文件,引入组件然后将类绑定在window.CREATE下
# 上传文件到cdn
由于打包会自动上传图片,请先使用tinypng压缩图片,减少资源体积
npm run upload '文件夹名' 上传文件到测试环境
npm run upload-prod '文件夹名' 上传文件到线上环境
例如:npm run upload 'dist/'
将dist/目录下的所有文件包含子文件夹都上传到/config/index.js里配置的build.cdnDir目录下
## 项目结构
|--bin // 脚本目录
|--build // 项目构建相关文件
|--config
| |--entry.js // 自动生成的入口文件
| |--index.js // 配置文件
|--dist // 打包输出目录
|--gulp // gulp输出目录,旧游戏项目使用
|--mock // mock数据目录
|--service // http接口请求
| |--apis
| |--common.js // 通用http接口请求
| |--track.js // 埋点
| |--http.js // 基础http接口请求
|--src
| |--common
| |--css // 公用css
| |--images // 常用图片
| |--js // 公用js
| |--layout // 公用的html模块
| |--lib // js类库
| |--components // 页面通用js组件
| |--pages // h5页面目录
| |--game // 游戏
| |--landing // 落地页
| |--app // app内h5页面
| |--activity // 活动页
| |--temp // 临时需求
| |--article // 热文
| |--index // 目录页
| |--labs // 测试页面
|--static // express 静态目录
|--.eslintignore // eslint忽略配置
|--.eslintrc.js // eslint规则
|--.gitignore // git忽略配置
|--app.js // express服务器
|--gulpfile.js // gulp配置
|--postcss.config.js // postcss配置
|--tsconfig.json // typescript配置
\ No newline at end of file
/*
* @Author: miaokefu@duiba.com.cn
* @Date: 2018-08-08 21:00:54
* @Last Modified by: Dec-F (fanxuehui@duiba.com.cn)
* @Last Modified time: 2018-09-04 16:14:44
*/
import {getUrlParameter} from '@js/utils';
import {get, post} from '../../http';
/**
* 获取所有题目及其他数据
*/
export const getConfig = () => get('/youtui/questionKing/findQuestionList', {
consumerIdOrder: getUrlParameter('consumerIdOrder'),
});
/**
* cdk
*/
export const getCDK = () => get('/youtui/questionKing/getCDK',{
id: getUrlParameter('id')
});
/**
* 埋点数据
*/
export const getEmbed = () => {
return indexedDB({
})
}
export const checkAnswer = (questionId, userAnswerId) => get('/youtui/questionKing/checkAnswer', {
questionId: questionId,
userAnswerId: userAnswerId
});
export const getShareInfo = (bonus) => get('/youtui/questionKing/getShareUrl', {
id: getUrlParameter('id'),
consumerIdOrder: getUrlParameter('consumerIdOrder'),
bonus: bonus
});
/*
* @Author: miaokefu@duiba.com.cn
* @Date: 2018-08-21 17:11:21
* @Last Modified by: Dec-F (fanxuehui@duiba.com.cn)
* @desc 热文接口
*/
import {getUrlParameter} from '@js/utils';
import {get, post} from '../../http';
/**
* 获取文章信息
*/
export const getArticleInfo = () => get('/youtui/hotText/info', {
id: getUrlParameter('id'),
appPreview: getUrlParameter('appPreview'),
pageId: getUrlParameter('pageId')
});
/**
* 获取评论
*/
export const getComment = () => get('/youtui/content/countComment', {
contentId: getUrlParameter('id'),
contentType: getUrlParameter('type'),
start: 0
});
/**
* 获取内容点赞数
*/
export const getStar = () => get('/youtui/content/countStar', {
contentId: getUrlParameter('id'),
contentType: getUrlParameter('type')
});
/**
* 获取当前用户对指定分享内容的点赞状态
*/
export const getStarStatus = () => get('/youtui/content/starStatus', {
contentId: getUrlParameter('id'),
contentType: getUrlParameter('type')
});
/**
* 内容评论
* @param { } commentId
* @param {*} commentText
*/
export const postComment = (commentText, commentId) => {
let params = {
contentId: getUrlParameter('id'),
contentType: getUrlParameter('type'),
commentId: commentId,
commentText: commentText,
}
if (!getUrlParameter('appPreview')) {
params.shareUserId = getUrlParameter('sourceUserId');
}
return post('/youtui/content/comment', params);
}
/**
* 内容点赞
*/
export const postStar = () => {
let params = {
contentId: getUrlParameter('id'),
contentType: getUrlParameter('type')
};
if (!getUrlParameter('appPreview')) {
params.shareUserId = getUrlParameter('sourceUserId');
}
return post('/youtui/content/star', params);
};
/**
* 顶通低通
*/
export const getBanners = () => get('/youtui/content/banners');
/**
* 文章列表
*/
export const getAppArticleList = () => get('/youtui/content/appArticleList', {
appPreview: getUrlParameter('appPreview'),
contentIdOrder: getUrlParameter('contentIdOrder'),
id: getUrlParameter('id')
});
/**
* 看一看列表
*/
export const getH5ArticleList = () => get('/youtui/content/h5ArticleList',{
contentIdOrder: getUrlParameter('contentIdOrder'),
id: getUrlParameter('id')
});
/**
* 编辑推荐
*/
export const getRecommends = () => get('/youtui/content/recommends', {
contentIdOrder: getUrlParameter('contentIdOrder'),
appPreview: getUrlParameter('appPreview'),
id: getUrlParameter('id')
});
/**
* 获取资源位
*/
export const getResource = () => get('/youtui/content/resource');
/*
* @Author: miaokefu@duiba.com.cn
* @Date: 2018-08-30 11:58:43
* @desc 金币派送
*/
import {getUrlParameter} from '@js/utils';
import {get, post} from '../../http';
export const getIndex = () => get('/goldSend/index');
/**
* 参与
* @param {*} amount
* @param {*} actNum 活动编号 1 10点活动 2 20点活动
*/
export const doJoin = (amount,actNum ) => get('/goldSend/doJoin' , {
amount: amount,
actNum: actNum
});
/**
* 完成
* @param {*} actNum 活动编号 1 10点活动 2 20点活动
*/
export const finish = (actNum) => get('/goldSend/finish', {
actNum: actNum
});
/**
* 获取游戏结果的金币数量
* @param {*} actNum 活动编号 1 10点活动 2 20点活动
*/
export const result = (actNum) => get('/goldSend/result', {
actNum: actNum
});
/**
* 开始游戏
* @param {*} actNum 活动编号 1 10点活动 2 20点活动
*/
export const start = (actNum) => get('/goldSend/start', {
actNum: actNum
});
/**
* 获取分享信息
* @param {*} actNum 活动编号 1 10点活动 2 20点活动
*/
export const getShareInfo = (actNum) => get('/goldSend/share', {
id: getUrlParameter('id'),
actNum: actNum
});
/**
* 获取参与人数
*/
export const personCount = () => get('/goldSend/personCount');
/**
* 好友助力
*/
export const boost = () => get('/goldSend/boost', {
joinTime: getUrlParameter('joinTime'),
actNum: getUrlParameter('actNum'),
sourceId: getUrlParameter('sourceId')
});
/**
* 好友助力2
*/
export const boost2 = (actNum) => get('/goldSend/boost2', {
id: getUrlParameter('id'),
actNum: actNum
});
import { getUrlParameter } from '@js/utils';
import { get, post } from '../../http';
/**
* 获取开奖信息
*/
const options = {
id: getUrlParameter('contentId'),
tender: Number(getUrlParameter('appPreview')),
prizeId: getUrlParameter('prizeId'),
consumerIdOrder: getUrlParameter('consumerIdOrder'),
cdKey: getUrlParameter('cdKey')
};
export const openPrize = () => get('/youtui/ttl/openPrize');
export const getIndex = () => get('/youtui/ttl/index', options);
export const getShare = () => post('/youtui/ttl/share', options);
export const getTicket = () => post('/youtui/ttl/getTicket',options);
export const getCdk = () => get('/youtui/ttl/getCdKey', options);
export const getPrizePersonList = () => get('/youtui/ttl/getPrizePersonList',options);
import { getUrlParameter } from '@js/utils';
import { get, post } from '../../http';
export const getIndex = () => get('/youtui/greetingCard/index', {
id: getUrlParameter('id'),
sourceUserId: getUrlParameter('sourceUserId'),
sourceToken: getUrlParameter('sourceToken'),
consumerIdOrder: getUrlParameter('consumerIdOrder'),
appPreview: getUrlParameter('appPreview'),
recordId: getUrlParameter('recordId')
});
export const getWxShareInfo = (opts) => get('/youtui/greetingCard/share', {
consumerIdOrder: getUrlParameter('consumerIdOrder'),
contentType: getUrlParameter('type'),
contentId: getUrlParameter('id'),
cardId: opts.cardId,
appPreview: getUrlParameter('appPreview'),
cardContentId: opts.cardContentId,
userContent: opts.userContent
});
import {getUrlParameter} from '@js/utils';
import {get, post} from '../../http';
import {getStorage} from "@common/js/utils"
/**
* 获取配置信息
* @param {*} resultStatus 参与状态,0 未参与 1 参与
* @param {*} isPic 是否为二维码链接
*/
export const getIndex = ( resultStatus, isPic) => get('/userKeyWord/index', {
id: getUrlParameter('id'),
consumerIdOrder: getUrlParameter('consumerIdOrder'),
appPreview: getUrlParameter('appPreview') || 0,
isPic :isPic || '',
resultStatus: resultStatus
});
export const doJoin = () => get('/userKeyWord/doJoin', {
id: getUrlParameter('id'),
appPreview: getUrlParameter('appPreview'),
consumerIdOrder: getUrlParameter('consumerIdOrder')
});
export const getShareInfo = (resultStatus) => get('/userKeyWord/share', {
contentId: getUrlParameter('id'),
contentType: getUrlParameter('type'),
consumerIdOrder: getUrlParameter('consumerIdOrder'),
resultStatus: resultStatus
});
\ No newline at end of file
import { getUrlParameter } from '@js/utils';
import { get, post } from '../../http';
export const saveImage = (opts) => post('/youtui/album/save', {
imgUrls: opts.imgUrls,
bgmId: parseInt(opts.bgmId,10),
templateId: parseInt(opts.templateId, 10),
appPreview: getUrlParameter("appPreview")
});
export const getHistoryList = (opts) => get('/youtui/album/list', {
currentPage: parseInt(opts.currentPage,10),
pageSize: 10,
appPreview: getUrlParameter("appPreview")
});
export const getDetail = (opts) => get('/youtui/album/detail', {
albumId: parseInt(opts.albumId,10),
appPreview: getUrlParameter("appPreview")
});
export const getIndex = (opts) => get('/youtui/album/index', {
contentId: getUrlParameter("id"),
appPreview: getUrlParameter("appPreview"),
consumerIdOrder: getUrlParameter("consumerIdOrder"),
recordId: getUrlParameter("recordId")
});
export const getShare = (opts) => get('/youtui/album/share', {
contentId: getUrlParameter("id"),
appPreview: getUrlParameter("appPreview"),
consumerIdOrder: getUrlParameter("consumerIdOrder"),
headImgUrl: opts.headImgUrl || getUrlParameter("headImgUrl"),
nickName: opts.nickName || getUrlParameter("nickName"),
recordId: getUrlParameter("recordId"),
contentType: getUrlParameter("type"),
sourceUserId: getUrlParameter("sourceUserId"),
albumId: opts.albumId,
saveSwitch: opts.saveSwitch
});
export const wxUpload = (opts) => post('/youtui/album/download', {
mediaIds: opts.mediaIds
});
\ No newline at end of file
import {getUrlParameter} from '@js/utils';
import {get, post} from '../../http';
export const getIndex = (recordId) => get('/youtui/national/index', {
img: getUrlParameter('img'),
nickName: decodeURIComponent(getUrlParameter('nickName')) ,
contentId: getUrlParameter('id'),
consumerIdOrder: getUrlParameter('consumerIdOrder'),
appPreview: getUrlParameter('appPreview'),
recordId: recordId || getUrlParameter('recordId'),
});
export const getWxUserInfo = () => get('/youtui/national/getWxUserInfo', {
});
export const sendBless = ({
userName, userImg, province, content, type,isSave , recordId
}) => get('/youtui/national/share', {
recordId: recordId, // 当自己访问自己分享内容时,需要把上一次的分享内容带上
userName: userName || 'vi',
userImg: userImg || 'vi-pic',
province: province,
content: content,
type: type,
contentId: getUrlParameter('id'),
consumerIdOrder: getUrlParameter('consumerIdOrder'),
appPreview: getUrlParameter('appPreview'),
contentType: getUrlParameter('type'),
saveSwitch: isSave // 是否保存记录
});
/*
* @Author: miaokefu@duiba.com.cn
* @Date: 2018-08-14 13:09:00
* @Last Modified by: miaokefu@duiba.com.cn
* @Last Modified time: 2018-08-15 16:57:15
*/
import {getUrlParameter} from '@js/utils';
import {get} from '../../http';
/**
* 获取页面初始化信息
* @param isPic 是否从二维码进入
* 页面类型 0:占卜页面;1:分享者-结果页面 2:自己-结果页面 ,
*/
export const getIndex = (isPic) => get('/youtui/qixi/index', {
id: getUrlParameter('id'),
isPic: isPic,
consumerIdOrder: getUrlParameter('consumerIdOrder')
});
/**
* cdk
*/
export const getCDK = () => get('/youtui/qixi/getCDK',{
id: getUrlParameter('id')
});
export const getKeyword = () => get('/youtui/qixi/getKeyword',{
});
export const getRedPacket = () => get('/youtui/qixi/getRedPacket',{
});
export const getShareInfo = (title) => get('/youtui/share/getQixiShareUrl',{
id: getUrlParameter('id'),
consumerIdOrder: getUrlParameter('consumerIdOrder'),
title: title
// bonus: 8.8 // 写死
});
import {getUrlParameter} from '@js/utils';
import {get, post} from '../../http';
/**
* 获取页面初始化信息
* @param isPic 是否从二维码进入
* 页面类型 0:占卜页面;1:分享者-结果页面 2:自己-结果页面 ,
*/
export const getIndex = (tender) => get('/youtui/yanxi/index', {
id: getUrlParameter('id'),
consumerIdOrder: getUrlParameter('consumerIdOrder'),
tender
});
export const getList = () => get('/youtui/yanxi/getQuestionList', {});
export const getResult = (answer, tender) => get('/youtui/yanxi/getYanxiResult', {
answer: encodeURI(answer),
tender
});
export const getWxShareUrl = (type) => get('/youtui/share/getYanxiShareUrl', {
type: type,
id: getUrlParameter('id'),
consumerIdOrder: getUrlParameter('consumerIdOrder')
});
export const getDownloadUrl = () => get('/youtui/system/getDownloadUrl', {
channelString: "yysc-cc-a-yxgl-97-2"
});
import {getUrlParameter} from '@js/utils';
import {get, post} from '../../http';
/**
* 获取提现记录
*/
export const getCashRankList = () => get('/server/consumer/getCashRankList', {});
\ No newline at end of file
/*
* @Author: miaokefu@duiba.com.cn
* @Date: 2018-08-13 13:32:44
* @Last Modified by: miaokefu@duiba.com.cn
* @Last Modified time: 2018-09-20 16:42:19
* @desc 公用的http后端请求
*/
import { getUrlParameter } from '@js/utils';
import { get, post } from '../http';
/**
* 获取apk下载链接
* @param {*} channel
*/
export const getDownloadUrl = channel =>
get('/youtui/system/getDownloadUrl', {
channelString: channel,
});
/**
* 获取微信初始化信息
* @param {*} url 不带#后面部分
*/
export const getWxConfig = url =>
get('/youtui/context/getWxConfig', {
url: url,
contentId: getUrlParameter('id'),
contentType: getUrlParameter('type')
});
/**
* 获取app端内分享信息
*/
export const getAppShareInfo = (shareFrom = 1) =>
get('/youtui/content/share', {
contentId: getUrlParameter('id'),
contentType: getUrlParameter('type'),
shareFrom: shareFrom, // 固定为1 点击分享来源(0:app卡片;1:预览页)
});
/**
* 端外通用分享信息接口
* @param {*} extParam 扩展参数
*/
export const getCommonShare = extParam =>
get('/youtui/share/commonShareUrl', {
contentId: getUrlParameter('id'),
contentType: getUrlParameter('type'),
consumerIdOrder: getUrlParameter('consumerIdOrder'),
...extParam,
});
export const getLandAB = () => get('/youtui/ab/getLand');
/**
* 上传图片
* @param {*} data
*/
export const uploadPic = data =>
post(
'/upload/uploadPicByBase64',
{
picBase64: data,
},
{
headers: { 'content-type': 'application/json;charset=UTF-8' },
}
);
/**
* 获取短链
* @param {String} url 原链接
*/
export const getShortLink = url => {
let regexp = /^https?:\/\/(([a-zA-Z0-9_-])+(\.)?)*(:\d+)?((\/((\.)?(\?)?=?&?[a-zA-Z0-9_-](\?)?)*)*)$/i;
let matchObj = regexp.exec(url);
let path = matchObj ? matchObj[5] : url;
return get('/qsaK/create', {
path: encodeURIComponent(path), // url去除协议和域名部分
});
};
/**
* 上传音频
* @param {*} data
*/
export const uploadAudio = data =>
post(
'/upload/uploadSoundByBase64',
{
picBase64: data,
},
{
headers: { 'content-type': 'application/json;charset=UTF-8' },
}
);
\ No newline at end of file
/*
* @Author: miaokefu@duiba.com.cn
* @Date: 2018-08-27 19:31:54
*/
import { getUrlParameter } from '@js/utils';
import { get } from '../../http';
/**
* cdk
*/
export const getCDK = () =>
get('/youtui/farm/getCdkey', {
gameId: getUrlParameter('id')
});
export const getGameList = () =>
get('/youtui/content/backFlow', {
contentId: getUrlParameter('id')
});
/*
* @Author: hanqing@duiba.com.cn
* @Date: 2018-10-02
*/
import {getUrlParameter} from '@js/utils';
import {get} from '../../http';
/**
* user
*/
export const getUser = () => get('/youtui/user/getSourceUserInfo',{
});
export const countDownLoadNum = () => get('/youtui/farm/countDownLoadNum',{
});
export const countShareNum = () => get('/youtui/farm/countShareNum',{
clickType: getUrlParameter('clickType'),
timp:getUrlParameter('timp'),
gameId: getUrlParameter('gameId')
});
\ No newline at end of file
/*
* @Author: miaokefu@duiba.com.cn
* @Date: 2018-10-18 10:29:26
*/
import { getUrlParameter } from '@js/utils';
import { get, post } from '../http';
/**
* 获取资源位
*/
export const getResource = ()=> get('/youtui/pdd/resource');
\ No newline at end of file
import { getUrlParameter } from '@js/utils';
import { get, post } from '../http';
export const getIndex = params =>
get('/youtui/tempalate/test/answer/index', {
id: getUrlParameter('id'),
consumerIdOrder: getUrlParameter('consumerIdOrder'),
...params,
});
export const sendResultAndShare = params =>
get('/youtui/tempalate/test/answer/share', {
id: getUrlParameter('id'),
sourceUserId: getUrlParameter('sourceUserId'),
consumerIdOrder: getUrlParameter('consumerIdOrder'),
...params,
});
export const testAgain = params =>
get('/youtui/tempalate/test/answer/testAgain', {
id: getUrlParameter('id'),
consumerIdOrder: getUrlParameter('consumerIdOrder'),
...params,
});
export const getDownloadUrl = () =>
get('/youtui/system/getDownloadUrl', {
channelString: 'yysc-cc-a-yxgl-97-2',
});
export const getResult = (params) => {
console.log(params,"params")
return post('/youtui/tempalate/test/random/result', {
id: getUrlParameter('id'),
list: params
});
}
export const getBottom = (params) => {
return get('/youtui/tempalate/banners');
}
\ No newline at end of file
/*
* @Author: miaokefu@duiba.com.cn
* @Date: 2018-08-13 14:06:04
* @Last Modified by: miaokefu@duiba.com.cn
* @Last Modified time: 2018-10-26 12:46:42
* @desc 统一埋点接口
*/
import { parseUrlParams, deleteInvalidKey} from '@js/utils';
import axios from 'axios';
let urlParams = parseUrlParams();
let {
sessionKey,
sourceToken,
sourceUserId,
consumerIdOrder,
appPreview,
share_way,
shareContentIndex,
isPic,
version,
contentIdOrder
} = urlParams;
let contentId = urlParams.id;
let contentType = urlParams.type;
/**
* 用户行为埋点
* @param {Number} type 埋点类型
* @param {Object} data 特殊字段对象
* @desc type = 801时需要传入当前分享信息的shareContentIndex和share_way,而不是url上的shareContentIndex和share_way,统计当前分享文案以及分享渠道对回访的影响
*
*/
const track = (type, data) => {
if (type === undefined || type === null) {
console.error('埋点值不能为空');
}
// type为1需要传入整个url参数纪录访问
// 08.22 所有埋点统一拼上urlQuery,不再区分type为1的情况
// if (type === 1) {
data = Object.assign({}, data, { urlQuery: urlParams })
// }
return axios({
method: 'get',
url: '/youtui/log/embedContentLogs',
params: deleteInvalidKey({
type: type,
sessionKey: sessionKey,
sourceToken: sourceToken,
sourceUserId: sourceUserId,
contentId: contentId, // 内容id
contentType: contentType, // 内容类型
consumerIdOrder: consumerIdOrder,
appPreview: appPreview,
share_way: share_way,
shareContentIndex: shareContentIndex, // 分享标题文案分流用的
isPic: isPic,
version: version,
// content_id_order: contentIdOrder || 1,
...data
}),
timeout: 3000,
});
}
export default track;
import * as constants from '@js/constants';
import { getNetworkType, getUrlParameter } from '@js/utils';
import axios from 'axios';
import qs from 'qs';
const handleResult = (res, errorInfo) => {
let { data, success, desc, code } = res.data;
if (success && code === '0000000') {
return data;
} else {
console.error(errorInfo || 'getTuiaApi error', code, desc);
}
};
/**
* 获取token
*/
const getToken = userId => {
return axios({
method: 'post',
url: constants.TUIA_IP + '/viewAdvert/getToken',
data: qs.stringify({
appKey: constants.TUIA_APP_KEY,
slotId: constants.TUIA_SLOT_ID,
deviceId: userId,
}),
headers: { 'content-type': 'application/x-www-form-urlencoded;charset=UTF-8' },
})
.then(res => {
return handleResult(res, 'getTuiaToken error');
})
.catch(err => {
console.error(err);
});
};
/**
* 获取广告
* @param {*} token
* @param {*} ip
*/
const getAdvert = (token, ip) => {
return axios({
method: 'post',
url: constants.TUIA_IP + '/viewAdvert/getAdvert',
data: qs.stringify({
token: token,
userAgent: navigator.userAgent,
ip: ip,
networkType: getNetworkType(),
}),
headers: { 'content-type': 'application/x-www-form-urlencoded;charset=UTF-8' },
})
.then(res => {
let { data, success, code } = res.data;
// res中塞入token
if (success && code === '0000000') {
data && Object.assign(data, { token: token });
}
return handleResult(res, 'getTuiaAdvert error');
})
.catch(err => {
console.error(err);
});
};
/**
* 发送tuia埋点
* @param {*} token
* @param {*} orderId
* @param {*} event
*/
const eventReport = (token, orderId, event) => {
return axios({
method: 'post',
url: constants.TUIA_IP + '/viewAdvert/eventReport',
data: qs.stringify({
token: token,
orderId: orderId,
event: event,
userAgent: navigator.userAgent,
}),
headers: { 'content-type': 'application/x-www-form-urlencoded;charset=UTF-8' },
})
.then(res => {
return handleResult(res, 'getTuiaToken error');
})
.catch(err => {
console.error(err);
});
};
const getTuiaAdvert = (ip, userId) => {
return getToken(userId)
.then(data => {
console.log(data);
return getAdvert(data, ip);
})
.then(data => {
return data;
});
};
export { getToken, getAdvert, eventReport, getTuiaAdvert };
import {getUrlParameter} from '@js/utils';
import qs from 'qs';
import axios from 'axios';
// import toast from '@components/toast/2.0.0';
import Promise from 'promise-polyfill';
axios.defaults.timeout = 10000; // 超时时间
// 根据环境设置baseUrl
// let baseUrl = '';
// if (process.env.NODE_ENV === 'development') {
// baseUrl = '';
// } else if (process.env.NODE_ENV === 'production') {
// baseUrl = '';
// }
// axios.defaults.baseURL = baseUrl;
// axios请求拦截
axios.interceptors.request.use(
config => {
// 统一拼上固定要传的参数
let method = config.method;
let baseParams = {
sessionKey: getUrlParameter('sessionKey'),
sourceToken: getUrlParameter('sourceToken'),
sourceUserId: getUrlParameter('sourceUserId')
}
// 本地开发模拟用户
if (getUrlParameter('debug')) {
baseParams.sessionKey = 'nFgB9FwDLjiui2F86D8gJhzV8BDMBGkPLfzzLK6rB';
baseParams.sourceToken = 'emyBj9UvCLx';
baseParams.sourceUserId = '10831004';
}
// config.headers.base = baseParams;
// if (method === 'get') {
config.params = {...baseParams, ...config.params}
// } else
if (method === 'post' && config.headers['content-type'] == 'application/x-www-form-urlencoded;charset=UTF-8'){
// config.data = qs.stringify(config.data);
}
return config;
},
error => {
return Promise.error(error);
}
);
// axios响应拦截
axios.interceptors.response.use(
response => {
if (response.status === 200) {
return Promise.resolve(response);
} else {
return Promise.reject(response);
}
}
)
const handleReuslt = (res, resolve, reject) => {
let {
data,
success,
desc,
code
} = res.data;
if (code == '0000000') {
resolve(data);
} else {
console.error('服务端返回 code !== 0000000');
console.error(res.data);
reject(res.data);
}
}
export const get = (url, params, config)=> {
return new Promise((resolve, reject)=>{
axios({
method:'get',
url:url,
params: params,
paramsSerializer: function(params) {
return qs.stringify(params, {arrayFormat: 'repeat'})
},
...config
}).then(res => {
handleReuslt(res, resolve, reject);
}).catch(err => {
console.error(err);
reject(err.data);
});
});
}
export const post = (url, params,config)=> {
return new Promise((resolve, reject)=>{
axios({
method:'post',
url:url,
data: params,
// headers: { 'content-type': 'application/x-www-form-urlencoded;charset=UTF-8' },
headers: { 'content-type': 'application/json;charset=UTF-8' },
...config
}).then(res => {
handleReuslt(res, resolve, reject);
}).catch(err => {
console.error(err);
reject(err.data);
});
});
}
// 浮标、插件、主会场常用代码块
// 变量 是否必须 默认值 可选值 说明
// @img_url_prod 是 生产环境图片地址
// @img_url_dev 是 开发环境图片路径
// @env 否 'dev' dev, prev, prod 环境定义,之后可通过gulp replace在打包时替换值
// @screen_width 否 640 设计稿尺寸
@env: 'dev';
@url_prod: @img_url_prod;
@url_prev: @img_url_dev; // 本地手机端预览,在对应less文件所在文件夹下创建img文件夹放置本地测试图片
@url_dev: @img_url_dev; //本地环境
@url: `@{env} === 'dev' ? @{url_dev} :@{env} === 'prev' ? @{url_prev}: @{url_prod}`;
@screen_width: 640;
@rem_base_prod: 200rem * @screen_width / 640; // prod
@rem_base_dev: 1px; //dev chrome中将屏幕宽度改为640 方便调整位置
@str_rem_base_prod: 'rem_base_prod';
@str_rem_base_dev: 'rem_base_dev';
// js中不能识别1rem或者1px这种非字符串,通过@字符串值获取这两者
@str_rem_base: `@{env} === 'dev' ? @{str_rem_base_dev} : @{str_rem_base_prod}`;
@rem: @@str_rem_base;
// 开发过程中chrome中创建的750设备会被限制在640的body中
//测试环境下,还未转为rem,在设计稿超出640时,需要解除body最大宽度限制
body when(@env = 'dev') and (@screen_width > 640) {
max-width: none;
}
// 背景设置方法
.publicBackground(@img, @repeat: no-repeat) {
background-size: cover;
background-repeat: @repeat;
}
// @img为''时不设置背景图片地址,主要用于活动工具中背景无初始值使用
.publicBackground(@img, @repeat: no-repeat) when not (@img = '') {
background-image: url("@{url}@{img}");
}
// 定位设置方法 左上
.positiona(@top, @left) {
position: absolute;
top: @top/@rem;
left: @left/@rem;
}
// 定位设置方法 右上
.positionb(@top, @right) {
position: absolute;
top: @top/@rem;
right: @right/@rem;
}
//宽高设置方法
.widhei(@width, @height) {
width: @width/@rem;
height: @height/@rem;
}
.hide {
display: none;
}
\ No newline at end of file
/*
* @Author: alfred
* @Date: 2018-04-12 17:06:00
* @Last Modified by: miaokefu@duiba.com.cn
* @Last Modified time: 2018-09-19 16:46:25
*/
html, body, h1, h2, h3, h4, h5, h6, div, dl, dt, dd, ul, ol, li, p, blockquote, pre, hr, figure,
table, caption, th, td, form, fieldset, legend, input, button, textarea, menu {
margin: 0;
padding: 0;
}
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
*:before,
*:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
ul {
padding: 0;
margin: 0;
}
img {
vertical-align: middle;
max-width: 100%;
}
ul {
list-style: none;
}
a {
text-decoration: none;
&:link, &:visited, &:hover, &:active {
color: inherit;
}
}
body {
/*苹果手机点击阴影去除*/
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
/*在ios中,调整字体大小,会改变body的css属性:-webkit-text-size-adjust,导致字体大小变大。*/
-webkit-text-size-adjust: 100% !important;
}
a {
outline: none;
-moz-outline-style: none;
}
/*苹果手机点击阴影去除*/
html {
//overflow-x: hidden;
}
body {
font-size: 12px; /*no*/
line-height: 1;
//overflow-x: hidden;
width: 100%;
margin: 0 auto;
color: #333;
// background-color: #f0f0f0;
-webkit-overflow-scrolling: touch;
-webkit-touch-callout: none;
}
// safari 及某些浏览器必须设置 inherit , 否则将使用默认样式
// 1. Correct color not being inherited.
// Known issue: affects color of disabled elements.
// 2. Correct font properties not being inherited.
// 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
//
button,
input,
optgroup,
select,
textarea {
color: inherit; // 1
font: inherit; // 2
margin: 0; // 3
}
input, textarea {
outline: none;
border: none;
}
button{
border: none;
}
select {
line-height: 1;
-webkit-appearance: none;
border: 0;
background: transparent;
width: 100%;
height: 100%;
display: block;
}
a:link , a:visited , a:hover , a:active{
text-decoration:none;
}
html{
font-size: 12px;
}
.clearfix {
zoom: 1;
&:before, &:after {
content: "";
display: table;
}
&:after {
clear: both;
overflow: hidden;
}
}
.line1() {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.hide {
display: none;
}
.clearfix() {
*zoom: 1;
&:before,
&:after {
display: table;
content: '';
}
&:after {
clear: both;
}
}
.hidden() {
display: none !important;
visibility: hidden;
}
.line0() {
overflow: hidden;
white-space: nowrap;
}
.line1() {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.line2() {
display: -webkit-box;
overflow: hidden;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
.line3() {
display: -webkit-box;
overflow: hidden;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
}
.linex(@num) {
display: -webkit-box;
overflow: hidden;
-webkit-box-orient: vertical;
-webkit-line-clamp: @num;
}
.perspective(@value: 1000) {
-webkit-perspective: @value;
-moz-perspective: @value;
-ms-perspective: @value;
perspective: @value;
}
// user select 不允许用户选中页面中文字
.user-select-none() {
-webkit-user-select: none;
/* Chrome all / Safari all */
-ms-user-select: none;
/* IE 10+ */
user-select: none;
}
//数字 字体加粗 用Helvetica Neue字体
.font-weight() {
font-family: 'Helvetica Neue', HeitiJ-Light, Helvetica, STHeiTi, sans-serif;
-webkit-font-smoothing: antialiased;
font-weight: bold;
}
.base64(@width, @height, @src) {
width: @width;
height: @height;
background-size: contain;
background-repeat: no-repeat;
background-image: url(@src);
display: inline-block;
}
//设置宽高
.size(@width: 1, @height: 1) {
width: @width*1px;
height: @height*1px;
} //设置背景图片
.bgi(@src) {
background-image: url(@src);
background-repeat: no-repeat;
background-size: contain;
}
.bgc(@src) {
background-image: url(@src);
background-repeat: no-repeat;
background-size: cover;
}
.bgf(@src) {
background-image: url(@src);
background-repeat: no-repeat;
background-size: 100% 100%;
}
//设置段落
.text(@fontsize, @height: @fontsize, @lineheight: @height) {
font-size: @fontsize*1px;
height: @height*1px;
line-height: @lineheight*1px;
} //清除浮动
.clearfix {
&::after {
content: '';
display: table;
clear: both;
}
} //垂直水平居中
.middle {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
} //水平居中
.center {
margin-left: auto;
margin-right: auto;
} //绝对定位
.pos(@left: 0, @top: 0) {
position: absolute;
left: @left*1px;
top: @top*1px;
}
.posr(@right: 0, @top: 0) {
position: absolute;
top: @top*1px;
right: @right*1px;
}
.gray {
filter: grayscale(100%);
filter: gray;
}
.tooltip {
@width: 300;
@height: 80;
@border: 2;
@borderSize: 10;
display: inline-block;
.size(@width, @height);
background: #fffae1;
border: @border*1px solid #8b572a;
border-radius: 10px;
.text(30, @height);
color: #8b572a;
text-align: center;
position: absolute;
&:after,
&:before {
content: ' ';
.size(0, 0);
}
&:after {
position: absolute;
top: (@height - 2 * @border) * 1px;
left: (@width - @borderSize*2)/2 * 1px;
display: inline-block;
border: solid @borderSize*1px;
border-color: #fffae1 transparent transparent transparent;
z-index: 2;
}
&:before {
position: absolute;
top: (@height - 1.5 * @border) * 1px;
left: (@width - @borderSize*2 - @border*2)/2 * 1px;
display: inline-block;
border: solid (@borderSize+ @border) * 1px;
border-color: #8b572a transparent transparent transparent;
z-index: 1;
}
}
.flex_mid {
display: flex;
align-items: center;
justify-content: center;
}
.ellipsis {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
require('@lib/zepto/1.1.4/index');
require('./statistics-3');
let $ = window.Zepto;
export default $
/**
* 检查是否支持.webp 格式图片
*
* 支持 webp CDN ?x-oss-process=image/format,webp
* 不支持 CDN ?x-oss-process=image/quality,Q_80
*/
;
(function() {
var urlarr = [];
// localStorage存在且之前没设置过iswebp
if (localStorage && !localStorage.iswebp) {
var cs = document.createElement('canvas');
// 如果不支持canvas则退出
if (cs.getContext && cs.getContext('2d')) {
try {
localStorage.iswebp = (0 === cs.toDataURL('image/webp').indexOf('data:image/webp'));
} catch (e) {
// safari 浏览器无恒模式在低于11版本会有bug
// https://stackoverflow.com/questions/21159301/quotaexceedederror-dom-exception-22-an-attempt-was-made-to-add-something-to-st
console.error(e);
}
}
}
function getOssImg(url) {
if (!url) {
return url;
}
// 不支持localStorage或者没有设置过iswebp或者isweb是false
if (!localStorage || !localStorage.iswebp || localStorage.iswebp === 'false') {
url = url + '?x-oss-process=image/quality,Q_80';
return url;
} else {
// gif 的图片不做处理
urlarr = url.split('.');
if (urlarr.length > 0 && urlarr[urlarr.length - 1] === 'gif') {
return url;
}
url = url + '?x-oss-process=image/format,webp';
return url;
}
}
String.prototype.ossimg = function() {
return getOssImg(this);
};
})();
export const TUIA_SLOT_ID = 199649;
export const TUIA_APP_KEY = '3VM75AhAQUCJMP2cwdH4j7q9JCp8';
export const TUIA_IP = '//activity.tuia.cn';
\ No newline at end of file
import axios from 'axios';
import { parseUrlParams } from './utils';
let { sourceToken, sessionKey, sourceUserId } = parseUrlParams();
export default (fetch = function(opts) {
return new Promise(function(resolve, reject) {
opts.params = opts.params || {};
Object.assign(opts.params, {
sourceToken,
sessionKey,
sourceUserId
});
axios(opts)
.then(function(res) {
res = res.data;
if (res.success) {
resolve(res.data);
} else {
reject(res);
}
})
.catch(function(err) {
reject(err);
});
});
});
/*
* @Author: Zhang Min
* @Date: 2018-05-14 14:41:49
* @Last Modified by: miaokefu@duiba.com.cn
* @Last Modified time: 2018-08-16 16:57:20
*/
/**
* 预加载图片
* 1.调用 preload(image, useWebp)
* 2.image 图片路径数组/图片路径名称
* 3.seWebp 预加载是否使用webp优化。默认为true,除外:预加载css中图片素材,不开启webp优化
*/
const preload = (images, useWebp = true) => {
const load = (image, _i, useWebp) => {
_i = new Image();
if (useWebp && typeof ''.ossimg === 'function') {
image = image.ossimg();
};
_i.src = image;
_i.onload = _i.onerror = function() {
_i.onload = _i.onerror = null;
_i = null;
};
};
if (typeof images === 'string') {
let _image;
load(images, _image, useWebp);
} else {
let _imageArr = [];
images.forEach((image, i) => {
load(image, _imageArr[i], useWebp);
});
}
};
module.exports = preload;
\ No newline at end of file
This diff is collapsed.
import qs from 'qs';
import axios from 'axios';
import Promise from 'promise-polyfill';
axios.defaults.timeout = 10000; // 超时时间
const DATA_FORM = 'application/x-www-form-urlencoded;charset=UTF-8';
const DATA_JSON = 'application/json;charset=UTF-8';
const isDev = window.location.hostname == "127.0.0.1";
// const dev = process.env.NODE_ENV == 'development';
// console.log("process.env.NODE_ENV = " + process.env.NODE_ENV);
// 根据环境设置baseUrl
// let baseUrl = '';
// if (process.env.NODE_ENV === 'development') {
// baseUrl = '';
// } else if (process.env.NODE_ENV === 'production') {
// baseUrl = '';
// }
axios.defaults.baseURL = isDev ? HTTP : '';
console.log("HTTP = " + HTTP);
console.log("MOCK = " + MOCK);
console.log("PROXY = " + PROXY);
function insertExt(url){
var list = url.split("?");
if(list.length == 1){
return url + '.json';
}
return list.shift()+ '.json?' + list.join("?");
}
// axios请求拦截
axios.interceptors.request.use(
config => {
// 统一拼上固定要传的参数
let method = config.method;
if (method === 'post' && config.headers['content-type'] == DATA_FORM){
}
console.log(config);
if(isDev && MOCK){
config.url = insertExt(config.url);
}
return config;
},
error => {
return Promise.error(error);
}
);
// axios响应拦截
axios.interceptors.response.use(
response => {
if (response.status === 200) {
return Promise.resolve(response);
} else {
return Promise.reject(response);
}
}
)
const handleReuslt = (res, resolve, reject) => {
let {
data,
success,
desc,
code
} = res.data;
if (success) {
resolve(res.data);
} else {
console.error(res.data);
reject(res.data);
}
}
export const get = (url, params, config)=> {
return new Promise((resolve, reject)=>{
axios({
method:'get',
url:url,
params: params,
paramsSerializer: function(params) {
return qs.stringify(params, {arrayFormat: 'repeat'})
},
...config
}).then(res => {
handleReuslt(res, resolve, reject);
}).catch(err => {
console.error(err);
reject(err);
});
});
}
export const post = (url, params, config)=> {
if(isDev && MOCK){
return get(url, params, config);
}
return new Promise((resolve, reject)=>{
axios({
method:'post',
url:url,
data: params,
headers: { 'content-type': config && config.isForm ? DATA_FORM : DATA_JSON },
...config
}).then(res => {
handleReuslt(res, resolve, reject);
}).catch(err => {
console.error(err);
reject(err);
});
});
}
import { get } from "@js/request";
import { parseUrlParams, formatUrl } from '@js/tooler'
const API = {
getOaJssdk: '/kjy/mp/seller/getOaJssdk',
getScId: '/kjy/mp/seller/getScId'
}
let config = {};
function updateLink(contentId){
get(API.getScId, {
contentId: contentId,
showCard: 0
}).then(res => {
var obj = parseUrlParams();
obj.scid = res.data;
config.link = formatUrl(window.location.href.split("?")[0], obj);
console.log(config.link);
})
}
function shareConfig(obj){
// alert(JSON.stringify(config));
let {title, desc, img, debug} = obj;
config = obj;
get(API.getOaJssdk, {
url: window.location.href.split("#")[0]
}).then(res => {
if(res.success){
var data = res.data;
wx.config({
debug: !!debug,//生产环境需要关闭debug模式
appId: data.appid,//appId通过微信服务号后台查看
timestamp: data.timestamp,//生成签名的时间戳
nonceStr: data.noncestr,//生成签名的随机字符串
signature: data.sign,//签名
jsApiList: [//需要调用的JS接口列表
'checkJsApi',//判断当前客户端版本是否支持指定JS接口
'onMenuShareTimeline',//分享给好友
'onMenuShareAppMessage'//分享到朋友圈
]
});
}
})
wx.ready(function () {
//分享朋友圈
wx.onMenuShareTimeline({
title: title,
link: config.link,
imgUrl: img,
success: function (res) {
},
cancel: function (res) {
},
fail: function (res) {
}
});
//分享给好友
wx.onMenuShareAppMessage({
title: title, // 分享标题
desc: desc, // 分享描述
link: config.link, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: img, // 自定义图标
type: 'link', // 分享类型,music、video或link,不填默认为link
dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
success: function (res) {
},
cancel: function (res) {
},
fail: function (res) {
}
});
});
}
export {
shareConfig,
updateLink
}
This diff is collapsed.
/**
*解析全部的参数,返回一个Object
*
* @returns
*/
function parseUrlParams(url = location.search) {
var paramsArr = decodeURIComponent(url)
.replace(/amp;/g, '')
.split('&'),
result = {};
// 删除?
paramsArr[0] = paramsArr[0].substr(1);
for (var i = 0, j = paramsArr.length; i < j; i++) {
var valArr = paramsArr[i].split('=');
result[valArr[0]] = decodeURIComponent(valArr[1]);
}
return result;
}
/**
* 格式化url,添加参数
*
* @param {*} url
* @param {*} params
* @returns
*/
const formatUrl = (url, params) => {
if (!url) {
return '';
}
let keys = Object.keys(params);
if (keys.length === 0) {
return url;
}
let base = url.indexOf('?') > -1 ? `${url}&` : `${url}?`;
return keys.reduce((acc, v, i) => {
if (i === 0) {
return (acc += `${v}=${params[v]}`);
} else {
return (acc += `&${v}=${params[v]}`);
}
}, base);
};
/**
* 获取url中特定字符串的值
* @param {*} name 字符串key
* @param {*} path 默认为页面链接地址,也可自己传某段string
*/
const getUrlParameter = (name, path = window.location.href) => {
const result =
decodeURIComponent(
(new RegExp('[?|&]' + name + '=([^&;]+?)(&|#|;|$)').exec(path) || [
undefined,
''
])[1].replace(/\+/g, '%20')
) || null;
return result ? result : '';
};
/**
* 判断是否在小程序内部
*/
const isWeChatApplet = () => {
const ua = window.navigator.userAgent.toLowerCase();
if(ua.indexOf('miniprogramhtmlwebview') != -1){
return true;
}
return false;
}
export {
getUrlParameter,
parseUrlParams,
formatUrl,
isWeChatApplet
};
\ No newline at end of file
This diff is collapsed.
const addVConsole = () => {
let host = location.host;
if (host.indexOf('youtui.tuiatest.cn') > -1 || host.indexOf('youtui.tuiapre.cn') > -1 || host.indexOf(':4000') > -1) {
var VConsole = require('vconsole/dist/vconsole.min');
var vConsole = new VConsole();
}
};
export default addVConsole;
/**
* @desc:
* @author : Dec-F
* @Date : 2018-07-31 15:13:36
* @Last Modified by: miaokefu@duiba.com.cn
* @Last Modified time: 2018-09-20 17:10:55
*/
/**
* wxShare(opts)
*
* opts:{
* url:'' //当前页面url(不带hash)
* wxShareTitle: ‘’, //标题
wxShareSubTitle:‘’, // 副标题
shareUrl: {//分享出去的url
circle:'' //朋友圈
friends:'' //好友
},
wxShareImg: ‘’ //图片,
success:function(res) { //成功的回调 res.type=1:分享好友成功 =2 分享朋友圈成功
}
* }
*
*
*/
import * as wxsdk from '@js/wxsdk';
export const wxShare = opts => {
// 微信url不能包含#hash后面部分
wx.ready(() => {
wxsdk.share({
wxShareTitle: opts.wxShareTitle, //标题
wxShareSubTitle: opts.wxShareSubTitle, // 副标题
shareUrl: opts.shareUrl,
wxShareImg: opts.wxShareImg, //图片,
success: opts.success
});
});
wxsdk
.init({
url: opts.url, //当前页面url(不带hash)
jsApiList: ["chooseImage","uploadImage","downloadImage","getLocalImgData"], // 需要使用的JS接口列表 默认包含['checkJsApi', 'onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ']
debug: false
})
.then(res => {
console.log('wxinit', res);
});
};
/**
*
* wxImgUploade()
* wx上传图片
*
*
*/
export const wxImgUploade = opts => {
return new Promise((resove, reject)=>{
let images = [];
wxsdk
.init({
url: location.href.split('#')[0], //当前页面url(不带hash)
jsApiList: ["chooseImage","uploadImage","downloadImage","getLocalImgData"], // 需要使用的JS接口列表 默认包含['checkJsApi', 'onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ']
debug: false
})
.then(res => {
wx.ready(() => {
wxsdk.imageUploade(opts).then(data=>{
images = data;
console.log(data, "stepuuuuu");
resove(images);
});
});
});
})
};
import {formatUrl} from '@js/utils';
/**
* 微信授权
* @param {*} userId 用户id
*/
const wxAuth = (userId, extParam , serverUrl = '/youtui/temporary/getWxUserInfo4url')=>{
let wxAuthUrl = `https://open.weixin.qq.com/connect/oauth2/authorize`;
let appid = `wx231876932416d2c7`;
// 预发:youtui-pre.tuia.cn/youtui/temporary/getWxUserInfo
// 线上:activity.qushaio.com/youtui/temporary/getWxUserInfo
let redirectUrl = encodeURIComponent(`${location.origin}${serverUrl}`);
let frags = location.href.split('#');
let url = '';
if (frags.length > 1) {
// 存在#
url = formatUrl(frags[0], {
wxAuthed: 1,
...extParam
}) + '#' + frags[1];
} else {
url = formatUrl(location.href, {
wxAuthed: 1,
...extParam
});
}
let state = {
userId: userId,
url: encodeURIComponent(url)
};
var stateStr = JSON.stringify(state);
setTimeout(() => {
console.log('wxAuth redirect', `${wxAuthUrl}?appid=${appid}&redirect_uri=${redirectUrl}&response_type=code&scope=snsapi_userinfo&state=${stateStr}#wechat_redirect`);
location.href = `${wxAuthUrl}?appid=${appid}&redirect_uri=${redirectUrl}&response_type=code&scope=snsapi_userinfo&state=${stateStr}#wechat_redirect`
}, 10);
}
export default wxAuth;
This diff is collapsed.
<script type="text/javascript">
;(function () {
if (!/eruda=true/.test(window.location.href)) return;
var oHead = document.head;
var oScript = document.createElement('script');
oScript.type = "text/javascript";
oScript.src = "//yun.playpangu.com/h5-mami/optimize/eruda.min.js?t=20180514";
oHead.appendChild(oScript);
oScript.onload = function () { eruda.init() }
})();
</script>
\ No newline at end of file
#include("@layout/global/eruda.html")
<meta charset="UTF-8">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta content="telephone=no" name="format-detection" />
<script>
! function (e, i) {
var t = e.documentElement,
n = navigator.userAgent.match(/iphone|ipod|ipad/gi),
a = n ? Math.min(i.devicePixelRatio, 3) : 1,
m = "orientationchange" in window ? "orientationchange" : "resize";
t.dataset.dpr = a;
for (var d, l, c = !1, o = e.getElementsByTagName("meta"), r = 0; r < o.length; r++) l = o[r], "viewport" == l.name &&
(c = !0, d = l);
if (c) d.content = "width=device-width,initial-scale=1.0,maximum-scale=1.0, minimum-scale=1.0,user-scalable=no";
else {
var o = e.createElement("meta");
o.name = "viewport", o.content =
"width=device-width,initial-scale=1.0,maximum-scale=1.0, minimum-scale=1.0,user-scalable=no", t.firstElementChild
.appendChild(o)
}
var s = function () {
var e = t.clientWidth;
e / a > 750 && (e = 750 * a), window.remScale = e / 750, t.style.fontSize = 200 * (e / 750) + "px"
};
s(), e.addEventListener && i.addEventListener(m, s, !1)
}(document, window);
</script>
\ No newline at end of file
This diff is collapsed.
<script src="//yun.dui88.com/h5-mami/webgame/bundle/exchange/entry-201806291554.js"></script>
<script src="//yun.dui88.com/h5-mami/webgame/components/stay-time/entry-201805281451.js"></script>
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.
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.
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