Commit 4a61a299 authored by haiyoucuv's avatar haiyoucuv

init

parents
# 顶部的EditorConfig文件
root = true
# unix风格的换行符,每个文件都以换行符结尾
[*]
end_of_line = lf
insert_final_newline = true
# 设置默认字符集
charset = utf-8
# 去除行尾空白字符
trim_trailing_whitespace = true
# 使用空格缩进,设置2个空格缩进
indent_style = space
indent_size = 2
# 忽略eslint校验路径,例如:
# src/libs/@spark
\ No newline at end of file
module.exports = {
parser: '@babel/eslint-parser',
env: {
browser: true,
es6: true,
node: true,
},
globals: {
CFG: true,
wx: true,
FYGE: true,
SPARK_ESLINT_PLUGIN: true,
remScale: true,
},
plugins: ['html', 'react', '@spark/best-practices', '@spark/security'],
extends: ['eslint:recommended', 'plugin:react/recommended'],
settings: {
react: {
version: 'detect',
},
},
parserOptions: {
sourceType: 'module',
ecmaVersion: 7,
ecmaFeatures: {
experimentalObjectRestSpread: true,
jsx: true,
},
babelOptions: {
configFile: './node_modules/@spark/code-inspector/static/babel.config.js',
},
},
rules: {
'no-undef': 'error',
'no-unused-vars': ['error', { vars: 'all', args: 'after-used', argsIgnorePattern: '^_', varsIgnorePattern: '^_', ignoreRestSiblings: true }],
'no-dupe-keys': 'error',
'no-fallthrough': 'error',
'no-global-assign': 'error',
'no-implied-eval': 'error',
'no-self-assign': 'error',
'no-self-compare': 'error',
'no-sequences': 'error',
'no-unused-expressions': ['error', { allowShortCircuit: true, allowTernary: true, allowTaggedTemplates: true }],
'no-useless-escape': 'error',
'no-empty-pattern': 'error',
'no-empty-function': ['error', { allow: ['arrowFunctions', 'functions', 'methods'] }],
'no-var': 'error',
'no-dupe-class-members': 'error',
'no-unsafe-optional-chaining': 'error',
'no-const-assign': 'error',
'no-empty': ['error', { allowEmptyCatch: true }],
'prefer-const': 'warn',
'no-extra-boolean-cast': 'warn',
'no-mixed-spaces-and-tabs': 'warn',
'no-alert': 'warn',
'no-new-wrappers': 'warn',
'no-useless-concat': 'warn',
'no-useless-return': 'warn',
'prefer-promise-reject-errors': ['warn', { allowEmptyReject: true }],
'spaced-comment': 'warn',
'react/prop-types': 'off',
'react/display-name': 'off',
'react/jsx-pascal-case': 'error',
'jsx-quotes': 'warn',
// 'react/jsx-tag-spacing': 'error',
'react/require-resnder-return': 'error',
'semi': [1]
},
overrides: [
{
files: ['public/**/*.html'],
rules: {
'no-var': 'off',
'@spark/security/third-party-whitelist': 'error',
'@spark/best-practices/no-url-in-js': 'error',
'@spark/best-practices/no-arrow-function': 'error',
'@spark/best-practices/no-es6-variable-declaration': 'error',
},
},
{
files: ['src/**/*.{js,jsx}'],
rules: {
'@spark/best-practices/no-url-in-js': 'error',
},
},
],
};
.DS_Store
node_modules/
___cache/
__cache/
coverage/
npm-debug.log
selenium-debug.log
.idea
.builds
.project
.vscode
yarn-error.log
.yarn
.package-lock
yarn.lock
.cache
packages/**/package-lock.json
released
output.js
output.js.map
.psd
.psb
#src/assets/
\ No newline at end of file
registry = http://npm.dui88.com
\ No newline at end of file
module.exports = {
semi: true, // 结尾加分号
singleQuote: false, // 使用单引号
jsxSingleQuote: false, // jsx中使用单引号
bracketSpacing: true, // 括号和参数之间有空格
jsxBracketSameLine: true, // 标签属性较多时,标签箭头>另起一行
quoteProps: 'as-needed', // 属性加引号需要加时再加
printWidth: 120, // 每行字符个数
};
registry "http://npm.dui88.com"
\ No newline at end of file
import MD from 'spark-utils/out/md/index.js';
import { logClick } from "@spark/utils/src-js/md";
import { jsonp } from "@spark/api-base";
let appId = CFG.appID;
const dcm = '202.' + CFG.projectId + '.0.0';
const domain = '';
const dom = `${CFG.channel}.0.0.0`;
const MDList = Array.from({ length: 30 }).map((_, index) => {
return {
ele: `.md${index + 1}`,
data: {
dpm: `${appId}.110.${index + 1}.1`,
dcm,
domain,
appId,
dom
},
once: false
};
})
export default () =>
MD({
show: MDList, // 曝光
click: MDList // 点击
});
export function logExposure(params) {
jsonp("/exposure/standard", params);
}
export function handleLogExposure(id, id2 = 1) {
logExposure({
dpm: `${appId}.110.${id}.${id2}`,
dcm,
domain,
appId,
dom
});
}
export function handleLogClick(id, id2 = 1) {
logClick({
dpm: `${appId}.110.${id}.${id2}`,
dcm,
domain,
appId,
dom
});
}
### 注意事项
xxxxxxx
### 迭代日志
## 20230202 [大雁链接](https://www.bilibili.com)
+ haha
+ haha1
+ haha2
### 端午节-线上测试:
官微菜单栏:
https://93842-activity.dexfu.cn/customShare/share?id=Did1NjA4NjM&actUrl=https%3A%2F%2F93842-activity.dexfu.cn%2Fprojectx%2Fp8d9bf93b%2Findex.html%3FappID%3D93842&channel=guanwei
官微权益中心:
https://93842-activity.dexfu.cn/customShare/share?id=Did1NjA4NjM&actUrl=https%3A%2F%2F93842-activity.dexfu.cn%2Fprojectx%2Fp8d9bf93b%2Findex.html%3FappID%3D93842&channel=quanyizhongxin
寿险小程序:
https://93842-activity.dexfu.cn/customShare/share?id=Did1NjA4NjM&actUrl=https%3A%2F%2F93842-activity.dexfu.cn%2Fprojectx%2Fp8d9bf93b%2Findex.html%3FappID%3D93842&channel=shouxian
官微推文:
https://93842-activity.dexfu.cn/customShare/share?id=Did1NjA4NjM&actUrl=https%3A%2F%2F93842-activity.dexfu.cn%2Fprojectx%2Fp8d9bf93b%2Findex.html%3FappID%3D93842&channel=tuiwen
太好钉:
https://93842-activity.dexfu.cn/customShare/share?id=Did1NjA4NjM&actUrl=https%3A%2F%2F93842-activity.dexfu.cn%2Fprojectx%2Fp8d9bf93b%2Findex.html%3FappID%3D93842&channel=taihaoding
海报:
https://93842-activity.dexfu.cn/customShare/share?id=Did1NjA4NjM&actUrl=https%3A%2F%2F93842-activity.dexfu.cn%2Fprojectx%2Fp8d9bf93b%2Findex.html%3FappID%3D93842&channel=haibao
太好店小程序:
https://93842-activity.dexfu.cn/customShare/share?id=Did1NjA4NjM&actUrl=https%3A%2F%2F93842-activity.dexfu.cn%2Fprojectx%2Fp8d9bf93b%2Findex.html%3FappID%3D93842&channel=taihaodian
企微:
https://93842-activity.dexfu.cn/customShare/share?id=Did1NjA4NjM&actUrl=https%3A%2F%2F93842-activity.dexfu.cn%2Fprojectx%2Fp8d9bf93b%2Findex.html%3FappID%3D93842&channel=qiwei
服务大厅:
https://93842-activity.dexfu.cn/customShare/share?id=Did1NjA4NjM&actUrl=https%3A%2F%2F93842-activity.dexfu.cn%2Fprojectx%2Fp8d9bf93b%2Findex.html%3FappID%3D93842&channel=fuwu
### 端午节-线上正式:
官微菜单栏:
https://93842-activity.dexfu.cn/customShare/share?id=Did1NjA4NzE&actUrl=https%3A%2F%2F93842-activity.dexfu.cn%2Fprojectx%2Fpeb5290b6%2Findex.html%3FappID%3D93842&channel=guanwei
官微权益中心:
https://93842-activity.dexfu.cn/customShare/share?id=Did1NjA4NzE&actUrl=https%3A%2F%2F93842-activity.dexfu.cn%2Fprojectx%2Fpeb5290b6%2Findex.html%3FappID%3D93842&channel=quanyizhongxin
寿险小程序:
https://93842-activity.dexfu.cn/customShare/share?id=Did1NjA4NzE&actUrl=https%3A%2F%2F93842-activity.dexfu.cn%2Fprojectx%2Fpeb5290b6%2Findex.html%3FappID%3D93842&channel=shouxian
官微推文:
https://93842-activity.dexfu.cn/customShare/share?id=Did1NjA4NzE&actUrl=https%3A%2F%2F93842-activity.dexfu.cn%2Fprojectx%2Fpeb5290b6%2Findex.html%3FappID%3D93842&channel=tuiwen
太好钉:
https://93842-activity.dexfu.cn/customShare/share?id=Did1NjA4NzE&actUrl=https%3A%2F%2F93842-activity.dexfu.cn%2Fprojectx%2Fpeb5290b6%2Findex.html%3FappID%3D93842&channel=taihaoding
海报:
https://93842-activity.dexfu.cn/customShare/share?id=Did1NjA4NzE&actUrl=https%3A%2F%2F93842-activity.dexfu.cn%2Fprojectx%2Fpeb5290b6%2Findex.html%3FappID%3D93842&channel=haibao
太好店小程序:
https://93842-activity.dexfu.cn/customShare/share?id=Did1NjA4NzE&actUrl=https%3A%2F%2F93842-activity.dexfu.cn%2Fprojectx%2Fpeb5290b6%2Findex.html%3FappID%3D93842&channel=taihaodian
企微:
https://93842-activity.dexfu.cn/customShare/share?id=Did1NjA4NzE&actUrl=https%3A%2F%2F93842-activity.dexfu.cn%2Fprojectx%2Fpeb5290b6%2Findex.html%3FappID%3D93842&channel=qiwei
服务大厅:
https://93842-activity.dexfu.cn/customShare/share?id=Did1NjA4NzE&actUrl=https%3A%2F%2F93842-activity.dexfu.cn%2Fprojectx%2Fpeb5290b6%2Findex.html%3FappID%3D93842&channel=fuwu
/*
将此文件放到project/config/scripts/assets/目录下
在package.json文件的"scripts"字段下,分别修改dev和build命令:
"dev": "node ./config/scripts/assets/generateAssetList.js && node ./config/webpack.dev.config.js"
"build": "node ./config/scripts/assets/generateAssetList.js && node ./config/scripts/assets/index.js imgmin imgup && node ./config/webpack.prod.config.js"
*/
const fs = require('fs')
const path = require('path')
/* 请先配置:预加载的资源文件夹名称,或者设置预加载、异步加载资源路径*/
const preloadFolder = []; // 在/src/assets文件夹下,请设置需要预加载的资源文件目录,默认值预加载为loading文件夹, 其他均为异步加载
const otherFolder = ['loadingDemo']; // 在/src/assets文件夹下,不做任务处理的文件夹,不需要预加载, 也不需要异步加载
const initAssetList = { // 初始化预设资源处理
preLoadImg:[], // 设置预加载图片,例如:["loading/bg174.png","loading/上面.png","loading/底部173.png"]
asyncLoadImg:[] // 设置异步加载图片
}
/**
* 搜索文件夹里的文件
* @param {*} folderList 预加载文件夹名称数组
* @param {*} folderPath 文件夹地址,绝对路径
* @param {*} regExp 正则表达式,用于匹配目标文件
* @returns {string[]} 返回文件相对路径地址
*/
function searchFileFromFolder(folderPath='/src/assets', regExp=/\.(png|jpg|jpeg|svga|spi|json|mp3|wav)$/i) {
const preLoadImg = [], asyncLoadImg = [];
const searchOneDir = (absolutePath, relativePath) => {
fs.readdirSync(absolutePath).forEach(v => {
const absPath = absolutePath + '/' + v;
const relPath = relativePath ? relativePath + '/' + v : v;
if(fs.statSync(absPath).isFile()) {
if(regExp.test(v)){
if(preloadFolder.includes(relPath.split('/')[0])){
preLoadImg.push(relPath);
}else if(!otherFolder.includes(relPath.split('/')[0])){
asyncLoadImg.push(relPath)
}
}
}else {
searchOneDir(absPath, relPath);
}
});
}
searchOneDir(path.resolve('.') + folderPath, '');
console.log('资源预处理成功~')
return {
preLoadImg: [
...initAssetList.preLoadImg,
...preLoadImg
],
asyncLoadImg: [
...initAssetList.asyncLoadImg,
...asyncLoadImg
]
};
}
// 读资源目录
const assetList = searchFileFromFolder();
// 写资源列表json
fs.writeFileSync(path.resolve('.') + '/src/assetList.json', JSON.stringify(assetList))
\ No newline at end of file
const { assets } = require("spark-assets");
const args = process.argv.splice(2);
let argsObj = {
imgmin: false,
imgup: false
}
if (args.length == 1) {
argsObj.imgmin = 'imgmin' == args[0];
argsObj.imgup = 'imgup' == args[0];
} else if (args.length == 2) {
argsObj.imgmin = 'imgmin' == args[0];
argsObj.imgup = 'imgup' == args[1];
}
assets(argsObj)
\ No newline at end of file
exports.SPARK_CONFIG_DIR_KEY = ['OUTPUT_DIR', 'SOURCE_DIR', 'TEMP_DIR', 'ENTRY', 'TEMPLATE']
exports.SPARK_CONFIG = 'sparkrc.js'
//对应项目在线素材存储的cdn配置,用于迭代开发从线上拉取素材到本地
exports.SPARK_CDN_RES_CFG='sparkrescfg.json'
\ No newline at end of file
const loaderUtils = require('loader-utils');
module.exports = function (source) {
const options = loaderUtils.getOptions(this);
let result = source;
if (options.arr) {
options.arr.map(op => {
result = result.replace(op.replaceFrom, op.replaceTo);
})
} else {
result = source.replace(options.replaceFrom, options.replaceTo);
}
return result
};
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { exec } = require('child_process');
class GitToHtmlPlugin {
process(htmlPluginData) {
return new Promise(function (resolve) {
let gitStr = '';
exec('git remote -v & git branch --show-current & git config --global user.name', (_err, stdout, _stderr) => {
if (stdout) {
gitStr = `<script>CFG.___G___='${encodeURIComponent(stdout.replace(/\n/g, ';'))}'</script>`
}
htmlPluginData.html = htmlPluginData.html.replace('</body>', `${gitStr}</body>`);
resolve();
});
});
};
apply(compiler) {
compiler.hooks.compilation.tap('GitToHtmlPlugin', (compilation) => {
HtmlWebpackPlugin.getHooks(compilation).afterTemplateExecution.tapAsync(
"GitToHtmlPlugin",
async (html, cb) => {
await this.process(html);
cb(null, html);
}
);
});
}
}
module.exports = GitToHtmlPlugin;
const babel = require('@babel/core');
const HtmlWebpackPlugin = require("html-webpack-plugin");
class HtmlJsToES5Plugin {
process(htmlPluginData) {
return new Promise(function (resolve) {
const scriptRegExp = /<script>[\s\S]*?<\/script>/gis;
htmlPluginData.html = htmlPluginData.html.replace(scriptRegExp, function (match) {
const code = match.replace("<script>", "").replace("</script>", "");
const es5Code = babel.transform(code, { 'presets': ['@babel/preset-env'] }).code;
return `<script>${es5Code}</script>`;
});
resolve();
});
};
apply(compiler){
compiler.hooks.compilation.tap('HtmlJsToES5Plugin', (compilation) => {
HtmlWebpackPlugin.getHooks(compilation).afterTemplateExecution.tapAsync(
"HtmlJsToES5Plugin",
async (html, cb) => {
await this.process(html);
cb(null, html);
}
);
});
}
}
// exports.default = HtmlJsToES5Plugin;
module.exports = HtmlJsToES5Plugin;
// 端口是否被占用
const net = require("net");
exports.getProcessIdOnPort=function(port) {
try {
const execOptions = {
encoding: 'utf8',
stdio: [
'pipe',
'pipe',
'ignore',
],
};
return execSync('lsof -i:' + port + ' -P -t -sTCP:LISTEN', execOptions)
.split('\n')[0]
.trim();
} catch (e) {
return null;
}
}
exports.isPortAvailable = function (port, host = "localhost") {
return new Promise((resolve) => {
if (isNaN(port) || port != parseInt(port) || port < 0 || port > 65536) {
resolve(false);
}
try {
const tester = net.createServer()
// catch errors, and resolve false
.once('error', err => {
resolve(false);
})
// return true if succed
.once('listening', (err) => {
tester
.once('close', () => {
resolve(true);
})
.close()
})
.listen(port, host);
} catch (e) {
resolve(false);
}
})
}
const childProcessSync=async function(cmd, params, cwd, printLog = true) {
return new Promise((resolve, reject) => {
let proc = childProcess(cmd, params, cwd, printLog);
proc.on('close', (code) => {
if (code === 0) {
resolve(proc['logContent']);
} else {
reject(code);
}
});
});
}
const getGitBranch=async function(cwd) {
try {
const result = await childProcessSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], cwd, false);
if (!result.startsWith('fatal:')) {
return result.trim();
}
} catch (e) {
return undefined;
}
}
const getProjectNameByPackage=function() {
return require(`${process.cwd()}/package.json`).name
}
/**
* 理论上每个项目独一无二的文件夹名字-默认取分支名
* 如果当前未创建分支,取包名+日期
* (实际很多情况是直接clone老项目,包名相同,以防资源被替换,所以用日期加一下)
*/
exports.getCdnFolderName=async function() {
const branch = await getGitBranch(process.cwd());
const date = Date.now();
if (branch) {
return branch + "/" + date;
}
let foldername = getProjectNameByPackage() + "/" + date;
return foldername;
}
const path = require('path');
const { SPARK_CONFIG_DIR_KEY, SPARK_CONFIG } = require('./scripts/constant');
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const ProgressBarPlugin = require("progress-bar-webpack-plugin");
module.exports = function (isProd) {
const appPath = process.cwd();
const sparkConfig = require(path.join(appPath, SPARK_CONFIG));
const cssReg = /\.(css|less)$/;
// 处理相对路径
SPARK_CONFIG_DIR_KEY.map((key) => {
sparkConfig[key] = path.resolve(appPath, sparkConfig[key]);
});
const stylePlugins = [
require("autoprefixer")({
overrideBrowserslist: ["> 1%", "last 2 versions", "not ie <= 8"],
})
];
if (sparkConfig.PX2REM) {
stylePlugins.push(
require("postcss-px2rem-exclude")({
remUnit: 100, // 注意算法,这是750设计稿,html的font-size按照750比例
exclude: /noRem/i,
})
);
}
const styleLoader = (cssOptions = {}) => {
return [
{
loader: "style-loader",
},
isProd && {
loader: MiniCssExtractPlugin.loader,
options: {
esModule: false,
},
},
{
loader: "css-loader",
options: {
...cssOptions,
importLoaders: 2, // 如果遇到css里面的 @import 执行后面两个loader。 不然如果import了less,css-loader是解析不了
},
},
{
loader: "postcss-loader",
options: {
sourceMap: isProd,
plugins: stylePlugins,
},
},
{
loader: require.resolve("less-loader"),
options: {
sourceMap: isProd,
lessOptions: {
modifyVars: {
"@RES_PATH": `"${isProd ? sparkConfig.RES_PATH_PROD + '/' : sparkConfig.RES_PATH}"`,
},
}
},
},
].filter(Boolean);
};
return {
entry: sparkConfig.ENTRY,
mode: isProd ? 'production' : 'development',
devtool: isProd ? "source-map" : "cheap-module-source-map",
output: {
path: path.resolve(__dirname, sparkConfig.OUTPUT_DIR),
filename: "js/[name].js",
},
resolve: {
extensions: ['.js', '.jsx', '.json'],
alias: {
"@src": path.resolve(__dirname, sparkConfig.SOURCE_DIR),
},
},
module: {
strictExportPresence: true,
rules: [
{
test: cssReg,
use: styleLoader(),
// include: sparkConfig.SOURCE_DIR,
},
{
test: /\.(js|jsx)$/,
loader: require.resolve("babel-loader"),
// exclude: [path.resolve("node_modules")],
options: {
presets: [
require("@babel/preset-env").default,
require("@babel/preset-react").default
],
plugins: [
["@babel/plugin-proposal-decorators", { "legacy": true }],
["@babel/plugin-proposal-class-properties", { "loose": false }],
require("@babel/plugin-transform-runtime").default,
],
sourceType: 'unambiguous'
},
},
{
test: [/\.(jpg|jpeg|png|svg|bmp)$/, /\.(eot|woff2?|ttf|svg)$/],
loader: require.resolve("url-loader"),
options: {
name: "[path][name].[ext]", // name默认是加上hash值。这里做了更改,不让加
outputPath: "images",
limit: 10240, // url-loader处理图片默认是转成base64, 这里配置如果小于10kb转base64,否则使用file-loader打包到images文件夹下
},
},
].filter(Boolean),
},
plugins: [
isProd &&
new MiniCssExtractPlugin({
filename: "styles/[name].[hash].css",
}),
new HtmlWebpackPlugin({
template: sparkConfig.TEMPLATE,
minify: !sparkConfig.UNMINIFY_INDEX && isProd,
}),
new CleanWebpackPlugin({
// cleanOnceBeforeBuildPatterns:['**/*', 'dist'] // 这里不用写 是默认的。 路径会根据output 输出的路径去清除
}),
new ProgressBarPlugin(),
].filter(Boolean),
optimization: {
minimize: isProd,
minimizer: [
// 替换的js压缩 因为uglifyjs不支持es6语法,
new TerserPlugin({
cache: true,
sourceMap: isProd,
extractComments: false, // 提取注释
parallel: true, // 多线程
terserOptions: {
compress: {
pure_funcs: ["console.log"],
},
},
}),
// 压缩css
new OptimizeCSSAssetsPlugin({
assetNameRegExp: /\.css$/g,
cssProcessor: require("cssnano"),
cssProcessorPluginOptions: {
preset: ["default", { discardComments: { removeAll: true } }],
},
canPrint: true,
}),
],
// 修改文件的ids的形成方式,避免单文件修改,会导致其他文件的hash值变化,影响缓存
moduleIds: "hashed",
splitChunks: {
chunks: "all",
minSize: 30000, // 小于这个限制的会打包进Main.js
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10, // 优先级权重,层级 相当于z-index。 谁值越大权会按照谁的规则打包
name: "vendors",
},
},
},
// chunks 映射关系的 list单独从 app.js里提取出来
runtimeChunk: {
name: (entrypoint) => `runtime-${entrypoint.name}`,
},
},
};
}
const { SPARK_CONFIG } = require("./scripts/constant");
const Webpack = require("webpack");
const webpackBaseConfig = require("./webpack.common.config");
const WebpackMerge = require("webpack-merge");
const WebpackDevServer = require("webpack-dev-server");
const opn = require("opn");
const apiMocker = require('mocker-api');
const path = require('path');
const { getProcessIdOnPort } = require("./scripts/utils");
const {isPortAvailable} = require("./scripts/utils");
const sparkConfig = require(path.resolve(SPARK_CONFIG));
const webpackDevConfig = function () {
return {
devServer: {
useLocalIp: true,
open: false,
hot: true,
host: "0.0.0.0",
// hotOnly: true
before(app) {
app.use(/^\/$/, async (req, res, next) => {
const send = res.send.bind(res);
res.send = (body) => {
let result = body.toString();
result = result.replace('${APPID}', 'test');
send(result);
}
next();
})
if (sparkConfig.API_MOCK) {
apiMocker(app, path.resolve('./mock/index.js'), {
changeHost: true,
})
}
}
},
plugins: [
// new Webpack.WatchIgnorePlugin([/[\\/]mock[\\/]/]),
new Webpack.HotModuleReplacementPlugin()
]
};
};
const buildDev = async function (config) {
const { port } = config;
return new Promise(async (resolve, reject) => {
const config = WebpackMerge(webpackBaseConfig(false), webpackDevConfig());
const compiler = Webpack(config);
const devServerOptions = Object.assign({}, config.devServer);
console.log('devServerOptions', devServerOptions);
const server = new WebpackDevServer(compiler, devServerOptions);
let i = 0;
for (; i < 100; i++) {
const canUse = await isPortAvailable(port + i, "0.0.0.0");
console.log(port + i, canUse)
if (canUse) {
break;
}
}
server.listen(
port + i || 8088,
"0.0.0.0",
() => {
console.log(`Starting server on http://localhost:${port}`);
opn(`http://localhost:${port + i || 8088}`);
resolve();
},
(err) => {
if (err) console.error("server linsten err--", err);
reject();
}
);
});
};
const args = process.argv.splice(2);
const port = args[0] || 8088
buildDev({
port: Number(port)
})
const path = require("path");
const chalk = require("chalk");
const fs = require('fs-extra');
const Webpack = require("webpack");
const WebpackMerge = require("webpack-merge");
const webpackBaseConfig = require("./webpack.common.config");
const {Uploader} = require("spark-assets");
const isProd = true;
const {getCdnFolderName} = require("./scripts/utils");
const {SPARK_CONFIG} = require("./scripts/constant");
const HtmlJsToES5Plugin = require("./scripts/plugins/HtmlJsToES5Plugin");
const {DepReporter} = require('spark-log-event');
// const sparkConfig = require('../sparkrc');
const ScriptExtHtmlWebpackPlugin = require("script-ext-html-webpack-plugin");
const GitToHtmlPlugin = require("./scripts/plugins/GitToHtmlPlugin");
const JavaScriptObfuscator = require("javascript-obfuscator");
const PATH_ROOT = 'spark/v2';
const webpackProdConfig = function (cdnFolderName, resPathProd) {
return {
output: {
publicPath: `//yun.duiba.com.cn/spark/v2/${cdnFolderName}/`,
filename: isProd ? "js/[name].[contenthash:8].js" : "js/[name].[contenthash:4].js",
},
resolveLoader: {
modules: ['node_modules', path.resolve(__dirname, './scripts/loaders')]
},
module: {
rules: [
{
test: /sparkrc\.js$/,
exclude: [path.resolve("node_modules")],
use: [
{
loader: 'replaceLoader',
options: {
arr: [
{
replaceFrom: /(MOCK_STATUS: true)|(MOCK_STATUS:true)|("MOCK_STATUS": true)|("MOCK_STATUS":true)/,
replaceTo: '"MOCK_STATUS": false'
},
{
replaceFrom: /(RES_PATH:'\/src\/assets\/')|(RES_PATH: '\/src\/assets\/')|("RES_PATH":"\/src\/assets\/")|("RES_PATH": "\/src\/assets\/")/,
replaceTo: `"RES_PATH":"${resPathProd}/"`
}
]
}
}
]
},
]
},
plugins: [
new Webpack.IgnorePlugin(/[\\/]mock[\\/]/),
new ScriptExtHtmlWebpackPlugin({
custom: {
test: /\.js$/,
attribute: 'crossorigin',
value: 'anonymous'
}
}),
new GitToHtmlPlugin(),
new HtmlJsToES5Plugin(),
new DepReporter(),
new Webpack.ContextReplacementPlugin(
/moment[/\\]locale$/,
/zh-cn/,
),
],
node: {
crypto: 'empty'
}
};
};
const buildProd = async function () {
const cdnFolderName = await getCdnFolderName();
const appPath = process.cwd();
const sparkConfig = require(path.join(appPath, SPARK_CONFIG));
const _webpackProdConfig = await webpackProdConfig(cdnFolderName, sparkConfig.RES_PATH_PROD || '');
//新增 JS_PATH_PROD 用作
const newSparkCfg = Object.assign({}, sparkConfig);
newSparkCfg['JS_PATH_PROD'] = `https://yun.duiba.com.cn/spark/v2/${cdnFolderName}/js`;
const str = `module.exports =${JSON.stringify(newSparkCfg, null, 2)}`;
fs.writeFileSync(path.join(appPath, SPARK_CONFIG), str);
return new Promise((resolve, reject) => {
const config = WebpackMerge(webpackBaseConfig(isProd), _webpackProdConfig);
const compiler = Webpack(config);
compiler.run(async (error, stats) => {
if (error) {
return reject(error);
}
console.log(
stats.toString({
chunks: false, // 使构建过程更静默无输出
colors: true, // 在控制台展示颜色
})
);
console.log(`${chalk.yellow("打包成功, 等待上传")}\n`);
const files = fs.readdirSync(config.output.path + "/js");
let fileName = "";
for (let i = 0; i < files.length; i++) {
if (files[i].endsWith('.js') && files[i].indexOf("main") == 0) {
fileName = files[i];
}
}
const js = fs.readFileSync(path.join(config.output.path, "js/" + fileName), "utf-8");
const resJs = JavaScriptObfuscator.obfuscate(
js,
{
debugProtectionInterval: 4000,
debugProtection: true,
// 单行输出
compact: true,
selfDefending: true,
controlFlowFlattening: true,
controlFlowFlatteningThreshold: 0.3,
// 注入死代码
deadCodeInjection: true,
deadCodeInjectionThreshold: 0.2,
// 标识符名称生成器
// hexadecimal 16进制 包体增大较多
// mangled 短名称
// mangled-shuffled 与mangled相同,但带有洗牌字母表
// "identifier-names-generator": 'mangled-shuffled',
// 数字转表达式 如:
// const foo = 1234;
// const foo=-0xd93+-0x10b4+0x41*0x67+0x84e*0x3+-0xff8;
// numbersToExpressions: true,
log: true,
// 拆分字面字符串
splitStrings: true,
stringArray: true,
stringArrayRotate: true,
stringArrayCallsTransform: true,
stringArrayCallsTransformThreshold: 1,
stringArrayWrappersParametersMaxCount: 5,
stringArrayThreshold: 1,
// transformObjectKeys: true,
target: "browser-no-eval",
}
);
fs.writeFileSync(path.join(config.output.path, "js/" + fileName), resJs.getObfuscatedCode(), "utf-8");
const uploader = new Uploader();
await Promise.all([
await uploader.uploadDir(
config.output.path,
`${PATH_ROOT}/${cdnFolderName}`,
/.(html|map)$/
),
await uploader.uploadDir(
config.output.path + "/js",
`${PATH_ROOT}/${cdnFolderName}/js/map_123_map`,
/.(html|js|css|css\.map)$/
),
]);
resolve();
});
});
};
buildProd();
{
"version": "0.2",
"language": "en",
"words": [
"duiba",
"fyge",
"hanzi",
"projectx",
"webfonts",
"Weixin",
"webp"
]
}
{
"compilerOptions": {
"experimentalDecorators": true,
"baseUrl": "./",
"paths": {
"@src/*": ["src/*"]
}
},
"exclude": [
"node_modules"
]
}
\ No newline at end of file
{"numOfComponents":5048,"numOfProject":2884}
\ No newline at end of file
const {AES, enc, mode, pad} = require("crypto-js");
const getOptions = (iv) => {
return {
iv: enc.Utf8.parse(iv),
mode: mode.CBC,
padding: pad.ZeroPadding,
};
}
/** 加密 */
exports.AESEncrypt = (str, key, iv) => {
const options = getOptions(iv);
return AES.encrypt(str, enc.Utf8.parse(key), options).toString();
};
/** 解密 */
exports.AESDecrypt = (cipherText, key, iv) => {
const options = getOptions(iv);
return AES.decrypt(cipherText, enc.Utf8.parse(key), options)
.toString(enc.Utf8)
.trim()
.replace(//g, '')
.replace(//g, '')
.replace(/\v/g, '')
.replace(/\x00/g, '');
};
module.exports = {
"success": true,
"message": "报错了~",
"code": null,
"data": {
"shareInfo": JSON.stringify({
"title": "分享标题",
"content": "分享描述",
// 缩略图-非小程序端
"thumbnail": "https://yun.duiba.com.cn/polaris/thumb.68900332d31453cda9bdf783b9ef7e7042c3c6ac.png",
// 缩略图-小程序端
"thumbnail_mini": "https://yun.duiba.com.cn/polaris/share_mini.0129b9ad510447874f454dfb8f98992a9527aa62.png"
}),
// 分享中间页-线上测试
"shareMiddle": "https://93842-activity.dexfu.cn/customShare/share?id=Did1NjA4NjM&channel=channelName&isFromShare=1&empno=empnoParam&empname=empnameParam&param=changHangParam&actUrl=activityUrl&src=sxwx2db",
// 分享中间页-线上正式
// "shareMiddle": "https://93842-activity.dexfu.cn/customShare/share?id=Did1NjA4NzE&channel=channelName&isFromShare=1&empno=empnoParam&empname=empnameParam&param=changHangParam&actUrl=activityUrl&src=sxwx2db",
// 小程序分享落地页前缀
"miniProgramUrl": {
"qujiankang": "/packageHealthy/pages/webviewguanwei/webviewguanwei",
"xiaochengxu": "pages/webview/webview",
"taihaodian": "pages/newWeb/index",
"gongzhong": "/customShare/share?id=Did1NTc3OTk"
},
"posterQrCode": "https://yun.duiba.com.cn/polaris/%E6%AD%A3%E5%BC%8F.3e6da171761686ed529d75eaf31237d40d0fd334.png"
}
}
\ No newline at end of file
module.exports = {
"data": 3,
"success": true
}
\ No newline at end of file
module.exports = {
"data": "<p>以下是游戏规则:手速要快,点击红包雨。。333。。。。。。。。。。。。。。。。。。。。11111111111111sadasdadadsad5555555557777777777799999999999911111111111111111111111222222222222222222222222222222222222222222222222222222222222222333333333333333333333333333333333333333333333333333333333333311111111111111111111111111111111111111111111111111111111111111122222222222222222222222222222222222222222222222222222222222222233333333333333333333333333333333333333333333333333333333333331111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222223333333333333333333333333333333333333333333333333333333333333</p>",
"success": true
}
\ No newline at end of file
const rule = require("./common/rule");
const drawNum = require("./common/drawNum");
const coopFrontVariable = require("./common/coopFrontVariable");
const {AESEncrypt} = require("./Crypto");
const proxy = {
...require("./project"),
"GET /projectRule.query": rule,
"GET /drawNum.query": drawNum,
"GET /coop_frontVariable.query": coopFrontVariable,
"GET /spring/start.do": {
"code": "code",
"success": true,
"message": "message",
"timeStamp": Date.now(),
"data": AESEncrypt(JSON.stringify({
"startId": "officia",
"countDown": 30
}), "1696BD3E5BB915A0", "cDOiBC1n2QrkAY2P"),
},
};
module.exports = proxy;
module.exports = {
"GET /home/index.do": {
code: null,
data: {
startTime: +new Date() - 34234234, /// 活动开始时间戳
endTime: +new Date() + 34234234, /// 活动结束时间戳
remainAnswerTimes: 324, /// 剩余答题机会
nickname: null,
avatar: null,
salesman: true, // 是否代理人
shareCode: '326534', // 分享code
},
message: null,
success: true,
timeStamp: +new Date(),
},
"GET /home/startAnswer.do": {
code: null,
data: {
startId: 1,
},
message: null,
success: true,
timeStamp: 1723602734176,
},
"GET /home/submitAnswer.do": {
code: null,
data: {
awardTimes: 18,
},
message: null,
success: true,
timeStamp: 1723602734176,
}
};
const fs = require('fs')
let proxy = {}
fs.readdirSync(__dirname)
.some(filename => {
if (filename !== 'index.js') {
proxy = Object.assign(proxy, require('./' + filename))
}
})
module.exports = proxy;
module.exports = {
"/common/queryUserInfo.do": {
"code": null,
"data": {
openId: "openId45342", // 静默授权 openid
unionId: "unionId2342", // unionId
nonSilentOpenid: "nonSilentOpenid65432", // 非静默授权
newEmpNo: "newEmpNo11", // 自己的业务员工号 不是业务员就没有
friendEmpNo: "friendEmpNo11", // 邀请人的业务员工号
friendOpenId: "friendOpenId543", // 邀请人的OpenId
},
"message": null,
"success": true
},
}
\ No newline at end of file
module.exports = {
"GET /common/prizeRecord.do": {
code: null,
data: {
activityCode: "1",
list: [
{
gmtCreate: 1741598452000,
gwObjectStatus: 1,
id: "2271436954",
prizeId: "sp_virtual_gw_1",
prizeImg: "//yun.duiba.com.cn/polaris/bkimg.cdn.bcebos.6ef8023b6501b44c5dc1f49a9fa478a72a9689f5.png",
prizeName: "太保虚拟商品",
userRecordId: 2271437739,
},
{
gmtCreate: 1741598341000,
gwObjectStatus: 0,
id: "2271435639",
prizeId: "sp_virtual_gw_1",
prizeImg: "//yun.duiba.com.cn/polaris/bkimg.cdn.bcebos.6ef8023b6501b44c5dc1f49a9fa478a72a9689f5.png",
prizeName: "太保虚拟商品",
userRecordId: 2271437739,
},
{
gmtCreate: 1741597050000,
gwObjectStatus: 0,
id: "2271419006",
prizeId: "sp_virtual_gw_1",
prizeImg: "//yun.duiba.com.cn/polaris/bkimg.cdn.bcebos.6ef8023b6501b44c5dc1f49a9fa478a72a9689f5.png",
prizeName: "太保虚拟商品",
userRecordId: 2271437739,
},
{
gmtCreate: 1741326305000,
gwObjectStatus: 1,
id: "2267883678",
prizeId: "sp_object_gw_1",
prizeImg: "//yun.duiba.com.cn/polaris/yihetang.45e0a9fd9a8e59e5b6b4ea774cd56f43bf81458c.png",
prizeName: "官微实物奖品官微实物奖品官微实物奖品",
userRecordId: null,
},
...new Array(10).fill({}).map((_, i) => {
return {
gmtCreate: 1723602636000,
gwObjectStatus: null,
id: "500750476" + i,
userRecordId: "500750476" + i,
prizeId: "sp_virtual_gw",
prizeImg:
i == 0
? "https://yun.duiba.com.cn/spark/assets/f77861647e7b55e9c95e9c49d891a21526157a76.jpg"
: "//yun.dui88.com/projectxh5/phonebill-250-250.png",
prizeName: "10元话费" + i,
};
}),
],
focusStatus: true,
bindStatus: false,
},
message: null,
success: true,
timeStamp: 1723602734176,
},
};
module.exports = {
"GET /customActivity/qrcode/getQrcode": {
success: true,
code: "0000000000",
desc: "OK",
timestamp: 1730699350735,
data: "data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAAPcAAAD3CAIAAABO7lUEAAAFqklEQVR42u3cQY7cMAwEwMn/H+08IJdgYLJbmhL26PXIcsmHBsXP5/Mn+Pf8M7L3yT7pd0/xfDW+u89b/7W88h/KKaeccsopp5xyyimnnHLKKU8of8bGW+/+RA2be2Nz5efW8MXfopxyyimnnHLKKaeccsopp5zyEuX92dmcqranyO75uf0zaoxyyimnnHLKKaeccsopp5xyyn9Q+ZyYzTtnd8tb82n7ulFOOeWUU0455ZRTTjnllFNOOeX7lU/ZuqJNDf1VcZRTTjnllFNOOeWUU0455ZRTTvm7o63O6cTTbnfcedkY5ZRTTjnllFNOOeWUU0455ZRHlJ/Y79g1Z12jf7lrKKfcNZRT7hrKKXcN5ZS75j7lT9nY7LyT3c931KUdMSinnHLKKaeccsopp5xyyimnvER5W0q4aXpzhps6N/dP/CtAOeWUU0455ZRTTjnllFNOOeW1yttWrc3Z5rm+E78mc6tKOeWUU0455ZRTTjnllFNOOeUp5XdUGp1YidWm86138fQNyimnnHLKKaeccsopp5xyyik/SPnkFJOp3Oa77+9hnX2DX8+Zcsopp5xyyimnnHLKKaeccsoPUp6tRpoT3FbVtLmq1+xnyimnnHLKKaeccsopp5xyyimPKJ97i0/9aHuu/q7W2V///kQc5ZRTTjnllFNOOeWUU0455ZS/rXwz98meN3vrueb2xuZvvbWGowngWzOknHLKKaeccsopp5xyyimnnPKI8s05ndiDOJsbZrsFHdrdiXLKKaeccsopp5xyyimnnHLKI8rnsqE7TsRlK5/mVmNz/ywnv5RTTjnllFNOOeWUU0455ZRTXqK8LZlqc7+ZY7Z1ieo/R0c55ZRTTjnllFNOOeWUU0455Snlbanc5h7rr46aW/lNCcszpJxyyimnnHLKKaeccsopp5zyBeVtzrJ7zN64786UU0455ZRTTjnllFNOOeWUU96sPGs62zv4xB7N/bnhaBJNOeWUU0455ZRTTjnllFNOOeWXKd9MEvv7SsfztSFVmyf9KKeccsopp5xyyimnnHLKKae8R/lcwtWW92W787T9V/9ueXMClFNOOeWUU0455ZRTTjnllFOeUD6XKG2qaktI+/O+zS/Fcs5LOeWUU0455ZRTTjnllFNOOeULym9do6zFE580mzaOJpKUU0455ZRTTjnllFNOOeWUUx5R3p9VZZPE7GnAE/sixf1QTjnllFNOOeWUU0455ZRTTvmC8v4qov499ssp4RHdlCinnHLKKaeccsopp5xyyimnfEF5dpZ3dIiey+DmnvSnnotyGiinnHLKKaeccsopp5xyykuU35HuZdO0zeqozRm2JdHfJ4mUU0455ZRTTjnllFNOOeWUU/628mxP5M0k8cTTgHesxnKVHuWUU0455ZRTTjnllFNOOeWUR5RvVtLMGWqrPcrO8MT88cXvJuWUU0455ZRTTjnllFNOOeWU1yrPJoBz2dmt59barlmunKOccsopp5xyyimnnHLKKaec8lrl2dNu/eey2vo4Z/dzvL6Ncsopp5xyyimnnHLKKaeccsoXlD9lY7P6547fyiaAR9SlUU455ZRTTjnllFNOOeWUU075gvJ4R5iqvXFiJ+UTs+DNrxvllFNOOeWUU0455ZRTTjnllKeUZ1PC7BvK7sO538qufDx7pZxyyimnnHLKKaeccsopp5zyEuWb/YX7M8Fs2uhE3FSSSDnllFNOOeWUU0455ZRTTjnltys/sa90NiHd1Jn9lv3nf1FOOeWUU0455ZRTTjnllFNOOeXxFGxT1ebu7c8xf6tai3LKKaeccsopp5xyyimnnPLfUD63+nP3aUvKsqfLNt9p9ttBOeWUU0455ZRTTjnllFNOOeU9yts6O8fPUwVTws2ePptruPwVoJxyyimnnHLKKaeccsopp5zyBeWPYdw+/gJfOheLC3d1xwAAAABJRU5ErkJggg==",
},
};
module.exports = {
"/task_1/queryTasks.do": {
"code": null,
"message": null,
"success": true,
"data": {
"endTimestamp": 1622356189000,
"item": [
{
"title": "浏览短剧",
"subTitle": "食物食物食物食物食物食物食物衣蛾三四获得50枚",
"taskStatus": 0, // 任务状态 * 0 去完成,任务完成次数未达到上限 * 1 待领奖 * 2 已完成,任务完成次数达到上限
"buttonText": "1",
"code": "browse_view_mini",
"completedSize": 0,
"desc": "1",
"extra": null,
"icon": "//yun.duiba.com.cn/spark/assets/f77861647e7b55e9c95e9c49d891a21526157a76.jpg",
"id": "task1",
"index": null,
"intervalLimitSize": 4,
"intervalType": 1,
// "jumpUrl": "/packageVariety/pages/videoVariety/videoVariety?source_channel=duanwu",
"jumpUrl": "https://www.baidu.com/",
"options": [
{
"degree": null,
"icon": null,
"icon2": null,
"id": "o79a0b9d2",
"index": 1,
"name": "抽奖奖品",
"prizeId": "sp_1",
"prizeType": 1,
"refId": null,
"refType": null,
"sendCount": 1
}
],
"prizePendingCode": null,
"prizePendingCodeList": [
{
"index": 1,
"code": "awefrgdrtyhgr566y4e564235"
}
],
"ruleId": "ru_1",
"sendPrize": null,
},
{
"title": "浏览视频任务名称试试太长的名称繁琐的就看见佛教给哦肉丝哦IE家人腹肌是能打",
"subTitle": "食物食物食物食物食物食物食物衣蛾三四获得50枚",
"taskStatus": 0, // 任务状态 * 0 去完成,任务完成次数未达到上限 * 1 待领奖 * 2 已完成,任务完成次数达到上限
"buttonText": "1",
"code": "browse_view",
"completedSize": 0,
"desc": "1",
"extra": null,
"icon": "//yun.duiba.com.cn/spark/assets/f77861647e7b55e9c95e9c49d891a21526157a76.jpg",
"id": "task1",
"index": null,
"intervalLimitSize": 4,
"intervalType": 1,
"jumpUrl": "//yun.duiba.com.cn/polaris/3928%E9%A2%84%E5%91%8A__92pct_smaller.a97b770fba99798654d52d33c3e7cd9e85d42f63.mp4",
"options": [
{
"degree": null,
"icon": null,
"icon2": null,
"id": "o79a0b9d2",
"index": 1,
"name": "抽奖奖品",
"prizeId": "sp_1",
"prizeType": 1,
"refId": null,
"refType": null,
"sendCount": 1
}
],
"prizePendingCode": null,
"prizePendingCodeList": [
{
"index": 1,
"code": "awefrgdrtyhgr566y4e564235"
}
],
"ruleId": "ru_1",
"sendPrize": null,
},
{
"title": "浏览任务名称试试太长的名称繁琐的就看见佛教给哦肉丝哦IE家人腹肌是能打",
"subTitle": "食物食物食物食物食物食物食物衣蛾三四获得50枚",
"taskStatus": 0, // 任务状态 * 0 去完成,任务完成次数未达到上限 * 1 待领奖 * 2 已完成,任务完成次数达到上限
"buttonText": "1",
"code": "browse_product",
"completedSize": 0,
"desc": "1",
"extra": null,
"icon": "//yun.duiba.com.cn/spark/assets/f77861647e7b55e9c95e9c49d891a21526157a76.jpg",
"id": "task1",
"index": null,
"intervalLimitSize": 4,
"intervalType": 1,
"jumpUrl": "//yun.duiba.com.cn/polaris/1.7daf1cf068b7ed6f80c9bff91236be64624d5ac6.png",
"options": [
{
"degree": null,
"icon": null,
"icon2": null,
"id": "o79a0b9d2",
"index": 1,
"name": "抽奖奖品",
"prizeId": "sp_1",
"prizeType": 1,
"refId": null,
"refType": null,
"sendCount": 1
}
],
"prizePendingCode": null,
"prizePendingCodeList": [
{
"index": 1,
"code": "awefrgdrtyhgr566y4e564235"
}
],
"ruleId": "ru_1",
"sendPrize": null,
},
{
"title": "每日签到",
"subTitle": "游戏次数+1",
"taskStatus": 2, // 任务状态 * 0 去完成,任务完成次数未达到上限 * 1 待领奖 * 2 已完成,任务完成次数达到上限
"buttonText": "1",
"code": "common_sign",
"completedSize": 0,
"desc": "1",
"extra": null,
"icon": "//yun.duiba.com.cn/spark/assets/f77861647e7b55e9c95e9c49d891a21526157a76.jpg",
"id": "task1",
"index": null,
"intervalLimitSize": 4,
"intervalType": 1,
"jumpUrl": "https://projectx-console.duiba.com.cn/#/development",
"options": [
{
"degree": null,
"icon": null,
"icon2": null,
"id": "o79a0b9d2",
"index": 1,
"name": "抽奖奖品",
"prizeId": "sp_1",
"prizeType": 1,
"refId": null,
"refType": null,
"sendCount": 1
}
],
"prizePendingCode": null,
"prizePendingCodeList": [
{
"index": 1,
"code": "awefrgdrtyhgr566y4e564235"
}
],
"ruleId": "ru_1",
"sendPrize": null,
},
{
"title": "1v1留资查询",
"subTitle": "游戏次数+65",
"taskStatus": 0, // 任务状态 * 0 去完成,任务完成次数未达到上限 * 1 待领奖 * 2 已完成,任务完成次数达到上限
"buttonText": "1",
"code": "third_retain",
"completedSize": 2,
"desc": "1",
"extra": null,
"icon": "//yun.duiba.com.cn/spark/assets/f77861647e7b55e9c95e9c49d891a21526157a76.jpg",
"id": "task3",
"index": null,
"intervalLimitSize": 3,
"intervalType": 1,
"jumpUrl": "1",
"options": [
{
"degree": null,
"icon": null,
"icon2": null,
"id": "o79a0b9d2",
"index": 1,
"name": "抽奖奖品",
"prizeId": "sp_1",
"prizeType": 1,
"refId": null,
"refType": null,
"sendCount": 1
}
],
"prizePendingCode": null,
"prizePendingCodeList": [
{
"index": 1,
"code": "awefrgdrtyhgr566y4e564235"
}
],
"ruleId": "ru_1",
"sendPrize": null,
},
{
"title": "啦啦啦啦啦",
"subTitle": "游戏次数+1111",
"taskStatus": 1, // 任务状态 * 0 去完成,任务完成次数未达到上限 * 1 待领奖 * 2 已完成,任务完成次数达到上限
"buttonText": "1",
"code": "followAndBind",
"completedSize": 10,
"desc": "1",
"extra": null,
"icon": "//yun.duiba.com.cn/spark/assets/f77861647e7b55e9c95e9c49d891a21526157a76.jpg",
"id": "task2",
"index": null,
"intervalLimitSize": 10,
"intervalType": 1,
"jumpUrl": "https://www.baidu.com",
"options": [
{
"degree": null,
"icon": null,
"icon2": null,
"id": "o79a0b9d2",
"index": 1,
"name": "抽奖奖品",
"prizeId": "sp_1",
"prizeType": 1,
"refId": null,
"refType": null,
"sendCount": 1
}
],
"prizePendingCode": null,
"prizePendingCodeList": [
{
"index": 1,
"code": "awefrgdrtyhgr566y4e564235"
}
],
"ruleId": "ru_1",
"sendPrize": null,
},
],
"startTimestamp": 1619418589000,
"timestamp": 1619590450914
}
},
"POST /task_1/doCompleted.do": {
"code": null,
"data": {
"buttonText": "1",
"code": "1",
"desc": "1",
"extra": null,
"icon": null,
"id": "3b8mxhjo",
"options": [
{
"extra": null,
"optionId": "o693fc73e",
"optionImg": null,
"optionName": "游戏x1",
"position": null,
"prizeId": "sp_1",
"prizeType": 1,
"ruleId": "ru_1",
"sendCount": 55,
"url": "null24155",
"userRecordId": 24155
}
],
"prizePendingCode": null,
"sendPrize": true,
"timestamp": 1619146587178,
"title": "1"
},
"message": null,
"success": true
},
"POST /task_1/sendPrize.do": {
"code": null,
"data": {
"extra": null,
"options": [
{
"optionId": "o693fc73e",
"optionImg": null,
"optionName": "游戏x1",
"position": null,
"prizeId": "sp_1",
"sendCount": 15345,
"prizeType": 1,
"ruleId": "ru_1",
"url": "null18519"
}
]
},
"message": null,
"success": true
}
}
module.exports = {
"GET /home/drawIndex.do": {
"success": true,
"message": "报错了~",
"code": null,
timeStamp: Date.now(),
"data": {
"startTime": +new Date() - 123, //活动开始时间戳
"endTime": +new Date() + 123, //活动结束时间戳
"remainDrawTimes": 1, // 抽奖次数
"actPrizeList": [
{
prizeName: `奖品名称奖品名称奖品名称奖品名称1`,
prizeImg: `//yun.duiba.com.cn/polaris/jinmoqiang.9e5bbc004f69ab6a3f34d93daeda028616a9f00d.png`,
prizeId: `thanks1`,
},
{
prizeName: `奖品名称奖品名称`,
prizeImg: `//yun.duiba.com.cn/polaris/kouzhao.dc55dac6db1ff94c4666c2602d6cb0ac84139982.png`,
prizeId: `thanks2`,
},
{
prizeName: `奖品名称奖品`,
prizeImg: `//yun.duiba.com.cn/polaris/mac.fe55aa43e5a231d568973dcdd0b91e0263d5a12c.png`,
prizeId: `thanks3`,
},
{
prizeName: `奖品名称4`,
prizeImg: `//yun.duiba.com.cn/polaris/mgtv.e5f0709a2a4083bc57ce52ff200a50a2e56b2658.png`,
prizeId: `thanks4`,
},
{
prizeName: `奖品名称5`,
prizeImg: `//yun.duiba.com.cn/polaris/qq.73ad13cd0c6fd705327d12957c12e9d5b2e77baa.png`,
prizeId: `thanks5`,
},
{
prizeName: `奖品名称6`,
prizeImg: `//yun.duiba.com.cn/polaris/xx.e2f6a49a2954673d16d956d7b3bba25c2b6c667e.png`,
prizeId: `thanks6`,
},
{
prizeName: `奖品名称7`,
prizeImg: `//yun.duiba.com.cn/polaris/xx.e2f6a49a2954673d16d956d7b3bba25c2b6c667e.png`,
prizeId: `thanks7`,
},
{
prizeName: `谢谢参与lll`,
prizeImg: `https://yun.duiba.com.cn/spark/assets/f77861647e7b55e9c95e9c49d891a21526157a76.jpg`,
prizeId: `thanks`,
},
]
}
},
"GET /home/doDraw.do": {
"success": true,
"message": "报错了~",
"code": null,
"data": {
prizeId: `thanks1`, // 奖品id thanks
prizeName: `奖品名称6gggggggggggggggggggvvvbbbbhsgxhsghshxbhsxbhs`,
prizeImg: `//yun.duiba.com.cn/polaris/xx.e2f6a49a2954673d16d956d7b3bba25c2b6c667e.png`,
},
},
}
\ No newline at end of file
{
"name": "temp_base",
"version": "3.6.8",
"private": true,
"scripts": {
"dev": "cross-env NODE_ENV=development node ./config/scripts/assets/generateAssetList.js && node ./config/webpack.dev.config.js",
"imgmin": "node ./config/scripts/assets/index.js imgmin",
"imgup": "node ./config/scripts/assets/index.js imgup",
"imgminup": "node ./config/scripts/assets/index.js imgmin imgup",
"spark:prebuild": "ncu @spark/pre-build -u && yarn && npx pre-build",
"lint": "eslint --ext .js,jsx,.html src public",
"prod": "rimraf ./dist &&cross-env NODE_ENV=production node ./config/webpack.prod.config.js",
"build": "rimraf ./dist &&cross-env NODE_ENV=production node ./config/scripts/assets/generateAssetList.js && node ./config/scripts/assets/index.js imgmin imgup && node ./config/webpack.prod.config.js"
},
"dependencies": {
"@spark/api-base": "^2.0.7",
"@spark/circle-turntable": "^1.0.3",
"@spark/dbdomain": "^1.0.25",
"@spark/share": "^2.0.340",
"@spark/svgaplayer": "^2.0.5",
"@spark/ui": "^2.0.8",
"@spark/utils": "^2.0.17",
"classnames": "^2.5.1",
"crypto-js": "^4.2.0",
"duiba-utils": "^1.0.2",
"history": "^4.10.1",
"javascript-obfuscator": "^4.1.0",
"mobx": "^6.2.0",
"mobx-react": "^7.1.0",
"qs": "^6.9.4",
"react": "^16.4.1",
"react-dom": "^16.4.1",
"sa-sdk-javascript": "^1.27.4",
"spark-utils": "^0.0.12",
"terser-webpack-plugin": "4.2.3",
"video.js": "^8.22.0"
},
"devDependencies": {
"@babel/core": "^7.12.10",
"@babel/eslint-parser": "^7.17.0",
"@babel/plugin-proposal-decorators": "^7.13.15",
"@babel/plugin-transform-runtime": "^7.12.10",
"@babel/preset-env": "^7.12.11",
"@babel/preset-react": "^7.12.10",
"@spark/eslint-plugin-best-practices": "^0.0.1-beta.2",
"@spark/eslint-plugin-security": "^0.0.1-beta.5",
"@spark/pre-build": "^0.0.1-beta.11",
"@types/crypto-js": "^4.2.2",
"autoprefixer": "^9.8.6",
"babel-loader": "^8.2.2",
"chalk": "^4.1.0",
"clean-webpack-plugin": "^3.0.0",
"commander": "^11.1.0",
"cross-env": "^7.0.3",
"css-loader": "^3.6.0",
"eslint": "^8.22.0",
"eslint-plugin-html": "^6.2.0",
"eslint-plugin-react": "^7.29.4",
"fs-extra": "^9.0.1",
"html-webpack-plugin": "^4.5.1",
"less": "^4.1.0",
"less-loader": "^7.2.1",
"mini-css-extract-plugin": "^1.3.4",
"mocker-api": "^2.7.5",
"npm-check-updates": "^12.5.4",
"optimize-css-assets-webpack-plugin": "^5.0.4",
"postcss-loader": "^3.0.0",
"postcss-px2rem-exclude": "0.0.6",
"prettier": "^2.0.5",
"progress-bar-webpack-plugin": "^2.1.0",
"rimraf": "^3.0.2",
"script-ext-html-webpack-plugin": "^2.1.5",
"spark-assets": "^2.6.2",
"spark-log-event": "^1.0.4",
"style-loader": "^1.2.1",
"url-loader": "^4.1.1",
"webpack": "^4.43.0",
"webpack-bundle-analyzer": "^4.5.0",
"webpack-cli": "^4.3.1",
"webpack-dev-server": "^3.11.0",
"webpack-merge": "^4.2.2"
}
}
{"proSetting":{"projectxIDs":{"testId":[{"label":"测试","value":"pa1ce2110"}],"prodId":[{"label":"线上测试","value":"p8d9bf93b"},{"label":"线上正式","value":"peb5290b6"}]},"skinVariables":[],"mockSetting":{"projectId":"","pageId":""}},"envSetting":{},"psdSetting":{"psdFSSetting":true,"psdCenterSetting":true}}
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<link rel="dns-prefetch" href="//yun.duiba.com.cn" />
<link rel="preconnect" href="//embedlog.duiba.com.cn">
<title>粽意测试局</title>
<script type="text/javascript">
if (localStorage && localStorage.isWebp) {
document
.getElementsByTagName('html')[0]
.setAttribute('duiba-webp', 'true');
}
</script>
<script src="//yun.duiba.com.cn/spark/v2/spark.base.fz.wxpollyfill.js"></script>
<script src="//yun.duiba.com.cn/js-libs/rem/1.1.3/rem.min.js"></script>
<script src="//yun.duiba.com.cn/h5/lib/zepto.min.js"></script>
<script src="//res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
<script>
var CFG = CFG || {};
CFG.projectId = location.pathname.split('/')[2] || '1';
function getUrlParam(name) {
var search = window.location.search;
var matched = search
.slice(1)
.match(new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i'));
return search.length ? matched && matched[2] : null;
}
CFG.appID = '${APPID}';
CFG.activityName = "官微-25端午节活动";
CFG.channel = getUrlParam("channel") || sessionStorage.getItem("channel")
CFG.empno = getUrlParam('empno') || sessionStorage.getItem("empno")
CFG.empname = getUrlParam('empname') || sessionStorage.getItem("empname")
CFG.empno && sessionStorage.setItem("empno", CFG.empno)
CFG.empname && sessionStorage.setItem("empname", CFG.empname)
CFG.channel && sessionStorage.setItem("channel", CFG.channel)
if (location.href.indexOf("customShare") > 0) {
CFG.appID = "93842";
if (location.href.indexOf("Did1NjA4NjM") > 0) { // 线上测试免登中间页
CFG.projectId = "p8d9bf93b"; // 线上测试
} else {
CFG.projectId = "peb5290b6"; // 线上正式
}
}
// 动态域名
CFG.domain = window.location.origin;
// 首页 app.jsx中会拼动态域名
CFG.index = '/projectx/' + CFG.projectId + '/index.html?appID=' + CFG.appID;
// 我的奖品页
CFG.prize = 'myPrize.html?appID=' + CFG.appID + '&channel=' + getUrlParam("channel") + '&fromPage=home';
// 免登的地址
CFG.middleRequest = "https://93842-activity.dexfu.cn//customActivity/taibao/login?";
// 正式要改
CFG.middleTHRequest = "https://93842-activity.dexfu.cn//customActivity/taibao/thd/login?";
// 正式 奖品页面跳转链接
CFG.prizeJumpUrl = "https://wx.cpic.com.cn/cpiccustomerclub/userInformation/index.html";
// 生产
CFG.sensorUrl = 'https://xnjkfx.cpic.com.cn:8006/sa?project=SXGW';
// 环境,test测试,prod生产 TODO
CFG.env = 'prod';
CFG.environment = '';
//关注公众号二维码-正式
CFG.codeUrl = 'https://yun.duiba.com.cn/polaris/guanzhuCode.a398f4a2e47acb9265b0022adf36c9355921d975.png'
// 官微绑定页面地址 生产环境
CFG.bindUrl = 'https://wx.cpic.com.cn/sxwxclub/wx/menuByState?state=21039&source_channel=24NEMT'
if (CFG.env == 'test') {
// 测试
CFG.environment = 'test';
CFG.miniEnv = "trial";
CFG.sensorUrl = 'https://xnjkfxsit.cpic.com.cn/sa?project=SXGW';
//关注公众号二维码-测试
CFG.codeUrl = "https://yun.duiba.com.cn/polaris/moon-test.8a5c54742e74780a76e7809255016cf522441232.png";
// 测试 奖品页面跳转链接
CFG.prizeJumpUrl = "https://wxtest.cpic.com.cn/cpiccustomerclub/userInformation/index.html";
// 官微绑定页面地址 测试环境
CFG.bindUrl = "https://wxtest.cpic.com.cn/sxwxclub/wx/menuByState?state=21039&source_channel=24NEMT";
}
if (!getUrlParam("appID")) {
// alert("【警告】检测到活动url中没有appID参数\n缺少该参数会导致埋点、分享、app信息获取错误。")
}
</script>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
\ No newline at end of file
{"proName":"太保-端午节-20250429","proDesc":"","proPath":"/Users/yujiating/Documents/programme/太保-端午节-20250429","createTime":1745912031535}
module.exports ={
"OUTPUT_DIR": "dist",
"SOURCE_DIR": "src",
"TEMP_DIR": "./.temp",
"ENTRY": "src/app.jsx",
"TEMPLATE": "./public/index.html",
"API_MOCK": true,
"PX2REM": true,
"IMAGE_Q1": 0.6,
"IMAGE_Q2": 0.8,
"RES_PATH": "/src/assets/",
"RES_PATH_PROD": "//yun.duiba.com.cn/spark/v2/temp_base/1747634221363",
"JS_PATH_PROD": "https://yun.duiba.com.cn/spark/v2/temp_base/1748589458226/js"
}
\ No newline at end of file
{"assetsPathArr":["//yun.duiba.com.cn/spark/v2/temp_base/1678169645525/loadingDemo/上面.png","//yun.duiba.com.cn/spark/v2/temp_base/1678169645525/loadingDemo/底部173.png","//yun.duiba.com.cn/spark/v2/temp_base/1678169645525/loadingDemo/背景.jpg"]}
\ No newline at end of file
import API from "@src/api";
import {
setCookieId
} from "@src/api/utils";
/**
* 普通跳转客服
* 注意:小程序需要额外增加业务域名 https://duiba.qiyukf.com/
*/
export function jumpService() {
location.href = location.origin + '/faq/index'
}
export function appJump(url, hideNavbar = false, data = {}) {
API.tempSaveCookie().then((res) => {
if (res?.data) {
localStorage.setItem("db_temp_cookie", res.data);
// setCookieId(res.data);
}
}).finally(() => {
// app对应跳转方法
window.MarsJSBridge.invoke("pushPage", {
uri: url,
data,
pageParams: {
hideNavbar,
}
});
});
}
import { generateAPI } from "./utils.js"
const API = generateAPI({
/** 获取活动规则 */
getRule: 'projectRule.query',
/** 获取前端配置项 */
getFrontVariable: 'coop_frontVariable.query',
/** 参与接口 post请求 */
doJoin: {
uri: 'join.do',
method: "post"
},
/** 签到 */
doSign: {
uri: 'checkin_1/doSign.do',
withToken: true, // 携带token
},
// cookie丢失-临时保存cookie
tempSaveCookie: {
uri: "/autoLogin/tempSaveCookie",
showMsg: false,
},
// cookie丢失-重新设置cookie
resetCookie: "/autoLogin/resetCookie",
userLogin: {
uri: "userLogin.check",
showMsg: false,
},
buriedPoint: {
uri: "home/buriedPoint.do",
showMsg: false,
},
home: 'home/index.do',
startAnswer: {
uri: 'home/startAnswer.do',
withToken: true, // 携带token
},
submitAnswer: {
uri: 'home/submitAnswer.do',
withToken: true, // 携带token
},
/** 抽奖首页 */
drawIndex: "home/drawIndex.do",
/** 抽奖 */
drawJoin: {
uri: "home/doDraw.do",
withToken: true,
},
/** 查询用户信息(神策埋点用) */
queryUserInfo: "common/queryUserInfo.do",
/** 查询任务列表 */
queryTasks: "task_1/queryTasks.do",
/** 完成任务 */
doCompleted: {
method: "post",
uri: "task_1/doCompleted.do",
withToken: true,
},
/** 任务发奖 */
sendPrize: {
method: "post",
uri: "task_1/sendPrize.do",
withToken: true,
},
/** 奖品页信息 */
getPrizePageInfo: "common/prizeRecord.do",
createCode: "/customActivity/taibao/custom/createCode",
thdLoginNew: {
uri: '/customActivity/taibao/thd/authLogin'
},
tbLoginNew: {
uri: 'https://customer-link.duiba.com.cn/customer/93842/taibao/login'
},
})
// console.log('======', API)
export default API
declare type Methods = 'get' | 'post';
declare interface APIArguments {
uri: string,
method?: Methods | Uppercase<Methods>,
headers?: any
withToken?: boolean
secret?: string,
secretKey?: string,
contentType?: string,
showMsg?:boolean,
showLoading?: boolean;
}
declare type APIConfig = APIArguments | string
declare interface GenerateAPIParams {
[key: string]: APIConfig
}
declare type RequestParamType = Record<string, any>
declare interface ResponseType<T = any> {
code: number,
success: boolean,
message: string,
data: T
}
export declare function generateAPI<
T extends GenerateAPIParams = GenerateAPIParams,
P = RequestParamType,
Q = ResponseType>
(apiList: T): {
[key in keyof T]: (args?: P) => Promise<Q>
}
import { callApi } from '@spark/api-base'
import { Loading, Toast } from '@spark/ui'
import { isFromShare, newUser } from 'duiba-utils';
import { errorHandler } from "@src/utils/errorHandler";
import API from "@src/api/index";
import { getPxToken } from "@src/built-in/getPxToken";
const mergeData = {
user_type: newUser ? '0' : '1',
is_from_share: isFromShare ? '0' : '1',
channel: CFG.channel || '',
from: CFG.channel || ''
}
// let tempCookieId = "";
//
// export function setCookieId(cookieId) {
// tempCookieId = cookieId;
// }
export function resetBackCookie(duibaTempCookieId) {
return new Promise((resolve) => {
callApi("/autoLogin/resetCookie", {
duibaTempCookieId
}).then((resp) => {
return resolve('success');
}, (e) => {
return resolve(e);
});
});
}
/**
* 请求方法get、post处理
* @param {*} value
* @returns
*/
function getRequestParams(value) {
if (typeof value === 'string') {
return {
uri: value,
method: 'get'
}
} else if (typeof value === 'object') {
const { uri, method = 'get', showMsg = true, showLoading = false, headers, withToken, secret, secretKey, contentType = 'form' } = value;
return {
uri,
method,
headers,
withToken,
secret,
secretKey,
contentType,
showLoading,
showMsg
}
} else {
console.error('getRequestParams: 传参有误');
}
}
/**
* 请求API通用处理
* @param {*} value
* @returns
*/
export function generateAPI(apiList) {
const api = {};
for (const key in apiList) {
const value = apiList[key];
const { method, uri, headers: mHeaders, withToken, secret, secretKey, contentType, showLoading, showMsg = true } = getRequestParams(value);
api[key] = async (params = {}, headers) => {
// cookie丢失的问题
// 如遇跳转Cookie丢失,打开如下代码
// const duibaTempCookieId = localStorage.getItem("db_temp_cookie");
// // const duibaTempCookieId = tempCookieId;
//
// if (duibaTempCookieId) {
// localStorage.removeItem("db_temp_cookie");
// // tempCookieId = "";
//
// const res = await API.userLogin()
// .catch(async () => {
// await resetBackCookie(duibaTempCookieId);
// });
//
// if (!res || !res.success) {
// await resetBackCookie(duibaTempCookieId);
// }
// }
// 根据接口配置showLoading展示loading
// 600ms内结束的请求不显示loading,避免闪烁
let query = false;
showLoading && setTimeout(() => {
if (!query) {
Loading.show();
}
}, 600);
let token;
if (withToken) { // 是否携带token
try {
token = await getPxToken(); // 获取token
} catch (e) {
Toast('网络异常,请稍后再试~');
query = true;
showLoading && Loading.hide();// 根据接口配置showLoading关闭loading
return ({ success: false, data: '' });
}
}
const mergedHeaders = { ...mHeaders, ...headers }
if (withToken && token) {
params.token = token;
}
params = { ...params, ...mergeData };
const result = await callApi(uri, params, method, mergedHeaders, false, secret, secretKey, contentType)
.catch(e => {
query = true;
// 捕获网络异常
showMsg && Toast(e.message || '网络异常,请稍后再试~');
showLoading && Loading.hide();
});
query = true;
showLoading && Loading.hide();// 根据接口配置showLoading关闭loading
return new Promise((resolve) => {
if (result) {
// 判断接口错误
if (!result.success && showMsg) {
errorHandler(result);
}
// 返回整个结果
resolve(result);
} else {
resolve({ success: false, data: '' });
}
})
}
}
return api;
}
/**
* 活动主入口
*/
import React, { Component } from "react";
import ReactDOM from "react-dom";
import { observer } from "mobx-react";
import "./app.less";
import store from "./store/index";
import Modal from "./modal/modal";
import "./utils/checkwebp"; // webp检查
import MD from "../MD"; // 埋点
MD();
// 此处为spark-cli动态生成
import LoadingDemo from "@src/pages/LoadingDemo/LoadingDemo";
import Homepage from "./pages/homepage/homepage";
import { PAGE_MAP } from "./utils/constants";
import { ensureDomain, domain } from '@spark/dbdomain';
import Answerpage from "./pages/answerpage/answerpage";
import Prizepage from "./pages/prizepage/prizepage";
import Drawpage from "./pages/drawpage/drawpage";
import Resultpage from "./pages/resultpage/resultpage";
import MiddlePageNew from "@src/pages/middlePageNew/middlePageNew";
import { loadOneFont } from "./utils/preload1.3";
/**
* 所有页面场景
*/
const pageMap = {
[PAGE_MAP.LOADING_PAGE]: <LoadingDemo />,
[PAGE_MAP.HOME_PAGE]: <Homepage />,
[PAGE_MAP.QUES_PAGE]: <Answerpage />,
[PAGE_MAP.PRIZE_PAGE]: <Prizepage />,
[PAGE_MAP.DRAW_PAGE]: <Drawpage />,
[PAGE_MAP.RESU_PAGE]: <Resultpage />,
[PAGE_MAP.MID_PAGE]: <MiddlePageNew />,
};
@observer
class App extends Component {
async componentDidMount() {
// 获取前端开发配置,依据项目需要,酌情添加 !!!
if (store.curPage !== PAGE_MAP.MID_PAGE) {
await store.getFrontVariable();
// 获取动态域名
await ensureDomain();
CFG.domain = domain || window.location.origin;
CFG.index = CFG.domain + CFG.index;
}
if (store.curPage === PAGE_MAP.HOME_PAGE) {
this.loadFonts();
}
}
/**
* 加载特殊字体包
*/
loadFonts = async() => {
await loadOneFont(
"//yun.duiba.com.cn/polaris/Alimama_DongFangDaKai_Regular.48e78d785f0db9f0e1de9defb6a5994b76bfc188.ttf",
"Alimama_DongFangDaKai_Regular"
);
};
render() {
const { curPage, pageData } = store;
return (
<>
{{ ...pageMap[curPage], props: { ...pageData } }}
<Modal />
</>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
* {
margin: 0;
padding: 0;
-webkit-touch-callout: none; /*系统默认菜单被禁用*/
-khtml-user-select: none; /*早期浏览器*/
-moz-user-select: none; /*火狐*/
-ms-user-select: none; /*IE10*/
-webkit-tap-highlight-color: transparent;
user-select: text;
-webkit-user-select: text;
}
*:not(input,textarea) {
-webkit-touch-callout: none;
-webkit-user-select: none;
}
html,
body {
font-size: 24px;
width: 100%;
height: 100%;
-webkit-text-size-adjust: 100% !important;
text-size-adjust: 100% !important;
-moz-text-size-adjust: 100% !important;
overflow: hidden;
}
.modal_center {
left: 0 !important;
top: 0 !important;
bottom: 0 !important;
right: 0 !important;
margin: auto;
}
#root {
width: 100%;
height: 100%;
position: relative;
overflow: hidden;
}
.com_Container {
width: 100%;
height: 100%;
position: relative;
overflow-x: hidden;
overflow-y: auto;
}
{"preLoadImg":[],"asyncLoadImg":["answerPage/bg1.png","answerPage/bg2.png","answerPage/bg3.png","answerPage/bg4.png","answerPage/bg5.png","answerPage/content_bg.png","answerPage/option_bg.png","answerPage/option_bg_select.png","answerPage/progress1.png","answerPage/progress2.png","answerPage/progress3.png","answerPage/progress4.png","answerPage/progress5.png","answerPage/progress_bg.png","answerPage/progress_title.png","answerPage/queslast.png","answerPage/quesnext.png","answerPage/submitbtn.png","bindPop/bg.png","bindPop/bind_btn.png","common/back.png","common/close.png","drawChancePop/bg.png","drawChancePop/btn.png","drawFailPop/bg.png","drawFailPop/btn.png","drawPage/bg.png","drawPage/cloud.png","drawPage/draw_btn.png","drawPage/pointer.png","drawPage/prize_btn.png","drawPage/rule_btn.png","drawPage/subtitle_bg.png","drawPage/task_btn.png","drawPage/title.png","drawPage/turntable_bg.png","drawPage/turntable_box.png","drawSucPop/bg.png","drawSucPop/happy_btn.png","drawSucPop/leaves.png","drawSucPop/light.png","drawSucPop/prize_img.png","exitPop/bg.png","exitPop/cancel_btn.png","exitPop/confirm_btn.png","focusPop/bg.png","focusPop/qrcode_bg.png","homePage/bg.png","homePage/content.png","homePage/draw_btn.png","homePage/main_btn.png","homePage/ptize_btn.png","homePage/rule_btn.png","homePage/share_btn.png","homePage/subtitle_bg.png","homePage/task_btn.png","homePage/title.png","LoadingPage/loadingBg.jpg","LoadingPage/loadingFill.png","LoadingPage/loadingIp.png","mid/bg.jpg","prizePage/bg.png","prizePage/prize_btn.png","prizePage/prize_img.png","prizePage/prize_item_bg.png","prizePage/title.png","resultPage/bg.png","resultPage/code_bg.png","resultPage/code_img.png","resultPage/draw_btn.png","resultPage/product_btn.png","resultPage/share_btn.png","resultPage/传统守护者.png","resultPage/佛系随性派.png","resultPage/元气美食家.png","resultPage/狂热尝新党.png","resultPage/社交组局王.png","rulePop/bg.png","svga/choose.svga","svga/home.svga","svga/pop.svga","taskPop/bg.png","taskPop/grey_bg.png","taskPop/red_bg.png","taskPop/task_icon.png","taskPop/task_item_bg.png","taskPop/yellow_bg.png"]}
\ No newline at end of file
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