Commit ca1b3adc authored by haiyoucuv's avatar haiyoucuv

net

parent 23388ad9
......@@ -10,6 +10,10 @@
"lint": "eslint .",
"preview": "vite preview"
},
"files": [
"dist",
"README.md"
],
"main": "dist/index.cjs",
"module": "dist/index.js",
"types": "dist/index.d.ts",
......
......@@ -10,6 +10,10 @@
"lint": "eslint .",
"preview": "vite preview"
},
"files": [
"dist",
"README.md"
],
"main": "dist/index.cjs",
"module": "dist/index.js",
"types": "dist/index.d.ts",
......
......@@ -9,7 +9,7 @@ type MergedHTMLAttributes = Omit<
'onPause'
>;
export type HTMLDisplayElement = HTMLImageElement | HTMLCanvasElement | ImageBitmap;
export type DisplayElement = HTMLImageElement | HTMLCanvasElement | ImageBitmap;
export interface SvgaPlayerRef {
nativeElement: HTMLCanvasElement;
......@@ -18,8 +18,8 @@ export interface SvgaPlayerRef {
pause: () => Player;
resume: () => Player;
stop: () => Player;
replaceImage: (name: string, img: string | HTMLDisplayElement) => Promise<HTMLDisplayElement>;
addImage: (parentName: string, targetName: string, img: string | HTMLDisplayElement, width?: number, height?: number) => void;
replaceImage: (name: string, img: string | DisplayElement) => Promise<DisplayElement>;
addImage: (parentName: string, targetName: string, img: string | DisplayElement, width?: number, height?: number) => void;
removeImage: (targetName: string) => void;
}
......@@ -84,7 +84,7 @@ export const SvgaPlayer = forwardRef<
playInfo.current.player.stop();
return playInfo.current.player;
},
async replaceImage(name: string, img: string | HTMLDisplayElement): Promise<HTMLDisplayElement> {
async replaceImage(name: string, img: string | DisplayElement): Promise<DisplayElement> {
const player = playInfo.current.player;
if (playInfo.current.player && playInfo.current.player.videoEntity) {
if (typeof img === 'string') {
......@@ -95,7 +95,7 @@ export const SvgaPlayer = forwardRef<
return img;
}
},
async addImage(parentName: string, targetName: string, img: string | HTMLDisplayElement, width?: number, height?: number) {
async addImage(parentName: string, targetName: string, img: string | DisplayElement, width?: number, height?: number) {
const player = playInfo.current.player;
if (player && player.videoEntity) {
let videoItem = player.videoEntity
......
......@@ -10,10 +10,18 @@
"lint": "eslint .",
"preview": "vite preview"
},
"files": [
"dist",
"README.md"
],
"main": "dist/index.cjs",
"module": "dist/index.js",
"types": "dist/index.d.ts",
"dependencies": {
"svga": "^2.1.1"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
}
import React, { HTMLAttributes, CSSProperties, MouseEventHandler, ReactElement, useState } from "react";
export interface IBaseButtonProps {
className?: string;
}
import React, { HTMLAttributes, ReactElement, useState } from "react";
type MergedHTMLAttributes = Omit<
......@@ -11,8 +6,9 @@ type MergedHTMLAttributes = Omit<
'onPause'
>;
interface IButtonProps extends IBaseButtonProps, MergedHTMLAttributes {
interface IButtonProps extends MergedHTMLAttributes {
anchorX?: "center" | "left" | "right";
anchorY?: "center" | "top" | "bottom";
}
......@@ -26,31 +22,40 @@ export const Button = (props: IButtonProps): ReactElement => {
const {
children,
className,
onClick = () => void 0,
style = {}
style,
onTouchStart,
onTouchEnd,
onTouchCancel,
anchorX = "center",
anchorY = "center",
} = props;
const [scale, setScale] = useState("unset");
const onTouchStart = () => {
setScale("scale(0.9,0.9)");
const touchStart = (e: React.TouchEvent<HTMLDivElement>) => {
onTouchStart && onTouchStart(e);
setScale("scale(0.92, 0.92)");
};
const onTouchEnd = () => {
const touchEnd = (e: React.TouchEvent<HTMLDivElement>) => {
onTouchEnd && onTouchEnd(e);
setScale("unset");
};
const onTouchCancel = onTouchEnd;
const touchCancel = (e: React.TouchEvent<HTMLDivElement>) => {
onTouchCancel && onTouchCancel(e);
setScale("unset");
}
return <div
className={className}
onTouchStart={onTouchStart}
onTouchEnd={onTouchEnd}
onTouchCancel={onTouchCancel}
onClick={onClick}
onTouchStart={touchStart}
onTouchEnd={touchEnd}
onTouchCancel={touchCancel}
style={{
transitionDuration: "0.5s",
transitionDuration: "50ms",
transform: scale,
transformOrigin: `${anchorX} ${anchorY}`,
...style,
}}
>
......
export * from "./components/Button";
......@@ -31,7 +31,7 @@ export default defineConfig(({ mode }): UserConfig => {
},
plugins: [
react(),
dts({ rollupTypes: true, tsconfigPath: './tsconfig.app.json' })
dts({ tsconfigPath: './tsconfig.app.json' })
],
css: {
preprocessorOptions: {
......
# React + TypeScript + Vite
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
Currently, two official plugins are available:
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
## Expanding the ESLint configuration
If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:
- Configure the top-level `parserOptions` property like this:
```js
export default tseslint.config({
languageOptions: {
// other options...
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
},
})
```
- Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked`
- Optionally add `...tseslint.configs.stylisticTypeChecked`
- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config:
```js
// eslint.config.js
import react from 'eslint-plugin-react'
export default tseslint.config({
// Set the react version
settings: { react: { version: '18.3' } },
plugins: {
// Add the react plugin
react,
},
rules: {
// other rules...
// Enable its recommended rules
...react.configs.recommended.rules,
...react.configs['jsx-runtime'].rules,
},
})
```
export default [
{
url: '/game/index.do',
response: ({ query }) => {
console.log(query)
return {
"success": true,
"code": "",
"message": "",
"data": {
"actStartTimestamp": 1704038400000,
"actEndTimestamp": 1735660799000,
"currentTimestamp": 1712647160069,
"homeSubtitle": "副标题副标题副标题",
"leftCredits": 1234,
"currentVipLevel": 3,
"currentVipLevelWeeklySecKillLimit": 2,
"currentWeekLeftSecKillChance": 1,
"currentWeekSecKillBeLimited": false,
"vipLevelWeeklySecKillLimitConfigList": [
{
"vipLevel": 1,
"limit": 1
},
{
"vipLevel": 2,
"limit": 1
},
{
"vipLevel": 3,
"limit": 2
},
{
"vipLevel": 4,
"limit": 3
},
{
"vipLevel": 5,
"limit": 4
}
],
"dailySecKillLimit": 1,
"todaySecKillBeLimited": true,
"leftPeriod": {
"period": 1,
"startTimestamp": 111,
"endTimestamp": 222
},
"middlePeriod": {
"period": 2,
"startTimestamp": 333,
"endTimestamp": 444,
"secKillInfoList": [
{
"ruleId": "ru_4",
"optionId": "bbbbaaaa",
"optionName": "50元微信立减金",
"optionImg": "https://www.baidu.com/ljj_50.png",
"prizeUseRuleTitle": "满800元可用",
"prizeUseRuleDesc": "收到了附件撒冷风机撒都发了",
"totalStock": 20,
"leftStock": 15,
"minLevel": null,
"costCredits": 800,
"strikeCredits": 1200,
"todayCurrentPeriodSecKillFlag": false
},
{
"ruleId": "ru_5",
"optionId": "bbbbbbbb",
"optionName": "100元微信立减金",
"optionImg": "https://www.baidu.com/ljj_100.png",
"prizeUseRuleTitle": "满1000元可用",
"prizeUseRuleDesc": "收到绝对是撒旦法拉水电费",
"totalStock": 10,
"leftStock": 3,
"minLevel": 3,
"costCredits": 1000,
"strikeCredits": 1800,
"todayCurrentPeriodSecKillFlag": true
}
]
},
"rightPeriod": {
"period": 1,
"startTimestamp": 555,
"endTimestamp": 666
},
"dailyExchangeLimit": 1,
"todayExchangeBeLimited": true,
"exchangeInfoList": [
{
"ruleId": "ru_6",
"optionId": "ccccaaaa",
"optionName": "10元话费",
"optionImg": "https://www.baidu.com/hf_10.png",
"totalStock": 10,
"leftStock": 3,
"minLevel": null,
"costCredits": 100,
"todayExchangeFlag": false
},
{
"ruleId": "ru_7",
"optionId": "ccccbbbb",
"optionName": "20元话费",
"optionImg": "https://www.baidu.com/hf_20.png",
"totalStock": 5,
"leftStock": 1,
"minLevel": null,
"costCredits": 200,
"todayExchangeFlag": true
},
{
"ruleId": "ru_8",
"optionId": "cccccccc",
"optionName": "50元话费",
"optionImg": "https://www.baidu.com/hf_50.png",
"totalStock": 3,
"leftStock": 0,
"minLevel": 4,
"costCredits": 250,
"todayExchangeFlag": false
}
]
}
}
},
}
]
......@@ -28,8 +28,7 @@ export default [
},
},
{
url: '/spring/start.do',
method: 'get',
url: '/join.do',
response: ({query}) => {
return {
"code": "code",
......
{
"name": "@grace/playground",
"name": "@grace/template",
"private": true,
"version": "0.0.1",
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
......@@ -14,7 +14,6 @@
"@grace/built-in": "workspace:^",
"@grace/svgaplayer": "workspace:^",
"@grace/ui": "workspace:^",
"@types/node": "^22.7.6",
"axios": "^1.7.7",
"chalk": "^5.3.0",
"crypto-js": "^4.2.0",
......@@ -24,6 +23,7 @@
"mobx": "^6.13.1",
"mobx-react": "^9.1.1",
"progress": "^2.0.3",
"qs": "^6.13.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"spark-utils": "^1.1.2"
......@@ -36,6 +36,7 @@
"@types/crypto-js": "^4.2.2",
"@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",
......
......@@ -5,7 +5,8 @@ import store from "./store/store";
import "./utils/checkwebp";
import MD from "./MD"; // 埋点
import "./MD";
import { PAGE_MAP } from "./utils/constants";
import LoadingDemo from "./pages/LoadingDemo/LoadingDemo";
import HomeDemo from "./pages/HomeDemo/HomeDemo";
......@@ -15,8 +16,6 @@ import './App.less'
import '@csstools/normalize.css';
import API from "./api";
MD();
const pageMap = {
[PAGE_MAP.LOADING_PAGE]: <LoadingDemo />,
......@@ -29,7 +28,7 @@ class App extends Component {
async componentDidMount() {
await store.getFrontVariable();
store.initRule();
API.doJoin();
API.index({aaaa: "啊实打实"});
}
render() {
......
import { logClick, logExposure, MDAuto } from "@grace/built-in";
import { IAutoMdData } from "@grace/built-in/src";
const appId = CFG.appID;
const dcm = "202." + CFG.projectId + ".0.0";
const domain = "https://embedlog.duiba.com.cn";
const MDList = new Array(2).fill("").map((v, i) => {
const MDList: IAutoMdData[] = new Array(10).fill("").map((_, i) => {
return {
ele: `.md${i + 1}`,
data: {
......@@ -16,13 +17,12 @@ const MDList = new Array(2).fill("").map((v, i) => {
};
});
export default () =>
MDAuto({
MDAuto({
show: MDList, // 曝光
click: MDList, // 点击
});
});
export function handleLogExposure(id, id2 = 0) {
export function handleLogExposure(id: number | string, id2: number | string = 0) {
logExposure({
dpm: `${appId}.110.${id}.${id2}`,
dcm,
......@@ -31,7 +31,7 @@ export function handleLogExposure(id, id2 = 0) {
});
}
export function handleLogClick(id, id2 = 0) {
export function handleLogClick(id: number | string, id2: number | string = 0) {
logClick({
dpm: `${appId}.110.${id}.${id2}`,
dcm,
......
......@@ -5,11 +5,6 @@ const API = generateAPI({
getRule: 'projectRule.query',
/** 获取前端配置项 */
getFrontVariable: 'coop_frontVariable.query',
/** 参与接口 post请求 */
doJoin: {
uri: 'join.do',
method: "post"
},
/** 签到 */
doSign: {
uri: 'checkin_1/doSign.do',
......@@ -27,9 +22,10 @@ const API = generateAPI({
uri: "userLogin.check",
showMsg: false,
},
buriedPoint: {
uri: "home/buriedPoint.do",
showMsg: false,
index: {
method: 'post',
uri: "game/index.do",
},
})
......
......@@ -7,6 +7,8 @@ import { getPxToken } from "@/built-in/getPxToken.js";
import { Axios } from 'axios';
import qs from "qs";
interface IRes {
success: boolean;
data: any;
......@@ -30,7 +32,7 @@ export function resetBackCookie(duibaTempCookieId) {
return new Promise((resolve) => {
apiAxios.request({
url: "/autoLogin/resetCookie",
data: {
params: {
duibaTempCookieId
}
}).then((resp) => {
......@@ -48,25 +50,15 @@ export function resetBackCookie(duibaTempCookieId) {
*/
function getRequestParams(value) {
if (typeof value === 'string') {
return {
uri: value,
method: 'get'
}
return { uri: value, method: 'get' };
} else if (typeof value === 'object') {
const {
uri,
method = 'get',
showMsg = true,
headers,
withToken,
headers, withToken,
} = value;
return {
uri,
method,
headers,
withToken,
showMsg
}
return { uri, method, headers, withToken, showMsg };
} else {
console.error('getRequestParams: 传参有误');
}
......@@ -122,6 +114,8 @@ export function generateAPI(apiList): { [key in string]: (params?, headers?) =>
api[key] = async (params: any = {}, headers: any = {}) => {
const isPost = method.toLowerCase() === 'post';
// cookie丢失的问题
// 如遇跳转Cookie丢失,打开如下代码
// const duibaTempCookieId = localStorage.getItem("db_temp_cookie");
......@@ -156,7 +150,8 @@ export function generateAPI(apiList): { [key in string]: (params?, headers?) =>
method,
url: uri,
headers: mergedHeaders,
data: params,
params: (!isPost) && qs.stringify(params),
data: isPost && qs.stringify(params),
});
if (res) {
......
/**
* Created by rockyl on 2019-12-10.
*/
export const queryParams: any = {};
let search = window.location.search;
......@@ -16,7 +12,7 @@ for (const item of search.replace('?', '').split('&')) {
export function windowVisibility(callback?: (visible: boolean) => void) {
//设置隐藏属性和改变可见属性的事件的名称
let visibilityChange;
let visibilityChange: string;
if (typeof document.hidden !== 'undefined') {
visibilityChange = 'visibilitychange';
} else if (typeof document['msHidden'] !== 'undefined') {
......
/**
* Created by rockyl on 2020/11/30.
*/
declare const CFG: any;
/**
* Created by rockyl on 2020/9/21.
*/
export * from './net'
export * from './browser'
export * from './utils'
export * from './init'
/**
* Created by rockyl on 2020/9/21.
*/
import {queryParams, windowVisibility,} from "./browser";
import {accessLog} from "./utils";
import { queryParams, windowVisibility, } from "./browser";
import { accessLog } from "./utils";
export let appID: string, channelType: string, projectID: string, isFromShare: boolean, newUser: boolean = true;
//appID提取
if (queryParams.appID) {
appID = queryParams.appID;
}else if (CFG.appID) {
} else if (CFG.appID) {
appID = CFG.appID;
}
......@@ -66,7 +62,7 @@ if (window['isSharePage']) {
function dealPageRemainTime() {
let startTimer = new Date().getTime();
let endTimer;
let endTimer: number;
windowVisibility((visibility) => {
if (visibility) {
......
/**
* Created by rockyl on 2019-11-22.
*/
import { injectProp, obj2query } from "./utils";
/**
* http请求
* @param url
* @param method
* @param params
* @param type
* @param headers
*/
export function httpRequest(url: string, method: string = 'get', params?: any, type: 'text' | 'json' | 'jsonp' = 'text', headers?) {
let openUrl = url.indexOf('blob') === 0 ? url : urlJoin(url, '__ts__=' + Date.now());
let mParams = {};
injectProp(mParams, params);
return new Promise((resolve, reject) => {
let mHeaders = {
'Content-Type': 'application/x-www-form-urlencoded',
};
injectProp(mHeaders, headers);
let request = { url, method, params: mParams, type, headers: mHeaders };
const mock = window['mock'];
let mockRule;
if (mock) {
mock(request, (rule) => {
mockRule = rule;
if (!mockRule) {
doRequest(request, resolve, reject);
}
}, resolve, reject);
} else {
request.url = openUrl;
doRequest(request, resolve, reject);
}
});
}
function doProxyRequest(payload, resolve, reject) {
let proxyWindow = window['proxy_window'];
window.addEventListener('message', onMessage, false);
proxyWindow.postMessage(JSON.stringify({
action: 'http-request-proxy',
payload: payload,
}), '*');
function onMessage(event) {
window.removeEventListener('message', onMessage);
try {
let data = JSON.parse(event.data);
console.log('onMessage', event.data);
switch (data.action) {
case 'http-request-proxy-resolve':
resolve(data.payload);
break;
case 'http-request-proxy-reject':
reject(data.payload);
break;
}
} catch (e) {
}
}
}
function doXhrRequest({ url, method, params, type, headers }, resolve, reject) {
let xhr;
if (window["XMLHttpRequest"]) {
xhr = new XMLHttpRequest();
} else if (window["ActiveXObject"]) {
xhr = new window["ActiveXObject"]();
} else {
console.log('no xhr');
}
if (xhr != null) {
const isGet = method.toUpperCase() === 'GET';
const queryStr = obj2query(params);
let openUrl = url;
if (openUrl.indexOf('projectx') == 0) {
openUrl = '/' + openUrl;
}
if (isGet) {
openUrl = urlJoin(openUrl, queryStr);
}
xhr.open(method, openUrl, true);
for (let key in headers) {
xhr.setRequestHeader(key, headers[key]);
}
xhr.responseType = type;
xhr.onreadystatechange = () => {
if (xhr.readyState == 4 && xhr.status == 200) {
resolve(xhr.response)
}
};
xhr.onerror = (reason): void => {
reject(reason)
};
xhr.onloadend = (): void => {
if (xhr.status == 404) {
reject(url + ' 404 (Not Found)')
}
};
if (isGet) {
xhr.send();
} else {
xhr.send(queryStr);
}
}
}
function doRequest(payload, resolve, reject) {
if (window['proxy_window'] && payload.url.indexOf('blob') !== 0) {
doProxyRequest(payload, function (p) {
resolve(p);
}, reject);
} else {
doXhrRequest(payload, resolve, reject);
}
}
export function urlJoin(url, query) {
if (query) {
url += url.indexOf('?') < 0 ? '?' : '';
url += url[url.length - 1] === '?' ? '' : '&';
return url + query;
} else {
return url;
}
}
/**
* Created by rockyl on 2020/9/21.
*/
import {httpRequest} from "./net";
import {appID, projectID} from "./init";
import { appID, projectID } from "./init";
import axios from "axios";
export function cleanNewUser() {
if(!localStorage) return;
if (!localStorage) return;
let key = 'nu_' + appID + '_' + projectID;
localStorage.removeItem(key);
}
export function accessLog(pageBizId, params?) {
export function accessLog(pageBizId: number, params?: { remain: number; }) {
let p = {
pageBizId,
...params,
};
injectProp(p, params);
return httpRequest('buriedPoint', 'get', p);
}
/**
* 属性注入方法
* @param target 目标对象
* @param data 被注入对象
* @param callback 自定义注入方法
* @param ignoreMethod 是否忽略方法
* @param ignoreNull 是否忽略Null字段
*
* @return 是否有字段注入
*/
export function injectProp(target: any, data?: any, callback?: Function, ignoreMethod: boolean = true, ignoreNull: boolean = true): boolean {
if(!target || !data) {
return false;
}
let result = false;
for(let key in data) {
let value: any = data[key];
if((!ignoreMethod || typeof value != 'function') && (!ignoreNull || value != null)) {
if(callback) {
callback(target, key, value);
} else {
try {
target[key] = value;
} catch(e) {
}
}
result = true;
}
}
return result;
}
/**
* 数组查找
* @param arr
* @param predicate
*/
export function arrayFind(arr, predicate) {
if(!arr) {
return;
}
for(let i = 0, li = arr.length; i < li; i++) {
const item = arr[i];
if(predicate(item, i, arr)) {
return item;
}
}
}
/**
* 对象转query字符串
* @param obj
*/
export function obj2query(obj: any): string {
if(!obj) {
return '';
}
const arr: string[] = [];
for(const key in obj) {
arr.push(key + (key ? '=' : '') + obj[key]);
}
return arr.join('&');
axios.get("buriedPoint", {
params: p
});
}
import { CodeError } from "./common-helpers/CodeError";
import { Errors as ERRORS } from "./common-helpers/errors";
import { jsonp } from "@grace/built-in";
import { evalJsScript } from "@grace/built-in";
import { evalJsScript, jsonp } from "@grace/built-in";
import axios from "axios";
const isProd = location.href.indexOf('.com.cn/projectx') >= 0;
......
/**
* index.jsx
* Created by 还有醋v on 2022/10/10 下午3:03.
* Copyright © 2022 haiyoucuv. All rights reserved.
*/
import React, { CSSProperties, MouseEventHandler, ReactElement, useState } from "react";
interface IButtonProps {
className?: string;
onClick?: MouseEventHandler;
children?: ReactElement,
style?: CSSProperties,
}
/**
* @return ReactElement
* @constructor
* @param props
*/
export const Button = (props: IButtonProps): ReactElement => {
const {
children,
className,
onClick = () => void 0,
style = {}
} = props;
const [scale, setScale] = useState("unset");
const onTouchStart = () => {
setScale("scale(0.9,0.9)");
};
const onTouchEnd = () => {
setScale("unset");
};
const onTouchCancel = onTouchEnd;
return React.createElement("div", {
className, onTouchStart, onTouchEnd, onTouchCancel, onClick, style: {
transitionDuration: 0.5, transform: scale, ...style
}
}, children);
};
......@@ -19,4 +19,13 @@
width: 400px;
height: 400px;
}
.button {
position: absolute;
width: 100px;
height: 100px;
left: 100px;
top: 100px;
.sparkBg("LoadingPage/loadingFill.png");
}
}
......@@ -3,6 +3,7 @@ import { observer } from 'mobx-react';
import './HomeDemo.less';
import { SvgaPlayer } from "@grace/svgaplayer";
import { Button } from "@grace/ui";
import svga from "../../assets/LoadingPage/1红色标题.svga";
import png from "../../assets/LoadingPage/loadingIp.png";
......@@ -16,10 +17,13 @@ class HomeDemo extends React.Component {
render() {
return <div className="homeDemo md1">
<div className="homeImg md1" />
<div className="homeImg" />
<img src={png} />
当前为活动首页
<SvgaPlayer className="svga" src={svga} />
<Button className="button md2" />
</div>;
}
}
......
/// <reference types="vite/client" />
declare const CFG: any;
declare module "*.svga" {
const src: string;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
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