Commit 931ab5f3 authored by 俞嘉婷's avatar 俞嘉婷

init commit

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
# 接入方id
VITE_APPID = 'c1f2ceaa600c41ea813876207a511f9b'
# 小程序id
VITE_MINIPRO_ID = 'e9c05375fb23d509'
VITE_MINIPRO_TEST_ID = '6b94edbbde5edba3'
# 当前项目的地址
VITE_PROJECT_URL = 'https://yxq.95516.com/taskCenter/index.html'
# 分享图片
VITE_SHARE_ICON = 'https://yxq.95516.com/taskCenter/assets/home/shareIcon.png'
# h5APPID
VITE_H5_APPID = '72624b3efbd34aecb32b10c05820f86f'
# h5Url
VITE_H5_PROJECT_URL = 'yxq.95516.com/taskCenter/index.html'
# 测试活动地址
VITE_TEST_PROJECT_URL = 'https://unionpay-task.duibatest.com.cn/taskCenter/index.html'
\ No newline at end of file
# 接入方id
VITE_APPID = "926a475b41f94d3494d595825313d1e8"
# 小程序id
VITE_MINIPRO_ID = '6b94edbbde5edba3'
# 当前项目的地址
VITE_PROJECT_URL = 'https://unionpay-task.duibatest.com.cn/taskCenter/index.html'
# 分享图片
VITE_SHARE_ICON = 'https://yxq.95516.com/taskCenter/assets/home/shareIcon.png'
# 测试活动地址
VITE_TEST_PROJECT_URL = 'https://unionpay-task.duibatest.com.cn/taskCenter/index.html'
\ No newline at end of file
# 接入方id
VITE_APPID = 'c1f2ceaa600c41ea813876207a511f9b'
# 小程序id
VITE_MINIPRO_ID = 'e9c05375fb23d509'
VITE_MINIPRO_TEST_ID = '6b94edbbde5edba3'
# 当前项目的地址
VITE_PROJECT_URL = 'https://yxq.95516.com/taskCenter/index.html'
# 分享图片
VITE_SHARE_ICON = 'https://yxq.95516.com/taskCenter/assets/home/shareIcon.png'
# h5APPID
VITE_H5_APPID = '72624b3efbd34aecb32b10c05820f86f'
# h5Url
VITE_H5_PROJECT_URL = 'yxq.95516.com/taskCenter/index.html'
# 测试活动地址
VITE_TEST_PROJECT_URL = 'https://unionpay-task.duibatest.com.cn/taskCenter/index.html'
\ No newline at end of file
# 接入方id
VITE_APPID = '926a475b41f94d3494d595825313d1e8'
# 小程序id
VITE_MINIPRO_ID = '6b94edbbde5edba3'
# 当前项目的地址
VITE_PROJECT_URL = 'https://unionpay-task.duibatest.com.cn/taskCenter/index.html'
# 分享图片
VITE_SHARE_ICON = 'https://yxq.95516.com/taskCenter/assets/home/shareIcon.png'
\ No newline at end of file
# 忽略eslint校验路径,例如:
# src/libs/@spark
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,
upsdk: 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
# React + 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
ssh weiyan@bm.dui88.com -p60022
This diff is collapsed.
*{margin:0;padding:0;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}html,body{font-size:.24rem;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}.popupCenterShow{animation:centerShowAni .5s ease-out}@keyframes centerShowAni{0%{transform:scale(0)}66.7%{transform:scale(1.1)}to{transform:scale(1)}}@font-face{font-family:SFMono-Medium;src:url(./assets/font/SFMono-Medium.ttf)}.customStyle{position:fixed!important;top:50%;left:50%;transform:translate(-50%,-50%)}.inputCon{position:absolute}.timeInput1,.timeInput2{position:absolute;width:4rem;height:.5rem;z-index:10}.timeInput2{top:1rem}.modal-hoc-bg{position:fixed;top:0;bottom:0;right:0;left:0;background-color:rgba(0,0,0,.8);z-index:1000}@font-face{font-family:SFMono-Medium;src:url(../../assets/font/SFMono-Medium.ttf)}.wanLiuDialog{width:7.5rem;height:4.48rem;position:absolute}.wanLiuDialog .bg,.wanLiuDialog .characterBg{width:6.48rem;height:4.48rem;left:.51rem;position:absolute;background-repeat:no-repeat;background-size:100% 100%;background-position:left top}.wanLiuDialog .tuiChuBtn,.wanLiuDialog .characterTuiChuBtn{width:2.11rem;height:.76rem;left:1.25rem;top:2.78rem;position:absolute;background-repeat:no-repeat;background-size:100% 100%;background-position:left top}.wanLiuDialog .continueBtn,.wanLiuDialog .characterContinueBtn{width:2.11rem;height:.76rem;left:4.11rem;top:2.78rem;position:absolute;background-repeat:no-repeat;background-size:100% 100%;background-position:left top}.wanLiuDialog .progressText{width:5.58rem;height:.35rem;text-align:center;position:absolute;left:.93rem;top:1.49rem;font-size:.3rem;color:#1b1b1b;line-height:.4rem}.wanLiuDialog .timeText{width:5.58rem;height:.4rem;text-align:center;position:absolute;left:.93rem;top:1.95rem;font-size:.3rem;color:#1b1b1b;line-height:.4rem}#toast_layer{position:absolute;left:0;top:0;box-sizing:border-box;width:100vw;height:100vh;display:flex;display:-webkit-flex;justify-content:center;-webkit-justify-content:center;align-items:center;-webkit-align-items:center}#toast_layer .wrapper{display:flex;display:-webkit-flex;justify-content:center;-webkit-justify-content:center;flex-direction:column;-webkit-flex-direction:column;align-items:center;-webkit-align-items:center;max-width:80%}#toast_layer .wrapper .toast-message{opacity:0;margin-bottom:.1rem;font-size:0;transition:opacity .3s;-webkit-transition:opacity .3s;background-color:rgba(0,0,10,.8);box-shadow:.01rem .02rem .05rem .01rem rgba(0,0,0,.2);-webkit-box-shadow:.01rem .02rem .05rem .01rem rgba(0,0,0,.2);border-radius:.2rem}#toast_layer .wrapper .toast-message .toast-content{display:inline-block;overflow:hidden;padding:.2rem .25rem;font-family:-apple-system,system-ui,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;color:#fff;font-size:.3rem;text-align:center;max-width:100%;overflow-wrap:anywhere}#overlay_layer{position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:2001;pointer-events:none}@font-face{font-family:SFMono-Medium;src:url(../../assets/font/SFMono-Medium.ttf)}.homePage{width:100%;height:100vh;overflow-y:hidden;overflow-x:hidden;position:absolute}.homePage .bg{width:7.5rem;height:16.24rem;position:absolute;background-repeat:no-repeat;background-size:100% 100%;background-position:left top}.homePage .beginbtn{position:fixed;width:5.51rem;height:2.19rem;left:1.15rem;bottom:1.11rem;background-repeat:no-repeat;background-size:100% 100%;background-position:left top}.homePage .characterBeginbtn{width:4.75rem;height:1.47rem;left:1.31rem;bottom:1.44rem}.homePage .oldHealthyBeginbtn{width:4.83rem;height:1.86rem;left:1.26rem;bottom:1.31rem}.homePage .yinsi{position:fixed;width:3.73rem;height:.3rem;left:1.88rem;bottom:1.11rem;background-repeat:no-repeat;background-size:100% 100%;background-position:left top}.homePage .yinsi .selectIcon{display:inline-block;position:absolute;width:.19rem;height:.17rem;left:.06rem;top:.07rem;background-repeat:no-repeat;background-size:100% 100%;background-position:left top}.homePage .yinsi .gouxuan{display:inline-block;position:absolute;width:.38rem;height:.38rem;left:-.03rem;top:-.04rem;background:rgba(0,0,0,0)}.homePage .yinsi .chakanyinsi{display:inline-block;position:absolute;width:1.7rem;height:.3rem;right:0rem;top:0rem}.homePage .characterYinsi,.homePage .oldHealthyYinsi{width:3.75rem;height:.3rem;left:1.85rem;bottom:.9rem}
This diff is collapsed.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
<!doctype html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title></title><script>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;
}
document.addEventListener("DOMContentLoaded", function () {
!(function (e, i) {
var t = e.documentElement,
n = navigator.userAgent.match(/iphone|ipod|ipad/gi),
a = n ? Math.min(i.devicePixelRatio, 3) : 1,
m = 'orientationchange' in window ? 'orientationchange' : 'resize';
t.dataset.dpr = a;
for (
var d, l, c = !1, o = e.getElementsByTagName('meta'), r = 0; r < o.length; r++
)
(l = o[r]), 'viewport' == l.name && ((c = !0), (d = l));
if (c)
d.content =
'width=device-width,initial-scale=1.0,maximum-scale=1.0, minimum-scale=1.0,user-scalable=no';
else {
var o = e.createElement('meta');
(o.name = 'viewport'),
(o.content =
'width=device-width,initial-scale=1.0,maximum-scale=1.0, minimum-scale=1.0,user-scalable=no'),
t.firstElementChild.appendChild(o);
}
var s = function () {
var e = t.clientWidth;
e / a > 750 && (e = 750 * a),
(window.remScale = e / 750),
(t.style.fontSize = 100 * (e / 750) + 'px');
};
s(), e.addEventListener && i.addEventListener(m, s, !1);
})(document, window);
})</script><style></style><script type="module" crossorigin src="./assets/index-5f7f0a32.js"></script><link rel="stylesheet" href="./assets/index-5ff380f1.css"><script type="module">import.meta.url;import("_").catch(()=>1);async function* g(){};if(location.protocol!="file:"){window.__vite_is_modern_browser=true}</script><script type="module">!function(){if(window.__vite_is_modern_browser)return;console.warn("vite: loading legacy chunks, syntax error above and the same error below should be ignored");var e=document.getElementById("vite-legacy-polyfill"),n=document.createElement("script");n.src=e.src,n.onload=function(){System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))},document.body.appendChild(n)}();</script></head><body><div id="root"></div><script src="./assets/js/duiba.js"></script><script>var CFG = {}
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.activityName = "寻找剧中人活动";
CFG.channel = getUrlParam("sourceFrom") || sessionStorage.getItem("channel");
CFG.channel && sessionStorage.setItem("channel", CFG.channel);
// 生产
CFG.sensorUrl = 'https://xnjkfx.cpic.com.cn:8006/sa?project=SXGW';
if(location.href.indexOf("duibatest") > -1) {
var vConsole = new VConsole();
CFG.sensorUrl = 'https://xnjkfxsit.cpic.com.cn/sa?project=SXGW';
}</script><script nomodule>!function(){var e=document,t=e.createElement("script");if(!("noModule"in t)&&"onbeforeload"in t){var n=!1;e.addEventListener("beforeload",(function(e){if(e.target===t)n=!0;else if(!e.target.hasAttribute("nomodule")||!n)return;e.preventDefault()}),!0),t.type="module",t.src=".",e.head.appendChild(t),t.remove()}}();</script><script nomodule crossorigin id="vite-legacy-polyfill" src="./assets/polyfills-legacy-0b3f12d3.js"></script><script nomodule crossorigin id="vite-legacy-entry" data-src="./assets/index-legacy-86eb523b.js">System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))</script></body></html>
\ No newline at end of file
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<!-- <link rel="icon" type="image/svg+xml" href="/vite.svg" /> -->
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>太保时光藏馆</title>
<script>
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;
}
document.addEventListener("DOMContentLoaded", function () {
!(function (e, i) {
var t = e.documentElement,
n = navigator.userAgent.match(/iphone|ipod|ipad/gi),
a = n ? Math.min(i.devicePixelRatio, 3) : 1,
m = 'orientationchange' in window ? 'orientationchange' : 'resize';
t.dataset.dpr = a;
for (
var d, l, c = !1, o = e.getElementsByTagName('meta'), r = 0; r < o.length; r++
)
(l = o[r]), 'viewport' == l.name && ((c = !0), (d = l));
if (c)
d.content =
'width=device-width,initial-scale=1.0,maximum-scale=1.0, minimum-scale=1.0,user-scalable=no';
else {
var o = e.createElement('meta');
(o.name = 'viewport'),
(o.content =
'width=device-width,initial-scale=1.0,maximum-scale=1.0, minimum-scale=1.0,user-scalable=no'),
t.firstElementChild.appendChild(o);
}
var s = function () {
var e = t.clientWidth;
e / a > 750 && (e = 750 * a),
(window.remScale = e / 750),
(t.style.fontSize = 100 * (e / 750) + 'px');
};
s(), e.addEventListener && i.addEventListener(m, s, !1);
})(document, window);
})
</script>
<style>
/* @font-face {
font-family: SFMono-Medium;
src: url('./assets/font/SFMono-Medium.ttf');
} */
</style>
</head>
<body>
<div id="root"></div>
<script type="module" src="./src/main.jsx"></script>
<script src="./assets/js/duiba.js"></script>
<script>
var CFG = {}
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.activityName = "寻找剧中人活动";
CFG.channel = getUrlParam("sourceFrom") || sessionStorage.getItem("channel");
CFG.channel && sessionStorage.setItem("channel", CFG.channel);
// 生产
CFG.sensorUrl = 'https://xnjkfx.cpic.com.cn:8006/sa?project=SXGW';
if(location.href.indexOf("duibatest") > -1) {
var vConsole = new VConsole();
CFG.sensorUrl = 'https://xnjkfxsit.cpic.com.cn/sa?project=SXGW';
}
</script>
</body>
</html>
\ No newline at end of file
import Mock from "mockjs"
export const homeJs = [{
url: '/api/test', //请求地址
method: 'post', //请求方式
response: () => {
return {
code: 200,
msg: 'ok',
data: {
task: 1
}
}
},
}, {
url: '/activity/index', //请求地址
response: () => {
return {
code: 200,
msg: 'ok',
data: {
task: 1
}
}
},
}]
import { homeJs } from "./home";
export default [
...homeJs
]
\ No newline at end of file
This diff is collapsed.
{
"name": "ylyxq-20240510",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "cross-env NODE_ENV=development node ./src/utils/generateAssetList.js && vite --mode dev",
"dev:test": "cross-env NODE_ENV=test node ./src/utils/generateAssetList.js && vite --mode test",
"build:test": "cross-env NODE_ENV=test node ./src/utils/generateAssetList.js && vite build --mode test",
"build": "cross-env NODE_ENV=production node ./src/utils/generateAssetList.js && vite build --mode production",
"lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
},
"dependencies": {
"@babel/plugin-proposal-class-properties": "^7.18.6",
"@babel/plugin-proposal-decorators": "^7.24.1",
"axios": "^1.6.8",
"cross-env": "^7.0.3",
"crypto-js": "^4.2.0",
"history": "4.10.1",
"html2canvas": "1.4.1",
"mobx": "^6.12.3",
"mobx-react": "^9.1.1",
"mobx-react-lite": "^4.0.7",
"mockjs": "^1.1.0",
"npm": "10.5.0",
"postcss-plugin-px2rem": "^0.8.1",
"qrcode": "^1.5.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hot-toast": "^2.4.1",
"react-router-dom": "5.2.1",
"sa-sdk-javascript": "^1.27.5",
"swiper": "8.4.5",
"vite-plugin-html": "^3.2.2",
"vite-plugin-mock": "^3.0.2",
"vite-plugin-proxy": "^0.5.0"
},
"devDependencies": {
"@types/react": "^18.2.66",
"@types/react-dom": "^18.2.22",
"@vitejs/plugin-legacy": "4.1.1",
"@vitejs/plugin-react": "^4.2.1",
"eslint": "^8.57.0",
"eslint-plugin-react": "^7.34.1",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.6",
"less": "^4.2.0",
"terser": "^5.31.1",
"vite": "^4.2.0"
}
}
This diff is collapsed.
#root {
width: 750px;
margin: 0 auto;
padding: 2rem;
text-align: center;
}
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.react:hover {
filter: drop-shadow(0 0 2em #61dafbaa);
}
@keyframes logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@media (prefers-reduced-motion: no-preference) {
a:nth-of-type(2) .logo {
animation: logo-spin infinite 20s linear;
}
}
.card {
padding: 2em;
}
.read-the-docs {
color: #888;
}
import request from './request'
// 登录
export const login = (data) => {
return request({
method: 'post',
url: '/api/test',
data
})
}
export const indexApi = (data) => {
return request({
method: 'get',
url: '/activity/index',
data
})
}
export const join = (data) => {
return request({
method: 'post',
url: '/activity/join',
data
})
}
import axios from 'axios'
// import { toast } from 'react-toastify';
// import { toast } from 'react-hot-toast';
import { errMessageMap } from '../utils/constants';
import { randomStr } from '../utils/utils';
import CryptoJS from 'crypto-js'
import Toast from '../components/toast';
// import { createHashHistory } from "history";
// const history = createHashHistory();
const service = axios.create({
baseURL: import.meta.env.MODE != 'dev' ? '/dbcpic-api/app' : '', // mockjs 模拟数据这里必须为空,否则请求报404
// baseURL: '/api', // mockjs 模拟数据这里必须为空,否则请求报404
method: 'post',
timeout: 20000
})
let notShowMessage = false;
service.interceptors.request.use(config => {
// console.log("config==>", typeof config.data, config.data)
// 请求加签名
// let timestamp = new Date().getTime();
// let nonceStr = randomStr(20);
// let app_secret = 'duiba123123';
// let sign = null
// if(config.url.indexOf("test/autoLogin") == -1 ) {
// if(config.data) {
// sign = CryptoJS.MD5(`${app_secret}${JSON.stringify(config.data)}${nonceStr}${timestamp}`).toString();
// config.data = {
// data: JSON.stringify({
// ...config.data,
// }),
// timestamp,
// nonceStr,
// sign
// }
// } else {
// sign = CryptoJS.MD5(`${app_secret}${nonceStr}${timestamp}`).toString();
// config.data = {
// timestamp,
// nonceStr,
// sign
// }
// }
// }
const isPostType = config.postType === 'formData'
notShowMessage = config?.notShowMessage;
config.headers['Content-Type'] = isPostType ? 'application/x-www-form-urlencoded' : 'application/json'
if (config.method === 'get' && config.data) {
let url = config.url + '?';
for (const propName of Object.keys(config.data)) {
const value = config.data[propName];
var part = encodeURIComponent(propName) + "=";
if (value !== null && typeof (value) !== "undefined") {
if (typeof value === 'object') {
for (const key of Object.keys(value)) {
if (value[key] !== null && typeof (value[key]) !== 'undefined') {
let params = propName + '[' + key + ']';
let subPart = encodeURIComponent(params) + '=';
url += subPart + encodeURIComponent(value[key]) + '&';
}
}
} else {
url += part + encodeURIComponent(value) + "&";
}
}
}
// url = url.slice(0, -1);
// if(config.url.indexOf("api.map") == -1) {
// url += `sign=${sign}`
// }
config.data = {};
config.url = url;
}
// console.error("看看生成的", config, config.data);
return config
}, error => {
// message.error('请求失败')
Promise.reject(error)
})
// 响应拦截器 TODO 接口成功的状态情况
service.interceptors.response.use(data => {
// console.warn("不是报错了吗")
// console.warn("跳转了吗", data.data.code, data)
// 所有请求完成后都要执行的操作
if (!data.data.ok) {
// if(data.data.code == '100018') {
// history.replace({ pathname: '/errorPage' })
// return data.data;
// }
// if(data.data.code == '100002') {
// history.replace({ pathname: '/' })
// return data.data;
// }
// if(data.data.code == '100020') {
// history.replace({ pathname: '/notePage' })
// return data.data;
// }
console.error("data.code", data.data.code, errMessageMap[data.data.code], notShowMessage)
if (!notShowMessage) {
if(errMessageMap[data.data.code]) {
Toast(errMessageMap[data.data.code])
} else {
Toast(data.data.msg || '网络异常,请稍后再试哦~')
}
}
return data.data;
}
return data.data
}, error => {
let {
// errorMessage
msg
} = error
// if (!notShowMessage) {
Toast(msg || '网络异常,请稍后再试哦~')
// }
return Promise.reject(error)
})
export default service
\ No newline at end of file
import React, { useEffect, useState } from 'react'
import { observer } from 'mobx-react';
import './index.less'
// import { login } from './api/api.js'
// import store from './store/index.js'
import Modal from './modal/modal.jsx'
import store from './store/index.js'
import modalStore from './store/modal.js'
import HomePage from './pages/homePage/homePage.jsx'
import { PAGE_MAP } from './utils/constants.js'
const pageMap = {
[PAGE_MAP.HOME_PAGE]: <HomePage />,
};
@observer
class App extends React.Component {
// const [count, setCount] = useState(0)
state = {
}
async componentDidMount() {
}
render() {
const { curPage, pageData } = store;
return (
<>
{{ ...pageMap[curPage], props: { ...pageData } }}
<Modal />
</>
)
}
}
export default App
{"preLoadImg":[],"asyncLoadImg":["./assets/homePage/homeBg.png"]}
\ No newline at end of file
import "./style.less";
import { getLayer, parseHtml } from "./utils";
let _toastWrapper;
const toastItems = [];
function getWrapper() {
if (!_toastWrapper) {
const layer = getLayer('toast');
_toastWrapper = document.createElement("div");
_toastWrapper.className = 'wrapper';
layer.appendChild(_toastWrapper);
}
return _toastWrapper;
}
function createToastItem(opt) {
let content = opt.content;
let options = opt.options;
const wrapperClass = options.itemClass || '';
const contentClass = options.contentClass || '';
let el = parseHtml(`<div class="toast-message ${wrapperClass}">
<div class="toast-content ${contentClass}"></div>
</div>`);
let contentEl = el.children[0];
if (typeof content === 'string') {
if (content.indexOf('<') >= 0 && content.indexOf('>') >= 0) {
contentEl.innerHTML = content;
}
else {
contentEl.innerText = content;
}
}
else {
contentEl.appendChild(content);
}
return el;
}
/**
* Toast
* @ctype PROCESS
* @description Toast
* @param {string|HTMLElement} content - 内容
* @param {number} [time=2000] - 停留时间ms
* @param {Object} [options] - 配置项
* @param {string} [options.itemClass] - 单项包装样式类
* @param {string} [options.contentClass] - 单项内容样式类
* @param {boolean} [options.hideOthers=false] - 隐藏其他Toast
* @returns
* hide function 主动隐藏当前Toast实例的方法
* @example 一般调用
* Toast('hello')
* @example 主动隐藏
* const hideMe = Toast('hello', 0) //时间传入0表示不自动隐藏
* setTimeout(hideMe, 5000) //5秒后隐藏
*/
export default function Toast(content, time = 3000, options = {}) {
const wrapper = getWrapper();
const { hideOthers = false } = options;
if (hideOthers) {
for (let item of toastItems) {
item(false);
}
}
let hidden = false;
let toastItem = createToastItem({ content, options });
toastItems.push(hide);
wrapper.appendChild(toastItem);
setTimeout(() => {
toastItem.style.opacity = '1';
if (time > 0) {
setTimeout(hide, time);
}
});
return hide;
function hide(anim = true) {
if (hidden) {
return;
}
hidden = true;
hideToast(toastItem, anim);
}
}
function hideToast(toastItem, anim = true) {
toastItems.splice(toastItems.indexOf(toastItem), 1);
const wrapper = getWrapper();
if (anim) {
toastItem.style.opacity = '0';
setTimeout(() => {
if (toastItem.parentNode) {
wrapper.removeChild(toastItem);
}
}, 300);
}
else {
if (toastItem.parentNode) {
wrapper.removeChild(toastItem);
}
}
}
#toast_layer {
position: absolute;
left: 0;
top: 0;
box-sizing: border-box;
width: 100vw;
height: 100vh;
display: flex;
display: -webkit-flex;
justify-content: center;
-webkit-justify-content: center;
align-items: center;
-webkit-align-items: center;
.wrapper {
display: flex;
display: -webkit-flex;
justify-content: center;
-webkit-justify-content: center;
flex-direction: column;
-webkit-flex-direction: column;
align-items: center;
-webkit-align-items: center;
max-width: 80%;
.toast-message {
opacity: 0;
margin-bottom: 10px;
font-size: 0;
transition: opacity 0.3s;
-webkit-transition: opacity 0.3s;
background-color: rgba(0, 0, 10, 0.8);
box-shadow: 1px 2px 5px 1px rgba(0, 0, 0, 0.2);
-webkit-box-shadow: 1px 2px 5px 1px rgba(0, 0, 0, 0.2);
border-radius: 20px;
.toast-content {
display: inline-block;
overflow: hidden;
padding: 20px 25px;
font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
color: #fff;
font-size: 30px;
text-align: center;
max-width: 100%;
overflow-wrap: anywhere;
}
}
}
}
#overlay_layer {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
z-index: 2001;
pointer-events: none;
}
import './top-layer.less';
let topLayer;
const layerNames = ['loading', 'toast'];
const layers = [];
export function getLayer(name) {
if (!topLayer) {
topLayer = document.createElement("div");
topLayer.id = 'overlay_layer';
for (let lname of layerNames) {
let layer = document.createElement("div");
layer.id = lname + '_layer';
topLayer.appendChild(layer);
layers[lname] = layer;
}
document.body.appendChild(topLayer);
}
return layers[name];
}
export function parseHtml(htmlText) {
var el = document.createElement('div');
el.innerHTML = htmlText;
return el.children[0];
}
/**
* 加载图片
* @ctype PROCESS
* @description 加载图片
* @param {string} src - 图片url
* @param {boolean} [crossOrigin=false] - 是否跨域
* @returns
* img HTMLImageElement Image节点
*/
export function loadImage(src, crossOrigin = false) {
return new Promise((resolve, reject) => {
let img = new Image();
if (crossOrigin) {
img.crossOrigin = 'anonymous';
}
img.onload = function () {
resolve(img);
};
img.onerror = function (e) {
reject(e);
};
img.src = src;
});
}
\ No newline at end of file
import React, { Component } from 'react';
import './index.less';
import { observer } from 'mobx-react';
import store, { skinId } from '../../store';
import { PAGE_MAP } from '../../utils/constants';
import modalStore from '../../store/modal';
import { sensorMdClick, sensorMdExpouse } from '../../utils/sensorMd';
@observer
class WanLiuDialog extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
sensorMdExpouse("xcxPopupExpouse", { pageName: `退出挽留弹窗` })
}
tuiChuBtnFun() {
sensorMdClick("xcxPopupClick", { pageName: `退出挽留弹窗`, buttonName: '退出' })
store.changePage(PAGE_MAP.HOME_PAGE)
modalStore.closePop("WanLiuDialog")
}
continueFun() {
sensorMdClick("xcxPopupClick", { pageName: `退出挽留弹窗`, buttonName: '继续评估' })
modalStore.closePop("WanLiuDialog")
}
render() {
return <div className="wanLiuDialog modal_center">
弹窗
</div>
}
}
export default WanLiuDialog;
\ No newline at end of file
@import url('../../res.less');
.wanLiuDialog {
width: 750px;
height: 448px;
position: absolute;
.bg {
width: 648px;
height: 448px;
left: 51px;
position: absolute;
.formatBg();
}
.characterBg {
width: 648px;
height: 448px;
left: 51px;
position: absolute;
.formatBg();
}
.tuiChuBtn {
width: 211px;
height: 76px;
left: 125px;
top: 278px;
position: absolute;
.formatBg();
}
.characterTuiChuBtn {
width: 211px;
height: 76px;
left: 125px;
top: 278px;
position: absolute;
.formatBg();
}
.continueBtn {
width: 211px;
height: 76px;
left: 411px;
top: 278px;
position: absolute;
.formatBg();
}
.characterContinueBtn {
width: 211px;
height: 76px;
left: 411px;
top: 278px;
position: absolute;
.formatBg();
}
.progressText {
width: 558px;
height: 35px;
text-align: center;
position: absolute;
left: 93px;
top: 149px;
font-size: 30px;
color: rgb(27, 27, 27);
line-height: 40px;
}
.timeText {
width: 558px;
height: 40px;
text-align: center;
position: absolute;
left: 93px;
top: 195px;
font-size: 30px;
color: rgb(27, 27, 27);
line-height: 40px;
}
}
\ No newline at end of file
This diff is collapsed.
:root {
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;
color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
body {
margin: 0;
display: flex;
place-items: center;
min-width: 320px;
min-height: 100vh;
}
h1 {
font-size: 3.2em;
line-height: 1.1;
}
button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
background-color: #1a1a1a;
cursor: pointer;
transition: border-color 0.25s;
}
button:hover {
border-color: #646cff;
}
button:focus,
button:focus-visible {
outline: 4px auto -webkit-focus-ring-color;
}
@media (prefers-color-scheme: light) {
:root {
color: #213547;
background-color: #ffffff;
}
a:hover {
color: #747bff;
}
button {
background-color: #f9f9f9;
}
}
* {
margin: 0;
padding: 0;
-webkit-touch-callout:none; /*系统默认菜单被禁用*/
-webkit-user-select:none; /*webkit浏览器*/
-khtml-user-select:none; /*早期浏览器*/
-moz-user-select:none;/*火狐*/
-ms-user-select:none; /*IE10*/
user-select:none;
-webkit-tap-highlight-color: transparent;
}
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;
}
.popupCenterShow {
animation: centerShowAni 500ms ease-out;
@keyframes centerShowAni {
0% {
transform: scale(0);
}
66.7% {
transform: scale(1.1);
}
100% {
transform: scale(1);
}
}
}
@font-face {
font-family: SFMono-Medium;
src: url('./assets/font/SFMono-Medium.ttf');
}
.customStyle {
position: fixed!important;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
// .toast222{
// position: absolute;
// top:500px !important;
// z-index: 1000000;
// }
.inputCon {
position: absolute;
}
.timeInput1, .timeInput2 {
position: absolute;
width: 400px;
height: 50px;
z-index: 10;
}
.timeInput2 {
top: 100px;
}
\ No newline at end of file
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './app.jsx'
import './index.less'
import '../mock/index.js'
// import { Toaster } from 'react-hot-toast';
import Modal from './modal/modal.jsx'
ReactDOM.createRoot(document.getElementById('root')).render(
<>
<App />
</>
)
import React, { Component } from "react";
import './modal.less';
import modalStore from '../store/modal';
import { toJS } from "mobx";
import { observer } from "mobx-react";
import WanLiuDialog from "../components/wanLiuDialog";
/**
* 弹窗配置
*/
export const cfg = {
WanLiuDialog: WanLiuDialog,
};
@observer
class Modal extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
document.body.style.overflow = 'hidden';
}
componentWillUnmount() {
document.body.style.overflow = 'auto';
}
render() {
const list = toJS(modalStore.popList);
if (!list.length) {
// TODO:此处根据需要自行修改
// document.body.style.overflow='auto';
return <section></section>;
}
let PopUpMulti, popUpMultiData;
if (list.length > 1 && list[list.length - 1].isMulti == true) {
const popObj2 = list[list.length - 1];
PopUpMulti = cfg[popObj2.key];
popUpMultiData = popObj2.data;
}
const popObj = list[0];
const PopUp = cfg[popObj.key];
const popData = popObj.data;
if (PopUp || PopUpMulti) {
document.body.style.overflow = 'hidden';
// document.getElementById("indexId").style.pointerEvents = 'none'
// document.body.style.pointerEvents = 'none'
}
return <section className="modal-hoc-bg" style={{
zIndex: modalStore.popList.length ? 1000 : -1,
display: modalStore.popList.length ? 'block' : 'none'
}}>
{PopUp && <PopUp popData={popData} />}
{PopUpMulti && <section className="modal-hoc-bg" style={{
zIndex: modalStore.popList.length ? 1000 : -1,
display: modalStore.popList.length ? 'block' : 'none'
}}><PopUpMulti popData={popUpMultiData} />
</section>}
</section>;
}
}
export default Modal;
\ No newline at end of file
.modal-hoc-bg {
position: fixed;
top: 0;
bottom: 0;
right: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.8);
z-index: 1000;
// pointer-events: all;
}
\ No newline at end of file
import React, { Component } from 'react';
import './homePage.less';
import { _throttle } from '../../utils/utils';
import skinStore from '../../store/newSkin';
import Toast from '../../components/toast';
import store, { skinId } from '../../store';
import { PAGE_MAP } from '../../utils/constants';
import { observer } from 'mobx-react';
import { sensorMdClick, sensorMdExpouse } from '../../utils/sensorMd';
import modalStore from '../../store/modal';
@observer
class HomePage extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
sensorMdExpouse("xcxPage", { pageName: `首页` })
store.getIndexInfo();
// modalStore.pushPop("WanLiuDialog")
}
beginBtnFun() {
sensorMdClick("xcxClick", { pageName: `首页`, buttonName: '开始测试' })
const flag = store.checkActivityStatus();
if (!flag) return;
store.joinActivity();
}
render() {
return (
<div className="homePage modal_center">
<div className="bg" style={{ 'backgroundImage': `url(${skinStore.homeJs.homeBg})` }}></div>
</div>
);
}
}
export default HomePage;
@import url('../../res.less');
.homePage {
width: 100%;
height: 100vh;
overflow-y: hidden;
overflow-x: hidden;
position: absolute;
.bg {
width: 750px;
height: 1624px;
position: absolute;
.formatBg();
}
.beginbtn {
position: fixed;
width: 551px;
height: 219px;
left: 115px;
// top: 1294px;
bottom: 111px;
.formatBg();
}
.characterBeginbtn {
width: 475px;
height: 147px;
left: 131px;
// top: 1333px;
bottom: 144px;
}
.oldHealthyBeginbtn {
width: 483px;
height: 186px;
left: 126px;
// top: 1309px;
bottom: 131px;
}
.yinsi {
position: fixed;
width: 373px;
height: 30px;
left: 188px;
// top: 1483px;
bottom: 111px;
.formatBg();
.selectIcon {
display: inline-block;
position: absolute;
width: 19px;
height: 17px;
left: 6px;
top: 7px;
.formatBg();
}
.gouxuan {
display: inline-block;
position: absolute;
width: 38px;
height: 38px;
left: -3px;
top: -4px;
background: rgba(0, 0, 0, 0);
}
.chakanyinsi {
display: inline-block;
position: absolute;
width: 170px;
height: 30px;
right: 0px;
top: 0px;
}
}
.characterYinsi {
width: 375px;
height: 30px;
left: 185px;
// top: 1504px;
bottom: 90px;
}
.oldHealthyYinsi {
width: 375px;
height: 30px;
left: 185px;
// top: 1504px;
bottom: 90px;
}
}
\ No newline at end of file
@RES_PATH: '/public/assets/';
@webp: '?x-oss-process=image/format,webp';
.sparkBg(@value) {
background-repeat: no-repeat;
background-size: 100% 100%;
background-position: left top;
background-image: url("@{RES_PATH}@{value}");
[duiba-webp='true'] & {
background-image: url("@{RES_PATH}@{value}@{webp}");
}
}
.formatBg() {
background-repeat: no-repeat;
background-size: 100% 100%;
background-position: left top;
}
/* 文本过长隐藏文字并显示省略号 单行*/
.lineClamp1() {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.lineClampN(@num) {
white-space: wrap;
text-overflow: -o-ellipsis-lastline;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: @num;
overflow: hidden;
}
.breathAnimation() {
animation: scale 1s linear infinite alternate;
@keyframes scale {
0% {
transform: scale(0.9);
}
100% {
transform: scale(1.04);
}
}
}
@font-face {
font-family: SFMono-Medium;
src: url('./assets/font/SFMono-Medium.ttf');
}
.btnShow() {
animation: btnShowAni 600ms ease-out infinite;
@keyframes btnShowAni {
0%,
100% {
transform: scale(1);
}
50% {
transform: scale(1.1);
}
}
}
\ No newline at end of file
import {
makeAutoObservable
} from 'mobx';
import {
} from '../api/api';
import {
delUrlParam,
getUrlParam,
isIos,
} from '../utils';
import Toast from '../components/toast';
import { getQRCode, randomStr, url2Base64, waitTime } from '../utils/utils';
import CryptoJS from 'crypto-js'
import modalStore from './modal';
import { GetCurrSkinId, getCustomShareId } from "../utils/utils";
import { PAGE_MAP } from '../utils/constants';
import { indexApi, join } from "../api/api.js";
export const skinId = GetCurrSkinId() || getCustomShareId();
const store = makeAutoObservable({
/** 当前页面 */
curPage:
{
// index: PAGE_MAP.HOME_PAGE,
}[skinId] || PAGE_MAP.HOME_PAGE,
pageData: {},
changePage(val) {
this.curPage = val
},
indexInfo: {},
getIndexInfo() {
indexApi({ activityId: '' }).then(res => {
console.log(res)
if (res.ok) {
store.indexInfo = res.data
}
});
},
checkActivityStatus() {
const activityInfo = store.indexInfo.activityInfo;
if (activityInfo && activityInfo.startTime && activityInfo.endTime) {
const startTime = activityInfo.startTime;
const endTime = activityInfo.endTime;
const now = new Date().getTime();
if (now >= startTime && now <= endTime) {
return true;
}
if (now < startTime) {
Toast('活动暂未开始,敬请期待~')
}
if (now > endTime) {
Toast('活动已结束,感谢您的关注~')
}
}
Toast('活动异常~')
return false;
},
joinActivity() {
join({ activityId: '' }).then(res => {
console.log(res)
if (res.ok) {
this.curQuesIndex = 0;
this.changePage(PAGE_MAP.QUES_PAGE)
} else {
Toast(res.msg)
}
});
}
});
export default store;
import { makeAutoObservable } from 'mobx';
// 此处配置页面的优先级,越大优先级越高
// PopIndex:11
/**
* 弹窗优先级 可以是负数, 不写默认是10, 数值越小,层级越高
*/
const modalIndex = {
}
const modalStore = makeAutoObservable({
popList: [],
/**
*
* @param {*} key 弹窗名,一般是类名的字符串
* @param {*} data 需要传递的数据,弹窗中使用 const {popData} = props; 获取
* @param {*} isMulti 是否是二级弹窗,在不关闭已有弹窗的基础上,弹出当前弹窗。注意,如果是二级弹窗,关闭时必须传key
*/
pushPop(key, data = {}, isMulti = false) {
if (this.popList.length) {
let cacheList = this.popList.slice();
cacheList.push({ key, data, isMulti });
cacheList = cacheList.sort((a, b) => ((modalIndex[b.key] ? modalIndex[b.key] : 10) - (modalIndex[a.key] ? modalIndex[a.key] : 10)))
this.popList.clear();
this.popList.push(...cacheList);
} else {
this.popList.push({ key, data, isMulti });
}
if(document.getElementById("indexId")) {
document.getElementById("indexId").style.pointerEvents = 'none'
}
// console.log("this.popList:::",toJS(this.popList));
},
/**
*
* @param {*} key 弹窗名,一般是类名的字符串,关闭指定弹窗,若未指定,则关闭当前弹窗
*/
closePop(key) {
if (key) {
let cacheList = this.popList.slice();
cacheList = cacheList.filter(obj => (obj.key != key));
this.popList.clear();
this.popList.push(...cacheList);
} else {
this.popList.shift();
}
if(document.getElementById("indexId") && this.popList.length == 0) {
document.getElementById("indexId").style.pointerEvents = 'auto'
}
},
/**
* 关闭所有弹窗
*/
closePopAll() {
this.popList.clear();
}
});
export default modalStore;
import {
makeAutoObservable
} from 'mobx';
// import CryptoJS from 'crypto-js';
// // const CryptoJS = require('crypto-js');
// const hash = createHash('sha256');
// hash.update(bundle[fileName].source);
// const hashValue = hash.digest('hex').substring(0, 8);
// 首页
let homeJs1 = {
homeBg: './assets/homePage/homeBg.png',
}
// 处理图片防止缓存
const dealImg = (obj) => {
Object.keys(obj)?.map(item => {
if (typeof obj[item] == 'string') {
obj[item] = `${obj[item]}?v=${__BUILD_TIME__}`
} else if (Array.isArray(obj[item])) {
return dealImg(obj[item])
}
})
return obj
}
let homeJs = dealImg(homeJs1)
const skinStore = makeAutoObservable({
homeJs,
})
export default skinStore;
export const PAGE_MAP = {
HOME_PAGE: 'homePage',
QUES_PAGE: 'quesPage',
AGREE_PAGE: 'agreePage',
RESULT_PAGE: 'resultPage'
}
export const errMessageMap = {
200009: "奖品已抢完,明天再来吧~",
200002: "请刷新页面,奖品库存已领完~",
}
/**
* 渠道参数
* 1.个险app gxapp
* 2.个险企微 gxqw
* 3.寿险小程序 shouxian
*/
export const CHANNEL_PARAMS = {
/** 个险app */
GXAPP: "gxapp",
/** 个险企微 */
GXQW: "gxqw",
/** 寿险小程序 */
SHOUXIAN_MINI: "shouxian",
}
/** 神策 sysSourceName渠道参数 */
export const SYS_SOURCE_CHANNEL = {
/** 个险app */
[CHANNEL_PARAMS.GXAPP]: "个险",
/** 个险企微 */
[CHANNEL_PARAMS.GXQW]: "个险",
/** 寿险小程序 */
[CHANNEL_PARAMS.SHOUXIAN_MINI]: "官微",
}
/** 神策 activitySource渠道参数 */
export const ACTIVITY_SOURCE_CHANNEL = {
/** 个险app */
[CHANNEL_PARAMS.GXAPP]: "个险app",
/** 个险企微 */
[CHANNEL_PARAMS.GXQW]: "个险企微",
/** 寿险小程序 */
[CHANNEL_PARAMS.SHOUXIAN_MINI]: "寿险小程序",
}
export const EVENT_TYPE = {
CLICK: "click",
BROWSE: "browse",
}
/*
将此文件放到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')
import fs from 'fs'
import path from 'path'
/* 请先配置:预加载的资源文件夹名称,或者设置预加载、异步加载资源路径*/
const preloadFolder = ['home']; // 在/src/assets文件夹下,请设置需要预加载的资源文件目录,默认值预加载为loading文件夹, 其他均为异步加载
const otherFolder = ['bankBanner', 'coupon', 'loading', 'modal', 'prize']; // 在/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='/public/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;
// console.log(relPath)
if(fs.statSync(absPath).isFile()) {
if(regExp.test(v)){
if(preloadFolder.includes(relPath.split('/')[0])){
preLoadImg.push('./assets/' + relPath);
}else if(!otherFolder.includes(relPath.split('/')[0])){
// console.log("relPath", relPath)
asyncLoadImg.push('./assets/' + relPath)
} else {
// console.log("relPath", relPath)
asyncLoadImg.push('./assets/' + 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
export function diffTime(beforeDate, systemDate) {
let _beforeDate = beforeDate
if (!_beforeDate) return "-";
_beforeDate = new Date(
typeof beforeDate === "string" && isNaN(beforeDate) ?
beforeDate.replace(/-/g, "/") :
Number(beforeDate)
);
const diff = new Date().getTime() - new Date(_beforeDate).getTime();
// 计算天数
const day = Math.floor(diff / 1000 / 60 / 60 / 24);
return day;
}
export function strLen(str, num) {
if(!str) return '';
return str > num ? str.slice(0, num) + '...' : str;
}
export 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;
}
/**
* 删除url中的参数
* @param {*} url
* @param {*} arg
*/
export function delUrlParam(url, paramKey) {
const _url = new URL(url)
const search = new URLSearchParams(_url.search)
search.delete(paramKey)
_url.search = search.toString();
return _url.href;
}
/** 判断云闪付环境*/
export function isYunApp() {
let agent = navigator.userAgent.toLowerCase();
// let isInsideWallet = (((new RegExp(/(com.unionpay.chsp)/).test(agent)) || (new RegExp(/(com.unionpay.mobilepay)/).test(agent))) && agent.indexOf('UnionPaySDK') == -1);
let isInsideWallet = agent.indexOf('unionpaysdk') == -1;
// console.log('isInsideWallet',isInsideWallet)
return isInsideWallet;
}
/**
* 日期格式化
* @param date 接收可以被new Date()方法转换的内容
* @param format 字符串,需要的格式例如:'yyyy/MM/dd hh:mm:ss'
* @returns {String}
*/
export const dateFormatter = (date, format = "yyyy/MM/dd") => {
if (!date) return "-";
let _date = date
let _format = format
_date = new Date(
typeof date === "string" && isNaN(date)
? date.replace(/-/g, "/")
: Number(date)
);
const o = {
"M+": _date.getMonth() + 1,
"d+": _date.getDate(),
"h+": _date.getHours(),
"m+": _date.getMinutes(),
"s+": _date.getSeconds(),
"q+": Math.floor((_date.getMonth() + 3) / 3),
S: _date.getMilliseconds(),
};
if (/(y+)/.test(_format)) {
_format = format.replace(
RegExp.$1,
(_date.getFullYear() + "").substr(4 - RegExp.$1.length)
);
}
for (const k in o) {
if (new RegExp("(" + k + ")").test(_format)) {
_format = _format.replace(
RegExp.$1,
RegExp.$1.length === 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length)
);
}
}
return _format;
};
// 设置导航栏
export const editTitle = (title = '') => {
upsdk.pluginReady(function () {
upsdk.setNavigationBarTitle({
title: title,
});
// 前端API调用
upsdk.setTitleStyle({
// 可选,导航栏(含状态栏)背景色及透明度。16进制,前2位(8F)透明度,后六位(FFFFFF)颜色,仅对当前页有效,其余页还是申请配置的导航默认颜色
navBackgroundColor: '0xFFff585A',
appletStyle: 'white', //可选,black-黑色主题,white-白色主题
backBtnVisible: '0', // 可选,左侧返回按钮是否显示。'0'不显示,'1'显示,不传或空则默认显示
appletTitleBarVisible: '1', // 可选,标题栏是否显示。'0'不显示,'1'显示,默认显示
appletTitleGradientOrient: 'top', // 可选,渐变色方向,支持top、bottom、left、right
appletTitleGradientStartColor: '0xFFff585A', //渐变起始颜色
appletTitleGradientEndColor: '0xFFff585A' //渐变结束颜色
});
});
}
// Mozilla/5.0 (Linux; Android 10; PBCT10 Build/QKQ1.191224.003; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/77.0.3865.92 Mobile Safari/537.36(com.unionpay.mobilepay) (cordova 7.0.0) (updebug 2) (clientVersion 480) (version 905)(UnionPay/1.0 CloudPay)(language zh_CN)(upHtml)(UnionPaySDK 49992999)(BankVersion 278)
// rn跳转
export const rnJump = (dest, params = {}) => {
console.error("params", params)
upsdk.pluginReady(function(){
upsdk.openRNPage({
dest, //具体参数
...params,
isFinished: "0", // 默认0,在当前窗口打开, 1 关闭当前webview(我用这个之后直接白屏)
})
})
}
//小程序跳转
export const xcxJump = (appId, otherParam = {}) =>{
console.error("otherParam", otherParam)
upsdk.pluginReady(function () {
upsdk.openApplet({
appId: appId, // 加密的小程序应用id
param: "", // 可选,拼在小程序 url 后的查询参数
...otherParam,
// gId=1表示商品id为1
fail: function (code) {
// code=101表示appId为空,code=102表示找不到该应用
// console.log('open app:' + code);
}
})
})
}
//云网跳转
export const ywJump = (appId,encryptId)=>{
upsdk.openAppInfoByIdExt({
appId:appId, // 非加密 和加密id择一必传
encryptId:encryptId, //加密id 和非加密id择一必传
type:"", //支持rn、native、html、applet,非必传,建议传
perm:"", // 应用打开条件(同应用信息中perm), 非必传,建议传
extraData:"", //JsonString 额外传递参数,非必传
isFinish:"", // 打开应用后,是否关闭当前界面;’0’:不关闭,’1’:关闭,默认0。非必传
showLoading:"", //打开应用时是否显示loading,’0’:不展示,’1’:展示,默认1。非必传
scenarioId:"", // 场景号,仅打开小程序生效。非必传
});
}
// 是否是ios
export const isIos = () => {
const _isIos = navigator.userAgent.match(/iphone|ipod|ipad/gi);
return _isIos
}
\ No newline at end of file
/**
* Created by rockyl on 2020/12/8.
*/
(function autoStart() {
let visibilityChange;
if (typeof document.hidden !== 'undefined') {
visibilityChange = 'visibilitychange';
}
else if (typeof document['msHidden'] !== 'undefined') {
visibilityChange = 'msvisibilitychange';
}
else if (typeof document['webkitHidden'] !== 'undefined') {
visibilityChange = 'webkitvisibilitychange';
}
function handleVisibilityChange(e) {
visibilityChanged(document.visibilityState == "visible");
}
document.addEventListener(visibilityChange, handleVisibilityChange, false);
})();
const watchers = [];
function visibilityChanged(visible) {
for (let watcher of watchers) {
watcher && watcher(visible);
}
}
/**
* 观察页面显隐性变化
* @ctype PROCESS
* @description 观察页面显隐性变化
* @param {function} [callback] - 回调
* @example 一般用法
* function onPageVisibilityChange(visible){
* console.log('页面' + visible? '可见' : '不可见')
* }
* watchPageVisibility(onPageVisibilityChange)
*/
export function watchPageVisibility(callback) {
let index = watchers.indexOf(callback);
if (index < 0) {
watchers.push(callback);
}
}
/**
* 取消观察页面显隐性变化
* @ctype PROCESS
* @description 取消观察页面显隐性变化
* @param {function} [callback] - 回调
* @example 一般用法
* function onPageVisibilityChange(visible){
* console.log('页面' + visible? '可见' : '不可见')
* }
* unwatchPageVisibility(onPageVisibilityChange)
*/
export function unwatchPageVisibility(callback) {
let index = watchers.indexOf(callback);
if (index >= 0) {
watchers.splice(index, 1);
}
return {
type: index >= 0 ? 'success' : 'failed',
};
}
var sdkversion_placeholder = "1.26.5"; function wrapPluginInitFn(e, t, a) { if (t && (e.plugin_name = t), a && e.init) { var i = e.init; e.init = function (r, n) { if (wrapLogFn(r, e, t), r.readyState && r.readyState.state >= 3 || !r.on) return s(); function s() { i.call(e, r, n) } r.on(a, s) } } return e } function wrapLogFn(e, t, a) { function i(t, i) { e.logger ? e.logger.msg.apply(e.logger, i).module(a + "" || "").level(t).log() : e.log && e.log.apply(e, i) } t.log = function () { i("log", arguments) }, t.warn = function () { i("warn", arguments) }, t.error = function () { i("error", arguments) } } function createPlugin(e, t, a) { return wrapPluginInitFn(e, t, a), e.plugin_version = sdkversion_placeholder, e } var page_hidden_status_refresh_time = 5e3, MAX_DURATION = 432e3; function PageLeave() { this.sd = null, this.start_time = +new Date, this.page_show_status = !0, this.page_hidden_status = !1, this._ = {}, this.timer = null, this.current_page_url = document.referrer, this.url = location.href, this.title = document.title || "", this.option = {}, this.heartbeat_interval_time = 5e3, this.heartbeat_interval_timer = null, this.page_id = null, this.storage_name = "sawebjssdkpageleave", this.max_duration = MAX_DURATION } PageLeave.prototype.init = function (e, t) { if (e) { if (this.sd = e, this._ = this.sd._, t) { this.option = t; var a = t.heartbeat_interval_time; a && (this._.isNumber(a) || this._.isNumber(1 * a)) && 1 * a > 0 && (this.heartbeat_interval_time = 1e3 * a); var i = t.max_duration; i && (this._.isNumber(i) || this._.isNumber(1 * i)) && 1 * i > 0 && (this.max_duration = i) } this.page_id = Number(String(this._.getRandom()).slice(2, 5) + String(this._.getRandom()).slice(2, 4) + String((new Date).getTime()).slice(-4)), this.addEventListener(), !0 === document.hidden ? this.page_show_status = !1 : this.addHeartBeatInterval(), this.log("PageLeave\u521d\u59cb\u5316\u5b8c\u6bd5") } else this.log("\u795e\u7b56JS SDK\u672a\u6210\u529f\u5f15\u5165") }, PageLeave.prototype.log = function (e) { this.sd && this.sd.log(e) }, PageLeave.prototype.refreshPageEndTimer = function () { var e = this; this.timer && (clearTimeout(this.timer), this.timer = null), this.timer = setTimeout(function () { e.page_hidden_status = !1 }, page_hidden_status_refresh_time) }, PageLeave.prototype.hiddenStatusHandler = function () { clearTimeout(this.timer), this.timer = null, this.page_hidden_status = !1 }, PageLeave.prototype.pageStartHandler = function () { this.start_time = +new Date, !0 == !document.hidden ? this.page_show_status = !0 : this.page_show_status = !1, this.url = location.href, this.title = document.title }, PageLeave.prototype.pageEndHandler = function () { if (!0 !== this.page_hidden_status) { var e = this.getPageLeaveProperties(); !1 === this.page_show_status && delete e.event_duration, this.page_show_status = !1, this.page_hidden_status = !0, this.isCollectUrl(this.url) && this.sd.track("$WebPageLeave", e), this.refreshPageEndTimer(), this.delHeartBeatData() } }, PageLeave.prototype.addEventListener = function () { this.addPageStartListener(), this.addPageSwitchListener(), this.addSinglePageListener(), this.addPageEndListener() }, PageLeave.prototype.addPageStartListener = function () { var e = this; "onpageshow" in window && this._.addEvent(window, "pageshow", function () { e.pageStartHandler(), e.hiddenStatusHandler() }) }, PageLeave.prototype.isCollectUrl = function (e) { return "function" != typeof this.option.isCollectUrl || ("string" != typeof e || "" === e || this.option.isCollectUrl(e)) }, PageLeave.prototype.addSinglePageListener = function () { var e = this; this.sd.ee && this.sd.ee.spa.prepend("switch", function (t) { t !== location.href && (e.url = t, e.pageEndHandler(), e.stopHeartBeatInterval(), e.current_page_url = e.url, e.pageStartHandler(), e.hiddenStatusHandler(), e.addHeartBeatInterval()) }) }, PageLeave.prototype.addPageEndListener = function () { var e = this; this._.each(["pagehide", "beforeunload", "unload"], function (t) { "on" + t in window && e._.addEvent(window, t, function () { e.pageEndHandler(), e.stopHeartBeatInterval() }) }) }, PageLeave.prototype.addPageSwitchListener = function () { var e = this; this._.listenPageState({ visible: function () { e.pageStartHandler(), e.hiddenStatusHandler(), e.addHeartBeatInterval() }, hidden: function () { e.url = location.href, e.title = document.title, e.pageEndHandler(), e.stopHeartBeatInterval() } }) }, PageLeave.prototype.addHeartBeatInterval = function () { this._.localStorage.isSupport() && this.startHeartBeatInterval() }, PageLeave.prototype.startHeartBeatInterval = function () { var e = this; this.heartbeat_interval_timer && this.stopHeartBeatInterval(); var t = !0; this.isCollectUrl(this.url) || (t = !1), this.heartbeat_interval_timer = setInterval(function () { t && e.saveHeartBeatData() }, this.heartbeat_interval_time), t && this.saveHeartBeatData("is_first_heartbeat"), this.reissueHeartBeatData() }, PageLeave.prototype.stopHeartBeatInterval = function () { clearInterval(this.heartbeat_interval_timer), this.heartbeat_interval_timer = null }, PageLeave.prototype.saveHeartBeatData = function (e) { var t = this.getPageLeaveProperties(), a = new Date; t.$time = a, "is_first_heartbeat" === e && (t.event_duration = 3.14); var i = this.sd.kit.buildData({ type: "track", event: "$WebPageLeave", properties: t }); i.heartbeat_interval_time = this.heartbeat_interval_time, this.sd.store.saveObjectVal(this.storage_name + "-" + this.page_id, i) }, PageLeave.prototype.delHeartBeatData = function (e) { this._.localStorage.isSupport() && this._.localStorage.remove(e || this.storage_name + "-" + this.page_id) }, PageLeave.prototype.reissueHeartBeatData = function () { for (var e = window.localStorage.length - 1; e >= 0; e--) { var t = window.localStorage.key(e); if (t && t !== this.storage_name + "-" + this.page_id && 0 === t.indexOf(this.storage_name + "-")) { var a = this.sd.store.readObjectVal(t); this._.isObject(a) && 1 * new Date - a.time > a.heartbeat_interval_time + 5e3 && (delete a.heartbeat_interval_time, a._flush_time = (new Date).getTime(), this.sd.kit.sendData(a), this.delHeartBeatData(t)) } } }, PageLeave.prototype.getPageLeaveProperties = function () { var e = (+new Date - this.start_time) / 1e3; (isNaN(e) || e < 0 || e > this.max_duration) && (e = 0), e = Number(e.toFixed(3)); var t = this._.getReferrer(this.current_page_url), a = document.documentElement && document.documentElement.scrollTop || window.pageYOffset || document.body && document.body.scrollTop || 0; a = Math.round(a) || 0; var i = { $title: this.title, $url: this._.getURL(this.url), $url_path: this._.getURLPath(this._.URL(this.url).pathname), $referrer_host: t ? this._.getHostname(t) : "", $referrer: t, $viewport_position: a }; return 0 !== e && (i.event_duration = e), i = this._.extend(i, this.option.custom_props) }; var pageLeave = new PageLeave, index = createPlugin(pageLeave, "PageLeave", "sdkReady"); export default index;
// import { loadSvga } from '@spark/svgaplayer'
// import * as FYGE from 'fyge';
// import { Howl } from 'howler';
// import { RES_PATH } from '../../sparkrc'
// const RES_PATH = '../assets';
// const require('svgaplayerweb')
// import SVGA from "svgaplayerweb";
// import {Downloader, Parser} from 'svga.lite'
// import { DB } from 'svga'
// const disableWorker = !!window['svga_parser_disable_worker']
// import assetsList from 'x../assetList.json';
// const cache = {}
// const loadings = {}
const loaderCache = []
// const svgaMap = [];
/**
* 预加载资源(/png|jpg|jpeg|svga|spi|json|mp3|wav/)
* @param {string[]} urlList 资源地址列表
* @param {number} batchNum 每批并行加载的资源个数(一般来说该数字越大整体加载速度越快,但加载前期会更卡顿)
* @param {Function} [onProgress] 加载进度回调,每加载完一个资源回调一次,入参为进度值(0,1]
* @returns {Promise} 返回一个只会resolve(loadedData)的promise,loadedData保存了所有预加载好的资源,可通过相对路径索引
* @example
* //例
* const loadedData = await PreloadAsset(urlList, 10, onProgress);
* const image = loadedData['image/fish.png'];
* const svgaData = loadedData['svga/fish.svga'];
* const spiData = loadedData['spine/fish.spi'];
* const lottieData = loadedData['lottie/fish.json'];
*/
export function preloadAsset(urlList, batchNum, onProgress) {
return new Promise((resolve) => {
// assetsList.preLoadImg.forEach(item => {
// require(item)
// });
// const newList = urlList.concat(assetsList.preLoadImg)
let _batchNum = batchNum
/** 要加载资源总数 */
const totalNum = urlList.length;
/** 要加载的资源索引 */
let assetIndex = -1;
/** 已加载完毕的资源个数 */
let loadedNum = 0;
/** 存放加载好的数据,用地址索引 */
const loadedData = {};
/** 加载逻辑 */
const doLoad = async () => {
if (loadedNum >= totalNum) {
totalNum == 0 && onProgress && onProgress(1); // 无加载资源时,即为假loading
resolve(loadedData); // 加载完毕
} else {
assetIndex++;
if (assetIndex >= totalNum) return
const key = urlList[assetIndex];
// let url = RES_PATH + urlList[assetIndex];
let url = urlList[assetIndex];
// if(url.indexOf('svga') === -1) {
// url = RES_PATH + urlList[assetIndex];
// }
const result = await loadOneAsset(url);
if (!result) {
console.warn('加载异常', url);
}
loadedData[key] = result;
loadedNum++;
onProgress && onProgress(loadedNum / totalNum);
doLoad();
}
}
_batchNum = batchNum || 1;
for (let index = 0; index < _batchNum; index++) {
doLoad();
}
})
}
/**
* 加载一个资源
* @param {string} url 地址
*/
async function loadOneAsset(url) {
const fileType = url.split('.').pop();
switch (true) {
case (/png|jpg|jpeg/).test(fileType):
return await loadOneImg(url);
case (/svga/).test(fileType):
// return await loadOneSvga(url);
// return await doLoadSvga(url);
// case (/spi/).test(fileType):
// return await loadOneSpi(url);
// case (/json/).test(fileType):
// return await loadOneJson(url);
// case (/mp3|wav/).test(fileType):
// return await loadOneAudio(url);
default:
console.warn('非法资源', url);
return false;
}
}
/**
* 加载一张图片
* @param {string} url 地址
*/
function loadOneImg(url) {
return new Promise(resolve => {
const img = new Image();
img.onload = () => {
resolve(img);
// console.warn('成功加载')
}
img.onerror = err => {
console.warn('load', url, err);
resolve(false)
};
// img.crossOrigin = 'Anonymous'
img.src = url;
document.body.appendChild(img)
img.style.position = 'fixed'
img.style.width = '0'
img.style.height = '0'
img.style.left = '-99999px'
})
}
/**
* 加载一个svga
* @param {string} url 地址
*/
// async function doLoadSvga(url) {
// let loader = loaderCache.length > 0 ? loaderCache.pop() : {
// downloader: new Downloader(),
// // @ts-ignore
// parser: new Parser({disableWorker}),
// }
// const {downloader, parser} = loader
// const fileData = await downloader.get(url)
// const svgaData = await parser.do(fileData)
// for (let {frames} of svgaData.sprites) {
// for (let {transform} of frames) {
// transform._tx = transform.tx
// transform._ty = transform.ty
// }
// }
// loaderCache.push(loader)
// console.warn('chenggong svga', url)
// return svgaData
// }
// /**
// * 加载一个spine
// * @param {string} url 地址
// */
// function loadOneSpi(url) {
// return new Promise(resolve => {
// FYGE.loadSpine(url, spineData => {
// resolve(spineData);
// }, err => {
// console.warn('load', url, err);
// resolve(false);
// })
// })
// }
// /**
// * 加载一个Json
// * @param {string} url 地址
// */
// function loadOneJson(url) {
// return new Promise(resolve => {
// FYGE.GlobalLoader.loadJson((result, res) => {
// if (result) {
// resolve(res);
// } else {
// console.warn('load fail', url);
// resolve(false);
// }
// }, url)
// })
// }
// /**
// * 加载一个音频
// * @param {string} url 地址
// */
// function loadOneAudio(url) {
// return new Promise(resolve => {
// const sound = new Howl({
// src: url,
// onload: () => resolve(sound),
// onloaderror: err => {
// console.warn('load fail', url, err);
// resolve(false);
// },
// });
// })
// }
This diff is collapsed.
export const healthy = {
"type-2": {
title: "高风险人群",
feature: ['每天吸烟/饮酒', 'BMI≥28', '重度压力', '慢性病未控制', '家族多重重疾史'],
advice: [
'1.尽快就医或联系健康管理师,制定戒烟/减重/慢性病管理计划;',
'2.每周监测血压/血糖并记录;',
'3.坚持每日运动30分钟(如快走),减少久坐;',
'4.重度压力者需优先心理咨询(推荐认知行为疗法)。'
]
},
"type-1": {
title: "中风险人群",
feature: ['超重(BMI 24-27.9)', '偶尔吸烟/饮酒', '中度压力', '家族单病种病史'],
advice: [
'1.每周保持一定的运动量,进一步减少吸烟/饮酒;',
'2.增加蔬果摄入量,例如可以用用坚果替代零食;',
'3.学习压力管理技巧;',
'4.每半年针对性体检。'
]
},
"type-0": {
title: "低风险人群",
feature: ['BMI正常', '无不良习惯', '压力水平低', '规律运动'],
advice: [
'1.保持每周多次运动(推荐游泳或瑜伽);',
'2.每年1次全面体检(重点关注甲状腺、肝肾功能);',
'3.维持每周的社交活动,预防认知衰退;',
]
}
}
export const oldHealthy = {
"type-1": {
title: '记忆力较好',
score: '0-20'
},
"type-2": {
title: '记忆力开始衰退',
score: '20-40'
},
"type-3": {
title: '记忆力下降较为严重',
score: '40以上'
}
}
export const character = {
"type-1": {
title: "完美型",
label: '完美主义者',
persons: [
{
name: '周瑜',
desc: '三国时期军事家,追求卓越与战术完美,因“既生瑜何生亮”体现对自身及他人高标准的执念。',
},
{
name: '切·格瓦拉',
desc: '革命家,坚持理想主义,以严格的道德准则推动社会变革,但常因现实与理想的落差感到挫败。',
},
{
name: '孔子',
desc: '儒家创始人,强调礼法与秩序,致力于道德规范的完善,体现了1号对原则的坚守。',
},
]
},
"type-2": {
title: "助人型",
label: '给予者',
persons: [
{
name: '雷锋',
desc: '以无私奉献闻名,通过帮助他人实现自我价值,典型2号的利他主义特质。',
},
{
name: '特蕾莎修女',
desc: '(搜索结果未直接提及,但符合2号特征)毕生服务贫困人群,以关爱行动践行2号的核心动机。',
},
{
name: '蜘蛛侠(虚构角色)',
desc: '漫威英雄,象征“能力越大责任越大”,通过拯救他人获得存在意义。',
},
]
},
"type-3": {
title: "成就型",
label: '实干家',
persons: [
{
name: '诸葛亮',
desc: '三国谋士,以高效执行力和目标导向著称,善于通过成就证明自身价值。',
},
{
name: '马克·扎克伯格',
desc: 'Facebook创始人,追求社会影响力与商业成功,体现3号的竞争意识和效率至上。',
},
{
name: '马云',
desc: '阿里巴巴创始人,擅长激励团队并推动目标达成,典型3号的领导风格。',
},
]
},
"type-4": {
title: "自我型",
label: '艺术家',
persons: [
{
name: '张国荣',
desc: '香港歌手演员,情感细腻且追求独特艺术表达,常陷入理想与现实的矛盾。',
},
{
name: '林黛玉(虚构角色)',
desc: '《红楼梦》人物,多愁善感,通过诗歌抒发内心孤独,体现4号的深度情感需求。',
},
{
name: '弗里达·卡罗',
desc: '(搜索结果未直接提及)墨西哥画家,作品充满痛苦与自我探索,符合4号的悲剧美学倾向。',
},
]
},
"type-5": {
title: "思考型",
label: '观察者',
persons: [
{
name: '爱因斯坦',
desc: '物理学家,痴迷于科学研究,通过逻辑分析探索宇宙奥秘,典型5号的求知欲。',
},
{
name: '温伯格',
desc: 'IT管理大师,专注技术研究,社交回避,体现5号对知识与独立的追求。',
},
{
name: '周星驰',
desc: '喜剧演员,擅长以独特视角解构生活,内心世界丰富但社交疏离。',
},
]
},
"type-6": {
title: "忠诚型",
label: '怀疑论者',
persons: [
{
name: '关羽',
desc: '三国名将,忠义无双,对刘备团队极度忠诚,体现6号的信任与风险防范意识。',
},
{
name: '李达康(虚构角色)',
desc: '《人民的名义》角色,谨慎务实,对体制既依赖又质疑,反映6号的矛盾心理。',
},
{
name: 'J.K.罗琳',
desc: '(搜索结果未提及)《哈利·波特》作者,逆境中坚持写作,体现6号在压力下的韧性。',
},
]
},
"type-7": {
title: "活跃型",
label: '享乐主义者',
persons: [
{
name: '陈冠希',
desc: '艺人,热衷新鲜事物与自由生活方式,逃避束缚,典型7号的享乐倾向。',
},
{
name: '老顽童(虚构角色)',
desc: '《射雕英雄传》人物,追求玩乐与冒险,拒绝责任,体现7号的逃避心理。',
},
{
name: '理查德·布兰森',
desc: '维珍集团创始人,冒险精神与多元化兴趣,符合7号对新鲜体验的渴望。',
},
]
},
"type-8": {
title: "领袖型",
label: '挑战者',
persons: [
{
name: '曹操',
desc: '三国枭雄,强势果断,通过掌控权力实现目标,典型8号的支配欲。',
},
{
name: '半泽直树(虚构角色)',
desc: '日剧主角,以“以牙还牙”对抗不公,展现8号的正义感与对抗性。',
},
{
name: '撒切尔夫人',
desc: '英国前首相,铁腕政治风格,体现8号对权威的掌控与执行力。',
},
]
},
"type-9": {
title: "和平型",
label: '调停者',
persons: [
{
name: '周恩来',
desc: '外交家,以温和斡旋化解矛盾,西安事变中平衡各方利益,典型9号的和谐导向。',
},
{
name: '尼尔森·曼德拉',
desc: '南非前总统,倡导种族和解,通过非暴力沟通实现和平,体现9号的包容性。',
},
{
name: '甘地',
desc: '印度国父,以非暴力抵抗推动独立,追求集体和谐与社会稳定。',
},
]
}
}
export const RES_INFO = {
healthy: healthy,
oldHealthy: oldHealthy,
character: character
}
import sensors from 'sa-sdk-javascript';
import { ACTIVITY_SOURCE_CHANNEL, SYS_SOURCE_CHANNEL } from './constants';
import pageleave from './pageleave';
// import { getUrlParam } from './utils';
export const initSensors = (info) => {
sensors.init({
server_url: CFG.sensorUrl,
is_track_single_page: true,
show_log: true,
heatmap: {
clickmap: 'default',
scroll_notice_map: 'not_collect',
collect_tags: {
div: true
},
},
});
sensors.login(info?.unionid);
const shareTypeMap = {
1: "客户邀请",
2: "业务员邀请"
}
const skinId = getUrlParam("skinId");
// 本次没区分业务员/客户 就null
const shareType = !!skinId ? shareTypeMap[skinId] : null;
const publicObjec = Object.assign({
currentUrl: location.href,
referrer: document.referrer,
unionid: info?.unionId,
openid: info?.openId,
miniOpenid: info?.miniOpenid,
officerOrEmp: info?.officerOrEmp,
subscribeFlg: info?.subscribeFlg,
programLogin: info?.programLogin,
userLevel: info?.userLevel,
source: CFG.channel,
source_channel: CFG.channel,
userAccount: '太平洋寿险小程序',
systemName: '寿险2013版微信公众平台',
// activityName: CFG.activityName,
functionalpartition: "增值服务",
service_name: 'TODO',
// activityId: '25Searchcharacters',
// c_date: "2025/06/16-2099/12/31",
activitySource: ACTIVITY_SOURCE_CHANNEL[CFG.channel] || "",
sysSourceName: SYS_SOURCE_CHANNEL[CFG.channel] || "",
friendDistinctId: getUrlParam("uid") || "",
shareMark: !!getUrlParam("uid") ? "是" : "否",
shareType: shareType,
empNp: info?.empNp,
friendOpenId: info?.friendOpenId,
empno: info?.newEmpNo,
friendEmpNp: info?.friendEmpNp,
friendEmpNo: info?.friendEmpNo,
wxNickName: info?.nickname,
sex: info?.sex,
age: info?.age,
province: info?.province,
memberAttribution: info?.memberAttribution,
memberLevel: info?.customLevel
}, window['__tbSensorsObj__']);
sensors.registerPage(publicObjec);
sensors.quick('autoTrack');
};
export const pageLeave = (pagaName, duration) => {
sensors.use(pageleave, {
custom_props: {
pagaName
},
heartbeat_intervaltime: duration,
max_duration: duration * 24 * 60 * 60,
isCollectUrl: function (url) {
return true
}
})
}
/**
* 页面曝光埋点
* @param {string} eventName
* @param {{pageName:string,activityName:string,prize:string}} option
*/
export const sensorMdExpouse = (eventName, option) => {
console.log('神策曝光', eventName, option);
sensors.track(eventName, option);
};
/**
* 页面点击埋点
* @param {string} eventName
* @param {{pageName:string,activityName:string,buttonName:string,prize:string}} option
*/
export const sensorMdClick = (eventName, option) => {
console.log('神策点击', eventName, option);
sensors.track(eventName, option);
};
import { isYunApp } from ".";
/**
* 获取当前皮肤id
* @returns
*/
export const GetCurrSkinId = () => {
// eslint-disable-next-line no-useless-escape
const matched = location.pathname.match(/\/([^\/]*).html/);
const currSkinId = matched ? matched && matched[1] : ''
console.log('当前皮肤id', currSkinId)
return currSkinId
}
export const getCustomShareId = () => {
const matched = location.href.match(/\/share\?id=(.*)/);
const shareId = matched ? matched && matched[1] : '';
console.log('自定义活动页id', shareId);
return shareId;
};
import QRCode from 'qrcode'
import modalStore from "../store/modal";
export async function getQRCode(url) {
const _myQRCode = await QRCode.toDataURL(url)
return _myQRCode
}
/**
* @description: 函数节流,普通防连点
* @param {(Function, number?)}
* @return {Function}
*/
export const _throttle = (fun, delay = 2000) => {
let last, deferTimer;
return function () {
const now = +new Date();
if (last && now < last + delay) {
clearTimeout(deferTimer);
deferTimer = setTimeout(() => {
last = now;
}, delay);
} else {
last = now;
fun.apply(this, arguments);
}
};
};
// 计算1970/1/1 距今的秒数
export const calcSecond = () => {
const lastStamp = new Date(1970, 1, 1).getTime()
const nowStamp = new Date().getTime()
const seconds = Math.floor((nowStamp - lastStamp) / 1000)
console.error("看看我的秒数", seconds)
return seconds
}
export const randomStr = (length = 16) => {
let str = '';
let strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
const max = strPol.length;
for(let i = 0; i < length; i++) {
str += strPol[Math.floor(Math.random() * max)]
}
// console.error("看看我的随机串", str)
return str
}
export function waitTime(time){
return new Promise((resolve)=>{
setTimeout(() => {
resolve();
}, time);
});
}
export const convertImageToCanvas = (image) => {
var canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
canvas.getContext("2d").drawImage(image, 0, 0);
return canvas;
};
export const url2Base64 = (src) => {
return new Promise((resolve) => {
// const imgDom = document.querySelector("#posterCom");
const img = new Image();
img.setAttribute("crossOrigin", "anonymous");
img.src = src;
img.onload = () => {
const canvas = convertImageToCanvas(img);
const url = canvas.toDataURL("image/png");
// imgDom.append(img);
img.style.className = "pic";
// console.log(url.replace(/(data:image\/png;base64,)/g, ''))
resolve(url);
};
img.onerror = () => {
resolve("");
};
});
}
/**
* @description: 支持异步函数的节流,防止接口时间太长击穿防连点
* @return {Function}
* @param fun
* @param delay
*/
export const _asyncThrottle = (fun, delay = 2000) => {
let last, deferTimer;
let canClick = true;
return function () {
const now = Date.now();
if (!canClick) return;
if (last && now < last + delay) {
// clearTimeout(deferTimer);
// deferTimer = setTimeout(() => {
// last = now;
// }, delay);
} else {
last = now;
const ps = fun.apply(this, arguments);
if (ps instanceof Promise) {
canClick = false;
ps.finally(() => {
canClick = true;
});
}
}
};
};
/**
* 日期格式化
* @param date 接收可以被new Date()方法转换的内容
* @param format 字符串,需要的格式例如:'yyyy/MM/dd hh:mm:ss'
* @returns {String}
*/
export const dateFormatter = (date, format = "yyyy/MM/dd") => {
if (!date) return "-";
let _date = date
let _format = format
_date = new Date(
typeof date === "string" && isNaN(date)
? date.replace(/-/g, "/")
: Number(date)
);
const o = {
"M+": _date.getMonth() + 1,
"d+": _date.getDate(),
"h+": _date.getHours(),
"m+": _date.getMinutes(),
"s+": _date.getSeconds(),
"q+": Math.floor((_date.getMonth() + 3) / 3),
S: _date.getMilliseconds(),
};
if (/(y+)/.test(_format)) {
_format = format.replace(
RegExp.$1,
(date.getFullYear() + "").substr(4 - RegExp.$1.length)
);
}
for (const k in o) {
if (new RegExp("(" + k + ")").test(_format)) {
_format = _format.replace(
RegExp.$1,
RegExp.$1.length === 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length)
);
}
}
return _format;
};
/**
* 千分位
*/
export const formatThousand = (num) => {
var reg = /\d{1,3}(?=(\d{3})+$)/g;
return (num + '').replace(reg, '$&,');
}
\ No newline at end of file
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import postcssPluginPx2rem from "postcss-plugin-px2rem"
import { viteMockServe } from 'vite-plugin-mock'
import fs from 'fs';
import path, {resolve} from 'path'
import legacy from '@vitejs/plugin-legacy';
import { createHtmlPlugin } from 'vite-plugin-html'
// 使用模板的话需要对html模版进行一些处理,加一些占位符
const newParams = {
minify:true,
pages:[
// 第一个页面的配置
{
filename: "index.html",
template: "./index.html",
entry: "./src/main.jsx",
},
]
}
//配置参数
const px2remOptions = {
rootValue: 100, //换算基数, 默认100 ,也就是1440px ,这样的话把根标签的字体规定为1rem为50px,这样就可以从设计稿上量出多少个px直接在代码中写多少px了
unitPrecision: 5, //允许REM单位增长到的十进制数字,其实就是精度控制
// propWhiteList: [], // 默认值是一个空数组,这意味着禁用白名单并启用所有属性。
// propBlackList: [], // 黑名单
// exclude:false, //默认false,可以(reg)利用正则表达式排除某些文件夹的方法,例如/(node_module)/ 。如果想把前端UI框架内的px也转换成rem,请把此属性设为默认值
// selectorBlackList: [], //要忽略并保留为px的选择器
// ignoreIdentifier: false, //(boolean/string)忽略单个属性的方法,启用ignoreidentifier后,replace将自动设置为true。
// replace: true, // (布尔值)替换包含REM的规则,而不是添加回退。
mediaQuery: false, //(布尔值)允许在媒体查询中转换px
minPixelValue: 0 //设置要替换的最小像素值(3px会被转rem)。 默认 0
}
// https://vitejs.dev/config/
export default defineConfig({
define:{
__BUILD_TIME__: JSON.stringify(Date.now())
},
base: './',
plugins: [
react({
babel: {
plugins: [
["@babel/plugin-proposal-decorators", { legacy: true }],
["@babel/plugin-proposal-class-properties", { loose: true }],
],
},
}),
viteMockServe({
mockPath: 'mock', //mock文件路径,在根路径下创建一个mock文件
// 是否实时更新
watchFiles: true,
localEnabled: true, //mock开关
prodEnabled: false, //生产环境下为false,这样就不会被打包到生产包中
ignore: /^\_/, //忽略开始_路径
}),
legacy(),
createHtmlPlugin(newParams)
],
css: {
postcss: {
plugins: [postcssPluginPx2rem(px2remOptions)]
},
preprocessorOptions: {
less: {
javascriptEnabled: true, // 支持内联 JavaScript
modifyVars: { // 更改主题
}
}
}
},
server: {
host: true,
proxy: {
'/api': {
target: 'https://unionpay-task.duibatest.com.c/api',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
// 其他可选配置项
}
}
},
build: {
target: "es2015",
rollupOptions: {
input: {
'index': './src/main.jsx',
},
},
},
})
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