Commit b2d42324 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
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
tmp.txt
dist/*/*
!dist/index.html
___cache
registry = http://npm.dui88.com
\ No newline at end of file
# NO SPARK !!!!!
# 为了消除疯火台影响,特地做此框架,建设中,未完工
UPLOAD_DIR=db_games/spark/v3
\ No newline at end of file
# .env.production
CDN_DOMAIN=https://yun.duiba.com.cn
OSS_REGION=oss-cn-hangzhou
OSS_BUCKET=duiba
OSS_ACCESS_KEY_ID=LTAI5tPUSSxgkEmKPAfVXUQQ
OSS_ACCESS_SECRET=6sk3EDd1BYrXlAUoh8maMuN7hOMkh1
import { execSync } from 'child_process';
import * as path from "path";
import { promises as fs } from "fs";
import * as Os from "os";
import * as fsSync from "fs";
import * as crypto from "crypto";
/** 压缩引擎路径表 */
const enginePathMap = {
/** macOS */
'darwin': 'pngquant/macos/pngquant',
/** Windows */
'win32': 'pngquant/windows/pngquant'
}
export async function compressAllImage(
paths = [],
onProgress: (cur?: number, total?: number) => void = () => void 0,
) {
const platform = Os.platform();
const pngquantPath = path.join(__dirname, "./", enginePathMap[platform]);
// 设置引擎文件的执行权限(仅 macOS)
if (pngquantPath && platform === 'darwin') {
if ((await fs.stat(pngquantPath)).mode != 33261) {
// 默认为 33188
await fs.chmod(pngquantPath, 33261);
}
}
const qualityParam = `--quality 0-99`,
speedParam = `--speed 4`,
// skipParam = platform == "win32" ? "" : '--skip-if-larger',
skipParam = '--skip-if-larger',
outputParam = '--ext=.png',
writeParam = '--force',
// colorsParam = config.colors,
// compressOptions = `${qualityParam} ${speedParam} ${skipParam} ${outputParam} ${writeParam} ${colorsParam}`;
compressOptions = `${qualityParam} ${speedParam} ${skipParam} ${outputParam} ${writeParam}`;
let completed = 0;
const chunkSize = 20;
const userHomeDir = Os.homedir();
const cacheDir = path.join(userHomeDir, ".image_compress_cache");
if (!fsSync.existsSync(cacheDir)) await fs.mkdir(cacheDir, { recursive: true });
const now = Date.now();
const tempDir = path.join(userHomeDir, `.image_compress_temp/${now}`);
if (!fsSync.existsSync(tempDir)) await fs.mkdir(tempDir, { recursive: true });
for (let i = 0; i < paths.length; i += chunkSize) {
const chunk = paths.slice(i, i + chunkSize);
const ps = chunk.map(async (imgPath, idx) => {
const tempName = `${tempDir}/${i + idx}.png`;
// 检查缓存
const fileBuffer = await fs.readFile(imgPath);
const md5Hash = crypto.createHash("md5").update(fileBuffer).digest("hex");
const cachedFilePath = path.join(cacheDir, `${md5Hash}.png`);
if (fsSync.existsSync(cachedFilePath)) {
// 如果缓存文件存在,直接复制到目标路径
await fs.copyFile(cachedFilePath, imgPath);
} else {
// 如果缓存文件不存在,执行压缩操作并缓存
await fs.copyFile(imgPath, tempName);
execSync(`"${pngquantPath}" ${compressOptions} "${tempName}"`);
await fs.copyFile(tempName, imgPath);
await fs.copyFile(tempName, cachedFilePath);
}
completed++;
onProgress(completed, paths.length);
});
await Promise.all(ps);
}
await fs.rm(tempDir, { recursive: true });
}
import {promises as fs} from "fs";
import SvgaDescriptor from "./SvgaDescriptor";
import {compressAllImage} from "./ImageCompress";
import * as pako from "pako";
import protobuf from "protobufjs";
import chalk from "chalk";
import * as Os from "node:os";
import * as path from "node:path";
const ProtoMovieEntity = protobuf.Root
.fromJSON(SvgaDescriptor)
.lookupType('com.opensource.svga.MovieEntity');
/**
* 压缩Svga
* @author haiyoucuv
* @param {string}svga
* @return {Promise<boolean|ArrayBuffer>}
*/
export async function compressSvga(svga: string): Promise<Uint8Array> {
try {
const buffer = await fs.readFile(svga);
// 解析svga
const data = ProtoMovieEntity.decode(pako.inflate(buffer)).toJSON();
const {images} = data;
let tempDir = svga.replace(/\.svga/, '') + "__temp__/";
// if (Os.platform() == "win32") {
// const now = Date.now();
// tempDir = `C:\\Temp\\duiba\\${now}`
//
// if (!fs.existsSync("C:\\Temp")) fs.mkdirSync("C:\\Temp");
// if (!fs.existsSync("C:\\Temp\\duiba")) fs.mkdirSync("C:\\Temp\\duiba");
// if (!fs.existsSync(tempDir)) fs.mkdirSync(tempDir);
// }
await fs.mkdir(tempDir);
const ps1 = Object.keys(images).map(async (name) => {
const path = `${tempDir}${name}.png`;
await fs.writeFile(path, Buffer.from(images[name], 'base64'));
return path;
});
// 保存图片
const imgPaths = await Promise.all(ps1);
// 压缩图片
await compressAllImage(imgPaths);
// 读取图片,还原到data
const ps2 = Object.keys(images).map(async (name) => {
const path = `${tempDir}${name}.png`;
const buffer = await fs.readFile(path);
data.images[name] = buffer.toString('base64');
});
await Promise.all(ps2);
await fs.rm(tempDir, {recursive: true});
// 压缩buffer
return pako.deflate(ProtoMovieEntity.encode(data).finish());
} catch (e) {
console.log(e);
return null;
}
}
export async function compressAllSvga(
paths = [],
onProgress: (cur?: number, total?: number) => void = () => void 0,
) {
for (let i = 0; i < paths.length; i++) {
const svga = paths[i];
const fileName = path.basename(svga);
try {
const sizePre = (await fs.stat(svga)).size;
const result = await compressSvga(svga);
if (result) {
await fs.writeFile(svga, result);
const sizeOp = (await fs.stat(svga)).size;
const radio = ((1 - sizeOp / sizePre) * 100).toFixed(2);
console.log(chalk.green("压缩Svga成功:" + fileName, `,压缩率:${radio}`));
}
} catch (e) {
console.log(chalk.red("压缩Svga失败:" + fileName));
}
onProgress(i + 1, paths.length);
}
// let completed = 0;
// const svgaPArr = paths.map((svga) => {
// return (async () => {
// const fileName = path.basename(svga);
// try {
// const sizePre = (await fs.stat(svga)).size;
// const result = await compressSvga(svga);
// if (result) {
// await fs.writeFile(svga, result);
// const sizeOp = (await fs.stat(svga)).size;
// const radio = ((1 - sizeOp / sizePre) * 100).toFixed(2);
// console.log(chalk.green("压缩Svga成功:" + fileName, `,压缩率:${radio}`));
// }
// } catch (e) {
// console.log(chalk.red("压缩Svga失败:" + fileName));
// }
//
// onProgress(completed++, paths.length);
// })();
// });
//
// await Promise.all(svgaPArr);
}
This diff is collapsed.
This diff is collapsed.
# pngquant 3 [![CI](https://github.com/kornelski/pngquant/actions/workflows/ci.yml/badge.svg)](https://github.com/kornelski/pngquant/actions/workflows/ci.yml)
[pngquant](https://pngquant.org) is a PNG compressor that significantly reduces file sizes by converting images to a more efficient 8-bit PNG format *with alpha channel* (often 60-80% smaller than 24/32-bit PNG files). Compressed images are fully standards-compliant and are supported by all web browsers and operating systems.
[This](https://github.com/kornelski/pngquant) is the official `pngquant` repository. The compression engine is also available [as an embeddable library](https://github.com/ImageOptim/libimagequant).
## Usage
- batch conversion of multiple files: `pngquant *.png`
- Unix-style stdin/stdout chaining: `… | pngquant - | …`
To further reduce file size, try [oxipng](https://lib.rs/oxipng), [ImageOptim](https://imageoptim.com), or [zopflipng](https://github.com/google/zopfli).
## Features
* High-quality palette generation
- advanced quantization algorithm with support for gamma correction and premultiplied alpha
- unique dithering algorithm that does not add unnecessary noise to the image
* Configurable quality level
- automatically finds required number of colors and can skip images which can't be converted with the desired quality
* Fast, modern code
- based on a portable [libimagequant library](https://github.com/ImageOptim/libimagequant)
- C99 with no workarounds for legacy systems or compilers ([apart from Visual Studio](https://github.com/kornelski/pngquant/tree/msvc))
- multicore support (via OpenMP) and Intel SSE optimizations
## Options
See `pngquant -h` for full list.
### `--quality min-max`
`min` and `max` are numbers in range 0 (worst) to 100 (perfect), similar to JPEG. pngquant will use the least amount of colors required to meet or exceed the `max` quality. If conversion results in quality below the `min` quality the image won't be saved (if outputting to stdin, 24-bit original will be output) and pngquant will exit with status code 99.
pngquant --quality=65-80 image.png
### `--ext new.png`
Set custom extension (suffix) for output filename. By default `-or8.png` or `-fs8.png` is used. If you use `--ext=.png --force` options pngquant will overwrite input files in place (use with caution).
### `-o out.png` or `--output out.png`
Writes converted file to the given path. When this option is used only single input file is allowed.
### `--skip-if-larger`
Don't write converted files if the conversion isn't worth it.
### `--speed N`
Speed/quality trade-off from 1 (slowest, highest quality, smallest files) to 11 (fastest, less consistent quality, light comperssion). The default is 4. It's recommended to keep the default, unless you need to generate images in real time (e.g. map tiles). Higher speeds are fine with 256 colors, but don't handle lower number of colors well.
### `--nofs`
Disables Floyd-Steinberg dithering.
### `--floyd=0.5`
Controls level of dithering (0 = none, 1 = full). Note that the `=` character is required.
### `--posterize bits`
Reduce precision of the palette by number of bits. Use when the image will be displayed on low-depth screens (e.g. 16-bit displays or compressed textures in ARGB444 format).
### `--strip`
Don't copy optional PNG chunks. Metadata is always removed on Mac (when using Cocoa reader).
See [man page](https://github.com/kornelski/pngquant/blob/master/pngquant.1) (`man pngquant`) for the full list of options.
## License
pngquant is dual-licensed:
* Under **GPL v3** or later with an additional [copyright notice](https://github.com/kornelski/pngquant/blob/master/COPYRIGHT) that must be kept for the older parts of the code.
* Or [a **commercial license**](https://supso.org/projects/pngquant) for use in non-GPL software (e.g. closed-source or App Store distribution). You can [get the license via Super Source](https://supso.org/projects/pngquant). Email kornel@pngquant.org if you have any questions.
Apple's Notarization is a control-freak mess, and I don't have enough patience to deal with their tooling. 'brew install pngquant' may work too
This diff is collapsed.
@echo off
set path=%~d0%~p0
:start
"%path%pngquant.exe" --force --verbose --quality=45-85 %1
"%path%pngquant.exe" --force --verbose --ordered --speed=1 --quality=50-90 %1
shift
if NOT x%1==x goto start
@echo off
set path=%~d0%~p0
:start
"%path%pngquant.exe" --force --verbose 256 %1
shift
if NOT x%1==x goto start
# pngquant 2
[pngquant](https://pngquant.org) is a PNG compresor that significantly reduces file sizes by converting images to a more efficient 8-bit PNG format *with alpha channel* (often 60-80% smaller than 24/32-bit PNG files). Compressed images are fully standards-compliant and are supported by all web browsers and operating systems.
[This](https://github.com/kornelski/pngquant) is the official `pngquant` repository. The compression engine is also available [as an embeddable library](https://github.com/ImageOptim/libimagequant).
## Usage
- batch conversion of multiple files: `pngquant *.png`
- Unix-style stdin/stdout chaining: `… | pngquant - | …`
To further reduce file size, try [optipng](http://optipng.sourceforge.net), [ImageOptim](https://imageoptim.com), or [zopflipng](https://github.com/google/zopfli).
## Features
* High-quality palette generation
- advanced quantization algorithm with support for gamma correction and premultiplied alpha
- unique dithering algorithm that does not add unnecessary noise to the image
* Configurable quality level
- automatically finds required number of colors and can skip images which can't be converted with the desired quality
* Fast, modern code
- based on a portable [libimagequant library](https://github.com/ImageOptim/libimagequant)
- C99 with no workarounds for legacy systems or compilers ([apart from Visual Studio](https://github.com/kornelski/pngquant/tree/msvc))
- multicore support (via OpenMP) and Intel SSE optimizations
## Options
See `pngquant -h` for full list.
### `--quality min-max`
`min` and `max` are numbers in range 0 (worst) to 100 (perfect), similar to JPEG. pngquant will use the least amount of colors required to meet or exceed the `max` quality. If conversion results in quality below the `min` quality the image won't be saved (if outputting to stdin, 24-bit original will be output) and pngquant will exit with status code 99.
pngquant --quality=65-80 image.png
### `--ext new.png`
Set custom extension (suffix) for output filename. By default `-or8.png` or `-fs8.png` is used. If you use `--ext=.png --force` options pngquant will overwrite input files in place (use with caution).
### `-o out.png` or `--output out.png`
Writes converted file to the given path. When this option is used only single input file is allowed.
### `--skip-if-larger`
Don't write converted files if the conversion isn't worth it.
### `--speed N`
Speed/quality trade-off from 1 (slowest, highest quality, smallest files) to 11 (fastest, less consistent quality, light comperssion). The default is 3. It's recommended to keep the default, unless you need to generate images in real time (e.g. map tiles). Higher speeds are fine with 256 colors, but don't handle lower number of colors well.
### `--nofs`
Disables Floyd-Steinberg dithering.
### `--floyd=0.5`
Controls level of dithering (0 = none, 1 = full). Note that the `=` character is required.
### `--posterize bits`
Reduce precision of the palette by number of bits. Use when the image will be displayed on low-depth screens (e.g. 16-bit displays or compressed textures in ARGB444 format).
### `--strip`
Don't copy optional PNG chunks. Metadata is always removed on Mac (when using Cocoa reader).
See [man page](https://github.com/kornelski/pngquant/blob/master/pngquant.1) (`man pngquant`) for the full list of options.
## License
pngquant is dual-licensed:
* Under **GPL v3** or later with an additional [copyright notice](https://github.com/kornelski/pngquant/blob/master/COPYRIGHT) that must be kept for the older parts of the code.
* Or [a **commercial license**](https://supportedsource.org/projects/pngquant) for use in non-GPL software (e.g. closed-source or App Store distribution). You can [get the license via Supported Source](https://supportedsource.org/projects/pngquant/purchase). Email kornel@pngquant.org if you have any questions.
import chalk from "chalk";
import AutoUpload from "../Uploader/Uploader.ts";
import * as path from "path";
import {findFiles} from "../commom/helper.ts";
import {compressAllImage} from "../AssetsMin/ImageCompress.ts";
import {compressAllSvga} from "../AssetsMin/SvgaCompress.ts";
import ProgressBar from "progress";
interface IDuibaPublishOptions {
buildVersion: string | number,
uploadDir: string,
accessKeySecret: string,
accessKeyId: string,
bucket: string,
region: string,
}
export default function DuibaPublish(options: IDuibaPublishOptions) {
const {
buildVersion,
uploadDir,
accessKeySecret,
accessKeyId,
bucket,
region,
} = options;
return {
name: 'duiba-publish',
async closeBundle() {
// 资源压缩
console.log(chalk.green("开始资源压缩了"));
console.log(chalk.green("开始压缩图片了"));
const imgPaths = findFiles(path.resolve("dist"), /\.png$/);
const bar = new ProgressBar(`压缩图片进度 [:bar] :current/${imgPaths.length} :percent :elapseds`, {
complete: "●",
incomplete: "○",
width: 20,
total: imgPaths.length,
callback: () => {
console.log("%cAll complete.", "color: green");
}
})
await compressAllImage(imgPaths, (cur, total) => {
bar.tick();
});
console.log(chalk.green("\n压缩图片结束了\n"));
// 资源压缩
console.log(chalk.green("开始压缩Svga了"));
const svgaPaths = findFiles(path.resolve("dist"), /\.svga$/);
await compressAllSvga(svgaPaths, (cur, total) => {
// process.stdout.write(chalk.green(`\r压缩Svga进度:${cur}/${total}`));
});
console.log(chalk.green("\n压缩Svga结束了\n"));
console.log(chalk.green("开始上传了"));
const autoUpload = new AutoUpload({
dir: path.resolve("dist"),
originDir: `/${uploadDir}/${buildVersion}/`,
accessKeySecret, accessKeyId, bucket, region,
});
await autoUpload.start();
console.log(`${chalk.green(`上传成功,版本号: ${buildVersion}`)}`);
}
}
}
import * as path from "path";
import * as fs from "fs";
import ProgressBar from "progress";
import OSS from "ali-oss";
interface IAutoUploadOptions {
dir: string,
originDir: string,
bucket: string,
accessKeyId: string,
accessKeySecret: string,
region: string,
}
export default class AutoUpload {
options: IAutoUploadOptions = {
dir: "",
originDir: "",
region: "oss-cn-hangzhou",
accessKeyId: "",
accessKeySecret: "",
bucket: ""
};
client = null;
bar = null;
private _files: any[];
private existFiles: number = 0;
private uploadFiles: number = 0;
private errorFiles: number = 0;
constructor(props: IAutoUploadOptions) {
this.options = Object.assign({}, this.options, props);
const checkOptions = [
"dir", "originDir",
"bucket", "region",
"accessKeySecret", "accessKeyId",
];
for (const optionKey of checkOptions) {
if (!this.options[optionKey]) {
throw new Error(`AutoUpload: required option "${optionKey}"`);
}
}
this.init();
}
init() {
const {accessKeyId, accessKeySecret, bucket, region} = this.options;
this.client = new OSS({region, accessKeyId, accessKeySecret, bucket});
this.bar = new ProgressBar(`文件上传中 [:bar] :current/${this.files().length} :percent :elapseds`, {
complete: "●",
incomplete: "○",
width: 20,
total: this.files().length,
callback: () => {
console.log("%cAll complete.", "color: green");
console.log(`%c本次队列文件共${this.files().length}个,已存在文件${this.existFiles}个,上传文件${this.uploadFiles}个,上传失败文件${this.errorFiles}个`, "color: green");
}
})
return this;
}
files() {
if (this._files) return this._files;
this._files = [];
/**
* 文件遍历方法
* @param filePath 需要遍历的文件路径
*/
const fileDisplay = (filePath) => {
//根据文件路径读取文件,返回文件列表
const files = fs.readdirSync(filePath);
files.forEach((filename) => {
//获取当前文件的绝对路径
const fileDir = path.join(filePath, filename);
//根据文件路径获取文件信息,返回一个fs.Stats对象
const stats = fs.statSync(fileDir);
const isFile = stats.isFile();//是文件
const isDir = stats.isDirectory();//是文件夹
if (isFile) {
this._files.push(fileDir);
} else if (isDir) {
fileDisplay(fileDir);//递归,如果是文件夹,就继续遍历该文件夹下面的文件
}
});
}
//调用文件遍历方法
fileDisplay(this.options.dir);
return this._files;
}
async start() {
const ps = this.files().map((file) => {
const relativePath = path.relative(this.options.dir, file)
.replace(path.sep, "/");
this.existFiles = 0;
this.uploadFiles = 0;
this.errorFiles = 0;
const originPath = `${this.options.originDir}${relativePath}`;
return (async () => {
let originFile = null;
originFile = await this.client.head(originPath)
.catch((error: Error) => originFile = error);
try {
if (originFile.status === 404) {
await this.client.put(originPath, file);
this.uploadFiles += 1;
} else {
this.existFiles += 1;
}
} catch (error) {
this.errorFiles += 1;
}
this.bar.tick();
})();
});
await Promise.all(ps).catch((err) => {
console.error("上传错误", err);
});
}
}
import * as fs from "node:fs";
export function findFiles(dir: string, regExp: RegExp) {
let fileArr = [];
if (fs.existsSync(dir)) {
const files = fs.readdirSync(dir);
files.forEach((file) => {
const fpath = dir + '/' + file;
const stat = fs.lstatSync(fpath);
if (stat.isFile() && regExp.test(file)) {
fileArr.push(fpath);
} else if (stat.isDirectory()) {
fileArr.push(...findFiles(fpath, regExp));
}
})
}
return fileArr;
}
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import tseslint from 'typescript-eslint'
export default tseslint.config(
{ ignores: ['dist'] },
{
extends: [js.configs.recommended, ...tseslint.configs.recommended],
files: ['**/*.{ts,tsx}'],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
plugins: {
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
},
rules: {
...reactHooks.configs.recommended.rules,
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-unused-expressions": "off",
"prefer-rest-params": "off",
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
},
},
)
<!doctype html>
<html lang="en">
<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/js-libs/rem/1.1.3/rem.min.js"></script>
<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.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}';
// 新小程序会传version=hg 旧小程序不会传
CFG.version = getUrlParam('version') || sessionStorage.getItem('version');
CFG.version && sessionStorage.setItem("version", CFG.version);
CFG.isNewMiniVersion = CFG.version == 'hg';
CFG.subUrl = (CFG.isNewMiniVersion ? `/packages/activityCenter/subscibe` : `/pagesNews/subscribeMiddlePage/subscribeNews`) +
"?source=duiba&subId=1922853657613651969&activeNo=" + CFG.projectId + "&activityUrl=" + encodeURI(location.href)
CFG.index = '/projectx/' + CFG.projectId + '/index.html?appID=' + CFG.appID;
// 免登中间页id
CFG.loginMidId = "Did1NjAwMDc"; // 线上正式
if (location.href.indexOf("duibatest") > -1) {
CFG.loginMidId = "Did1MTM2NTU"; // 测试
} else if (CFG.projectId == 'p555448e6') { // TODO 线上测试id
CFG.loginMidId = "Did1NTk5OTk"; // 线上测试
}
// 免登中间页
CFG.loginMidUrl = "/customShare/share?id=" + CFG.loginMidId + "&source=duiba&projectId=" + CFG.projectId + "&redirectUrl=";
if (!getUrlParam("appID")) {
// alert("【警告】检测到活动url中没有appID参数\n缺少该参数会导致埋点、分享、app信息获取错误。")
}
</script>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/App.tsx"></script>
</body>
</html>
\ No newline at end of file
import CryptoJS from 'crypto-js';
const { mode, pad, enc, AES } = CryptoJS;
const getOptions = (iv: string) => {
return {
iv: enc.Utf8.parse(iv),
mode: mode.CBC,
padding: pad.ZeroPadding,
};
}
/** 加密 */
export function AESEncrypt(str: string, key: string, iv: string) {
const options = getOptions(iv);
return AES.encrypt(str, enc.Utf8.parse(key), options).toString();
}
/** 解密 */
export function AESDecrypt(cipherText: string, key: string, iv: string) {
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, '');
}
export default [
{
url: "/gaw/address/getChildrenByParentCode",
response: ({ query }) => {
return {
"success": true,
"code": "0000000000",
"desc": "OK",
"timestamp": 1736580360076,
"data": [{
"name": "东华门街道",
"adCode": "110101001",
"level": 4
},
{
"name": "景山街道",
"adCode": "110101002",
"level": 4
},
{
"name": "交道口街道",
"adCode": "110101003",
"level": 4
},
{
"name": "安定门街道",
"adCode": "110101004",
"level": 4
},
{
"name": "北新桥街道",
"adCode": "110101005",
"level": 4
},
{
"name": "东四街道",
"adCode": "110101006",
"level": 4
},
{
"name": "朝阳门街道",
"adCode": "110101007",
"level": 4
},
{
"name": "建国门街道",
"adCode": "110101008",
"level": 4
},
{
"name": "东直门街道",
"adCode": "110101009",
"level": 4
},
{
"name": "和平里街道",
"adCode": "110101010",
"level": 4
},
{
"name": "前门街道",
"adCode": "110101011",
"level": 4
},
{
"name": "崇文门外街道",
"adCode": "110101012",
"level": 4
},
{
"name": "东花市街道",
"adCode": "110101013",
"level": 4
},
{
"name": "龙潭街道",
"adCode": "110101014",
"level": 4
},
{
"name": "体育馆路街道",
"adCode": "110101015",
"level": 4
},
{
"name": "天坛街道",
"adCode": "110101016",
"level": 4
},
{
"name": "永定门外街道",
"adCode": "110101017",
"level": 4
}
]
}
},
},
]
export default [
{
url: '/inviteAssist_1/getInviteCode.do',
response: ({ query }) => {
return {
"code": null,
"data": {
"dueTime": null,
"extra": null,
"inviteCode": "ZHHUJS",
"timestamp": 1746965897230
},
"message": null,
"success": true,
"timeStamp": 1746965897241
}
}
}
]
export default [
{
url: "/challenge/index.do",
method: 'get',
response: ({ query }) => {
return {
"code": "sit sint proident nostrud",
"success": true,
"message": "dolor reprehenderit ex culpa veniam",
"data": {
"choosedChallengeId": "1",
"challengeStartTime": 27404105.225178465,
"challengeEndTime": -87229323.37597737,
"boolShowFailPop": false,
"challengeSuccessPopInfo": null,
// {
// "prizeName": "30天的奖励",
// "prizeImg": "//yun.duiba.com.cn/polaris/045CCBB8-F6C7-43DB-9F81-45F52430A878.441c8f13daf61c48b85fe383e764d9089f1d4a66.png",
// },
"challengeConfigList": [
{
"challengeId": "1",
"challengeTotalDay": 30,
"prizeName": "30天的任务",
"prizeImg": "//yun.duiba.com.cn/polaris/045CCBB8-F6C7-43DB-9F81-45F52430A878.441c8f13daf61c48b85fe383e764d9089f1d4a66.png",
"resignJf": 666,
"resignQg": 666,
},
{
"challengeId": "2",
"challengeTotalDay": 60,
"prizeName": "60天的任务",
"prizeImg": "//yun.duiba.com.cn/polaris/045CCBB8-F6C7-43DB-9F81-45F52430A878.441c8f13daf61c48b85fe383e764d9089f1d4a66.png",
"resignJf": 888,
"resignQg": 888,
},
{
"challengeId": "3",
"challengeTotalDay": 90,
"prizeName": "90天的任务",
"prizeImg": "//yun.duiba.com.cn/polaris/045CCBB8-F6C7-43DB-9F81-45F52430A878.441c8f13daf61c48b85fe383e764d9089f1d4a66.png",
"resignJf": 999,
"resignQg": 999,
},
{
"challengeId": "4",
"challengeTotalDay": 120,
"prizeName": "120天的任务",
"prizeImg": "//yun.duiba.com.cn/polaris/045CCBB8-F6C7-43DB-9F81-45F52430A878.441c8f13daf61c48b85fe383e764d9089f1d4a66.png",
"resignJf": 999,
"resignQg": 999,
}
],
"hasChallengeDay": 30,
"boolNeedResign": false,
"boolNeedResignPop": false,
"taskInfoList": [
{
"code": "sign",
"icon": "//yun.duiba.com.cn/polaris/credits.55f43bd9eece2d29fd077bbad5f38ea147938c45.png",
"subTitle": "签到",
"title": "签到",
"completedSize": 1,
"intervalLimitSize": 1,
"intervalType": -18649400.705077305,
"jumpUrl": '',
"boolShowCompletePop": false,
"id": 1,
},
{
"code": "xhqg_{200}",
"icon": "//yun.duiba.com.cn/polaris/Qg.ce064174141cb66ced062f69809e43cfb4595486.png",
"subTitle": "点击确认消耗200青果",
"title": "消耗200青果",
"completedSize": 0,
"intervalLimitSize": 1,
"intervalType": 69737947.09434697,
"jumpUrl": '',
"boolShowCompletePop": false,
"id": 2,
},
{
"code": "xhjf_{300}",
"icon": "//yun.duiba.com.cn/polaris/credits.55f43bd9eece2d29fd077bbad5f38ea147938c45.png",
"subTitle": "点击确认消耗300积分",
"title": "消耗300积分",
"completedSize": 0,
"intervalLimitSize": 1,
"intervalType": 15800400.399293274,
"jumpUrl": '',
"boolShowCompletePop": false,
"id": 3,
},
{
"code": "yqzl",
"icon": "//yun.duiba.com.cn/polaris/assist.2d9c5be86de1b7ff8652c27d9df73e625d316fdb.png",
"subTitle": "邀请助力",
"title": "邀请助力",
"completedSize": 3,
"intervalLimitSize": 6,
"intervalType": -54395962.26549375,
"jumpUrl": '',
"boolShowCompletePop": false,
"id": 4,
},
{
"code": "yqzl_new",
"icon": "//yun.duiba.com.cn/polaris/sign.3976eb6cfb3124aee5a0d3c869f82398a8713928.png",
"subTitle": "邀请新用户",
"title": "邀请新用户",
"completedSize": 3,
"intervalLimitSize": 6,
"intervalType": -54395962.26549375,
"jumpUrl": '',
"boolShowCompletePop": false,
"id": 5,
},
{
"code": "scan",
"icon": "//yun.duiba.com.cn/polaris/scan.9b0733c0dae1cc733524431ec5112478e2fefba3.png",
"subTitle": "扫码",
"title": "扫码",
"completedSize": 3,
"intervalLimitSize": 6,
"intervalType": -54395962.26549375,
"jumpUrl": '',
"boolShowCompletePop": false,
"id": 6,
},
{
"code": "browse_{x}",
"icon": "//yun.duiba.com.cn/polaris/see.c249defe0f5dcd540898adbffe3fc6c7f9e7f212.png",
"subTitle": "浏览",
"title": "浏览",
"completedSize": 3,
"intervalLimitSize": 6,
"intervalType": -54395962.26549375,
"jumpUrl": 'https://www.baidu.com/index.html',
"boolShowCompletePop": false,
"id": 7,
},
],
"boolNeedChallengeCompletePop": false,
"boolOpenChallenge": true,
}
}
},
},
{
url: "/challenge/baseIndex.do",
method: 'get',
response: ({ query }) => {
return {
"code": "veniam eiusmod sunt officia in",
"success": true,
"message": "incididunt ipsum aliquip sint dolore",
"data": {
"jfNum": 3000,
"qgNum": 4000,
}
}
},
},
{
url: "/challenge/chooseChallenge.do",
method: 'get',
response: ({ query }) => {
return {
"code": "proident ullamco quis",
"success": true,
"message": "labore",
"data": {},
}
},
},
{
url: "/challenge/taskComplete.do",
method: 'get',
response: ({ query }) => {
return {
"code": "proident ullamco quis",
"success": true,
"message": "labore",
"data": {},
}
},
},
{
url: "/challenge/resign.do",
method: 'get',
response: ({ query }) => {
return {
"code": "irure ut",
"success": true,
"message": "Ut nulla cillum esse",
"data": {},
}
},
},
{
url: "/challenge/getInviterCode.do",
method: 'post',
response: ({ query }) => {
return {
"code": "sint dolor",
"success": true,
"message": "officia",
"data": {
"inviteCode": "111"
}
}
},
},
{
url: "/challenge/assist.do",
method: 'get',
response: ({ query }) => {
return {
"code": "velit in ullamco enim",
"success": false,
"message": "dolore",
"data": {},
}
},
}
]
export default [
{
url: '/credits/creditsCost.do',
method: 'post',
response: ({ query }) => {
return {
"code": null,
"data": "pca599ef9a7645cc9421c39e92ca9e28",
"message": null,
"success": true,
"timeStamp": 1742894067802
}
},
},
{
url: '/credits/queryStatus.do',
method: 'get',
response: ({ query }) => {
return {
"code": null, "data": 1, "message": null, "success": true, "timeStamp": 1742894067868
}
},
},
{
url: '/credits/creditsLogList.do',
method: 'post',
response: ({ query }) => {
return {
"success": true,
"code": "",
"message": "",
"data": {
"leftCredits": 123,
"list": [
{
"id": 222,
"cycle": "20250316",
"type": 1,
"delta": -10,
"desc": "投注红球",
"gmtCreate": 22222
},
{
"id": 111,
"cycle": "20250316",
"type": 1,
"delta": -10,
"desc": "投注红球",
"gmtCreate": 11111
},
{
"id": 222,
"cycle": "20250316",
"type": 1,
"delta": -10,
"desc": "投注红球",
"gmtCreate": 22222
},
{
"id": 111,
"cycle": "20250316",
"type": 1,
"delta": -10,
"desc": "投注红球",
"gmtCreate": 11111
},
{
"id": 222,
"cycle": "20250316",
"type": 1,
"delta": -10,
"desc": "投注红球",
"gmtCreate": 22222
},
{
"id": 111,
"cycle": "20250316",
"type": 1,
"delta": -10,
"desc": "投注红球",
"gmtCreate": 11111
},
{
"id": 222,
"cycle": "20250316",
"type": 1,
"delta": -10,
"desc": "投注红球",
"gmtCreate": 22222
},
{
"id": 111,
"cycle": "20250316",
"type": 1,
"delta": -10,
"desc": "投注红球",
"gmtCreate": 11111
},
{
"id": 222,
"cycle": "20250316",
"type": 1,
"delta": -10,
"desc": "投注红球",
"gmtCreate": 22222
},
{
"id": 111,
"cycle": "20250316",
"type": 1,
"delta": -10,
"desc": "投注红球",
"gmtCreate": 11111
},
{
"id": 222,
"cycle": "20250316",
"type": 1,
"delta": -10,
"desc": "投注红球",
"gmtCreate": 22222
},
{
"id": 123123,
"cycle": "20250316",
"type": 1,
"delta": -10,
"desc": "投注蓝球",
"gmtCreate": 11111
}
],
"haveMore": false
}
}
},
},
]
\ No newline at end of file
import { AESEncrypt } from "./Crypto";
export default [
{
url: '/projectRule.query',
method: 'get',
response: ({ query }) => {
return {
"data": "<p>以下是游戏规则:手速要快,点击红包雨。。333。。。。。。。。。。。。。。。。。。。。11111111111111sadasdadadsad5555555557777777777799999999999911111111111111111111111222222222222222222222222222222222222222222222222222222222222222333333333333333333333333333333333333333333333333333333333333311111111111111111111111111111111111111111111111111111111111111122222222222222222222222222222222222222222222222222222222222222233333333333333333333333333333333333333333333333333333333333331111111111111111111111111111111111111111111111111111111111111112222222222222222222222222222222222222222222222222222222222222223333333333333333333333333333333333333333333333333333333333333</p>",
"success": true
}
},
},
{
url: '/coop_frontVariable.query',
method: 'get',
response: ({ query }) => {
return {
"success": true,
"message": "报错了~",
"code": null,
"data": {
"privacyTxt": "privacyTxtprivacyTxtprivacyTxtprivacyTxtprivacyTxtprivacyTxtprivacyTxtprivacyTxt",
"prizeInfoAuthTxt": "prizeInfoAuthTxtprizeInfoAuthTxtprizeInfoAuthTxtprizeInfoAuthTxtprizeInfoAuthTxtprizeInfoAuthTxtprizeInfoAuthTxtprizeInfoAuthTxt",
"test_config_02": "111",
// 规则长图
"ruleImg": '//yun.duiba.com.cn/polaris/bg.18539c61e0103e01a339dd268558b2559ab178ba.png',
shareInfo: [
{
"title": 'normal',
"desc": '2025年“3·15”金融消费者权益保护教育宣传活动',
"imgUrl": '//yun.duiba.com.cn/polaris/image.42930d3760a71de0c9b80cb7481767718dca11d3.png'
},
{
"title": 'invite',
"desc": '2025年“3·15”金融消费者权益保护教育宣传活动',
"imgUrl": '//yun.duiba.com.cn/polaris/image%20(1).aba678324b060ee2050bbdaf83c05c8ddb3a3dd2.png'
}
],
shopUrl: 'https://'
}
}
},
},
{
url: '/join.do',
response: ({ query }) => {
return {
"code": "code",
"success": true,
"message": "message",
"timeStamp": Date.now(),
"data": AESEncrypt(JSON.stringify({
"startId": "officia",
"countDown": 30
}), "1696BD3E5BB915A0", "cDOiBC1n2QrkAY2P"),
}
},
},
{
url: '/common/records.do',
response: ({ query }) => {
return {
"code": "code",
"success": true,
"message": "message",
"timeStamp": Date.now(),
"data": [
{
"extra": {
"name": "优惠券-大转盘02优惠券-大转盘02优惠券-大转盘02",
"icon": "//yun.dui88.com/images/201907/tua0um9jjp.jpg",
"refType": "coupon",
"refId": "49354",
"type": 2
},
"strategyId": 11,
"gmtCreate": 1565213353000,
"id": 331,
"prizeId": "g4c4c3edd",
"type": 4,
"moneyStatus": 1,
"moneyCanReissueStartTimestamp": 1565213353000,
"moneyCanReissueEndTimestamp": 1565213353000,
},
{
"extra": {
"name": "优惠券-大转盘03",
"icon": "//yun.duiba.com.cn/polaris/%E6%95%B0%E6%8D%AE%E5%86%B3%E7%AD%96%E5%B7%A5%E5%85%B7.531c2dae250ab379fd6216eb038e60bc12ab9dd6.png",
"refType": "coupon",
"refId": "49354",
"type": 2
},
"strategyId": 11,
"gmtCreate": 1565213116000,
"id": 330,
"prizeId": "g0e432eeb",
"type": 4,
"moneyStatus": 10,
"moneyCanReissueStartTimestamp": 1565213353000,
"moneyCanReissueEndTimestamp": 1565213353000,
},
{
"extra": {
"name": "优惠券-大转盘05",
"icon": "//yun.dui88.com/images/201907/tua0um9jjp.jpg",
"refType": "coupon",
"refId": "49354",
"type": 2
},
"strategyId": 11,
"gmtCreate": 1565212826000,
"id": 329,
"prizeId": "g900c8442",
"type": 4,
"moneyStatus": 11,
"moneyCanReissueStartTimestamp": 1565213353000,
"moneyCanReissueEndTimestamp": 1565213353000,
},
{
"extra": {
"name": "优惠券-大转盘01",
"icon": "//yun.dui88.com/images/201907/tua0um9jjp.jpg",
"refType": "coupon",
"refId": "49354",
"type": 2
},
"gmtCreate": 1565205625000,
"id": 328,
"strategyId": 11,
"prizeId": "g4c7ba888",
"type": 4,
"moneyStatus": 2,
"moneyCanReissueStartTimestamp": 1565213353000,
"moneyCanReissueEndTimestamp": 1565213353000,
},
{
"extra": {
"name": "优惠券-大转盘05",
"icon": "//yun.dui88.com/images/201907/tua0um9jjp.jpg",
"refType": "coupon",
"refId": "49354",
"type": 2
},
"strategyId": 11,
"gmtCreate": 1565203101000,
"id": 327,
"prizeId": "g900c8442",
"type": 1,
"moneyStatus": 1,
"moneyCanReissueStartTimestamp": 1565213353000,
"moneyCanReissueEndTimestamp": 1565213353000,
},
{
"extra": {
"name": "优惠券-大转盘03",
"icon": "//yun.dui88.com/images/201907/tua0um9jjp.jpg",
"refType": "coupon",
"refId": "49354",
"type": 2
},
"strategyId": 11,
"gmtCreate": 1565203040000,
"id": 326,
"prizeId": "g0e432eeb",
"type": 1,
"moneyStatus": 1,
"moneyCanReissueStartTimestamp": 1565213353000,
"moneyCanReissueEndTimestamp": 1565213353000,
},
{
"extra": {
"name": "优惠券-大转盘04",
"icon": "//yun.dui88.com/images/201907/tua0um9jjp.jpg",
"refType": "coupon",
"refId": "49354",
"type": 2
},
"gmtCreate": 1565197386000,
"id": 325,
"prizeId": "gc1a8c03c"
},
{
"extra": {
"name": "last",
"icon": "//yun.dui88.com/images/201907/tua0um9jjp.jpg",
"refType": "coupon",
"refId": "49354",
"type": 2
},
"gmtCreate": 1565197080000,
"id": 324,
"strategyId": 11,
"prizeId": "g0e432eeb",
"type": 1,
"moneyStatus": 1,
"moneyCanReissueStartTimestamp": 1565213353000,
"moneyCanReissueEndTimestamp": 1565213353000,
},
],
}
},
},
{
url: '/common/moneyReissue.do',
response: ({ query }) => {
return {
"code": "code",
"success": true,
"message": "message",
"timeStamp": Date.now(),
"data": {}
}
},
},
{
url: "/customActivity/kouweiwang/prize/queryOrderNo",
method: 'get',
response: ({ query }) => {
return {
"success": true,
"message": "报错了~",
"code": null,
"data": {
"recordId": 1,
"projectId": 1,
"orderNo": 1234567890,
"activityId": 1,
"uid": 1,
},
}
}
},
]
export default [
{
url: '/main/index.do',
response: ({ query }) => {
const signDay = Math.random() * 7 >> 0;
return {
success: true,
code: "",
message: "",
timeStamp: Date.now(),
data: {
actStartTime: Date.now() - 1000000,
actEndTime: Date.now() + 1000000,
currentTime: Date.now(),
guideFlag: true,
creditsNum: 923,
expireDays: 7,
currentStoreNum: 1000,
storeLimitNum: 1000,
continueSignDays: 3,
todaySignFlag: false,
signRecords: new Array(7).fill(1).map((_, index) => {
return {
id: index,
day: index + 1,
creditsNum: 100 + Math.random() * 100 >> 0,
boolSign: index < signDay,
}
}),
overflowBubble: {
creditsNum: 700,
expireTime: 1746669495352,
id: 218090705,
},
bubbleRecords: new Array(1 + (Math.random() * 4 >> 0)).fill(1).map((_, index) => {
return {
id: index,
creditsNum: 100 + Math.random() * 100 >> 0,
expireTime: Date.now() + 10000 + (Math.random() * 10 >> 0) * 1000,
type: 1 + Math.random() * 2 >> 0,
}
}),
returnAwardCreditsNum: 0,
downGoldVo: {
creditsNum: 100,
multipleValue: 5,
taskId: "5555555",
url: "urlurlurlurlurlurl",
},
downGoldVo: null,
}
}
},
},
{
url: '/main/completeGuide.do',
response: ({ query }) => {
return {
success: true,
code: "",
message: "",
data: {
creditsNum: 100,
},
}
},
},
{
url: '/main/sign.do',
response: ({ query }) => {
return {
success: true,
code: "",
message: "",
data: {
signCredits: 100,
extraCredits: 100,
boolLimit: true,
multipleValue: 3,
url: "urlurlurlurlurl",
taskId: "taskId",
newLuckCreditsNum: 33,
},
}
},
},
{
url: '/main/receiveBubble.do',
response: ({ query }) => {
return {
success: true,
code: "",
message: "",
data: {
creditNum: 888,
}
}
},
},
{
url: '/main/startVideo.do',
response: ({ query }) => {
return {
success: true,
code: "",
message: "",
data: {
creditNum: 888,
}
}
},
},
]
export default [
{
url: '/log/click',
method: 'get',
response: 1,
},
{
url: '/exposure/standard',
method: 'get',
response: 1,
},
]
This diff is collapsed.
export default [
{
url: '/wechatShare/getShareInfo/v2',
method: 'get',
response: 1,
},
]
{
"name": "grace-templete",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"preinstall": "npx only-allow pnpm",
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview"
},
"dependencies": {
"@csstools/normalize.css": "^12.1.1",
"@grace/built-in": "*",
"@grace/svgaplayer": "*",
"@grace/ui": "*",
"@pixi/devtools": "^2.0.1",
"@pixi/ui": "^2.2.3",
"@spark/dbdomain": "^1.0.25",
"@spark/share": "^2.0.340",
"@tailwindcss/postcss": "^4.0.6",
"@types/qrcode": "^1.5.5",
"axios": "^1.9.0",
"chalk": "^5.3.0",
"classnames": "^2.5.1",
"crypto-js": "^4.2.0",
"cssnano": "^7.0.6",
"detect-collisions": "^9.26.4",
"duiba-utils": "^2.0.2",
"emittery": "^1.1.0",
"gsap": "^3.12.7",
"howler": "^2.2.4",
"html2canvas": "^1.4.1",
"intersection-observer": "^0.12.2",
"less": "^4.3.0",
"mobx": "^6.13.7",
"mobx-react": "^9.2.0",
"pixi-stats": "^4.1.2",
"pixi.js": "^8.9.1",
"postcss": "^8.5.3",
"progress": "^2.0.3",
"protobufjs": "^7.5.0",
"qrcode": "^1.5.4",
"qs": "^6.14.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"spark-utils": "^1.1.2",
"swiper": "8.4.5",
"tailwindcss": "^4.1.4"
},
"devDependencies": {
"@assetpack/core": "^1.4.0",
"@babel/plugin-proposal-class-properties": "^7.18.6",
"@babel/plugin-proposal-decorators": "^7.24.7",
"@eslint/js": "^9.9.0",
"@types/ali-oss": "^6.16.11",
"@types/crypto-js": "^4.2.2",
"@types/howler": "^2.2.12",
"@types/pako": "^2.0.3",
"@types/postcss-pxtorem": "^6.0.3",
"@types/progress": "^2.0.7",
"@types/qs": "^6.9.16",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@vitejs/plugin-legacy": "^5.4.2",
"@vitejs/plugin-react": "^4.3.1",
"ali-oss": "^6.21.0",
"autoprefixer": "^10.4.20",
"dotenv": "^16.4.5",
"eslint": "^9.9.0",
"eslint-plugin-react-hooks": "^5.1.0-rc.0",
"eslint-plugin-react-refresh": "^0.4.9",
"globals": "^15.9.0",
"mockjs": "^1.1.0",
"pako": "^2.1.0",
"postcss-pxtorem": "^6.1.0",
"terser": "^5.36.0",
"typescript": "5.5.4",
"typescript-eslint": "^8.0.1",
"vite": "^6.3.3",
"vite-plugin-mock": "^3.0.2"
}
}
This diff is collapsed.
{"proSetting":{"projectxIDs":{"testId":[{"label":"test","value":"pd71a2911"},{"label":"test2","value":"p960d47b7"}],"prodId":[{"label":"线上测试","value":"p69bb35bf"}]},"skinVariables":[],"mockSetting":{"projectId":"","pageId":""}},"envSetting":{},"psdSetting":{"psdFSSetting":true,"psdCenterSetting":true}}
{"proName":"未命名项目","proDesc":"","proPath":"D:\\Duiba\\口味王\\天天领积分\\kww_dayDayGetCredits_250512","createTime":1729847802806}
import React, {Component} from 'react'
import {observer} from "mobx-react";
import {createRoot} from "react-dom/client";
import store from "./store/store";
import "./core/checkwebp.ts";
import "./MD";
import './App.less'
import '@csstools/normalize.css';
import musicStore from "@/store/musicStore.ts";
import {initWx} from "@/built-in/share/weixin/weixin.ts";
import { ModalCtrl } from "@/core/ctrls/ModalCtrl.tsx";
import { PageCtrl } from "@/core/ctrls/PageCtrl.tsx";
import { GetCurrSkinId, getCustomShareId } from "@/utils/utils.ts";
import HomePage from "@/pages/HomePage/HomePage.tsx";
import MyPrize from "@/pages/MyPrize/MyPrize.tsx";
import LoadingDemo from "@/pages/LoadingDemo/LoadingDemo.tsx";
import { loadFont } from "@/core/preload.ts";
import zzgfyht from "@/assets/font/zzgfyht.ttf";
@observer
class App extends Component {
showDefaultPage = () => {
const skinId = GetCurrSkinId() || getCustomShareId();
const defaultPage = {
myPrize: MyPrize, // TODO 举例子 新宿台奖品页
index: LoadingDemo,
}[skinId] || LoadingDemo;
PageCtrl.changePage(defaultPage);
}
async componentDidMount() {
this.showDefaultPage();
await store.getFrontVariable();
store.initShare()
}
componentWillUnmount() {
}
render() {
return <>
<PageCtrl/>
<ModalCtrl/>
</>;
}
}
const root = createRoot(document.getElementById('root')!);
root.render(
<App/>
);
export function isWeiXin() {
return /micromessenger/i.test(navigator.userAgent.toLowerCase());
}
/**
* 判断是否为ios系统
*/
export function isIos() {
return navigator.userAgent.match(/iphone|ipod|ipad/gi)
}
import { logClick, logExposure, MDAuto } from "@grace/built-in";
import { IAutoMdData } from "@grace/built-in";
import {getUrlParam} from "@/utils/utils.ts";
const appId = CFG.appID;
const dcm = "202." + CFG.projectId + ".0.0";
const domain = "";
const channel = getUrlParam("channel");
const dom = `${channel}.0.0.0`;
const MDList: IAutoMdData[] = new Array(20).fill("").map((_, i) => {
return {
ele: `.md${i + 1}`,
data: {
dpm: `${appId}.110.${i + 1}.1`,
dcm,
dom,
domain,
appId,
},
once: false,
};
});
MDList.push({
ele: ".md10_0",
data: {
dpm: `${appId}.110.10.0`,
dcm,
dom,
domain,
appId,
},
once: true,
});
MDList.push({
ele: ".md10_1",
data: {
dpm: `${appId}.110.10.1`,
dcm,
dom,
domain,
appId,
},
once: true,
});
MDAuto({
show: MDList, // 曝光
click: MDList, // 点击
});
export function handleLogExposure(id: number | string, id2: number | string = 1) {
logExposure({
dpm: `${appId}.110.${id}.${id2}`,
dcm,
domain,
appId,
});
}
export function handleLogClick(id: number | string, id2: number | string = 1) {
logClick({
dpm: `${appId}.110.${id}.${id2}`,
dcm,
domain,
appId,
});
}
import { generateAPI } from "./utils"
const API = generateAPI({
/** 获取活动规则 */
getRule: 'projectRule.query',
/** 获取前端配置项 */
getFrontVariable: 'coop_frontVariable.query',
// getShareInfo: '/wechatShare/getShareInfo/v2',
getShareInfo: '/wechatMiniApp/ticket/info',
/** 签到 */
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,
},
// 奖品记录
records: "common/records.do",
// 红包补领
redpacket: "common/moneyReissue.do",
getInviteCode: {
uri: 'inviteAssist_1/getInviteCode.do',
withToken: true,
method: 'post',
},
doAssist: {
uri: 'inviteAssist_1/doAssist.do',
withToken: true,
method: 'post',
showMsg: false,
},
/** 获取地区 */
getParentCode: "/gaw/address/getChildrenByParentCode",
// 挑战-首页
getChallengeIndex: "challenge/index.do",
//挑战-基础首页
getChallengeBaseIndex: "challenge/baseIndex.do",
// 挑战-补签
getChallengeResign: "challenge/resign.do",
// 挑战-任务完成接口
getChallenegeComplete: "challenge/taskComplete.do",
//挑战-获取邀请码
getChallengeInviteCode: "challenge/inviteCode.do",
// 挑战-助力
getChallengeAssist: {
uri: "challenge/assist.do",
showMsg: false,
},
// 挑战-选择挑战
getChooseChallenge: "challenge/chooseChallenge.do",
// 扣积分
queryStatus: "credits/queryStatus.do",
creditsCost: {
uri: "credits/creditsCost.do",
method: "post"
},
// 奖品
queryOrder: "customActivity/kouweiwang/prize/queryOrderNo",
index: "main/index.do",
completeGuide: "main/completeGuide.do",
sign: "main/sign.do",
receiveBubble: "main/receiveBubble.do",
startVideo: "main/startVideo.do",
})
// console.log('======', API)
export default API
import {isFromShare, newUser} from '@/built-in/duiba-utils';
import {errorHandler} from "@/utils/errorHandler.js";
import {getPxToken} from "@/built-in/getPxToken.js";
import {Axios, AxiosRequestConfig} from 'axios';
import qs from "qs";
import {getUrlParam} from "@/utils/utils.ts";
interface IRes {
uid: any;
activityId: any;
orderNo: any;
success: boolean;
data: any;
msg?: string;
message?: string;
code?: number | string;
timeStamp?: number;
timestamp?: number;
}
const mergeData = {
user_type: newUser ? '0' : '1',
is_from_share: isFromShare ? '0' : '1',
from: getUrlParam("channel"),
}
// let tempCookieId = "";
//
// export function setCookieId(cookieId) {
// tempCookieId = cookieId;
// }
export function resetBackCookie(duibaTempCookieId) {
return new Promise((resolve) => {
apiAxios.request({
url: "/autoLogin/resetCookie",
params: {
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,
headers, withToken,
} = value;
return {uri, method, headers, withToken, showMsg};
} else {
console.error('getRequestParams: 传参有误');
}
}
const apiAxios = new Axios({
timeout: 10000,
});
apiAxios.interceptors.response.use(
async (resp) => {
try {
return JSON.parse(resp.data);
} catch (e) {
return {success: false};
}
},
async (error) => {
console.error(error);
return {success: false};
}
);
export interface IApiCfg {
uri: string,
method?: "get" | "post" | "GET" | "POST",
showMsg?: boolean,
withToken?: boolean,
headers?: any,
}
export interface IApiList {
[key: string]: string | IApiCfg;
}
/**
* 请求API通用处理
* @returns
* @param apiList
*/
export function generateAPI<T>(apiList: T): { [key in keyof T]: (params?, headers?) => Promise<IRes> } {
const api = {} as { [key in keyof T]: (params?, headers?) => Promise<IRes> };
for (const key in apiList) {
// @ts-ignore
let value: IApiCfg = apiList[key];
if (typeof value === 'string') {
value = {
uri: value,
method: 'get'
} as IApiCfg;
}
const {
method = 'get',
uri,
headers: mHeaders,
withToken,
showMsg = true
} = value;
api[key] = async (params: any = {}, headers: any = {}) => {
const isPost = method.toLowerCase() === 'post';
// 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);
// }
// }
if (withToken) { // 是否携带token
params.token = await getPxToken()
.catch(() => {
// Toast('网络异常,请稍后再试~');
return "";
});
}
const mergedHeaders = {...mHeaders, ...headers}
params = {...params, ...mergeData};
const config: AxiosRequestConfig = {
method,
url: uri,
headers: mergedHeaders,
}
if (isPost) {
config.data = qs.stringify(params);
} else {
config.params = params;
}
const res: IRes = await apiAxios.request(config);
if (!res.success && showMsg) {
errorHandler(res);
}
return res;
}
}
return api;
}
@import "./res.less";
//@import "tailwindcss";
* {
margin: 0;
padding: 0;
}
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;
}
#app {
width: 100%;
height: 100%;
position: relative;
overflow: hidden;
}
.com_banner {
position: fixed;
left: 35px;
bottom: 54px;
width: 684px;
height: 150px;
.webpBg("common/banner.png");
}
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.
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.
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.
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