Commit 7af2c21d authored by 蒋佳奇's avatar 蒋佳奇

feat: Frist Version

parents
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
registry = http://npm.dui88.com/
\ No newline at end of file
# node
# Version v22
FROM duiba-habor-registry.cn-hangzhou.cr.aliyuncs.com/duiba_front/node:22.14.0
MAINTAINER op@duiba.com.cn
ARG appname
ARG NODE_ENV
RUN echo "export LANG=en_US.UTF-8" && echo "Asia/Shanghai" > /etc/timezone
ENV LANG='en_US.UTF-8'
RUN mkdir /root/duiba-deploy/
ADD ./duiba-deploy /root/duiba-deploy/
WORKDIR /root/duiba-deploy/
#define entry point which will be run first when the container starts up
ENTRYPOINT node server
\ No newline at end of file
# Tuia-Manager-System-Demo
此工程为推啊后台管理系统DEMO,基于React + TypeScript + Vite + Mobx搭建。
[TOC]
## 项目结构
**工程目录结构**
```
tuia-manager-system-demo
├── dist # 构建目录
├── mock # 模拟数据
├── server # 部署脚本
├── src
│   ├── apis # 接口服务
│   ├── components
│   │ ├── common # 公共组件库
│   │ ├── **/* # 业务组件库(不接入autoImport)
│   ├── constants # 常量
│   ├── hooks # 常用hooks
│   ├── layouts # 布局组件(不接入autoImport)
│   ├── pages # 页面组件(已接入文件系统路由)
│   ├── stores # mobx store
│ │   utils # 工具库
│ │   main.tsx # 入口文件
├── README.md
└── vite.config.ts
```
## Proxy
### Yapi-MOCK助手插件
1. 安装YAPI-MOCK助手(https://marketplace.visualstudio.com/items?itemName=Hidetoxic.yapi-mock-helper)
2. 在yapi-mock.config.json中指定项目代理服务器端口
3. 在vite.config.ts的server.proxy指定代理地址为本地指定端口(demo端口为10089,建议fork后修改)
4. 启动项目后,从资源管理器,启动YAPI-MOCK助手
![alt text](https://yun.dui88.com/jjq/images/d2skfpns6sl6jgf1rylpd.png)
5. 通过VSCode状态栏,以切换代理地址
![alt text](https://yun.dui88.com/jjq/images/e5b63_q7vskpu9_v3s14_.png)
![alt text](https://yun.dui88.com/jjq/images/sxemnih-qnsdesqkhaxi8.png)
Tips: 虽然目前无法配置Yapi,但启用【YAPI-MOCK缓存模式(默认)】时,可通过手动维护mock文件夹目录,使用本地代理。支持热更新。
### vite代理
你也可以通过修改vite.config.ts的server.proxy配置,自定义代理。
## Auto Import
除业务组件、布局组件(见目录结构)外,项目绝大部份类型声明及变量定义,使用unplugin-auto-import自动导入,无需手动引入。
tips: 请注意开发过程中终端输出的错误提示,<span style="color:red">[重复导入错误]</span>。此错误会导致构建失败。
## 文件系统路由
此工程使用文件系统路由,参考[nuxt路由](https://nuxt.zhcndoc.com/docs/getting-started/routing)
## TODO
- 组件库完善: 大家在系统开发过程中,如编写了通用的组件,请同步到demo中。
\ No newline at end of file
/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// noinspection JSUnusedGlobalSymbols
// Generated by unplugin-auto-import
// biome-ignore lint: disable
export {}
declare global {
const Button: typeof import('antd')['Button']
const Card: typeof import('antd')['Card']
const Form: typeof import('antd')['Form']
const Input: typeof import('antd')['Input']
const Layout: typeof import('antd')['Layout']
const Link: typeof import('react-router-dom')['Link']
const Menu: typeof import('antd')['Menu']
const NavLink: typeof import('react-router-dom')['NavLink']
const Navigate: typeof import('react-router-dom')['Navigate']
const Observer: typeof import('mobx-react-lite')['Observer']
const Outlet: typeof import('react-router-dom')['Outlet']
const REGEX: typeof import('pixiu-number-toolkit')['REGEX']
const Result: typeof import('antd')['Result']
const Role: typeof import('./src/constants/enums/index')['Role']
const Route: typeof import('react-router-dom')['Route']
const Routes: typeof import('react-router-dom')['Routes']
const Rules: typeof import('./src/utils/REG')['Rules']
const Spin: typeof import('antd')['Spin']
const UserList: typeof import('./src/constants/userList')['UserList']
const action: typeof import('mobx')['action']
const autorun: typeof import('mobx')['autorun']
const axios: typeof import('axios')['default']
const buildREG: typeof import('./src/utils/REG')['buildREG']
const changeDate: typeof import('./src/utils/date')['changeDate']
const computed: typeof import('mobx')['computed']
const cookie: typeof import('./src/utils/cookie')['default']
const counterStore: typeof import('./src/stores/counterStore')['counterStore']
const createRef: typeof import('react')['createRef']
const createRequester: typeof import('./src/utils/request')['createRequester']
const digitUppercase: typeof import('./src/utils/money')['digitUppercase']
const extendObservable: typeof import('mobx')['extendObservable']
const fenToYuan: typeof import('./src/utils/money')['fenToYuan']
const flow: typeof import('mobx')['flow']
const flowResult: typeof import('mobx')['flowResult']
const forwardRef: typeof import('react')['forwardRef']
const getCustomList: typeof import('./src/apis/index')['getCustomList']
const getFailedRecords: typeof import('./src/apis/index')['getFailedRecords']
const getRealTime: typeof import('./src/apis/index')['getRealTime']
const getTopOnlineApp: typeof import('./src/apis/index')['getTopOnlineApp']
const getUserById: typeof import('./src/apis/user/index')['getUserById']
const getUserList: typeof import('./src/apis/user/index')['getUserList']
const intercept: typeof import('mobx')['intercept']
const isEmail: typeof import('./src/utils/REG')['isEmail']
const isNothing: typeof import('./src/utils/index')['isNothing']
const lazy: typeof import('react')['lazy']
const liToYuan: typeof import('./src/utils/money')['liToYuan']
const makeAutoObservable: typeof import('mobx')['makeAutoObservable']
const makeObservable: typeof import('mobx')['makeObservable']
const memo: typeof import('react')['memo']
const message: typeof import('antd')['message']
const observable: typeof import('mobx')['observable']
const observe: typeof import('mobx')['observe']
const observer: typeof import('mobx-react-lite')['observer']
const onBecomeObserved: typeof import('mobx')['onBecomeObserved']
const onBecomeUnobserved: typeof import('mobx')['onBecomeUnobserved']
const onReactionError: typeof import('mobx')['onReactionError']
const permission: typeof import('./src/utils/permission')['default']
const precent: typeof import('./src/utils/number')['precent']
const precentAddSuffix: typeof import('./src/utils/number')['precentAddSuffix']
const prefixYuan: typeof import('./src/utils/money')['prefixYuan']
const rangePresets: typeof import('./src/utils/date')['rangePresets']
const reaction: typeof import('mobx')['reaction']
const record2options: typeof import('./src/utils/index')['record2options']
const request: typeof import('./src/utils/request')['default']
const runInAction: typeof import('mobx')['runInAction']
const smartFenToYuan: typeof import('./src/utils/money')['smartFenToYuan']
const startTransition: typeof import('react')['startTransition']
const theme: typeof import('antd')['theme']
const toJS: typeof import('mobx')['toJS']
const unitYuan: typeof import('./src/utils/money')['unitYuan']
const useCallback: typeof import('react')['useCallback']
const useContext: typeof import('react')['useContext']
const useDebugValue: typeof import('react')['useDebugValue']
const useDeferredValue: typeof import('react')['useDeferredValue']
const useEffect: typeof import('react')['useEffect']
const useHref: typeof import('react-router-dom')['useHref']
const useId: typeof import('react')['useId']
const useImperativeHandle: typeof import('react')['useImperativeHandle']
const useInRouterContext: typeof import('react-router-dom')['useInRouterContext']
const useInsertionEffect: typeof import('react')['useInsertionEffect']
const useLayoutEffect: typeof import('react')['useLayoutEffect']
const useLinkClickHandler: typeof import('react-router-dom')['useLinkClickHandler']
const useLocalObservable: typeof import('mobx-react-lite')['useLocalObservable']
const useLocation: typeof import('react-router-dom')['useLocation']
const useMemo: typeof import('react')['useMemo']
const useNavigate: typeof import('react-router-dom')['useNavigate']
const useNavigationType: typeof import('react-router-dom')['useNavigationType']
const useOutlet: typeof import('react-router-dom')['useOutlet']
const useOutletContext: typeof import('react-router-dom')['useOutletContext']
const useParams: typeof import('react-router-dom')['useParams']
const useReducer: typeof import('react')['useReducer']
const useRef: typeof import('react')['useRef']
const useRequest: typeof import('./src/hooks/useRequest')['default']
const useResolvedPath: typeof import('react-router-dom')['useResolvedPath']
const useRoutes: typeof import('react-router-dom')['useRoutes']
const useSearchParams: typeof import('react-router-dom')['useSearchParams']
const useState: typeof import('react')['useState']
const useSyncExternalStore: typeof import('react')['useSyncExternalStore']
const useTransition: typeof import('react')['useTransition']
const when: typeof import('mobx')['when']
const yuanToFen: typeof import('./src/utils/money')['yuanToFen']
const yuanToLi: typeof import('./src/utils/money')['yuanToLi']
}
// for type re-export
declare global {
// @ts-ignore
export type { UserEntity } from './src/apis/user/type'
import('./src/apis/user/type')
}
import jsConfig from '@tuia/eslint-config-common/global.js'
import reactConfig from '@tuia/eslint-config-common/react.js'
import tsConfig from '@tuia/eslint-config-common/typeScript.js'
import reactRefresh from 'eslint-plugin-react-refresh'
export default [...jsConfig, ...reactConfig, ...tsConfig, { ignores: ['dist'] }, reactRefresh.configs.vite]
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="https://yun.tuisnake.com/tuia/payment/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
{
"success": true,
"errorCode": null,
"desc": null,
"data": {
"diff": -6246.87,
"topIncreaseApp": [
{
"id": 98600,
"appName": "******",
"mediaOperation": "仵莹,王婷婷",
"currentValue": 14963.39,
"contrastValue": 9390.59,
"variation": 5572.8,
"proportion": -0.8921,
"sdkPv0": 1754.0,
"sdkPv1": 1088.0,
"sdkPvVariation": 666.0,
"sdkUvAfModulus": 0.8336024842655757,
"arcPsuAfModulus": 0.06348398537112174,
"lcParcAfModulus": 0.0110354064552087,
"plpPlcAfModulus": 1.618543503861416E-4,
"acPplpAfModulus": -0.09171626955770755,
"quotaList": [
"sdkUv"
]
},
{
"id": 97986,
"appName": "******",
"mediaOperation": "刘侠,朱文誓,汪俐娜,高瑜",
"currentValue": 1242.95,
"contrastValue": 285.89,
"variation": 957.06,
"proportion": -0.1532,
"sdkPv0": 0.0,
"sdkPv1": 3872.0,
"sdkPvVariation": -3872.0,
"sdkUvAfModulus": "NaN",
"arcPsuAfModulus": "NaN",
"lcParcAfModulus": "NaN",
"plpPlcAfModulus": "NaN",
"acPplpAfModulus": "NaN",
"quotaList": []
},
{
"id": 98064,
"appName": "******",
"mediaOperation": "张冰玉,罗嘉瑶,高瑜",
"currentValue": 951.68,
"contrastValue": 46.82,
"variation": 904.86,
"proportion": -0.1449,
"sdkPv0": 24684.0,
"sdkPv1": 1812.0,
"sdkPvVariation": 22872.0,
"sdkUvAfModulus": 0.7231745321207218,
"arcPsuAfModulus": -0.09612166015774935,
"lcParcAfModulus": 0.00851603735202846,
"plpPlcAfModulus": 0.006381495652369838,
"acPplpAfModulus": 0.16580627471713055,
"quotaList": [
"sdkUv"
]
},
{
"id": 77448,
"appName": "******",
"mediaOperation": "刘凯鑫,平雪芳,陆苏畅",
"currentValue": 1717.73,
"contrastValue": 920.66,
"variation": 797.07,
"proportion": -0.1276,
"sdkPv0": 0.0,
"sdkPv1": 0.0,
"sdkPvVariation": 0.0,
"sdkUvAfModulus": "NaN",
"arcPsuAfModulus": "NaN",
"lcParcAfModulus": "NaN",
"plpPlcAfModulus": "NaN",
"acPplpAfModulus": "NaN",
"quotaList": []
},
{
"id": 97946,
"appName": "******",
"mediaOperation": "刘思宇,王婷婷",
"currentValue": 2246.91,
"contrastValue": 1743.87,
"variation": 503.04,
"proportion": -0.0805,
"sdkPv0": 398.0,
"sdkPv1": 236.0,
"sdkPvVariation": 162.0,
"sdkUvAfModulus": 0.5911174280834033,
"arcPsuAfModulus": 0.0984166657048161,
"lcParcAfModulus": 0.012478264099955231,
"plpPlcAfModulus": 7.208500621620617E-4,
"acPplpAfModulus": -0.2972667920496633,
"quotaList": [
"sdkUv"
]
},
{
"id": 98063,
"appName": "******",
"mediaOperation": "张冰玉,王倩,罗嘉瑶,高瑜",
"currentValue": 703.46,
"contrastValue": 290.3,
"variation": 413.16,
"proportion": -0.0661,
"sdkPv0": 13518.0,
"sdkPv1": 9907.0,
"sdkPvVariation": 3611.0,
"sdkUvAfModulus": 0.5500477453522594,
"arcPsuAfModulus": -0.23177211626731192,
"lcParcAfModulus": -0.011280047205970254,
"plpPlcAfModulus": 0.006170630356702715,
"acPplpAfModulus": 0.2007294608177557,
"quotaList": [
"sdkUv",
"acPplp"
]
},
{
"id": 98076,
"appName": "******",
"mediaOperation": "刘思宇,王婷婷",
"currentValue": 380.69,
"contrastValue": 0.0,
"variation": 380.69,
"proportion": -0.0609,
"sdkPv0": 60.0,
"sdkPv1": 0.0,
"sdkPvVariation": 60.0,
"sdkUvAfModulus": "NaN",
"arcPsuAfModulus": "NaN",
"lcParcAfModulus": "NaN",
"plpPlcAfModulus": "NaN",
"acPplpAfModulus": "NaN",
"quotaList": []
},
{
"id": 97780,
"appName": "******",
"mediaOperation": "罗嘉瑶,高瑜",
"currentValue": 1784.1,
"contrastValue": 1404.79,
"variation": 379.31,
"proportion": -0.0607,
"sdkPv0": 770.0,
"sdkPv1": 577.0,
"sdkPvVariation": 193.0,
"sdkUvAfModulus": 0.6459639290359871,
"arcPsuAfModulus": -0.2710469099387849,
"lcParcAfModulus": 0.01376064956294883,
"plpPlcAfModulus": 3.7397530977757856E-4,
"acPplpAfModulus": 0.06885453615250178,
"quotaList": [
"sdkUv"
]
},
{
"id": 96319,
"appName": "******",
"mediaOperation": "刘凯鑫,陆苏畅",
"currentValue": 342.89,
"contrastValue": 0.0,
"variation": 342.89,
"proportion": -0.0549,
"sdkPv0": 0.0,
"sdkPv1": 0.0,
"sdkPvVariation": 0.0,
"sdkUvAfModulus": "NaN",
"arcPsuAfModulus": "NaN",
"lcParcAfModulus": "NaN",
"plpPlcAfModulus": "NaN",
"acPplpAfModulus": "NaN",
"quotaList": []
},
{
"id": 97885,
"appName": "******",
"mediaOperation": "陈艺艺",
"currentValue": 295.77,
"contrastValue": 0.0,
"variation": 295.77,
"proportion": -0.0473,
"sdkPv0": 210.0,
"sdkPv1": 0.0,
"sdkPvVariation": 210.0,
"sdkUvAfModulus": "NaN",
"arcPsuAfModulus": "NaN",
"lcParcAfModulus": "NaN",
"plpPlcAfModulus": "NaN",
"acPplpAfModulus": "NaN",
"quotaList": []
},
{
"id": 98685,
"appName": "******",
"mediaOperation": "王倩,罗嘉瑶,邓天书,陆苏畅,高瑜",
"currentValue": 789.08,
"contrastValue": 567.07,
"variation": 222.01,
"proportion": -0.0355,
"sdkPv0": 4971.0,
"sdkPv1": 3922.0,
"sdkPvVariation": 1049.0,
"sdkUvAfModulus": 0.6139821323078174,
"arcPsuAfModulus": 0.2408929690618504,
"lcParcAfModulus": 0.00562467457995597,
"plpPlcAfModulus": -2.4018620660129814E-4,
"acPplpAfModulus": 0.13926003784377486,
"quotaList": [
"sdkUv",
"arcPsu"
]
},
{
"id": 94654,
"appName": "******",
"mediaOperation": "张冰玉,王倩,罗嘉瑶,高瑜",
"currentValue": 202.06,
"contrastValue": 2.29,
"variation": 199.77,
"proportion": -0.032,
"sdkPv0": 21521.0,
"sdkPv1": 1452.0,
"sdkPvVariation": 20069.0,
"sdkUvAfModulus": 0.4185781563581576,
"arcPsuAfModulus": 0.4249971767250049,
"lcParcAfModulus": -0.020715985549402453,
"plpPlcAfModulus": 0.030376861641203293,
"acPplpAfModulus": -0.10533181972623178,
"quotaList": [
"sdkUv",
"arcPsu"
]
},
{
"id": 71092,
"appName": "******",
"mediaOperation": "刘凯鑫,常平凡,罗嘉瑶,陆苏畅",
"currentValue": 561.25,
"contrastValue": 368.71,
"variation": 192.54,
"proportion": -0.0308,
"sdkPv0": 0.0,
"sdkPv1": 0.0,
"sdkPvVariation": 0.0,
"sdkUvAfModulus": "NaN",
"arcPsuAfModulus": "NaN",
"lcParcAfModulus": "NaN",
"plpPlcAfModulus": "NaN",
"acPplpAfModulus": "NaN",
"quotaList": []
},
{
"id": 98687,
"appName": "******",
"mediaOperation": "刘侠,朱文誓,杨奕帆,汪俐娜,高瑜",
"currentValue": 496.2,
"contrastValue": 322.03,
"variation": 174.17,
"proportion": -0.0279,
"sdkPv0": 0.0,
"sdkPv1": 9411.0,
"sdkPvVariation": -9411.0,
"sdkUvAfModulus": "NaN",
"arcPsuAfModulus": "NaN",
"lcParcAfModulus": "NaN",
"plpPlcAfModulus": "NaN",
"acPplpAfModulus": "NaN",
"quotaList": []
},
{
"id": 90437,
"appName": "******",
"mediaOperation": "张冰玉,罗嘉瑶,高瑜",
"currentValue": 137.58,
"contrastValue": 1.19,
"variation": 136.39,
"proportion": -0.0218,
"sdkPv0": 1577.0,
"sdkPv1": 213.0,
"sdkPvVariation": 1364.0,
"sdkUvAfModulus": 0.44093660483217484,
"arcPsuAfModulus": 0.03975659975924599,
"lcParcAfModulus": 0.08374928516931086,
"plpPlcAfModulus": -0.028504694325077188,
"acPplpAfModulus": 0.40705281591419107,
"quotaList": [
"sdkUv",
"acPplp"
]
},
{
"id": 98347,
"appName": "******",
"mediaOperation": "刘侠,朱文誓,汪俐娜,高瑜",
"currentValue": 699.4,
"contrastValue": 649.52,
"variation": 49.88,
"proportion": -0.008,
"sdkPv0": 0.0,
"sdkPv1": 6554.0,
"sdkPvVariation": -6554.0,
"sdkUvAfModulus": "NaN",
"arcPsuAfModulus": "NaN",
"lcParcAfModulus": "NaN",
"plpPlcAfModulus": "NaN",
"acPplpAfModulus": "NaN",
"quotaList": []
},
{
"id": 77210,
"appName": "******",
"mediaOperation": "刘凯鑫",
"currentValue": 33.26,
"contrastValue": 0.0,
"variation": 33.26,
"proportion": -0.0053,
"sdkPv0": 0.0,
"sdkPv1": 0.0,
"sdkPvVariation": 0.0,
"sdkUvAfModulus": "NaN",
"arcPsuAfModulus": "NaN",
"lcParcAfModulus": "NaN",
"plpPlcAfModulus": "NaN",
"acPplpAfModulus": "NaN",
"quotaList": []
},
{
"id": 90708,
"appName": "******",
"mediaOperation": "张冰玉,罗嘉瑶,高瑜",
"currentValue": 55.83,
"contrastValue": 27.42,
"variation": 28.41,
"proportion": -0.0045,
"sdkPv0": 6523.0,
"sdkPv1": 1563.0,
"sdkPvVariation": 4960.0,
"sdkUvAfModulus": 0.6289955774710959,
"arcPsuAfModulus": -0.08935760238419373,
"lcParcAfModulus": -0.027399979771678216,
"plpPlcAfModulus": -0.008672829369122953,
"acPplpAfModulus": -0.24557401100390897,
"quotaList": [
"sdkUv"
]
},
{
"id": 96889,
"appName": "******",
"mediaOperation": "王婷婷",
"currentValue": 26.46,
"contrastValue": 2.65,
"variation": 23.81,
"proportion": -0.0038,
"sdkPv0": 0.0,
"sdkPv1": 0.0,
"sdkPvVariation": 0.0,
"sdkUvAfModulus": "NaN",
"arcPsuAfModulus": "NaN",
"lcParcAfModulus": "NaN",
"plpPlcAfModulus": "NaN",
"acPplpAfModulus": "NaN",
"quotaList": []
},
{
"id": 91000,
"appName": "******",
"mediaOperation": "平雪芳",
"currentValue": 26.3,
"contrastValue": 2.85,
"variation": 23.45,
"proportion": -0.0038,
"sdkPv0": 39.0,
"sdkPv1": 50.0,
"sdkPvVariation": -11.0,
"sdkUvAfModulus": -0.09590409198213108,
"arcPsuAfModulus": -0.16798119576444753,
"lcParcAfModulus": -0.06761755938072467,
"plpPlcAfModulus": -0.023411199644438888,
"acPplpAfModulus": 0.6450859532282578,
"quotaList": [
"acPplp"
]
},
{
"id": 97782,
"appName": "******",
"mediaOperation": "张冰玉,罗嘉瑶,高瑜",
"currentValue": 485.99,
"contrastValue": 470.87,
"variation": 15.12,
"proportion": -0.0024,
"sdkPv0": 169.0,
"sdkPv1": 147.0,
"sdkPvVariation": 22.0,
"sdkUvAfModulus": 0.45890145236754903,
"arcPsuAfModulus": -0.28232440589612545,
"lcParcAfModulus": -0.1508429423622133,
"plpPlcAfModulus": -1.4904864134425037E-5,
"acPplpAfModulus": 0.10791629450997774,
"quotaList": [
"sdkUv"
]
},
{
"id": 95984,
"appName": "******",
"mediaOperation": "张冰玉,罗嘉瑶,高瑜",
"currentValue": 13.5,
"contrastValue": 1.97,
"variation": 11.53,
"proportion": -0.0018,
"sdkPv0": 298.0,
"sdkPv1": 309.0,
"sdkPvVariation": -11.0,
"sdkUvAfModulus": 0.09490072860308561,
"arcPsuAfModulus": -0.13337513464916484,
"lcParcAfModulus": 0.055029492312625584,
"plpPlcAfModulus": 0.004242640567901196,
"acPplpAfModulus": 0.7124520038672228,
"quotaList": [
"acPplp"
]
},
{
"id": 93562,
"appName": "******",
"mediaOperation": "张冰玉,罗嘉瑶,高瑜",
"currentValue": 430.13,
"contrastValue": 422.59,
"variation": 7.54,
"proportion": -0.0012,
"sdkPv0": 21459.0,
"sdkPv1": 15141.0,
"sdkPvVariation": 6318.0,
"sdkUvAfModulus": 0.4866767674881535,
"arcPsuAfModulus": -0.49316621015001927,
"lcParcAfModulus": 0.010624803303801422,
"plpPlcAfModulus": 6.680300623784229E-4,
"acPplpAfModulus": 0.008864188995647409,
"quotaList": [
"sdkUv"
]
},
{
"id": 95601,
"appName": "******",
"mediaOperation": "仵莹",
"currentValue": 5.29,
"contrastValue": 3.33,
"variation": 1.96,
"proportion": -3.0E-4,
"sdkPv0": 383.0,
"sdkPv1": 445.0,
"sdkPvVariation": -62.0,
"sdkUvAfModulus": -0.1754081619312994,
"arcPsuAfModulus": -0.001216106636029871,
"lcParcAfModulus": 0.01795179971929501,
"plpPlcAfModulus": 1.1430662400312357E-4,
"acPplpAfModulus": 0.8053096250893725,
"quotaList": [
"acPplp"
]
},
{
"id": 90026,
"appName": "******",
"mediaOperation": "仵莹",
"currentValue": 1.36,
"contrastValue": 0.0,
"variation": 1.36,
"proportion": -2.0E-4,
"sdkPv0": 21.0,
"sdkPv1": 0.0,
"sdkPvVariation": 21.0,
"sdkUvAfModulus": "NaN",
"arcPsuAfModulus": "NaN",
"lcParcAfModulus": "NaN",
"plpPlcAfModulus": "NaN",
"acPplpAfModulus": "NaN",
"quotaList": []
},
{
"id": 81904,
"appName": "******",
"mediaOperation": "王婷婷",
"currentValue": 1.19,
"contrastValue": 0.0,
"variation": 1.19,
"proportion": -2.0E-4,
"sdkPv0": 7.0,
"sdkPv1": 7.0,
"sdkPvVariation": 0.0,
"sdkUvAfModulus": -0.007042253521126766,
"arcPsuAfModulus": -0.28873239436619713,
"lcParcAfModulus": -0.028169014084507043,
"plpPlcAfModulus": -0.007042253521126766,
"acPplpAfModulus": 0.6690140845070423,
"quotaList": []
},
{
"id": 90927,
"appName": "******",
"mediaOperation": "平雪芳",
"currentValue": 1.62,
"contrastValue": 0.69,
"variation": 0.93,
"proportion": -1.0E-4,
"sdkPv0": 7.0,
"sdkPv1": 1.0,
"sdkPvVariation": 6.0,
"sdkUvAfModulus": 0.579030588776449,
"arcPsuAfModulus": 0.05465156393744251,
"lcParcAfModulus": -0.1534901103955842,
"plpPlcAfModulus": -0.003996090156393755,
"acPplpAfModulus": -0.20883164673413065,
"quotaList": [
"sdkUv"
]
},
{
"id": 34500,
"appName": "******",
"mediaOperation": "王婷婷",
"currentValue": 0.89,
"contrastValue": 0.0,
"variation": 0.89,
"proportion": -1.0E-4,
"sdkPv0": 8.0,
"sdkPv1": 0.0,
"sdkPvVariation": 8.0,
"sdkUvAfModulus": "NaN",
"arcPsuAfModulus": "NaN",
"lcParcAfModulus": "NaN",
"plpPlcAfModulus": "NaN",
"acPplpAfModulus": "NaN",
"quotaList": []
},
{
"id": 21325,
"appName": "******",
"mediaOperation": "仵莹",
"currentValue": 0.95,
"contrastValue": 0.21,
"variation": 0.74,
"proportion": -1.0E-4,
"sdkPv0": 25.0,
"sdkPv1": 22.0,
"sdkPvVariation": 3.0,
"sdkUvAfModulus": 0.032677491464586705,
"arcPsuAfModulus": 0.4318574015175248,
"lcParcAfModulus": -0.0014774362432499856,
"plpPlcAfModulus": -0.0014774362432499856,
"acPplpAfModulus": 0.5325102345313886,
"quotaList": [
"arcPsu",
"acPplp"
]
},
{
"id": 98172,
"appName": "******",
"mediaOperation": "刘思宇",
"currentValue": 1.24,
"contrastValue": 0.59,
"variation": 0.65,
"proportion": -1.0E-4,
"sdkPv0": 0.0,
"sdkPv1": 0.0,
"sdkPvVariation": 0.0,
"sdkUvAfModulus": "NaN",
"arcPsuAfModulus": "NaN",
"lcParcAfModulus": "NaN",
"plpPlcAfModulus": "NaN",
"acPplpAfModulus": "NaN",
"quotaList": []
}
],
"topPlummetApp": [
{
"id": 93845,
"appName": "******",
"mediaOperation": "刘凯鑫,常平凡,陆苏畅",
"currentValue": 30140.41,
"contrastValue": 39135.27,
"variation": -8994.86,
"proportion": 1.4399,
"sdkPv0": 0.0,
"sdkPv1": 0.0,
"sdkPvVariation": 0.0,
"sdkUvAfModulus": "NaN",
"arcPsuAfModulus": "NaN",
"lcParcAfModulus": "NaN",
"plpPlcAfModulus": "NaN",
"acPplpAfModulus": "NaN",
"quotaList": []
},
{
"id": 95090,
"appName": "******",
"mediaOperation": "平雪芳,陆苏畅",
"currentValue": 13308.84,
"contrastValue": 17725.45,
"variation": -4416.61,
"proportion": 0.707,
"sdkPv0": 0.0,
"sdkPv1": 0.0,
"sdkPvVariation": 0.0,
"sdkUvAfModulus": "NaN",
"arcPsuAfModulus": "NaN",
"lcParcAfModulus": "NaN",
"plpPlcAfModulus": "NaN",
"acPplpAfModulus": "NaN",
"quotaList": []
},
{
"id": 98322,
"appName": "******",
"mediaOperation": "刘侠,朱文誓,汪俐娜,高瑜",
"currentValue": 10000.53,
"contrastValue": 13139.03,
"variation": -3138.5,
"proportion": 0.5024,
"sdkPv0": 7.0,
"sdkPv1": 70392.0,
"sdkPvVariation": -70385.0,
"sdkUvAfModulus": -0.48901418969636845,
"arcPsuAfModulus": 0.4999902561455519,
"lcParcAfModulus": -0.0036636927843562007,
"plpPlcAfModulus": -0.0036643003677846306,
"acPplpAfModulus": -0.003667561005938695,
"quotaList": [
"sdkUv"
]
},
{
"id": 96465,
"appName": "******",
"mediaOperation": "刘凯鑫,陆苏畅",
"currentValue": 6259.54,
"contrastValue": 7766.19,
"variation": -1506.65,
"proportion": 0.2412,
"sdkPv0": 0.0,
"sdkPv1": 0.0,
"sdkPvVariation": 0.0,
"sdkUvAfModulus": "NaN",
"arcPsuAfModulus": "NaN",
"lcParcAfModulus": "NaN",
"plpPlcAfModulus": "NaN",
"acPplpAfModulus": "NaN",
"quotaList": []
},
{
"id": 97279,
"appName": "******",
"mediaOperation": "仵莹",
"currentValue": 1794.69,
"contrastValue": 2632.43,
"variation": -837.74,
"proportion": 0.1341,
"sdkPv0": 30569.0,
"sdkPv1": 6692.0,
"sdkPvVariation": 23877.0,
"sdkUvAfModulus": 0.4620494102425503,
"arcPsuAfModulus": -0.4228109896888634,
"lcParcAfModulus": -0.017906300753323296,
"plpPlcAfModulus": -0.017741505744490772,
"acPplpAfModulus": -0.0794917935707723,
"quotaList": [
"arcPsu"
]
},
{
"id": 98688,
"appName": "******",
"mediaOperation": "刘侠,宋小妮,朱文誓,汪俐娜,高瑜",
"currentValue": 178.76,
"contrastValue": 975.08,
"variation": -796.32,
"proportion": 0.1275,
"sdkPv0": 0.0,
"sdkPv1": 8460.0,
"sdkPvVariation": -8460.0,
"sdkUvAfModulus": "NaN",
"arcPsuAfModulus": "NaN",
"lcParcAfModulus": "NaN",
"plpPlcAfModulus": "NaN",
"acPplpAfModulus": "NaN",
"quotaList": []
},
{
"id": 98385,
"appName": "******",
"mediaOperation": "刘凯鑫,陈艺艺",
"currentValue": 2526.23,
"contrastValue": 3135.44,
"variation": -609.21,
"proportion": 0.0975,
"sdkPv0": 0.0,
"sdkPv1": 0.0,
"sdkPvVariation": 0.0,
"sdkUvAfModulus": "NaN",
"arcPsuAfModulus": "NaN",
"lcParcAfModulus": "NaN",
"plpPlcAfModulus": "NaN",
"acPplpAfModulus": "NaN",
"quotaList": []
},
{
"id": 41305,
"appName": "******",
"mediaOperation": "王婷婷",
"currentValue": 695.93,
"contrastValue": 1264.94,
"variation": -569.01,
"proportion": 0.0911,
"sdkPv0": 29555.0,
"sdkPv1": 30508.0,
"sdkPvVariation": -953.0,
"sdkUvAfModulus": -0.03388892797070358,
"arcPsuAfModulus": -0.006011594534092658,
"lcParcAfModulus": -0.01175626438604645,
"plpPlcAfModulus": 2.1717408021465236E-5,
"acPplpAfModulus": -0.9483214957011359,
"quotaList": [
"acPplp"
]
},
{
"id": 85157,
"appName": "******",
"mediaOperation": "仵莹",
"currentValue": 906.42,
"contrastValue": 1422.51,
"variation": -516.09,
"proportion": 0.0826,
"sdkPv0": 6906.0,
"sdkPv1": 8404.0,
"sdkPvVariation": -1498.0,
"sdkUvAfModulus": -0.4039384023976599,
"arcPsuAfModulus": 0.036597974370834015,
"lcParcAfModulus": 8.008237370996597E-4,
"plpPlcAfModulus": -1.9686340739039039E-4,
"acPplpAfModulus": -0.558465936087016,
"quotaList": [
"sdkUv",
"acPplp"
]
},
{
"id": 83603,
"appName": "******",
"mediaOperation": "仵莹",
"currentValue": 145.58,
"contrastValue": 570.64,
"variation": -425.06,
"proportion": 0.068,
"sdkPv0": 753.0,
"sdkPv1": 495.0,
"sdkPvVariation": 258.0,
"sdkUvAfModulus": 0.025735949549818626,
"arcPsuAfModulus": 0.11268215735197351,
"lcParcAfModulus": -0.09442380069536974,
"plpPlcAfModulus": -0.00201068719756534,
"acPplpAfModulus": -0.7651474052052728,
"quotaList": [
"acPplp"
]
},
{
"id": 97497,
"appName": "******",
"mediaOperation": "刘侠,朱文誓,汪俐娜,高瑜",
"currentValue": 116.91,
"contrastValue": 413.85,
"variation": -296.94,
"proportion": 0.0475,
"sdkPv0": 0.0,
"sdkPv1": 1770.0,
"sdkPvVariation": -1770.0,
"sdkUvAfModulus": "NaN",
"arcPsuAfModulus": "NaN",
"lcParcAfModulus": "NaN",
"plpPlcAfModulus": "NaN",
"acPplpAfModulus": "NaN",
"quotaList": []
},
{
"id": 98011,
"appName": "******",
"mediaOperation": "常平凡,平雪芳,汪俐娜,陆苏畅",
"currentValue": 784.17,
"contrastValue": 1038.77,
"variation": -254.6,
"proportion": 0.0408,
"sdkPv0": 0.0,
"sdkPv1": 0.0,
"sdkPvVariation": 0.0,
"sdkUvAfModulus": "NaN",
"arcPsuAfModulus": "NaN",
"lcParcAfModulus": "NaN",
"plpPlcAfModulus": "NaN",
"acPplpAfModulus": "NaN",
"quotaList": []
},
{
"id": 97984,
"appName": "******",
"mediaOperation": "罗嘉瑶,高瑜",
"currentValue": 953.99,
"contrastValue": 1136.39,
"variation": -182.4,
"proportion": 0.0292,
"sdkPv0": 16794.0,
"sdkPv1": 14991.0,
"sdkPvVariation": 1803.0,
"sdkUvAfModulus": 0.37281060368045843,
"arcPsuAfModulus": -0.3566116688791919,
"lcParcAfModulus": 0.015476686155024677,
"plpPlcAfModulus": -0.0018575997324413768,
"acPplpAfModulus": -0.2532434415528837,
"quotaList": [
"arcPsu",
"acPplp"
]
},
{
"id": 98515,
"appName": "******",
"mediaOperation": "平雪芳",
"currentValue": 115.66,
"contrastValue": 239.77,
"variation": -124.11,
"proportion": 0.0199,
"sdkPv0": 630.0,
"sdkPv1": 1146.0,
"sdkPvVariation": -516.0,
"sdkUvAfModulus": -0.8216872460768148,
"arcPsuAfModulus": -0.02908236727264508,
"lcParcAfModulus": -0.007025598998381665,
"plpPlcAfModulus": 2.2226310649547276E-4,
"acPplpAfModulus": -0.14198252454566299,
"quotaList": [
"sdkUv"
]
},
{
"id": 94664,
"appName": "******",
"mediaOperation": "罗嘉瑶,高瑜",
"currentValue": 793.3,
"contrastValue": 912.37,
"variation": -119.07,
"proportion": 0.0191,
"sdkPv0": 22332.0,
"sdkPv1": 18604.0,
"sdkPvVariation": 3728.0,
"sdkUvAfModulus": 0.40210279300349155,
"arcPsuAfModulus": -0.5205617275005912,
"lcParcAfModulus": 0.010585482981083524,
"plpPlcAfModulus": -7.074973473607276E-4,
"acPplpAfModulus": -0.06604249916747298,
"quotaList": [
"arcPsu"
]
},
{
"id": 98696,
"appName": "******",
"mediaOperation": "刘侠,宋小妮,朱文誓,汪俐娜,高瑜",
"currentValue": 3.89,
"contrastValue": 98.5,
"variation": -94.61,
"proportion": 0.0151,
"sdkPv0": 0.0,
"sdkPv1": 2333.0,
"sdkPvVariation": -2333.0,
"sdkUvAfModulus": "NaN",
"arcPsuAfModulus": "NaN",
"lcParcAfModulus": "NaN",
"plpPlcAfModulus": "NaN",
"acPplpAfModulus": "NaN",
"quotaList": []
},
{
"id": 97835,
"appName": "******",
"mediaOperation": "刘凯鑫,陆苏畅",
"currentValue": 412.33,
"contrastValue": 499.81,
"variation": -87.48,
"proportion": 0.014,
"sdkPv0": 0.0,
"sdkPv1": 0.0,
"sdkPvVariation": 0.0,
"sdkUvAfModulus": "NaN",
"arcPsuAfModulus": "NaN",
"lcParcAfModulus": "NaN",
"plpPlcAfModulus": "NaN",
"acPplpAfModulus": "NaN",
"quotaList": []
},
{
"id": 95328,
"appName": "******",
"mediaOperation": "陈艺艺",
"currentValue": 430.18,
"contrastValue": 492.63,
"variation": -62.45,
"proportion": 0.01,
"sdkPv0": 1043.0,
"sdkPv1": 1044.0,
"sdkPvVariation": -1.0,
"sdkUvAfModulus": -0.09092847196282446,
"arcPsuAfModulus": 0.0838032537829433,
"lcParcAfModulus": -0.5856260923978582,
"plpPlcAfModulus": -5.349324357228079E-5,
"acPplpAfModulus": 0.23958868861280178,
"quotaList": [
"lcParc"
]
},
{
"id": 97575,
"appName": "******",
"mediaOperation": "王婷婷",
"currentValue": 117.42,
"contrastValue": 172.53,
"variation": -55.11,
"proportion": 0.0088,
"sdkPv0": 13.0,
"sdkPv1": 17.0,
"sdkPvVariation": -4.0,
"sdkUvAfModulus": -0.17138450369844355,
"arcPsuAfModulus": 0.2819167573609099,
"lcParcAfModulus": 0.006936098076219004,
"plpPlcAfModulus": -0.0019719931737789153,
"acPplpAfModulus": -0.5377906476906487,
"quotaList": [
"acPplp"
]
},
{
"id": 96651,
"appName": "******",
"mediaOperation": "平雪芳",
"currentValue": 130.23,
"contrastValue": 158.99,
"variation": -28.76,
"proportion": 0.0046,
"sdkPv0": 0.0,
"sdkPv1": 0.0,
"sdkPvVariation": 0.0,
"sdkUvAfModulus": "NaN",
"arcPsuAfModulus": "NaN",
"lcParcAfModulus": "NaN",
"plpPlcAfModulus": "NaN",
"acPplpAfModulus": "NaN",
"quotaList": []
},
{
"id": 84951,
"appName": "******",
"mediaOperation": "平雪芳",
"currentValue": 4.38,
"contrastValue": 32.28,
"variation": -27.9,
"proportion": 0.0045,
"sdkPv0": 0.0,
"sdkPv1": 0.0,
"sdkPvVariation": 0.0,
"sdkUvAfModulus": "NaN",
"arcPsuAfModulus": "NaN",
"lcParcAfModulus": "NaN",
"plpPlcAfModulus": "NaN",
"acPplpAfModulus": "NaN",
"quotaList": []
},
{
"id": 22421,
"appName": "******",
"mediaOperation": "王婷婷",
"currentValue": 1.13,
"contrastValue": 28.07,
"variation": -26.94,
"proportion": 0.0043,
"sdkPv0": 20.0,
"sdkPv1": 22.0,
"sdkPvVariation": -2.0,
"sdkUvAfModulus": -0.04516944286195596,
"arcPsuAfModulus": -0.36440095055508476,
"lcParcAfModulus": 0.005512005464176977,
"plpPlcAfModulus": 0.005512005464176977,
"acPplpAfModulus": -0.5794055956546053,
"quotaList": [
"arcPsu",
"acPplp"
]
},
{
"id": 88299,
"appName": "******",
"mediaOperation": "王婷婷",
"currentValue": 1.93,
"contrastValue": 28.53,
"variation": -26.6,
"proportion": 0.0043,
"sdkPv0": 11.0,
"sdkPv1": 10.0,
"sdkPvVariation": 1.0,
"sdkUvAfModulus": 0.037477651974316475,
"arcPsuAfModulus": 0.11843139655031815,
"lcParcAfModulus": 0.11145419755792339,
"plpPlcAfModulus": 0.012403756395165406,
"acPplpAfModulus": -0.7202329975222767,
"quotaList": [
"acPplp"
]
},
{
"id": 21683,
"appName": "******",
"mediaOperation": "王婷婷",
"currentValue": 7.79,
"contrastValue": 34.19,
"variation": -26.4,
"proportion": 0.0042,
"sdkPv0": 0.0,
"sdkPv1": 0.0,
"sdkPvVariation": 0.0,
"sdkUvAfModulus": "NaN",
"arcPsuAfModulus": "NaN",
"lcParcAfModulus": "NaN",
"plpPlcAfModulus": "NaN",
"acPplpAfModulus": "NaN",
"quotaList": []
},
{
"id": 97530,
"appName": "******",
"mediaOperation": "平雪芳",
"currentValue": 5.37,
"contrastValue": 29.59,
"variation": -24.22,
"proportion": 0.0039,
"sdkPv0": 74.0,
"sdkPv1": 63.0,
"sdkPvVariation": 11.0,
"sdkUvAfModulus": 0.07529957634831629,
"arcPsuAfModulus": 0.06806823629843749,
"lcParcAfModulus": 0.0014576541783268666,
"plpPlcAfModulus": 0.0014576541783268666,
"acPplpAfModulus": -0.8537168789965925,
"quotaList": [
"acPplp"
]
},
{
"id": 91789,
"appName": "******",
"mediaOperation": "刘思宇",
"currentValue": 1.15,
"contrastValue": 22.63,
"variation": -21.48,
"proportion": 0.0034,
"sdkPv0": 0.0,
"sdkPv1": 0.0,
"sdkPvVariation": 0.0,
"sdkUvAfModulus": "NaN",
"arcPsuAfModulus": "NaN",
"lcParcAfModulus": "NaN",
"plpPlcAfModulus": "NaN",
"acPplpAfModulus": "NaN",
"quotaList": []
},
{
"id": 91873,
"appName": "******",
"mediaOperation": "平雪芳",
"currentValue": 23.0,
"contrastValue": 37.7,
"variation": -14.7,
"proportion": 0.0024,
"sdkPv0": 0.0,
"sdkPv1": 0.0,
"sdkPvVariation": 0.0,
"sdkUvAfModulus": "NaN",
"arcPsuAfModulus": "NaN",
"lcParcAfModulus": "NaN",
"plpPlcAfModulus": "NaN",
"acPplpAfModulus": "NaN",
"quotaList": []
},
{
"id": 77752,
"appName": "******",
"mediaOperation": "平雪芳",
"currentValue": 3.26,
"contrastValue": 16.96,
"variation": -13.7,
"proportion": 0.0022,
"sdkPv0": 0.0,
"sdkPv1": 0.0,
"sdkPvVariation": 0.0,
"sdkUvAfModulus": "NaN",
"arcPsuAfModulus": "NaN",
"lcParcAfModulus": "NaN",
"plpPlcAfModulus": "NaN",
"acPplpAfModulus": "NaN",
"quotaList": []
},
{
"id": 91239,
"appName": "******",
"mediaOperation": "王婷婷",
"currentValue": 8.52,
"contrastValue": 17.06,
"variation": -8.54,
"proportion": 0.0014,
"sdkPv0": 67.0,
"sdkPv1": 81.0,
"sdkPvVariation": -14.0,
"sdkUvAfModulus": -0.12840328267762924,
"arcPsuAfModulus": -0.2010800612577594,
"lcParcAfModulus": 0.21018890369896723,
"plpPlcAfModulus": -0.003201928056241141,
"acPplpAfModulus": -0.457125824309403,
"quotaList": [
"arcPsu",
"acPplp"
]
},
{
"id": 83749,
"appName": "******",
"mediaOperation": "王婷婷",
"currentValue": 21.24,
"contrastValue": 28.91,
"variation": -7.67,
"proportion": 0.0012,
"sdkPv0": 0.0,
"sdkPv1": 0.0,
"sdkPvVariation": 0.0,
"sdkUvAfModulus": "NaN",
"arcPsuAfModulus": "NaN",
"lcParcAfModulus": "NaN",
"plpPlcAfModulus": "NaN",
"acPplpAfModulus": "NaN",
"quotaList": []
}
]
}
}
\ No newline at end of file
{
"name": "demo",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview"
},
"dependencies": {
"@tailwindcss/vite": "^4.1.0",
"@tuia/eslint-config-common": "3.0.1-beta.2",
"antd": "^5.24.5",
"axios": "^1.8.4",
"dayjs": "^1.11.13",
"mobx": "^6.13.7",
"mobx-react-lite": "^4.1.0",
"numeral": "^2.0.6",
"pixiu-number-toolkit": "^3.0.11",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-router": "^7.4.0",
"react-router-dom": "^7.4.0",
"tailwindcss": "^4.1.0"
},
"devDependencies": {
"@ant-design/v5-patch-for-react-19": "^1.0.3",
"@types/numeral": "^2.0.5",
"@types/react": "^19.0.10",
"@types/react-dom": "^19.0.4",
"@vitejs/plugin-react-swc": "^3.8.0",
"eslint-plugin-react-refresh": "^0.4.19",
"globals": "^15.15.0",
"typescript": "~5.7.2",
"unplugin-auto-import": "^19.1.2",
"vite": "^6.2.0",
"vite-plugin-pages": "^0.32.5"
}
}
import config from '@tuia/eslint-config-common/prettier.js'
export default { ...config }
const NodeDocker = require('@tuia/node-docker')
const Koa = require('koa')
const logger = require('koa-logger')
const onerror = require('koa-onerror')
const Router = require('koa-router')
const koaStatic = require('koa-static')
const path = require('path')
const Eurekaclient = require('@tuia/eureka-client-ts').default
const app = new Koa()
const router = new Router()
// error handler
onerror(app)
app.use(
logger((str, args) => {
!str.includes('/monitor/check') && console.log(str)
})
)
app.use(koaStatic(path.join(__dirname, './dist')))
// 用于中台确认应用是否运行正常
router.get('/monitor/check', function (ctx, next) {
ctx.body = 'ok'
})
app.use(router.routes())
const dockerApp = new NodeDocker({
app,
appType: 'koa',
port: 3000,
})
dockerApp.startServer().then(async () => {
const client = new Eurekaclient({
port: 3000,
appName: '<app-name>',
services: [
// 需要通信的其他应用名
],
})
await client.start()
global.eureka = client
})
// 进程结束主动通知Eureka取消注册
let isShuttingDown = false
async function deregisterEureka() {
if (global.eureka) {
console.log('Deregistering from Eureka...')
await new Promise((resolve) => {
global.eureka.eureka.deregister(() => {
console.log('Deregistered from Eureka...')
resolve()
})
})
}
}
async function gracefulShutdown() {
if (isShuttingDown) return
isShuttingDown = true
console.log('Exitting...')
await deregisterEureka()
process.exit(0)
}
;['exit', 'SIGINT', 'SIGTERM'].forEach((event) => {
process.on(event, gracefulShutdown)
})
{
"name": "tuia-payment-manager-node",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"@tuia/eureka-client-ts": "^0.3.8",
"@tuia/node-docker": "^0.0.3",
"koa": "^2.15.3",
"koa-logger": "^3.2.1",
"koa-onerror": "^4.2.0",
"koa-router": "^12.0.1",
"koa-static": "^5.0.0"
},
"devDependencies": {
"@koa/cors": "^5.0.0"
}
}
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@koa/cors@^5.0.0":
version "5.0.0"
resolved "https://registry.npmmirror.com/@koa/cors/-/cors-5.0.0.tgz#0029b5f057fa0d0ae0e37dd2c89ece315a0daffd"
integrity sha512-x/iUDjcS90W69PryLDIMgFyV21YLTnG9zOpPXS7Bkt2b8AsY3zZsIpOLBkYr9fBcF3HbkKaER5hOBZLfpLgYNw==
dependencies:
vary "^1.1.2"
"@tuia/eureka-client-ts@^0.3.8":
version "0.3.8"
resolved "https://registry.npmmirror.com/@tuia/eureka-client-ts/-/eureka-client-ts-0.3.8.tgz#9eb3ee2a710ceed6bf55ff0c685fc2204951a34b"
integrity sha512-7FqNqj0nawv+N0Sv2NjJwummgt3UyG6larIAq1+r2kAdcS+KAuRZVmfP0rXZFvz8fwFYFDsszVfxNvaHvwd5Wg==
dependencies:
"@types/eureka-js-client" "^4.4.2"
"@types/netmask" "^1.0.30"
"@types/node" "^12.6.6"
address "^1.1.0"
axios "^0.19.0"
eureka-js-client "^4.5.0"
netmask "^1.0.6"
typescript "^3.5.3"
"@tuia/node-docker@^0.0.3":
version "0.0.3"
resolved "https://registry.npmmirror.com/@tuia/node-docker/-/node-docker-0.0.3.tgz#85c35d5d90f9a9763753f6a6f2af0a006f53aa05"
integrity sha512-3ez/uH2H4MT0H0+4iE/DhbdZtqzSUfSpj52AFTVHdllegAOVSHw4bwjB93wJ5vhKFmzYKt4fltJME2SWnld+ZQ==
"@types/eureka-js-client@^4.4.2":
version "4.5.9"
resolved "https://registry.npmmirror.com/@types/eureka-js-client/-/eureka-js-client-4.5.9.tgz#75a83133ff5442b2c0d8debcb467690531af3844"
integrity sha512-hxQPPVPs1EZQ/L07PXV5kgPSzRAwEVTbbqwRGYoTYDekgyJ04Z7TUtUHCVQ6pYuN+UCYNfOug1XRgcCXxIUWNw==
"@types/netmask@^1.0.30":
version "1.0.30"
resolved "https://registry.npmmirror.com/@types/netmask/-/netmask-1.0.30.tgz#b68005e3e3c19f517ced4610bb69dce2e0c5babb"
integrity sha512-Kl1xAICLv1Y7/WsNXkPKldRMz3QmXUYMIzr3rMXnIBDy9c4/sYG7V6P6u7Ja3w+uNtNQrRudJduqVoYX/DxfZg==
"@types/node@^12.6.6":
version "12.20.55"
resolved "https://registry.npmmirror.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240"
integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==
accepts@^1.3.5:
version "1.3.8"
resolved "https://registry.npmmirror.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e"
integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==
dependencies:
mime-types "~2.1.34"
negotiator "0.6.3"
address@^1.1.0:
version "1.2.2"
resolved "https://registry.npmmirror.com/address/-/address-1.2.2.tgz#2b5248dac5485a6390532c6a517fda2e3faac89e"
integrity sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==
ajv@^6.12.3:
version "6.12.6"
resolved "https://registry.npmmirror.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
dependencies:
fast-deep-equal "^3.1.1"
fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
ansi-styles@^3.2.1:
version "3.2.1"
resolved "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
dependencies:
color-convert "^1.9.0"
argparse@^1.0.7:
version "1.0.10"
resolved "https://registry.npmmirror.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==
dependencies:
sprintf-js "~1.0.2"
asn1@~0.2.3:
version "0.2.6"
resolved "https://registry.npmmirror.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d"
integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==
dependencies:
safer-buffer "~2.1.0"
assert-plus@1.0.0, assert-plus@^1.0.0:
version "1.0.0"
resolved "https://registry.npmmirror.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==
async@^2.0.1:
version "2.6.4"
resolved "https://registry.npmmirror.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221"
integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==
dependencies:
lodash "^4.17.14"
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
aws-sign2@~0.7.0:
version "0.7.0"
resolved "https://registry.npmmirror.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==
aws4@^1.8.0:
version "1.13.0"
resolved "https://registry.npmmirror.com/aws4/-/aws4-1.13.0.tgz#d9b802e9bb9c248d7be5f7f5ef178dc3684e9dcc"
integrity sha512-3AungXC4I8kKsS9PuS4JH2nc+0bVY/mjgrephHTIi8fpEeGsTHBUJeosp0Wc1myYMElmD0B3Oc4XL/HVJ4PV2g==
axios@^0.19.0:
version "0.19.2"
resolved "https://registry.npmmirror.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27"
integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==
dependencies:
follow-redirects "1.5.10"
bcrypt-pbkdf@^1.0.0:
version "1.0.2"
resolved "https://registry.npmmirror.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==
dependencies:
tweetnacl "^0.14.3"
bytes@^3.1.0:
version "3.1.2"
resolved "https://registry.npmmirror.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5"
integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==
cache-content-type@^1.0.0:
version "1.0.1"
resolved "https://registry.npmmirror.com/cache-content-type/-/cache-content-type-1.0.1.tgz#035cde2b08ee2129f4a8315ea8f00a00dba1453c"
integrity sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==
dependencies:
mime-types "^2.1.18"
ylru "^1.2.0"
caseless@~0.12.0:
version "0.12.0"
resolved "https://registry.npmmirror.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==
chalk@^2.4.2:
version "2.4.2"
resolved "https://registry.npmmirror.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
dependencies:
ansi-styles "^3.2.1"
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
co@^4.6.0:
version "4.6.0"
resolved "https://registry.npmmirror.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==
color-convert@^1.9.0:
version "1.9.3"
resolved "https://registry.npmmirror.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
dependencies:
color-name "1.1.3"
color-name@1.1.3:
version "1.1.3"
resolved "https://registry.npmmirror.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==
combined-stream@^1.0.6, combined-stream@~1.0.6:
version "1.0.8"
resolved "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
dependencies:
delayed-stream "~1.0.0"
content-disposition@~0.5.2:
version "0.5.4"
resolved "https://registry.npmmirror.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe"
integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==
dependencies:
safe-buffer "5.2.1"
content-type@^1.0.4:
version "1.0.5"
resolved "https://registry.npmmirror.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918"
integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==
cookies@~0.9.0:
version "0.9.1"
resolved "https://registry.npmmirror.com/cookies/-/cookies-0.9.1.tgz#3ffed6f60bb4fb5f146feeedba50acc418af67e3"
integrity sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw==
dependencies:
depd "~2.0.0"
keygrip "~1.1.0"
core-util-is@1.0.2:
version "1.0.2"
resolved "https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==
dashdash@^1.12.0:
version "1.14.1"
resolved "https://registry.npmmirror.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
integrity sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==
dependencies:
assert-plus "^1.0.0"
debug@=3.1.0:
version "3.1.0"
resolved "https://registry.npmmirror.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
dependencies:
ms "2.0.0"
debug@^3.1.0:
version "3.2.7"
resolved "https://registry.npmmirror.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
dependencies:
ms "^2.1.1"
debug@^4.1.1, debug@^4.3.2, debug@^4.3.4:
version "4.3.5"
resolved "https://registry.npmmirror.com/debug/-/debug-4.3.5.tgz#e83444eceb9fedd4a1da56d671ae2446a01a6e1e"
integrity sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==
dependencies:
ms "2.1.2"
deep-equal@~1.0.1:
version "1.0.1"
resolved "https://registry.npmmirror.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
integrity sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw==
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
delegates@^1.0.0:
version "1.0.0"
resolved "https://registry.npmmirror.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==
depd@2.0.0, depd@^2.0.0, depd@~2.0.0:
version "2.0.0"
resolved "https://registry.npmmirror.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==
depd@~1.1.2:
version "1.1.2"
resolved "https://registry.npmmirror.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==
destroy@^1.0.4:
version "1.2.0"
resolved "https://registry.npmmirror.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015"
integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==
ecc-jsbn@~0.1.1:
version "0.1.2"
resolved "https://registry.npmmirror.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==
dependencies:
jsbn "~0.1.0"
safer-buffer "^2.1.0"
ee-first@1.1.1:
version "1.1.1"
resolved "https://registry.npmmirror.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==
encodeurl@^1.0.2:
version "1.0.2"
resolved "https://registry.npmmirror.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==
escape-html@^1.0.3:
version "1.0.3"
resolved "https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==
escape-string-regexp@^1.0.5:
version "1.0.5"
resolved "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==
esprima@^4.0.0:
version "4.0.1"
resolved "https://registry.npmmirror.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
eureka-js-client@^4.5.0:
version "4.5.0"
resolved "https://registry.npmmirror.com/eureka-js-client/-/eureka-js-client-4.5.0.tgz#45d46935dfe81e41b0aa26420dc92d54ef97b0c4"
integrity sha512-vnkrw7UPAHdJbTsjpgVJfqjr3FFJnEJNq4acRbc6s8qTAhO0LhTDkN4a/1TUYlsr480x0PWjA6jzqVGCjyWE7g==
dependencies:
async "^2.0.1"
js-yaml "^3.3.1"
lodash "^4.13.1"
request "^2.83.0"
extend@~3.0.2:
version "3.0.2"
resolved "https://registry.npmmirror.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
extsprintf@1.3.0:
version "1.3.0"
resolved "https://registry.npmmirror.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==
extsprintf@^1.2.0:
version "1.4.1"
resolved "https://registry.npmmirror.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07"
integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==
fast-deep-equal@^3.1.1:
version "3.1.3"
resolved "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
fast-json-stable-stringify@^2.0.0:
version "2.1.0"
resolved "https://registry.npmmirror.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
follow-redirects@1.5.10:
version "1.5.10"
resolved "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a"
integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==
dependencies:
debug "=3.1.0"
forever-agent@~0.6.1:
version "0.6.1"
resolved "https://registry.npmmirror.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==
form-data@~2.3.2:
version "2.3.3"
resolved "https://registry.npmmirror.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.6"
mime-types "^2.1.12"
fresh@~0.5.2:
version "0.5.2"
resolved "https://registry.npmmirror.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==
getpass@^0.1.1:
version "0.1.7"
resolved "https://registry.npmmirror.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==
dependencies:
assert-plus "^1.0.0"
har-schema@^2.0.0:
version "2.0.0"
resolved "https://registry.npmmirror.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
integrity sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==
har-validator@~5.1.3:
version "5.1.5"
resolved "https://registry.npmmirror.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd"
integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==
dependencies:
ajv "^6.12.3"
har-schema "^2.0.0"
has-flag@^3.0.0:
version "3.0.0"
resolved "https://registry.npmmirror.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==
has-symbols@^1.0.3:
version "1.0.3"
resolved "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
has-tostringtag@^1.0.0:
version "1.0.2"
resolved "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc"
integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==
dependencies:
has-symbols "^1.0.3"
http-assert@^1.3.0:
version "1.5.0"
resolved "https://registry.npmmirror.com/http-assert/-/http-assert-1.5.0.tgz#c389ccd87ac16ed2dfa6246fd73b926aa00e6b8f"
integrity sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==
dependencies:
deep-equal "~1.0.1"
http-errors "~1.8.0"
http-errors@^1.6.3, http-errors@^1.7.3, http-errors@~1.8.0:
version "1.8.1"
resolved "https://registry.npmmirror.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c"
integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==
dependencies:
depd "~1.1.2"
inherits "2.0.4"
setprototypeof "1.2.0"
statuses ">= 1.5.0 < 2"
toidentifier "1.0.1"
http-errors@^2.0.0:
version "2.0.0"
resolved "https://registry.npmmirror.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3"
integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==
dependencies:
depd "2.0.0"
inherits "2.0.4"
setprototypeof "1.2.0"
statuses "2.0.1"
toidentifier "1.0.1"
http-errors@~1.6.2:
version "1.6.3"
resolved "https://registry.npmmirror.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d"
integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==
dependencies:
depd "~1.1.2"
inherits "2.0.3"
setprototypeof "1.1.0"
statuses ">= 1.4.0 < 2"
http-signature@~1.2.0:
version "1.2.0"
resolved "https://registry.npmmirror.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
integrity sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==
dependencies:
assert-plus "^1.0.0"
jsprim "^1.2.2"
sshpk "^1.7.0"
humanize-number@0.0.2:
version "0.0.2"
resolved "https://registry.npmmirror.com/humanize-number/-/humanize-number-0.0.2.tgz#11c0af6a471643633588588048f1799541489c18"
integrity sha512-un3ZAcNQGI7RzaWGZzQDH47HETM4Wrj6z6E4TId8Yeq9w5ZKUVB1nrT2jwFheTUjEmqcgTjXDc959jum+ai1kQ==
inherits@2.0.3:
version "2.0.3"
resolved "https://registry.npmmirror.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==
inherits@2.0.4:
version "2.0.4"
resolved "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
is-generator-function@^1.0.7:
version "1.0.10"
resolved "https://registry.npmmirror.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72"
integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==
dependencies:
has-tostringtag "^1.0.0"
is-typedarray@~1.0.0:
version "1.0.0"
resolved "https://registry.npmmirror.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==
isstream@~0.1.2:
version "0.1.2"
resolved "https://registry.npmmirror.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==
js-yaml@^3.3.1:
version "3.14.1"
resolved "https://registry.npmmirror.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537"
integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==
dependencies:
argparse "^1.0.7"
esprima "^4.0.0"
jsbn@~0.1.0:
version "0.1.1"
resolved "https://registry.npmmirror.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==
json-schema-traverse@^0.4.1:
version "0.4.1"
resolved "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
json-schema@0.4.0:
version "0.4.0"
resolved "https://registry.npmmirror.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5"
integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==
json-stringify-safe@~5.0.1:
version "5.0.1"
resolved "https://registry.npmmirror.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==
jsprim@^1.2.2:
version "1.4.2"
resolved "https://registry.npmmirror.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb"
integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==
dependencies:
assert-plus "1.0.0"
extsprintf "1.3.0"
json-schema "0.4.0"
verror "1.10.0"
keygrip@~1.1.0:
version "1.1.0"
resolved "https://registry.npmmirror.com/keygrip/-/keygrip-1.1.0.tgz#871b1681d5e159c62a445b0c74b615e0917e7226"
integrity sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==
dependencies:
tsscmp "1.0.6"
koa-compose@^4.1.0:
version "4.1.0"
resolved "https://registry.npmmirror.com/koa-compose/-/koa-compose-4.1.0.tgz#507306b9371901db41121c812e923d0d67d3e877"
integrity sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==
koa-convert@^2.0.0:
version "2.0.0"
resolved "https://registry.npmmirror.com/koa-convert/-/koa-convert-2.0.0.tgz#86a0c44d81d40551bae22fee6709904573eea4f5"
integrity sha512-asOvN6bFlSnxewce2e/DK3p4tltyfC4VM7ZwuTuepI7dEQVcvpyFuBcEARu1+Hxg8DIwytce2n7jrZtRlPrARA==
dependencies:
co "^4.6.0"
koa-compose "^4.1.0"
koa-logger@^3.2.1:
version "3.2.1"
resolved "https://registry.npmmirror.com/koa-logger/-/koa-logger-3.2.1.tgz#ab9db879526db3837cc9ce4fd983c025b1689f22"
integrity sha512-MjlznhLLKy9+kG8nAXKJLM0/ClsQp/Or2vI3a5rbSQmgl8IJBQO0KI5FA70BvW+hqjtxjp49SpH2E7okS6NmHg==
dependencies:
bytes "^3.1.0"
chalk "^2.4.2"
humanize-number "0.0.2"
passthrough-counter "^1.0.0"
koa-onerror@^4.2.0:
version "4.2.0"
resolved "https://registry.npmmirror.com/koa-onerror/-/koa-onerror-4.2.0.tgz#c617bb71dd036f27f6ade58e70480a50ff5fd4b1"
integrity sha512-D15tp5rxevHqqcvOiEDbtQolG6z3NpBNupz3EUZz43pjYv5SGMom2Xz1FKM8oTya56+aq+hejPW/iBrNnC/UGQ==
dependencies:
escape-html "^1.0.3"
stream-wormhole "^1.1.0"
koa-router@^12.0.1:
version "12.0.1"
resolved "https://registry.npmmirror.com/koa-router/-/koa-router-12.0.1.tgz#a3c1c331032d442da786f0631d23e74d51b6882e"
integrity sha512-gaDdj3GtzoLoeosacd50kBBTnnh3B9AYxDThQUo4sfUyXdOhY6ku1qyZKW88tQCRgc3Sw6ChXYXWZwwgjOxE0w==
dependencies:
debug "^4.3.4"
http-errors "^2.0.0"
koa-compose "^4.1.0"
methods "^1.1.2"
path-to-regexp "^6.2.1"
koa-send@^5.0.0:
version "5.0.1"
resolved "https://registry.npmmirror.com/koa-send/-/koa-send-5.0.1.tgz#39dceebfafb395d0d60beaffba3a70b4f543fe79"
integrity sha512-tmcyQ/wXXuxpDxyNXv5yNNkdAMdFRqwtegBXUaowiQzUKqJehttS0x2j0eOZDQAyloAth5w6wwBImnFzkUz3pQ==
dependencies:
debug "^4.1.1"
http-errors "^1.7.3"
resolve-path "^1.4.0"
koa-static@^5.0.0:
version "5.0.0"
resolved "https://registry.npmmirror.com/koa-static/-/koa-static-5.0.0.tgz#5e92fc96b537ad5219f425319c95b64772776943"
integrity sha512-UqyYyH5YEXaJrf9S8E23GoJFQZXkBVJ9zYYMPGz919MSX1KuvAcycIuS0ci150HCoPf4XQVhQ84Qf8xRPWxFaQ==
dependencies:
debug "^3.1.0"
koa-send "^5.0.0"
koa@^2.15.3:
version "2.15.3"
resolved "https://registry.npmmirror.com/koa/-/koa-2.15.3.tgz#062809266ee75ce0c75f6510a005b0e38f8c519a"
integrity sha512-j/8tY9j5t+GVMLeioLaxweJiKUayFhlGqNTzf2ZGwL0ZCQijd2RLHK0SLW5Tsko8YyyqCZC2cojIb0/s62qTAg==
dependencies:
accepts "^1.3.5"
cache-content-type "^1.0.0"
content-disposition "~0.5.2"
content-type "^1.0.4"
cookies "~0.9.0"
debug "^4.3.2"
delegates "^1.0.0"
depd "^2.0.0"
destroy "^1.0.4"
encodeurl "^1.0.2"
escape-html "^1.0.3"
fresh "~0.5.2"
http-assert "^1.3.0"
http-errors "^1.6.3"
is-generator-function "^1.0.7"
koa-compose "^4.1.0"
koa-convert "^2.0.0"
on-finished "^2.3.0"
only "~0.0.2"
parseurl "^1.3.2"
statuses "^1.5.0"
type-is "^1.6.16"
vary "^1.1.2"
lodash@^4.13.1, lodash@^4.17.14:
version "4.17.21"
resolved "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
media-typer@0.3.0:
version "0.3.0"
resolved "https://registry.npmmirror.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==
methods@^1.1.2:
version "1.1.2"
resolved "https://registry.npmmirror.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==
mime-db@1.52.0:
version "1.52.0"
resolved "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
mime-types@^2.1.12, mime-types@^2.1.18, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34:
version "2.1.35"
resolved "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
dependencies:
mime-db "1.52.0"
ms@2.0.0:
version "2.0.0"
resolved "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==
ms@2.1.2:
version "2.1.2"
resolved "https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
ms@^2.1.1:
version "2.1.3"
resolved "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
negotiator@0.6.3:
version "0.6.3"
resolved "https://registry.npmmirror.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd"
integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==
netmask@^1.0.6:
version "1.0.6"
resolved "https://registry.npmmirror.com/netmask/-/netmask-1.0.6.tgz#20297e89d86f6f6400f250d9f4f6b4c1945fcd35"
integrity sha512-3DWDqAtIiPSkBXZyYEjwebfK56nrlQfRGt642fu8RPaL+ePu750+HCMHxjJCG3iEHq/0aeMvX6KIzlv7nuhfrA==
oauth-sign@~0.9.0:
version "0.9.0"
resolved "https://registry.npmmirror.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
on-finished@^2.3.0:
version "2.4.1"
resolved "https://registry.npmmirror.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f"
integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==
dependencies:
ee-first "1.1.1"
only@~0.0.2:
version "0.0.2"
resolved "https://registry.npmmirror.com/only/-/only-0.0.2.tgz#2afde84d03e50b9a8edc444e30610a70295edfb4"
integrity sha512-Fvw+Jemq5fjjyWz6CpKx6w9s7xxqo3+JCyM0WXWeCSOboZ8ABkyvP8ID4CZuChA/wxSx+XSJmdOm8rGVyJ1hdQ==
parseurl@^1.3.2:
version "1.3.3"
resolved "https://registry.npmmirror.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
passthrough-counter@^1.0.0:
version "1.0.0"
resolved "https://registry.npmmirror.com/passthrough-counter/-/passthrough-counter-1.0.0.tgz#1967d9e66da572b5c023c787db112a387ab166fa"
integrity sha512-Wy8PXTLqPAN0oEgBrlnsXPMww3SYJ44tQ8aVrGAI4h4JZYCS0oYqsPqtPR8OhJpv6qFbpbB7XAn0liKV7EXubA==
path-is-absolute@1.0.1:
version "1.0.1"
resolved "https://registry.npmmirror.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==
path-to-regexp@^6.2.1:
version "6.2.2"
resolved "https://registry.npmmirror.com/path-to-regexp/-/path-to-regexp-6.2.2.tgz#324377a83e5049cbecadc5554d6a63a9a4866b36"
integrity sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==
performance-now@^2.1.0:
version "2.1.0"
resolved "https://registry.npmmirror.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==
psl@^1.1.28:
version "1.9.0"
resolved "https://registry.npmmirror.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7"
integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==
punycode@^2.1.0, punycode@^2.1.1:
version "2.3.1"
resolved "https://registry.npmmirror.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5"
integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==
qs@~6.5.2:
version "6.5.3"
resolved "https://registry.npmmirror.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad"
integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==
request@^2.83.0:
version "2.88.2"
resolved "https://registry.npmmirror.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==
dependencies:
aws-sign2 "~0.7.0"
aws4 "^1.8.0"
caseless "~0.12.0"
combined-stream "~1.0.6"
extend "~3.0.2"
forever-agent "~0.6.1"
form-data "~2.3.2"
har-validator "~5.1.3"
http-signature "~1.2.0"
is-typedarray "~1.0.0"
isstream "~0.1.2"
json-stringify-safe "~5.0.1"
mime-types "~2.1.19"
oauth-sign "~0.9.0"
performance-now "^2.1.0"
qs "~6.5.2"
safe-buffer "^5.1.2"
tough-cookie "~2.5.0"
tunnel-agent "^0.6.0"
uuid "^3.3.2"
resolve-path@^1.4.0:
version "1.4.0"
resolved "https://registry.npmmirror.com/resolve-path/-/resolve-path-1.4.0.tgz#c4bda9f5efb2fce65247873ab36bb4d834fe16f7"
integrity sha512-i1xevIst/Qa+nA9olDxLWnLk8YZbi8R/7JPbCMcgyWaFR6bKWaexgJgEB5oc2PKMjYdrHynyz0NY+if+H98t1w==
dependencies:
http-errors "~1.6.2"
path-is-absolute "1.0.1"
safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.2:
version "5.2.1"
resolved "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
version "2.1.2"
resolved "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
setprototypeof@1.1.0:
version "1.1.0"
resolved "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656"
integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==
setprototypeof@1.2.0:
version "1.2.0"
resolved "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424"
integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==
sprintf-js@~1.0.2:
version "1.0.3"
resolved "https://registry.npmmirror.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==
sshpk@^1.7.0:
version "1.18.0"
resolved "https://registry.npmmirror.com/sshpk/-/sshpk-1.18.0.tgz#1663e55cddf4d688b86a46b77f0d5fe363aba028"
integrity sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==
dependencies:
asn1 "~0.2.3"
assert-plus "^1.0.0"
bcrypt-pbkdf "^1.0.0"
dashdash "^1.12.0"
ecc-jsbn "~0.1.1"
getpass "^0.1.1"
jsbn "~0.1.0"
safer-buffer "^2.0.2"
tweetnacl "~0.14.0"
statuses@2.0.1:
version "2.0.1"
resolved "https://registry.npmmirror.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63"
integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==
"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@^1.5.0:
version "1.5.0"
resolved "https://registry.npmmirror.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==
stream-wormhole@^1.1.0:
version "1.1.0"
resolved "https://registry.npmmirror.com/stream-wormhole/-/stream-wormhole-1.1.0.tgz#300aff46ced553cfec642a05251885417693c33d"
integrity sha512-gHFfL3px0Kctd6Po0M8TzEvt3De/xu6cnRrjlfYNhwbhLPLwigI2t1nc6jrzNuaYg5C4YF78PPFuQPzRiqn9ew==
supports-color@^5.3.0:
version "5.5.0"
resolved "https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
dependencies:
has-flag "^3.0.0"
toidentifier@1.0.1:
version "1.0.1"
resolved "https://registry.npmmirror.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35"
integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==
tough-cookie@~2.5.0:
version "2.5.0"
resolved "https://registry.npmmirror.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==
dependencies:
psl "^1.1.28"
punycode "^2.1.1"
tsscmp@1.0.6:
version "1.0.6"
resolved "https://registry.npmmirror.com/tsscmp/-/tsscmp-1.0.6.tgz#85b99583ac3589ec4bfef825b5000aa911d605eb"
integrity sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==
tunnel-agent@^0.6.0:
version "0.6.0"
resolved "https://registry.npmmirror.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==
dependencies:
safe-buffer "^5.0.1"
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
version "0.14.5"
resolved "https://registry.npmmirror.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==
type-is@^1.6.16:
version "1.6.18"
resolved "https://registry.npmmirror.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"
integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==
dependencies:
media-typer "0.3.0"
mime-types "~2.1.24"
typescript@^3.5.3:
version "3.9.10"
resolved "https://registry.npmmirror.com/typescript/-/typescript-3.9.10.tgz#70f3910ac7a51ed6bef79da7800690b19bf778b8"
integrity sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==
uri-js@^4.2.2:
version "4.4.1"
resolved "https://registry.npmmirror.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"
integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==
dependencies:
punycode "^2.1.0"
uuid@^3.3.2:
version "3.4.0"
resolved "https://registry.npmmirror.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
vary@^1.1.2:
version "1.1.2"
resolved "https://registry.npmmirror.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
verror@1.10.0:
version "1.10.0"
resolved "https://registry.npmmirror.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
integrity sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==
dependencies:
assert-plus "^1.0.0"
core-util-is "1.0.2"
extsprintf "^1.2.0"
ylru@^1.2.0:
version "1.4.0"
resolved "https://registry.npmmirror.com/ylru/-/ylru-1.4.0.tgz#0cf0aa57e9c24f8a2cbde0cc1ca2c9592ac4e0f6"
integrity sha512-2OQsPNEmBCvXuFlIni/a+Rn+R2pHW9INm0BxXJ4hVDA8TirqMj+J/Rp9ItLatT/5pZqWwefVrTQcHpixsxnVlA==
import { Suspense } from 'react'
import routes from '~react-pages'
import Layouts from './layouts'
const App: React.FC = () => {
return (
<Suspense fallback={<Spin fullscreen />}>
<Layouts>{useRoutes(routes)}</Layouts>
</Suspense>
)
}
export default App
export const getCustomList = () => {
return request.post<void, number[]>('/custom/list')
}
export const getFailedRecords = () => {
return request.get<void, number[]>('/complain/failedRecords')
}
export const getTopOnlineApp = () => {
return request.get<void, number[]>('/top/online/app')
}
export const getUserList = () => {
return new Promise<Array<UserEntity>>((resolve) => {
setTimeout(() => resolve(UserList), 1000)
})
}
export const getUserById = (id: number) => {
return new Promise<UserEntity | undefined>((resolve) => {
setTimeout(() => resolve(UserList.find((item) => item.id === id)), 1000)
})
}
export interface UserEntity {
id: number
name: string
}
// enum demo
export const Role = {
MANAGER: 1,
EMPLOYEE: 2,
CUSTOM: 3,
} as const
export type Role = (typeof Role)[keyof typeof Role]
export const UserList = [
{ id: 1, name: 'Jia Qi' },
{ id: 2, name: 'Xing Wang' },
]
interface UseRequestOption<TRequest extends unknown[], TResult> {
defaultParams?: TRequest
mannual?: boolean
onSuccess?: (data: TResult) => void
onError?: (error: Error, params: TRequest) => void
onFinally?: () => void
}
interface UseRequestResult<TRequest extends unknown[], TResult> {
data?: Awaited<TResult>
loading: boolean
error?: Error
run: (...args: TRequest) => Promise<TResult>
refresh: () => Promise<TResult>
}
const useRequest = <TRequest extends unknown[], TResult>(
request: (...args: TRequest) => TResult,
options: UseRequestOption<TRequest, TResult> = {}
): UseRequestResult<TRequest, TResult> => {
const [data, setData] = useState<Awaited<TResult>>()
const [loading, setLoading] = useState(false)
const [error, setError] = useState<Error>()
const cacheParams = useRef<TRequest>(options.defaultParams || ([] as unknown as TRequest))
const run = useCallback(async (...args: TRequest) => {
setLoading(true)
try {
cacheParams.current = args
const result = await request(...args)
options.onSuccess?.(result)
setData(result)
return result
} catch (err) {
options.onError?.(err as Error, args)
setError(err as Error)
throw err
} finally {
options.onFinally?.()
setLoading(false)
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
const refresh = useCallback(() => {
return run(...cacheParams.current)
}, [run])
useEffect(() => {
if (options.mannual) {
return
}
refresh()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
return {
data,
loading,
error,
run,
refresh,
}
}
export default useRequest
@import "tailwindcss"
\ No newline at end of file
const AuthLayout: React.FC<React.PropsWithChildren> = ({ children }) => {
return children
}
export default AuthLayout
import { useNavigate } from 'react-router-dom'
import { DashboardOutlined } from '@ant-design/icons'
// src/layouts/BasicLayout.tsx
import { Layout, Menu, theme } from 'antd'
const { Header, Content, Sider } = Layout
const menuItems = [
{
key: '/',
icon: <DashboardOutlined />,
label: 'Dashboard',
},
]
const BasicLayout: React.FC<React.PropsWithChildren> = ({ children }) => {
const {
token: { colorBgContainer },
} = theme.useToken()
const navigate = useNavigate()
return (
<Layout style={{ minHeight: '100vh' }}>
<Sider breakpoint='lg'>
<div className='demo-logo-vertical' />
<Menu theme='dark' mode='vertical' items={menuItems} onSelect={({ key }) => navigate(key)} />
</Sider>
<Layout>
<Header style={{ padding: 0, background: colorBgContainer }} />
<Content style={{ margin: '24px 16px 0' }}>
<div style={{ padding: 24, background: colorBgContainer }}>{children}</div>
</Content>
</Layout>
</Layout>
)
}
export default BasicLayout
import AuthLayout from './AuthLayout'
import BasicLayout from './BasicLayout'
const Layout: React.FC<React.PropsWithChildren> = ({ children }) => {
const location = useLocation()
const Layout = useMemo(() => (location.pathname === '/login' ? AuthLayout : BasicLayout), [location.pathname])
const navigate = useNavigate()
const [loading, setLoading] = useState(true)
useEffect(() => {
const token = localStorage.getItem('token')
if (location.pathname !== '/login' && !token) {
navigate('/login')
} else {
setLoading(false)
}
}, [location.pathname, navigate])
if (loading) return <Spin fullscreen />
return <Layout>{children}</Layout>
}
export default Layout
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { HashRouter } from 'react-router-dom'
import App from './App'
import './index.css'
import '@ant-design/v5-patch-for-react-19'
import 'antd/dist/reset.css'
const app = createRoot(document.getElementById('root')!)
app.render(
<StrictMode>
<HashRouter>
<App />
</HashRouter>
</StrictMode>
)
const About = () => <div>About</div>
export default About
const Counter = observer(() => {
const { count, doubleCount, loading, syncIncrement, asyncIncrement } = counterStore
return (
<div>
<p>Count: {count}</p>
<p>Double Count: {doubleCount}</p>
<Button onClick={syncIncrement}>+1</Button>
<Button onClick={asyncIncrement} disabled={loading}>
{loading ? 'Loading...' : 'Fetch Data'}
</Button>
</div>
)
})
export default Counter
// src/pages/dashboard/index.tsx
export default function Dashboard() {
const navigate = useNavigate()
const handleLogout = () => {
localStorage.removeItem('token')
navigate('/login')
}
return (
<Card title='控制台' extra={<Button onClick={handleLogout}>退出登录</Button>}>
<p>欢迎使用后台管理系统</p>
</Card>
)
}
import { LockOutlined, UserOutlined } from '@ant-design/icons'
type FieldType = {
username?: string
password?: string
}
export default function LoginPage() {
const navigate = useNavigate()
const [messageApi, contextHolder] = message.useMessage()
const onFinish = (values: FieldType) => {
if (values.username === 'admin' && values.password === '123456') {
localStorage.setItem('token', 'fake-jwt-token')
navigate('/')
messageApi.success('登录成功!')
} else {
messageApi.error('账号或密码错误')
}
}
return (
<div style={{ width: 360, margin: '100px auto' }}>
{contextHolder}
<h1 style={{ textAlign: 'center', marginBottom: 24 }}>后台管理系统</h1>
<Form name='login' initialValues={{ remember: true }} onFinish={onFinish}>
<Form.Item<FieldType> name='username' rules={[{ required: true, message: '请输入用户名' }]}>
<Input prefix={<UserOutlined />} placeholder='用户名' />
</Form.Item>
<Form.Item<FieldType> name='password' rules={[{ required: true, message: '请输入密码' }]}>
<Input.Password prefix={<LockOutlined />} placeholder='密码' />
</Form.Item>
<Form.Item>
<Button type='primary' htmlType='submit' block>
登录
</Button>
</Form.Item>
</Form>
</div>
)
}
const User: React.FC = () => {
return (
<div>
<header>
<h1 className='text-3xl font-bold underline'>Hello world!</h1>
</header>
<main>
<Outlet />
</main>
</div>
)
}
export default User
const SpercificUser = function () {
const { id } = useParams()
return <div>User {id}</div>
}
export default SpercificUser
const Index = () => <div>User Index</div>
export default Index
const UtilsExample: React.FC = () => {
// 金额对于后端来说只能是number & string & 空 & null & undefined
const a = prefixYuan(yuanToLi('300000', 2))
const b = smartFenToYuan('0', 3)
const c = liToYuan('0')
const d = digitUppercase('0')
// 正则
const e = buildREG(REGEX.INTEGER, 'undefined')
const f = precentAddSuffix(35)
return (
<div>
<p>1: {a}</p>
<p>2: {b}</p>
<p>3: {c}</p>
<p>4: {d}</p>
<p>5: {e}</p>
<p>6: {f}</p>
</div>
)
}
export default UtilsExample
import { useNavigate } from 'react-router-dom'
export default function NotFound() {
const navigate = useNavigate()
return (
<Result
status='404'
title='404'
subTitle='抱歉,您访问的页面不存在'
extra={
<Button type='primary' onClick={() => navigate('/')}>
返回首页
</Button>
}
/>
)
}
import React from 'react'
const Home: React.FC = () => {
const { data, run, loading } = useRequest(getUserList, { mannual: true })
const { run: userRun } = useRequest(getUserById, { defaultParams: [1], mannual: true })
const { data: failedRecords } = useRequest(getTopOnlineApp)
useEffect(() => {
userRun(1)
run()
}, [failedRecords, run, userRun])
return (
<div>
<header>首页</header>
<Button loading={loading} onClick={() => run()}>
测试
</Button>
{data?.map((user) => (
<React.Fragment key={user.id}>
<div>
<strong>id:</strong>
{user.id}
</div>
<div>
<strong>name:</strong>
{user.name}
</div>
</React.Fragment>
))}
</div>
)
}
export default Home
class CounterStore {
count = 0
loading = false
constructor() {
makeAutoObservable(this) // 自动推断类型
}
// Computed:计算属性
get doubleCount() {
return this.count * 2
}
// Action:同步修改状态
syncIncrement = () => {
this.count += 1
}
// Action:异步修改状态
asyncIncrement = async () => {
this.loading = true
await new Promise((resolve) => setTimeout(resolve, 1000))
this.count = 100
this.loading = false
}
}
export const counterStore = new CounterStore()
/**
* 常用正则表达式库
*/
import { REGEX, buildRegex } from 'pixiu-number-toolkit'
const isEmail = (email: string): boolean => {
if (isNothing(email)) {
return false
} else {
return REGEX.EMAIL.test(email)
}
}
/**
* @param REGEX 正则表达式= [
* https://www.muchappy.com/open_source/pixiu-number-toolkit/basic/regex
* NUMBER: 基础数字,包括正数、负数和小数
* INTEGER: 整数,包括正整数、负整数和零
* POSITIVE_INTEGER: 正整数
* NEGATIVE_INTEGER: 负整数
* NON_POSITIVE_INTEGER: 非正整数(包括负数和零)
* FLOAT: 浮点数
* POSITIVE_FLOAT: 正浮点数
* NEGATIVE_FLOAT: 负浮点数
* EMAIL: 电子邮箱地址
* CHINESE_NAME: 中文姓名
* ENGLISH_LETTER: 英文字母
* LOWERCASE_ENGLISH_LETTER: 小写英文字母
* UPPERCASE_ENGLISH_LETTER: 大写英文字母
* ]
* @param value 待验证的值
* @description 通过正则表达式验证值是否符合规则
* @returns true:符合规则 false:不符合规则
*/
const buildREG = (REGEX: RegExp, value: string | number): boolean => {
const strictRegex = buildRegex(REGEX, { strict: true })
return strictRegex.test(value + '')
}
const Rules = {
required: {
required: true,
message: '必填',
},
id: {
pattern: /^\d{0,20}$/,
message: '只能是数字',
},
ids: {
pattern: /^\d{0,20}(,\d{0,20})*$/,
message: '输入的格式有误',
},
name: {
max: 20,
message: '最多不超过20个字',
},
noCN: {
pattern: /^[^\u4e00-\u9fa5]+$/,
message: '不能出现中文',
},
email: {
pattern: REGEX.EMAIL,
message: '请输入正确的邮箱格式',
},
url: {
pattern: REGEX.URL,
message: '请输入正确的网址',
},
positiveInt: {
pattern: REGEX.POSITIVE_INTEGER,
message: '请输入正整数',
},
intLt1e100: {
pattern: /^([1-9][0-9]{0,1}|100)$/,
message: '请输入1-100整数',
},
intLt0e100: {
pattern: /^100$|^(\d|[1-9]\d)$/,
message: '请输入0-100整数',
},
float0e100: {
pattern: /^(?:100(?:\.00?)?|\d{1,2}(?:\.\d{1,2})?)$/,
message: '请输入0-100之间的数字,最多保留两位小数',
},
// 金额校验 包含正负 0 两位小数
money: {
pattern: /(^([+-]?)[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^([+-]?)(0){1}$)|(^([+-]?)[0-9]\.[0-9]([0-9])?$)/,
message: '请输入两位小数以内的正负金额数',
},
percent: {
pattern: /^(\d|[1-9]\d|100)(\.\d{1,2})?$/,
message: '请输入正确的百分比',
},
}
export { isEmail, buildREG, Rules }
function getCookie(name: string) {
const reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)')
const matches = reg.exec(document.cookie)
return matches ? matches[2] : null
}
function setCookie(name: string, value: string, expired: number) {
const d = new Date()
d.setTime(d.getTime() + expired * 24 * 60 * 60 * 1000)
const expires = 'expires=' + d.toUTCString()
document.cookie = name + '=' + value + '; ' + expires
}
export default {
get: getCookie,
set: setCookie,
}
import type { TimeRangePickerProps } from 'antd'
import dayjs from 'dayjs'
/**
* 时间处理工具
**/
export const rangePresets: TimeRangePickerProps['presets'] = [
{ label: '今天', value: [dayjs(), dayjs()] },
{ label: '昨天', value: [dayjs().add(-1, 'd'), dayjs().add(-1, 'd')] },
{ label: '最近三天', value: [dayjs().add(-2, 'd'), dayjs()] },
{ label: '最近七天', value: [dayjs().add(-6, 'd'), dayjs()] },
{ label: '最近三十一天', value: [dayjs().add(-31, 'd'), dayjs()] },
{ label: '本月', value: [dayjs().startOf('month'), dayjs().endOf('month')] },
]
export const changeDate = (num: number, format = 'YYYY-MM-DD') => {
return dayjs().add(num, 'days').format(format)
}
export function isNothing(value: number | void | string | null) {
return (
value === '' ||
value === undefined ||
value === null ||
(typeof value === 'number' && (isNaN(value) || !isFinite(value)))
)
}
import numeral from 'numeral'
import { numberToChineseUppercaseCurrency, currency } from 'pixiu-number-toolkit'
/**
* 金额转换工具
* /
/**
*
* @param num 金额|单位分
* @description 1元 = 100分
* @param precision 小数点位数
* @returns 格式化的金额|单位元
* @description 默认保留2位小数
*/
const fenToYuan = (num: number | string, precision = 2): number | string => {
if (isNothing(num)) {
return ''
} else {
return numeral(num)
.divide(100)
.format(`0.${Array(precision).fill(0).join('')}`)
}
}
/**
*
* @param num 金额|单位分
* @description 1元 = 100分
* @param precision 小数点位数
* @returns 格式化的金额 |单位元
* @description 返回金额为整数,无小数点
* @description 返回金额为小数,保留precision小数点
*/
const smartFenToYuan = (num: number | string, precision = 2): number | string => {
if (isNothing(num)) {
return ''
}
return numeral(num)
.divide(100)
.format(`0[.]${Array(precision).fill(0).join('')}`)
}
/**
* @param num 金额|单位厘
* @description 1元 = 1000厘
* @param precision 小数点位数
* @returns 格式化的金额 |单位元
* @description 默认保留2位小数
*/
const liToYuan = (num: number | string, precision = 2): number | string => {
if (isNothing(num)) {
return ''
} else {
return numeral(num)
.divide(1000)
.format(`0.${Array(precision).fill(0).join('')}`)
}
}
/**
*
* @param num 金额|单位元
* @description 1元 = 100分
* @param precision 小数点位数
* @returns 格式化的金额|单位分
* 默认保留2位小数
*/
const yuanToFen = (num: number | string, precision = 2): number | string => {
if (isNothing(num)) {
return ''
} else {
return numeral(num)
.multiply(100)
.format(`0.${Array(precision).fill(0).join('')}`)
}
}
/**
* @param num 金额|单位元
* @description 1元 = 1000厘
* @param precision 小数点位数
* @returns 格式化的金额 |单位厘
* @description 默认保留2位小数
*/
const yuanToLi = (num: number | string, precision = 2): number | string => {
if (isNothing(num)) {
return ''
} else {
return numeral(num)
.multiply(1000)
.format(`0.${Array(precision).fill(0).join('')}`)
}
}
/**
*
* @param num 金额|单位元
* @returns 大写金额
* @description 小数点最多读取2位,角、分
* @description 负数,前面加"欠"
*/
const digitUppercase = (num: number | string): string => {
if (isNothing(num)) {
return ''
} else {
return numberToChineseUppercaseCurrency(Number(num))
}
}
/**
* 添加单位元
* @param num 数字
* @returns num + '元'
* @description 默认保留2位小数
*/
const unitYuan = (num: string | number, precision = 2): string => {
return currency(num, { suffix: '元', minimumFractionDigits: precision })
}
/**
* 添加前缀¥
* @param num 数字
* @returns ¥num
* @description 默认保留2位小数
*/
const prefixYuan = (num: string | number, precision = 2): string => {
return currency(num, { prefix: '¥', minimumFractionDigits: precision })
}
export { fenToYuan, smartFenToYuan, liToYuan, yuanToFen, yuanToLi, digitUppercase, unitYuan, prefixYuan }
import { currency } from 'pixiu-number-toolkit'
/**
* 数据处理工具
* /
/**
* 百分比格式|*100%
* @param num 数字
* @returns 百分比格式
* @example currency(0.35, { style: 'percent' }) = 35%
*/
const precent = (num: number | string, precision = 2): string | number => {
if (isNothing(num)) return '-'
return currency(num, { style: 'percent', minimumFractionDigits: precision })
}
/**
* 百分比格式|直接加后缀%
* @param num 数字
* @returns 百分比格式
* @example currency(35, { suffix: '%', minimumFractionDigits: precision }) = 35%
*/
const precentAddSuffix = (num: number | string, precision = 2): string | number => {
if (isNothing(num)) return '-'
return currency(num, { suffix: '%', minimumFractionDigits: precision })
}
export { precent, precentAddSuffix }
/**
* 权限工具类
*/
let permissionCodes: string[] = []
const Permissions = {
getPermissions() {
return permissionCodes
},
setPermissions(permissions: string[]) {
if (permissions && permissions.length) {
permissionCodes = [...permissions]
}
},
authRender<T>(item: T, code: string | string[]) {
if (this.ifRender(code)) {
return item
} else {
return null
}
},
// 判断是否需要渲染权限组件
ifRender(code: string | string[]): boolean {
// 用于判断是否需要渲染
let shouldRender = false
// 如果传入的是个权限数组,那么需要所有权限都有的情况下才能渲染
if (typeof code !== 'string') {
shouldRender = code.every((el) => {
return permissionCodes.some((item) => item.includes(el))
})
} else {
// 传入的是字符串则匹配是否有该权限
shouldRender = permissionCodes.some((item) => item.includes(code))
}
return shouldRender
},
}
export default Permissions
const XCsrfToken = cookie.get('csrf_token') || ''
export function createRequester() {
const requester = axios.create({
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
'X-Csrf-Token': XCsrfToken,
'X-Proxy-Enabled': 'enabled',
},
withCredentials: true,
})
return requester
}
const request = createRequester()
request.interceptors.request.use(function (config) {
const { params } = config
for (const key in params) {
if (isNothing(params[key])) {
delete params[key]
}
}
return { ...config, params }
})
request.interceptors.response.use(async function (response) {
const { data, success, desc } = response.data
if (success) return data
message.error(desc)
return Promise.reject(desc || '服务异常')
})
export default request
// const ssoRequest = createRequester()
// ssoRequest.interceptors.response.use(async function (response) {
// const { success, message: desc, code } = response.data
// if (success) return response.data
// // 无应用访问权限
// if (code === "SSO:01002") return response.data
// // 未登录
// message.error(desc)
// window.location.href = `https://sso.duiba.com.cn/login?systemId=677&redirect=${encodeURIComponent(
// window.location.origin
// )}`
// return response.data
// })
// export { ssoRequest }
/// <reference types="vite/client" />
/// <reference types="vite-plugin-pages/client-react" />
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
},
"include": [
"src",
"src/main.tsx",
"src/**/*.ts",
"src/**/*.d.ts",
"src/**/*.tsx",
"auto-imports.d.ts"
]
}
{
"files": [],
"compilerOptions": {
"jsx": "react-jsx",
"sourceMap": true,
"skipLibCheck": true,
"allowSyntheticDefaultImports": true,
"experimentalDecorators": true,
},
"references": [
{ "path": "./tsconfig.app.json" },
{ "path": "./tsconfig.node.json" }
]
}
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
"target": "ES2022",
"lib": ["ES2023"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
},
"include": ["vite.config.ts"]
}
import type { Plugin } from 'vite'
// 自定义插件:将 unplugin-auto-import 的重复导入警告转为错误
export function AutoImportError(): Plugin {
return {
name: 'auto-import-error',
configResolved() {
// 在 Vite 配置解析后注入逻辑
const logger = console
const originalWarning = logger.warn
// 劫持unimport的warn输出
logger.warn = (msg: string) => {
// 匹配 unplugin-auto-import 的重复导入警告
const match = msg.match(/Duplicated imports "(.+)", the one from "(.+)" has been ignored and "(.+)" is used/)
if (match) {
// 抛出错误并终止进程
const [, name, path1, path2] = match
const modifiedMsg = `[重复导入错误] ${name}${path1}${path2} 中重复导入`
// 提示:在开发环境下,抛出错误并终止进程
if (process.env.NODE_ENV === 'production') {
throw new Error(modifiedMsg)
}
logger.error(modifiedMsg)
return
}
// 其他警告正常输出
originalWarning.call(logger, msg)
}
},
}
}
import tailwindcss from '@tailwindcss/vite'
import react from '@vitejs/plugin-react-swc'
import AutoImport from 'unplugin-auto-import'
import { defineConfig } from 'vite'
import Pages from 'vite-plugin-pages'
import { AutoImportError } from './vite-plugins/auto-import-error'
// https://vite.dev/config/
export default defineConfig({
server: {
proxy: {
'^/(.*)': {
target: 'http://localhost:10089',
changeOrigin: true,
bypass: (req) => {
const url = req.url
if (req.headers['x-proxy-enabled']) {
return null
}
return url
},
},
},
},
plugins: [
AutoImportError(),
AutoImport.vite({
include: [/\.tsx?$/],
dirs: [
'src/apis/**',
'src/components/common/**',
'src/constants/**',
'src/hooks/**',
'src/utils/**',
'src/stores/**',
],
imports: [
{
antd: ['message', 'Spin', 'Layout', 'Menu', 'theme', 'Button', 'Form', 'Input', 'Card', 'Result'],
axios: [['default', 'axios']],
'pixiu-number-toolkit': ['REGEX'],
},
'react',
'react-router-dom',
'mobx',
'mobx-react-lite',
],
}),
react(),
Pages({
routeStyle: 'next',
importMode: 'async',
dirs: 'src/pages',
exclude: ['**/components/*.ts[x]?', '**/hooks/*.ts[x]?'],
extendRoute(route) {
if (route.path === '/login') {
return route
}
return {
...route,
meta: {
requiresAuth: true,
layout: 'index',
},
}
},
}),
tailwindcss(),
],
})
{
"baseUrl": "https://docs.dui88.com",
"apiMap": [
{
"projectId": "<number>",
"apiPrefix": "/<apiPrefix>",
"token": "09bcbc7dfc228daaf9671db239d876836228791fb2488429c9f57146380fe46f"
}
],
"proxy": {
"targets": [
{
"name": "测试环境",
"target": "https://eye.dui8pre.com"
},
{
"name": "生产环境",
"target": "https://eye.dui88.com"
}
],
"port": 10089
}
}
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